From: patrick Date: Wed, 28 Apr 2021 12:29:46 +0000 (+0000) Subject: Import LLVM 11.1.0 release including clang, lld and lldb. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=dda2819751e49c83612958492e38917049128b41;p=openbsd Import LLVM 11.1.0 release including clang, lld and lldb. --- diff --git a/gnu/llvm/lldb/.clang-tidy b/gnu/llvm/lldb/.clang-tidy new file mode 100644 index 00000000000..e949902171e --- /dev/null +++ b/gnu/llvm/lldb/.clang-tidy @@ -0,0 +1,2 @@ +# Checks enabled in the top-level .clang-tidy minus readability-identifier-naming +Checks: '-*,clang-diagnostic-*,llvm-*,misc-*,-misc-unused-parameters,-misc-non-private-member-variables-in-classes' diff --git a/gnu/llvm/lldb/CMakeLists.txt b/gnu/llvm/lldb/CMakeLists.txt index 573b8556989..bf748020ea4 100644 --- a/gnu/llvm/lldb/CMakeLists.txt +++ b/gnu/llvm/lldb/CMakeLists.txt @@ -92,8 +92,7 @@ option(LLDB_INCLUDE_TESTS "Generate build targets for the LLDB unit tests." ${LL if(LLDB_INCLUDE_TESTS) add_subdirectory(test) add_subdirectory(unittests) - add_subdirectory(utils/lit-cpuid) - add_subdirectory(utils/lldb-dotest) + add_subdirectory(utils) endif() if (LLDB_ENABLE_PYTHON) @@ -225,6 +224,10 @@ if (LLDB_ENABLE_PYTHON) else() set(LLDB_PYTHON_INSTALL_PATH ${LLDB_PYTHON_RELATIVE_PATH}) endif() + if (NOT CMAKE_CFG_INTDIR STREQUAL ".") + string(REPLACE ${CMAKE_CFG_INTDIR} "\$\{CMAKE_INSTALL_CONFIG_NAME\}" LLDB_PYTHON_INSTALL_PATH ${LLDB_PYTHON_INSTALL_PATH}) + string(REPLACE ${CMAKE_CFG_INTDIR} "\$\{CMAKE_INSTALL_CONFIG_NAME\}" lldb_python_build_path ${lldb_python_build_path}) + endif() add_custom_target(lldb-python-scripts) add_dependencies(lldb-python-scripts finish_swig) install(DIRECTORY ${lldb_python_build_path}/../ diff --git a/gnu/llvm/lldb/bindings/CMakeLists.txt b/gnu/llvm/lldb/bindings/CMakeLists.txt index 92ae402c478..a2e51c263f7 100644 --- a/gnu/llvm/lldb/bindings/CMakeLists.txt +++ b/gnu/llvm/lldb/bindings/CMakeLists.txt @@ -1,4 +1,4 @@ -file(GLOB SWIG_INTERFACES interfaces/*.i) +file(GLOB SWIG_INTERFACES interface/*.i) file(GLOB_RECURSE SWIG_SOURCES *.swig) file(GLOB SWIG_HEADERS ${LLDB_SOURCE_DIR}/include/lldb/API/*.h @@ -48,7 +48,7 @@ if (LLDB_ENABLE_PYTHON) -o ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapPython.cpp ${LLDB_SOURCE_DIR}/bindings/python.swig VERBATIM - COMMENT "Builds LLDB Python wrapper") + COMMENT "Building LLDB Python wrapper") add_custom_target(swig_wrapper ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapPython.cpp @@ -69,7 +69,7 @@ if (LLDB_ENABLE_LUA) -o ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapLua.cpp ${LLDB_SOURCE_DIR}/bindings/lua.swig VERBATIM - COMMENT "Builds LLDB Lua wrapper") + COMMENT "Building LLDB Lua wrapper") add_custom_target(swig_wrapper_lua ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapLua.cpp diff --git a/gnu/llvm/lldb/bindings/headers.swig b/gnu/llvm/lldb/bindings/headers.swig index 69fd28e33c5..6e1668ea4c4 100644 --- a/gnu/llvm/lldb/bindings/headers.swig +++ b/gnu/llvm/lldb/bindings/headers.swig @@ -15,18 +15,20 @@ #include "lldb/API/SBBreakpointName.h" #include "lldb/API/SBBroadcaster.h" #include "lldb/API/SBCommandInterpreter.h" +#include "lldb/API/SBCommandInterpreterRunOptions.h" #include "lldb/API/SBCommandReturnObject.h" #include "lldb/API/SBCommunication.h" #include "lldb/API/SBCompileUnit.h" #include "lldb/API/SBData.h" #include "lldb/API/SBDebugger.h" #include "lldb/API/SBDeclaration.h" +#include "lldb/API/SBEnvironment.h" #include "lldb/API/SBError.h" #include "lldb/API/SBEvent.h" #include "lldb/API/SBExecutionContext.h" #include "lldb/API/SBExpressionOptions.h" -#include "lldb/API/SBFileSpec.h" #include "lldb/API/SBFile.h" +#include "lldb/API/SBFileSpec.h" #include "lldb/API/SBFileSpecList.h" #include "lldb/API/SBFrame.h" #include "lldb/API/SBFunction.h" @@ -46,6 +48,7 @@ #include "lldb/API/SBProcessInfo.h" #include "lldb/API/SBQueue.h" #include "lldb/API/SBQueueItem.h" +#include "lldb/API/SBReproducer.h" #include "lldb/API/SBSection.h" #include "lldb/API/SBSourceManager.h" #include "lldb/API/SBStream.h" @@ -68,9 +71,9 @@ #include "lldb/API/SBTypeNameSpecifier.h" #include "lldb/API/SBTypeSummary.h" #include "lldb/API/SBTypeSynthetic.h" +#include "lldb/API/SBUnixSignals.h" #include "lldb/API/SBValue.h" #include "lldb/API/SBValueList.h" #include "lldb/API/SBVariablesOptions.h" #include "lldb/API/SBWatchpoint.h" -#include "lldb/API/SBUnixSignals.h" %} diff --git a/gnu/llvm/lldb/bindings/interface/SBAddress.i b/gnu/llvm/lldb/bindings/interface/SBAddress.i index 4658534d153..6fd06c83d29 100644 --- a/gnu/llvm/lldb/bindings/interface/SBAddress.i +++ b/gnu/llvm/lldb/bindings/interface/SBAddress.i @@ -144,27 +144,34 @@ public: #ifdef SWIGPYTHON %pythoncode %{ + __runtime_error_str = 'This resolves the SBAddress using the SBTarget from lldb.target so this property can ONLY be used in the interactive script interpreter (i.e. under the lldb script command). For things like Python based commands and breakpoint callbacks use GetLoadAddress instead.' + def __get_load_addr_property__ (self): - '''Get the load address for a lldb.SBAddress using the current target.''' + '''Get the load address for a lldb.SBAddress using the current target. This resolves the SBAddress using the SBTarget from lldb.target so this property can ONLY be used in the interactive script interpreter (i.e. under the lldb script command). For things like Python based commands and breakpoint callbacks use GetLoadAddress instead.''' + if not target: + raise RuntimeError(self.__runtime_error_str) return self.GetLoadAddress (target) def __set_load_addr_property__ (self, load_addr): - '''Set the load address for a lldb.SBAddress using the current target.''' + '''Set the load address for a lldb.SBAddress using the current target. This resolves the SBAddress using the SBTarget from lldb.target so this property can ONLY be used in the interactive script interpreter (i.e. under the lldb script command). For things like Python based commands and breakpoint callbacks use GetLoadAddress instead.''' + if not target: + raise RuntimeError(self.__runtime_error_str) return self.SetLoadAddress (load_addr, target) def __int__(self): - '''Convert an address to a load address if there is a process and that process is alive, or to a file address otherwise.''' + '''Convert an address to a load address if there is a process and that process is alive, or to a file address otherwise. This resolves the SBAddress using the SBTarget from lldb.target so this property can ONLY be used in the interactive script interpreter (i.e. under the lldb script command). For things like Python based commands and breakpoint callbacks use GetLoadAddress instead.''' + if not process or not target: + raise RuntimeError(self.__runtime_error_str) if process.is_alive: return self.GetLoadAddress (target) - else: - return self.GetFileAddress () + return self.GetFileAddress () def __oct__(self): - '''Convert the address to an octal string''' + '''Convert the address to an octal string. This resolves the SBAddress using the SBTarget from lldb.target so this property can ONLY be used in the interactive script interpreter (i.e. under the lldb script command). For things like Python based commands and breakpoint callbacks use GetLoadAddress instead.''' return '%o' % int(self) def __hex__(self): - '''Convert the address to an hex string''' + '''Convert the address to an hex string. This resolves the SBAddress using the SBTarget from lldb.target so this property can ONLY be used in the interactive script interpreter (i.e. under the lldb script command). For things like Python based commands and breakpoint callbacks use GetLoadAddress instead.''' return '0x%x' % int(self) module = property(GetModule, None, doc='''A read only property that returns an lldb object that represents the module (lldb.SBModule) that this address resides within.''') @@ -176,7 +183,7 @@ public: offset = property(GetOffset, None, doc='''A read only property that returns the section offset in bytes as an integer.''') section = property(GetSection, None, doc='''A read only property that returns an lldb object that represents the section (lldb.SBSection) that this address resides within.''') file_addr = property(GetFileAddress, None, doc='''A read only property that returns file address for the section as an integer. This is the address that represents the address as it is found in the object file that defines it.''') - load_addr = property(__get_load_addr_property__, __set_load_addr_property__, doc='''A read/write property that gets/sets the SBAddress using load address. The setter resolves SBAddress using the SBTarget from lldb.target so this property can ONLY be used in the interactive script interpreter (i.e. under the lldb script command) and not in Python based commands, or breakpoint commands.''') + load_addr = property(__get_load_addr_property__, __set_load_addr_property__, doc='''A read/write property that gets/sets the SBAddress using load address. This resolves the SBAddress using the SBTarget from lldb.target so this property can ONLY be used in the interactive script interpreter (i.e. under the lldb script command). For things like Python based commands and breakpoint callbacks use GetLoadAddress instead.''') %} #endif diff --git a/gnu/llvm/lldb/bindings/interface/SBBlock.i b/gnu/llvm/lldb/bindings/interface/SBBlock.i index 8bd8e37953c..812b41fe5c3 100644 --- a/gnu/llvm/lldb/bindings/interface/SBBlock.i +++ b/gnu/llvm/lldb/bindings/interface/SBBlock.i @@ -152,7 +152,7 @@ public: sibling = property(GetSibling, None, doc='''A read only property that returns the same result as GetSibling().''') name = property(GetInlinedName, None, doc='''A read only property that returns the same result as GetInlinedName().''') inlined_block = property(GetContainingInlinedBlock, None, doc='''A read only property that returns the same result as GetContainingInlinedBlock().''') - range = property(get_ranges_access_object, None, doc='''A read only property that allows item access to the address ranges for a block by integer (range = block.range[0]) and by lldb.SBAdddress (find the range that contains the specified lldb.SBAddress like "pc_range = lldb.frame.block.range[frame.addr]").''') + range = property(get_ranges_access_object, None, doc='''A read only property that allows item access to the address ranges for a block by integer (range = block.range[0]) and by lldb.SBAddress (find the range that contains the specified lldb.SBAddress like "pc_range = lldb.frame.block.range[frame.addr]").''') ranges = property(get_ranges_array, None, doc='''A read only property that returns a list() object that contains all of the address ranges for the block.''') num_ranges = property(GetNumRanges, None, doc='''A read only property that returns the same result as GetNumRanges().''') %} diff --git a/gnu/llvm/lldb/bindings/interface/SBBreakpoint.i b/gnu/llvm/lldb/bindings/interface/SBBreakpoint.i index 20354346be9..a2d747db0bf 100644 --- a/gnu/llvm/lldb/bindings/interface/SBBreakpoint.i +++ b/gnu/llvm/lldb/bindings/interface/SBBreakpoint.i @@ -206,6 +206,9 @@ public: bool AddName (const char *new_name); + SBError + AddNameWithErrorHandling (const char *new_name); + void RemoveName (const char *name_to_remove); diff --git a/gnu/llvm/lldb/bindings/interface/SBCommandInterpreter.i b/gnu/llvm/lldb/bindings/interface/SBCommandInterpreter.i index ad2e8f1662c..498084ae3ab 100644 --- a/gnu/llvm/lldb/bindings/interface/SBCommandInterpreter.i +++ b/gnu/llvm/lldb/bindings/interface/SBCommandInterpreter.i @@ -8,70 +8,6 @@ namespace lldb { -%feature("docstring", -"SBCommandInterpreterRunOptions controls how the RunCommandInterpreter runs the code it is fed. -A default SBCommandInterpreterRunOptions object has: - StopOnContinue: false - StopOnError: false - StopOnCrash: false - EchoCommands: true - PrintResults: true - AddToHistory: true - -") SBCommandInterpreterRunOptions; -class SBCommandInterpreterRunOptions -{ -friend class SBDebugger; -public: - SBCommandInterpreterRunOptions(); - ~SBCommandInterpreterRunOptions(); - - bool - GetStopOnContinue () const; - - void - SetStopOnContinue (bool); - - bool - GetStopOnError () const; - - void - SetStopOnError (bool); - - bool - GetStopOnCrash () const; - - void - SetStopOnCrash (bool); - - bool - GetEchoCommands () const; - - void - SetEchoCommands (bool); - - bool - GetPrintResults () const; - - void - SetPrintResults (bool); - - bool - GetAddToHistory () const; - - void - SetAddToHistory (bool); -private: - lldb_private::CommandInterpreterRunOptions * - get () const; - - lldb_private::CommandInterpreterRunOptions & - ref () const; - - // This is set in the constructor and will always be valid. - mutable std::unique_ptr m_opaque_up; -}; - %feature("docstring", "SBCommandInterpreter handles/interprets commands for lldb. You get the command interpreter from the SBDebugger instance. For example (from test/ diff --git a/gnu/llvm/lldb/bindings/interface/SBCommandInterpreterRunOptions.i b/gnu/llvm/lldb/bindings/interface/SBCommandInterpreterRunOptions.i new file mode 100644 index 00000000000..f9ccbbd24db --- /dev/null +++ b/gnu/llvm/lldb/bindings/interface/SBCommandInterpreterRunOptions.i @@ -0,0 +1,75 @@ +//===-- SWIG Interface for SBCommandInterpreter -----------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +namespace lldb { + +%feature("docstring", +"SBCommandInterpreterRunOptions controls how the RunCommandInterpreter runs the code it is fed. +A default SBCommandInterpreterRunOptions object has: + StopOnContinue: false + StopOnError: false + StopOnCrash: false + EchoCommands: true + PrintResults: true + AddToHistory: true + +") SBCommandInterpreterRunOptions; +class SBCommandInterpreterRunOptions +{ +friend class SBDebugger; +public: + SBCommandInterpreterRunOptions(); + ~SBCommandInterpreterRunOptions(); + + bool + GetStopOnContinue () const; + + void + SetStopOnContinue (bool); + + bool + GetStopOnError () const; + + void + SetStopOnError (bool); + + bool + GetStopOnCrash () const; + + void + SetStopOnCrash (bool); + + bool + GetEchoCommands () const; + + void + SetEchoCommands (bool); + + bool + GetPrintResults () const; + + void + SetPrintResults (bool); + + bool + GetAddToHistory () const; + + void + SetAddToHistory (bool); +private: + lldb_private::CommandInterpreterRunOptions * + get () const; + + lldb_private::CommandInterpreterRunOptions & + ref () const; + + // This is set in the constructor and will always be valid. + mutable std::unique_ptr m_opaque_up; +}; + +} // namespace lldb diff --git a/gnu/llvm/lldb/bindings/interface/SBEnvironment.i b/gnu/llvm/lldb/bindings/interface/SBEnvironment.i new file mode 100644 index 00000000000..4ca22fc314d --- /dev/null +++ b/gnu/llvm/lldb/bindings/interface/SBEnvironment.i @@ -0,0 +1,48 @@ +//===-- SWIG Interface for SBEnvironment-------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +namespace lldb { + +%feature("docstring", +"Represents the environment of a certain process. + +Example: + for entry in lldb.debugger.GetSelectedTarget().GetEnvironment().GetEntries(): + print(entry) + +") SBEnvironment; +class SBEnvironment { +public: + SBEnvironment (); + + SBEnvironment (const lldb::SBEnvironment &rhs); + + ~SBEnvironment(); + + size_t GetNumValues(); + + const char *Get(const char *name); + + const char *GetNameAtIndex(size_t index); + + const char *GetValueAtIndex(size_t index); + + SBStringList GetEntries(); + + void PutEntry(const char *name_and_value); + + void SetEntries(const SBStringList &entries, bool append); + + bool Set(const char *name, const char *value, bool overwrite); + + bool Unset(const char *name); + + void Clear(); +}; + +} // namespace lldb diff --git a/gnu/llvm/lldb/bindings/interface/SBExpressionOptions.i b/gnu/llvm/lldb/bindings/interface/SBExpressionOptions.i index 5dbd7007c01..950641c320d 100644 --- a/gnu/llvm/lldb/bindings/interface/SBExpressionOptions.i +++ b/gnu/llvm/lldb/bindings/interface/SBExpressionOptions.i @@ -59,7 +59,7 @@ public: uint32_t GetTimeoutInMicroSeconds () const; - %feature("docstring", "Sets the timeout in microseconds to run the expression for. If try all threads is set to true and the expression doesn't complete within the specified timeout, all threads will be resumed for the same timeout to see if the expresson will finish.") SetTimeoutInMicroSeconds; + %feature("docstring", "Sets the timeout in microseconds to run the expression for. If try all threads is set to true and the expression doesn't complete within the specified timeout, all threads will be resumed for the same timeout to see if the expression will finish.") SetTimeoutInMicroSeconds; void SetTimeoutInMicroSeconds (uint32_t timeout = 0); @@ -80,7 +80,7 @@ public: bool GetStopOthers () const; - %feature("docstring", "Sets whether to stop other threads at all while running expressins. If false, TryAllThreads does nothing.") SetTryAllThreads; + %feature("docstring", "Sets whether to stop other threads at all while running expressions. If false, TryAllThreads does nothing.") SetTryAllThreads; void SetStopOthers (bool stop_others = true); @@ -126,6 +126,14 @@ public: bool GetAutoApplyFixIts(); + %feature("docstring", "Sets how often LLDB should retry applying fix-its to an expression.") SetRetriesWithFixIts; + void + SetRetriesWithFixIts(uint64_t retries); + + %feature("docstring", "Gets how often LLDB will retry applying fix-its to an expression.") GetRetriesWithFixIts; + uint64_t + GetRetriesWithFixIts(); + bool GetTopLevel(); diff --git a/gnu/llvm/lldb/bindings/interface/SBFile.i b/gnu/llvm/lldb/bindings/interface/SBFile.i index a19666995cd..c86c5f26f14 100644 --- a/gnu/llvm/lldb/bindings/interface/SBFile.i +++ b/gnu/llvm/lldb/bindings/interface/SBFile.i @@ -92,7 +92,7 @@ public: SBFile, call SBFile.Close(). If there is no underlying python file to unwrap, GetFile will - use the file descriptor, if availble to create a new python + use the file descriptor, if available to create a new python file object using `open(fd, mode=..., closefd=False)` "); FileSP GetFile(); diff --git a/gnu/llvm/lldb/bindings/interface/SBLaunchInfo.i b/gnu/llvm/lldb/bindings/interface/SBLaunchInfo.i index e76950c6fb4..1de89b58b27 100644 --- a/gnu/llvm/lldb/bindings/interface/SBLaunchInfo.i +++ b/gnu/llvm/lldb/bindings/interface/SBLaunchInfo.i @@ -64,6 +64,12 @@ public: void SetEnvironmentEntries (const char **envp, bool append); + void + SetEnvironment(const SBEnvironment &env, bool append); + + SBEnvironment + GetEnvironment(); + void Clear (); diff --git a/gnu/llvm/lldb/bindings/interface/SBModule.i b/gnu/llvm/lldb/bindings/interface/SBModule.i index a9d9480cd7c..e902af0c49c 100644 --- a/gnu/llvm/lldb/bindings/interface/SBModule.i +++ b/gnu/llvm/lldb/bindings/interface/SBModule.i @@ -344,6 +344,15 @@ public: lldb::SBAddress GetObjectFileEntryPointAddress() const; + %feature("docstring", " + Returns the number of modules in the module cache. This is an + implementation detail exposed for testing and should not be relied upon. + + @return + The number of modules in the module cache.") GetNumberAllocatedModules; + static uint32_t + GetNumberAllocatedModules(); + STRING_EXTENSION(SBModule) #ifdef SWIGPYTHON diff --git a/gnu/llvm/lldb/bindings/interface/SBPlatform.i b/gnu/llvm/lldb/bindings/interface/SBPlatform.i index 9baa2eb970c..81945222c05 100644 --- a/gnu/llvm/lldb/bindings/interface/SBPlatform.i +++ b/gnu/llvm/lldb/bindings/interface/SBPlatform.i @@ -115,6 +115,8 @@ public: ~SBPlatform(); + static SBPlatform GetHostPlatform(); + bool IsValid () const; @@ -192,6 +194,9 @@ public: lldb::SBUnixSignals GetUnixSignals(); + lldb::SBEnvironment + GetEnvironment(); + }; } // namespace lldb diff --git a/gnu/llvm/lldb/bindings/interface/SBProcess.i b/gnu/llvm/lldb/bindings/interface/SBProcess.i index ac6a265faec..b54c4629f9d 100644 --- a/gnu/llvm/lldb/bindings/interface/SBProcess.i +++ b/gnu/llvm/lldb/bindings/interface/SBProcess.i @@ -346,6 +346,11 @@ public: bool GetDescription (lldb::SBStream &description); + %feature("autodoc", " + Returns the process' extended crash information.") GetExtendedCrashInformation; + lldb::SBStructuredData + GetExtendedCrashInformation (); + uint32_t GetNumSupportedHardwareWatchpoints (lldb::SBError &error) const; diff --git a/gnu/llvm/lldb/bindings/interface/SBReproducer.i b/gnu/llvm/lldb/bindings/interface/SBReproducer.i new file mode 100644 index 00000000000..7c9b007db3c --- /dev/null +++ b/gnu/llvm/lldb/bindings/interface/SBReproducer.i @@ -0,0 +1,18 @@ +//===-- SWIG Interface for SBReproducer--------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +namespace lldb { +class SBReproducer +{ + public: + static const char *Capture(const char *path); + static const char *PassiveReplay(const char *path); + static bool SetAutoGenerate(bool b); + static void SetWorkingDirectory(const char *path); +}; +} diff --git a/gnu/llvm/lldb/bindings/interface/SBStream.i b/gnu/llvm/lldb/bindings/interface/SBStream.i index 31fb3802bf6..edd67f87c3f 100644 --- a/gnu/llvm/lldb/bindings/interface/SBStream.i +++ b/gnu/llvm/lldb/bindings/interface/SBStream.i @@ -62,14 +62,8 @@ public: size_t GetSize(); - // wrapping the variadic Printf() with a plain Print() - // because it is hard to support varargs in SWIG bridgings - %extend { - void Print (const char* str) - { - self->Printf("%s", str); - } - } + void + Print (const char* str); void RedirectToFile (const char *path, bool append); diff --git a/gnu/llvm/lldb/bindings/interface/SBTarget.i b/gnu/llvm/lldb/bindings/interface/SBTarget.i index 371bf5c35eb..57b5ccea639 100644 --- a/gnu/llvm/lldb/bindings/interface/SBTarget.i +++ b/gnu/llvm/lldb/bindings/interface/SBTarget.i @@ -677,6 +677,9 @@ public: lldb::SBBreakpoint BreakpointCreateByAddress (addr_t address); + lldb::SBEnvironment + GetEnvironment(); + lldb::SBBreakpoint BreakpointCreateBySBAddress (SBAddress &sb_address); diff --git a/gnu/llvm/lldb/bindings/interfaces.swig b/gnu/llvm/lldb/bindings/interfaces.swig index 780fe34392f..2df7a05b4f4 100644 --- a/gnu/llvm/lldb/bindings/interfaces.swig +++ b/gnu/llvm/lldb/bindings/interfaces.swig @@ -22,6 +22,7 @@ %include "./interface/SBBreakpointName.i" %include "./interface/SBBroadcaster.i" %include "./interface/SBCommandInterpreter.i" +%include "./interface/SBCommandInterpreterRunOptions.i" %include "./interface/SBCommandReturnObject.i" %include "./interface/SBCommunication.i" %include "./interface/SBCompileUnit.i" @@ -29,6 +30,7 @@ %include "./interface/SBDebugger.i" %include "./interface/SBDeclaration.i" %include "./interface/SBError.i" +%include "./interface/SBEnvironment.i" %include "./interface/SBEvent.i" %include "./interface/SBExecutionContext.i" %include "./interface/SBExpressionOptions.i" @@ -53,6 +55,7 @@ %include "./interface/SBProcessInfo.i" %include "./interface/SBQueue.i" %include "./interface/SBQueueItem.i" +%include "./interface/SBReproducer.i" %include "./interface/SBSection.i" %include "./interface/SBSourceManager.i" %include "./interface/SBStream.i" diff --git a/gnu/llvm/lldb/bindings/python.swig b/gnu/llvm/lldb/bindings/python.swig index b086d436e57..5b1269878da 100644 --- a/gnu/llvm/lldb/bindings/python.swig +++ b/gnu/llvm/lldb/bindings/python.swig @@ -128,8 +128,15 @@ using namespace lldb; %include "./python/python-wrapper.swig" %pythoncode%{ +_initialize = True +try: + import lldbconfig + _initialize = lldbconfig.INITIALIZE +except ImportError: + pass debugger_unique_id = 0 -SBDebugger.Initialize() +if _initialize: + SBDebugger.Initialize() debugger = None target = None process = None diff --git a/gnu/llvm/lldb/bindings/python/python-typemaps.swig b/gnu/llvm/lldb/bindings/python/python-typemaps.swig index bfd7ef9007d..c08aeab71f7 100644 --- a/gnu/llvm/lldb/bindings/python/python-typemaps.swig +++ b/gnu/llvm/lldb/bindings/python/python-typemaps.swig @@ -59,37 +59,25 @@ $result = list.release(); } - %typemap(in) lldb::tid_t { - if (PythonInteger::Check($input)) - { - PythonInteger py_int(PyRefType::Borrowed, $input); - $1 = static_cast(py_int.GetInteger()); - } - else - { - PyErr_SetString(PyExc_ValueError, "Expecting an integer"); + PythonObject obj = Retain($input); + lldb::tid_t value = unwrapOrSetPythonException(As(obj)); + if (PyErr_Occurred()) return nullptr; - } + $1 = value; } %typemap(in) lldb::StateType { - if (PythonInteger::Check($input)) - { - PythonInteger py_int(PyRefType::Borrowed, $input); - int64_t state_type_value = py_int.GetInteger() ; - - if (state_type_value > lldb::StateType::kLastStateType) { - PyErr_SetString(PyExc_ValueError, "Not a valid StateType value"); - return nullptr; - } - $1 = static_cast(state_type_value); - } - else - { - PyErr_SetString(PyExc_ValueError, "Expecting an integer"); + PythonObject obj = Retain($input); + unsigned long long state_type_value = + unwrapOrSetPythonException(As(obj)); + if (PyErr_Occurred()) + return nullptr; + if (state_type_value > lldb::StateType::kLastStateType) { + PyErr_SetString(PyExc_ValueError, "Not a valid StateType value"); return nullptr; } + $1 = static_cast(state_type_value); } /* Typemap definitions to allow SWIG to properly handle char buffer. */ @@ -488,39 +476,53 @@ bool SetNumberFromPyObject(double &number, PyObject *obj) { } } +%inline %{ + +struct Py_buffer_RAII { + Py_buffer buffer = {}; + Py_buffer_RAII() {}; + Py_buffer &operator=(const Py_buffer_RAII &) = delete; + Py_buffer_RAII(const Py_buffer_RAII &) = delete; + ~Py_buffer_RAII() { + if (buffer.obj) + PyBuffer_Release(&buffer); + } +}; + +%} + // These two pybuffer macros are copied out of swig/Lib/python/pybuffer.i, // and fixed so they will not crash if PyObject_GetBuffer fails. // https://github.com/swig/swig/issues/1640 +// +// I've also moved the call to PyBuffer_Release to the end of the SWIG wrapper, +// doing it right away is not legal according to the python buffer protocol. %define %pybuffer_mutable_binary(TYPEMAP, SIZE) -%typemap(in) (TYPEMAP, SIZE) { +%typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) { int res; Py_ssize_t size = 0; void *buf = 0; - Py_buffer view; - res = PyObject_GetBuffer($input, &view, PyBUF_WRITABLE); + res = PyObject_GetBuffer($input, &view.buffer, PyBUF_WRITABLE); if (res < 0) { PyErr_Clear(); %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum); } - size = view.len; - buf = view.buf; - PyBuffer_Release(&view); + size = view.buffer.len; + buf = view.buffer.buf; $1 = ($1_ltype) buf; $2 = ($2_ltype) (size/sizeof($*1_type)); } %enddef %define %pybuffer_binary(TYPEMAP, SIZE) -%typemap(in) (TYPEMAP, SIZE) { +%typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) { int res; Py_ssize_t size = 0; const void *buf = 0; - Py_buffer view; - res = PyObject_GetBuffer($input, &view, PyBUF_CONTIG_RO); + res = PyObject_GetBuffer($input, &view.buffer, PyBUF_CONTIG_RO); if (res < 0) { PyErr_Clear(); %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum); } - size = view.len; - buf = view.buf; - PyBuffer_Release(&view); + size = view.buffer.len; + buf = view.buffer.buf; $1 = ($1_ltype) buf; $2 = ($2_ltype) (size / sizeof($*1_type)); } diff --git a/gnu/llvm/lldb/bindings/python/python-wrapper.swig b/gnu/llvm/lldb/bindings/python/python-wrapper.swig index 3a63165cf58..f9e89373fe2 100644 --- a/gnu/llvm/lldb/bindings/python/python-wrapper.swig +++ b/gnu/llvm/lldb/bindings/python/python-wrapper.swig @@ -444,6 +444,7 @@ LLDBSwigPythonCallBreakpointResolver if (PyErr_Occurred()) { PyErr_Print(); + PyErr_Clear(); return 0; } @@ -457,11 +458,13 @@ LLDBSwigPythonCallBreakpointResolver return 1; } - PythonInteger int_result = result.AsType(); - if (!int_result.IsAllocated()) - return 0; + long long ret_val = unwrapOrSetPythonException(As(result)); - unsigned int ret_val = int_result.GetInteger(); + if (PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + return 0; + } return ret_val; } @@ -515,26 +518,17 @@ LLDBSwigPython_CalculateNumChildren return 0; } - PythonObject result; - + size_t ret_val; if (arg_info.get().max_positional_args < 1) - result = pfunc(); + ret_val = unwrapOrSetPythonException(As(pfunc.Call())); else - result = pfunc(PythonInteger(max)); - - if (!result.IsAllocated()) - return 0; - - PythonInteger int_result = result.AsType(); - if (!int_result.IsAllocated()) - return 0; - - size_t ret_val = int_result.GetInteger(); + ret_val = unwrapOrSetPythonException(As(pfunc.Call(PythonInteger(max)))); - if (PyErr_Occurred()) //FIXME use Expected to catch python exceptions + if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); + return 0; } if (arg_info.get().max_positional_args < 1) @@ -588,16 +582,15 @@ LLDBSwigPython_GetIndexOfChildWithName if (!pfunc.IsAllocated()) return UINT32_MAX; - PythonObject result = pfunc(PythonString(child_name)); + llvm::Expected result = pfunc.Call(PythonString(child_name)); - if (!result.IsAllocated()) - return UINT32_MAX; + long long retval = unwrapOrSetPythonException(As(std::move(result))); - PythonInteger int_result = result.AsType(); - if (!int_result.IsAllocated()) + if (PyErr_Occurred()) { + PyErr_Clear(); // FIXME print this? do something else return UINT32_MAX; + } - int64_t retval = int_result.GetInteger(); if (retval >= 0) return (uint32_t)retval; diff --git a/gnu/llvm/lldb/cmake/modules/AddLLDB.cmake b/gnu/llvm/lldb/cmake/modules/AddLLDB.cmake index ecf0b66a41a..4ed5c647c5d 100644 --- a/gnu/llvm/lldb/cmake/modules/AddLLDB.cmake +++ b/gnu/llvm/lldb/cmake/modules/AddLLDB.cmake @@ -336,3 +336,17 @@ function(lldb_find_system_debugserver path) endif() endif() endfunction() + +# Removes all module flags from the current CMAKE_CXX_FLAGS. Used for +# the Objective-C++ code in lldb which we don't want to build with modules. +# Reasons for this are that modules with Objective-C++ would require that +# all LLVM/Clang modules are Objective-C++ compatible (which they are likely +# not) and we would have rebuild a second set of modules just for the few +# Objective-C++ files in lldb (which slows down the build process). +macro(remove_module_flags) + string(REGEX REPLACE "-fmodules-cache-path=[^ ]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + string(REGEX REPLACE "-fmodules-local-submodule-visibility" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + string(REGEX REPLACE "-fmodules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + string(REGEX REPLACE "-gmodules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + string(REGEX REPLACE "-fcxx-modules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") +endmacro() diff --git a/gnu/llvm/lldb/cmake/modules/FindLuaAndSwig.cmake b/gnu/llvm/lldb/cmake/modules/FindLuaAndSwig.cmake index 2e99933a745..968f905ef2d 100644 --- a/gnu/llvm/lldb/cmake/modules/FindLuaAndSwig.cmake +++ b/gnu/llvm/lldb/cmake/modules/FindLuaAndSwig.cmake @@ -7,9 +7,9 @@ if(LUA_LIBRARIES AND LUA_INCLUDE_DIR AND SWIG_EXECUTABLE) set(LUAANDSWIG_FOUND TRUE) else() - find_package(SWIG 2.0 QUIET) + find_package(SWIG 2.0) if (SWIG_FOUND) - find_package(Lua QUIET) + find_package(Lua 5.3) if(LUA_FOUND AND SWIG_FOUND) mark_as_advanced( LUA_LIBRARIES diff --git a/gnu/llvm/lldb/cmake/modules/FindPythonInterpAndLibs.cmake b/gnu/llvm/lldb/cmake/modules/FindPythonInterpAndLibs.cmake index 85862254101..243e0463f48 100644 --- a/gnu/llvm/lldb/cmake/modules/FindPythonInterpAndLibs.cmake +++ b/gnu/llvm/lldb/cmake/modules/FindPythonInterpAndLibs.cmake @@ -4,26 +4,79 @@ # # Find the python interpreter and libraries as a whole. +macro(FindPython3) + # Use PYTHON_HOME as a hint to find Python 3. + set(Python3_ROOT_DIR "${PYTHON_HOME}") + find_package(Python3 COMPONENTS Interpreter Development) + if(Python3_FOUND AND Python3_Interpreter_FOUND) + set(PYTHON_LIBRARIES ${Python3_LIBRARIES}) + set(PYTHON_INCLUDE_DIRS ${Python3_INCLUDE_DIRS}) + set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE}) + + # The install name for the Python 3 framework in Xcode is relative to + # the framework's location and not the dylib itself. + # + # @rpath/Python3.framework/Versions/3.x/Python3 + # + # This means that we need to compute the path to the Python3.framework + # and use that as the RPATH instead of the usual dylib's directory. + # + # The check below shouldn't match Homebrew's Python framework as it is + # called Python.framework instead of Python3.framework. + if (APPLE AND Python3_LIBRARIES MATCHES "Python3.framework") + string(FIND "${Python3_LIBRARIES}" "Python3.framework" python_framework_pos) + string(SUBSTRING "${Python3_LIBRARIES}" "0" ${python_framework_pos} PYTHON_RPATH) + endif() + + set(PYTHON3_FOUND TRUE) + mark_as_advanced( + PYTHON_LIBRARIES + PYTHON_INCLUDE_DIRS + PYTHON_EXECUTABLE + PYTHON_RPATH + SWIG_EXECUTABLE) + endif() +endmacro() + +macro(FindPython2) + # Use PYTHON_HOME as a hint to find Python 2. + set(Python2_ROOT_DIR "${PYTHON_HOME}") + find_package(Python2 COMPONENTS Interpreter Development) + if(Python2_FOUND AND Python2_Interpreter_FOUND) + set(PYTHON_LIBRARIES ${Python2_LIBRARIES}) + set(PYTHON_INCLUDE_DIRS ${Python2_INCLUDE_DIRS}) + set(PYTHON_EXECUTABLE ${Python2_EXECUTABLE}) + + set(PYTHON2_FOUND TRUE) + mark_as_advanced( + PYTHON_LIBRARIES + PYTHON_INCLUDE_DIRS + PYTHON_EXECUTABLE + SWIG_EXECUTABLE) + endif() +endmacro() + if(PYTHON_LIBRARIES AND PYTHON_INCLUDE_DIRS AND PYTHON_EXECUTABLE AND SWIG_EXECUTABLE) set(PYTHONINTERPANDLIBS_FOUND TRUE) else() - find_package(SWIG 2.0 QUIET) + find_package(SWIG 2.0) if (SWIG_FOUND) - if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") - find_package(Python3 COMPONENTS Interpreter Development QUIET) - if (Python3_FOUND AND Python3_Interpreter_FOUND) - set(PYTHON_LIBRARIES ${Python3_LIBRARIES}) - set(PYTHON_INCLUDE_DIRS ${Python3_INCLUDE_DIRS}) - set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE}) - mark_as_advanced( - PYTHON_LIBRARIES - PYTHON_INCLUDE_DIRS - PYTHON_EXECUTABLE - SWIG_EXECUTABLE) + if(NOT CMAKE_VERSION VERSION_LESS 3.12) + if (LLDB_PYTHON_VERSION) + if (LLDB_PYTHON_VERSION VERSION_EQUAL "2") + FindPython2() + elseif(LLDB_PYTHON_VERSION VERSION_EQUAL "3") + FindPython3() + endif() + else() + FindPython3() + if (NOT PYTHON3_FOUND AND NOT CMAKE_SYSTEM_NAME STREQUAL Windows) + FindPython2() + endif() endif() else() - find_package(PythonInterp QUIET) - find_package(PythonLibs QUIET) + find_package(PythonInterp) + find_package(PythonLibs) if(PYTHONINTERP_FOUND AND PYTHONLIBS_FOUND AND SWIG_FOUND) if (NOT CMAKE_CROSSCOMPILING) string(REPLACE "." ";" pythonlibs_version_list ${PYTHONLIBS_VERSION_STRING}) @@ -47,6 +100,7 @@ else() message(STATUS "SWIG 2 or later is required for Python support in LLDB but could not be found") endif() + include(FindPackageHandleStandardArgs) find_package_handle_standard_args(PythonInterpAndLibs FOUND_VAR diff --git a/gnu/llvm/lldb/cmake/modules/LLDBConfig.cmake b/gnu/llvm/lldb/cmake/modules/LLDBConfig.cmake index 4a15a343ee1..8465cfe3b7b 100644 --- a/gnu/llvm/lldb/cmake/modules/LLDBConfig.cmake +++ b/gnu/llvm/lldb/cmake/modules/LLDBConfig.cmake @@ -1,6 +1,5 @@ include(CheckCXXSymbolExists) include(CheckTypeSize) -include(CMakeDependentOption) set(LLDB_PROJECT_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) set(LLDB_SOURCE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/source") @@ -60,7 +59,6 @@ add_optional_dependency(LLDB_ENABLE_LUA "Enable Lua scripting support in LLDB" L add_optional_dependency(LLDB_ENABLE_PYTHON "Enable Python scripting support in LLDB" PythonInterpAndLibs PYTHONINTERPANDLIBS_FOUND) add_optional_dependency(LLDB_ENABLE_LIBXML2 "Enable Libxml 2 support in LLDB" LibXml2 LIBXML2_FOUND VERSION 2.8) -option(LLDB_RELOCATABLE_PYTHON "Use the PYTHONHOME environment variable to locate Python." OFF) option(LLDB_USE_SYSTEM_SIX "Use six.py shipped with system and do not install a copy of it" OFF) option(LLDB_USE_ENTITLEMENTS "When codesigning, use entitlements if available" ON) option(LLDB_BUILD_FRAMEWORK "Build LLDB.framework (Darwin only)" OFF) @@ -141,10 +139,20 @@ if (LLDB_ENABLE_LIBEDIT) endif() if (LLDB_ENABLE_PYTHON) + if(CMAKE_SYSTEM_NAME MATCHES "Windows") + set(default_embed_python_home ON) + else() + set(default_embed_python_home OFF) + endif() + option(LLDB_EMBED_PYTHON_HOME + "Embed PYTHONHOME in the binary. If set to OFF, PYTHONHOME environment variable will be used to to locate Python." + ${default_embed_python_home}) + include_directories(${PYTHON_INCLUDE_DIRS}) - if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows" AND NOT LLDB_RELOCATABLE_PYTHON) + if (LLDB_EMBED_PYTHON_HOME) get_filename_component(PYTHON_HOME "${PYTHON_EXECUTABLE}" DIRECTORY) - file(TO_CMAKE_PATH "${PYTHON_HOME}" LLDB_PYTHON_HOME) + set(LLDB_PYTHON_HOME "${PYTHON_HOME}" CACHE STRING + "Path to use as PYTHONHOME in lldb. If a relative path is specified, it will be resolved at runtime relative to liblldb directory.") endif() endif() @@ -226,7 +234,6 @@ if (LLDB_ENABLE_LZMA) endif() if (LLDB_ENABLE_LIBXML2) - list(APPEND system_libs ${LIBXML2_LIBRARIES}) include_directories(${LIBXML2_INCLUDE_DIR}) endif() @@ -272,12 +279,6 @@ if (APPLE) find_library(FOUNDATION_LIBRARY Foundation) find_library(CORE_FOUNDATION_LIBRARY CoreFoundation) find_library(SECURITY_LIBRARY Security) - list(APPEND system_libs - ${FOUNDATION_LIBRARY} - ${CORE_FOUNDATION_LIBRARY} - ${CORE_SERVICES_LIBRARY} - ${SECURITY_LIBRARY} - ${DEBUG_SYMBOLS_LIBRARY}) include_directories(${LIBXML2_INCLUDE_DIR}) endif() @@ -288,11 +289,8 @@ endif() if(NOT PURE_WINDOWS) set(CMAKE_THREAD_PREFER_PTHREAD TRUE) find_package(Threads REQUIRED) - list(APPEND system_libs ${CMAKE_THREAD_LIBS_INIT}) endif() -list(APPEND system_libs ${CMAKE_DL_LIBS}) - # Figure out if lldb could use lldb-server. If so, then we'll # ensure we build lldb-server when an lldb target is being built. if (CMAKE_SYSTEM_NAME MATCHES "Android|Darwin|FreeBSD|Linux|NetBSD|Windows") diff --git a/gnu/llvm/lldb/cmake/modules/LLDBFramework.cmake b/gnu/llvm/lldb/cmake/modules/LLDBFramework.cmake index fd4c2e41d76..c52daaa4fa8 100644 --- a/gnu/llvm/lldb/cmake/modules/LLDBFramework.cmake +++ b/gnu/llvm/lldb/cmake/modules/LLDBFramework.cmake @@ -59,8 +59,7 @@ list(REMOVE_ITEM root_public_headers ${root_private_headers}) set(lldb_header_staging ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders) foreach(header ${public_headers} - ${root_public_headers} - ${LLDB_SOURCE_DIR}/include/lldb/Utility/SharingPtr.h) + ${root_public_headers}) get_filename_component(basename ${header} NAME) set(staged_header ${lldb_header_staging}/${basename}) diff --git a/gnu/llvm/lldb/docs/conf.py b/gnu/llvm/lldb/docs/conf.py index bd95cbe6cd9..ca1d6f79092 100644 --- a/gnu/llvm/lldb/docs/conf.py +++ b/gnu/llvm/lldb/docs/conf.py @@ -46,12 +46,14 @@ copyright = u'2007-%d, The LLDB Team' % date.today().year # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the -# built documents. +# built documents. These are currently set to zero because we don't use them. +# Should somebody consider in the future to change them, they need to be updated +# everytime a new release comes out. # # The short version. -version = '8' +#version = '0' # The full version, including alpha/beta/rc tags. -release = '8' +#release = '0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/gnu/llvm/lldb/docs/index.rst b/gnu/llvm/lldb/docs/index.rst index f1e1eda7609..50441f5be91 100644 --- a/gnu/llvm/lldb/docs/index.rst +++ b/gnu/llvm/lldb/docs/index.rst @@ -3,7 +3,7 @@ The LLDB Debugger ================= -Welcome to the LLDB version |release| documentation! +Welcome to the LLDB documentation! LLDB is a next generation, high-performance debugger. It is built as a set of reusable components which highly leverage existing libraries in the larger LLVM @@ -69,12 +69,12 @@ Platform Support LLDB is known to work on the following platforms, but ports to new platforms are welcome: -* macOS desktop user space debugging for i386 and x86_64 -* iOS, tvOS, and watchOS simulator debugging on i386 and x86_64 +* macOS debugging for i386, x86_64 and AArch64 +* iOS, tvOS, and watchOS simulator debugging on i386, x86_64 and AArch64 * iOS, tvOS, and watchOS device debugging on ARM and AArch64 -* Linux local user-space debugging for i386, x86_64 and PPC64le -* FreeBSD local user-space debugging for i386 and x86_64 -* Windows local user-space debugging for i386 (*) +* Linux user-space debugging for i386, x86_64 and PPC64le +* FreeBSD user-space debugging for i386 and x86_64 +* Windows user-space debugging for i386 (*) (*) Support for Windows is under active development. Basic functionality is expected to work, with functionality improving rapidly. diff --git a/gnu/llvm/lldb/docs/lldb-gdb-remote.txt b/gnu/llvm/lldb/docs/lldb-gdb-remote.txt index 06cd09d77c4..276beedd047 100644 --- a/gnu/llvm/lldb/docs/lldb-gdb-remote.txt +++ b/gnu/llvm/lldb/docs/lldb-gdb-remote.txt @@ -3,7 +3,7 @@ remote debugging. Why? Normally you need to start the correct GDB and the correct GDB server when debugging. If you have mismatch, then things go wrong very quickly. LLDB makes extensive use of the GDB remote protocol and we wanted to make sure that the experience was a bit more dynamic where we can -discover information about a remote target with having to know anything up +discover information about a remote target without having to know anything up front. We also ran into performance issues with the existing GDB remote protocol that can be overcome when using a reliable communications layer. Some packets improve performance, others allow for remote process launching diff --git a/gnu/llvm/lldb/docs/lldb-platform-packets.txt b/gnu/llvm/lldb/docs/lldb-platform-packets.txt index ed5d7170171..23d1cacc5f7 100644 --- a/gnu/llvm/lldb/docs/lldb-platform-packets.txt +++ b/gnu/llvm/lldb/docs/lldb-platform-packets.txt @@ -351,7 +351,7 @@ incompatible with the flags that gdb specifies. // response is F followed by the opened file descriptor in base 10. // "F-1,errno" with the errno if an error occurs. // -// COMPATABILITY +// COMPATIBILITY // The gdb-remote serial protocol documentatio defines a vFile:open: // packet which uses incompatible flag values, e.g. 1 means O_WRONLY // in gdb's vFile:open:, but it means eOpenOptionRead to lldb's diff --git a/gnu/llvm/lldb/docs/man/lldb.rst b/gnu/llvm/lldb/docs/man/lldb.rst index b4972df1b60..87be124d788 100644 --- a/gnu/llvm/lldb/docs/man/lldb.rst +++ b/gnu/llvm/lldb/docs/man/lldb.rst @@ -251,11 +251,16 @@ EXAMPLES The debugger can be started in several modes. -Passing an executable as a positional argument prepares :program:`lldb` to -debug the given executable. Arguments passed after -- are considered arguments -to the debugged executable. +Passing an executable as a positional argument prepares lldb to debug the given +executable. To disambiguate between arguments passed to lldb and arguments +passed to the debugged executable, arguments starting with a - must be passed +after --. - lldb --arch x86_64 /path/to/program -- --arch arvm7 + lldb --arch x86_64 /path/to/program program argument -- --arch arvm7 + +For convenience, passing the executable after -- is also supported. + + lldb --arch x86_64 -- /path/to/program program argument --arch arvm7 Passing one of the attach options causes :program:`lldb` to immediately attach to the given process. @@ -298,7 +303,14 @@ CONFIGURATION FILES ------------------- :program:`lldb` reads things like settings, aliases and commands from the -.lldbinit file. It will first look for ~/.lldbinit and load that first. +.lldbinit file. + +First, it will read the application specific init file whose name is +~/.lldbinit followed by a "-" and the name of the current program. This would +be ~/.lldbinit-lldb for the command line :program:`lldb` and ~/.lldbinit-Xcode +for Xcode. If there is no application specific init file, the global +~/.lldbinit is read. + Secondly, it will look for an .lldbinit file in the current working directory. For security reasons, :program:`lldb` will print a warning and not source this file by default. This behavior can be changed by changing the diff --git a/gnu/llvm/lldb/docs/resources/bots.rst b/gnu/llvm/lldb/docs/resources/bots.rst index ed2d75ae7aa..efe8c7116b0 100644 --- a/gnu/llvm/lldb/docs/resources/bots.rst +++ b/gnu/llvm/lldb/docs/resources/bots.rst @@ -4,13 +4,12 @@ Continuous Integration Buildbot -------- -LLVM Buildbot is the place where Volunteers provide build machines to work as -build slaves. Everyone can `add a buildbot for LLDB -`_. - +LLVM Buildbot is the place where volunteers provide build machines. Everyone can +`add a buildbot for LLDB `_. * `lldb-x64-windows-ninja `_ * `lldb-x86_64-debian `_ +* `lldb-aarch64-ubuntu `_ * `lldb-x86_64-fedora `_ Documentation diff --git a/gnu/llvm/lldb/docs/resources/build.rst b/gnu/llvm/lldb/docs/resources/build.rst index 41586e22048..c1cb6ec1a93 100644 --- a/gnu/llvm/lldb/docs/resources/build.rst +++ b/gnu/llvm/lldb/docs/resources/build.rst @@ -34,7 +34,7 @@ If you want to run the test suite, you'll need to build LLDB with Python scripting support. * `Python `_ -* `SWIG `_ +* `SWIG `_ 2 or later. Optional Dependencies ********************* @@ -79,29 +79,38 @@ commands below. Windows ******* -* Visual Studio 2015 or greater -* Windows SDK 8.0 or higher. In general it is best to use the latest available - version. -* `GnuWin32 `_ -* `Python 3.5 or higher `_ or - higher. Earlier versions of Python can be made to work by compiling your own - distribution from source, but this workflow is unsupported and you are own - your own. +* Visual Studio 2017. +* The latest Windows SDK. +* The Active Template Library (ATL). +* `GnuWin32 `_ for CoreUtils and Make. +* `Python 3.6 or 3.8 `_. Python 3.7 + is known to be incompatible. Make sure to (1) get the x64 variant if that's + what you're targetting and (2) install the debug library if you want to build + a debug lldb. * `Python Tools for Visual Studio `_. If you plan to debug test failures or even write new tests at all, PTVS is an indispensable debugging extension to VS that enables full editing and debugging support for Python - (including mixed native/managed debugging) + (including mixed native/managed debugging). The steps outlined here describes how to set up your system and install the required dependencies such that they can be found when needed during the build process. They only need to be performed once. -#. Install Visual Studio and the Windows SDK. +#. Install Visual Studio with the Windows SDK and ATL components. #. Install GnuWin32, making sure ``\bin`` is added to - your PATH environment variable. + your PATH environment variable. Verify that utilities like ``dirname`` and + ``make`` are available from your terminal. #. Install SWIG for Windows, making sure ```` is added to - your PATH environment variable. + your PATH environment variable. Verify that ``swig`` is available from your + terminal. +#. Register the Debug Interface Access DLLs with the Registry from a privileged + terminal. + +:: + +> regsvr32 "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\DIA SDK\bin\msdia140.dll" +> regsvr32 "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\DIA SDK\bin\amd64\msdia140.dll" Any command prompt from which you build LLDB should have a valid Visual Studio environment setup. This means you should run ``vcvarsall.bat`` or open an @@ -286,14 +295,6 @@ the executable and the working directory to point to binaries inside of the ninja tree. -NetBSD -^^^^^^ - -Current stable NetBSD release doesn't ship with libpanel(3), therefore it's -required to disable curses(3) support with the -``-DLLDB_ENABLE_CURSES:BOOL=FALSE`` option. To make sure check if -``/usr/include/panel.h`` exists in your system. - macOS ^^^^^ diff --git a/gnu/llvm/lldb/docs/resources/caveats.rst b/gnu/llvm/lldb/docs/resources/caveats.rst index 780fb349051..2f37a6821ca 100644 --- a/gnu/llvm/lldb/docs/resources/caveats.rst +++ b/gnu/llvm/lldb/docs/resources/caveats.rst @@ -10,7 +10,7 @@ Python ------ LLDB has a powerful scripting interface which is accessible through Python. -Python is available either from withing LLDB through a (interactive) script +Python is available either from within LLDB through a (interactive) script interpreter, or as a Python module which you can import from the Python interpreter. @@ -31,7 +31,41 @@ against Python comes with some constraints to be aware of. the one used to build and link LLDB. The previous considerations are especially important during development, but -apply to binary distributions of LLDB as well. For example, the LLDB that comes -with Xcode links against the Python 3 that's part of Xcode. Therefore you -should always use the Python in Xcode (through ``xcrun python3`` or -``/usr/bin/python3``) to import the lldb module or install packages. +apply to binary distributions of LLDB as well. + +LLDB in Xcode on macOS +`````````````````````` + +Users of lldb in Xcode on macOS commonly run into these issues when they +install Python, often unknowingly as a dependency pulled in by Homebrew or +other package managers. The problem is the symlinks that get created in +``/usr/local/bin``, which comes before ``/usr/bin`` in your path. You can use +``which python3`` to check to what it resolves. + +To be sure you use the Python that matches with the lldb in Xcode use ``xcrun`` +or use the absolute path to the shims in ``/usr/bin``. + +:: + + $ xcrun python3 + $ /usr/bin/python3 + +Similarly, to install packages and be able to use them from within lldb, you'll +need to install them with the matching ``pip3``. + +:: + + $ xcrun pip3 + $ /usr/bin/pip3 + +The same is true for Python 2. Although Python 2 comes with the operating +system rather than Xcode, you can still use ``xcrun`` to launch the system +variant. + +:: + + $ xcrun python + $ /usr/bin/python + +Keep in mind that Python 2 is deprecated and no longer maintained. Future +versions of macOS will not include Python 2.7. diff --git a/gnu/llvm/lldb/docs/resources/reproducers.rst b/gnu/llvm/lldb/docs/resources/reproducers.rst index d28cade4521..1b109c06d90 100644 --- a/gnu/llvm/lldb/docs/resources/reproducers.rst +++ b/gnu/llvm/lldb/docs/resources/reproducers.rst @@ -91,7 +91,103 @@ debugger can have bugs, the reproducer can have bugs too. Design ------ -Coming soon. + +Replay +`````` + +Reproducers support two replay modes. The main and most common mode is active +replay. It's called active, because it's LLDB that is driving replay by calling +the captured SB API functions one after each other. The second mode is passive +replay. In this mode, LLDB sits idle until an SB API function is called, for +example from Python, and then replays just this individual call. + +Active Replay +^^^^^^^^^^^^^ + +No matter how a reproducer was captured, they can always be replayed with the +command line driver. When a reproducer is passed with the `--replay` flag, the +driver short-circuits and passes off control to the reproducer infrastructure, +effectively bypassing its normal operation. This works because the driver is +implemented using the SB API and is therefore nothing more than a sequence of +SB API calls. + +Replay is driven by the ``Registry::Replay``. As long as there's data in the +buffer holding the API data, the next SB API function call is deserialized. +Once the function is known, the registry can retrieve its signature, and use +that to deserialize its arguments. The function can then be invoked, most +commonly through the synthesized default replayer, or potentially using a +custom defined replay function. This process continues, until more data is +available or a replay error is encountered. + +During replay only a function's side effects matter. The result returned by the +replayed function is ignored because it cannot be observed beyond the driver. +This is sound, because anything that is passed into a subsequent API call will +have been serialized as an input argument. This also works for SB API objects +because the reproducers know about every object that has crossed the API +boundary, which is true by definition for object return values. + + +Passive Replay +^^^^^^^^^^^^^^ + +Passive replay exists to support running the API test suite against a +reproducer. The API test suite is written in Python and tests the debugger by +calling into its API from Python. To make this work, the API must transparently +replay itself when called. This is what makes passive replay different from +driver replay, where it is lldb itself that's driving replay. For passive +replay, the driving factor is external. + +In order to replay API calls, the reproducers need a way to intercept them. +Every API call is already instrumented with an ``LLDB_RECORD_*`` macro that +captures its input arguments. Furthermore, it also contains the necessary logic +to detect which calls cross the API boundary and should be intercepted. We were +able to reuse all of this to implement passive replay. + +During passive replay is enabled, nothing happens until an SB API is called. +Inside that API function, the macro detects whether this call should be +replayed (i.e. crossed the API boundary). If the answer is yes, the next +function is deserialized from the SB API data and compared to the current +function. If the signature matches, we deserialize its input arguments and +reinvoke the current function with the deserialized arguments. We don't need to +do anything special to prevent us from recursively calling the replayed version +again, as the API boundary crossing logic knows that we're still behind the API +boundary when we re-invoked the current function. + +Another big difference with driver replay is the return value. While this +didn't matter for driver replay, it's key for passive replay, because that's +what gets checked by the test suite. Luckily, the ``LLDB_RECORD_*`` macros +contained sufficient type information to derive the result type. + +Testing +------- + +Reproducers are tested in the following ways: + + - Unit tests to cover the reproducer infrastructure. There are tests for the + provider, loader and for the reproducer instrumentation. + - Feature specific end-to-end test cases in the ``test/Shell/Reproducer`` + directory. These tests serve as integration and regression tests for the + reproducers infrastructure, as well as doing some sanity checking for basic + debugger functionality. + - The API and shell tests can be run against a replayed reproducer. The + ``check-lldb-reproducers`` target will run the API and shell test suite + twice: first running the test normally while capturing a reproducer and then + a second time using the replayed session as the test input. For the shell + tests this use a little shim (``lldb-repro``) that uses the arguments and + current working directory to transparently generate or replay a reproducer. + For the API tests an extra argument with the reproducer path is passed to + ``dotest.py`` which initializes the debugger in the appropriate mode. + Certain tests do not fit this paradigm (for example test that check the + output of the binary being debugged) and are skipped by marking them as + unsupported by adding ``UNSUPPORTED: lldb-repro`` to the top of the shell + test or adding the ``skipIfReproducer`` decorator for the API tests. + +Additional testing is possible: + + - It's possible to unconditionally capture reproducers while running the + entire test suite by setting the ``LLDB_CAPTURE_REPRODUCER`` environment + variable. Assuming no bugs in reproducers, this can also help to reproduce + and investigate test failures. Knows Issues ------------ diff --git a/gnu/llvm/lldb/docs/resources/test.rst b/gnu/llvm/lldb/docs/resources/test.rst index 9966ad12eac..6f39a45d4b7 100644 --- a/gnu/llvm/lldb/docs/resources/test.rst +++ b/gnu/llvm/lldb/docs/resources/test.rst @@ -1,27 +1,203 @@ Testing ======= +.. contents:: + :local: + +Test Suite Structure +-------------------- + The LLDB test suite consists of three different kinds of test: -* Unit test. These are located under ``lldb/unittests`` and are written in C++ - using googletest. -* Integration tests that test the debugger through the SB API. These are - located under ``lldb/packages/Python/lldbsuite`` and are written in Python - using ``dotest`` (LLDB's custom testing framework on top of unittest2). -* Integration tests that test the debugger through the command line. These are - locarted under `lldb/tests/Shell` and are written in a shell-style format - using FileCheck to verify its output. +* **Unit tests**: written in C++ using the googletest unit testing library. +* **Shell tests**: Integration tests that test the debugger through the command + line. These tests interact with the debugger either through the command line + driver or through ``lldb-test`` which is a tool that exposes the internal + data structures in an easy-to-parse way for testing. Most people will know + these as *lit tests* in LLVM, although lit is the test driver and ShellTest + is the test format that uses ``RUN:`` lines. `FileCheck + `_ is used to verify + the output. +* **API tests**: Integration tests that interact with the debugger through the + SB API. These are written in Python and use LLDB's ``dotest.py`` testing + framework on top of Python's `unittest2 + `_. + +All three test suites use ``lit`` (`LLVM Integrated Tester +`_ ) as the test driver. The test +suites can be run as a whole or separately. + + +Unit Tests +`````````` + +Unit tests are located under ``lldb/unittests``. If it's possible to test +something in isolation or as a single unit, you should make it a unit test. + +Often you need instances of the core objects such as a debugger, target or +process, in order to test something meaningful. We already have a handful of +tests that have the necessary boiler plate, but this is something we could +abstract away and make it more user friendly. + +Shell Tests +``````````` + +Shell tests are located under ``lldb/test/Shell``. These tests are generally +built around checking the output of ``lldb`` (the command line driver) or +``lldb-test`` using ``FileCheck``. Shell tests are generally small and fast to +write because they require little boilerplate. + +``lldb-test`` is a relatively new addition to the test suite. It was the first +tool that was added that is designed for testing. Since then it has been +continuously extended with new subcommands, improving our test coverage. Among +other things you can use it to query lldb for symbol files, for object files +and breakpoints. + +Obviously shell tests are great for testing the command line driver itself or +the subcomponents already exposed by lldb-test. But when it comes to LLDB's +vast functionality, most things can be tested both through the driver as well +as the Python API. For example, to test setting a breakpoint, you could do it +from the command line driver with ``b main`` or you could use the SB API and do +something like ``target.BreakpointCreateByName`` [#]_. + +A good rule of thumb is to prefer shell tests when what is being tested is +relatively simple. Expressivity is limited compared to the API tests, which +means that you have to have a well-defined test scenario that you can easily +match with ``FileCheck``. + +Another thing to consider are the binaries being debugged, which we call +inferiors. For shell tests, they have to be relatively simple. The +``dotest.py`` test framework has extensive support for complex build scenarios +and different variants, which is described in more detail below, while shell +tests are limited to single lines of shell commands with compiler and linker +invocations. + +On the same topic, another interesting aspect of the shell tests is that there +you can often get away with a broken or incomplete binary, whereas the API +tests almost always require a fully functional executable. This enables testing +of (some) aspects of handling of binaries with non-native architectures or +operating systems. + +Finally, the shell tests always run in batch mode. You start with some input +and the test verifies the output. The debugger can be sensitive to its +environment, such as the the platform it runs on. It can be hard to express +that the same test might behave slightly differently on macOS and Linux. +Additionally, the debugger is an interactive tool, and the shell test provide +no good way of testing those interactive aspects, such as tab completion for +example. + +API Tests +````````` + +API tests are located under ``lldb/test/API``. They are run with the +``dotest.py``. Tests are written in Python and test binaries (inferiors) are +compiled with Make. The majority of API tests are end-to-end tests that compile +programs from source, run them, and debug the processes. + +As mentioned before, ``dotest.py`` is LLDB's testing framework. The +implementation is located under ``lldb/packages/Python/lldbsuite``. We have +several extensions and custom test primitives on top of what's offered by +`unittest2 `_. Those can be +found in +`lldbtest.py `_. + +Below is the directory layout of the `example API test +`_. +The test directory will always contain a python file, starting with ``Test``. +Most of the tests are structured as a binary being debugged, so there will be +one or more source files and a ``Makefile``. -All three test suites use the `LLVM Integrated Tester -`_ (lit) as their test driver. The -test suites can be run as a whole or separately. +:: -Many of the tests are accompanied by a C (C++, ObjC, etc.) source file. Each -test first compiles the source file and then uses LLDB to debug the resulting -executable. + sample_test + ├── Makefile + ├── TestSampleTest.py + └── main.c + +Let's start with the Python test file. Every test is its own class and can have +one or more test methods, that start with ``test_``. Many tests define +multiple test methods and share a bunch of common code. For example, for a +fictive test that makes sure we can set breakpoints we might have one test +method that ensures we can set a breakpoint by address, on that sets a +breakpoint by name and another that sets the same breakpoint by file and line +number. The setup, teardown and everything else other than setting the +breakpoint could be shared. + +Our testing framework also has a bunch of utilities that abstract common +operations, such as creating targets, setting breakpoints etc. When code is +shared across tests, we extract it into a utility in ``lldbutil``. It's always +worth taking a look at `lldbutil +`_ +to see if there's a utility to simplify some of the testing boiler plate. +Because we can't always audit every existing test, this is doubly true when +looking at an existing test for inspiration. + +It's possible to skip or `XFAIL +`_ +tests using decorators. You'll see them a lot. The debugger can be sensitive to +things like the architecture, the host and target platform, the compiler +version etc. LLDB comes with a range of predefined decorators for these +configurations. -.. contents:: - :local: +:: + + @expectedFailureAll(archs=["aarch64"], oslist=["linux"] + +Another great thing about these decorators is that they're very easy to extend, +it's even possible to define a function in a test case that determines whether +the test should be run or not. + +:: + + @expectedFailure(checking_function_name) + +In addition to providing a lot more flexibility when it comes to writing the +test, the API test also allow for much more complex scenarios when it comes to +building inferiors. Every test has its own ``Makefile``, most of them only a +few lines long. A shared ``Makefile`` (``Makefile.rules``) with about a +thousand lines of rules takes care of most if not all of the boiler plate, +while individual make files can be used to build more advanced tests. 
 + +Here's an example of a simple ``Makefile`` used by the example test. + +:: + + C_SOURCES := main.c + CFLAGS_EXTRAS := -std=c99 + + include Makefile.rules + +Finding the right variables to set can be tricky. You can always take a look at +`Makefile.rules `_ +but often it's easier to find an existing ``Makefile`` that does something +similar to what you want to do. + +Another thing this enables is having different variants for the same test +case. By default, we run every test for all 3 debug info formats, so once with +DWARF from the object files, once with gmodules and finally with a dSYM on +macOS or split DWARF (DWO) on Linux. But there are many more things we can test +that are orthogonal to the test itself. On GreenDragon we have a matrix bot +that runs the test suite under different configurations, with older host +compilers and different DWARF versions. + +As you can imagine, this quickly lead to combinatorial explosion in the number +of variants. It's very tempting to add more variants because it's an easy way +to increase test coverage. It doesn't scale. It's easy to set up, but increases +the runtime of the tests and has a large ongoing cost. + +The key take away is that the different variants don't obviate the need for +focused tests. So relying on it to test say DWARF5 is a really bad idea. +Instead you should write tests that check the specific DWARF5 feature, and have +the variant as a nice-to-have. + +In conclusion, you'll want to opt for an API test to test the API itself or +when you need the expressivity, either for the test case itself or for the +program being debugged. The fact that the API tests work with different +variants mean that more general tests should be API tests, so that they can be +run against the different variants. + +Running The Tests +----------------- .. note:: @@ -35,7 +211,7 @@ executable. This is due to lack of the ``$ORIGIN`` linker feature. Running the Full Test Suite ---------------------------- +``````````````````````````` The easiest way to run the LLDB test suite is to use the ``check-lldb`` build target. @@ -51,14 +227,14 @@ built with a custom version of clang, do: :: - > cmake -DLLDB_TEST_USER_ARGS="-A i386 -C /path/to/custom/clang" -G Ninja - > ninja check-lldb + $ cmake -DLLDB_TEST_USER_ARGS="-A i386 -C /path/to/custom/clang" -G Ninja + $ ninja check-lldb Note that multiple ``-A`` and ``-C`` flags can be specified to ``LLDB_TEST_USER_ARGS``. Running a Single Test Suite ---------------------------- +``````````````````````````` Each test suite can be run separately, similar to running the whole test suite with ``check-lldb``. @@ -74,7 +250,7 @@ tests don't actually live under ``lldb/test``, this convenience is only available for the shell tests. Running a Single Test ---------------------- +````````````````````` The recommended way to run a single test is by invoking the lit driver with a filter. This ensures that the test is run with the same configuration as when @@ -82,7 +258,7 @@ run as part of a test suite. :: - > ./bin/llvm-lit -sv lldb/test --filter + $ ./bin/llvm-lit -sv tools/lldb/test --filter Because lit automatically scans a directory for tests, it's also possible to @@ -90,7 +266,7 @@ pass a subdirectory to run a specific subset of the tests. :: - > ./bin/llvm-lit -sv tools/lldb/test/Shell/Commands/CommandScriptImmediateOutput + $ ./bin/llvm-lit -sv tools/lldb/test/Shell/Commands/CommandScriptImmediateOutput For the SB API tests it is possible to forward arguments to ``dotest.py`` by @@ -98,14 +274,14 @@ passing ``--param`` to lit and setting a value for ``dotest-args``. :: - > ./bin/llvm-lit -sv tools/lldb/test --param dotest-args='-C gcc' + $ ./bin/llvm-lit -sv tools/lldb/test --param dotest-args='-C gcc' Below is an overview of running individual test in the unit and API test suites without going through the lit driver. Running a Specific Test or Set of Tests: API Tests --------------------------------------------------- +`````````````````````````````````````````````````` In addition to running all the LLDB test suites with the ``check-lldb`` CMake target above, it is possible to run individual LLDB tests. If you have a CMake @@ -119,12 +295,12 @@ For example, to run the test cases defined in TestInferiorCrashing.py, run: :: - > ./bin/lldb-dotest -p TestInferiorCrashing.py + $ ./bin/lldb-dotest -p TestInferiorCrashing.py :: - > cd $lldb/test - > python dotest.py --executable -p TestInferiorCrashing.py ../packages/Python/lldbsuite/test + $ cd $lldb/test + $ python dotest.py --executable -p TestInferiorCrashing.py ../packages/Python/lldbsuite/test If the test is not specified by name (e.g. if you leave the ``-p`` argument off), all tests in that directory will be executed: @@ -132,21 +308,21 @@ off), all tests in that directory will be executed: :: - > ./bin/lldb-dotest functionalities/data-formatter + $ ./bin/lldb-dotest functionalities/data-formatter :: - > python dotest.py --executable functionalities/data-formatter + $ python dotest.py --executable functionalities/data-formatter Many more options that are available. To see a list of all of them, run: :: - > python dotest.py -h + $ python dotest.py -h Running a Specific Test or Set of Tests: Unit Tests ---------------------------------------------------- +``````````````````````````````````````````````````` The unit tests are simple executables, located in the build directory under ``tools/lldb/unittests``. @@ -154,18 +330,18 @@ To run them, just run the test binary, for example, to run all the Host tests: :: - > ./tools/lldb/unittests/Host/HostTests + $ ./tools/lldb/unittests/Host/HostTests To run a specific test, pass a filter, for example: :: - > ./tools/lldb/unittests/Host/HostTests --gtest_filter=SocketTest.DomainListenConnectAccept + $ ./tools/lldb/unittests/Host/HostTests --gtest_filter=SocketTest.DomainListenConnectAccept Running the Test Suite Remotely -------------------------------- +``````````````````````````````` Running the test-suite remotely is similar to the process of running a local test suite, but there are two things to have in mind: @@ -191,7 +367,7 @@ On non-Windows platforms, you can use the ``-d`` option to ``dotest.py`` which will cause the script to wait for a while until a debugger is attached. Debugging Test Failures on Windows ----------------------------------- +`````````````````````````````````` On Windows, it is strongly recommended to use Python Tools for Visual Studio for debugging test failures. It can seamlessly step between native and managed @@ -241,5 +417,4 @@ A quick guide to getting started with PTVS is as follows: --arch=i686 --executable D:/src/llvmbuild/ninja/bin/lldb.exe -s D:/src/llvmbuild/ninja/lldb-test-traces -u CXXFLAGS -u CFLAGS --enable-crash-dialog -C d:\src\llvmbuild\ninja_release\bin\clang.exe -p TestPaths.py D:\src\llvm\tools\lldb\packages\Python\lldbsuite\test --no-multiprocess - - +.. [#] `https://lldb.llvm.org/python_reference/lldb.SBTarget-class.html#BreakpointCreateByName `_ diff --git a/gnu/llvm/lldb/docs/status/releases.rst b/gnu/llvm/lldb/docs/status/releases.rst index de397f233c4..250d656c0b8 100644 --- a/gnu/llvm/lldb/docs/status/releases.rst +++ b/gnu/llvm/lldb/docs/status/releases.rst @@ -8,14 +8,7 @@ Nightly builds of LLDB are packaged and tested from trunk: Debian and Ubuntu: https://apt.llvm.org -The pkgsrc framework offers a package with recent LLDB in the wip repository: - -:: - - cd pkgsrc/wip/lldb-git - make install clean - Releases -------- -LLDB is packaged in most of the Debian & Ubuntu releases. +LLDB is packaged in most of the Debian & Ubuntu releases and in pkgsrc (NetBSD). diff --git a/gnu/llvm/lldb/docs/status/status.rst b/gnu/llvm/lldb/docs/status/status.rst index 9b4bd58bb61..5b7fd663577 100644 --- a/gnu/llvm/lldb/docs/status/status.rst +++ b/gnu/llvm/lldb/docs/status/status.rst @@ -1,6 +1,19 @@ Status ====== +FreeBSD +------- + +LLDB on FreeBSD lags behind the Linux implementation but is improving rapidly. +For more details, see the Features by OS section below. + +Linux +----- + +LLDB is improving on Linux. Linux is nearing feature completeness with Darwin +to debug x86_64, i386, ARM, AArch64, IBM POWER (ppc64), IBM Z (s390x), and +MIPS64 programs. For more details, see the Features by OS section below. + macOS ----- @@ -15,20 +28,10 @@ used from Python on the command line. This allows debug sessions to be scripted. It also allows powerful debugging actions to be created and attached to a variety of debugging workflows. -Linux ------ +NetBSD +------ -LLDB is improving on Linux. While the debugserver has not been ported (to -enable remote debugging) Linux is nearing feature completeness with Darwin to -debug x86_64 programs, and is partially working with i386 programs. ARM -architectures on Linux are untested. For more details, see the Features by OS -section below. - -FreeBSD -------- - -LLDB on FreeBSD lags behind the Linux implementation but is improving rapidly. -For more details, see the Features by OS section below. +LLDB is improving on NetBSD and reaching feature completeness with Linux. Windows ------- @@ -40,26 +43,26 @@ section below. Features Matrix --------------- -+--------------------------------+------------+-------------------------+------------+----------------------+ -| Feature | FreeBSD | Linux | macOS | Windows | -+================================+============+=========================+============+======================+ -| Backtracing | OK | OK | OK | OK | -+--------------------------------+------------+-------------------------+------------+----------------------+ -| Breakpoints | OK | OK | OK | OK | -+--------------------------------+------------+-------------------------+------------+----------------------+ -| C++11: | OK | OK | OK | Unknown | -+--------------------------------+------------+-------------------------+------------+----------------------+ -| Commandline lldb tool | OK | OK | OK | OK | -+--------------------------------+------------+-------------------------+------------+----------------------+ -| Core file debugging | OK (ELF) | OK (ELF) | OK (MachO) | OK (Minidump) | -+--------------------------------+------------+-------------------------+------------+----------------------+ -| Debugserver (remote debugging) | Not ported | Not ported | OK | Not ported | -+--------------------------------+------------+-------------------------+------------+----------------------+ -| Disassembly | OK | OK | OK | OK | -+--------------------------------+------------+-------------------------+------------+----------------------+ -| Expression evaluation | Unknown | Works with some bugs | OK | Works with some bugs | -+--------------------------------+------------+-------------------------+------------+----------------------+ -| JIT debugging | Unknown | Symbolic debugging only | Untested | No | -+--------------------------------+------------+-------------------------+------------+----------------------+ -| Objective-C 2.0: | Unknown | Not applicable | OK | Not applicable | -+--------------------------------+------------+-------------------------+------------+----------------------+ ++-----------------------+------------+-------------------------+-------------------+--------------------+----------------------+ +| Feature | FreeBSD | Linux | macOS | NetBSD | Windows | ++=======================+============+=========================+===================+====================+======================+ +| Backtracing | YES | YES | YES | YES | YES | ++-----------------------+------------+-------------------------+-------------------+--------------------+----------------------+ +| Breakpoints | YES | YES | YES | YES | YES | ++-----------------------+------------+-------------------------+-------------------+--------------------+----------------------+ +| C++11: | YES | YES | YES | YES | Unknown | ++-----------------------+------------+-------------------------+-------------------+--------------------+----------------------+ +| Commandline tool | YES | YES | YES | YES | YES | ++-----------------------+------------+-------------------------+-------------------+--------------------+----------------------+ +| Core file debugging | YES (ELF) | YES (ELF) | YES (MachO) | YES (ELF) | YES (Minidump) | ++-----------------------+------------+-------------------------+-------------------+--------------------+----------------------+ +| Remote debugging | NO | YES (lldb-server) | YES (debugserver) | YES (lldb-server) | NO | ++-----------------------+------------+-------------------------+-------------------+--------------------+----------------------+ +| Disassembly | YES | YES | YES | YES | YES | ++-----------------------+------------+-------------------------+-------------------+--------------------+----------------------+ +| Expression evaluation | Unknown | YES (known issues) | YES | YES (known issues) | YES (known issues) | ++-----------------------+------------+-------------------------+-------------------+--------------------+----------------------+ +| JIT debugging | Unknown | Symbolic debugging only | Untested | Work In Progress | NO | ++-----------------------+------------+-------------------------+-------------------+--------------------+----------------------+ +| Objective-C 2.0: | Unknown | N/A | YES | Unknown | N/A | ++-----------------------+------------+-------------------------+-------------------+--------------------+----------------------+ diff --git a/gnu/llvm/lldb/docs/use/formatting.rst b/gnu/llvm/lldb/docs/use/formatting.rst index 939c4e18f74..e2644d50217 100644 --- a/gnu/llvm/lldb/docs/use/formatting.rst +++ b/gnu/llvm/lldb/docs/use/formatting.rst @@ -134,7 +134,9 @@ A complete list of currently supported format string variables is listed below: +---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``thread.queue`` | The queue name of the thread if the target OS supports dispatch queues | +---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``thread.stop-reason`` | A textual reason each thread stopped | +| ``thread.stop-reason`` | A textual reason why the thread stopped. If the thread have a recognized frame, this displays its recognized stop reason. Otherwise, gets the stop info description. | ++---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``thread.stop-reason-raw`` | A textual reason why the thread stopped. Always returns stop info description. | +---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``thread.return-value`` | The return value of the latest step operation (currently only for step-out.) | +---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ diff --git a/gnu/llvm/lldb/docs/use/map.rst b/gnu/llvm/lldb/docs/use/map.rst index 3c6c6e6ffc6..0a785f2c0d9 100644 --- a/gnu/llvm/lldb/docs/use/map.rst +++ b/gnu/llvm/lldb/docs/use/map.rst @@ -609,6 +609,38 @@ Breakpoint Commands + + Disable a breakpoint. + + + + (gdb) disable 1 +
+ + + (lldb) breakpoint disable 1 +
+ (lldb) br dis 1 +
+ + + + + Enable a breakpoint. + + + + (gdb) enable 1 +
+ + + (lldb) breakpoint enable 1 +
+ (lldb) br en 1 +
+ + + diff --git a/gnu/llvm/lldb/docs/use/symbols.rst b/gnu/llvm/lldb/docs/use/symbols.rst index fe79782959a..757d165b9e2 100644 --- a/gnu/llvm/lldb/docs/use/symbols.rst +++ b/gnu/llvm/lldb/docs/use/symbols.rst @@ -267,7 +267,7 @@ contains the DWARF. Whenever DebugSymbols.framework is asked to lookup a dSYM file, it will first look in any file mapped UUID directories for a quick match if the defaults are appropriately set. -For example, if we take the sample UUID plist inforamtion from above, we can +For example, if we take the sample UUID plist information from above, we can create a File Mapped UUID directory cache in **~/Library/SymbolCache/dsyms/uuids**. We can easily see how things are laid out: diff --git a/gnu/llvm/lldb/docs/use/variable.rst b/gnu/llvm/lldb/docs/use/variable.rst index f3bde2de414..5b1fef7b06c 100644 --- a/gnu/llvm/lldb/docs/use/variable.rst +++ b/gnu/llvm/lldb/docs/use/variable.rst @@ -366,12 +366,13 @@ simply say ${var.z} because that symbol refers to the pointer z. In order to dereference it and get the pointed value, you should say ``${*var.z}``. The ``${*var`` tells LLDB to get the object that the expression paths leads to, and then dereference it. In this example is it equivalent to ``*(bObject.z)`` in -C/C++ syntax. Because . and -> operators can both be used, there is no need to -have dereferences in the middle of an expression path (e.g. you do not need to -type ``${*(var.x).x}``) to read A::x as contained in ``*(B::x)``. To achieve -that effect you can simply write ``${var.x->x}``, or even ``${var.x.x}``. The -``*`` operator only binds to the result of the whole expression path, rather -than piecewise, and there is no way to use parentheses to change that behavior. +C/C++ syntax. Because ``.`` and ``->`` operators can both be used, there is no +need to have dereferences in the middle of an expression path (e.g. you do not +need to type ``${*(var.x).x}``) to read A::x as contained in ``*(B::x)``. To +achieve that effect you can simply write ``${var.x->x}``, or even +``${var.x.x}``. The ``*`` operator only binds to the result of the whole +expression path, rather than piecewise, and there is no way to use parentheses +to change that behavior. Of course, a summary string can contain more than one ${var specifier, and can use ``${var`` and ``${*var`` specifiers together. @@ -573,7 +574,7 @@ the pointer value. However, because pointers have no notion of their size, the empty brackets [] operator does not work, and you must explicitly provide higher and lower bounds. -In general, LLDB needs the square brackets operator [] in order to handle +In general, LLDB needs the square brackets ``operator []`` in order to handle arrays and pointers correctly, and for pointers it also needs a range. However, a few special cases are defined to make your life easier: @@ -650,7 +651,7 @@ class, as shown in this example: (lldb) type summary add -P Rectangle Enter your Python command(s). Type 'DONE' to end. - def function (valobj,internal_dict): + def function (valobj,internal_dict,options): height_val = valobj.GetChildMemberWithName('height') width_val = valobj.GetChildMemberWithName('width') height = height_val.GetValueAsUnsigned(0) @@ -697,6 +698,12 @@ that (yet) via this method call, and you must use ``GetChildAtIndex()`` querying it for the array items one by one. Also, handling custom formats is something you have to deal with on your own. +``options`` Python summary formatters can optionally define this +third argument, which is an object of type ``lldb.SBTypeSummaryOptions``, +allowing for a few customizations of the result. The decision to +adopt or not this third argument - and the meaning of options +thereof - is up to the individual formatter's writer. + Other than interactively typing a Python script there are two other ways for you to input a Python script as a summary: @@ -715,14 +722,6 @@ you to input a Python script as a summary: LLDB will emit a warning if it is unable to find the function you passed, but will still register the binding. -Starting in SVN r222593, Python summary formatters can optionally define a -third argument: options - -This is an object of type ``lldb.SBTypeSummaryOptions`` that can be passed into -the formatter, allowing for a few customizations of the result. The decision to -adopt or not this third argument - and the meaning of options thereof - is -within the individual formatters' writer. - Regular Expression Typenames ---------------------------- @@ -845,7 +844,7 @@ adheres to a given interface (the word is italicized because Python has no explicit notion of interface, by that word we mean a given set of methods must be implemented by the Python class): -:: +.. code-block:: python class SyntheticChildrenProvider: def __init__(self, valobj, internal_dict): @@ -882,9 +881,30 @@ As a shortcut for this, you can inherit from lldb.SBSyntheticValueProvider, and just define get_value as other methods are defaulted in the superclass as returning default no-children responses. -If a synthetic child provider supplies a special child named $$dereference$$ -then it will be used when evaluating opertaor* and operator-> in the frame -variable command and related SB API functions. +If a synthetic child provider supplies a special child named +``$$dereference$$`` then it will be used when evaluating ``operator *`` and +``operator ->`` in the frame variable command and related SB API +functions. It is possible to declare this synthetic child without +including it in the range of children displayed by LLDB. For example, +this subset of a synthetic children provider class would allow the +synthetic value to be dereferenced without actually showing any +synthtic children in the UI: + +.. code-block:: python + + class SyntheticChildrenProvider: + [...] + def num_children(self): + return 0 + def get_child_index(self, name): + if name == '$$dereference$$': + return 0 + return -1 + def get_child_at_index(self, index): + if index == 0: + return + return None + For examples of how synthetic children are created, you are encouraged to look at examples/synthetic in the LLDB trunk. Please, be aware that the code in @@ -960,10 +980,10 @@ expression: Error [IRForTarget]: Call to a function '_ZNSt33vector >ixEm' that is not present in the target error: Couldn't convert the expression to DWARF -The reason for this is that classes might have an overloaded operator [], or -other special provisions and the expression command chooses to ignore synthetic -children in the interest of equivalency with code you asked to have compiled -from source. +The reason for this is that classes might have an overloaded ``operator []``, +or other special provisions and the expression command chooses to ignore +synthetic children in the interest of equivalency with code you asked to have +compiled from source. Filters ------- diff --git a/gnu/llvm/lldb/examples/darwin/heap_find/heap.py b/gnu/llvm/lldb/examples/darwin/heap_find/heap.py index 0c8744ff15f..a8bc377ffe4 100644 --- a/gnu/llvm/lldb/examples/darwin/heap_find/heap.py +++ b/gnu/llvm/lldb/examples/darwin/heap_find/heap.py @@ -226,7 +226,7 @@ def get_member_types_for_offset(value_type, offset, member_list): def append_regex_callback(option, opt, value, parser): try: ivar_regex = re.compile(value) - parser.values.ivar_regex_blacklist.append(ivar_regex) + parser.values.ivar_regex_exclusions.append(ivar_regex) except: print('error: an exception was thrown when compiling the ivar regular expression for "%s"' % value) @@ -287,7 +287,7 @@ def add_common_options(parser): type='string', action='callback', callback=append_regex_callback, - dest='ivar_regex_blacklist', + dest='ivar_regex_exclusions', default=[], help='specify one or more regular expressions used to backlist any matches that are in ivars') parser.add_option( @@ -773,8 +773,8 @@ def display_match_results( member_path += '.' member_path += member_name if member_path: - if options.ivar_regex_blacklist: - for ivar_regex in options.ivar_regex_blacklist: + if options.ivar_regex_exclusions: + for ivar_regex in options.ivar_regex_exclusions: if ivar_regex.match( member_path): print_entry = False diff --git a/gnu/llvm/lldb/examples/interposing/darwin/fd_interposing/FDInterposing.cpp b/gnu/llvm/lldb/examples/interposing/darwin/fd_interposing/FDInterposing.cpp index e3f429cdf30..de0be331cc5 100644 --- a/gnu/llvm/lldb/examples/interposing/darwin/fd_interposing/FDInterposing.cpp +++ b/gnu/llvm/lldb/examples/interposing/darwin/fd_interposing/FDInterposing.cpp @@ -68,13 +68,6 @@ #include #include -/// \def DISALLOW_COPY_AND_ASSIGN(TypeName) -/// Macro definition for easily disallowing copy constructor and -/// assignment operators in C++ classes. -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName &); \ - const TypeName &operator=(const TypeName &) - extern "C" { int accept$NOCANCEL(int, struct sockaddr *__restrict, socklen_t *__restrict); int close$NOCANCEL(int); @@ -135,7 +128,8 @@ protected: char *m_str; private: - DISALLOW_COPY_AND_ASSIGN(String); + String(const String &) = delete; + const String &operator=(const String &) = delete; }; // Type definitions @@ -147,7 +141,7 @@ typedef std::tr1::shared_ptr StringSP; // FDEvent // -// A class that describes a file desciptor event. +// A class that describes a file descriptor event. // // File descriptor events fall into one of two categories: create events // and delete events. @@ -185,7 +179,7 @@ private: // The frames for the stack backtrace for this event Frames m_frames; // If this is a file descriptor delete event, this might contain - // the correspoding file descriptor create event + // the corresponding file descriptor create event FDEventSP m_create_event_sp; // The file descriptor for this event int m_fd; @@ -232,18 +226,18 @@ typedef std::map FDEventMap; // event is detected, the open event will be removed and placed into // the close event so if something tries to double close a file // descriptor we can show the previous close event and the file -// desctiptor event that created it. When a new file descriptor create +// descriptor event that created it. When a new file descriptor create // event comes in, we will remove the previous one for that file -// desctiptor unless the environment variable +// descriptor unless the environment variable // "FileDescriptorStackLoggingNoCompact" -// is set. The file desctiptor history can be accessed using the +// is set. The file descriptor history can be accessed using the // get_fd_history() function. static FDEventMap g_fd_event_map; // A mutex to protect access to our data structures in g_fd_event_map // and also our logging messages static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; // Log all file descriptor create and close events by default. Only log -// warnings and erros if the "FileDescriptorMinimalLogging" environment +// warnings and errors if the "FileDescriptorMinimalLogging" environment // variable is set. static int g_log_all_calls = 1; // We compact the file descriptor events by default. Set the environment @@ -498,7 +492,7 @@ void save_backtrace(int fd, int err, const StringSP &string_sp, fd); } else if (g_compact) { // We are compacting so we remove previous create event - // when we get the correspinding delete event + // when we get the corresponding delete event event_array.pop_back(); } } else { @@ -518,7 +512,7 @@ void save_backtrace(int fd, int err, const StringSP &string_sp, // that this close if for... fd_event_sp->SetCreateEvent(event_array.back()); // We are compacting so we remove previous create event - // when we get the correspinding delete event + // when we get the corresponding delete event event_array.pop_back(); } } diff --git a/gnu/llvm/lldb/examples/python/crashlog.py b/gnu/llvm/lldb/examples/python/crashlog.py index b7b62acc60e..1c1602b0131 100755 --- a/gnu/llvm/lldb/examples/python/crashlog.py +++ b/gnu/llvm/lldb/examples/python/crashlog.py @@ -791,11 +791,11 @@ def save_crashlog(debugger, command, exe_ctx, result, dict): block_range = block.range[frame.addr] if block_range: block_start_addr = block_range[0] - frame_offset = frame_pc - block_start_addr.load_addr + frame_offset = frame_pc - block_start_addr.GetLoadAddress(target) else: - frame_offset = frame_pc - frame.function.addr.load_addr + frame_offset = frame_pc - frame.function.addr.GetLoadAddress(target) elif frame.symbol: - frame_offset = frame_pc - frame.symbol.addr.load_addr + frame_offset = frame_pc - frame.symbol.addr.GetLoadAddress(target) out_file.write( '%-3u %-32s 0x%16.16x %s' % (frame_idx, frame.module.file.basename, frame_pc, frame.name)) diff --git a/gnu/llvm/lldb/examples/python/gdbremote.py b/gnu/llvm/lldb/examples/python/gdbremote.py index dcacbfccdaf..52601c09d3b 100755 --- a/gnu/llvm/lldb/examples/python/gdbremote.py +++ b/gnu/llvm/lldb/examples/python/gdbremote.py @@ -16,6 +16,7 @@ # available. #---------------------------------------------------------------------- +from __future__ import print_function import binascii import subprocess import json @@ -324,10 +325,10 @@ def is_hex_byte(str): def get_hex_string_if_all_printable(str): try: - s = binascii.unhexlify(str) + s = binascii.unhexlify(str).decode() if all(c in string.printable for c in s): return s - except TypeError: + except (TypeError, binascii.Error, UnicodeDecodeError): pass return None @@ -548,10 +549,10 @@ class Packet: def get_key_value_pairs(self): kvp = list() if ';' in self.str: - key_value_pairs = string.split(self.str, ';') + key_value_pairs = self.str.split(';') for key_value_pair in key_value_pairs: if len(key_value_pair): - kvp.append(string.split(key_value_pair, ':')) + kvp.append(key_value_pair.split(':', 1)) return kvp def split(self, ch): @@ -678,7 +679,7 @@ def cmd_qXfer(options, cmd, args): def rsp_qXfer(options, cmd, cmd_args, rsp): - data = string.split(cmd_args, ':') + data = cmd_args.split(':') if data[0] == 'features': if data[1] == 'read': filename, extension = os.path.splitext(data[2]) @@ -825,8 +826,8 @@ def cmd_vCont(options, cmd, args): else: got_other_threads = 0 s = '' - for thread_action in string.split(args[1:], ';'): - (short_action, thread) = string.split(thread_action, ':') + for thread_action in args[1:].split(';'): + (short_action, thread) = thread_action.split(':', 1) tid = int(thread, 16) if short_action == 'c': action = 'continue' @@ -856,7 +857,7 @@ def rsp_vCont(options, cmd, cmd_args, rsp): if cmd_args == '?': # Skip the leading 'vCont;' rsp = rsp[6:] - modes = string.split(rsp, ';') + modes = rsp.split(';') s = "%s: supported extended continue modes include: " % (cmd) for i, mode in enumerate(modes): diff --git a/gnu/llvm/lldb/examples/python/mach_o.py b/gnu/llvm/lldb/examples/python/mach_o.py index eb97fe57cfc..1780bc3e320 100755 --- a/gnu/llvm/lldb/examples/python/mach_o.py +++ b/gnu/llvm/lldb/examples/python/mach_o.py @@ -965,7 +965,7 @@ class Mach: result = False print('error: section %s is missing in %s' % (lhs_section.sectname, rhs.path)) else: - print('error: comaparing a %s mach-o file with a %s mach-o file is not supported' % (self.type, rhs.type)) + print('error: comparing a %s mach-o file with a %s mach-o file is not supported' % (self.type, rhs.type)) result = False if not result: print('error: mach files differ') diff --git a/gnu/llvm/lldb/include/lldb/API/LLDB.h b/gnu/llvm/lldb/include/lldb/API/LLDB.h index 75e2d70c0c3..83c38d3b616 100644 --- a/gnu/llvm/lldb/include/lldb/API/LLDB.h +++ b/gnu/llvm/lldb/include/lldb/API/LLDB.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_LLDB_h_ -#define LLDB_LLDB_h_ +#ifndef LLDB_API_LLDB_H +#define LLDB_API_LLDB_H #include "lldb/API/SBAddress.h" #include "lldb/API/SBAttachInfo.h" @@ -24,6 +24,7 @@ #include "lldb/API/SBDebugger.h" #include "lldb/API/SBDeclaration.h" #include "lldb/API/SBDefines.h" +#include "lldb/API/SBEnvironment.h" #include "lldb/API/SBError.h" #include "lldb/API/SBEvent.h" #include "lldb/API/SBExecutionContext.h" @@ -78,4 +79,4 @@ #include "lldb/API/SBVariablesOptions.h" #include "lldb/API/SBWatchpoint.h" -#endif // LLDB_LLDB_h_ +#endif // LLDB_API_LLDB_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBAddress.h b/gnu/llvm/lldb/include/lldb/API/SBAddress.h index 2874a3602af..cf7555dc2ee 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBAddress.h +++ b/gnu/llvm/lldb/include/lldb/API/SBAddress.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBAddress_h_ -#define LLDB_SBAddress_h_ +#ifndef LLDB_API_SBADDRESS_H +#define LLDB_API_SBADDRESS_H #include "lldb/API/SBDefines.h" #include "lldb/API/SBModule.h" @@ -127,4 +127,4 @@ bool LLDB_API operator==(const SBAddress &lhs, const SBAddress &rhs); } // namespace lldb -#endif // LLDB_SBAddress_h_ +#endif // LLDB_API_SBADDRESS_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBAttachInfo.h b/gnu/llvm/lldb/include/lldb/API/SBAttachInfo.h index 3c20a08cb4a..9b211d0f74b 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBAttachInfo.h +++ b/gnu/llvm/lldb/include/lldb/API/SBAttachInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBAttachInfo_h_ -#define LLDB_SBAttachInfo_h_ +#ifndef LLDB_API_SBATTACHINFO_H +#define LLDB_API_SBATTACHINFO_H #include "lldb/API/SBDefines.h" @@ -174,4 +174,4 @@ protected: } // namespace lldb -#endif // LLDB_SBAttachInfo_h_ +#endif // LLDB_API_SBATTACHINFO_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBBlock.h b/gnu/llvm/lldb/include/lldb/API/SBBlock.h index 0ca92ff0c6a..be1ae18e9db 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBBlock.h +++ b/gnu/llvm/lldb/include/lldb/API/SBBlock.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBBlock_h_ -#define LLDB_SBBlock_h_ +#ifndef LLDB_API_SBBLOCK_H +#define LLDB_API_SBBLOCK_H #include "lldb/API/SBDefines.h" #include "lldb/API/SBFrame.h" @@ -92,4 +92,4 @@ private: } // namespace lldb -#endif // LLDB_SBBlock_h_ +#endif // LLDB_API_SBBLOCK_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBBreakpoint.h b/gnu/llvm/lldb/include/lldb/API/SBBreakpoint.h index a5ce91d9508..c9a52fcacf1 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBBreakpoint.h +++ b/gnu/llvm/lldb/include/lldb/API/SBBreakpoint.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBBreakpoint_h_ -#define LLDB_SBBreakpoint_h_ +#ifndef LLDB_API_SBBREAKPOINT_H +#define LLDB_API_SBBREAKPOINT_H #include "lldb/API/SBDefines.h" @@ -105,6 +105,8 @@ public: bool AddName(const char *new_name); + SBError AddNameWithErrorHandling(const char *new_name); + void RemoveName(const char *name_to_remove); bool MatchesName(const char *name); @@ -181,4 +183,4 @@ private: } // namespace lldb -#endif // LLDB_SBBreakpoint_h_ +#endif // LLDB_API_SBBREAKPOINT_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBBreakpointLocation.h b/gnu/llvm/lldb/include/lldb/API/SBBreakpointLocation.h index a9e2ef1dd1b..a906727f938 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBBreakpointLocation.h +++ b/gnu/llvm/lldb/include/lldb/API/SBBreakpointLocation.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBBreakpointLocation_h_ -#define LLDB_SBBreakpointLocation_h_ +#ifndef LLDB_API_SBBREAKPOINTLOCATION_H +#define LLDB_API_SBBREAKPOINTLOCATION_H #include "lldb/API/SBBreakpoint.h" #include "lldb/API/SBDefines.h" @@ -100,4 +100,4 @@ private: } // namespace lldb -#endif // LLDB_SBBreakpointLocation_h_ +#endif // LLDB_API_SBBREAKPOINTLOCATION_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBBreakpointName.h b/gnu/llvm/lldb/include/lldb/API/SBBreakpointName.h index 3a5f1acf3e4..8dd2c4e5ef3 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBBreakpointName.h +++ b/gnu/llvm/lldb/include/lldb/API/SBBreakpointName.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBBreakpointName_h_ -#define LLDB_SBBreakpointName_h_ +#ifndef LLDB_API_SBBREAKPOINTNAME_H +#define LLDB_API_SBBREAKPOINTNAME_H #include "lldb/API/SBDefines.h" @@ -119,4 +119,4 @@ private: } // namespace lldb -#endif // LLDB_SBBreakpointName_h_ +#endif // LLDB_API_SBBREAKPOINTNAME_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBBroadcaster.h b/gnu/llvm/lldb/include/lldb/API/SBBroadcaster.h index fc5e8880e9f..69a516a8bfb 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBBroadcaster.h +++ b/gnu/llvm/lldb/include/lldb/API/SBBroadcaster.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBBroadcaster_h_ -#define LLDB_SBBroadcaster_h_ +#ifndef LLDB_API_SBBROADCASTER_H +#define LLDB_API_SBBROADCASTER_H #include "lldb/API/SBDefines.h" @@ -81,4 +81,4 @@ private: } // namespace lldb -#endif // LLDB_SBBroadcaster_h_ +#endif // LLDB_API_SBBROADCASTER_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBCommandInterpreter.h b/gnu/llvm/lldb/include/lldb/API/SBCommandInterpreter.h index 6c80e8eb26d..a70e060bec9 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBCommandInterpreter.h +++ b/gnu/llvm/lldb/include/lldb/API/SBCommandInterpreter.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBCommandInterpreter_h_ -#define LLDB_SBCommandInterpreter_h_ +#ifndef LLDB_API_SBCOMMANDINTERPRETER_H +#define LLDB_API_SBCOMMANDINTERPRETER_H #include @@ -16,52 +16,6 @@ namespace lldb { -class LLDB_API SBCommandInterpreterRunOptions { - friend class SBDebugger; - friend class SBCommandInterpreter; - -public: - SBCommandInterpreterRunOptions(); - ~SBCommandInterpreterRunOptions(); - - bool GetStopOnContinue() const; - - void SetStopOnContinue(bool); - - bool GetStopOnError() const; - - void SetStopOnError(bool); - - bool GetStopOnCrash() const; - - void SetStopOnCrash(bool); - - bool GetEchoCommands() const; - - void SetEchoCommands(bool); - - bool GetEchoCommentCommands() const; - - void SetEchoCommentCommands(bool echo); - - bool GetPrintResults() const; - - void SetPrintResults(bool); - - bool GetAddToHistory() const; - - void SetAddToHistory(bool); - -private: - lldb_private::CommandInterpreterRunOptions *get() const; - - lldb_private::CommandInterpreterRunOptions &ref() const; - - // This is set in the constructor and will always be valid. - mutable std::unique_ptr - m_opaque_up; -}; - class SBCommandInterpreter { public: enum { @@ -111,14 +65,86 @@ public: lldb::SBCommand AddMultiwordCommand(const char *name, const char *help); + /// Add a new command to the lldb::CommandInterpreter. + /// + /// The new command won't support autorepeat. If you need this functionality, + /// use the override of this function that accepts the \a auto_repeat_command + /// parameter. + /// + /// \param[in] name + /// The name of the command. + /// + /// \param[in] impl + /// The handler of this command. + /// + /// \param[in] help + /// The general description to show as part of the help message of this + /// command. + /// + /// \return + /// A lldb::SBCommand representing the newly created command. lldb::SBCommand AddCommand(const char *name, lldb::SBCommandPluginInterface *impl, const char *help); + /// Add a new command to the lldb::CommandInterpreter. + /// + /// The new command won't support autorepeat. If you need this functionality, + /// use the override of this function that accepts the \a auto_repeat_command + /// parameter. + /// + /// \param[in] name + /// The name of the command. + /// + /// \param[in] impl + /// The handler of this command. + /// + /// \param[in] help + /// The general description to show as part of the help message of this + /// command. + /// + /// \param[in] syntax + /// The syntax to show as part of the help message of this command. This + /// could include a description of the different arguments and flags this + /// command accepts. + /// + /// \return + /// A lldb::SBCommand representing the newly created command. lldb::SBCommand AddCommand(const char *name, lldb::SBCommandPluginInterface *impl, const char *help, const char *syntax); + /// Add a new command to the lldb::CommandInterpreter. + /// + /// \param[in] name + /// The name of the command. + /// + /// \param[in] impl + /// The handler of this command. + /// + /// \param[in] help + /// The general description to show as part of the help message of this + /// command. + /// + /// \param[in] syntax + /// The syntax to show as part of the help message of this command. This + /// could include a description of the different arguments and flags this + /// command accepts. + /// + /// \param[in] auto_repeat_command + /// Autorepeating is triggered when the user presses Enter successively + /// after executing a command. If \b nullptr is provided, the previous + /// exact command will be repeated. If \b "" is provided, autorepeating + /// is disabled. Otherwise, the provided string is used as a repeat + /// command. + /// + /// \return + /// A lldb::SBCommand representing the newly created command. + lldb::SBCommand AddCommand(const char *name, + lldb::SBCommandPluginInterface *impl, + const char *help, const char *syntax, + const char *auto_repeat_command); + void SourceInitFileInHomeDirectory(lldb::SBCommandReturnObject &result); void @@ -283,14 +309,90 @@ public: lldb::SBCommand AddMultiwordCommand(const char *name, const char *help = nullptr); + /// Add a new subcommand to the lldb::SBCommand. + /// + /// The new command won't support autorepeat. If you need this functionality, + /// use the override of this function that accepts the \a auto_repeat + /// parameter. + /// + /// \param[in] name + /// The name of the command. + /// + /// \param[in] impl + /// The handler of this command. + /// + /// \param[in] help + /// The general description to show as part of the help message of this + /// command. + /// + /// \return + /// A lldb::SBCommand representing the newly created command. lldb::SBCommand AddCommand(const char *name, lldb::SBCommandPluginInterface *impl, const char *help = nullptr); + /// Add a new subcommand to the lldb::SBCommand. + /// + /// The new command won't support autorepeat. If you need this functionality, + /// use the override of this function that accepts the \a auto_repeat_command + /// parameter. + /// + /// \param[in] name + /// The name of the command. + /// + /// \param[in] impl + /// The handler of this command. + /// + /// \param[in] help + /// The general description to show as part of the help message of this + /// command. + /// + /// \param[in] syntax + /// The syntax to show as part of the help message of this command. This + /// could include a description of the different arguments and flags this + /// command accepts. + /// + /// \return + /// A lldb::SBCommand representing the newly created command. lldb::SBCommand AddCommand(const char *name, lldb::SBCommandPluginInterface *impl, const char *help, const char *syntax); + /// Add a new subcommand to the lldb::SBCommand. + /// + /// The new command won't support autorepeat. If you need this functionality, + /// use the override of this function that accepts the \a auto_repeat_command + /// parameter. + /// + /// \param[in] name + /// The name of the command. + /// + /// \param[in] impl + /// The handler of this command. + /// + /// \param[in] help + /// The general description to show as part of the help message of this + /// command. + /// + /// \param[in] syntax + /// The syntax to show as part of the help message of this command. This + /// could include a description of the different arguments and flags this + /// command accepts. + /// + /// \param[in] auto_repeat_command + /// Autorepeating is triggered when the user presses Enter successively + /// after executing a command. If \b nullptr is provided, the previous + /// exact command will be repeated. If \b "" is provided, autorepeating + /// is disabled. Otherwise, the provided string is used as a repeat + /// command. + /// + /// \return + /// A lldb::SBCommand representing the newly created command. + lldb::SBCommand AddCommand(const char *name, + lldb::SBCommandPluginInterface *impl, + const char *help, const char *syntax, + const char *auto_repeat_command); + private: friend class SBDebugger; friend class SBCommandInterpreter; @@ -302,4 +404,4 @@ private: } // namespace lldb -#endif // LLDB_SBCommandInterpreter_h_ +#endif // LLDB_API_SBCOMMANDINTERPRETER_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h b/gnu/llvm/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h new file mode 100644 index 00000000000..82d6feedc02 --- /dev/null +++ b/gnu/llvm/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h @@ -0,0 +1,102 @@ +//===-- SBCommandInterpreterRunOptions.h ------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_API_SBCOMMANDINTERPRETERRUNOPTIONS_H +#define LLDB_API_SBCOMMANDINTERPRETERRUNOPTIONS_H + +#include + +#include "lldb/API/SBDefines.h" + +namespace lldb_private { +class CommandInterpreterRunOptions; +class CommandInterpreterRunResult; +} // namespace lldb_private + +namespace lldb { + +class LLDB_API SBCommandInterpreterRunOptions { + friend class SBDebugger; + friend class SBCommandInterpreter; + +public: + SBCommandInterpreterRunOptions(); + ~SBCommandInterpreterRunOptions(); + + bool GetStopOnContinue() const; + + void SetStopOnContinue(bool); + + bool GetStopOnError() const; + + void SetStopOnError(bool); + + bool GetStopOnCrash() const; + + void SetStopOnCrash(bool); + + bool GetEchoCommands() const; + + void SetEchoCommands(bool); + + bool GetEchoCommentCommands() const; + + void SetEchoCommentCommands(bool echo); + + bool GetPrintResults() const; + + void SetPrintResults(bool); + + bool GetAddToHistory() const; + + void SetAddToHistory(bool); + + bool GetAutoHandleEvents() const; + + void SetAutoHandleEvents(bool); + + bool GetSpawnThread() const; + + void SetSpawnThread(bool); + +private: + lldb_private::CommandInterpreterRunOptions *get() const; + + lldb_private::CommandInterpreterRunOptions &ref() const; + + // This is set in the constructor and will always be valid. + mutable std::unique_ptr + m_opaque_up; +}; + +class LLDB_API SBCommandInterpreterRunResult { + friend class SBDebugger; + friend class SBCommandInterpreter; + +public: + SBCommandInterpreterRunResult(); + SBCommandInterpreterRunResult(const SBCommandInterpreterRunResult &rhs); + ~SBCommandInterpreterRunResult(); + + SBCommandInterpreterRunResult & + operator=(const SBCommandInterpreterRunResult &rhs); + + int GetNumberOfErrors() const; + lldb::CommandInterpreterResult GetResult() const; + +private: + SBCommandInterpreterRunResult( + const lldb_private::CommandInterpreterRunResult &rhs); + + // This is set in the constructor and will always be valid. + std::unique_ptr m_opaque_up; +}; + +} // namespace lldb + +#endif // LLDB_API_SBCOMMANDINTERPRETERRUNOPTIONS_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBCommandReturnObject.h b/gnu/llvm/lldb/include/lldb/API/SBCommandReturnObject.h index e3fbacf85af..4ee296eb179 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBCommandReturnObject.h +++ b/gnu/llvm/lldb/include/lldb/API/SBCommandReturnObject.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBCommandReturnObject_h_ -#define LLDB_SBCommandReturnObject_h_ +#ifndef LLDB_API_SBCOMMANDRETURNOBJECT_H +#define LLDB_API_SBCOMMANDRETURNOBJECT_H #include @@ -124,4 +124,4 @@ private: } // namespace lldb -#endif // LLDB_SBCommandReturnObject_h_ +#endif // LLDB_API_SBCOMMANDRETURNOBJECT_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBCommunication.h b/gnu/llvm/lldb/include/lldb/API/SBCommunication.h index 5b803fc6017..84c341c0dfe 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBCommunication.h +++ b/gnu/llvm/lldb/include/lldb/API/SBCommunication.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBCommunication_h_ -#define LLDB_SBCommunication_h_ +#ifndef LLDB_API_SBCOMMUNICATION_H +#define LLDB_API_SBCOMMUNICATION_H #include "lldb/API/SBDefines.h" #include "lldb/API/SBError.h" @@ -72,7 +72,8 @@ public: void *callback_baton); private: - DISALLOW_COPY_AND_ASSIGN(SBCommunication); + SBCommunication(const SBCommunication &) = delete; + const SBCommunication &operator=(const SBCommunication &) = delete; lldb_private::Communication *m_opaque; bool m_opaque_owned; @@ -80,4 +81,4 @@ private: } // namespace lldb -#endif // LLDB_SBCommunication_h_ +#endif // LLDB_API_SBCOMMUNICATION_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBCompileUnit.h b/gnu/llvm/lldb/include/lldb/API/SBCompileUnit.h index b6b138207d6..0c05ef44e31 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBCompileUnit.h +++ b/gnu/llvm/lldb/include/lldb/API/SBCompileUnit.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBCompileUnit_h_ -#define LLDB_SBCompileUnit_h_ +#ifndef LLDB_API_SBCOMPILEUNIT_H +#define LLDB_API_SBCOMPILEUNIT_H #include "lldb/API/SBDefines.h" #include "lldb/API/SBFileSpec.h" @@ -92,4 +92,4 @@ private: } // namespace lldb -#endif // LLDB_SBCompileUnit_h_ +#endif // LLDB_API_SBCOMPILEUNIT_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBData.h b/gnu/llvm/lldb/include/lldb/API/SBData.h index 886fe829a46..95c8086d5d4 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBData.h +++ b/gnu/llvm/lldb/include/lldb/API/SBData.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBData_h_ -#define LLDB_SBData_h_ +#ifndef LLDB_API_SBDATA_H +#define LLDB_API_SBDATA_H #include "lldb/API/SBDefines.h" @@ -152,4 +152,4 @@ private: } // namespace lldb -#endif // LLDB_SBData_h_ +#endif // LLDB_API_SBDATA_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBDebugger.h b/gnu/llvm/lldb/include/lldb/API/SBDebugger.h index 580f6281fbb..b3bfa230139 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBDebugger.h +++ b/gnu/llvm/lldb/include/lldb/API/SBDebugger.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBDebugger_h_ -#define LLDB_SBDebugger_h_ +#ifndef LLDB_API_SBDEBUGGER_H +#define LLDB_API_SBDEBUGGER_H #include @@ -199,6 +199,10 @@ public: bool GetUseColor() const; + bool SetUseSourceCache(bool use_source_cache); + + bool GetUseSourceCache() const; + static bool GetDefaultArchitecture(char *arch_name, size_t arch_name_len); static bool SetDefaultArchitecture(const char *arch_name); @@ -286,13 +290,50 @@ public: SBTypeSynthetic GetSyntheticForType(SBTypeNameSpecifier); + /// Run the command interpreter. + /// + /// \param[in] auto_handle_events + /// If true, automatically handle resulting events. This takes precedence + /// and overrides the corresponding option in + /// SBCommandInterpreterRunOptions. + /// + /// \param[in] spawn_thread + /// If true, start a new thread for IO handling. This takes precedence + /// and overrides the corresponding option in + /// SBCommandInterpreterRunOptions. void RunCommandInterpreter(bool auto_handle_events, bool spawn_thread); + /// Run the command interpreter. + /// + /// \param[in] auto_handle_events + /// If true, automatically handle resulting events. This takes precedence + /// and overrides the corresponding option in + /// SBCommandInterpreterRunOptions. + /// + /// \param[in] spawn_thread + /// If true, start a new thread for IO handling. This takes precedence + /// and overrides the corresponding option in + /// SBCommandInterpreterRunOptions. + /// + /// \param[in] options + /// Parameter collection of type SBCommandInterpreterRunOptions. + /// + /// \param[out] num_errors + /// The number of errors. + /// + /// \param[out] quit_requested + /// Whether a quit was requested. + /// + /// \param[out] stopped_for_crash + /// Whether the interpreter stopped for a crash. void RunCommandInterpreter(bool auto_handle_events, bool spawn_thread, SBCommandInterpreterRunOptions &options, int &num_errors, bool &quit_requested, bool &stopped_for_crash); + SBCommandInterpreterRunResult + RunCommandInterpreter(const SBCommandInterpreterRunOptions &options); + SBError RunREPL(lldb::LanguageType language, const char *repl_options); private: @@ -319,4 +360,4 @@ private: } // namespace lldb -#endif // LLDB_SBDebugger_h_ +#endif // LLDB_API_SBDEBUGGER_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBDeclaration.h b/gnu/llvm/lldb/include/lldb/API/SBDeclaration.h index d2b423e40fe..aeaa28e1cad 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBDeclaration.h +++ b/gnu/llvm/lldb/include/lldb/API/SBDeclaration.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBDeclaration_h_ -#define LLDB_SBDeclaration_h_ +#ifndef LLDB_API_SBDECLARATION_H +#define LLDB_API_SBDECLARATION_H #include "lldb/API/SBDefines.h" #include "lldb/API/SBFileSpec.h" @@ -68,4 +68,4 @@ private: } // namespace lldb -#endif // LLDB_SBDeclaration_h_ +#endif // LLDB_API_SBDECLARATION_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBDefines.h b/gnu/llvm/lldb/include/lldb/API/SBDefines.h index 68aca930d19..a5b639c6dc7 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBDefines.h +++ b/gnu/llvm/lldb/include/lldb/API/SBDefines.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBDefines_h_ -#define LLDB_SBDefines_h_ - +#ifndef LLDB_API_SBDEFINES_H +#define LLDB_API_SBDEFINES_H #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" @@ -29,6 +28,7 @@ class LLDB_API SBBroadcaster; class LLDB_API SBCommand; class LLDB_API SBCommandInterpreter; class LLDB_API SBCommandInterpreterRunOptions; +class LLDB_API SBCommandInterpreterRunResult; class LLDB_API SBCommandPluginInterface; class LLDB_API SBCommandReturnObject; class LLDB_API SBCommunication; @@ -36,6 +36,7 @@ class LLDB_API SBCompileUnit; class LLDB_API SBData; class LLDB_API SBDebugger; class LLDB_API SBDeclaration; +class LLDB_API SBEnvironment; class LLDB_API SBError; class LLDB_API SBEvent; class LLDB_API SBEventList; @@ -99,4 +100,4 @@ typedef bool (*SBBreakpointHitCallback)(void *baton, SBProcess &process, lldb::SBBreakpointLocation &location); } -#endif // LLDB_SBDefines_h_ +#endif // LLDB_API_SBDEFINES_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBEnvironment.h b/gnu/llvm/lldb/include/lldb/API/SBEnvironment.h new file mode 100644 index 00000000000..f40ee01a42a --- /dev/null +++ b/gnu/llvm/lldb/include/lldb/API/SBEnvironment.h @@ -0,0 +1,137 @@ +//===-- SBEnvironment.h -----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_API_SBENVIRONMENT_H +#define LLDB_API_SBENVIRONMENT_H + +#include "lldb/API/SBDefines.h" + +namespace lldb { + +class LLDB_API SBEnvironment { +public: + SBEnvironment(); + + SBEnvironment(const lldb::SBEnvironment &rhs); + + ~SBEnvironment(); + + const lldb::SBEnvironment &operator=(const lldb::SBEnvironment &rhs); + + /// Return the value of a given environment variable. + /// + /// \param [in] name + /// The name of the environment variable. + /// + /// \return + /// The value of the environment variable or null if not present. + /// If the environment variable has no value but is present, a valid + /// pointer to an empty string will be returned. + const char *Get(const char *name); + + /// \return + /// The number of environment variables. + size_t GetNumValues(); + + /// Return the name of the environment variable at a given index from the + /// internal list of environment variables. + /// + /// \param [in] index + /// The index of the environment variable in the internal list. + /// + /// \return + /// The name at the given index or null if the index is invalid. + const char *GetNameAtIndex(size_t index); + + /// Return the value of the environment variable at a given index from the + /// internal list of environment variables. + /// + /// \param [in] index + /// The index of the environment variable in the internal list. + /// + /// \return + /// The value at the given index or null if the index is invalid. + /// If the environment variable has no value but is present, a valid + /// pointer to an empty string will be returned. + const char *GetValueAtIndex(size_t index); + + /// Return all environment variables contained in this object. Each variable + /// is returned as a string with the following format + /// name=value + /// + /// \return + /// Return an lldb::SBStringList object with the environment variables. + SBStringList GetEntries(); + + /// Add or replace an existing environment variable. The input must be a + /// string with the format + /// name=value + /// + /// \param [in] name_and_value + /// The entry to set which conforms to the format mentioned above. + void PutEntry(const char *name_and_value); + + /// Update this object with the given environment variables. The input is a + /// list of entries with the same format required by SBEnvironment::PutEntry. + /// + /// If append is false, the provided environment will replace the existing + /// environment. Otherwise, existing values will be updated of left untouched + /// accordingly. + /// + /// \param [in] entries + /// The environment variable entries. + /// + /// \param [in] append + /// Flag that controls whether to replace the existing environment. + void SetEntries(const SBStringList &entries, bool append); + + /// Set the value of a given environment variable. + /// If the variable exists, its value is updated only if overwrite is true. + /// + /// \param [in] name + /// The name of the environment variable to set. + /// + /// \param [in] value + /// The value of the environment variable to set. + /// + /// \param [in] overwrite + /// Flag that indicates whether to overwrite an existing environment + /// variable. + /// + /// \return + /// Return whether the variable was added or modified. + bool Set(const char *name, const char *value, bool overwrite); + + /// Unset an environment variable if exists. + /// + /// \param [in] name + /// The name of the environment variable to unset. + /// + /// \return + /// Return whether a variable was actually unset. + bool Unset(const char *name); + + /// Delete all the environment variables. + void Clear(); + +protected: + friend class SBPlatform; + friend class SBTarget; + friend class SBLaunchInfo; + + SBEnvironment(lldb_private::Environment rhs); + + lldb_private::Environment &ref() const; + +private: + std::unique_ptr m_opaque_up; +}; + +} // namespace lldb + +#endif // LLDB_API_SBENVIRONMENT_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBError.h b/gnu/llvm/lldb/include/lldb/API/SBError.h index 3db2658d9fb..e1960ef9a98 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBError.h +++ b/gnu/llvm/lldb/include/lldb/API/SBError.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBError_h_ -#define LLDB_SBError_h_ +#ifndef LLDB_API_SBERROR_H +#define LLDB_API_SBERROR_H #include "lldb/API/SBDefines.h" @@ -90,4 +90,4 @@ private: } // namespace lldb -#endif // LLDB_SBError_h_ +#endif // LLDB_API_SBERROR_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBEvent.h b/gnu/llvm/lldb/include/lldb/API/SBEvent.h index d297cbeff67..a7975bf9aba 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBEvent.h +++ b/gnu/llvm/lldb/include/lldb/API/SBEvent.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBEvent_h_ -#define LLDB_SBEvent_h_ +#ifndef LLDB_API_SBEVENT_H +#define LLDB_API_SBEVENT_H #include "lldb/API/SBDefines.h" @@ -84,4 +84,4 @@ private: } // namespace lldb -#endif // LLDB_SBEvent_h_ +#endif // LLDB_API_SBEVENT_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBExecutionContext.h b/gnu/llvm/lldb/include/lldb/API/SBExecutionContext.h index 45c0b1b7f97..d8447aeb1a2 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBExecutionContext.h +++ b/gnu/llvm/lldb/include/lldb/API/SBExecutionContext.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBExecutionContext_h_ -#define LLDB_SBExecutionContext_h_ +#ifndef LLDB_API_SBEXECUTIONCONTEXT_H +#define LLDB_API_SBEXECUTIONCONTEXT_H #include "lldb/API/SBDefines.h" @@ -60,4 +60,4 @@ private: } // namespace lldb -#endif // LLDB_SBExecutionContext_h_ +#endif // LLDB_API_SBEXECUTIONCONTEXT_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBExpressionOptions.h b/gnu/llvm/lldb/include/lldb/API/SBExpressionOptions.h index 04cd74f730f..9fc6e9ea957 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBExpressionOptions.h +++ b/gnu/llvm/lldb/include/lldb/API/SBExpressionOptions.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBExpressionOptions_h_ -#define LLDB_SBExpressionOptions_h_ +#ifndef LLDB_API_SBEXPRESSIONOPTIONS_H +#define LLDB_API_SBEXPRESSIONOPTIONS_H #include "lldb/API/SBDefines.h" @@ -86,6 +86,10 @@ public: bool GetAutoApplyFixIts(); + void SetRetriesWithFixIts(uint64_t retries); + + uint64_t GetRetriesWithFixIts(); + bool GetTopLevel(); void SetTopLevel(bool b = true); @@ -112,4 +116,4 @@ private: } // namespace lldb -#endif // LLDB_SBExpressionOptions_h_ +#endif // LLDB_API_SBEXPRESSIONOPTIONS_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBFile.h b/gnu/llvm/lldb/include/lldb/API/SBFile.h index 7d6c1480992..a8b16520332 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBFile.h +++ b/gnu/llvm/lldb/include/lldb/API/SBFile.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBFile_h_ -#define LLDB_SBFile_h_ +#ifndef LLDB_API_SBFILE_H +#define LLDB_API_SBFILE_H #include "lldb/API/SBDefines.h" @@ -23,10 +23,13 @@ class LLDB_API SBFile { public: SBFile(); SBFile(FileSP file_sp); + SBFile(const SBFile &rhs); SBFile(FILE *file, bool transfer_ownership); SBFile(int fd, const char *mode, bool transfer_ownership); ~SBFile(); + SBFile &operator=(const SBFile &rhs); + SBError Read(uint8_t *buf, size_t num_bytes, size_t *bytes_read); SBError Write(const uint8_t *buf, size_t num_bytes, size_t *bytes_written); SBError Flush(); @@ -44,4 +47,4 @@ private: } // namespace lldb -#endif // LLDB_SBFile_h_ +#endif // LLDB_API_SBFILE_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBFileSpec.h b/gnu/llvm/lldb/include/lldb/API/SBFileSpec.h index 27149775901..a2f02ac7820 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBFileSpec.h +++ b/gnu/llvm/lldb/include/lldb/API/SBFileSpec.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBFileSpec_h_ -#define LLDB_SBFileSpec_h_ +#ifndef LLDB_API_SBFILESPEC_H +#define LLDB_API_SBFILESPEC_H #include "lldb/API/SBDefines.h" @@ -92,4 +92,4 @@ private: } // namespace lldb -#endif // LLDB_SBFileSpec_h_ +#endif // LLDB_API_SBFILESPEC_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBFileSpecList.h b/gnu/llvm/lldb/include/lldb/API/SBFileSpecList.h index 5a131509d26..1a654865a30 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBFileSpecList.h +++ b/gnu/llvm/lldb/include/lldb/API/SBFileSpecList.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBFileSpecList_h_ -#define LLDB_SBFileSpecList_h_ +#ifndef LLDB_API_SBFILESPECLIST_H +#define LLDB_API_SBFILESPECLIST_H #include "lldb/API/SBDefines.h" @@ -54,4 +54,4 @@ private: } // namespace lldb -#endif // LLDB_SBFileSpecList_h_ +#endif // LLDB_API_SBFILESPECLIST_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBFrame.h b/gnu/llvm/lldb/include/lldb/API/SBFrame.h index b213f898551..2e368accbbb 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBFrame.h +++ b/gnu/llvm/lldb/include/lldb/API/SBFrame.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBFrame_h_ -#define LLDB_SBFrame_h_ +#ifndef LLDB_API_SBFRAME_H +#define LLDB_API_SBFRAME_H #include "lldb/API/SBDefines.h" #include "lldb/API/SBValueList.h" @@ -202,4 +202,4 @@ protected: } // namespace lldb -#endif // LLDB_SBFrame_h_ +#endif // LLDB_API_SBFRAME_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBFunction.h b/gnu/llvm/lldb/include/lldb/API/SBFunction.h index 43f01d7e57d..bd643a62206 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBFunction.h +++ b/gnu/llvm/lldb/include/lldb/API/SBFunction.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBFunction_h_ -#define LLDB_SBFunction_h_ +#ifndef LLDB_API_SBFUNCTION_H +#define LLDB_API_SBFUNCTION_H #include "lldb/API/SBAddress.h" #include "lldb/API/SBDefines.h" @@ -79,4 +79,4 @@ private: } // namespace lldb -#endif // LLDB_SBFunction_h_ +#endif // LLDB_API_SBFUNCTION_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBHostOS.h b/gnu/llvm/lldb/include/lldb/API/SBHostOS.h index ecd7920f2c1..b170f8d6581 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBHostOS.h +++ b/gnu/llvm/lldb/include/lldb/API/SBHostOS.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBHostOS_h_ -#define LLDB_SBHostOS_h_ +#ifndef LLDB_API_SBHOSTOS_H +#define LLDB_API_SBHOSTOS_H #include "lldb/API/SBDefines.h" #include "lldb/API/SBFileSpec.h" @@ -41,4 +41,4 @@ private: } // namespace lldb -#endif // LLDB_SBHostOS_h_ +#endif // LLDB_API_SBHOSTOS_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBInstruction.h b/gnu/llvm/lldb/include/lldb/API/SBInstruction.h index 7d83a37ba5d..7d07e168cf0 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBInstruction.h +++ b/gnu/llvm/lldb/include/lldb/API/SBInstruction.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBInstruction_h_ -#define LLDB_SBInstruction_h_ +#ifndef LLDB_API_SBINSTRUCTION_H +#define LLDB_API_SBINSTRUCTION_H #include "lldb/API/SBData.h" #include "lldb/API/SBDefines.h" @@ -86,4 +86,4 @@ private: } // namespace lldb -#endif // LLDB_SBInstruction_h_ +#endif // LLDB_API_SBINSTRUCTION_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBInstructionList.h b/gnu/llvm/lldb/include/lldb/API/SBInstructionList.h index e203d0b8056..ae8988004e2 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBInstructionList.h +++ b/gnu/llvm/lldb/include/lldb/API/SBInstructionList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBInstructionList_h_ -#define LLDB_SBInstructionList_h_ +#ifndef LLDB_API_SBINSTRUCTIONLIST_H +#define LLDB_API_SBINSTRUCTIONLIST_H #include "lldb/API/SBDefines.h" @@ -69,4 +69,4 @@ private: } // namespace lldb -#endif // LLDB_SBInstructionList_h_ +#endif // LLDB_API_SBINSTRUCTIONLIST_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBLanguageRuntime.h b/gnu/llvm/lldb/include/lldb/API/SBLanguageRuntime.h index d28c441593e..38aac05d490 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBLanguageRuntime.h +++ b/gnu/llvm/lldb/include/lldb/API/SBLanguageRuntime.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBLanguageRuntime_h_ -#define LLDB_SBLanguageRuntime_h_ +#ifndef LLDB_API_SBLANGUAGERUNTIME_H +#define LLDB_API_SBLANGUAGERUNTIME_H #include "lldb/API/SBDefines.h" @@ -22,4 +22,4 @@ public: } // namespace lldb -#endif // LLDB_SBLanguageRuntime_h_ +#endif // LLDB_API_SBLANGUAGERUNTIME_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBLaunchInfo.h b/gnu/llvm/lldb/include/lldb/API/SBLaunchInfo.h index c7b381ffdf9..04ebb570768 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBLaunchInfo.h +++ b/gnu/llvm/lldb/include/lldb/API/SBLaunchInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBLaunchInfo_h_ -#define LLDB_SBLaunchInfo_h_ +#ifndef LLDB_API_SBLAUNCHINFO_H +#define LLDB_API_SBLAUNCHINFO_H #include "lldb/API/SBDefines.h" @@ -26,6 +26,10 @@ public: ~SBLaunchInfo(); + SBLaunchInfo(const SBLaunchInfo &rhs); + + SBLaunchInfo &operator=(const SBLaunchInfo &rhs); + lldb::pid_t GetProcessID(); uint32_t GetUserID(); @@ -90,8 +94,41 @@ public: const char *GetEnvironmentEntryAtIndex(uint32_t idx); + /// Update this object with the given environment variables. + /// + /// If append is false, the provided environment will replace the existing + /// environment. Otherwise, existing values will be updated of left untouched + /// accordingly. + /// + /// \param [in] envp + /// The new environment variables as a list of strings with the following + /// format + /// name=value + /// + /// \param [in] append + /// Flag that controls whether to replace the existing environment. void SetEnvironmentEntries(const char **envp, bool append); + /// Update this object with the given environment variables. + /// + /// If append is false, the provided environment will replace the existing + /// environment. Otherwise, existing values will be updated of left untouched + /// accordingly. + /// + /// \param [in] env + /// The new environment variables. + /// + /// \param [in] append + /// Flag that controls whether to replace the existing environment. + void SetEnvironment(const SBEnvironment &env, bool append); + + /// Return the environment variables of this object. + /// + /// \return + /// An lldb::SBEnvironment object which is a copy of the SBLaunchInfo's + /// environment. + SBEnvironment GetEnvironment(); + void Clear(); const char *GetWorkingDirectory() const; @@ -146,4 +183,4 @@ protected: } // namespace lldb -#endif // LLDB_SBLaunchInfo_h_ +#endif // LLDB_API_SBLAUNCHINFO_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBLineEntry.h b/gnu/llvm/lldb/include/lldb/API/SBLineEntry.h index 855c28d14b8..7c2431ba3c8 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBLineEntry.h +++ b/gnu/llvm/lldb/include/lldb/API/SBLineEntry.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBLineEntry_h_ -#define LLDB_SBLineEntry_h_ +#ifndef LLDB_API_SBLINEENTRY_H +#define LLDB_API_SBLINEENTRY_H #include "lldb/API/SBAddress.h" #include "lldb/API/SBDefines.h" @@ -75,4 +75,4 @@ private: } // namespace lldb -#endif // LLDB_SBLineEntry_h_ +#endif // LLDB_API_SBLINEENTRY_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBListener.h b/gnu/llvm/lldb/include/lldb/API/SBListener.h index 21aface97bd..2144e7956b1 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBListener.h +++ b/gnu/llvm/lldb/include/lldb/API/SBListener.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBListener_h_ -#define LLDB_SBListener_h_ +#ifndef LLDB_API_SBLISTENER_H +#define LLDB_API_SBLISTENER_H #include "lldb/API/SBDefines.h" @@ -105,4 +105,4 @@ private: } // namespace lldb -#endif // LLDB_SBListener_h_ +#endif // LLDB_API_SBLISTENER_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBMemoryRegionInfo.h b/gnu/llvm/lldb/include/lldb/API/SBMemoryRegionInfo.h index 2a9ae94218f..d82c7060655 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBMemoryRegionInfo.h +++ b/gnu/llvm/lldb/include/lldb/API/SBMemoryRegionInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBMemoryRegionInfo_h_ -#define LLDB_SBMemoryRegionInfo_h_ +#ifndef LLDB_API_SBMEMORYREGIONINFO_H +#define LLDB_API_SBMEMORYREGIONINFO_H #include "lldb/API/SBData.h" #include "lldb/API/SBDefines.h" @@ -95,4 +95,4 @@ private: } // namespace lldb -#endif // LLDB_SBMemoryRegionInfo_h_ +#endif // LLDB_API_SBMEMORYREGIONINFO_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBMemoryRegionInfoList.h b/gnu/llvm/lldb/include/lldb/API/SBMemoryRegionInfoList.h index 5592efef485..a7122ee9108 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBMemoryRegionInfoList.h +++ b/gnu/llvm/lldb/include/lldb/API/SBMemoryRegionInfoList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBMemoryRegionInfoList_h_ -#define LLDB_SBMemoryRegionInfoList_h_ +#ifndef LLDB_API_SBMEMORYREGIONINFOLIST_H +#define LLDB_API_SBMEMORYREGIONINFOLIST_H #include "lldb/API/SBDefines.h" @@ -52,4 +52,4 @@ private: } // namespace lldb -#endif // LLDB_SBMemoryRegionInfoList_h_ +#endif // LLDB_API_SBMEMORYREGIONINFOLIST_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBModule.h b/gnu/llvm/lldb/include/lldb/API/SBModule.h index d2b6a18db84..859eaffe89a 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBModule.h +++ b/gnu/llvm/lldb/include/lldb/API/SBModule.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBModule_h_ -#define LLDB_SBModule_h_ +#ifndef LLDB_API_SBMODULE_H +#define LLDB_API_SBMODULE_H #include "lldb/API/SBDefines.h" #include "lldb/API/SBError.h" @@ -288,6 +288,9 @@ public: lldb::SBAddress GetObjectFileHeaderAddress() const; lldb::SBAddress GetObjectFileEntryPointAddress() const; + /// Get the number of global modules. + static uint32_t GetNumberAllocatedModules(); + private: friend class SBAddress; friend class SBFrame; @@ -306,4 +309,4 @@ private: } // namespace lldb -#endif // LLDB_SBModule_h_ +#endif // LLDB_API_SBMODULE_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBModuleSpec.h b/gnu/llvm/lldb/include/lldb/API/SBModuleSpec.h index 29b3117a261..7529879b78b 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBModuleSpec.h +++ b/gnu/llvm/lldb/include/lldb/API/SBModuleSpec.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBModuleSpec_h_ -#define LLDB_SBModuleSpec_h_ +#ifndef LLDB_API_SBMODULESPEC_H +#define LLDB_API_SBMODULESPEC_H #include "lldb/API/SBDefines.h" #include "lldb/API/SBFileSpec.h" @@ -119,4 +119,4 @@ private: } // namespace lldb -#endif // LLDB_SBModuleSpec_h_ +#endif // LLDB_API_SBMODULESPEC_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBPlatform.h b/gnu/llvm/lldb/include/lldb/API/SBPlatform.h index 7207b2e2a78..4d251b12995 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBPlatform.h +++ b/gnu/llvm/lldb/include/lldb/API/SBPlatform.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBPlatform_h_ -#define LLDB_SBPlatform_h_ +#ifndef LLDB_API_SBPLATFORM_H +#define LLDB_API_SBPLATFORM_H #include "lldb/API/SBDefines.h" @@ -28,7 +28,7 @@ public: ~SBPlatformConnectOptions(); - void operator=(const SBPlatformConnectOptions &rhs); + SBPlatformConnectOptions &operator=(const SBPlatformConnectOptions &rhs); const char *GetURL(); @@ -55,6 +55,8 @@ public: SBPlatformShellCommand(const SBPlatformShellCommand &rhs); + SBPlatformShellCommand &operator=(const SBPlatformShellCommand &rhs); + ~SBPlatformShellCommand(); void Clear(); @@ -89,8 +91,14 @@ public: SBPlatform(const char *platform_name); + SBPlatform(const SBPlatform &rhs); + + SBPlatform &operator=(const SBPlatform &rhs); + ~SBPlatform(); + static SBPlatform GetHostPlatform(); + explicit operator bool() const; bool IsValid() const; @@ -146,6 +154,14 @@ public: SBUnixSignals GetUnixSignals() const; + /// Return the environment variables of the remote platform connection + /// process. + /// + /// \return + /// An lldb::SBEnvironment object which is a copy of the platform's + /// environment. + SBEnvironment GetEnvironment(); + protected: friend class SBDebugger; friend class SBTarget; @@ -163,4 +179,4 @@ protected: } // namespace lldb -#endif // LLDB_SBPlatform_h_ +#endif // LLDB_API_SBPLATFORM_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBProcess.h b/gnu/llvm/lldb/include/lldb/API/SBProcess.h index 8ab8bfa3a93..a90ec2a29a3 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBProcess.h +++ b/gnu/llvm/lldb/include/lldb/API/SBProcess.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBProcess_h_ -#define LLDB_SBProcess_h_ +#ifndef LLDB_API_SBPROCESS_H +#define LLDB_API_SBPROCESS_H #include "lldb/API/SBDefines.h" #include "lldb/API/SBError.h" @@ -222,6 +222,8 @@ public: bool GetDescription(lldb::SBStream &description); + SBStructuredData GetExtendedCrashInformation(); + /// Start Tracing with the given SBTraceOptions. /// /// \param[in] options @@ -416,4 +418,4 @@ protected: } // namespace lldb -#endif // LLDB_SBProcess_h_ +#endif // LLDB_API_SBPROCESS_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBProcessInfo.h b/gnu/llvm/lldb/include/lldb/API/SBProcessInfo.h index 86dba9a8e11..0cc5f6a2f9f 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBProcessInfo.h +++ b/gnu/llvm/lldb/include/lldb/API/SBProcessInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBProcessInfo_h_ -#define LLDB_SBProcessInfo_h_ +#ifndef LLDB_API_SBPROCESSINFO_H +#define LLDB_API_SBPROCESSINFO_H #include "lldb/API/SBDefines.h" @@ -62,4 +62,4 @@ private: } // namespace lldb -#endif // LLDB_SBProcessInfo_h_ +#endif // LLDB_API_SBPROCESSINFO_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBQueue.h b/gnu/llvm/lldb/include/lldb/API/SBQueue.h index 0124c1c90dd..c563f3ee1c2 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBQueue.h +++ b/gnu/llvm/lldb/include/lldb/API/SBQueue.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBQueue_h_ -#define LLDB_SBQueue_h_ +#ifndef LLDB_API_SBQUEUE_H +#define LLDB_API_SBQUEUE_H #include @@ -66,4 +66,4 @@ private: } // namespace lldb -#endif // LLDB_SBQueue_h_ +#endif // LLDB_API_SBQUEUE_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBQueueItem.h b/gnu/llvm/lldb/include/lldb/API/SBQueueItem.h index 455a1f98379..435dafe534a 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBQueueItem.h +++ b/gnu/llvm/lldb/include/lldb/API/SBQueueItem.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBQueueItem_h_ -#define LLDB_SBQueueItem_h_ +#ifndef LLDB_API_SBQUEUEITEM_H +#define LLDB_API_SBQUEUEITEM_H #include "lldb/API/SBAddress.h" #include "lldb/API/SBDefines.h" @@ -46,4 +46,4 @@ private: } // namespace lldb -#endif // LLDB_SBQueueItem_h_ +#endif // LLDB_API_SBQUEUEITEM_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBReproducer.h b/gnu/llvm/lldb/include/lldb/API/SBReproducer.h index 93d78f55fd7..78044e9acbc 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBReproducer.h +++ b/gnu/llvm/lldb/include/lldb/API/SBReproducer.h @@ -22,8 +22,17 @@ public: static const char *Capture(const char *path); static const char *Replay(const char *path); static const char *Replay(const char *path, bool skip_version_check); + static const char *PassiveReplay(const char *path); static const char *GetPath(); + static bool SetAutoGenerate(bool b); static bool Generate(); + + /// The working directory is set to the current working directory when the + /// reproducers are initialized. This method allows setting a different + /// working directory. This is used by the API test suite which temporarily + /// changes the directory to where the test lives. This is a NO-OP in every + /// mode but capture. + static void SetWorkingDirectory(const char *path); }; } // namespace lldb diff --git a/gnu/llvm/lldb/include/lldb/API/SBSection.h b/gnu/llvm/lldb/include/lldb/API/SBSection.h index 06a195ee78d..d722dbe4ff1 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBSection.h +++ b/gnu/llvm/lldb/include/lldb/API/SBSection.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBSection_h_ -#define LLDB_SBSection_h_ +#ifndef LLDB_API_SBSECTION_H +#define LLDB_API_SBSECTION_H #include "lldb/API/SBData.h" #include "lldb/API/SBDefines.h" @@ -98,4 +98,4 @@ private: } // namespace lldb -#endif // LLDB_SBSection_h_ +#endif // LLDB_API_SBSECTION_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBSourceManager.h b/gnu/llvm/lldb/include/lldb/API/SBSourceManager.h index 3d69aa25a93..c8302dbda3c 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBSourceManager.h +++ b/gnu/llvm/lldb/include/lldb/API/SBSourceManager.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBSourceManager_h_ -#define LLDB_SBSourceManager_h_ +#ifndef LLDB_API_SBSOURCEMANAGER_H +#define LLDB_API_SBSOURCEMANAGER_H #include "lldb/API/SBDefines.h" @@ -44,4 +44,4 @@ private: } // namespace lldb -#endif // LLDB_SBSourceManager_h_ +#endif // LLDB_API_SBSOURCEMANAGER_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBStream.h b/gnu/llvm/lldb/include/lldb/API/SBStream.h index b78c498e5f3..f44b87bb4c9 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBStream.h +++ b/gnu/llvm/lldb/include/lldb/API/SBStream.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBStream_h_ -#define LLDB_SBStream_h_ +#ifndef LLDB_API_SBSTREAM_H +#define LLDB_API_SBSTREAM_H #include @@ -37,6 +37,8 @@ public: void Printf(const char *format, ...) __attribute__((format(printf, 2, 3))); + void Print(const char *str); + void RedirectToFile(const char *path, bool append); void RedirectToFile(lldb::SBFile file); @@ -99,11 +101,12 @@ protected: lldb_private::Stream &ref(); private: - DISALLOW_COPY_AND_ASSIGN(SBStream); + SBStream(const SBStream &) = delete; + const SBStream &operator=(const SBStream &) = delete; std::unique_ptr m_opaque_up; bool m_is_file; }; } // namespace lldb -#endif // LLDB_SBStream_h_ +#endif // LLDB_API_SBSTREAM_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBStringList.h b/gnu/llvm/lldb/include/lldb/API/SBStringList.h index 1df1e45f96f..4842c162bd6 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBStringList.h +++ b/gnu/llvm/lldb/include/lldb/API/SBStringList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBStringList_h_ -#define LLDB_SBStringList_h_ +#ifndef LLDB_API_SBSTRINGLIST_H +#define LLDB_API_SBSTRINGLIST_H #include "lldb/API/SBDefines.h" @@ -62,4 +62,4 @@ private: } // namespace lldb -#endif // LLDB_SBStringList_h_ +#endif // LLDB_API_SBSTRINGLIST_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBStructuredData.h b/gnu/llvm/lldb/include/lldb/API/SBStructuredData.h index 785e91047fd..44a86bdabe2 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBStructuredData.h +++ b/gnu/llvm/lldb/include/lldb/API/SBStructuredData.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SBStructuredData_h -#define SBStructuredData_h +#ifndef LLDB_API_SBSTRUCTUREDDATA_H +#define LLDB_API_SBSTRUCTUREDDATA_H #include "lldb/API/SBDefines.h" #include "lldb/API/SBModule.h" @@ -91,6 +91,7 @@ protected: friend class SBTraceOptions; friend class SBDebugger; friend class SBTarget; + friend class SBProcess; friend class SBThread; friend class SBThreadPlan; friend class SBBreakpoint; @@ -101,4 +102,4 @@ protected: }; } // namespace lldb -#endif /* SBStructuredData_h */ +#endif // LLDB_API_SBSTRUCTUREDDATA_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBSymbol.h b/gnu/llvm/lldb/include/lldb/API/SBSymbol.h index 52486b83d1a..66f73c82a73 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBSymbol.h +++ b/gnu/llvm/lldb/include/lldb/API/SBSymbol.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBSymbol_h_ -#define LLDB_SBSymbol_h_ +#ifndef LLDB_API_SBSYMBOL_H +#define LLDB_API_SBSYMBOL_H #include "lldb/API/SBAddress.h" #include "lldb/API/SBDefines.h" @@ -83,4 +83,4 @@ private: } // namespace lldb -#endif // LLDB_SBSymbol_h_ +#endif // LLDB_API_SBSYMBOL_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBSymbolContext.h b/gnu/llvm/lldb/include/lldb/API/SBSymbolContext.h index 3d16d0989ca..16ad29ea873 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBSymbolContext.h +++ b/gnu/llvm/lldb/include/lldb/API/SBSymbolContext.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBSymbolContext_h_ -#define LLDB_SBSymbolContext_h_ +#ifndef LLDB_API_SBSYMBOLCONTEXT_H +#define LLDB_API_SBSYMBOLCONTEXT_H #include "lldb/API/SBBlock.h" #include "lldb/API/SBCompileUnit.h" @@ -80,4 +80,4 @@ private: } // namespace lldb -#endif // LLDB_SBSymbolContext_h_ +#endif // LLDB_API_SBSYMBOLCONTEXT_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBSymbolContextList.h b/gnu/llvm/lldb/include/lldb/API/SBSymbolContextList.h index 577993ce96d..4026afc2135 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBSymbolContextList.h +++ b/gnu/llvm/lldb/include/lldb/API/SBSymbolContextList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBSymbolContextList_h_ -#define LLDB_SBSymbolContextList_h_ +#ifndef LLDB_API_SBSYMBOLCONTEXTLIST_H +#define LLDB_API_SBSYMBOLCONTEXTLIST_H #include "lldb/API/SBDefines.h" #include "lldb/API/SBSymbolContext.h" @@ -55,4 +55,4 @@ private: } // namespace lldb -#endif // LLDB_SBSymbolContextList_h_ +#endif // LLDB_API_SBSYMBOLCONTEXTLIST_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBTarget.h b/gnu/llvm/lldb/include/lldb/API/SBTarget.h index 80a7fa00dbc..fad842c9cb1 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBTarget.h +++ b/gnu/llvm/lldb/include/lldb/API/SBTarget.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBTarget_h_ -#define LLDB_SBTarget_h_ +#ifndef LLDB_API_SBTARGET_H +#define LLDB_API_SBTARGET_H #include "lldb/API/SBAddress.h" #include "lldb/API/SBAttachInfo.h" @@ -94,6 +94,15 @@ public: /// A platform object. lldb::SBPlatform GetPlatform(); + /// Return the environment variables that would be used to launch a new + /// process. + /// + /// \return + /// An lldb::SBEnvironment object which is a copy of the target's + /// environment. + + SBEnvironment GetEnvironment(); + /// Install any binaries that need to be installed. /// /// This function does nothing when debugging on the host system. @@ -127,7 +136,9 @@ public: /// The argument array. /// /// \param[in] envp - /// The environment array. + /// The environment array. If this is null, the default + /// environment values (provided through `settings set + /// target.env-vars`) will be used. /// /// \param[in] stdin_path /// The path to use when re-directing the STDIN of the new @@ -175,7 +186,9 @@ public: /// The argument array. /// /// \param[in] envp - /// The environment array. + /// The environment array. If this isn't provided, the default + /// environment values (provided through `settings set + /// target.env-vars`) will be used. /// /// \param[in] working_directory /// The working directory to have the child process run in @@ -829,6 +842,7 @@ protected: friend class SBFunction; friend class SBInstruction; friend class SBModule; + friend class SBPlatform; friend class SBProcess; friend class SBSection; friend class SBSourceManager; @@ -849,4 +863,4 @@ private: } // namespace lldb -#endif // LLDB_SBTarget_h_ +#endif // LLDB_API_SBTARGET_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBThread.h b/gnu/llvm/lldb/include/lldb/API/SBThread.h index b5f1794f9fe..894120c6d98 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBThread.h +++ b/gnu/llvm/lldb/include/lldb/API/SBThread.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBThread_h_ -#define LLDB_SBThread_h_ +#ifndef LLDB_API_SBTHREAD_H +#define LLDB_API_SBTHREAD_H #include "lldb/API/SBDefines.h" @@ -232,4 +232,4 @@ private: } // namespace lldb -#endif // LLDB_SBThread_h_ +#endif // LLDB_API_SBTHREAD_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBThreadCollection.h b/gnu/llvm/lldb/include/lldb/API/SBThreadCollection.h index 1c6b4639c6e..fe57a6b95d9 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBThreadCollection.h +++ b/gnu/llvm/lldb/include/lldb/API/SBThreadCollection.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBThreadCollection_h_ -#define LLDB_SBThreadCollection_h_ +#ifndef LLDB_API_SBTHREADCOLLECTION_H +#define LLDB_API_SBTHREADCOLLECTION_H #include "lldb/API/SBDefines.h" @@ -54,4 +54,4 @@ private: } // namespace lldb -#endif // LLDB_SBThreadCollection_h_ +#endif // LLDB_API_SBTHREADCOLLECTION_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBThreadPlan.h b/gnu/llvm/lldb/include/lldb/API/SBThreadPlan.h index dbe417e6374..8f16f4f5c4d 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBThreadPlan.h +++ b/gnu/llvm/lldb/include/lldb/API/SBThreadPlan.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBThreadPlan_h_ -#define LLDB_SBThreadPlan_h_ +#ifndef LLDB_API_SBTHREADPLAN_H +#define LLDB_API_SBTHREADPLAN_H #include "lldb/API/SBDefines.h" @@ -125,4 +125,4 @@ private: } // namespace lldb -#endif // LLDB_SBThreadPlan_h_ +#endif // LLDB_API_SBTHREADPLAN_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBTrace.h b/gnu/llvm/lldb/include/lldb/API/SBTrace.h index 87c67adac75..053abaeada1 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBTrace.h +++ b/gnu/llvm/lldb/include/lldb/API/SBTrace.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBTrace_h_ -#define LLDB_SBTrace_h_ +#ifndef LLDB_API_SBTRACE_H +#define LLDB_API_SBTRACE_H #include "lldb/API/SBDefines.h" #include "lldb/API/SBError.h" @@ -113,4 +113,4 @@ protected: }; } // namespace lldb -#endif // LLDB_SBTrace_h_ +#endif // LLDB_API_SBTRACE_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBTraceOptions.h b/gnu/llvm/lldb/include/lldb/API/SBTraceOptions.h index 4c586bfd55c..22d71fbd382 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBTraceOptions.h +++ b/gnu/llvm/lldb/include/lldb/API/SBTraceOptions.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SBTRACEOPTIONS_H_ -#define SBTRACEOPTIONS_H_ +#ifndef LLDB_API_SBTRACEOPTIONS_H +#define LLDB_API_SBTRACEOPTIONS_H #include "lldb/API/SBDefines.h" @@ -56,4 +56,4 @@ protected: }; } -#endif /* SBTRACEOPTIONS_H_ */ +#endif // LLDB_API_SBTRACEOPTIONS_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBType.h b/gnu/llvm/lldb/include/lldb/API/SBType.h index b3f92b7bcd0..b0af4335119 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBType.h +++ b/gnu/llvm/lldb/include/lldb/API/SBType.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBType_h_ -#define LLDB_SBType_h_ +#ifndef LLDB_API_SBTYPE_H +#define LLDB_API_SBTYPE_H #include "lldb/API/SBDefines.h" @@ -259,4 +259,4 @@ private: } // namespace lldb -#endif // LLDB_SBType_h_ +#endif // LLDB_API_SBTYPE_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBTypeCategory.h b/gnu/llvm/lldb/include/lldb/API/SBTypeCategory.h index c0f4cee1d26..ee1c0f6910e 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBTypeCategory.h +++ b/gnu/llvm/lldb/include/lldb/API/SBTypeCategory.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBTypeCategory_h_ -#define LLDB_SBTypeCategory_h_ +#ifndef LLDB_API_SBTYPECATEGORY_H +#define LLDB_API_SBTYPECATEGORY_H #include "lldb/API/SBDefines.h" @@ -113,4 +113,4 @@ protected: } // namespace lldb -#endif // LLDB_SBTypeCategory_h_ +#endif // LLDB_API_SBTYPECATEGORY_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBTypeEnumMember.h b/gnu/llvm/lldb/include/lldb/API/SBTypeEnumMember.h index 2410dbcc212..45f8cc6638b 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBTypeEnumMember.h +++ b/gnu/llvm/lldb/include/lldb/API/SBTypeEnumMember.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBTypeEnumMember_h_ -#define LLDB_SBTypeEnumMember_h_ +#ifndef LLDB_API_SBTYPEENUMMEMBER_H +#define LLDB_API_SBTYPEENUMMEMBER_H #include "lldb/API/SBDefines.h" @@ -80,4 +80,4 @@ private: } // namespace lldb -#endif // LLDB_SBTypeEnumMember_h_ +#endif // LLDB_API_SBTYPEENUMMEMBER_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBTypeFilter.h b/gnu/llvm/lldb/include/lldb/API/SBTypeFilter.h index 4a0de11d19c..5f02e231d12 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBTypeFilter.h +++ b/gnu/llvm/lldb/include/lldb/API/SBTypeFilter.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBTypeFilter_h_ -#define LLDB_SBTypeFilter_h_ +#ifndef LLDB_API_SBTYPEFILTER_H +#define LLDB_API_SBTYPEFILTER_H #include "lldb/API/SBDefines.h" @@ -71,4 +71,4 @@ protected: } // namespace lldb -#endif // LLDB_SBTypeFilter_h_ +#endif // LLDB_API_SBTYPEFILTER_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBTypeFormat.h b/gnu/llvm/lldb/include/lldb/API/SBTypeFormat.h index 8a0ac77a1e9..b3404592703 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBTypeFormat.h +++ b/gnu/llvm/lldb/include/lldb/API/SBTypeFormat.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBTypeFormat_h_ -#define LLDB_SBTypeFormat_h_ +#ifndef LLDB_API_SBTYPEFORMAT_H +#define LLDB_API_SBTYPEFORMAT_H #include "lldb/API/SBDefines.h" @@ -75,4 +75,4 @@ protected: } // namespace lldb -#endif // LLDB_SBTypeFormat_h_ +#endif // LLDB_API_SBTYPEFORMAT_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBTypeNameSpecifier.h b/gnu/llvm/lldb/include/lldb/API/SBTypeNameSpecifier.h index 9fe449d029c..eee424c1710 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBTypeNameSpecifier.h +++ b/gnu/llvm/lldb/include/lldb/API/SBTypeNameSpecifier.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBTypeNameSpecifier_h_ -#define LLDB_SBTypeNameSpecifier_h_ +#ifndef LLDB_API_SBTYPENAMESPECIFIER_H +#define LLDB_API_SBTYPENAMESPECIFIER_H #include "lldb/API/SBDefines.h" @@ -62,4 +62,4 @@ protected: } // namespace lldb -#endif // LLDB_SBTypeNameSpecifier_h_ +#endif // LLDB_API_SBTYPENAMESPECIFIER_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBTypeSummary.h b/gnu/llvm/lldb/include/lldb/API/SBTypeSummary.h index bb7121f8ae4..929bfb6124b 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBTypeSummary.h +++ b/gnu/llvm/lldb/include/lldb/API/SBTypeSummary.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBTypeSummary_h_ -#define LLDB_SBTypeSummary_h_ +#ifndef LLDB_API_SBTYPESUMMARY_H +#define LLDB_API_SBTYPESUMMARY_H #include "lldb/API/SBDefines.h" @@ -136,4 +136,4 @@ protected: } // namespace lldb -#endif // LLDB_SBTypeSummary_h_ +#endif // LLDB_API_SBTYPESUMMARY_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBTypeSynthetic.h b/gnu/llvm/lldb/include/lldb/API/SBTypeSynthetic.h index c190643c1eb..9dab9d851f0 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBTypeSynthetic.h +++ b/gnu/llvm/lldb/include/lldb/API/SBTypeSynthetic.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBTypeSynthetic_h_ -#define LLDB_SBTypeSynthetic_h_ +#ifndef LLDB_API_SBTYPESYNTHETIC_H +#define LLDB_API_SBTYPESYNTHETIC_H #include "lldb/API/SBDefines.h" @@ -77,4 +77,4 @@ protected: } // namespace lldb -#endif // LLDB_SBTypeSynthetic_h_ +#endif // LLDB_API_SBTYPESYNTHETIC_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBUnixSignals.h b/gnu/llvm/lldb/include/lldb/API/SBUnixSignals.h index c7e99d1f63d..9757eac7ee3 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBUnixSignals.h +++ b/gnu/llvm/lldb/include/lldb/API/SBUnixSignals.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBUnixSignals_h_ -#define LLDB_SBUnixSignals_h_ +#ifndef LLDB_API_SBUNIXSIGNALS_H +#define LLDB_API_SBUNIXSIGNALS_H #include "lldb/API/SBDefines.h" @@ -68,4 +68,4 @@ private: } // namespace lldb -#endif // LLDB_SBUnixSignals_h_ +#endif // LLDB_API_SBUNIXSIGNALS_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBValue.h b/gnu/llvm/lldb/include/lldb/API/SBValue.h index 5f8d17f8642..69be02545b3 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBValue.h +++ b/gnu/llvm/lldb/include/lldb/API/SBValue.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBValue_h_ -#define LLDB_SBValue_h_ +#ifndef LLDB_API_SBVALUE_H +#define LLDB_API_SBVALUE_H #include "lldb/API/SBData.h" #include "lldb/API/SBDefines.h" @@ -430,4 +430,4 @@ private: } // namespace lldb -#endif // LLDB_SBValue_h_ +#endif // LLDB_API_SBVALUE_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBValueList.h b/gnu/llvm/lldb/include/lldb/API/SBValueList.h index d305b3564c2..dc8389b7529 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBValueList.h +++ b/gnu/llvm/lldb/include/lldb/API/SBValueList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBValueList_h_ -#define LLDB_SBValueList_h_ +#ifndef LLDB_API_SBVALUELIST_H +#define LLDB_API_SBVALUELIST_H #include "lldb/API/SBDefines.h" @@ -72,4 +72,4 @@ private: } // namespace lldb -#endif // LLDB_SBValueList_h_ +#endif // LLDB_API_SBVALUELIST_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBVariablesOptions.h b/gnu/llvm/lldb/include/lldb/API/SBVariablesOptions.h index e226ce4ae13..53ab4b7e14f 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBVariablesOptions.h +++ b/gnu/llvm/lldb/include/lldb/API/SBVariablesOptions.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBVariablesOptions_h_ -#define LLDB_SBVariablesOptions_h_ +#ifndef LLDB_API_SBVARIABLESOPTIONS_H +#define LLDB_API_SBVARIABLESOPTIONS_H #include "lldb/API/SBDefines.h" @@ -79,4 +79,4 @@ private: } // namespace lldb -#endif // LLDB_SBValue_h_ +#endif // LLDB_API_SBVARIABLESOPTIONS_H diff --git a/gnu/llvm/lldb/include/lldb/API/SBWatchpoint.h b/gnu/llvm/lldb/include/lldb/API/SBWatchpoint.h index 05ff0ca7e44..08c5faa3a92 100644 --- a/gnu/llvm/lldb/include/lldb/API/SBWatchpoint.h +++ b/gnu/llvm/lldb/include/lldb/API/SBWatchpoint.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBWatchpoint_h_ -#define LLDB_SBWatchpoint_h_ +#ifndef LLDB_API_SBWATCHPOINT_H +#define LLDB_API_SBWATCHPOINT_H #include "lldb/API/SBDefines.h" @@ -82,4 +82,4 @@ private: } // namespace lldb -#endif // LLDB_SBWatchpoint_h_ +#endif // LLDB_API_SBWATCHPOINT_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/Breakpoint.h b/gnu/llvm/lldb/include/lldb/Breakpoint/Breakpoint.h index 94411bd57a6..d29d21070fd 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/Breakpoint.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/Breakpoint.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Breakpoint_h_ -#define liblldb_Breakpoint_h_ +#ifndef LLDB_BREAKPOINT_BREAKPOINT_H +#define LLDB_BREAKPOINT_BREAKPOINT_H #include #include @@ -137,12 +137,14 @@ public: lldb::BreakpointSP m_new_breakpoint_sp; BreakpointLocationCollection m_locations; - DISALLOW_COPY_AND_ASSIGN(BreakpointEventData); + BreakpointEventData(const BreakpointEventData &) = delete; + const BreakpointEventData &operator=(const BreakpointEventData &) = delete; }; // Saving & restoring breakpoints: static lldb::BreakpointSP CreateFromStructuredData( - Target &target, StructuredData::ObjectSP &data_object_sp, Status &error); + lldb::TargetSP target_sp, StructuredData::ObjectSP &data_object_sp, + Status &error); static bool SerializedBreakpointMatchesNames(StructuredData::ObjectSP &bkpt_object_sp, @@ -568,6 +570,11 @@ public: return GetPermissions().GetAllowDelete(); } + // This one should only be used by Target to copy breakpoints from target to + // target - primarily from the dummy target to prime new targets. + static lldb::BreakpointSP CopyFromBreakpoint(lldb::TargetSP new_target, + const Breakpoint &bp_to_copy_from); + protected: friend class Target; // Protected Methods @@ -625,9 +632,8 @@ protected: } private: - // This one should only be used by Target to copy breakpoints from target to - // target - primarily from the dummy target to prime new targets. - Breakpoint(Target &new_target, Breakpoint &bp_to_copy_from); + // To call from CopyFromBreakpoint. + Breakpoint(Target &new_target, const Breakpoint &bp_to_copy_from); // For Breakpoint only bool m_being_created; @@ -664,9 +670,10 @@ private: void SendBreakpointChangedEvent(BreakpointEventData *data); - DISALLOW_COPY_AND_ASSIGN(Breakpoint); + Breakpoint(const Breakpoint &) = delete; + const Breakpoint &operator=(const Breakpoint &) = delete; }; } // namespace lldb_private -#endif // liblldb_Breakpoint_h_ +#endif // LLDB_BREAKPOINT_BREAKPOINT_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointID.h b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointID.h index 9daa5b6c5e8..64432f2d3cd 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointID.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointID.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_BreakpointID_h_ -#define liblldb_BreakpointID_h_ - +#ifndef LLDB_BREAKPOINT_BREAKPOINTID_H +#define LLDB_BREAKPOINT_BREAKPOINTID_H #include "lldb/lldb-private.h" @@ -95,4 +94,4 @@ protected: } // namespace lldb_private -#endif // liblldb_BreakpointID_h_ +#endif // LLDB_BREAKPOINT_BREAKPOINTID_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointIDList.h b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointIDList.h index c6429220c7f..924cb1f26b8 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointIDList.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointIDList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_BreakpointIDList_h_ -#define liblldb_BreakpointIDList_h_ +#ifndef LLDB_BREAKPOINT_BREAKPOINTIDLIST_H +#define LLDB_BREAKPOINT_BREAKPOINTIDLIST_H #include #include @@ -68,9 +68,10 @@ private: BreakpointIDArray m_breakpoint_ids; BreakpointID m_invalid_id; - DISALLOW_COPY_AND_ASSIGN(BreakpointIDList); + BreakpointIDList(const BreakpointIDList &) = delete; + const BreakpointIDList &operator=(const BreakpointIDList &) = delete; }; } // namespace lldb_private -#endif // liblldb_BreakpointIDList_h_ +#endif // LLDB_BREAKPOINT_BREAKPOINTIDLIST_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointList.h b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointList.h index ad68151fefc..346972ec3a1 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointList.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_BreakpointList_h_ -#define liblldb_BreakpointList_h_ +#ifndef LLDB_BREAKPOINT_BREAKPOINTLIST_H +#define LLDB_BREAKPOINT_BREAKPOINTLIST_H #include #include @@ -168,9 +168,10 @@ public: } private: - DISALLOW_COPY_AND_ASSIGN(BreakpointList); + BreakpointList(const BreakpointList &) = delete; + const BreakpointList &operator=(const BreakpointList &) = delete; }; } // namespace lldb_private -#endif // liblldb_BreakpointList_h_ +#endif // LLDB_BREAKPOINT_BREAKPOINTLIST_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointLocation.h b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointLocation.h index 86bb164162c..3fc571eaa29 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointLocation.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointLocation.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_BreakpointLocation_h_ -#define liblldb_BreakpointLocation_h_ +#ifndef LLDB_BREAKPOINT_BREAKPOINTLOCATION_H +#define LLDB_BREAKPOINT_BREAKPOINTLOCATION_H #include #include @@ -345,9 +345,10 @@ private: void SendBreakpointLocationChangedEvent(lldb::BreakpointEventType eventKind); - DISALLOW_COPY_AND_ASSIGN(BreakpointLocation); + BreakpointLocation(const BreakpointLocation &) = delete; + const BreakpointLocation &operator=(const BreakpointLocation &) = delete; }; } // namespace lldb_private -#endif // liblldb_BreakpointLocation_h_ +#endif // LLDB_BREAKPOINT_BREAKPOINTLOCATION_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h index be400636877..ffdb81e363e 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_BreakpointLocationCollection_h_ -#define liblldb_BreakpointLocationCollection_h_ +#ifndef LLDB_BREAKPOINT_BREAKPOINTLOCATIONCOLLECTION_H +#define LLDB_BREAKPOINT_BREAKPOINTLOCATIONCOLLECTION_H #include #include @@ -175,4 +175,4 @@ public: } // namespace lldb_private -#endif // liblldb_BreakpointLocationCollection_h_ +#endif // LLDB_BREAKPOINT_BREAKPOINTLOCATIONCOLLECTION_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointLocationList.h b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointLocationList.h index 89ad2f54c92..4b36c919ee3 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointLocationList.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointLocationList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_BreakpointLocationList_h_ -#define liblldb_BreakpointLocationList_h_ +#ifndef LLDB_BREAKPOINT_BREAKPOINTLOCATIONLIST_H +#define LLDB_BREAKPOINT_BREAKPOINTLOCATIONLIST_H #include #include @@ -212,4 +212,4 @@ public: } // namespace lldb_private -#endif // liblldb_BreakpointLocationList_h_ +#endif // LLDB_BREAKPOINT_BREAKPOINTLOCATIONLIST_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointName.h b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointName.h index 61020a62807..8786dbc9a16 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointName.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointName.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Breakpoint_Name_h_ -#define liblldb_Breakpoint_Name_h_ +#ifndef LLDB_BREAKPOINT_BREAKPOINTNAME_H +#define LLDB_BREAKPOINT_BREAKPOINTNAME_H #include #include @@ -205,4 +205,4 @@ private: } // namespace lldb_private -#endif // liblldb_Breakpoint_Name_h_ +#endif // LLDB_BREAKPOINT_BREAKPOINTNAME_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointOptions.h b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointOptions.h index 2c52170eb9f..615b4eb77be 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointOptions.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointOptions.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_BreakpointOptions_h_ -#define liblldb_BreakpointOptions_h_ +#ifndef LLDB_BREAKPOINT_BREAKPOINTOPTIONS_H +#define LLDB_BREAKPOINT_BREAKPOINTOPTIONS_H #include #include @@ -406,4 +406,4 @@ private: } // namespace lldb_private -#endif // liblldb_BreakpointOptions_h_ +#endif // LLDB_BREAKPOINT_BREAKPOINTOPTIONS_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointPrecondition.h b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointPrecondition.h index 2a9461b52fa..5f0c11b595b 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointPrecondition.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointPrecondition.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_BreakpointPrecondition_h_ -#define liblldb_BreakpointPrecondition_h_ +#ifndef LLDB_BREAKPOINT_BREAKPOINTPRECONDITION_H +#define LLDB_BREAKPOINT_BREAKPOINTPRECONDITION_H #include "lldb/lldb-enumerations.h" diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolver.h b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolver.h index c1dbf9ac0ae..d067b1eea6f 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolver.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolver.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_BreakpointResolver_h_ -#define liblldb_BreakpointResolver_h_ +#ifndef LLDB_BREAKPOINT_BREAKPOINTRESOLVER_H +#define LLDB_BREAKPOINT_BREAKPOINTRESOLVER_H #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Core/Address.h" @@ -44,7 +44,8 @@ public: /// The breakpoint that owns this resolver. /// \param[in] resolverType /// The concrete breakpoint resolver type for this breakpoint. - BreakpointResolver(Breakpoint *bkpt, unsigned char resolverType, + BreakpointResolver(const lldb::BreakpointSP &bkpt, + unsigned char resolverType, lldb::addr_t offset = 0); /// The Destructor is virtual, all significant breakpoint resolvers derive @@ -55,7 +56,15 @@ public: /// /// \param[in] bkpt /// The breakpoint that owns this resolver. - void SetBreakpoint(Breakpoint *bkpt); + void SetBreakpoint(const lldb::BreakpointSP &bkpt); + + /// This gets the breakpoint for this resolver. + lldb::BreakpointSP GetBreakpoint() const { + auto breakpoint_sp = m_breakpoint.expired() ? lldb::BreakpointSP() : + m_breakpoint.lock(); + assert(breakpoint_sp); + return breakpoint_sp; + } /// This updates the offset for this breakpoint. All the locations /// currently set for this breakpoint will have their offset adjusted when @@ -65,12 +74,6 @@ public: /// The offset to add to all locations. void SetOffset(lldb::addr_t offset); - /// This updates the offset for this breakpoint. All the locations - /// currently set for this breakpoint will have their offset adjusted when - /// this is called. - /// - /// \param[in] offset - /// The offset to add to all locations. lldb::addr_t GetOffset() const { return m_offset; } /// In response to this method the resolver scans all the modules in the @@ -155,7 +158,7 @@ public: static ResolverTy NameToResolverTy(llvm::StringRef name); virtual lldb::BreakpointResolverSP - CopyForBreakpoint(Breakpoint &breakpoint) = 0; + CopyForBreakpoint(lldb::BreakpointSP &breakpoint) = 0; protected: // Used for serializing resolver options: @@ -208,20 +211,21 @@ protected: lldb::BreakpointLocationSP AddLocation(Address loc_addr, bool *new_location = nullptr); - Breakpoint *m_breakpoint; // This is the breakpoint we add locations to. - lldb::addr_t m_offset; // A random offset the user asked us to add to any - // breakpoints we set. - private: /// Helper for \p SetSCMatchesByLine. void AddLocation(SearchFilter &filter, const SymbolContext &sc, bool skip_prologue, llvm::StringRef log_ident); + lldb::BreakpointWP m_breakpoint; // This is the breakpoint we add locations to. + lldb::addr_t m_offset; // A random offset the user asked us to add to any + // breakpoints we set. + // Subclass identifier (for llvm isa/dyn_cast) const unsigned char SubclassID; - DISALLOW_COPY_AND_ASSIGN(BreakpointResolver); + BreakpointResolver(const BreakpointResolver &) = delete; + const BreakpointResolver &operator=(const BreakpointResolver &) = delete; }; } // namespace lldb_private -#endif // liblldb_BreakpointResolver_h_ +#endif // LLDB_BREAKPOINT_BREAKPOINTRESOLVER_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h index 3df89641c71..5454487e51a 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_BreakpointResolverAddress_h_ -#define liblldb_BreakpointResolverAddress_h_ +#ifndef LLDB_BREAKPOINT_BREAKPOINTRESOLVERADDRESS_H +#define LLDB_BREAKPOINT_BREAKPOINTRESOLVERADDRESS_H #include "lldb/Breakpoint/BreakpointResolver.h" #include "lldb/Core/ModuleSpec.h" @@ -21,15 +21,17 @@ namespace lldb_private { class BreakpointResolverAddress : public BreakpointResolver { public: - BreakpointResolverAddress(Breakpoint *bkpt, const Address &addr); + BreakpointResolverAddress(const lldb::BreakpointSP &bkpt, + const Address &addr); - BreakpointResolverAddress(Breakpoint *bkpt, const Address &addr, + BreakpointResolverAddress(const lldb::BreakpointSP &bkpt, + const Address &addr, const FileSpec &module_spec); - ~BreakpointResolverAddress() override; + ~BreakpointResolverAddress() override = default; static BreakpointResolver * - CreateFromStructuredData(Breakpoint *bkpt, + CreateFromStructuredData(const lldb::BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict, Status &error); @@ -56,11 +58,12 @@ public: return V->getResolverID() == BreakpointResolver::AddressResolver; } - lldb::BreakpointResolverSP CopyForBreakpoint(Breakpoint &breakpoint) override; + lldb::BreakpointResolverSP + CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override; protected: - Address - m_addr; // The address - may be Section Offset or may be just an offset + Address m_addr; // The address - may be Section Offset or + // may be just an offset lldb::addr_t m_resolved_addr; // The current value of the resolved load // address for this breakpoint, FileSpec m_module_filespec; // If this filespec is Valid, and m_addr is an @@ -68,9 +71,11 @@ protected: // to a Section+Offset address in this module, whenever that module gets // around to being loaded. private: - DISALLOW_COPY_AND_ASSIGN(BreakpointResolverAddress); + BreakpointResolverAddress(const BreakpointResolverAddress &) = delete; + const BreakpointResolverAddress & + operator=(const BreakpointResolverAddress &) = delete; }; } // namespace lldb_private -#endif // liblldb_BreakpointResolverAddress_h_ +#endif // LLDB_BREAKPOINT_BREAKPOINTRESOLVERADDRESS_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h index 9ca48ecf0dc..222fc6fcd45 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_BreakpointResolverFileLine_h_ -#define liblldb_BreakpointResolverFileLine_h_ +#ifndef LLDB_BREAKPOINT_BREAKPOINTRESOLVERFILELINE_H +#define LLDB_BREAKPOINT_BREAKPOINTRESOLVERFILELINE_H #include "lldb/Breakpoint/BreakpointResolver.h" @@ -20,19 +20,20 @@ namespace lldb_private { class BreakpointResolverFileLine : public BreakpointResolver { public: - BreakpointResolverFileLine(Breakpoint *bkpt, const FileSpec &resolver, + BreakpointResolverFileLine(const lldb::BreakpointSP &bkpt, + const FileSpec &resolver, 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, + CreateFromStructuredData(const lldb::BreakpointSP &bkpt, const StructuredData::Dictionary &data_dict, Status &error); StructuredData::ObjectSP SerializeToStructuredData() override; - ~BreakpointResolverFileLine() override; + ~BreakpointResolverFileLine() override = default; Searcher::CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context, @@ -52,7 +53,8 @@ public: return V->getResolverID() == BreakpointResolver::FileLineResolver; } - lldb::BreakpointResolverSP CopyForBreakpoint(Breakpoint &breakpoint) override; + lldb::BreakpointResolverSP + CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override; protected: void FilterContexts(SymbolContextList &sc_list, bool is_relative); @@ -67,9 +69,11 @@ protected: bool m_exact_match; private: - DISALLOW_COPY_AND_ASSIGN(BreakpointResolverFileLine); + BreakpointResolverFileLine(const BreakpointResolverFileLine &) = delete; + const BreakpointResolverFileLine & + operator=(const BreakpointResolverFileLine &) = delete; }; } // namespace lldb_private -#endif // liblldb_BreakpointResolverFileLine_h_ +#endif // LLDB_BREAKPOINT_BREAKPOINTRESOLVERFILELINE_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverFileRegex.h b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverFileRegex.h index df4c13ed59e..138d555e223 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverFileRegex.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverFileRegex.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_BreakpointResolverFileRegex_h_ -#define liblldb_BreakpointResolverFileRegex_h_ +#ifndef LLDB_BREAKPOINT_BREAKPOINTRESOLVERFILEREGEX_H +#define LLDB_BREAKPOINT_BREAKPOINTRESOLVERFILEREGEX_H #include #include "lldb/Breakpoint/BreakpointResolver.h" @@ -24,17 +24,17 @@ namespace lldb_private { class BreakpointResolverFileRegex : public BreakpointResolver { public: BreakpointResolverFileRegex( - Breakpoint *bkpt, RegularExpression regex, + const lldb::BreakpointSP &bkpt, RegularExpression regex, const std::unordered_set &func_name_set, bool exact_match); static BreakpointResolver * - CreateFromStructuredData(Breakpoint *bkpt, + CreateFromStructuredData(const lldb::BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict, Status &error); StructuredData::ObjectSP SerializeToStructuredData() override; - ~BreakpointResolverFileRegex() override; + ~BreakpointResolverFileRegex() override = default; Searcher::CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context, @@ -56,7 +56,8 @@ public: return V->getResolverID() == BreakpointResolver::FileRegexResolver; } - lldb::BreakpointResolverSP CopyForBreakpoint(Breakpoint &breakpoint) override; + lldb::BreakpointResolverSP + CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override; protected: friend class Breakpoint; @@ -69,9 +70,11 @@ protected: // comp_unit passed in. private: - DISALLOW_COPY_AND_ASSIGN(BreakpointResolverFileRegex); + BreakpointResolverFileRegex(const BreakpointResolverFileRegex &) = delete; + const BreakpointResolverFileRegex & + operator=(const BreakpointResolverFileRegex &) = delete; }; } // namespace lldb_private -#endif // liblldb_BreakpointResolverFileRegex_h_ +#endif // LLDB_BREAKPOINT_BREAKPOINTRESOLVERFILEREGEX_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverName.h b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverName.h index 196d88db848..7a9fc466076 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverName.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverName.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_BreakpointResolverName_h_ -#define liblldb_BreakpointResolverName_h_ +#ifndef LLDB_BREAKPOINT_BREAKPOINTRESOLVERNAME_H +#define LLDB_BREAKPOINT_BREAKPOINTRESOLVERNAME_H #include #include @@ -23,39 +23,41 @@ namespace lldb_private { class BreakpointResolverName : public BreakpointResolver { public: - BreakpointResolverName(Breakpoint *bkpt, const char *name, + BreakpointResolverName(const lldb::BreakpointSP &bkpt, const char *name, 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[], + BreakpointResolverName(const lldb::BreakpointSP &bkpt, const char *names[], 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, + BreakpointResolverName(const lldb::BreakpointSP &bkpt, + std::vector names, 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. - BreakpointResolverName(Breakpoint *bkpt, RegularExpression func_regex, + BreakpointResolverName(const lldb::BreakpointSP &bkpt, + RegularExpression func_regex, lldb::LanguageType language, lldb::addr_t offset, bool skip_prologue); static BreakpointResolver * - CreateFromStructuredData(Breakpoint *bkpt, + CreateFromStructuredData(const lldb::BreakpointSP &bkpt, const StructuredData::Dictionary &data_dict, Status &error); StructuredData::ObjectSP SerializeToStructuredData() override; - ~BreakpointResolverName() override; + ~BreakpointResolverName() override = default; Searcher::CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context, @@ -73,7 +75,8 @@ public: return V->getResolverID() == BreakpointResolver::NameResolver; } - lldb::BreakpointResolverSP CopyForBreakpoint(Breakpoint &breakpoint) override; + lldb::BreakpointResolverSP + CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override; protected: BreakpointResolverName(const BreakpointResolverName &rhs); @@ -91,4 +94,4 @@ protected: } // namespace lldb_private -#endif // liblldb_BreakpointResolverName_h_ +#endif // LLDB_BREAKPOINT_BREAKPOINTRESOLVERNAME_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h index 89a7d03ce93..26fd6f2f04d 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_BreakpointResolverScripted_h_ -#define liblldb_BreakpointResolverScripted_h_ +#ifndef LLDB_BREAKPOINT_BREAKPOINTRESOLVERSCRIPTED_H +#define LLDB_BREAKPOINT_BREAKPOINTRESOLVERSCRIPTED_H #include "lldb/lldb-forward.h" #include "lldb/Breakpoint/BreakpointResolver.h" @@ -23,15 +23,15 @@ namespace lldb_private { class BreakpointResolverScripted : public BreakpointResolver { public: - BreakpointResolverScripted(Breakpoint *bkpt, + BreakpointResolverScripted(const lldb::BreakpointSP &bkpt, const llvm::StringRef class_name, lldb::SearchDepth depth, StructuredDataImpl *args_data); - ~BreakpointResolverScripted() override; + ~BreakpointResolverScripted() override = default; static BreakpointResolver * - CreateFromStructuredData(Breakpoint *bkpt, + CreateFromStructuredData(const lldb::BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict, Status &error); @@ -53,12 +53,13 @@ public: return V->getResolverID() == BreakpointResolver::PythonResolver; } - lldb::BreakpointResolverSP CopyForBreakpoint(Breakpoint &breakpoint) override; + lldb::BreakpointResolverSP + CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override; protected: void NotifyBreakpointSet() override; private: - void CreateImplementationIfNeeded(); + void CreateImplementationIfNeeded(lldb::BreakpointSP bkpt); ScriptInterpreter *GetScriptInterpreter(); std::string m_class_name; @@ -69,9 +70,11 @@ private: // SBStructuredData). StructuredData::GenericSP m_implementation_sp; - DISALLOW_COPY_AND_ASSIGN(BreakpointResolverScripted); + BreakpointResolverScripted(const BreakpointResolverScripted &) = delete; + const BreakpointResolverScripted & + operator=(const BreakpointResolverScripted &) = delete; }; } // namespace lldb_private -#endif // liblldb_BreakpointResolverScripted_h_ +#endif // LLDB_BREAKPOINT_BREAKPOINTRESOLVERSCRIPTED_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointSite.h b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointSite.h index 5c9f79a9ab1..5ce17f511db 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointSite.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointSite.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_BreakpointSite_h_ -#define liblldb_BreakpointSite_h_ - +#ifndef LLDB_BREAKPOINT_BREAKPOINTSITE_H +#define LLDB_BREAKPOINT_BREAKPOINTSITE_H #include #include @@ -61,6 +60,8 @@ public: /// Sets the trap opcode bool SetTrapOpcode(const uint8_t *trap_opcode, uint32_t trap_opcode_size); + void SetHardwareIndex(uint32_t index) override; + /// Gets the original instruction bytes that were overwritten by the trap uint8_t *GetSavedOpcodeBytes(); @@ -224,9 +225,10 @@ private: const lldb::BreakpointLocationSP &owner, lldb::addr_t m_addr, bool use_hardware); - DISALLOW_COPY_AND_ASSIGN(BreakpointSite); + BreakpointSite(const BreakpointSite &) = delete; + const BreakpointSite &operator=(const BreakpointSite &) = delete; }; } // namespace lldb_private -#endif // liblldb_BreakpointSite_h_ +#endif // LLDB_BREAKPOINT_BREAKPOINTSITE_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointSiteList.h b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointSiteList.h index b10d119fcce..98091bbaeb0 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointSiteList.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/BreakpointSiteList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_BreakpointSiteList_h_ -#define liblldb_BreakpointSiteList_h_ +#ifndef LLDB_BREAKPOINT_BREAKPOINTSITELIST_H +#define LLDB_BREAKPOINT_BREAKPOINTSITELIST_H #include #include @@ -170,4 +170,4 @@ protected: } // namespace lldb_private -#endif // liblldb_BreakpointSiteList_h_ +#endif // LLDB_BREAKPOINT_BREAKPOINTSITELIST_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/Stoppoint.h b/gnu/llvm/lldb/include/lldb/Breakpoint/Stoppoint.h index f20b1007405..36df77c4e91 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/Stoppoint.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/Stoppoint.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Stoppoint_h_ -#define liblldb_Stoppoint_h_ +#ifndef LLDB_BREAKPOINT_STOPPOINT_H +#define LLDB_BREAKPOINT_STOPPOINT_H #include "lldb/Utility/UserID.h" #include "lldb/lldb-private.h" @@ -37,9 +37,10 @@ protected: private: // For Stoppoint only - DISALLOW_COPY_AND_ASSIGN(Stoppoint); + Stoppoint(const Stoppoint &) = delete; + const Stoppoint &operator=(const Stoppoint &) = delete; }; } // namespace lldb_private -#endif // liblldb_Stoppoint_h_ +#endif // LLDB_BREAKPOINT_STOPPOINT_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/StoppointCallbackContext.h b/gnu/llvm/lldb/include/lldb/Breakpoint/StoppointCallbackContext.h index c1724a6b276..db02ddd494f 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/StoppointCallbackContext.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/StoppointCallbackContext.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StoppointCallbackContext_h_ -#define liblldb_StoppointCallbackContext_h_ +#ifndef LLDB_BREAKPOINT_STOPPOINTCALLBACKCONTEXT_H +#define LLDB_BREAKPOINT_STOPPOINTCALLBACKCONTEXT_H #include "lldb/Target/ExecutionContext.h" #include "lldb/lldb-private.h" @@ -48,4 +48,4 @@ public: } // namespace lldb_private -#endif // liblldb_StoppointCallbackContext_h_ +#endif // LLDB_BREAKPOINT_STOPPOINTCALLBACKCONTEXT_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/StoppointLocation.h b/gnu/llvm/lldb/include/lldb/Breakpoint/StoppointLocation.h index 3926f452e56..4d6ca044ccc 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/StoppointLocation.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/StoppointLocation.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StoppointLocation_h_ -#define liblldb_StoppointLocation_h_ +#ifndef LLDB_BREAKPOINT_STOPPOINTLOCATION_H +#define LLDB_BREAKPOINT_STOPPOINTLOCATION_H #include "lldb/Utility/UserID.h" #include "lldb/lldb-private.h" @@ -48,7 +48,7 @@ public: virtual void Dump(Stream *stream) const {} - void SetHardwareIndex(uint32_t index) { m_hardware_index = index; } + virtual void SetHardwareIndex(uint32_t index) { m_hardware_index = index; } lldb::break_id_t GetID() const { return m_loc_id; } @@ -77,10 +77,11 @@ protected: private: // For StoppointLocation only - DISALLOW_COPY_AND_ASSIGN(StoppointLocation); + StoppointLocation(const StoppointLocation &) = delete; + const StoppointLocation &operator=(const StoppointLocation &) = delete; StoppointLocation() = delete; }; } // namespace lldb_private -#endif // liblldb_StoppointLocation_h_ +#endif // LLDB_BREAKPOINT_STOPPOINTLOCATION_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/Watchpoint.h b/gnu/llvm/lldb/include/lldb/Breakpoint/Watchpoint.h index 2cc74bb4c63..bce15f0a85d 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/Watchpoint.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/Watchpoint.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Watchpoint_h_ -#define liblldb_Watchpoint_h_ +#ifndef LLDB_BREAKPOINT_WATCHPOINT_H +#define LLDB_BREAKPOINT_WATCHPOINT_H #include #include @@ -54,7 +54,8 @@ public: lldb::WatchpointEventType m_watchpoint_event; lldb::WatchpointSP m_new_watchpoint_sp; - DISALLOW_COPY_AND_ASSIGN(WatchpointEventData); + WatchpointEventData(const WatchpointEventData &) = delete; + const WatchpointEventData &operator=(const WatchpointEventData &) = delete; }; Watchpoint(Target &target, lldb::addr_t addr, uint32_t size, @@ -160,8 +161,8 @@ private: void ResetHitCount() { m_hit_count = 0; } void ResetHistoricValues() { - m_old_value_sp.reset(nullptr); - m_new_value_sp.reset(nullptr); + m_old_value_sp.reset(); + m_new_value_sp.reset(); } Target &m_target; @@ -204,9 +205,10 @@ private: void SendWatchpointChangedEvent(WatchpointEventData *data); - DISALLOW_COPY_AND_ASSIGN(Watchpoint); + Watchpoint(const Watchpoint &) = delete; + const Watchpoint &operator=(const Watchpoint &) = delete; }; } // namespace lldb_private -#endif // liblldb_Watchpoint_h_ +#endif // LLDB_BREAKPOINT_WATCHPOINT_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/WatchpointList.h b/gnu/llvm/lldb/include/lldb/Breakpoint/WatchpointList.h index bb73d4ab75d..283f991b178 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/WatchpointList.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/WatchpointList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_WatchpointList_h_ -#define liblldb_WatchpointList_h_ +#ifndef LLDB_BREAKPOINT_WATCHPOINTLIST_H +#define LLDB_BREAKPOINT_WATCHPOINTLIST_H #include #include @@ -203,4 +203,4 @@ protected: } // namespace lldb_private -#endif // liblldb_WatchpointList_h_ +#endif // LLDB_BREAKPOINT_WATCHPOINTLIST_H diff --git a/gnu/llvm/lldb/include/lldb/Breakpoint/WatchpointOptions.h b/gnu/llvm/lldb/include/lldb/Breakpoint/WatchpointOptions.h index 0dc34d4ebef..0a18c52d36d 100644 --- a/gnu/llvm/lldb/include/lldb/Breakpoint/WatchpointOptions.h +++ b/gnu/llvm/lldb/include/lldb/Breakpoint/WatchpointOptions.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_WatchpointOptions_h_ -#define liblldb_WatchpointOptions_h_ +#ifndef LLDB_BREAKPOINT_WATCHPOINTOPTIONS_H +#define LLDB_BREAKPOINT_WATCHPOINTOPTIONS_H #include #include @@ -198,4 +198,4 @@ private: } // namespace lldb_private -#endif // liblldb_WatchpointOptions_h_ +#endif // LLDB_BREAKPOINT_WATCHPOINTOPTIONS_H diff --git a/gnu/llvm/lldb/include/lldb/Core/Address.h b/gnu/llvm/lldb/include/lldb/Core/Address.h index 70a7f790e40..71e50b91d68 100644 --- a/gnu/llvm/lldb/include/lldb/Core/Address.h +++ b/gnu/llvm/lldb/include/lldb/Core/Address.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Address_h_ -#define liblldb_Address_h_ +#ifndef LLDB_CORE_ADDRESS_H +#define LLDB_CORE_ADDRESS_H #include "lldb/lldb-defines.h" #include "lldb/lldb-forward.h" @@ -515,4 +515,4 @@ bool operator!=(const Address &lhs, const Address &rhs); } // namespace lldb_private -#endif // liblldb_Address_h_ +#endif // LLDB_CORE_ADDRESS_H diff --git a/gnu/llvm/lldb/include/lldb/Core/AddressRange.h b/gnu/llvm/lldb/include/lldb/Core/AddressRange.h index ac748713a18..8ccf96a436a 100644 --- a/gnu/llvm/lldb/include/lldb/Core/AddressRange.h +++ b/gnu/llvm/lldb/include/lldb/Core/AddressRange.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AddressRange_h_ -#define liblldb_AddressRange_h_ +#ifndef LLDB_CORE_ADDRESSRANGE_H +#define LLDB_CORE_ADDRESSRANGE_H #include "lldb/Core/Address.h" #include "lldb/lldb-forward.h" @@ -247,4 +247,4 @@ protected: } // namespace lldb_private -#endif // liblldb_AddressRange_h_ +#endif // LLDB_CORE_ADDRESSRANGE_H diff --git a/gnu/llvm/lldb/include/lldb/Core/AddressResolver.h b/gnu/llvm/lldb/include/lldb/Core/AddressResolver.h index cd95c7c31cd..9ac058a97cd 100644 --- a/gnu/llvm/lldb/include/lldb/Core/AddressResolver.h +++ b/gnu/llvm/lldb/include/lldb/Core/AddressResolver.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AddressResolver_h_ -#define liblldb_AddressResolver_h_ +#ifndef LLDB_CORE_ADDRESSRESOLVER_H +#define LLDB_CORE_ADDRESSRESOLVER_H #include "lldb/Core/AddressRange.h" #include "lldb/Core/SearchFilter.h" @@ -55,9 +55,10 @@ protected: std::vector m_address_ranges; private: - DISALLOW_COPY_AND_ASSIGN(AddressResolver); + AddressResolver(const AddressResolver &) = delete; + const AddressResolver &operator=(const AddressResolver &) = delete; }; } // namespace lldb_private -#endif // liblldb_AddressResolver_h_ +#endif // LLDB_CORE_ADDRESSRESOLVER_H diff --git a/gnu/llvm/lldb/include/lldb/Core/AddressResolverFileLine.h b/gnu/llvm/lldb/include/lldb/Core/AddressResolverFileLine.h index efbe3de1f29..46bf4155e86 100644 --- a/gnu/llvm/lldb/include/lldb/Core/AddressResolverFileLine.h +++ b/gnu/llvm/lldb/include/lldb/Core/AddressResolverFileLine.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AddressResolverFileLine_h_ -#define liblldb_AddressResolverFileLine_h_ +#ifndef LLDB_CORE_ADDRESSRESOLVERFILELINE_H +#define LLDB_CORE_ADDRESSRESOLVERFILELINE_H #include "lldb/Core/AddressResolver.h" #include "lldb/Core/SearchFilter.h" @@ -48,9 +48,11 @@ protected: // functions or not. private: - DISALLOW_COPY_AND_ASSIGN(AddressResolverFileLine); + AddressResolverFileLine(const AddressResolverFileLine &) = delete; + const AddressResolverFileLine & + operator=(const AddressResolverFileLine &) = delete; }; } // namespace lldb_private -#endif // liblldb_AddressResolverFileLine_h_ +#endif // LLDB_CORE_ADDRESSRESOLVERFILELINE_H diff --git a/gnu/llvm/lldb/include/lldb/Core/AddressResolverName.h b/gnu/llvm/lldb/include/lldb/Core/AddressResolverName.h index 8a039f9e1d9..0ec1ef05b0e 100644 --- a/gnu/llvm/lldb/include/lldb/Core/AddressResolverName.h +++ b/gnu/llvm/lldb/include/lldb/Core/AddressResolverName.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AddressResolverName_h_ -#define liblldb_AddressResolverName_h_ +#ifndef LLDB_CORE_ADDRESSRESOLVERNAME_H +#define LLDB_CORE_ADDRESSRESOLVERNAME_H #include "lldb/Core/AddressResolver.h" #include "lldb/Core/SearchFilter.h" @@ -54,9 +54,10 @@ protected: AddressResolver::MatchType m_match_type; private: - DISALLOW_COPY_AND_ASSIGN(AddressResolverName); + AddressResolverName(const AddressResolverName &) = delete; + const AddressResolverName &operator=(const AddressResolverName &) = delete; }; } // namespace lldb_private -#endif // liblldb_AddressResolverName_h_ +#endif // LLDB_CORE_ADDRESSRESOLVERNAME_H diff --git a/gnu/llvm/lldb/include/lldb/Core/Communication.h b/gnu/llvm/lldb/include/lldb/Core/Communication.h index 901b8fdb8c8..6b65974f952 100644 --- a/gnu/llvm/lldb/include/lldb/Core/Communication.h +++ b/gnu/llvm/lldb/include/lldb/Core/Communication.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Communication_h_ -#define liblldb_Communication_h_ +#ifndef LLDB_CORE_COMMUNICATION_H +#define LLDB_CORE_COMMUNICATION_H #include "lldb/Host/HostThread.h" #include "lldb/Utility/Broadcaster.h" @@ -221,7 +221,7 @@ public: /// /// \see /// class Connection - void SetConnection(Connection *connection); + void SetConnection(std::unique_ptr connection); /// Starts a read thread whose sole purpose it to read bytes from the /// current connection. This function will call connection's read function: @@ -359,9 +359,10 @@ protected: size_t GetCachedBytes(void *dst, size_t dst_len); private: - DISALLOW_COPY_AND_ASSIGN(Communication); + Communication(const Communication &) = delete; + const Communication &operator=(const Communication &) = delete; }; } // namespace lldb_private -#endif // liblldb_Communication_h_ +#endif // LLDB_CORE_COMMUNICATION_H diff --git a/gnu/llvm/lldb/include/lldb/Core/Debugger.h b/gnu/llvm/lldb/include/lldb/Core/Debugger.h index a8048427c8f..7bea0dbae08 100644 --- a/gnu/llvm/lldb/include/lldb/Core/Debugger.h +++ b/gnu/llvm/lldb/include/lldb/Core/Debugger.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Debugger_h_ -#define liblldb_Debugger_h_ +#ifndef LLDB_CORE_DEBUGGER_H +#define LLDB_CORE_DEBUGGER_H #include @@ -190,13 +190,15 @@ public: lldb::StreamFileSP &out, lldb::StreamFileSP &err); - void PushIOHandler(const lldb::IOHandlerSP &reader_sp, - bool cancel_top_handler = true); + /// Run the given IO handler and return immediately. + void RunIOHandlerAsync(const lldb::IOHandlerSP &reader_sp, + bool cancel_top_handler = true); - bool PopIOHandler(const lldb::IOHandlerSP &reader_sp); + /// Run the given IO handler and block until it's complete. + void RunIOHandlerSync(const lldb::IOHandlerSP &reader_sp); - // Synchronously run an input reader until it is done - void RunIOHandler(const lldb::IOHandlerSP &reader_sp); + /// Remove the given IO handler if it's currently active. + bool RemoveIOHandler(const lldb::IOHandlerSP &reader_sp); bool IsTopIOHandler(const lldb::IOHandlerSP &reader_sp); @@ -271,6 +273,10 @@ public: bool SetUseColor(bool use_color); + bool GetUseSourceCache() const; + + bool SetUseSourceCache(bool use_source_cache); + bool GetHighlightSource() const; lldb::StopShowColumn GetStopShowColumn() const; @@ -285,6 +291,10 @@ public: uint32_t GetDisassemblyLineCount() const; + llvm::StringRef GetStopShowLineMarkerAnsiPrefix() const; + + llvm::StringRef GetStopShowLineMarkerAnsiSuffix() const; + bool GetAutoOneLineSummaries() const; bool GetAutoIndent() const; @@ -307,7 +317,7 @@ public: bool LoadPlugin(const FileSpec &spec, Status &error); - void ExecuteIOHandlers(); + void RunIOHandlers(); bool IsForwardingEvents(); @@ -339,6 +349,11 @@ protected: static lldb::thread_result_t EventHandlerThread(lldb::thread_arg_t arg); + void PushIOHandler(const lldb::IOHandlerSP &reader_sp, + bool cancel_top_handler = true); + + bool PopIOHandler(const lldb::IOHandlerSP &reader_sp); + bool HasIOHandlerThread(); bool StartIOHandlerThread(); @@ -402,7 +417,9 @@ protected: std::array m_script_interpreters; - IOHandlerStack m_input_reader_stack; + IOHandlerStack m_io_handler_stack; + std::recursive_mutex m_io_handler_synchronous_mutex; + llvm::StringMap> m_log_streams; std::shared_ptr m_log_callback_stream_sp; ConstString m_instance_name; @@ -426,9 +443,10 @@ private: // object Debugger(lldb::LogOutputCallback m_log_callback, void *baton); - DISALLOW_COPY_AND_ASSIGN(Debugger); + Debugger(const Debugger &) = delete; + const Debugger &operator=(const Debugger &) = delete; }; } // namespace lldb_private -#endif // liblldb_Debugger_h_ +#endif // LLDB_CORE_DEBUGGER_H diff --git a/gnu/llvm/lldb/include/lldb/Core/Disassembler.h b/gnu/llvm/lldb/include/lldb/Core/Disassembler.h index 7ece0eeb708..926a74b933e 100644 --- a/gnu/llvm/lldb/include/lldb/Core/Disassembler.h +++ b/gnu/llvm/lldb/include/lldb/Core/Disassembler.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Disassembler_h_ -#define liblldb_Disassembler_h_ +#ifndef LLDB_CORE_DISASSEMBLER_H +#define LLDB_CORE_DISASSEMBLER_H #include "lldb/Core/Address.h" #include "lldb/Core/EmulateInstruction.h" @@ -349,7 +349,8 @@ public: protected: std::string m_description; - DISALLOW_COPY_AND_ASSIGN(PseudoInstruction); + PseudoInstruction(const PseudoInstruction &) = delete; + const PseudoInstruction &operator=(const PseudoInstruction &) = delete; }; class Disassembler : public std::enable_shared_from_this, @@ -379,13 +380,19 @@ public: FindPlugin(const ArchSpec &arch, const char *flavor, const char *plugin_name); // This version will use the value in the Target settings if flavor is NULL; - static lldb::DisassemblerSP - FindPluginForTarget(const lldb::TargetSP target_sp, const ArchSpec &arch, - const char *flavor, const char *plugin_name); + static lldb::DisassemblerSP FindPluginForTarget(const Target &target, + const ArchSpec &arch, + const char *flavor, + const char *plugin_name); + + struct Limit { + enum { Bytes, Instructions } kind; + lldb::addr_t value; + }; static lldb::DisassemblerSP DisassembleRange(const ArchSpec &arch, const char *plugin_name, - const char *flavor, const ExecutionContext &exe_ctx, + const char *flavor, Target &target, const AddressRange &disasm_range, bool prefer_file_cache); static lldb::DisassemblerSP @@ -394,36 +401,13 @@ public: size_t length, uint32_t max_num_instructions, bool data_from_file); - static bool Disassemble(Debugger &debugger, const ArchSpec &arch, - const char *plugin_name, const char *flavor, - const ExecutionContext &exe_ctx, - const AddressRange &range, uint32_t num_instructions, - bool mixed_source_and_assembly, - uint32_t num_mixed_context_lines, uint32_t options, - Stream &strm); - static bool Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name, const char *flavor, const ExecutionContext &exe_ctx, const Address &start, - uint32_t num_instructions, - bool mixed_source_and_assembly, + Limit limit, bool mixed_source_and_assembly, uint32_t num_mixed_context_lines, uint32_t options, Stream &strm); - static size_t - Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name, - const char *flavor, const ExecutionContext &exe_ctx, - SymbolContextList &sc_list, uint32_t num_instructions, - bool mixed_source_and_assembly, uint32_t num_mixed_context_lines, - uint32_t options, Stream &strm); - - static bool - Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name, - const char *flavor, const ExecutionContext &exe_ctx, - ConstString name, Module *module, - uint32_t num_instructions, bool mixed_source_and_assembly, - uint32_t num_mixed_context_lines, uint32_t options, Stream &strm); - static bool Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name, const char *flavor, const ExecutionContext &exe_ctx, @@ -434,25 +418,14 @@ public: Disassembler(const ArchSpec &arch, const char *flavor); ~Disassembler() override; - typedef const char *(*SummaryCallback)(const Instruction &inst, - ExecutionContext *exe_context, - void *user_data); - - static bool PrintInstructions(Disassembler *disasm_ptr, Debugger &debugger, - const ArchSpec &arch, - const ExecutionContext &exe_ctx, - uint32_t num_instructions, - bool mixed_source_and_assembly, - uint32_t num_mixed_context_lines, - uint32_t options, Stream &strm); - - size_t ParseInstructions(const ExecutionContext *exe_ctx, - const AddressRange &range, Stream *error_strm_ptr, - bool prefer_file_cache); + void PrintInstructions(Debugger &debugger, const ArchSpec &arch, + const ExecutionContext &exe_ctx, + bool mixed_source_and_assembly, + uint32_t num_mixed_context_lines, uint32_t options, + Stream &strm); - size_t ParseInstructions(const ExecutionContext *exe_ctx, - const Address &range, uint32_t num_instructions, - bool prefer_file_cache); + size_t ParseInstructions(Target &target, Address address, Limit limit, + Stream *error_strm_ptr, bool prefer_file_cache); virtual size_t DecodeInstructions(const Address &base_addr, const DataExtractor &data, @@ -548,9 +521,10 @@ protected: private: // For Disassembler only - DISALLOW_COPY_AND_ASSIGN(Disassembler); + Disassembler(const Disassembler &) = delete; + const Disassembler &operator=(const Disassembler &) = delete; }; } // namespace lldb_private -#endif // liblldb_Disassembler_h_ +#endif // LLDB_CORE_DISASSEMBLER_H diff --git a/gnu/llvm/lldb/include/lldb/Core/EmulateInstruction.h b/gnu/llvm/lldb/include/lldb/Core/EmulateInstruction.h index 6b19c17e549..a575488ba96 100644 --- a/gnu/llvm/lldb/include/lldb/Core/EmulateInstruction.h +++ b/gnu/llvm/lldb/include/lldb/Core/EmulateInstruction.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_EmulateInstruction_h_ -#define lldb_EmulateInstruction_h_ +#ifndef LLDB_CORE_EMULATEINSTRUCTION_H +#define LLDB_CORE_EMULATEINSTRUCTION_H #include @@ -499,9 +499,10 @@ protected: private: // For EmulateInstruction only - DISALLOW_COPY_AND_ASSIGN(EmulateInstruction); + EmulateInstruction(const EmulateInstruction &) = delete; + const EmulateInstruction &operator=(const EmulateInstruction &) = delete; }; } // namespace lldb_private -#endif // lldb_EmulateInstruction_h_ +#endif // LLDB_CORE_EMULATEINSTRUCTION_H diff --git a/gnu/llvm/lldb/include/lldb/Core/FileLineResolver.h b/gnu/llvm/lldb/include/lldb/Core/FileLineResolver.h index d6525b71bfd..68e252e93bc 100644 --- a/gnu/llvm/lldb/include/lldb/Core/FileLineResolver.h +++ b/gnu/llvm/lldb/include/lldb/Core/FileLineResolver.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_FileLineResolver_h_ -#define liblldb_FileLineResolver_h_ +#ifndef LLDB_CORE_FILELINERESOLVER_H +#define LLDB_CORE_FILELINERESOLVER_H #include "lldb/Core/SearchFilter.h" #include "lldb/Symbol/SymbolContext.h" @@ -58,9 +58,10 @@ protected: // functions or not. private: - DISALLOW_COPY_AND_ASSIGN(FileLineResolver); + FileLineResolver(const FileLineResolver &) = delete; + const FileLineResolver &operator=(const FileLineResolver &) = delete; }; } // namespace lldb_private -#endif // liblldb_FileLineResolver_h_ +#endif // LLDB_CORE_FILELINERESOLVER_H diff --git a/gnu/llvm/lldb/include/lldb/Core/FileSpecList.h b/gnu/llvm/lldb/include/lldb/Core/FileSpecList.h index 8edc3280b01..3e412a7e1a3 100644 --- a/gnu/llvm/lldb/include/lldb/Core/FileSpecList.h +++ b/gnu/llvm/lldb/include/lldb/Core/FileSpecList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_FileSpecList_h_ -#define liblldb_FileSpecList_h_ +#ifndef LLDB_CORE_FILESPECLIST_H +#define LLDB_CORE_FILESPECLIST_H #if defined(__cplusplus) #include "lldb/Utility/FileSpec.h" @@ -204,4 +204,4 @@ protected: } // namespace lldb_private #endif // #if defined(__cplusplus) -#endif // liblldb_FileSpecList_h_ +#endif // LLDB_CORE_FILESPECLIST_H diff --git a/gnu/llvm/lldb/include/lldb/Core/FormatEntity.h b/gnu/llvm/lldb/include/lldb/Core/FormatEntity.h index 8ee320b0ebb..91999f64ab5 100644 --- a/gnu/llvm/lldb/include/lldb/Core/FormatEntity.h +++ b/gnu/llvm/lldb/include/lldb/Core/FormatEntity.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_FormatEntity_h_ -#define liblldb_FormatEntity_h_ +#ifndef LLDB_CORE_FORMATENTITY_H +#define LLDB_CORE_FORMATENTITY_H #include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/FileSpec.h" @@ -61,6 +61,7 @@ public: ThreadName, ThreadQueue, ThreadStopReason, + ThreadStopReasonRaw, ThreadReturnValue, ThreadCompletedExpression, ScriptThread, @@ -218,4 +219,4 @@ protected: }; } // namespace lldb_private -#endif // liblldb_FormatEntity_h_ +#endif // LLDB_CORE_FORMATENTITY_H diff --git a/gnu/llvm/lldb/include/lldb/Core/Highlighter.h b/gnu/llvm/lldb/include/lldb/Core/Highlighter.h index 8a268ec1d6b..b138e57af41 100644 --- a/gnu/llvm/lldb/include/lldb/Core/Highlighter.h +++ b/gnu/llvm/lldb/include/lldb/Core/Highlighter.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Highlighter_h_ -#define liblldb_Highlighter_h_ +#ifndef LLDB_CORE_HIGHLIGHTER_H +#define LLDB_CORE_HIGHLIGHTER_H #include #include @@ -91,7 +91,8 @@ class Highlighter { public: Highlighter() = default; virtual ~Highlighter() = default; - DISALLOW_COPY_AND_ASSIGN(Highlighter); + Highlighter(const Highlighter &) = delete; + const Highlighter &operator=(const Highlighter &) = delete; /// Returns a human readable name for the selected highlighter. virtual llvm::StringRef GetName() const = 0; @@ -152,4 +153,4 @@ public: } // namespace lldb_private -#endif // liblldb_Highlighter_h_ +#endif // LLDB_CORE_HIGHLIGHTER_H diff --git a/gnu/llvm/lldb/include/lldb/Core/IOHandler.h b/gnu/llvm/lldb/include/lldb/Core/IOHandler.h index 9ab5eaaecb6..51592afbbab 100644 --- a/gnu/llvm/lldb/include/lldb/Core/IOHandler.h +++ b/gnu/llvm/lldb/include/lldb/Core/IOHandler.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_IOHandler_h_ -#define liblldb_IOHandler_h_ +#ifndef LLDB_CORE_IOHANDLER_H +#define LLDB_CORE_IOHANDLER_H #include "lldb/Core/ValueObjectList.h" #include "lldb/Host/Config.h" @@ -95,6 +95,8 @@ public: virtual void Deactivate() { m_active = false; } + virtual void TerminalSizeChanged() {} + virtual const char *GetPrompt() { // Prompt support isn't mandatory return nullptr; @@ -178,7 +180,8 @@ protected: bool m_active; private: - DISALLOW_COPY_AND_ASSIGN(IOHandler); + IOHandler(const IOHandler &) = delete; + const IOHandler &operator=(const IOHandler &) = delete; }; /// A delegate class for use with IOHandler subclasses. @@ -369,6 +372,8 @@ public: void Deactivate() override; + void TerminalSizeChanged() override; + ConstString GetControlSequence(char ch) override { return m_delegate.IOHandlerGetControlSequence(ch); } @@ -540,9 +545,10 @@ protected: IOHandler *m_top = nullptr; private: - DISALLOW_COPY_AND_ASSIGN(IOHandlerStack); + IOHandlerStack(const IOHandlerStack &) = delete; + const IOHandlerStack &operator=(const IOHandlerStack &) = delete; }; } // namespace lldb_private -#endif // liblldb_IOHandler_h_ +#endif // LLDB_CORE_IOHANDLER_H diff --git a/gnu/llvm/lldb/include/lldb/Core/IOHandlerCursesGUI.h b/gnu/llvm/lldb/include/lldb/Core/IOHandlerCursesGUI.h index afa43526972..fe62eaea643 100644 --- a/gnu/llvm/lldb/include/lldb/Core/IOHandlerCursesGUI.h +++ b/gnu/llvm/lldb/include/lldb/Core/IOHandlerCursesGUI.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_IOHandlerCursesGUI_h_ -#define liblldb_IOHandlerCursesGUI_h_ +#ifndef LLDB_CORE_IOHANDLERCURSESGUI_H +#define LLDB_CORE_IOHANDLERCURSESGUI_H #include "lldb/Core/IOHandler.h" @@ -37,4 +37,4 @@ protected: } // namespace lldb_private -#endif // liblldb_IOHandlerCursesGUI_h_ +#endif // LLDB_CORE_IOHANDLERCURSESGUI_H diff --git a/gnu/llvm/lldb/include/lldb/Core/LoadedModuleInfoList.h b/gnu/llvm/lldb/include/lldb/Core/LoadedModuleInfoList.h index 04e58fcdf31..49400f7f490 100644 --- a/gnu/llvm/lldb/include/lldb/Core/LoadedModuleInfoList.h +++ b/gnu/llvm/lldb/include/lldb/Core/LoadedModuleInfoList.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_LoadedModuleInfoList_h_ -#define liblldb_LoadedModuleInfoList_h_ - +#ifndef LLDB_CORE_LOADEDMODULEINFOLIST_H +#define LLDB_CORE_LOADEDMODULEINFOLIST_H #include #include @@ -113,4 +112,4 @@ public: }; } // namespace lldb_private -#endif // liblldb_LoadedModuleInfoList_h_ +#endif // LLDB_CORE_LOADEDMODULEINFOLIST_H diff --git a/gnu/llvm/lldb/include/lldb/Core/Mangled.h b/gnu/llvm/lldb/include/lldb/Core/Mangled.h index 6af68c3f585..c03fc1eb759 100644 --- a/gnu/llvm/lldb/include/lldb/Core/Mangled.h +++ b/gnu/llvm/lldb/include/lldb/Core/Mangled.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Mangled_h_ -#define liblldb_Mangled_h_ +#ifndef LLDB_CORE_MANGLED_H +#define LLDB_CORE_MANGLED_H #if defined(__cplusplus) #include "lldb/lldb-enumerations.h" @@ -132,13 +132,13 @@ public: /// /// \return /// A const reference to the demangled name string object. - ConstString GetDemangledName(lldb::LanguageType language) const; + ConstString GetDemangledName() const; /// Display demangled name get accessor. /// /// \return /// A const reference to the display demangled name string object. - ConstString GetDisplayDemangledName(lldb::LanguageType language) const; + ConstString GetDisplayDemangledName() const; void SetDemangledName(ConstString name) { m_demangled = name; } @@ -165,8 +165,7 @@ public: /// A const reference to the preferred name string object if this /// object has a valid name of that kind, else a const reference to the /// other name is returned. - ConstString GetName(lldb::LanguageType language, - NamePreference preference = ePreferDemangled) const; + ConstString GetName(NamePreference preference = ePreferDemangled) const; /// Check if "name" matches either the mangled or demangled name. /// @@ -175,13 +174,12 @@ public: /// /// \return /// \b True if \a name matches either name, \b false otherwise. - bool NameMatches(ConstString name, lldb::LanguageType language) const { + bool NameMatches(ConstString name) const { if (m_mangled == name) return true; - return GetDemangledName(language) == name; + return GetDemangledName() == name; } - bool NameMatches(const RegularExpression ®ex, - lldb::LanguageType language) const; + bool NameMatches(const RegularExpression ®ex) const; /// Get the memory cost of this object. /// @@ -282,4 +280,4 @@ Stream &operator<<(Stream &s, const Mangled &obj); } // namespace lldb_private #endif // #if defined(__cplusplus) -#endif // liblldb_Mangled_h_ +#endif // LLDB_CORE_MANGLED_H diff --git a/gnu/llvm/lldb/include/lldb/Core/MappedHash.h b/gnu/llvm/lldb/include/lldb/Core/MappedHash.h index 7dc9b5be346..a27ec82b9b8 100644 --- a/gnu/llvm/lldb/include/lldb/Core/MappedHash.h +++ b/gnu/llvm/lldb/include/lldb/Core/MappedHash.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_MappedHash_h_ -#define liblldb_MappedHash_h_ +#ifndef LLDB_CORE_MAPPEDHASH_H +#define LLDB_CORE_MAPPEDHASH_H #include #include @@ -307,4 +307,4 @@ public: }; }; -#endif // liblldb_MappedHash_h_ +#endif // LLDB_CORE_MAPPEDHASH_H diff --git a/gnu/llvm/lldb/include/lldb/Core/Module.h b/gnu/llvm/lldb/include/lldb/Core/Module.h index 2af18c83f23..8bd70ab16b5 100644 --- a/gnu/llvm/lldb/include/lldb/Core/Module.h +++ b/gnu/llvm/lldb/include/lldb/Core/Module.h @@ -6,10 +6,11 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Module_h_ -#define liblldb_Module_h_ +#ifndef LLDB_CORE_MODULE_H +#define LLDB_CORE_MODULE_H #include "lldb/Core/Address.h" +#include "lldb/Core/ModuleList.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContextScope.h" @@ -19,6 +20,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" +#include "lldb/Utility/XcodeSDK.h" #include "lldb/Utility/UUID.h" #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" @@ -301,7 +303,7 @@ public: /// A symbol context list that gets filled in with all of the /// matches. void FindFunctions(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, lldb::FunctionNameType name_type_mask, bool symbols_ok, bool inlines_ok, SymbolContextList &sc_list); @@ -364,7 +366,7 @@ public: /// A list of variables that gets the matches appended to. /// void FindGlobalVariables(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, size_t max_matches, VariableList &variable_list); /// Find global and static variables by regular expression. @@ -443,7 +445,7 @@ public: /// \param[out] type_list /// A type list gets populated with any matches. void FindTypesInNamespace(ConstString type_name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, size_t max_matches, TypeList &type_list); /// Get const accessor for the module architecture. @@ -508,6 +510,11 @@ public: m_mod_time = mod_time; } + /// This callback will be called by SymbolFile implementations when + /// parsing a compile unit that contains SDK information. + /// \param sysroot will be added to the path remapping dictionary. + void RegisterXcodeSDK(llvm::StringRef sdk, llvm::StringRef sysroot); + /// Tells whether this module is capable of being the main executable for a /// process. /// @@ -951,6 +958,12 @@ protected: ///by \a m_file. uint64_t m_object_offset; llvm::sys::TimePoint<> m_object_mod_time; + + /// DataBuffer containing the module image, if it was provided at + /// construction time. Otherwise the data will be retrieved by mapping + /// one of the FileSpec members above. + lldb::DataBufferSP m_data_sp; + lldb::ObjectFileSP m_objfile_sp; ///< A shared pointer to the object file ///parser for this module as it may or may ///not be shared with the SymbolFile @@ -966,10 +979,11 @@ protected: ///references to them TypeSystemMap m_type_system_map; ///< A map of any type systems associated ///with this module - PathMappingList m_source_mappings; ///< Module specific source remappings for - ///when you have debug info for a module - ///that doesn't match where the sources - ///currently are + /// Module specific source remappings for when you have debug info for a + /// module that doesn't match where the sources currently are. + PathMappingList m_source_mappings = + ModuleList::GetGlobalModuleListProperties().GetSymlinkMappings(); + lldb::SectionListUP m_sections_up; ///< Unified section list for module that /// is used by the ObjectFile and and /// ObjectFile instances for the debug info @@ -1036,14 +1050,15 @@ private: Module(); // Only used internally by CreateJITModule () void FindTypes_Impl( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, size_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types); - DISALLOW_COPY_AND_ASSIGN(Module); + Module(const Module &) = delete; + const Module &operator=(const Module &) = delete; }; } // namespace lldb_private -#endif // liblldb_Module_h_ +#endif // LLDB_CORE_MODULE_H diff --git a/gnu/llvm/lldb/include/lldb/Core/ModuleChild.h b/gnu/llvm/lldb/include/lldb/Core/ModuleChild.h index 0d59e4fb12c..63eb1372ff6 100644 --- a/gnu/llvm/lldb/include/lldb/Core/ModuleChild.h +++ b/gnu/llvm/lldb/include/lldb/Core/ModuleChild.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ModuleChild_h_ -#define liblldb_ModuleChild_h_ +#ifndef LLDB_CORE_MODULECHILD_H +#define LLDB_CORE_MODULECHILD_H #include "lldb/lldb-forward.h" @@ -58,4 +58,4 @@ protected: } // namespace lldb_private -#endif // liblldb_ModuleChild_h_ +#endif // LLDB_CORE_MODULECHILD_H diff --git a/gnu/llvm/lldb/include/lldb/Core/ModuleList.h b/gnu/llvm/lldb/include/lldb/Core/ModuleList.h index a6e80ed75c7..d90b27e474a 100644 --- a/gnu/llvm/lldb/include/lldb/Core/ModuleList.h +++ b/gnu/llvm/lldb/include/lldb/Core/ModuleList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ModuleList_h_ -#define liblldb_ModuleList_h_ +#ifndef LLDB_CORE_MODULELIST_H +#define LLDB_CORE_MODULELIST_H #include "lldb/Core/Address.h" #include "lldb/Core/ModuleSpec.h" @@ -20,6 +20,7 @@ #include "lldb/lldb-types.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/Support/RWMutex.h" #include #include @@ -46,6 +47,11 @@ class UUID; class VariableList; class ModuleListProperties : public Properties { + mutable llvm::sys::RWMutex m_symlink_paths_mutex; + PathMappingList m_symlink_paths; + + void UpdateSymlinkMappings(); + public: ModuleListProperties(); @@ -53,6 +59,8 @@ public: bool SetClangModulesCachePath(llvm::StringRef path); bool GetEnableExternalLookup() const; bool SetEnableExternalLookup(bool new_value); + + PathMappingList GetSymlinkMappings() const; }; /// \class ModuleList ModuleList.h "lldb/Core/ModuleList.h" @@ -131,7 +139,13 @@ public: /// /// \param[in] module_sp /// A shared pointer to a module to replace in this collection. - void ReplaceEquivalent(const lldb::ModuleSP &module_sp); + /// + /// \param[in] old_modules + /// Optional pointer to a vector which, if provided, will have shared + /// pointers to the replaced module(s) appended to it. + void ReplaceEquivalent( + const lldb::ModuleSP &module_sp, + llvm::SmallVectorImpl *old_modules = nullptr); /// Append a module to the module list, if it is not already there. /// @@ -435,12 +449,11 @@ public: static bool ModuleIsInCache(const Module *module_ptr); - static Status GetSharedModule(const ModuleSpec &module_spec, - lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, - bool *did_create_ptr, - bool always_create = false); + static Status + GetSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, + bool *did_create_ptr, bool always_create = false); static bool RemoveSharedModule(lldb::ModuleSP &module_sp); @@ -489,4 +502,4 @@ public: } // namespace lldb_private -#endif // liblldb_ModuleList_h_ +#endif // LLDB_CORE_MODULELIST_H diff --git a/gnu/llvm/lldb/include/lldb/Core/ModuleSpec.h b/gnu/llvm/lldb/include/lldb/Core/ModuleSpec.h index 6d024fe3434..9dd398a0529 100644 --- a/gnu/llvm/lldb/include/lldb/Core/ModuleSpec.h +++ b/gnu/llvm/lldb/include/lldb/Core/ModuleSpec.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ModuleSpec_h_ -#define liblldb_ModuleSpec_h_ +#ifndef LLDB_CORE_MODULESPEC_H +#define LLDB_CORE_MODULESPEC_H #include "lldb/Host/FileSystem.h" #include "lldb/Target/PathMappingList.h" @@ -30,11 +30,19 @@ public: m_object_name(), m_object_offset(0), m_object_size(0), m_source_mappings() {} - ModuleSpec(const FileSpec &file_spec, const UUID &uuid = UUID()) + /// If the \param data argument is passed, its contents will be used + /// as the module contents instead of trying to read them from + /// \param file_spec. + ModuleSpec(const FileSpec &file_spec, const UUID &uuid = UUID(), + lldb::DataBufferSP data = lldb::DataBufferSP()) : 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(FileSystem::Instance().GetByteSize(file_spec)), - m_source_mappings() {} + m_uuid(uuid), m_object_name(), m_object_offset(0), m_source_mappings(), + m_data(data) { + if (data) + m_object_size = data->GetByteSize(); + else if (m_file) + m_object_size = FileSystem::Instance().GetByteSize(file_spec); + } ModuleSpec(const FileSpec &file_spec, const ArchSpec &arch) : m_file(file_spec), m_platform_file(), m_symbol_file(), m_arch(arch), @@ -42,30 +50,6 @@ public: 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), - m_symbol_file(rhs.m_symbol_file), m_arch(rhs.m_arch), - m_uuid(rhs.m_uuid), m_object_name(rhs.m_object_name), - m_object_offset(rhs.m_object_offset), m_object_size(rhs.m_object_size), - m_object_mod_time(rhs.m_object_mod_time), - m_source_mappings(rhs.m_source_mappings) {} - - ModuleSpec &operator=(const ModuleSpec &rhs) { - if (this != &rhs) { - m_file = rhs.m_file; - m_platform_file = rhs.m_platform_file; - m_symbol_file = rhs.m_symbol_file; - m_arch = rhs.m_arch; - m_uuid = rhs.m_uuid; - m_object_name = rhs.m_object_name; - m_object_offset = rhs.m_object_offset; - m_object_size = rhs.m_object_size; - m_object_mod_time = rhs.m_object_mod_time; - m_source_mappings = rhs.m_source_mappings; - } - return *this; - } - FileSpec *GetFileSpecPtr() { return (m_file ? &m_file : nullptr); } const FileSpec *GetFileSpecPtr() const { @@ -146,6 +130,8 @@ public: PathMappingList &GetSourceMappingList() const { return m_source_mappings; } + lldb::DataBufferSP GetData() const { return m_data; } + void Clear() { m_file.Clear(); m_platform_file.Clear(); @@ -289,6 +275,7 @@ protected: uint64_t m_object_size; llvm::sys::TimePoint<> m_object_mod_time; mutable PathMappingList m_source_mappings; + lldb::DataBufferSP m_data = {}; }; class ModuleSpecList { @@ -415,4 +402,4 @@ protected: } // namespace lldb_private -#endif // liblldb_ModuleSpec_h_ +#endif // LLDB_CORE_MODULESPEC_H diff --git a/gnu/llvm/lldb/include/lldb/Core/Opcode.h b/gnu/llvm/lldb/include/lldb/Core/Opcode.h index 1a30ce4834a..a812ae23f6b 100644 --- a/gnu/llvm/lldb/include/lldb/Core/Opcode.h +++ b/gnu/llvm/lldb/include/lldb/Core/Opcode.h @@ -6,13 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Opcode_h -#define lldb_Opcode_h +#ifndef LLDB_CORE_OPCODE_H +#define LLDB_CORE_OPCODE_H #include "lldb/Utility/Endian.h" #include "lldb/lldb-enumerations.h" -#include "llvm/Support/MathExtras.h" +#include "llvm/Support/SwapByteOrder.h" #include #include @@ -270,4 +270,4 @@ protected: } // namespace lldb_private -#endif // lldb_Opcode_h +#endif // LLDB_CORE_OPCODE_H diff --git a/gnu/llvm/lldb/include/lldb/Core/PluginInterface.h b/gnu/llvm/lldb/include/lldb/Core/PluginInterface.h index 6e625a60591..17f6dc36715 100644 --- a/gnu/llvm/lldb/include/lldb/Core/PluginInterface.h +++ b/gnu/llvm/lldb/include/lldb/Core/PluginInterface.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PluginInterface_h_ -#define liblldb_PluginInterface_h_ +#ifndef LLDB_CORE_PLUGININTERFACE_H +#define LLDB_CORE_PLUGININTERFACE_H #include "lldb/lldb-private.h" @@ -24,4 +24,4 @@ public: } // namespace lldb_private -#endif // liblldb_PluginInterface_h_ +#endif // LLDB_CORE_PLUGININTERFACE_H diff --git a/gnu/llvm/lldb/include/lldb/Core/PluginManager.h b/gnu/llvm/lldb/include/lldb/Core/PluginManager.h index 5b859752b3c..5e0c9395dae 100644 --- a/gnu/llvm/lldb/include/lldb/Core/PluginManager.h +++ b/gnu/llvm/lldb/include/lldb/Core/PluginManager.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PluginManager_h_ -#define liblldb_PluginManager_h_ +#ifndef LLDB_CORE_PLUGINMANAGER_H +#define LLDB_CORE_PLUGINMANAGER_H #include "lldb/Core/Architecture.h" #include "lldb/Symbol/TypeSystem.h" @@ -22,6 +22,25 @@ #include #include +#define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName) \ + namespace lldb_private { \ + void lldb_initialize_##PluginName() { ClassName::Initialize(); } \ + void lldb_terminate_##PluginName() { ClassName::Terminate(); } \ + } + +#define LLDB_PLUGIN_DEFINE(PluginName) \ + LLDB_PLUGIN_DEFINE_ADV(PluginName, PluginName) + +// FIXME: Generate me with CMake +#define LLDB_PLUGIN_DECLARE(PluginName) \ + namespace lldb_private { \ + extern void lldb_initialize_##PluginName(); \ + extern void lldb_terminate_##PluginName(); \ + } + +#define LLDB_PLUGIN_INITIALIZE(PluginName) lldb_initialize_##PluginName() +#define LLDB_PLUGIN_TERMINATE(PluginName) lldb_terminate_##PluginName() + namespace lldb_private { class CommandInterpreter; class ConstString; @@ -42,15 +61,8 @@ public: static ABICreateInstance GetABICreateCallbackAtIndex(uint32_t idx); - static ABICreateInstance - GetABICreateCallbackForPluginName(ConstString name); - // Architecture - using ArchitectureCreateInstance = - std::unique_ptr (*)(const ArchSpec &); - - static void RegisterPlugin(ConstString name, - llvm::StringRef description, + static void RegisterPlugin(ConstString name, llvm::StringRef description, ArchitectureCreateInstance create_callback); static void UnregisterPlugin(ArchitectureCreateInstance create_callback); @@ -95,9 +107,6 @@ public: static JITLoaderCreateInstance GetJITLoaderCreateCallbackAtIndex(uint32_t idx); - static JITLoaderCreateInstance - GetJITLoaderCreateCallbackForPluginName(ConstString name); - // EmulateInstruction static bool RegisterPlugin(ConstString name, const char *description, EmulateInstructionCreateInstance create_callback); @@ -132,9 +141,6 @@ public: static LanguageCreateInstance GetLanguageCreateCallbackAtIndex(uint32_t idx); - static LanguageCreateInstance - GetLanguageCreateCallbackForPluginName(ConstString name); - // LanguageRuntime static bool RegisterPlugin( ConstString name, const char *description, @@ -153,9 +159,6 @@ public: static LanguageRuntimeGetExceptionPrecondition GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx); - static LanguageRuntimeCreateInstance - GetLanguageRuntimeCreateCallbackForPluginName(ConstString name); - // SystemRuntime static bool RegisterPlugin(ConstString name, const char *description, SystemRuntimeCreateInstance create_callback); @@ -165,9 +168,6 @@ public: static SystemRuntimeCreateInstance GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx); - static SystemRuntimeCreateInstance - GetSystemRuntimeCreateCallbackForPluginName(ConstString name); - // ObjectFile static bool RegisterPlugin(ConstString name, const char *description, @@ -187,9 +187,6 @@ public: static ObjectFileGetModuleSpecifications GetObjectFileGetModuleSpecificationsCallbackAtIndex(uint32_t idx); - static ObjectFileCreateInstance - GetObjectFileCreateCallbackForPluginName(ConstString name); - static ObjectFileCreateMemoryInstance GetObjectFileCreateMemoryCallbackForPluginName(ConstString name); @@ -207,9 +204,6 @@ public: static ObjectContainerCreateInstance GetObjectContainerCreateCallbackAtIndex(uint32_t idx); - static ObjectContainerCreateInstance - GetObjectContainerCreateCallbackForPluginName(ConstString name); - static ObjectFileGetModuleSpecifications GetObjectContainerGetModuleSpecificationsCallbackAtIndex(uint32_t idx); @@ -249,6 +243,9 @@ public: static const char *GetProcessPluginDescriptionAtIndex(uint32_t idx); + static void AutoCompleteProcessName(llvm::StringRef partial_name, + CompletionRequest &request); + // ScriptInterpreter static bool RegisterPlugin(ConstString name, const char *description, lldb::ScriptLanguage script_lang, @@ -309,9 +306,6 @@ public: static StructuredDataPluginCreateInstance GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx); - static StructuredDataPluginCreateInstance - GetStructuredDataPluginCreateCallbackForPluginName(ConstString name); - static StructuredDataFilterLaunchInfo GetStructuredDataFilterCallbackAtIndex(uint32_t idx, bool &iteration_complete); @@ -327,9 +321,6 @@ public: static SymbolFileCreateInstance GetSymbolFileCreateCallbackAtIndex(uint32_t idx); - static SymbolFileCreateInstance - GetSymbolFileCreateCallbackForPluginName(ConstString name); - // SymbolVendor static bool RegisterPlugin(ConstString name, const char *description, SymbolVendorCreateInstance create_callback); @@ -339,9 +330,6 @@ public: static SymbolVendorCreateInstance GetSymbolVendorCreateCallbackAtIndex(uint32_t idx); - static SymbolVendorCreateInstance - GetSymbolVendorCreateCallbackForPluginName(ConstString name); - // UnwindAssembly static bool RegisterPlugin(ConstString name, const char *description, UnwindAssemblyCreateInstance create_callback); @@ -351,9 +339,6 @@ public: static UnwindAssemblyCreateInstance GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx); - static UnwindAssemblyCreateInstance - GetUnwindAssemblyCreateCallbackForPluginName(ConstString name); - // MemoryHistory static bool RegisterPlugin(ConstString name, const char *description, MemoryHistoryCreateInstance create_callback); @@ -363,9 +348,6 @@ public: static MemoryHistoryCreateInstance GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx); - static MemoryHistoryCreateInstance - GetMemoryHistoryCreateCallbackForPluginName(ConstString name); - // InstrumentationRuntime static bool RegisterPlugin(ConstString name, const char *description, @@ -381,9 +363,6 @@ public: static InstrumentationRuntimeCreateInstance GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx); - static InstrumentationRuntimeCreateInstance - GetInstrumentationRuntimeCreateCallbackForPluginName(ConstString name); - // TypeSystem static bool RegisterPlugin(ConstString name, const char *description, TypeSystemCreateInstance create_callback, @@ -395,9 +374,6 @@ public: static TypeSystemCreateInstance GetTypeSystemCreateCallbackAtIndex(uint32_t idx); - static TypeSystemCreateInstance - GetTypeSystemCreateCallbackForPluginName(ConstString name); - static LanguageSet GetAllTypeSystemSupportedLanguagesForTypes(); static LanguageSet GetAllTypeSystemSupportedLanguagesForExpressions(); @@ -411,9 +387,6 @@ public: static REPLCreateInstance GetREPLCreateCallbackAtIndex(uint32_t idx); - static REPLCreateInstance - GetREPLCreateCallbackForPluginName(ConstString name); - static LanguageSet GetREPLAllTypeSystemSupportedLanguages(); // Some plug-ins might register a DebuggerInitializeCallback callback when @@ -478,4 +451,4 @@ public: } // namespace lldb_private -#endif // liblldb_PluginManager_h_ +#endif // LLDB_CORE_PLUGINMANAGER_H diff --git a/gnu/llvm/lldb/include/lldb/Core/PropertiesBase.td b/gnu/llvm/lldb/include/lldb/Core/PropertiesBase.td index 6e95ceb779b..1be3b908ed4 100644 --- a/gnu/llvm/lldb/include/lldb/Core/PropertiesBase.td +++ b/gnu/llvm/lldb/include/lldb/Core/PropertiesBase.td @@ -49,3 +49,9 @@ class DefaultUnsignedValue { class EnumValues { string EnumValues = enum; } + +// Determines the element type for arrays and dictionaries. +class ElementType { + string ElementType = value; + bit HasElementType = 1; +} diff --git a/gnu/llvm/lldb/include/lldb/Core/RichManglingContext.h b/gnu/llvm/lldb/include/lldb/Core/RichManglingContext.h index e6fa2599e55..68f80e73b72 100644 --- a/gnu/llvm/lldb/include/lldb/Core/RichManglingContext.h +++ b/gnu/llvm/lldb/include/lldb/Core/RichManglingContext.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RichManglingContext_h_ -#define liblldb_RichManglingContext_h_ +#ifndef LLDB_CORE_RICHMANGLINGCONTEXT_H +#define LLDB_CORE_RICHMANGLINGCONTEXT_H #include "lldb/lldb-forward.h" #include "lldb/lldb-private.h" diff --git a/gnu/llvm/lldb/include/lldb/Core/SearchFilter.h b/gnu/llvm/lldb/include/lldb/Core/SearchFilter.h index 74c4f3162a1..54dc65e4410 100644 --- a/gnu/llvm/lldb/include/lldb/Core/SearchFilter.h +++ b/gnu/llvm/lldb/include/lldb/Core/SearchFilter.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SearchFilter_h_ -#define liblldb_SearchFilter_h_ +#ifndef LLDB_CORE_SEARCHFILTER_H +#define LLDB_CORE_SEARCHFILTER_H #include "lldb/Core/FileSpecList.h" #include "lldb/Utility/StructuredData.h" @@ -98,6 +98,8 @@ public: /// The file spec to check against the filter. /// \return /// \b true if \a spec passes, and \b false otherwise. + /// + /// \note the default implementation always returns \c true. virtual bool ModulePasses(const FileSpec &spec); /// Call this method with a Module to see if that module passes the filter. @@ -107,6 +109,8 @@ public: /// /// \return /// \b true if \a module passes, and \b false otherwise. + /// + /// \note the default implementation always returns \c true. virtual bool ModulePasses(const lldb::ModuleSP &module_sp); /// Call this method with a Address to see if \a address passes the filter. @@ -116,6 +120,8 @@ public: /// /// \return /// \b true if \a address passes, and \b false otherwise. + /// + /// \note the default implementation always returns \c true. virtual bool AddressPasses(Address &addr); /// Call this method with a FileSpec to see if \a file spec passes the @@ -126,6 +132,8 @@ public: /// /// \return /// \b true if \a file spec passes, and \b false otherwise. + /// + /// \note the default implementation always returns \c true. virtual bool CompUnitPasses(FileSpec &fileSpec); /// Call this method with a CompileUnit to see if \a comp unit passes the @@ -136,6 +144,8 @@ public: /// /// \return /// \b true if \a Comp Unit passes, and \b false otherwise. + /// + /// \note the default implementation always returns \c true. virtual bool CompUnitPasses(CompileUnit &compUnit); /// Call this method with a Function to see if \a function passes the @@ -187,10 +197,10 @@ public: /// Standard "Dump" method. At present it does nothing. virtual void Dump(Stream *s) const; - lldb::SearchFilterSP CopyForBreakpoint(Breakpoint &breakpoint); + lldb::SearchFilterSP CreateCopy(lldb::TargetSP& target_sp); static lldb::SearchFilterSP - CreateFromStructuredData(Target &target, + CreateFromStructuredData(const lldb::TargetSP& target_sp, const StructuredData::Dictionary &data_dict, Status &error); @@ -261,13 +271,13 @@ protected: const SymbolContext &context, Searcher &searcher); - virtual lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) = 0; + virtual lldb::SearchFilterSP DoCreateCopy() = 0; void SetTarget(lldb::TargetSP &target_sp) { m_target_sp = target_sp; } - lldb::TargetSP - m_target_sp; // Every filter has to be associated with a target for - // now since you need a starting place for the search. + lldb::TargetSP m_target_sp; // Every filter has to be associated with + // a target for now since you need a starting + // place for the search. private: unsigned char SubclassID; }; @@ -288,14 +298,14 @@ public: bool ModulePasses(const lldb::ModuleSP &module_sp) override; static lldb::SearchFilterSP - CreateFromStructuredData(Target &target, + CreateFromStructuredData(const lldb::TargetSP& target_sp, const StructuredData::Dictionary &data_dict, Status &error); StructuredData::ObjectSP SerializeToStructuredData() override; protected: - lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override; + lldb::SearchFilterSP DoCreateCopy() override; }; /// \class SearchFilterByModule SearchFilter.h "lldb/Core/SearchFilter.h" This @@ -321,10 +331,6 @@ public: bool AddressPasses(Address &address) override; - bool CompUnitPasses(FileSpec &fileSpec) override; - - bool CompUnitPasses(CompileUnit &compUnit) override; - void GetDescription(Stream *s) override; uint32_t GetFilterRequiredItems() override; @@ -334,14 +340,14 @@ public: void Search(Searcher &searcher) override; static lldb::SearchFilterSP - CreateFromStructuredData(Target &target, + CreateFromStructuredData(const lldb::TargetSP& target_sp, const StructuredData::Dictionary &data_dict, Status &error); StructuredData::ObjectSP SerializeToStructuredData() override; protected: - lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override; + lldb::SearchFilterSP DoCreateCopy() override; private: FileSpec m_module_spec; @@ -372,10 +378,6 @@ public: bool AddressPasses(Address &address) override; - bool CompUnitPasses(FileSpec &fileSpec) override; - - bool CompUnitPasses(CompileUnit &compUnit) override; - void GetDescription(Stream *s) override; uint32_t GetFilterRequiredItems() override; @@ -385,7 +387,7 @@ public: void Search(Searcher &searcher) override; static lldb::SearchFilterSP - CreateFromStructuredData(Target &target, + CreateFromStructuredData(const lldb::TargetSP& target_sp, const StructuredData::Dictionary &data_dict, Status &error); @@ -394,9 +396,8 @@ public: void SerializeUnwrapped(StructuredData::DictionarySP &options_dict_sp); protected: - lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override; + lldb::SearchFilterSP DoCreateCopy() override; -protected: FileSpecList m_module_spec_list; }; @@ -425,14 +426,14 @@ public: void Search(Searcher &searcher) override; static lldb::SearchFilterSP - CreateFromStructuredData(Target &target, + CreateFromStructuredData(const lldb::TargetSP& target_sp, const StructuredData::Dictionary &data_dict, Status &error); StructuredData::ObjectSP SerializeToStructuredData() override; protected: - lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override; + lldb::SearchFilterSP DoCreateCopy() override; private: FileSpecList m_cu_spec_list; @@ -440,4 +441,4 @@ private: } // namespace lldb_private -#endif // liblldb_SearchFilter_h_ +#endif // LLDB_CORE_SEARCHFILTER_H diff --git a/gnu/llvm/lldb/include/lldb/Core/Section.h b/gnu/llvm/lldb/include/lldb/Core/Section.h index 509a0767be1..af2bb7896a5 100644 --- a/gnu/llvm/lldb/include/lldb/Core/Section.h +++ b/gnu/llvm/lldb/include/lldb/Core/Section.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Section_h_ -#define liblldb_Section_h_ +#ifndef LLDB_CORE_SECTION_H +#define LLDB_CORE_SECTION_H #include "lldb/Core/ModuleChild.h" #include "lldb/Utility/ConstString.h" @@ -29,7 +29,6 @@ class Address; class DataExtractor; class ObjectFile; class Section; -class Stream; class Target; class SectionList { @@ -56,7 +55,8 @@ public: bool ContainsSection(lldb::user_id_t sect_id) const; - void Dump(Stream *s, Target *target, bool show_header, uint32_t depth) const; + void Dump(llvm::raw_ostream &s, unsigned indent, Target *target, + bool show_header, uint32_t depth) const; lldb::SectionSP FindSectionByName(ConstString section_dstr) const; @@ -127,9 +127,10 @@ public: const SectionList &GetChildren() const { return m_children; } - void Dump(Stream *s, Target *target, uint32_t depth) const; + void Dump(llvm::raw_ostream &s, unsigned indent, Target *target, + uint32_t depth) const; - void DumpName(Stream *s) const; + void DumpName(llvm::raw_ostream &s) const; lldb::addr_t GetLoadBaseAddress(Target *target) const; @@ -267,9 +268,10 @@ protected: // This is specified as // as a multiple number of a host bytes private: - DISALLOW_COPY_AND_ASSIGN(Section); + Section(const Section &) = delete; + const Section &operator=(const Section &) = delete; }; } // namespace lldb_private -#endif // liblldb_Section_h_ +#endif // LLDB_CORE_SECTION_H diff --git a/gnu/llvm/lldb/include/lldb/Core/SourceManager.h b/gnu/llvm/lldb/include/lldb/Core/SourceManager.h index f1f56d0886c..7549c308f33 100644 --- a/gnu/llvm/lldb/include/lldb/Core/SourceManager.h +++ b/gnu/llvm/lldb/include/lldb/Core/SourceManager.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SourceManager_h_ -#define liblldb_SourceManager_h_ +#ifndef LLDB_CORE_SOURCEMANAGER_H +#define LLDB_CORE_SOURCEMANAGER_H #include "lldb/Utility/FileSpec.h" #include "lldb/lldb-defines.h" @@ -101,6 +101,9 @@ public: void AddSourceFile(const FileSP &file_sp); FileSP FindSourceFile(const FileSpec &file_spec) const; + // Removes all elements from the cache. + void Clear() { m_file_cache.clear(); } + protected: typedef std::map FileCache; FileCache m_file_cache; @@ -116,7 +119,7 @@ public: ~SourceManager(); - FileSP GetLastFile() { return m_last_file_sp; } + FileSP GetLastFile() { return GetFile(m_last_file_spec); } size_t DisplaySourceLinesWithLineNumbers(const FileSpec &file, uint32_t line, @@ -138,7 +141,9 @@ public: bool GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line); - bool DefaultFileAndLineSet() { return (m_last_file_sp.get() != nullptr); } + bool DefaultFileAndLineSet() { + return (GetFile(m_last_file_spec).get() != nullptr); + } void FindLinesMatchingRegex(FileSpec &file_spec, RegularExpression ®ex, uint32_t start_line, uint32_t end_line, @@ -147,7 +152,7 @@ public: FileSP GetFile(const FileSpec &file_spec); protected: - FileSP m_last_file_sp; + FileSpec m_last_file_spec; uint32_t m_last_line; uint32_t m_last_count; bool m_default_set; @@ -155,11 +160,12 @@ protected: lldb::DebuggerWP m_debugger_wp; private: - DISALLOW_COPY_AND_ASSIGN(SourceManager); + SourceManager(const SourceManager &) = delete; + const SourceManager &operator=(const SourceManager &) = delete; }; bool operator==(const SourceManager::File &lhs, const SourceManager::File &rhs); } // namespace lldb_private -#endif // liblldb_SourceManager_h_ +#endif // LLDB_CORE_SOURCEMANAGER_H diff --git a/gnu/llvm/lldb/include/lldb/Core/StreamAsynchronousIO.h b/gnu/llvm/lldb/include/lldb/Core/StreamAsynchronousIO.h index 6237e12b7d1..949a798955d 100644 --- a/gnu/llvm/lldb/include/lldb/Core/StreamAsynchronousIO.h +++ b/gnu/llvm/lldb/include/lldb/Core/StreamAsynchronousIO.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StreamAsynchronousIO_h_ -#define liblldb_StreamAsynchronousIO_h_ +#ifndef LLDB_CORE_STREAMASYNCHRONOUSIO_H +#define LLDB_CORE_STREAMASYNCHRONOUSIO_H #include "lldb/Utility/Stream.h" @@ -37,4 +37,4 @@ private: } // namespace lldb_private -#endif // liblldb_StreamAsynchronousIO_h +#endif // LLDB_CORE_STREAMASYNCHRONOUSIO_H diff --git a/gnu/llvm/lldb/include/lldb/Core/StreamBuffer.h b/gnu/llvm/lldb/include/lldb/Core/StreamBuffer.h index 6c516519781..9c48ddb44d7 100644 --- a/gnu/llvm/lldb/include/lldb/Core/StreamBuffer.h +++ b/gnu/llvm/lldb/include/lldb/Core/StreamBuffer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StreamBuffer_h_ -#define liblldb_StreamBuffer_h_ +#ifndef LLDB_CORE_STREAMBUFFER_H +#define LLDB_CORE_STREAMBUFFER_H #include "lldb/Utility/Stream.h" #include "llvm/ADT/SmallVector.h" @@ -51,4 +51,4 @@ protected: } // namespace lldb_private -#endif // #ifndef liblldb_StreamBuffer_h_ +#endif // LLDB_CORE_STREAMBUFFER_H diff --git a/gnu/llvm/lldb/include/lldb/Core/StreamFile.h b/gnu/llvm/lldb/include/lldb/Core/StreamFile.h index bd7d6e8e6ad..e71e31eb1d0 100644 --- a/gnu/llvm/lldb/include/lldb/Core/StreamFile.h +++ b/gnu/llvm/lldb/include/lldb/Core/StreamFile.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StreamFile_h_ -#define liblldb_StreamFile_h_ +#ifndef LLDB_CORE_STREAMFILE_H +#define LLDB_CORE_STREAMFILE_H #include "lldb/Host/File.h" #include "lldb/Utility/Stream.h" @@ -48,9 +48,10 @@ protected: size_t WriteImpl(const void *s, size_t length) override; private: - DISALLOW_COPY_AND_ASSIGN(StreamFile); + StreamFile(const StreamFile &) = delete; + const StreamFile &operator=(const StreamFile &) = delete; }; } // namespace lldb_private -#endif // liblldb_StreamFile_h_ +#endif // LLDB_CORE_STREAMFILE_H diff --git a/gnu/llvm/lldb/include/lldb/Core/StructuredDataImpl.h b/gnu/llvm/lldb/include/lldb/Core/StructuredDataImpl.h index c66e4736dc2..9aea645a3ea 100644 --- a/gnu/llvm/lldb/include/lldb/Core/StructuredDataImpl.h +++ b/gnu/llvm/lldb/include/lldb/Core/StructuredDataImpl.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StructuredDataImpl_h_ -#define liblldb_StructuredDataImpl_h_ +#ifndef LLDB_CORE_STRUCTUREDDATAIMPL_H +#define LLDB_CORE_STRUCTUREDDATAIMPL_H #include "lldb/Target/StructuredDataPlugin.h" #include "lldb/Utility/Event.h" diff --git a/gnu/llvm/lldb/include/lldb/Core/ThreadSafeDenseMap.h b/gnu/llvm/lldb/include/lldb/Core/ThreadSafeDenseMap.h index 420cb576358..2f6eb280e4a 100644 --- a/gnu/llvm/lldb/include/lldb/Core/ThreadSafeDenseMap.h +++ b/gnu/llvm/lldb/include/lldb/Core/ThreadSafeDenseMap.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadSafeDenseMap_h_ -#define liblldb_ThreadSafeDenseMap_h_ +#ifndef LLDB_CORE_THREADSAFEDENSEMAP_H +#define LLDB_CORE_THREADSAFEDENSEMAP_H #include @@ -62,4 +62,4 @@ protected: } // namespace lldb_private -#endif // liblldb_ThreadSafeDenseMap_h_ +#endif // LLDB_CORE_THREADSAFEDENSEMAP_H diff --git a/gnu/llvm/lldb/include/lldb/Core/ThreadSafeValue.h b/gnu/llvm/lldb/include/lldb/Core/ThreadSafeValue.h index 91f96814363..38b8034fad5 100644 --- a/gnu/llvm/lldb/include/lldb/Core/ThreadSafeValue.h +++ b/gnu/llvm/lldb/include/lldb/Core/ThreadSafeValue.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadSafeValue_h_ -#define liblldb_ThreadSafeValue_h_ - +#ifndef LLDB_CORE_THREADSAFEVALUE_H +#define LLDB_CORE_THREADSAFEVALUE_H #include @@ -54,8 +53,9 @@ private: mutable std::recursive_mutex m_mutex; // For ThreadSafeValue only - DISALLOW_COPY_AND_ASSIGN(ThreadSafeValue); + ThreadSafeValue(const ThreadSafeValue &) = delete; + const ThreadSafeValue &operator=(const ThreadSafeValue &) = delete; }; } // namespace lldb_private -#endif // liblldb_ThreadSafeValue_h_ +#endif // LLDB_CORE_THREADSAFEVALUE_H diff --git a/gnu/llvm/lldb/include/lldb/Core/UniqueCStringMap.h b/gnu/llvm/lldb/include/lldb/Core/UniqueCStringMap.h index 9949bd45f4f..e37027a0150 100644 --- a/gnu/llvm/lldb/include/lldb/Core/UniqueCStringMap.h +++ b/gnu/llvm/lldb/include/lldb/Core/UniqueCStringMap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_UniqueCStringMap_h_ -#define liblldb_UniqueCStringMap_h_ +#ifndef LLDB_CORE_UNIQUECSTRINGMAP_H +#define LLDB_CORE_UNIQUECSTRINGMAP_H #include #include @@ -32,6 +32,10 @@ public: T value; }; + typedef std::vector collection; + typedef typename collection::iterator iterator; + typedef typename collection::const_iterator const_iterator; + // Call this function multiple times to add a bunch of entries to this map, // then later call UniqueCStringMap::Sort() before doing any searches by // name. @@ -175,6 +179,18 @@ public: } } + iterator begin() { return m_map.begin(); } + iterator end() { return m_map.end(); } + const_iterator begin() const { return m_map.begin(); } + const_iterator end() const { return m_map.end(); } + + // Range-based for loop for all entries of the specified ConstString name. + llvm::iterator_range + equal_range(ConstString unique_cstr) const { + return llvm::make_range( + std::equal_range(m_map.begin(), m_map.end(), unique_cstr, Compare())); + }; + protected: struct Compare { bool operator()(const Entry &lhs, const Entry &rhs) { @@ -196,12 +212,9 @@ protected: return uintptr_t(lhs.GetCString()) < uintptr_t(rhs.GetCString()); } }; - typedef std::vector collection; - typedef typename collection::iterator iterator; - typedef typename collection::const_iterator const_iterator; collection m_map; }; } // namespace lldb_private -#endif // liblldb_UniqueCStringMap_h_ +#endif // LLDB_CORE_UNIQUECSTRINGMAP_H diff --git a/gnu/llvm/lldb/include/lldb/Core/UserSettingsController.h b/gnu/llvm/lldb/include/lldb/Core/UserSettingsController.h index 6ae3bdec166..f40ad54ac4d 100644 --- a/gnu/llvm/lldb/include/lldb/Core/UserSettingsController.h +++ b/gnu/llvm/lldb/include/lldb/Core/UserSettingsController.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_UserSettingsController_h_ -#define liblldb_UserSettingsController_h_ +#ifndef LLDB_CORE_USERSETTINGSCONTROLLER_H +#define LLDB_CORE_USERSETTINGSCONTROLLER_H #include "lldb/Utility/Status.h" #include "lldb/lldb-forward.h" @@ -88,4 +88,4 @@ protected: } // namespace lldb_private -#endif // liblldb_UserSettingsController_h_ +#endif // LLDB_CORE_USERSETTINGSCONTROLLER_H diff --git a/gnu/llvm/lldb/include/lldb/Core/Value.h b/gnu/llvm/lldb/include/lldb/Core/Value.h index 7b4cc3b71c2..641a64a3bbb 100644 --- a/gnu/llvm/lldb/include/lldb/Core/Value.h +++ b/gnu/llvm/lldb/include/lldb/Core/Value.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Value_h_ -#define liblldb_Value_h_ +#ifndef LLDB_CORE_VALUE_H +#define LLDB_CORE_VALUE_H #include "lldb/Symbol/CompilerType.h" #include "lldb/Utility/DataBufferHeap.h" @@ -258,4 +258,4 @@ private: } // namespace lldb_private -#endif // liblldb_Value_h_ +#endif // LLDB_CORE_VALUE_H diff --git a/gnu/llvm/lldb/include/lldb/Core/ValueObject.h b/gnu/llvm/lldb/include/lldb/Core/ValueObject.h index 1b000e617f0..0080368fd99 100644 --- a/gnu/llvm/lldb/include/lldb/Core/ValueObject.h +++ b/gnu/llvm/lldb/include/lldb/Core/ValueObject.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ValueObject_h_ -#define liblldb_ValueObject_h_ +#ifndef LLDB_CORE_VALUEOBJECT_H +#define LLDB_CORE_VALUEOBJECT_H #include "lldb/Core/Value.h" #include "lldb/Symbol/CompilerType.h" @@ -396,10 +396,8 @@ public: bool IsIntegerType(bool &is_signed); - virtual bool GetBaseClassPath(Stream &s); - virtual void GetExpressionPath( - Stream &s, bool qualify_cxx_base_classes, + Stream &s, GetExpressionPathFormat = eGetExpressionPathFormatDereferencePointers); lldb::ValueObjectSP GetValueForExpressionPath( @@ -577,7 +575,7 @@ public: virtual lldb::ValueObjectSP GetNonSyntheticValue(); - lldb::ValueObjectSP GetSyntheticValue(bool use_synthetic = true); + lldb::ValueObjectSP GetSyntheticValue(); virtual bool HasSyntheticValue(); @@ -889,7 +887,6 @@ protected: m_is_synthetic_children_generated : 1; friend class ValueObjectChild; - friend class ClangExpressionDeclMap; // For GetValue friend class ExpressionVariable; // For SetName friend class Target; // For SetName friend class ValueObjectConstResultImpl; @@ -905,7 +902,7 @@ protected: // Use this constructor to create a "root variable object". The ValueObject // will be locked to this context through-out its lifespan. - ValueObject(ExecutionContextScope *exe_scope, + ValueObject(ExecutionContextScope *exe_scope, ValueObjectManager &manager, AddressType child_ptr_or_ref_addr_type = eAddressTypeLoad); // Use this constructor to create a ValueObject owned by another ValueObject. @@ -929,7 +926,7 @@ protected: virtual bool HasDynamicValueTypeInfo() { return false; } - virtual void CalculateSyntheticValue(bool use_synthetic = true); + virtual void CalculateSyntheticValue(); // Should only be called by ValueObject::GetChildAtIndex() Returns a // ValueObject managed by this ValueObject's manager. @@ -966,9 +963,14 @@ protected: void SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType); +protected: + virtual void DoUpdateChildrenAddressType(ValueObject &valobj) { return; }; + private: virtual CompilerType MaybeCalculateCompleteType(); - void UpdateChildrenAddressType(); + void UpdateChildrenAddressType() { + GetRoot()->DoUpdateChildrenAddressType(*this); + } lldb::ValueObjectSP GetValueForExpressionPath_Impl( llvm::StringRef expression_cstr, @@ -977,7 +979,8 @@ private: const GetValueForExpressionPathOptions &options, ExpressionPathAftermath *final_task_on_target); - DISALLOW_COPY_AND_ASSIGN(ValueObject); + ValueObject(const ValueObject &) = delete; + const ValueObject &operator=(const ValueObject &) = delete; }; // A value object manager class that is seeded with the static variable value @@ -1023,4 +1026,4 @@ public: } // namespace lldb_private -#endif // liblldb_ValueObject_h_ +#endif // LLDB_CORE_VALUEOBJECT_H diff --git a/gnu/llvm/lldb/include/lldb/Core/ValueObjectCast.h b/gnu/llvm/lldb/include/lldb/Core/ValueObjectCast.h index feee493dfaf..d91ca6a92be 100644 --- a/gnu/llvm/lldb/include/lldb/Core/ValueObjectCast.h +++ b/gnu/llvm/lldb/include/lldb/Core/ValueObjectCast.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ValueObjectCast_h_ -#define liblldb_ValueObjectCast_h_ +#ifndef LLDB_CORE_VALUEOBJECTCAST_H +#define LLDB_CORE_VALUEOBJECTCAST_H #include "lldb/Core/ValueObject.h" #include "lldb/Symbol/CompilerType.h" @@ -57,9 +57,10 @@ protected: CompilerType m_cast_type; private: - DISALLOW_COPY_AND_ASSIGN(ValueObjectCast); + ValueObjectCast(const ValueObjectCast &) = delete; + const ValueObjectCast &operator=(const ValueObjectCast &) = delete; }; } // namespace lldb_private -#endif // liblldb_ValueObjectCast_h_ +#endif // LLDB_CORE_VALUEOBJECTCAST_H diff --git a/gnu/llvm/lldb/include/lldb/Core/ValueObjectChild.h b/gnu/llvm/lldb/include/lldb/Core/ValueObjectChild.h index 76209a22ec2..c6f44a29b05 100644 --- a/gnu/llvm/lldb/include/lldb/Core/ValueObjectChild.h +++ b/gnu/llvm/lldb/include/lldb/Core/ValueObjectChild.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ValueObjectChild_h_ -#define liblldb_ValueObjectChild_h_ +#ifndef LLDB_CORE_VALUEOBJECTCHILD_H +#define LLDB_CORE_VALUEOBJECTCHILD_H #include "lldb/Core/ValueObject.h" @@ -75,7 +75,6 @@ protected: // void // ReadValueFromMemory (ValueObject* parent, lldb::addr_t address); -protected: friend class ValueObject; friend class ValueObjectConstResult; friend class ValueObjectConstResultImpl; @@ -88,9 +87,10 @@ protected: AddressType child_ptr_or_ref_addr_type, uint64_t language_flags); - DISALLOW_COPY_AND_ASSIGN(ValueObjectChild); + ValueObjectChild(const ValueObjectChild &) = delete; + const ValueObjectChild &operator=(const ValueObjectChild &) = delete; }; } // namespace lldb_private -#endif // liblldb_ValueObjectChild_h_ +#endif // LLDB_CORE_VALUEOBJECTCHILD_H diff --git a/gnu/llvm/lldb/include/lldb/Core/ValueObjectConstResult.h b/gnu/llvm/lldb/include/lldb/Core/ValueObjectConstResult.h index 3bc957ef2b8..0e868c687e9 100644 --- a/gnu/llvm/lldb/include/lldb/Core/ValueObjectConstResult.h +++ b/gnu/llvm/lldb/include/lldb/Core/ValueObjectConstResult.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ValueObjectConstResult_h_ -#define liblldb_ValueObjectConstResult_h_ +#ifndef LLDB_CORE_VALUEOBJECTCONSTRESULT_H +#define LLDB_CORE_VALUEOBJECTCONSTRESULT_H #include "lldb/Core/Value.h" #include "lldb/Core/ValueObject.h" @@ -121,34 +121,40 @@ private: friend class ValueObjectConstResultImpl; ValueObjectConstResult(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, lldb::ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address); ValueObjectConstResult(ExecutionContextScope *exe_scope, - const CompilerType &compiler_type, - ConstString name, const DataExtractor &data, - lldb::addr_t address); + ValueObjectManager &manager, + const CompilerType &compiler_type, ConstString name, + const DataExtractor &data, lldb::addr_t address); ValueObjectConstResult(ExecutionContextScope *exe_scope, - const CompilerType &compiler_type, - ConstString name, + ValueObjectManager &manager, + const CompilerType &compiler_type, ConstString name, const lldb::DataBufferSP &result_data_sp, lldb::ByteOrder byte_order, uint32_t addr_size, lldb::addr_t address); ValueObjectConstResult(ExecutionContextScope *exe_scope, - const CompilerType &compiler_type, - ConstString name, lldb::addr_t address, - AddressType address_type, uint32_t addr_byte_size); + ValueObjectManager &manager, + const CompilerType &compiler_type, ConstString name, + lldb::addr_t address, AddressType address_type, + uint32_t addr_byte_size); - ValueObjectConstResult(ExecutionContextScope *exe_scope, const Value &value, + ValueObjectConstResult(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, const Value &value, ConstString name, Module *module = nullptr); - ValueObjectConstResult(ExecutionContextScope *exe_scope, const Status &error); + ValueObjectConstResult(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, const Status &error); - DISALLOW_COPY_AND_ASSIGN(ValueObjectConstResult); + ValueObjectConstResult(const ValueObjectConstResult &) = delete; + const ValueObjectConstResult & + operator=(const ValueObjectConstResult &) = delete; }; } // namespace lldb_private -#endif // liblldb_ValueObjectConstResult_h_ +#endif // LLDB_CORE_VALUEOBJECTCONSTRESULT_H diff --git a/gnu/llvm/lldb/include/lldb/Core/ValueObjectConstResultCast.h b/gnu/llvm/lldb/include/lldb/Core/ValueObjectConstResultCast.h index be9b12b4b57..ba81785866c 100644 --- a/gnu/llvm/lldb/include/lldb/Core/ValueObjectConstResultCast.h +++ b/gnu/llvm/lldb/include/lldb/Core/ValueObjectConstResultCast.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ValueObjectConstResultCast_h_ -#define liblldb_ValueObjectConstResultCast_h_ +#ifndef LLDB_CORE_VALUEOBJECTCONSTRESULTCAST_H +#define LLDB_CORE_VALUEOBJECTCONSTRESULTCAST_H #include "lldb/Core/ValueObjectCast.h" #include "lldb/Core/ValueObjectConstResultImpl.h" @@ -61,9 +61,11 @@ private: friend class ValueObjectConstResult; friend class ValueObjectConstResultImpl; - DISALLOW_COPY_AND_ASSIGN(ValueObjectConstResultCast); + ValueObjectConstResultCast(const ValueObjectConstResultCast &) = delete; + const ValueObjectConstResultCast & + operator=(const ValueObjectConstResultCast &) = delete; }; } // namespace lldb_private -#endif // liblldb_ValueObjectConstResultCast_h_ +#endif // LLDB_CORE_VALUEOBJECTCONSTRESULTCAST_H diff --git a/gnu/llvm/lldb/include/lldb/Core/ValueObjectConstResultChild.h b/gnu/llvm/lldb/include/lldb/Core/ValueObjectConstResultChild.h index 16fa74f71ed..b3606bfde0e 100644 --- a/gnu/llvm/lldb/include/lldb/Core/ValueObjectConstResultChild.h +++ b/gnu/llvm/lldb/include/lldb/Core/ValueObjectConstResultChild.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ValueObjectConstResultChild_h_ -#define liblldb_ValueObjectConstResultChild_h_ +#ifndef LLDB_CORE_VALUEOBJECTCONSTRESULTCHILD_H +#define LLDB_CORE_VALUEOBJECTCONSTRESULTCHILD_H #include "lldb/Core/ValueObjectChild.h" #include "lldb/Core/ValueObjectConstResultImpl.h" @@ -70,9 +70,11 @@ private: friend class ValueObjectConstResult; friend class ValueObjectConstResultImpl; - DISALLOW_COPY_AND_ASSIGN(ValueObjectConstResultChild); + ValueObjectConstResultChild(const ValueObjectConstResultChild &) = delete; + const ValueObjectConstResultChild & + operator=(const ValueObjectConstResultChild &) = delete; }; } // namespace lldb_private -#endif // liblldb_ValueObjectConstResultChild_h_ +#endif // LLDB_CORE_VALUEOBJECTCONSTRESULTCHILD_H diff --git a/gnu/llvm/lldb/include/lldb/Core/ValueObjectConstResultImpl.h b/gnu/llvm/lldb/include/lldb/Core/ValueObjectConstResultImpl.h index ffac98e12e6..1316bf66dfd 100644 --- a/gnu/llvm/lldb/include/lldb/Core/ValueObjectConstResultImpl.h +++ b/gnu/llvm/lldb/include/lldb/Core/ValueObjectConstResultImpl.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ValueObjectConstResultImpl_h_ -#define liblldb_ValueObjectConstResultImpl_h_ +#ifndef LLDB_CORE_VALUEOBJECTCONSTRESULTIMPL_H +#define LLDB_CORE_VALUEOBJECTCONSTRESULTIMPL_H #include "lldb/Utility/ConstString.h" #include "lldb/lldb-defines.h" @@ -71,9 +71,11 @@ private: lldb::ValueObjectSP m_load_addr_backend; lldb::ValueObjectSP m_address_of_backend; - DISALLOW_COPY_AND_ASSIGN(ValueObjectConstResultImpl); + ValueObjectConstResultImpl(const ValueObjectConstResultImpl &) = delete; + const ValueObjectConstResultImpl & + operator=(const ValueObjectConstResultImpl &) = delete; }; } // namespace lldb_private -#endif // liblldb_ValueObjectConstResultImpl_h_ +#endif // LLDB_CORE_VALUEOBJECTCONSTRESULTIMPL_H diff --git a/gnu/llvm/lldb/include/lldb/Core/ValueObjectDynamicValue.h b/gnu/llvm/lldb/include/lldb/Core/ValueObjectDynamicValue.h index f656d42e9a9..9f5304b55e9 100644 --- a/gnu/llvm/lldb/include/lldb/Core/ValueObjectDynamicValue.h +++ b/gnu/llvm/lldb/include/lldb/Core/ValueObjectDynamicValue.h @@ -6,15 +6,14 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ValueObjectDynamicValue_h_ -#define liblldb_ValueObjectDynamicValue_h_ +#ifndef LLDB_CORE_VALUEOBJECTDYNAMICVALUE_H +#define LLDB_CORE_VALUEOBJECTDYNAMICVALUE_H #include "lldb/Core/Address.h" #include "lldb/Core/ValueObject.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/Type.h" #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" @@ -128,9 +127,11 @@ private: ValueObjectDynamicValue(ValueObject &parent, lldb::DynamicValueType use_dynamic); - DISALLOW_COPY_AND_ASSIGN(ValueObjectDynamicValue); + ValueObjectDynamicValue(const ValueObjectDynamicValue &) = delete; + const ValueObjectDynamicValue & + operator=(const ValueObjectDynamicValue &) = delete; }; } // namespace lldb_private -#endif // liblldb_ValueObjectDynamicValue_h_ +#endif // LLDB_CORE_VALUEOBJECTDYNAMICVALUE_H diff --git a/gnu/llvm/lldb/include/lldb/Core/ValueObjectList.h b/gnu/llvm/lldb/include/lldb/Core/ValueObjectList.h index 42d19676d5d..f99fba41aa2 100644 --- a/gnu/llvm/lldb/include/lldb/Core/ValueObjectList.h +++ b/gnu/llvm/lldb/include/lldb/Core/ValueObjectList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ValueObjectList_h_ -#define liblldb_ValueObjectList_h_ +#ifndef LLDB_CORE_VALUEOBJECTLIST_H +#define LLDB_CORE_VALUEOBJECTLIST_H #include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" @@ -59,4 +59,4 @@ protected: } // namespace lldb_private -#endif // liblldb_ValueObjectList_h_ +#endif // LLDB_CORE_VALUEOBJECTLIST_H diff --git a/gnu/llvm/lldb/include/lldb/Core/ValueObjectMemory.h b/gnu/llvm/lldb/include/lldb/Core/ValueObjectMemory.h index df3557f1498..d1cd6ae4144 100644 --- a/gnu/llvm/lldb/include/lldb/Core/ValueObjectMemory.h +++ b/gnu/llvm/lldb/include/lldb/Core/ValueObjectMemory.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ValueObjectMemory_h_ -#define liblldb_ValueObjectMemory_h_ +#ifndef LLDB_CORE_VALUEOBJECTMEMORY_H +#define LLDB_CORE_VALUEOBJECTMEMORY_H #include "lldb/Core/Address.h" #include "lldb/Core/ValueObject.h" @@ -64,15 +64,18 @@ protected: CompilerType m_compiler_type; private: - ValueObjectMemory(ExecutionContextScope *exe_scope, llvm::StringRef name, + ValueObjectMemory(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, llvm::StringRef name, const Address &address, lldb::TypeSP &type_sp); - ValueObjectMemory(ExecutionContextScope *exe_scope, llvm::StringRef name, + ValueObjectMemory(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, llvm::StringRef name, const Address &address, const CompilerType &ast_type); // For ValueObject only - DISALLOW_COPY_AND_ASSIGN(ValueObjectMemory); + ValueObjectMemory(const ValueObjectMemory &) = delete; + const ValueObjectMemory &operator=(const ValueObjectMemory &) = delete; }; } // namespace lldb_private -#endif // liblldb_ValueObjectMemory_h_ +#endif // LLDB_CORE_VALUEOBJECTMEMORY_H diff --git a/gnu/llvm/lldb/include/lldb/Core/ValueObjectRegister.h b/gnu/llvm/lldb/include/lldb/Core/ValueObjectRegister.h index e584be6e605..41051d93b70 100644 --- a/gnu/llvm/lldb/include/lldb/Core/ValueObjectRegister.h +++ b/gnu/llvm/lldb/include/lldb/Core/ValueObjectRegister.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ValueObjectRegister_h_ -#define liblldb_ValueObjectRegister_h_ +#ifndef LLDB_CORE_VALUEOBJECTREGISTER_H +#define LLDB_CORE_VALUEOBJECTREGISTER_H #include "lldb/Core/ValueObject.h" #include "lldb/Symbol/CompilerType.h" @@ -28,43 +28,6 @@ class ExecutionContextScope; class Scalar; class Stream; -// A ValueObject that contains a root variable that may or may not -// have children. -class ValueObjectRegisterContext : public ValueObject { -public: - ~ValueObjectRegisterContext() override; - - uint64_t GetByteSize() override; - - lldb::ValueType GetValueType() const override { - return lldb::eValueTypeRegisterSet; - } - - ConstString GetTypeName() override; - - ConstString GetQualifiedTypeName() override; - - ConstString GetDisplayTypeName() override; - - size_t CalculateNumChildren(uint32_t max) override; - - ValueObject *CreateChildAtIndex(size_t idx, bool synthetic_array_member, - int32_t synthetic_index) override; - -protected: - bool UpdateValue() override; - - CompilerType GetCompilerTypeImpl() override; - - lldb::RegisterContextSP m_reg_ctx_sp; - -private: - ValueObjectRegisterContext(ValueObject &parent, - lldb::RegisterContextSP ®_ctx_sp); - // For ValueObject only - DISALLOW_COPY_AND_ASSIGN(ValueObjectRegisterContext); -}; - class ValueObjectRegisterSet : public ValueObject { public: ~ValueObjectRegisterSet() override; @@ -106,10 +69,13 @@ private: friend class ValueObjectRegisterContext; ValueObjectRegisterSet(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, lldb::RegisterContextSP ®_ctx_sp, uint32_t set_idx); // For ValueObject only - DISALLOW_COPY_AND_ASSIGN(ValueObjectRegisterSet); + ValueObjectRegisterSet(const ValueObjectRegisterSet &) = delete; + const ValueObjectRegisterSet & + operator=(const ValueObjectRegisterSet &) = delete; }; class ValueObjectRegister : public ValueObject { @@ -137,7 +103,7 @@ public: bool ResolveValue(Scalar &scalar) override; void - GetExpressionPath(Stream &s, bool qualify_cxx_base_classes, + GetExpressionPath(Stream &s, GetExpressionPathFormat epformat = eGetExpressionPathFormatDereferencePointers) override; @@ -160,12 +126,14 @@ private: ValueObjectRegister(ValueObject &parent, lldb::RegisterContextSP ®_ctx_sp, uint32_t reg_num); ValueObjectRegister(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, lldb::RegisterContextSP ®_ctx_sp, uint32_t reg_num); // For ValueObject only - DISALLOW_COPY_AND_ASSIGN(ValueObjectRegister); + ValueObjectRegister(const ValueObjectRegister &) = delete; + const ValueObjectRegister &operator=(const ValueObjectRegister &) = delete; }; } // namespace lldb_private -#endif // liblldb_ValueObjectRegister_h_ +#endif // LLDB_CORE_VALUEOBJECTREGISTER_H diff --git a/gnu/llvm/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h b/gnu/llvm/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h index ec395095351..cb471657aec 100644 --- a/gnu/llvm/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h +++ b/gnu/llvm/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ValueObjectSyntheticFilter_h_ -#define liblldb_ValueObjectSyntheticFilter_h_ +#ifndef LLDB_CORE_VALUEOBJECTSYNTHETICFILTER_H +#define LLDB_CORE_VALUEOBJECTSYNTHETICFILTER_H #include "lldb/Core/ValueObject.h" #include "lldb/Symbol/CompilerType.h" @@ -66,7 +66,7 @@ public: bool IsSynthetic() override { return true; } - void CalculateSyntheticValue(bool use_synthetic) override {} + void CalculateSyntheticValue() override {} bool IsDynamic() override { return ((m_parent != nullptr) ? m_parent->IsDynamic() : false); @@ -164,9 +164,10 @@ private: void CopyValueData(ValueObject *source); - DISALLOW_COPY_AND_ASSIGN(ValueObjectSynthetic); + ValueObjectSynthetic(const ValueObjectSynthetic &) = delete; + const ValueObjectSynthetic &operator=(const ValueObjectSynthetic &) = delete; }; } // namespace lldb_private -#endif // liblldb_ValueObjectSyntheticFilter_h_ +#endif // LLDB_CORE_VALUEOBJECTSYNTHETICFILTER_H diff --git a/gnu/llvm/lldb/include/lldb/Core/ValueObjectVariable.h b/gnu/llvm/lldb/include/lldb/Core/ValueObjectVariable.h index 86bb8ef9007..b7e262574a1 100644 --- a/gnu/llvm/lldb/include/lldb/Core/ValueObjectVariable.h +++ b/gnu/llvm/lldb/include/lldb/Core/ValueObjectVariable.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ValueObjectVariable_h_ -#define liblldb_ValueObjectVariable_h_ +#ifndef LLDB_CORE_VALUEOBJECTVARIABLE_H +#define LLDB_CORE_VALUEOBJECTVARIABLE_H #include "lldb/Core/ValueObject.h" @@ -67,6 +67,8 @@ public: protected: bool UpdateValue() override; + + void DoUpdateChildrenAddressType(ValueObject &valobj) override; CompilerType GetCompilerTypeImpl() override; @@ -77,11 +79,13 @@ protected: private: ValueObjectVariable(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, const lldb::VariableSP &var_sp); // For ValueObject only - DISALLOW_COPY_AND_ASSIGN(ValueObjectVariable); + ValueObjectVariable(const ValueObjectVariable &) = delete; + const ValueObjectVariable &operator=(const ValueObjectVariable &) = delete; }; } // namespace lldb_private -#endif // liblldb_ValueObjectVariable_h_ +#endif // LLDB_CORE_VALUEOBJECTVARIABLE_H diff --git a/gnu/llvm/lldb/include/lldb/Core/dwarf.h b/gnu/llvm/lldb/include/lldb/Core/dwarf.h index 832109e55c7..cd9cf249bc6 100644 --- a/gnu/llvm/lldb/include/lldb/Core/dwarf.h +++ b/gnu/llvm/lldb/include/lldb/Core/dwarf.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef DebugBase_dwarf_h_ -#define DebugBase_dwarf_h_ +#ifndef LLDB_CORE_DWARF_H +#define LLDB_CORE_DWARF_H #include "lldb/Utility/RangeMap.h" #include @@ -71,6 +71,6 @@ typedef uint32_t dw_offset_t; // Dwarf Debug Information Entry offset for any //#define DW_OP_APPLE_error 0xFF // Stops expression evaluation and //returns an error (no args) -typedef lldb_private::RangeArray DWARFRangeList; +typedef lldb_private::RangeVector DWARFRangeList; -#endif // DebugBase_dwarf_h_ +#endif // LLDB_CORE_DWARF_H diff --git a/gnu/llvm/lldb/include/lldb/DataFormatters/CXXFunctionPointer.h b/gnu/llvm/lldb/include/lldb/DataFormatters/CXXFunctionPointer.h index b5417895f7b..e9742bc31d8 100644 --- a/gnu/llvm/lldb/include/lldb/DataFormatters/CXXFunctionPointer.h +++ b/gnu/llvm/lldb/include/lldb/DataFormatters/CXXFunctionPointer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CXXFunctionPointer_h_ -#define liblldb_CXXFunctionPointer_h_ +#ifndef LLDB_DATAFORMATTERS_CXXFUNCTIONPOINTER_H +#define LLDB_DATAFORMATTERS_CXXFUNCTIONPOINTER_H #include "lldb/lldb-forward.h" @@ -18,4 +18,4 @@ bool CXXFunctionPointerSummaryProvider(ValueObject &valobj, Stream &stream, } // namespace formatters } // namespace lldb_private -#endif // liblldb_CXXFunctionPointer_h_ +#endif // LLDB_DATAFORMATTERS_CXXFUNCTIONPOINTER_H diff --git a/gnu/llvm/lldb/include/lldb/DataFormatters/DataVisualization.h b/gnu/llvm/lldb/include/lldb/DataFormatters/DataVisualization.h index f5c3487bcb3..b053aa074d9 100644 --- a/gnu/llvm/lldb/include/lldb/DataFormatters/DataVisualization.h +++ b/gnu/llvm/lldb/include/lldb/DataFormatters/DataVisualization.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_DataVisualization_h_ -#define lldb_DataVisualization_h_ - +#ifndef LLDB_DATAFORMATTERS_DATAVISUALIZATION_H +#define LLDB_DATAFORMATTERS_DATAVISUALIZATION_H #include "lldb/DataFormatters/FormatClasses.h" #include "lldb/DataFormatters/FormatManager.h" @@ -122,4 +121,4 @@ public: } // namespace lldb_private -#endif // lldb_DataVisualization_h_ +#endif // LLDB_DATAFORMATTERS_DATAVISUALIZATION_H diff --git a/gnu/llvm/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h b/gnu/llvm/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h index c37411539de..2f3bdf80a6f 100644 --- a/gnu/llvm/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h +++ b/gnu/llvm/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_DumpValueObjectOptions_h_ -#define lldb_DumpValueObjectOptions_h_ +#ifndef LLDB_DATAFORMATTERS_DUMPVALUEOBJECTOPTIONS_H +#define LLDB_DATAFORMATTERS_DUMPVALUEOBJECTOPTIONS_H #include @@ -127,7 +127,6 @@ public: DumpValueObjectOptions & SetPointerAsArray(const PointerAsArraySettings &ptr_array); -public: uint32_t m_max_depth = UINT32_MAX; lldb::DynamicValueType m_use_dynamic = lldb::eNoDynamicValues; uint32_t m_omit_summary_depth = 0; @@ -157,4 +156,4 @@ public: } // namespace lldb_private -#endif // lldb_DumpValueObjectOptions_h_ +#endif // LLDB_DATAFORMATTERS_DUMPVALUEOBJECTOPTIONS_H diff --git a/gnu/llvm/lldb/include/lldb/DataFormatters/FormatCache.h b/gnu/llvm/lldb/include/lldb/DataFormatters/FormatCache.h index f9dbe414640..e75aaee1a7b 100644 --- a/gnu/llvm/lldb/include/lldb/DataFormatters/FormatCache.h +++ b/gnu/llvm/lldb/include/lldb/DataFormatters/FormatCache.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_FormatCache_h_ -#define lldb_FormatCache_h_ +#ifndef LLDB_DATAFORMATTERS_FORMATCACHE_H +#define LLDB_DATAFORMATTERS_FORMATCACHE_H #include #include @@ -49,13 +49,13 @@ private: CacheMap m_map; std::recursive_mutex m_mutex; - uint64_t m_cache_hits; - uint64_t m_cache_misses; + uint64_t m_cache_hits = 0; + uint64_t m_cache_misses = 0; Entry &GetEntry(ConstString type); public: - FormatCache(); + FormatCache() = default; template bool Get(ConstString type, ImplSP &format_impl_sp); void Set(ConstString type, lldb::TypeFormatImplSP &format_sp); @@ -71,4 +71,4 @@ public: } // namespace lldb_private -#endif // lldb_FormatCache_h_ +#endif // LLDB_DATAFORMATTERS_FORMATCACHE_H diff --git a/gnu/llvm/lldb/include/lldb/DataFormatters/FormatClasses.h b/gnu/llvm/lldb/include/lldb/DataFormatters/FormatClasses.h index 91ce444244c..e3989133a60 100644 --- a/gnu/llvm/lldb/include/lldb/DataFormatters/FormatClasses.h +++ b/gnu/llvm/lldb/include/lldb/DataFormatters/FormatClasses.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_FormatClasses_h_ -#define lldb_FormatClasses_h_ +#ifndef LLDB_DATAFORMATTERS_FORMATCLASSES_H +#define LLDB_DATAFORMATTERS_FORMATCLASSES_H #include #include @@ -43,17 +43,15 @@ public: class FormattersMatchCandidate { public: - FormattersMatchCandidate(ConstString name, uint32_t reason, bool strip_ptr, + FormattersMatchCandidate(ConstString name, bool strip_ptr, bool strip_ref, bool strip_tydef) - : m_type_name(name), m_reason(reason), m_stripped_pointer(strip_ptr), + : m_type_name(name), m_stripped_pointer(strip_ptr), m_stripped_reference(strip_ref), m_stripped_typedef(strip_tydef) {} ~FormattersMatchCandidate() = default; ConstString GetTypeName() const { return m_type_name; } - uint32_t GetReason() const { return m_reason; } - bool DidStripPointer() const { return m_stripped_pointer; } bool DidStripReference() const { return m_stripped_reference; } @@ -75,7 +73,6 @@ public: private: ConstString m_type_name; - uint32_t m_reason; bool m_stripped_pointer; bool m_stripped_reference; bool m_stripped_typedef; @@ -112,21 +109,21 @@ public: TypeNameSpecifierImpl(llvm::StringRef name, bool is_regex) : m_is_regex(is_regex), m_type() { - m_type.m_type_name = name; + m_type.m_type_name = std::string(name); } // if constructing with a given type, is_regex cannot be true since we are // giving an exact type to match TypeNameSpecifierImpl(lldb::TypeSP type) : m_is_regex(false), m_type() { if (type) { - m_type.m_type_name = type->GetName().GetStringRef(); + m_type.m_type_name = std::string(type->GetName().GetStringRef()); m_type.m_compiler_type = type->GetForwardCompilerType(); } } TypeNameSpecifierImpl(CompilerType type) : m_is_regex(false), m_type() { if (type.IsValid()) { - m_type.m_type_name.assign(type.GetConstTypeName().GetCString()); + m_type.m_type_name.assign(type.GetTypeName().GetCString()); m_type.m_compiler_type = type; } } @@ -154,10 +151,11 @@ private: }; TypeOrName m_type; -private: - DISALLOW_COPY_AND_ASSIGN(TypeNameSpecifierImpl); + TypeNameSpecifierImpl(const TypeNameSpecifierImpl &) = delete; + const TypeNameSpecifierImpl & + operator=(const TypeNameSpecifierImpl &) = delete; }; } // namespace lldb_private -#endif // lldb_FormatClasses_h_ +#endif // LLDB_DATAFORMATTERS_FORMATCLASSES_H diff --git a/gnu/llvm/lldb/include/lldb/DataFormatters/FormatManager.h b/gnu/llvm/lldb/include/lldb/DataFormatters/FormatManager.h index dd522c487c8..56a0303f9b0 100644 --- a/gnu/llvm/lldb/include/lldb/DataFormatters/FormatManager.h +++ b/gnu/llvm/lldb/include/lldb/DataFormatters/FormatManager.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_FormatManager_h_ -#define lldb_FormatManager_h_ +#ifndef LLDB_DATAFORMATTERS_FORMATMANAGER_H +#define LLDB_DATAFORMATTERS_FORMATMANAGER_H #include #include @@ -170,7 +170,6 @@ public: GetPossibleMatches(ValueObject &valobj, lldb::DynamicValueType use_dynamic) { FormattersMatchVector matches; GetPossibleMatches(valobj, valobj.GetCompilerType(), - lldb_private::eFormatterChoiceCriterionDirectChoice, use_dynamic, matches, false, false, false, true); return matches; } @@ -184,7 +183,7 @@ public: private: static void GetPossibleMatches(ValueObject &valobj, - CompilerType compiler_type, uint32_t reason, + CompilerType compiler_type, lldb::DynamicValueType use_dynamic, FormattersMatchVector &entries, bool did_strip_ptr, bool did_strip_ref, @@ -224,4 +223,4 @@ private: } // namespace lldb_private -#endif // lldb_FormatManager_h_ +#endif // LLDB_DATAFORMATTERS_FORMATMANAGER_H diff --git a/gnu/llvm/lldb/include/lldb/DataFormatters/FormattersContainer.h b/gnu/llvm/lldb/include/lldb/DataFormatters/FormattersContainer.h index 86023dd9bf0..d414882bae1 100644 --- a/gnu/llvm/lldb/include/lldb/DataFormatters/FormattersContainer.h +++ b/gnu/llvm/lldb/include/lldb/DataFormatters/FormattersContainer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_FormattersContainer_h_ -#define lldb_FormattersContainer_h_ +#ifndef LLDB_DATAFORMATTERS_FORMATTERSCONTAINER_H +#define LLDB_DATAFORMATTERS_FORMATTERSCONTAINER_H #include #include @@ -181,16 +181,13 @@ public: } bool Get(ValueObject &valobj, MapValueType &entry, - lldb::DynamicValueType use_dynamic, uint32_t *why = nullptr) { - uint32_t value = lldb_private::eFormatterChoiceCriterionDirectChoice; + lldb::DynamicValueType use_dynamic) { CompilerType ast_type(valobj.GetCompilerType()); - bool ret = Get(valobj, ast_type, entry, use_dynamic, value); + bool ret = Get(valobj, ast_type, entry, use_dynamic); if (ret) entry = MapValueType(entry); else entry = MapValueType(); - if (why) - *why = value; return ret; } @@ -221,7 +218,8 @@ protected: BackEndType m_format_map; std::string m_name; - DISALLOW_COPY_AND_ASSIGN(FormattersContainer); + FormattersContainer(const FormattersContainer &) = delete; + const FormattersContainer &operator=(const FormattersContainer &) = delete; void Add_Impl(MapKeyType type, const MapValueType &entry, RegularExpression *dummy) { @@ -266,7 +264,7 @@ protected: ConstString key = m_format_map.GetKeyAtIndex(index); if (key) return lldb::TypeNameSpecifierImplSP( - new TypeNameSpecifierImpl(key.AsCString(), false)); + new TypeNameSpecifierImpl(key.GetStringRef(), false)); else return lldb::TypeNameSpecifierImplSP(); } @@ -308,16 +306,13 @@ protected: return false; } - bool Get(const FormattersMatchVector &candidates, MapValueType &entry, - uint32_t *reason) { + bool Get(const FormattersMatchVector &candidates, MapValueType &entry) { for (const FormattersMatchCandidate &candidate : candidates) { if (Get(candidate.GetTypeName(), entry)) { if (candidate.IsMatch(entry) == false) { entry.reset(); continue; } else { - if (reason) - *reason = candidate.GetReason(); return true; } } @@ -328,4 +323,4 @@ protected: } // namespace lldb_private -#endif // lldb_FormattersContainer_h_ +#endif // LLDB_DATAFORMATTERS_FORMATTERSCONTAINER_H diff --git a/gnu/llvm/lldb/include/lldb/DataFormatters/FormattersHelpers.h b/gnu/llvm/lldb/include/lldb/DataFormatters/FormattersHelpers.h index 79bd376c76e..a5b0da57e5d 100644 --- a/gnu/llvm/lldb/include/lldb/DataFormatters/FormattersHelpers.h +++ b/gnu/llvm/lldb/include/lldb/DataFormatters/FormattersHelpers.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_FormattersHelpers_h_ -#define lldb_FormattersHelpers_h_ +#ifndef LLDB_DATAFORMATTERS_FORMATTERSHELPERS_H +#define LLDB_DATAFORMATTERS_FORMATTERSHELPERS_H #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" @@ -56,6 +56,8 @@ size_t ExtractIndexFromString(const char *item_name); lldb::addr_t GetArrayAddressOrPointerValue(ValueObject &valobj); +lldb::ValueObjectSP GetValueOfLibCXXCompressedPair(ValueObject &pair); + time_t GetOSXEpoch(); struct InferiorSizedWord { @@ -184,4 +186,4 @@ private: } // namespace formatters } // namespace lldb_private -#endif // lldb_FormattersHelpers_h_ +#endif // LLDB_DATAFORMATTERS_FORMATTERSHELPERS_H diff --git a/gnu/llvm/lldb/include/lldb/DataFormatters/LanguageCategory.h b/gnu/llvm/lldb/include/lldb/DataFormatters/LanguageCategory.h index 1cffff91c19..d7676730fbd 100644 --- a/gnu/llvm/lldb/include/lldb/DataFormatters/LanguageCategory.h +++ b/gnu/llvm/lldb/include/lldb/DataFormatters/LanguageCategory.h @@ -7,9 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_LanguageCategory_h_ -#define lldb_LanguageCategory_h_ - +#ifndef LLDB_DATAFORMATTERS_LANGUAGECATEGORY_H +#define LLDB_DATAFORMATTERS_LANGUAGECATEGORY_H #include "lldb/DataFormatters/FormatCache.h" #include "lldb/DataFormatters/FormatClasses.h" @@ -58,4 +57,4 @@ private: } // namespace lldb_private -#endif // lldb_LanguageCategory_h_ +#endif // LLDB_DATAFORMATTERS_LANGUAGECATEGORY_H diff --git a/gnu/llvm/lldb/include/lldb/DataFormatters/StringPrinter.h b/gnu/llvm/lldb/include/lldb/DataFormatters/StringPrinter.h index 43b92019e6f..17c645f8637 100644 --- a/gnu/llvm/lldb/include/lldb/DataFormatters/StringPrinter.h +++ b/gnu/llvm/lldb/include/lldb/DataFormatters/StringPrinter.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StringPrinter_h_ -#define liblldb_StringPrinter_h_ +#ifndef LLDB_DATAFORMATTERS_STRINGPRINTER_H +#define LLDB_DATAFORMATTERS_STRINGPRINTER_H #include #include @@ -24,6 +24,8 @@ public: enum class GetPrintableElementType { ASCII, UTF8 }; + enum class EscapeStyle { CXX, Swift }; + class DumpToStreamOptions { public: DumpToStreamOptions() = default; @@ -68,9 +70,9 @@ public: bool GetIgnoreMaxLength() const { return m_ignore_max_length; } - void SetLanguage(lldb::LanguageType l) { m_language_type = l; } + void SetEscapeStyle(EscapeStyle style) { m_escape_style = style; } - lldb::LanguageType GetLanguage() const { return m_language_type; } + EscapeStyle GetEscapeStyle() const { return m_escape_style; } private: /// The used output stream. @@ -93,12 +95,8 @@ public: /// True iff a zero bytes ('\0') should terminate the memory region that /// is being dumped. bool m_zero_is_terminator = true; - /// The language that the generated string literal is supposed to be valid - /// for. This changes for example what and how certain characters are - /// escaped. - /// For example, printing the a string containing only a quote (") char - /// with eLanguageTypeC would escape the quote character. - lldb::LanguageType m_language_type = lldb::eLanguageTypeUnknown; + /// The language-specific style for escaping special characters. + EscapeStyle m_escape_style = EscapeStyle::CXX; }; class ReadStringAndDumpToStreamOptions : public DumpToStreamOptions { @@ -115,9 +113,15 @@ public: lldb::ProcessSP GetProcessSP() const { return m_process_sp; } + void SetHasSourceSize(bool e) { m_has_source_size = e; } + + bool HasSourceSize() const { return m_has_source_size; } + private: uint64_t m_location = 0; lldb::ProcessSP m_process_sp; + /// True iff we know the source size of the string. + bool m_has_source_size = false; }; class ReadBufferAndDumpToStreamOptions : public DumpToStreamOptions { @@ -141,75 +145,6 @@ public: bool m_is_truncated = false; }; - // I can't use a std::unique_ptr for this because the Deleter is a template - // argument there - // and I want the same type to represent both pointers I want to free and - // pointers I don't need to free - which is what this class essentially is - // It's very specialized to the needs of this file, and not suggested for - // general use - template - struct StringPrinterBufferPointer { - public: - typedef std::function Deleter; - - StringPrinterBufferPointer(std::nullptr_t ptr) - : m_data(nullptr), m_size(0), m_deleter() {} - - StringPrinterBufferPointer(const T *bytes, S size, - Deleter deleter = nullptr) - : m_data(bytes), m_size(size), m_deleter(deleter) {} - - StringPrinterBufferPointer(const U *bytes, S size, - Deleter deleter = nullptr) - : m_data(reinterpret_cast(bytes)), m_size(size), - m_deleter(deleter) {} - - StringPrinterBufferPointer(StringPrinterBufferPointer &&rhs) - : m_data(rhs.m_data), m_size(rhs.m_size), m_deleter(rhs.m_deleter) { - rhs.m_data = nullptr; - } - - StringPrinterBufferPointer(const StringPrinterBufferPointer &rhs) - : m_data(rhs.m_data), m_size(rhs.m_size), m_deleter(rhs.m_deleter) { - rhs.m_data = nullptr; // this is why m_data has to be mutable - } - - ~StringPrinterBufferPointer() { - if (m_data && m_deleter) - m_deleter(m_data); - m_data = nullptr; - } - - const T *GetBytes() const { return m_data; } - - const S GetSize() const { return m_size; } - - StringPrinterBufferPointer & - operator=(const StringPrinterBufferPointer &rhs) { - if (m_data && m_deleter) - m_deleter(m_data); - m_data = rhs.m_data; - m_size = rhs.m_size; - m_deleter = rhs.m_deleter; - rhs.m_data = nullptr; - return *this; - } - - private: - mutable const T *m_data; - size_t m_size; - Deleter m_deleter; - }; - - typedef std::function(uint8_t *, uint8_t *, uint8_t *&)> - EscapingHelper; - typedef std::function - EscapingHelperGenerator; - - static EscapingHelper - GetDefaultEscapingHelper(GetPrintableElementType elem_type); - template static bool ReadStringAndDumpToStream(const ReadStringAndDumpToStreamOptions &options); @@ -222,4 +157,4 @@ public: } // namespace formatters } // namespace lldb_private -#endif // liblldb_StringPrinter_h_ +#endif // LLDB_DATAFORMATTERS_STRINGPRINTER_H diff --git a/gnu/llvm/lldb/include/lldb/DataFormatters/TypeCategory.h b/gnu/llvm/lldb/include/lldb/DataFormatters/TypeCategory.h index d5aab6dc3a5..820872a59bd 100644 --- a/gnu/llvm/lldb/include/lldb/DataFormatters/TypeCategory.h +++ b/gnu/llvm/lldb/include/lldb/DataFormatters/TypeCategory.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_TypeCategory_h_ -#define lldb_TypeCategory_h_ +#ifndef LLDB_DATAFORMATTERS_TYPECATEGORY_H +#define LLDB_DATAFORMATTERS_TYPECATEGORY_H #include #include @@ -285,13 +285,13 @@ public: } bool Get(lldb::LanguageType lang, const FormattersMatchVector &candidates, - lldb::TypeFormatImplSP &entry, uint32_t *reason = nullptr); + lldb::TypeFormatImplSP &entry); bool Get(lldb::LanguageType lang, const FormattersMatchVector &candidates, - lldb::TypeSummaryImplSP &entry, uint32_t *reason = nullptr); + lldb::TypeSummaryImplSP &entry); bool Get(lldb::LanguageType lang, const FormattersMatchVector &candidates, - lldb::SyntheticChildrenSP &entry, uint32_t *reason = nullptr); + lldb::SyntheticChildrenSP &entry); void Clear(FormatCategoryItems items = ALL_ITEM_TYPES); @@ -366,4 +366,4 @@ private: } // namespace lldb_private -#endif // lldb_TypeCategory_h_ +#endif // LLDB_DATAFORMATTERS_TYPECATEGORY_H diff --git a/gnu/llvm/lldb/include/lldb/DataFormatters/TypeCategoryMap.h b/gnu/llvm/lldb/include/lldb/DataFormatters/TypeCategoryMap.h index ae577a33401..832652f7d74 100644 --- a/gnu/llvm/lldb/include/lldb/DataFormatters/TypeCategoryMap.h +++ b/gnu/llvm/lldb/include/lldb/DataFormatters/TypeCategoryMap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_TypeCategoryMap_h_ -#define lldb_TypeCategoryMap_h_ +#ifndef LLDB_DATAFORMATTERS_TYPECATEGORYMAP_H +#define LLDB_DATAFORMATTERS_TYPECATEGORYMAP_H #include #include @@ -108,4 +108,4 @@ private: }; } // namespace lldb_private -#endif // lldb_TypeCategoryMap_h_ +#endif // LLDB_DATAFORMATTERS_TYPECATEGORYMAP_H diff --git a/gnu/llvm/lldb/include/lldb/DataFormatters/TypeFormat.h b/gnu/llvm/lldb/include/lldb/DataFormatters/TypeFormat.h index 77e8c0efc70..b8ed6a3443b 100644 --- a/gnu/llvm/lldb/include/lldb/DataFormatters/TypeFormat.h +++ b/gnu/llvm/lldb/include/lldb/DataFormatters/TypeFormat.h @@ -7,9 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_TypeFormat_h_ -#define lldb_TypeFormat_h_ - +#ifndef LLDB_DATAFORMATTERS_TYPEFORMAT_H +#define LLDB_DATAFORMATTERS_TYPEFORMAT_H #include #include @@ -153,7 +152,8 @@ protected: uint32_t m_my_revision; private: - DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl); + TypeFormatImpl(const TypeFormatImpl &) = delete; + const TypeFormatImpl &operator=(const TypeFormatImpl &) = delete; }; class TypeFormatImpl_Format : public TypeFormatImpl { @@ -181,7 +181,9 @@ protected: lldb::Format m_format; private: - DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl_Format); + TypeFormatImpl_Format(const TypeFormatImpl_Format &) = delete; + const TypeFormatImpl_Format & + operator=(const TypeFormatImpl_Format &) = delete; }; class TypeFormatImpl_EnumType : public TypeFormatImpl { @@ -210,8 +212,10 @@ protected: mutable std::unordered_map m_types; private: - DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl_EnumType); + TypeFormatImpl_EnumType(const TypeFormatImpl_EnumType &) = delete; + const TypeFormatImpl_EnumType & + operator=(const TypeFormatImpl_EnumType &) = delete; }; } // namespace lldb_private -#endif // lldb_TypeFormat_h_ +#endif // LLDB_DATAFORMATTERS_TYPEFORMAT_H diff --git a/gnu/llvm/lldb/include/lldb/DataFormatters/TypeSummary.h b/gnu/llvm/lldb/include/lldb/DataFormatters/TypeSummary.h index 9c97b3606f2..6c3780f7276 100644 --- a/gnu/llvm/lldb/include/lldb/DataFormatters/TypeSummary.h +++ b/gnu/llvm/lldb/include/lldb/DataFormatters/TypeSummary.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_TypeSummary_h_ -#define lldb_TypeSummary_h_ +#ifndef LLDB_DATAFORMATTERS_TYPESUMMARY_H +#define LLDB_DATAFORMATTERS_TYPESUMMARY_H #include @@ -270,7 +270,8 @@ protected: private: Kind m_kind; - DISALLOW_COPY_AND_ASSIGN(TypeSummaryImpl); + TypeSummaryImpl(const TypeSummaryImpl &) = delete; + const TypeSummaryImpl &operator=(const TypeSummaryImpl &) = delete; }; // simple string-based summaries, using ${var to show data @@ -297,7 +298,8 @@ struct StringSummaryFormat : public TypeSummaryImpl { } private: - DISALLOW_COPY_AND_ASSIGN(StringSummaryFormat); + StringSummaryFormat(const StringSummaryFormat &) = delete; + const StringSummaryFormat &operator=(const StringSummaryFormat &) = delete; }; // summaries implemented via a C++ function @@ -341,7 +343,9 @@ struct CXXFunctionSummaryFormat : public TypeSummaryImpl { typedef std::shared_ptr SharedPointer; private: - DISALLOW_COPY_AND_ASSIGN(CXXFunctionSummaryFormat); + CXXFunctionSummaryFormat(const CXXFunctionSummaryFormat &) = delete; + const CXXFunctionSummaryFormat & + operator=(const CXXFunctionSummaryFormat &) = delete; }; // Python-based summaries, running script code to show data @@ -387,8 +391,9 @@ struct ScriptSummaryFormat : public TypeSummaryImpl { typedef std::shared_ptr SharedPointer; private: - DISALLOW_COPY_AND_ASSIGN(ScriptSummaryFormat); + ScriptSummaryFormat(const ScriptSummaryFormat &) = delete; + const ScriptSummaryFormat &operator=(const ScriptSummaryFormat &) = delete; }; } // namespace lldb_private -#endif // lldb_TypeSummary_h_ +#endif // LLDB_DATAFORMATTERS_TYPESUMMARY_H diff --git a/gnu/llvm/lldb/include/lldb/DataFormatters/TypeSynthetic.h b/gnu/llvm/lldb/include/lldb/DataFormatters/TypeSynthetic.h index 93443cf7e84..c852ff18bfa 100644 --- a/gnu/llvm/lldb/include/lldb/DataFormatters/TypeSynthetic.h +++ b/gnu/llvm/lldb/include/lldb/DataFormatters/TypeSynthetic.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_TypeSynthetic_h_ -#define lldb_TypeSynthetic_h_ +#ifndef LLDB_DATAFORMATTERS_TYPESYNTHETIC_H +#define LLDB_DATAFORMATTERS_TYPESYNTHETIC_H #include @@ -96,7 +96,9 @@ protected: private: bool m_valid; - DISALLOW_COPY_AND_ASSIGN(SyntheticChildrenFrontEnd); + SyntheticChildrenFrontEnd(const SyntheticChildrenFrontEnd &) = delete; + const SyntheticChildrenFrontEnd & + operator=(const SyntheticChildrenFrontEnd &) = delete; }; class SyntheticValueProviderFrontEnd : public SyntheticChildrenFrontEnd { @@ -121,7 +123,10 @@ public: lldb::ValueObjectSP GetSyntheticValue() override = 0; private: - DISALLOW_COPY_AND_ASSIGN(SyntheticValueProviderFrontEnd); + SyntheticValueProviderFrontEnd(const SyntheticValueProviderFrontEnd &) = + delete; + const SyntheticValueProviderFrontEnd & + operator=(const SyntheticValueProviderFrontEnd &) = delete; }; class SyntheticChildren { @@ -265,7 +270,8 @@ protected: Flags m_flags; private: - DISALLOW_COPY_AND_ASSIGN(SyntheticChildren); + SyntheticChildren(const SyntheticChildren &) = delete; + const SyntheticChildren &operator=(const SyntheticChildren &) = delete; }; class TypeFilterImpl : public SyntheticChildren { @@ -333,7 +339,8 @@ public: private: TypeFilterImpl *filter; - DISALLOW_COPY_AND_ASSIGN(FrontEnd); + FrontEnd(const FrontEnd &) = delete; + const FrontEnd &operator=(const FrontEnd &) = delete; }; SyntheticChildrenFrontEnd::AutoPointer @@ -344,7 +351,8 @@ public: typedef std::shared_ptr SharedPointer; private: - DISALLOW_COPY_AND_ASSIGN(TypeFilterImpl); + TypeFilterImpl(const TypeFilterImpl &) = delete; + const TypeFilterImpl &operator=(const TypeFilterImpl &) = delete; }; class CXXSyntheticChildren : public SyntheticChildren { @@ -372,7 +380,8 @@ protected: std::string m_description; private: - DISALLOW_COPY_AND_ASSIGN(CXXSyntheticChildren); + CXXSyntheticChildren(const CXXSyntheticChildren &) = delete; + const CXXSyntheticChildren &operator=(const CXXSyntheticChildren &) = delete; }; class ScriptedSyntheticChildren : public SyntheticChildren { @@ -435,7 +444,8 @@ public: StructuredData::ObjectSP m_wrapper_sp; ScriptInterpreter *m_interpreter; - DISALLOW_COPY_AND_ASSIGN(FrontEnd); + FrontEnd(const FrontEnd &) = delete; + const FrontEnd &operator=(const FrontEnd &) = delete; }; SyntheticChildrenFrontEnd::AutoPointer @@ -448,8 +458,10 @@ public: } private: - DISALLOW_COPY_AND_ASSIGN(ScriptedSyntheticChildren); + ScriptedSyntheticChildren(const ScriptedSyntheticChildren &) = delete; + const ScriptedSyntheticChildren & + operator=(const ScriptedSyntheticChildren &) = delete; }; } // namespace lldb_private -#endif // lldb_TypeSynthetic_h_ +#endif // LLDB_DATAFORMATTERS_TYPESYNTHETIC_H diff --git a/gnu/llvm/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h b/gnu/llvm/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h index 33813b38701..f1301d8595b 100644 --- a/gnu/llvm/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h +++ b/gnu/llvm/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h @@ -7,9 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_ValueObjectPrinter_h_ -#define lldb_ValueObjectPrinter_h_ - +#ifndef LLDB_DATAFORMATTERS_VALUEOBJECTPRINTER_H +#define LLDB_DATAFORMATTERS_VALUEOBJECTPRINTER_H #include "lldb/lldb-private.h" #include "lldb/lldb-public.h" @@ -58,7 +57,7 @@ protected: const char *GetDescriptionForDisplay(); - const char *GetRootNameForDisplay(const char *if_fail = nullptr); + const char *GetRootNameForDisplay(); bool ShouldPrintValueObject(); @@ -142,9 +141,10 @@ private: friend struct StringSummaryFormat; - DISALLOW_COPY_AND_ASSIGN(ValueObjectPrinter); + ValueObjectPrinter(const ValueObjectPrinter &) = delete; + const ValueObjectPrinter &operator=(const ValueObjectPrinter &) = delete; }; } // namespace lldb_private -#endif // lldb_ValueObjectPrinter_h_ +#endif // LLDB_DATAFORMATTERS_VALUEOBJECTPRINTER_H diff --git a/gnu/llvm/lldb/include/lldb/DataFormatters/VectorIterator.h b/gnu/llvm/lldb/include/lldb/DataFormatters/VectorIterator.h index cde4be498b0..33650a3dac8 100644 --- a/gnu/llvm/lldb/include/lldb/DataFormatters/VectorIterator.h +++ b/gnu/llvm/lldb/include/lldb/DataFormatters/VectorIterator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_VectorIterator_h_ -#define liblldb_VectorIterator_h_ +#ifndef LLDB_DATAFORMATTERS_VECTORITERATOR_H +#define LLDB_DATAFORMATTERS_VECTORITERATOR_H #include "lldb/lldb-forward.h" @@ -42,4 +42,4 @@ private: } // namespace formatters } // namespace lldb_private -#endif // liblldb_CF_h_ +#endif // LLDB_DATAFORMATTERS_VECTORITERATOR_H diff --git a/gnu/llvm/lldb/include/lldb/DataFormatters/VectorType.h b/gnu/llvm/lldb/include/lldb/DataFormatters/VectorType.h index b757f758e77..6a66b1815c2 100644 --- a/gnu/llvm/lldb/include/lldb/DataFormatters/VectorType.h +++ b/gnu/llvm/lldb/include/lldb/DataFormatters/VectorType.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_VectorType_h_ -#define liblldb_VectorType_h_ +#ifndef LLDB_DATAFORMATTERS_VECTORTYPE_H +#define LLDB_DATAFORMATTERS_VECTORTYPE_H #include "lldb/lldb-forward.h" @@ -21,4 +21,4 @@ VectorTypeSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); } // namespace formatters } // namespace lldb_private -#endif // liblldb_VectorType_h_ +#endif // LLDB_DATAFORMATTERS_VECTORTYPE_H diff --git a/gnu/llvm/lldb/include/lldb/Expression/DWARFExpression.h b/gnu/llvm/lldb/include/lldb/Expression/DWARFExpression.h index bfae142d5e0..6b63b186e3e 100644 --- a/gnu/llvm/lldb/include/lldb/Expression/DWARFExpression.h +++ b/gnu/llvm/lldb/include/lldb/Expression/DWARFExpression.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFExpression_h_ -#define liblldb_DWARFExpression_h_ +#ifndef LLDB_EXPRESSION_DWARFEXPRESSION_H +#define LLDB_EXPRESSION_DWARFEXPRESSION_H #include "lldb/Core/Address.h" #include "lldb/Core/Disassembler.h" @@ -217,14 +217,6 @@ public: lldb::addr_t func_load_addr, lldb::addr_t address, ABI *abi); - static bool PrintDWARFExpression(Stream &s, const DataExtractor &data, - int address_size, int dwarf_ref_size, - bool location_expression); - - static void PrintDWARFLocationList(Stream &s, const DWARFUnit *cu, - const DataExtractor &debug_loc_data, - lldb::offset_t offset); - bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op); private: @@ -233,11 +225,8 @@ private: /// \param[in] s /// The stream to use for pretty-printing. /// - /// \param[in] offset - /// The offset into the data buffer of the opcodes to be printed. - /// - /// \param[in] length - /// The length in bytes of the opcodes to be printed. + /// \param[in] data + /// The data extractor. /// /// \param[in] level /// The level of detail to use in pretty-printing. @@ -275,4 +264,4 @@ private: } // namespace lldb_private -#endif // liblldb_DWARFExpression_h_ +#endif // LLDB_EXPRESSION_DWARFEXPRESSION_H diff --git a/gnu/llvm/lldb/include/lldb/Expression/DiagnosticManager.h b/gnu/llvm/lldb/include/lldb/Expression/DiagnosticManager.h index e5aecce0872..c0271c954ba 100644 --- a/gnu/llvm/lldb/include/lldb/Expression/DiagnosticManager.h +++ b/gnu/llvm/lldb/include/lldb/Expression/DiagnosticManager.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_DiagnosticManager_h -#define lldb_DiagnosticManager_h +#ifndef LLDB_EXPRESSION_DIAGNOSTICMANAGER_H +#define LLDB_EXPRESSION_DIAGNOSTICMANAGER_H #include "lldb/lldb-defines.h" #include "lldb/lldb-types.h" @@ -78,7 +78,7 @@ public: bool precede_with_newline = true) { if (precede_with_newline) m_message.push_back('\n'); - m_message.append(message); + m_message += message; } protected: @@ -148,4 +148,4 @@ protected: }; } -#endif /* lldb_DiagnosticManager_h */ +#endif // LLDB_EXPRESSION_DIAGNOSTICMANAGER_H diff --git a/gnu/llvm/lldb/include/lldb/Expression/DynamicCheckerFunctions.h b/gnu/llvm/lldb/include/lldb/Expression/DynamicCheckerFunctions.h index 7be24b6ea96..02bce5abdf4 100644 --- a/gnu/llvm/lldb/include/lldb/Expression/DynamicCheckerFunctions.h +++ b/gnu/llvm/lldb/include/lldb/Expression/DynamicCheckerFunctions.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DynamicCheckerFunctions_h_ -#define liblldb_DynamicCheckerFunctions_h_ +#ifndef LLDB_EXPRESSION_DYNAMICCHECKERFUNCTIONS_H +#define LLDB_EXPRESSION_DYNAMICCHECKERFUNCTIONS_H #include "lldb/lldb-types.h" @@ -59,4 +59,4 @@ private: }; } // namespace lldb_private -#endif // liblldb_DynamicCheckerFunctions_h_ +#endif // LLDB_EXPRESSION_DYNAMICCHECKERFUNCTIONS_H diff --git a/gnu/llvm/lldb/include/lldb/Expression/Expression.h b/gnu/llvm/lldb/include/lldb/Expression/Expression.h index e0ea7e99f4f..aaac889e6ed 100644 --- a/gnu/llvm/lldb/include/lldb/Expression/Expression.h +++ b/gnu/llvm/lldb/include/lldb/Expression/Expression.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Expression_h_ -#define liblldb_Expression_h_ +#ifndef LLDB_EXPRESSION_EXPRESSION_H +#define LLDB_EXPRESSION_EXPRESSION_H #include #include @@ -51,7 +51,9 @@ public: /// Return the language that should be used when parsing. To use the /// default, return eLanguageTypeUnknown. - virtual lldb::LanguageType Language() { return lldb::eLanguageTypeUnknown; } + virtual lldb::LanguageType Language() const { + return lldb::eLanguageTypeUnknown; + } /// Return the Materializer that the parser should use when registering /// external values. @@ -101,4 +103,4 @@ protected: } // namespace lldb_private -#endif // liblldb_Expression_h_ +#endif // LLDB_EXPRESSION_EXPRESSION_H diff --git a/gnu/llvm/lldb/include/lldb/Expression/ExpressionParser.h b/gnu/llvm/lldb/include/lldb/Expression/ExpressionParser.h index 2e7b3075d50..71d2410ea7c 100644 --- a/gnu/llvm/lldb/include/lldb/Expression/ExpressionParser.h +++ b/gnu/llvm/lldb/include/lldb/Expression/ExpressionParser.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ExpressionParser_h_ -#define liblldb_ExpressionParser_h_ +#ifndef LLDB_EXPRESSION_EXPRESSIONPARSER_H +#define LLDB_EXPRESSION_EXPRESSIONPARSER_H #include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/Status.h" @@ -133,4 +133,4 @@ protected: }; } -#endif // liblldb_ExpressionParser_h_ +#endif // LLDB_EXPRESSION_EXPRESSIONPARSER_H diff --git a/gnu/llvm/lldb/include/lldb/Expression/ExpressionSourceCode.h b/gnu/llvm/lldb/include/lldb/Expression/ExpressionSourceCode.h index db8ef967ab1..a3be73997c2 100644 --- a/gnu/llvm/lldb/include/lldb/Expression/ExpressionSourceCode.h +++ b/gnu/llvm/lldb/include/lldb/Expression/ExpressionSourceCode.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ExpressionSourceCode_h -#define liblldb_ExpressionSourceCode_h +#ifndef LLDB_EXPRESSION_EXPRESSIONSOURCECODE_H +#define LLDB_EXPRESSION_EXPRESSIONSOURCECODE_H #include "lldb/lldb-enumerations.h" #include "llvm/ADT/ArrayRef.h" diff --git a/gnu/llvm/lldb/include/lldb/Expression/ExpressionTypeSystemHelper.h b/gnu/llvm/lldb/include/lldb/Expression/ExpressionTypeSystemHelper.h index 9c645532cdc..1bba30ad862 100644 --- a/gnu/llvm/lldb/include/lldb/Expression/ExpressionTypeSystemHelper.h +++ b/gnu/llvm/lldb/include/lldb/Expression/ExpressionTypeSystemHelper.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef ExpressionTypeSystemHelper_h -#define ExpressionTypeSystemHelper_h +#ifndef LLDB_EXPRESSION_EXPRESSIONTYPESYSTEMHELPER_H +#define LLDB_EXPRESSION_EXPRESSIONTYPESYSTEMHELPER_H #include "llvm/Support/Casting.h" @@ -44,4 +44,4 @@ protected: } // namespace lldb_private -#endif /* ExpressionTypeSystemHelper_h */ +#endif // LLDB_EXPRESSION_EXPRESSIONTYPESYSTEMHELPER_H diff --git a/gnu/llvm/lldb/include/lldb/Expression/ExpressionVariable.h b/gnu/llvm/lldb/include/lldb/Expression/ExpressionVariable.h index c20c2301bb5..60062d212ba 100644 --- a/gnu/llvm/lldb/include/lldb/Expression/ExpressionVariable.h +++ b/gnu/llvm/lldb/include/lldb/Expression/ExpressionVariable.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ExpressionVariable_h_ -#define liblldb_ExpressionVariable_h_ +#ifndef LLDB_EXPRESSION_EXPRESSIONVARIABLE_H +#define LLDB_EXPRESSION_EXPRESSIONVARIABLE_H #include #include @@ -221,11 +221,7 @@ public: uint32_t addr_byte_size) = 0; /// Return a new persistent variable name with the specified prefix. - ConstString GetNextPersistentVariableName(Target &target, - llvm::StringRef prefix); - - virtual llvm::StringRef - GetPersistentVariablePrefix(bool is_error = false) const = 0; + virtual ConstString GetNextPersistentVariableName(bool is_error = false) = 0; virtual void RemovePersistentVariable(lldb::ExpressionVariableSP variable) = 0; @@ -237,6 +233,10 @@ public: void RegisterExecutionUnit(lldb::IRExecutionUnitSP &execution_unit_sp); +protected: + virtual llvm::StringRef + GetPersistentVariablePrefix(bool is_error = false) const = 0; + private: LLVMCastKind m_kind; @@ -251,4 +251,4 @@ private: } // namespace lldb_private -#endif // liblldb_ExpressionVariable_h_ +#endif // LLDB_EXPRESSION_EXPRESSIONVARIABLE_H diff --git a/gnu/llvm/lldb/include/lldb/Expression/FunctionCaller.h b/gnu/llvm/lldb/include/lldb/Expression/FunctionCaller.h index 1303655f449..f35ee820edd 100644 --- a/gnu/llvm/lldb/include/lldb/Expression/FunctionCaller.h +++ b/gnu/llvm/lldb/include/lldb/Expression/FunctionCaller.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_FunctionCaller_h_ -#define liblldb_FunctionCaller_h_ +#ifndef LLDB_EXPRESSION_FUNCTIONCALLER_H +#define LLDB_EXPRESSION_FUNCTIONCALLER_H #include #include @@ -336,4 +336,4 @@ protected: } // namespace lldb_private -#endif // liblldb_FunctionCaller_h_ +#endif // LLDB_EXPRESSION_FUNCTIONCALLER_H diff --git a/gnu/llvm/lldb/include/lldb/Expression/IRExecutionUnit.h b/gnu/llvm/lldb/include/lldb/Expression/IRExecutionUnit.h index 05f2f8471ef..ad3c7372e67 100644 --- a/gnu/llvm/lldb/include/lldb/Expression/IRExecutionUnit.h +++ b/gnu/llvm/lldb/include/lldb/Expression/IRExecutionUnit.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_IRExecutionUnit_h_ -#define liblldb_IRExecutionUnit_h_ +#ifndef LLDB_EXPRESSION_IREXECUTIONUNIT_H +#define LLDB_EXPRESSION_IREXECUTIONUNIT_H #include #include @@ -71,7 +71,7 @@ public: llvm::Module *GetModule() { return m_module; } llvm::Function *GetFunction() { - return ((m_module != nullptr) ? m_module->getFunction(m_name.AsCString()) + return ((m_module != nullptr) ? m_module->getFunction(m_name.GetStringRef()) : nullptr); } @@ -406,4 +406,4 @@ private: } // namespace lldb_private -#endif // liblldb_IRExecutionUnit_h_ +#endif // LLDB_EXPRESSION_IREXECUTIONUNIT_H diff --git a/gnu/llvm/lldb/include/lldb/Expression/IRInterpreter.h b/gnu/llvm/lldb/include/lldb/Expression/IRInterpreter.h index 6148093e718..98ece967a92 100644 --- a/gnu/llvm/lldb/include/lldb/Expression/IRInterpreter.h +++ b/gnu/llvm/lldb/include/lldb/Expression/IRInterpreter.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_IRInterpreter_h_ -#define liblldb_IRInterpreter_h_ +#ifndef LLDB_EXPRESSION_IRINTERPRETER_H +#define LLDB_EXPRESSION_IRINTERPRETER_H #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Stream.h" @@ -22,7 +22,6 @@ class Module; namespace lldb_private { -class ClangExpressionDeclMap; class IRMemoryMap; } diff --git a/gnu/llvm/lldb/include/lldb/Expression/IRMemoryMap.h b/gnu/llvm/lldb/include/lldb/Expression/IRMemoryMap.h index d6a17a9848f..abec5442793 100644 --- a/gnu/llvm/lldb/include/lldb/Expression/IRMemoryMap.h +++ b/gnu/llvm/lldb/include/lldb/Expression/IRMemoryMap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_IRMemoryMap_h_ -#define lldb_IRMemoryMap_h_ +#ifndef LLDB_EXPRESSION_IRMEMORYMAP_H +#define LLDB_EXPRESSION_IRMEMORYMAP_H #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/UserID.h" @@ -107,7 +107,8 @@ private: size_t size, uint32_t permissions, uint8_t alignment, AllocationPolicy m_policy); - DISALLOW_COPY_AND_ASSIGN(Allocation); + Allocation(const Allocation &) = delete; + const Allocation &operator=(const Allocation &) = delete; }; static_assert(sizeof(Allocation) <= diff --git a/gnu/llvm/lldb/include/lldb/Expression/LLVMUserExpression.h b/gnu/llvm/lldb/include/lldb/Expression/LLVMUserExpression.h index 2679c01a4e0..244a28aec24 100644 --- a/gnu/llvm/lldb/include/lldb/Expression/LLVMUserExpression.h +++ b/gnu/llvm/lldb/include/lldb/Expression/LLVMUserExpression.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_LLVMUserExpression_h -#define liblldb_LLVMUserExpression_h +#ifndef LLDB_EXPRESSION_LLVMUSEREXPRESSION_H +#define LLDB_EXPRESSION_LLVMUSEREXPRESSION_H #include #include @@ -71,8 +71,6 @@ public: /// translation unit. const char *Text() override { return m_transformed_text.c_str(); } - lldb::ModuleSP GetJITModule() override; - protected: lldb::ExpressionResults DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, diff --git a/gnu/llvm/lldb/include/lldb/Expression/Materializer.h b/gnu/llvm/lldb/include/lldb/Expression/Materializer.h index 70f622e7850..754e67c5dfa 100644 --- a/gnu/llvm/lldb/include/lldb/Expression/Materializer.h +++ b/gnu/llvm/lldb/include/lldb/Expression/Materializer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Materializer_h -#define liblldb_Materializer_h +#ifndef LLDB_EXPRESSION_MATERIALIZER_H +#define LLDB_EXPRESSION_MATERIALIZER_H #include #include @@ -22,14 +22,12 @@ namespace lldb_private { class Materializer { public: - Materializer(); + Materializer() = default; ~Materializer(); class Dematerializer { public: - Dematerializer() - : m_materializer(nullptr), m_map(nullptr), - m_process_address(LLDB_INVALID_ADDRESS) {} + Dematerializer() = default; ~Dematerializer() { Wipe(); } @@ -56,11 +54,11 @@ public: } } - Materializer *m_materializer; + Materializer *m_materializer = nullptr; lldb::ThreadWP m_thread_wp; StackID m_stack_id; - IRMemoryMap *m_map; - lldb::addr_t m_process_address; + IRMemoryMap *m_map = nullptr; + lldb::addr_t m_process_address = LLDB_INVALID_ADDRESS; }; typedef std::shared_ptr DematerializerSP; @@ -128,10 +126,10 @@ private: DematerializerWP m_dematerializer_wp; EntityVector m_entities; - uint32_t m_current_offset; - uint32_t m_struct_alignment; + uint32_t m_current_offset = 0; + uint32_t m_struct_alignment = 8; }; } // namespace lldb_private -#endif // liblldb_Materializer_h +#endif // LLDB_EXPRESSION_MATERIALIZER_H diff --git a/gnu/llvm/lldb/include/lldb/Expression/REPL.h b/gnu/llvm/lldb/include/lldb/Expression/REPL.h index 035ad63271e..a0df53eb9b4 100644 --- a/gnu/llvm/lldb/include/lldb/Expression/REPL.h +++ b/gnu/llvm/lldb/include/lldb/Expression/REPL.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_REPL_h -#define lldb_REPL_h +#ifndef LLDB_EXPRESSION_REPL_H +#define LLDB_EXPRESSION_REPL_H #include @@ -130,8 +130,8 @@ protected: lldb::ValueObjectSP &valobj_sp, ExpressionVariable *var = nullptr) = 0; - virtual int CompleteCode(const std::string ¤t_code, - StringList &matches) = 0; + virtual void CompleteCode(const std::string ¤t_code, + CompletionRequest &request) = 0; OptionGroupFormat m_format_options = OptionGroupFormat(lldb::eFormatDefault); OptionGroupValueObjectDisplay m_varobj_options; @@ -158,4 +158,4 @@ private: } // namespace lldb_private -#endif // lldb_REPL_h +#endif // LLDB_EXPRESSION_REPL_H diff --git a/gnu/llvm/lldb/include/lldb/Expression/UserExpression.h b/gnu/llvm/lldb/include/lldb/Expression/UserExpression.h index 83122d8ba51..8236c417f73 100644 --- a/gnu/llvm/lldb/include/lldb/Expression/UserExpression.h +++ b/gnu/llvm/lldb/include/lldb/Expression/UserExpression.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_UserExpression_h_ -#define liblldb_UserExpression_h_ +#ifndef LLDB_EXPRESSION_USEREXPRESSION_H +#define LLDB_EXPRESSION_USEREXPRESSION_H #include #include @@ -194,7 +194,7 @@ public: /// Return the language that should be used when parsing. To use the /// default, return eLanguageTypeUnknown. - lldb::LanguageType Language() override { return m_language; } + lldb::LanguageType Language() const override { return m_language; } /// Return the desired result type of the function, or eResultTypeAny if /// indifferent. @@ -213,8 +213,6 @@ public: return lldb::ExpressionVariableSP(); } - virtual lldb::ModuleSP GetJITModule() { return lldb::ModuleSP(); } - /// Evaluate one expression in the scratch context of the target passed in /// the exe_ctx and return its result. /// @@ -244,9 +242,6 @@ public: /// If non-nullptr, the fixed expression is copied into the provided /// string. /// - /// \param[out] jit_module_sp_ptr - /// If non-nullptr, used to persist the generated IR module. - /// /// \param[in] ctx_obj /// If specified, then the expression will be evaluated in the context of /// this object. It means that the context object's address will be @@ -265,7 +260,6 @@ public: llvm::StringRef expr_cstr, llvm::StringRef expr_prefix, lldb::ValueObjectSP &result_valobj_sp, Status &error, std::string *fixed_expression = nullptr, - lldb::ModuleSP *jit_module_sp_ptr = nullptr, ValueObject *ctx_obj = nullptr); static const Status::ValueType kNoResult = @@ -314,4 +308,4 @@ protected: } // namespace lldb_private -#endif // liblldb_UserExpression_h_ +#endif // LLDB_EXPRESSION_USEREXPRESSION_H diff --git a/gnu/llvm/lldb/include/lldb/Expression/UtilityFunction.h b/gnu/llvm/lldb/include/lldb/Expression/UtilityFunction.h index c3d185899b0..5ebbc0ede1e 100644 --- a/gnu/llvm/lldb/include/lldb/Expression/UtilityFunction.h +++ b/gnu/llvm/lldb/include/lldb/Expression/UtilityFunction.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_UtilityFunction_h_ -#define liblldb_UtilityFunction_h_ +#ifndef LLDB_EXPRESSION_UTILITYFUNCTION_H +#define LLDB_EXPRESSION_UTILITYFUNCTION_H #include #include @@ -118,4 +118,4 @@ protected: } // namespace lldb_private -#endif // liblldb_UtilityFunction_h_ +#endif // LLDB_EXPRESSION_UTILITYFUNCTION_H diff --git a/gnu/llvm/lldb/include/lldb/Host/Config.h.cmake b/gnu/llvm/lldb/include/lldb/Host/Config.h.cmake index e9065ed04ca..42f4ca1a26c 100644 --- a/gnu/llvm/lldb/include/lldb/Host/Config.h.cmake +++ b/gnu/llvm/lldb/include/lldb/Host/Config.h.cmake @@ -46,6 +46,8 @@ #cmakedefine01 LLDB_ENABLE_PYTHON +#cmakedefine01 LLDB_EMBED_PYTHON_HOME + #cmakedefine LLDB_PYTHON_HOME "${LLDB_PYTHON_HOME}" #define LLDB_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" diff --git a/gnu/llvm/lldb/include/lldb/Host/ConnectionFileDescriptor.h b/gnu/llvm/lldb/include/lldb/Host/ConnectionFileDescriptor.h index 00444d011af..ff6bcc4766e 100644 --- a/gnu/llvm/lldb/include/lldb/Host/ConnectionFileDescriptor.h +++ b/gnu/llvm/lldb/include/lldb/Host/ConnectionFileDescriptor.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Host_ConnectionFileDescriptor_h_ -#define liblldb_Host_ConnectionFileDescriptor_h_ +#ifndef LLDB_HOST_CONNECTIONFILEDESCRIPTOR_H +#define LLDB_HOST_CONNECTIONFILEDESCRIPTOR_H #include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" diff --git a/gnu/llvm/lldb/include/lldb/Host/Debug.h b/gnu/llvm/lldb/include/lldb/Host/Debug.h index 036ce1ebccd..402325c4c16 100644 --- a/gnu/llvm/lldb/include/lldb/Host/Debug.h +++ b/gnu/llvm/lldb/include/lldb/Host/Debug.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Debug_h_ -#define liblldb_Debug_h_ +#ifndef LLDB_HOST_DEBUG_H +#define LLDB_HOST_DEBUG_H #include @@ -148,4 +148,4 @@ struct ThreadStopInfo { }; } -#endif // liblldb_Debug_h_ +#endif // LLDB_HOST_DEBUG_H diff --git a/gnu/llvm/lldb/include/lldb/Host/Editline.h b/gnu/llvm/lldb/include/lldb/Host/Editline.h index db3d9e48cfb..356e8f73473 100644 --- a/gnu/llvm/lldb/include/lldb/Host/Editline.h +++ b/gnu/llvm/lldb/include/lldb/Host/Editline.h @@ -19,17 +19,14 @@ // good amount of the text will // disappear. It's still in the buffer, just invisible. // b) The prompt printing logic for dealing with ANSI formatting characters is -// broken, which is why we're -// working around it here. -// c) When resizing the terminal window, if the cursor moves between rows -// libedit will get confused. d) The incremental search uses escape to cancel -// input, so it's confused by +// broken, which is why we're working around it here. +// c) The incremental search uses escape to cancel input, so it's confused by // ANSI sequences starting with escape. -// e) Emoji support is fairly terrible, presumably it doesn't understand +// d) Emoji support is fairly terrible, presumably it doesn't understand // composed characters? -#ifndef liblldb_Editline_h_ -#define liblldb_Editline_h_ +#ifndef LLDB_HOST_EDITLINE_H +#define LLDB_HOST_EDITLINE_H #if defined(__cplusplus) #include "lldb/Host/Config.h" @@ -50,6 +47,7 @@ #include #endif +#include #include #include #include @@ -171,9 +169,7 @@ public: /// editing scenarios. void SetContinuationPrompt(const char *continuation_prompt); - /// Required to update the width of the terminal registered for I/O. It is - /// critical that this - /// be correct at all times. + /// Call when the terminal size changes void TerminalSizeChanged(); /// Returns the prompt established by SetPrompt() @@ -328,7 +324,8 @@ private: bool CompleteCharacter(char ch, EditLineGetCharType &out); -private: + void ApplyTerminalSizeChange(); + #if LLDB_EDITLINE_USE_WCHAR std::wstring_convert> m_utf8conv; #endif @@ -350,6 +347,7 @@ private: std::string m_set_continuation_prompt; std::string m_current_prompt; bool m_needs_prompt_repaint = false; + volatile std::sig_atomic_t m_terminal_size_has_changed = 0; std::string m_editor_name; FILE *m_input_file; FILE *m_output_file; @@ -368,4 +366,4 @@ private: } #endif // #if defined(__cplusplus) -#endif // liblldb_Editline_h_ +#endif // LLDB_HOST_EDITLINE_H diff --git a/gnu/llvm/lldb/include/lldb/Host/File.h b/gnu/llvm/lldb/include/lldb/Host/File.h index 9beb20556dc..d205a3fe691 100644 --- a/gnu/llvm/lldb/include/lldb/Host/File.h +++ b/gnu/llvm/lldb/include/lldb/Host/File.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_File_h_ -#define liblldb_File_h_ +#ifndef LLDB_HOST_FILE_H +#define LLDB_HOST_FILE_H #include "lldb/Host/PosixApi.h" #include "lldb/Utility/IOObject.h" @@ -367,7 +367,8 @@ protected: void CalculateInteractiveAndTerminal(); private: - DISALLOW_COPY_AND_ASSIGN(File); + File(const File &) = delete; + const File &operator=(const File &) = delete; }; class NativeFile : public File { @@ -428,9 +429,10 @@ protected: std::mutex offset_access_mutex; private: - DISALLOW_COPY_AND_ASSIGN(NativeFile); + NativeFile(const NativeFile &) = delete; + const NativeFile &operator=(const NativeFile &) = delete; }; } // namespace lldb_private -#endif // liblldb_File_h_ +#endif // LLDB_HOST_FILE_H diff --git a/gnu/llvm/lldb/include/lldb/Host/FileCache.h b/gnu/llvm/lldb/include/lldb/Host/FileCache.h index c76916701eb..df0d9a88c6d 100644 --- a/gnu/llvm/lldb/include/lldb/Host/FileCache.h +++ b/gnu/llvm/lldb/include/lldb/Host/FileCache.h @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -#ifndef liblldb_Host_FileCache_h -#define liblldb_Host_FileCache_h +#ifndef LLDB_HOST_FILECACHE_H +#define LLDB_HOST_FILECACHE_H #include #include diff --git a/gnu/llvm/lldb/include/lldb/Host/FileSystem.h b/gnu/llvm/lldb/include/lldb/Host/FileSystem.h index 528c43519a3..8dcff340259 100644 --- a/gnu/llvm/lldb/include/lldb/Host/FileSystem.h +++ b/gnu/llvm/lldb/include/lldb/Host/FileSystem.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Host_FileSystem_h -#define liblldb_Host_FileSystem_h +#ifndef LLDB_HOST_FILESYSTEM_H +#define LLDB_HOST_FILESYSTEM_H #include "lldb/Host/File.h" #include "lldb/Utility/DataBufferLLVM.h" @@ -186,6 +186,9 @@ public: return m_fs; } + void Collect(const FileSpec &file_spec); + void Collect(const llvm::Twine &file); + private: static llvm::Optional &InstanceImpl(); llvm::IntrusiveRefCntPtr m_fs; diff --git a/gnu/llvm/lldb/include/lldb/Host/Host.h b/gnu/llvm/lldb/include/lldb/Host/Host.h index 884c5cf6321..f19cb85d232 100644 --- a/gnu/llvm/lldb/include/lldb/Host/Host.h +++ b/gnu/llvm/lldb/include/lldb/Host/Host.h @@ -27,8 +27,8 @@ namespace lldb_private { class FileAction; class ProcessLaunchInfo; class ProcessInstanceInfo; -class ProcessInstanceInfoList; class ProcessInstanceInfoMatch; +typedef std::vector ProcessInstanceInfoList; // Exit Type for inferior processes struct WaitStatus { @@ -232,6 +232,10 @@ public: static std::unique_ptr CreateDefaultConnection(llvm::StringRef url); + +protected: + static uint32_t FindProcessesImpl(const ProcessInstanceInfoMatch &match_info, + ProcessInstanceInfoList &proc_infos); }; } // namespace lldb_private diff --git a/gnu/llvm/lldb/include/lldb/Host/HostGetOpt.h b/gnu/llvm/lldb/include/lldb/Host/HostGetOpt.h index dedeb2e2fcc..746e03e1bd1 100644 --- a/gnu/llvm/lldb/include/lldb/Host/HostGetOpt.h +++ b/gnu/llvm/lldb/include/lldb/Host/HostGetOpt.h @@ -5,7 +5,9 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -#pragma once + +#ifndef LLDB_HOST_HOSTGETOPT_H +#define LLDB_HOST_HOSTGETOPT_H #if !defined(_MSC_VER) && !defined(__NetBSD__) @@ -21,3 +23,5 @@ #include #endif + +#endif // LLDB_HOST_HOSTGETOPT_H diff --git a/gnu/llvm/lldb/include/lldb/Host/HostInfo.h b/gnu/llvm/lldb/include/lldb/Host/HostInfo.h index 196127d4076..b7010d69d88 100644 --- a/gnu/llvm/lldb/include/lldb/Host/HostInfo.h +++ b/gnu/llvm/lldb/include/lldb/Host/HostInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_HostInfo_h_ -#define lldb_Host_HostInfo_h_ +#ifndef LLDB_HOST_HOSTINFO_H +#define LLDB_HOST_HOSTINFO_H /// \class HostInfo HostInfo.h "lldb/Host/HostInfo.h" /// A class that provides host computer information. @@ -35,7 +35,7 @@ #if defined(_WIN32) #include "lldb/Host/windows/HostInfoWindows.h" #define HOST_INFO_TYPE HostInfoWindows -#elif defined(__linux__) +#elif defined(__linux__) || defined(__EMSCRIPTEN__) #if defined(__ANDROID__) #include "lldb/Host/android/HostInfoAndroid.h" #define HOST_INFO_TYPE HostInfoAndroid diff --git a/gnu/llvm/lldb/include/lldb/Host/HostInfoBase.h b/gnu/llvm/lldb/include/lldb/Host/HostInfoBase.h index c59050cb34e..70682c9b685 100644 --- a/gnu/llvm/lldb/include/lldb/Host/HostInfoBase.h +++ b/gnu/llvm/lldb/include/lldb/Host/HostInfoBase.h @@ -6,12 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_HostInfoBase_h_ -#define lldb_Host_HostInfoBase_h_ +#ifndef LLDB_HOST_HOSTINFOBASE_H +#define LLDB_HOST_HOSTINFOBASE_H #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/UserIDResolver.h" +#include "lldb/Utility/XcodeSDK.h" #include "lldb/lldb-enumerations.h" #include "llvm/ADT/StringRef.h" @@ -91,6 +92,12 @@ public: static bool ComputePathRelativeToLibrary(FileSpec &file_spec, llvm::StringRef dir); + static FileSpec GetXcodeContentsDirectory() { return {}; } + static FileSpec GetXcodeDeveloperDirectory() { return {}; } + + /// Return the directory containing a specific Xcode SDK. + static llvm::StringRef GetXcodeSDKPath(XcodeSDK sdk) { return {}; } + protected: static bool ComputeSharedLibraryDirectory(FileSpec &file_spec); static bool ComputeSupportExeDirectory(FileSpec &file_spec); diff --git a/gnu/llvm/lldb/include/lldb/Host/HostNativeProcess.h b/gnu/llvm/lldb/include/lldb/Host/HostNativeProcess.h index c86a2aef38f..d1e577dc328 100644 --- a/gnu/llvm/lldb/include/lldb/Host/HostNativeProcess.h +++ b/gnu/llvm/lldb/include/lldb/Host/HostNativeProcess.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_HostNativeProcess_h_ -#define lldb_Host_HostNativeProcess_h_ +#ifndef LLDB_HOST_HOSTNATIVEPROCESS_H +#define LLDB_HOST_HOSTNATIVEPROCESS_H #if defined(_WIN32) #include "lldb/Host/windows/HostProcessWindows.h" diff --git a/gnu/llvm/lldb/include/lldb/Host/HostNativeProcessBase.h b/gnu/llvm/lldb/include/lldb/Host/HostNativeProcessBase.h index aaa517d5321..642c63443c2 100644 --- a/gnu/llvm/lldb/include/lldb/Host/HostNativeProcessBase.h +++ b/gnu/llvm/lldb/include/lldb/Host/HostNativeProcessBase.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_HostNativeProcessBase_h_ -#define lldb_Host_HostNativeProcessBase_h_ +#ifndef LLDB_HOST_HOSTNATIVEPROCESSBASE_H +#define LLDB_HOST_HOSTNATIVEPROCESSBASE_H #include "lldb/Host/HostProcess.h" #include "lldb/Utility/Status.h" @@ -19,7 +19,9 @@ namespace lldb_private { class HostThread; class HostNativeProcessBase { - DISALLOW_COPY_AND_ASSIGN(HostNativeProcessBase); + HostNativeProcessBase(const HostNativeProcessBase &) = delete; + const HostNativeProcessBase & + operator=(const HostNativeProcessBase &) = delete; public: HostNativeProcessBase() : m_process(LLDB_INVALID_PROCESS) {} diff --git a/gnu/llvm/lldb/include/lldb/Host/HostNativeThread.h b/gnu/llvm/lldb/include/lldb/Host/HostNativeThread.h index 8bf65849d88..cef08f0539a 100644 --- a/gnu/llvm/lldb/include/lldb/Host/HostNativeThread.h +++ b/gnu/llvm/lldb/include/lldb/Host/HostNativeThread.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_HostNativeThread_h_ -#define lldb_Host_HostNativeThread_h_ +#ifndef LLDB_HOST_HOSTNATIVETHREAD_H +#define LLDB_HOST_HOSTNATIVETHREAD_H #include "HostNativeThreadForward.h" diff --git a/gnu/llvm/lldb/include/lldb/Host/HostNativeThreadBase.h b/gnu/llvm/lldb/include/lldb/Host/HostNativeThreadBase.h index a196f0bc82c..0dfd363cc8f 100644 --- a/gnu/llvm/lldb/include/lldb/Host/HostNativeThreadBase.h +++ b/gnu/llvm/lldb/include/lldb/Host/HostNativeThreadBase.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_HostNativeThreadBase_h_ -#define lldb_Host_HostNativeThreadBase_h_ +#ifndef LLDB_HOST_HOSTNATIVETHREADBASE_H +#define LLDB_HOST_HOSTNATIVETHREADBASE_H #include "lldb/Utility/Status.h" #include "lldb/lldb-defines.h" @@ -23,7 +23,8 @@ namespace lldb_private { class HostNativeThreadBase { friend class ThreadLauncher; - DISALLOW_COPY_AND_ASSIGN(HostNativeThreadBase); + HostNativeThreadBase(const HostNativeThreadBase &) = delete; + const HostNativeThreadBase &operator=(const HostNativeThreadBase &) = delete; public: HostNativeThreadBase(); diff --git a/gnu/llvm/lldb/include/lldb/Host/HostNativeThreadForward.h b/gnu/llvm/lldb/include/lldb/Host/HostNativeThreadForward.h index 261d3c7a836..35b6e2f09e0 100644 --- a/gnu/llvm/lldb/include/lldb/Host/HostNativeThreadForward.h +++ b/gnu/llvm/lldb/include/lldb/Host/HostNativeThreadForward.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_HostNativeThreadForward_h_ -#define lldb_Host_HostNativeThreadForward_h_ +#ifndef LLDB_HOST_HOSTNATIVETHREADFORWARD_H +#define LLDB_HOST_HOSTNATIVETHREADFORWARD_H namespace lldb_private { #if defined(_WIN32) diff --git a/gnu/llvm/lldb/include/lldb/Host/HostProcess.h b/gnu/llvm/lldb/include/lldb/Host/HostProcess.h index fcea52a284d..0b7c3036422 100644 --- a/gnu/llvm/lldb/include/lldb/Host/HostProcess.h +++ b/gnu/llvm/lldb/include/lldb/Host/HostProcess.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_HostProcess_h_ -#define lldb_Host_HostProcess_h_ +#ifndef LLDB_HOST_HOSTPROCESS_H +#define LLDB_HOST_HOSTPROCESS_H #include "lldb/Host/Host.h" #include "lldb/lldb-types.h" diff --git a/gnu/llvm/lldb/include/lldb/Host/HostThread.h b/gnu/llvm/lldb/include/lldb/Host/HostThread.h index 7bf2a1dc2db..d3477e115e2 100644 --- a/gnu/llvm/lldb/include/lldb/Host/HostThread.h +++ b/gnu/llvm/lldb/include/lldb/Host/HostThread.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_HostThread_h_ -#define lldb_Host_HostThread_h_ +#ifndef LLDB_HOST_HOSTTHREAD_H +#define LLDB_HOST_HOSTTHREAD_H #include "lldb/Host/HostNativeThreadForward.h" #include "lldb/Utility/Status.h" diff --git a/gnu/llvm/lldb/include/lldb/Host/LZMA.h b/gnu/llvm/lldb/include/lldb/Host/LZMA.h index c741cc3bbde..5314dab53e4 100644 --- a/gnu/llvm/lldb/include/lldb/Host/LZMA.h +++ b/gnu/llvm/lldb/include/lldb/Host/LZMA.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Host_LZMA_h_ -#define liblldb_Host_LZMA_h_ +#ifndef LLDB_HOST_LZMA_H +#define LLDB_HOST_LZMA_H #include "llvm/ADT/ArrayRef.h" @@ -31,4 +31,4 @@ llvm::Error uncompress(llvm::ArrayRef InputBuffer, } // End of namespace lldb_private -#endif // liblldb_Host_LZMA_h_ +#endif // LLDB_HOST_LZMA_H diff --git a/gnu/llvm/lldb/include/lldb/Host/LockFile.h b/gnu/llvm/lldb/include/lldb/Host/LockFile.h index 2a1cd3dbb8f..ff09eb475f7 100644 --- a/gnu/llvm/lldb/include/lldb/Host/LockFile.h +++ b/gnu/llvm/lldb/include/lldb/Host/LockFile.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Host_LockFile_h_ -#define liblldb_Host_LockFile_h_ +#ifndef LLDB_HOST_LOCKFILE_H +#define LLDB_HOST_LOCKFILE_H #if defined(_WIN32) #include "lldb/Host/windows/LockFileWindows.h" @@ -21,4 +21,4 @@ typedef LockFilePosix LockFile; } #endif -#endif // liblldb_Host_LockFile_h_ +#endif // LLDB_HOST_LOCKFILE_H diff --git a/gnu/llvm/lldb/include/lldb/Host/LockFileBase.h b/gnu/llvm/lldb/include/lldb/Host/LockFileBase.h index be9e258c5c2..6a5fd424869 100644 --- a/gnu/llvm/lldb/include/lldb/Host/LockFileBase.h +++ b/gnu/llvm/lldb/include/lldb/Host/LockFileBase.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Host_LockFileBase_h_ -#define liblldb_Host_LockFileBase_h_ +#ifndef LLDB_HOST_LOCKFILEBASE_H +#define LLDB_HOST_LOCKFILEBASE_H #include "lldb/Utility/Status.h" diff --git a/gnu/llvm/lldb/include/lldb/Host/MainLoop.h b/gnu/llvm/lldb/include/lldb/Host/MainLoop.h index d59aa28ccb0..9ca5040b60a 100644 --- a/gnu/llvm/lldb/include/lldb/Host/MainLoop.h +++ b/gnu/llvm/lldb/include/lldb/Host/MainLoop.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_MainLoop_h_ -#define lldb_Host_MainLoop_h_ +#ifndef LLDB_HOST_MAINLOOP_H +#define LLDB_HOST_MAINLOOP_H #include "lldb/Host/Config.h" #include "lldb/Host/MainLoopBase.h" @@ -86,7 +86,8 @@ private: int m_signo; friend class MainLoop; - DISALLOW_COPY_AND_ASSIGN(SignalHandle); + SignalHandle(const SignalHandle &) = delete; + const SignalHandle &operator=(const SignalHandle &) = delete; }; struct SignalInfo { @@ -108,4 +109,4 @@ private: } // namespace lldb_private -#endif // lldb_Host_MainLoop_h_ +#endif // LLDB_HOST_MAINLOOP_H diff --git a/gnu/llvm/lldb/include/lldb/Host/MainLoopBase.h b/gnu/llvm/lldb/include/lldb/Host/MainLoopBase.h index 3fee2b2c09d..fa8cc77a94b 100644 --- a/gnu/llvm/lldb/include/lldb/Host/MainLoopBase.h +++ b/gnu/llvm/lldb/include/lldb/Host/MainLoopBase.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_posix_MainLoopBase_h_ -#define lldb_Host_posix_MainLoopBase_h_ +#ifndef LLDB_HOST_MAINLOOPBASE_H +#define LLDB_HOST_MAINLOOPBASE_H #include "lldb/Utility/IOObject.h" #include "lldb/Utility/Status.h" @@ -75,13 +75,14 @@ private: IOObject::WaitableHandle m_handle; friend class MainLoopBase; - DISALLOW_COPY_AND_ASSIGN(ReadHandle); + ReadHandle(const ReadHandle &) = delete; + const ReadHandle &operator=(const ReadHandle &) = delete; }; -private: - DISALLOW_COPY_AND_ASSIGN(MainLoopBase); + MainLoopBase(const MainLoopBase &) = delete; + const MainLoopBase &operator=(const MainLoopBase &) = delete; }; } // namespace lldb_private -#endif // lldb_Host_posix_MainLoopBase_h_ +#endif // LLDB_HOST_MAINLOOPBASE_H diff --git a/gnu/llvm/lldb/include/lldb/Host/MonitoringProcessLauncher.h b/gnu/llvm/lldb/include/lldb/Host/MonitoringProcessLauncher.h index 59111a04fc9..e2fce42a228 100644 --- a/gnu/llvm/lldb/include/lldb/Host/MonitoringProcessLauncher.h +++ b/gnu/llvm/lldb/include/lldb/Host/MonitoringProcessLauncher.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_MonitoringProcessLauncher_h_ -#define lldb_Host_MonitoringProcessLauncher_h_ +#ifndef LLDB_HOST_MONITORINGPROCESSLAUNCHER_H +#define LLDB_HOST_MONITORINGPROCESSLAUNCHER_H #include #include "lldb/Host/ProcessLauncher.h" @@ -31,4 +31,4 @@ private: } // namespace lldb_private -#endif // lldb_Host_MonitoringProcessLauncher_h_ +#endif // LLDB_HOST_MONITORINGPROCESSLAUNCHER_H diff --git a/gnu/llvm/lldb/include/lldb/Host/OptionParser.h b/gnu/llvm/lldb/include/lldb/Host/OptionParser.h index b03eeb74ec4..7c84c115ee0 100644 --- a/gnu/llvm/lldb/include/lldb/Host/OptionParser.h +++ b/gnu/llvm/lldb/include/lldb/Host/OptionParser.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionParser_h_ -#define liblldb_OptionParser_h_ +#ifndef LLDB_HOST_OPTIONPARSER_H +#define LLDB_HOST_OPTIONPARSER_H #include #include @@ -51,4 +51,4 @@ public: }; } -#endif // liblldb_OptionParser_h_ +#endif // LLDB_HOST_OPTIONPARSER_H diff --git a/gnu/llvm/lldb/include/lldb/Host/Pipe.h b/gnu/llvm/lldb/include/lldb/Host/Pipe.h index ea75342e542..06daf1f6dd9 100644 --- a/gnu/llvm/lldb/include/lldb/Host/Pipe.h +++ b/gnu/llvm/lldb/include/lldb/Host/Pipe.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Host_Pipe_h_ -#define liblldb_Host_Pipe_h_ +#ifndef LLDB_HOST_PIPE_H +#define LLDB_HOST_PIPE_H #if defined(_WIN32) #include "lldb/Host/windows/PipeWindows.h" @@ -21,4 +21,4 @@ typedef PipePosix Pipe; } #endif -#endif // liblldb_Host_Pipe_h_ +#endif // LLDB_HOST_PIPE_H diff --git a/gnu/llvm/lldb/include/lldb/Host/PipeBase.h b/gnu/llvm/lldb/include/lldb/Host/PipeBase.h index 1aa4db339b2..48c19b899ce 100644 --- a/gnu/llvm/lldb/include/lldb/Host/PipeBase.h +++ b/gnu/llvm/lldb/include/lldb/Host/PipeBase.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Host_PipeBase_h_ -#define liblldb_Host_PipeBase_h_ +#ifndef LLDB_HOST_PIPEBASE_H +#define LLDB_HOST_PIPEBASE_H #include #include diff --git a/gnu/llvm/lldb/include/lldb/Host/PosixApi.h b/gnu/llvm/lldb/include/lldb/Host/PosixApi.h index 04ca3a84983..4cbbd628157 100644 --- a/gnu/llvm/lldb/include/lldb/Host/PosixApi.h +++ b/gnu/llvm/lldb/include/lldb/Host/PosixApi.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Host_PosixApi_h -#define liblldb_Host_PosixApi_h +#ifndef LLDB_HOST_POSIXAPI_H +#define LLDB_HOST_POSIXAPI_H // This file defines platform specific functions, macros, and types necessary // to provide a minimum level of compatibility across all platforms to rely on diff --git a/gnu/llvm/lldb/include/lldb/Host/ProcessLaunchInfo.h b/gnu/llvm/lldb/include/lldb/Host/ProcessLaunchInfo.h index d068aa636bc..e83d8396e9f 100644 --- a/gnu/llvm/lldb/include/lldb/Host/ProcessLaunchInfo.h +++ b/gnu/llvm/lldb/include/lldb/Host/ProcessLaunchInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ProcessLaunch_Info_h -#define liblldb_ProcessLaunch_Info_h +#ifndef LLDB_HOST_PROCESSLAUNCHINFO_H +#define LLDB_HOST_PROCESSLAUNCHINFO_H // C++ Headers #include @@ -165,4 +165,4 @@ protected: }; } -#endif // liblldb_ProcessLaunch_Info_h +#endif // LLDB_HOST_PROCESSLAUNCHINFO_H diff --git a/gnu/llvm/lldb/include/lldb/Host/ProcessLauncher.h b/gnu/llvm/lldb/include/lldb/Host/ProcessLauncher.h index a5b6a6c76bb..9467b2c009b 100644 --- a/gnu/llvm/lldb/include/lldb/Host/ProcessLauncher.h +++ b/gnu/llvm/lldb/include/lldb/Host/ProcessLauncher.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_ProcessLauncher_h_ -#define lldb_Host_ProcessLauncher_h_ +#ifndef LLDB_HOST_PROCESSLAUNCHER_H +#define LLDB_HOST_PROCESSLAUNCHER_H namespace lldb_private { diff --git a/gnu/llvm/lldb/include/lldb/Host/ProcessRunLock.h b/gnu/llvm/lldb/include/lldb/Host/ProcessRunLock.h index 4927fbbf782..43463d144de 100644 --- a/gnu/llvm/lldb/include/lldb/Host/ProcessRunLock.h +++ b/gnu/llvm/lldb/include/lldb/Host/ProcessRunLock.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ProcessRunLock_h_ -#define liblldb_ProcessRunLock_h_ +#ifndef LLDB_HOST_PROCESSRUNLOCK_H +#define LLDB_HOST_PROCESSRUNLOCK_H #include #include @@ -67,7 +67,8 @@ public: ProcessRunLock *m_lock; private: - DISALLOW_COPY_AND_ASSIGN(ProcessRunLocker); + ProcessRunLocker(const ProcessRunLocker &) = delete; + const ProcessRunLocker &operator=(const ProcessRunLocker &) = delete; }; protected: @@ -75,9 +76,10 @@ protected: bool m_running; private: - DISALLOW_COPY_AND_ASSIGN(ProcessRunLock); + ProcessRunLock(const ProcessRunLock &) = delete; + const ProcessRunLock &operator=(const ProcessRunLock &) = delete; }; } // namespace lldb_private -#endif // liblldb_ProcessRunLock_h_ +#endif // LLDB_HOST_PROCESSRUNLOCK_H diff --git a/gnu/llvm/lldb/include/lldb/Host/PseudoTerminal.h b/gnu/llvm/lldb/include/lldb/Host/PseudoTerminal.h index 18679b6fcdd..8a5a233e774 100644 --- a/gnu/llvm/lldb/include/lldb/Host/PseudoTerminal.h +++ b/gnu/llvm/lldb/include/lldb/Host/PseudoTerminal.h @@ -29,36 +29,37 @@ public: /// Default constructor /// - /// Constructs this object with invalid master and slave file descriptors. + /// Constructs this object with invalid primary and secondary file + /// descriptors. PseudoTerminal(); /// Destructor /// - /// The destructor will close the master and slave file descriptors if they - /// are valid and ownership has not been released using one of: @li - /// PseudoTerminal::ReleaseMasterFileDescriptor() @li + /// The destructor will close the primary and secondary file descriptors if + /// they are valid and ownership has not been released using one of: @li + /// PseudoTerminal::ReleasePrimaryFileDescriptor() @li /// PseudoTerminal::ReleaseSaveFileDescriptor() ~PseudoTerminal(); - /// Close the master file descriptor if it is valid. - void CloseMasterFileDescriptor(); + /// Close the primary file descriptor if it is valid. + void ClosePrimaryFileDescriptor(); - /// Close the slave file descriptor if it is valid. - void CloseSlaveFileDescriptor(); + /// Close the secondary file descriptor if it is valid. + void CloseSecondaryFileDescriptor(); /// Fork a child process that uses pseudo terminals for its stdio. /// /// In the parent process, a call to this function results in a pid being - /// returned. If the pid is valid, the master file descriptor can be used + /// returned. If the pid is valid, the primary file descriptor can be used /// for read/write access to stdio of the child process. /// /// In the child process the stdin/stdout/stderr will already be routed to - /// the slave pseudo terminal and the master file descriptor will be closed - /// as it is no longer needed by the child process. + /// the secondary pseudo terminal and the primary file descriptor will be + /// closed as it is no longer needed by the child process. /// - /// This class will close the file descriptors for the master/slave when the - /// destructor is called. The file handles can be released using either: @li - /// PseudoTerminal::ReleaseMasterFileDescriptor() @li + /// This class will close the file descriptors for the primary/secondary when + /// the destructor is called. The file handles can be released using either: + /// @li PseudoTerminal::ReleasePrimaryFileDescriptor() @li /// PseudoTerminal::ReleaseSaveFileDescriptor() /// /// \param[out] error_str @@ -71,37 +72,37 @@ public: /// \b Child process: zero. lldb::pid_t Fork(char *error_str, size_t error_len); - /// The master file descriptor accessor. + /// The primary file descriptor accessor. /// - /// This object retains ownership of the master file descriptor when this + /// This object retains ownership of the primary file descriptor when this /// accessor is used. Users can call the member function - /// PseudoTerminal::ReleaseMasterFileDescriptor() if this object should - /// release ownership of the slave file descriptor. + /// PseudoTerminal::ReleasePrimaryFileDescriptor() if this object should + /// release ownership of the secondary file descriptor. /// /// \return - /// The master file descriptor, or PseudoTerminal::invalid_fd - /// if the master file descriptor is not currently valid. + /// The primary file descriptor, or PseudoTerminal::invalid_fd + /// if the primary file descriptor is not currently valid. /// - /// \see PseudoTerminal::ReleaseMasterFileDescriptor() - int GetMasterFileDescriptor() const; + /// \see PseudoTerminal::ReleasePrimaryFileDescriptor() + int GetPrimaryFileDescriptor() const; - /// The slave file descriptor accessor. + /// The secondary file descriptor accessor. /// - /// This object retains ownership of the slave file descriptor when this + /// This object retains ownership of the secondary file descriptor when this /// accessor is used. Users can call the member function - /// PseudoTerminal::ReleaseSlaveFileDescriptor() if this object should - /// release ownership of the slave file descriptor. + /// PseudoTerminal::ReleaseSecondaryFileDescriptor() if this object should + /// release ownership of the secondary file descriptor. /// /// \return - /// The slave file descriptor, or PseudoTerminal::invalid_fd - /// if the slave file descriptor is not currently valid. + /// The secondary file descriptor, or PseudoTerminal::invalid_fd + /// if the secondary file descriptor is not currently valid. /// - /// \see PseudoTerminal::ReleaseSlaveFileDescriptor() - int GetSlaveFileDescriptor() const; + /// \see PseudoTerminal::ReleaseSecondaryFileDescriptor() + int GetSecondaryFileDescriptor() const; - /// Get the name of the slave pseudo terminal. + /// Get the name of the secondary pseudo terminal. /// - /// A master pseudo terminal should already be valid prior to + /// A primary pseudo terminal should already be valid prior to /// calling this function. /// /// \param[out] error_str @@ -109,27 +110,27 @@ public: /// occur. This can be NULL if no error status is desired. /// /// \return - /// The name of the slave pseudo terminal as a NULL terminated + /// The name of the secondary pseudo terminal as a NULL terminated /// C. This string that comes from static memory, so a copy of /// the string should be made as subsequent calls can change /// this value. NULL is returned if this object doesn't have - /// a valid master pseudo terminal opened or if the call to + /// a valid primary pseudo terminal opened or if the call to /// \c ptsname() fails. /// - /// \see PseudoTerminal::OpenFirstAvailableMaster() - const char *GetSlaveName(char *error_str, size_t error_len) const; + /// \see PseudoTerminal::OpenFirstAvailablePrimary() + const char *GetSecondaryName(char *error_str, size_t error_len) const; /// Open the first available pseudo terminal. /// /// Opens the first available pseudo terminal with \a oflag as the - /// permissions. The opened master file descriptor is stored in this object + /// permissions. The opened primary file descriptor is stored in this object /// and can be accessed by calling the - /// PseudoTerminal::GetMasterFileDescriptor() accessor. Clients can call the - /// PseudoTerminal::ReleaseMasterFileDescriptor() accessor function if they - /// wish to use the master file descriptor beyond the lifespan of this + /// PseudoTerminal::GetPrimaryFileDescriptor() accessor. Clients can call the + /// PseudoTerminal::ReleasePrimaryFileDescriptor() accessor function if they + /// wish to use the primary file descriptor beyond the lifespan of this /// object. /// - /// If this object still has a valid master file descriptor when its + /// If this object still has a valid primary file descriptor when its /// destructor is called, it will close it. /// /// \param[in] oflag @@ -141,25 +142,25 @@ public: /// occur. This can be NULL if no error status is desired. /// /// \return - /// \b true when the master files descriptor is + /// \b true when the primary files descriptor is /// successfully opened. /// \b false if anything goes wrong. /// - /// \see PseudoTerminal::GetMasterFileDescriptor() @see - /// PseudoTerminal::ReleaseMasterFileDescriptor() - bool OpenFirstAvailableMaster(int oflag, char *error_str, size_t error_len); + /// \see PseudoTerminal::GetPrimaryFileDescriptor() @see + /// PseudoTerminal::ReleasePrimaryFileDescriptor() + bool OpenFirstAvailablePrimary(int oflag, char *error_str, size_t error_len); - /// Open the slave for the current master pseudo terminal. + /// Open the secondary for the current primary pseudo terminal. /// - /// A master pseudo terminal should already be valid prior to - /// calling this function. The opened slave file descriptor is stored in + /// A primary pseudo terminal should already be valid prior to + /// calling this function. The opened secondary file descriptor is stored in /// this object and can be accessed by calling the - /// PseudoTerminal::GetSlaveFileDescriptor() accessor. Clients can call the - /// PseudoTerminal::ReleaseSlaveFileDescriptor() accessor function if they - /// wish to use the slave file descriptor beyond the lifespan of this + /// PseudoTerminal::GetSecondaryFileDescriptor() accessor. Clients can call + /// the PseudoTerminal::ReleaseSecondaryFileDescriptor() accessor function if + /// they wish to use the secondary file descriptor beyond the lifespan of this /// object. /// - /// If this object still has a valid slave file descriptor when its + /// If this object still has a valid secondary file descriptor when its /// destructor is called, it will close it. /// /// \param[in] oflag @@ -170,48 +171,49 @@ public: /// occur. This can be NULL if no error status is desired. /// /// \return - /// \b true when the master files descriptor is + /// \b true when the primary files descriptor is /// successfully opened. /// \b false if anything goes wrong. /// - /// \see PseudoTerminal::OpenFirstAvailableMaster() @see - /// PseudoTerminal::GetSlaveFileDescriptor() @see - /// PseudoTerminal::ReleaseSlaveFileDescriptor() - bool OpenSlave(int oflag, char *error_str, size_t error_len); + /// \see PseudoTerminal::OpenFirstAvailablePrimary() @see + /// PseudoTerminal::GetSecondaryFileDescriptor() @see + /// PseudoTerminal::ReleaseSecondaryFileDescriptor() + bool OpenSecondary(int oflag, char *error_str, size_t error_len); - /// Release the master file descriptor. + /// Release the primary file descriptor. /// - /// Releases ownership of the master pseudo terminal file descriptor without - /// closing it. The destructor for this class will close the master file + /// Releases ownership of the primary pseudo terminal file descriptor without + /// closing it. The destructor for this class will close the primary file /// descriptor if the ownership isn't released using this call and the - /// master file descriptor has been opened. + /// primary file descriptor has been opened. /// /// \return - /// The master file descriptor, or PseudoTerminal::invalid_fd + /// The primary file descriptor, or PseudoTerminal::invalid_fd /// if the mast file descriptor is not currently valid. - int ReleaseMasterFileDescriptor(); + int ReleasePrimaryFileDescriptor(); - /// Release the slave file descriptor. + /// Release the secondary file descriptor. /// - /// Release ownership of the slave pseudo terminal file descriptor without - /// closing it. The destructor for this class will close the slave file - /// descriptor if the ownership isn't released using this call and the slave - /// file descriptor has been opened. + /// Release ownership of the secondary pseudo terminal file descriptor without + /// closing it. The destructor for this class will close the secondary file + /// descriptor if the ownership isn't released using this call and the + /// secondary file descriptor has been opened. /// /// \return - /// The slave file descriptor, or PseudoTerminal::invalid_fd - /// if the slave file descriptor is not currently valid. - int ReleaseSlaveFileDescriptor(); + /// The secondary file descriptor, or PseudoTerminal::invalid_fd + /// if the secondary file descriptor is not currently valid. + int ReleaseSecondaryFileDescriptor(); protected: // Member variables - int m_master_fd; ///< The file descriptor for the master. - int m_slave_fd; ///< The file descriptor for the slave. + int m_primary_fd; ///< The file descriptor for the primary. + int m_secondary_fd; ///< The file descriptor for the secondary. private: - DISALLOW_COPY_AND_ASSIGN(PseudoTerminal); + PseudoTerminal(const PseudoTerminal &) = delete; + const PseudoTerminal &operator=(const PseudoTerminal &) = delete; }; } // namespace lldb_private -#endif // #ifndef liblldb_PseudoTerminal_h_ +#endif // LLDB_HOST_PSEUDOTERMINAL_H diff --git a/gnu/llvm/lldb/include/lldb/Host/SafeMachO.h b/gnu/llvm/lldb/include/lldb/Host/SafeMachO.h index ec9887ececd..d7c376d23a4 100644 --- a/gnu/llvm/lldb/include/lldb/Host/SafeMachO.h +++ b/gnu/llvm/lldb/include/lldb/Host/SafeMachO.h @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -#ifndef liblldb_SafeMachO_h_ -#define liblldb_SafeMachO_h_ +#ifndef LLDB_HOST_SAFEMACHO_H +#define LLDB_HOST_SAFEMACHO_H // This header file is required to work around collisions between the defines // in mach/machine.h, and enum members of the same name in llvm's MachO.h. If @@ -112,4 +112,4 @@ #include "llvm/BinaryFormat/MachO.h" -#endif // liblldb_SafeMachO_h_ +#endif // LLDB_HOST_SAFEMACHO_H diff --git a/gnu/llvm/lldb/include/lldb/Host/Socket.h b/gnu/llvm/lldb/include/lldb/Host/Socket.h index c6df5634e24..36db0ec63e9 100644 --- a/gnu/llvm/lldb/include/lldb/Host/Socket.h +++ b/gnu/llvm/lldb/include/lldb/Host/Socket.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Host_Socket_h_ -#define liblldb_Host_Socket_h_ +#ifndef LLDB_HOST_SOCKET_H +#define LLDB_HOST_SOCKET_H #include #include @@ -36,6 +36,8 @@ typedef SOCKET NativeSocket; #else typedef int NativeSocket; #endif +class TCPSocket; +class UDPSocket; class Socket : public IOObject { public: @@ -64,13 +66,16 @@ public: // Initialize a Tcp Socket object in listening mode. listen and accept are // implemented separately because the caller may wish to manipulate or query // the socket after it is initialized, but before entering a blocking accept. - static Status TcpListen(llvm::StringRef host_and_port, - bool child_processes_inherit, Socket *&socket, - Predicate *predicate, int backlog = 5); - static Status TcpConnect(llvm::StringRef host_and_port, - bool child_processes_inherit, Socket *&socket); - static Status UdpConnect(llvm::StringRef host_and_port, - bool child_processes_inherit, Socket *&socket); + static llvm::Expected> + TcpListen(llvm::StringRef host_and_port, bool child_processes_inherit, + Predicate *predicate, int backlog = 5); + + static llvm::Expected> + TcpConnect(llvm::StringRef host_and_port, bool child_processes_inherit); + + static llvm::Expected> + UdpConnect(llvm::StringRef host_and_port, bool child_processes_inherit); + static Status UnixDomainConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket); @@ -127,4 +132,4 @@ protected: } // namespace lldb_private -#endif // liblldb_Host_Socket_h_ +#endif // LLDB_HOST_SOCKET_H diff --git a/gnu/llvm/lldb/include/lldb/Host/SocketAddress.h b/gnu/llvm/lldb/include/lldb/Host/SocketAddress.h index 766303a3c1f..862e1104a08 100644 --- a/gnu/llvm/lldb/include/lldb/Host/SocketAddress.h +++ b/gnu/llvm/lldb/include/lldb/Host/SocketAddress.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SocketAddress_h_ -#define liblldb_SocketAddress_h_ +#ifndef LLDB_HOST_SOCKETADDRESS_H +#define LLDB_HOST_SOCKETADDRESS_H #include @@ -185,4 +185,4 @@ protected: } // namespace lldb_private -#endif // liblldb_SocketAddress_h_ +#endif // LLDB_HOST_SOCKETADDRESS_H diff --git a/gnu/llvm/lldb/include/lldb/Host/StringConvert.h b/gnu/llvm/lldb/include/lldb/Host/StringConvert.h index 4b2c6901a96..ad629ff3042 100644 --- a/gnu/llvm/lldb/include/lldb/Host/StringConvert.h +++ b/gnu/llvm/lldb/include/lldb/Host/StringConvert.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StringConvert_h_ -#define liblldb_StringConvert_h_ +#ifndef LLDB_HOST_STRINGCONVERT_H +#define LLDB_HOST_STRINGCONVERT_H #include diff --git a/gnu/llvm/lldb/include/lldb/Host/Terminal.h b/gnu/llvm/lldb/include/lldb/Host/Terminal.h index 671f8d63f89..61993223ea0 100644 --- a/gnu/llvm/lldb/include/lldb/Host/Terminal.h +++ b/gnu/llvm/lldb/include/lldb/Host/Terminal.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Terminal_h_ -#define liblldb_Terminal_h_ +#ifndef LLDB_HOST_TERMINAL_H +#define LLDB_HOST_TERMINAL_H #if defined(__cplusplus) #include "lldb/Host/Config.h" @@ -179,4 +179,4 @@ protected: } // namespace lldb_private #endif // #if defined(__cplusplus) -#endif // #ifndef liblldb_Terminal_h_ +#endif // LLDB_HOST_TERMINAL_H diff --git a/gnu/llvm/lldb/include/lldb/Host/ThreadLauncher.h b/gnu/llvm/lldb/include/lldb/Host/ThreadLauncher.h index e45ffa9df75..00b42fa6a11 100644 --- a/gnu/llvm/lldb/include/lldb/Host/ThreadLauncher.h +++ b/gnu/llvm/lldb/include/lldb/Host/ThreadLauncher.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_ThreadLauncher_h_ -#define lldb_Host_ThreadLauncher_h_ +#ifndef LLDB_HOST_THREADLAUNCHER_H +#define LLDB_HOST_THREADLAUNCHER_H #include "lldb/Host/HostThread.h" #include "lldb/lldb-types.h" diff --git a/gnu/llvm/lldb/include/lldb/Host/Time.h b/gnu/llvm/lldb/include/lldb/Host/Time.h index b27eb082167..83b76ec0f9d 100644 --- a/gnu/llvm/lldb/include/lldb/Host/Time.h +++ b/gnu/llvm/lldb/include/lldb/Host/Time.h @@ -8,8 +8,8 @@ // Include system time headers, adding missing functions as necessary -#ifndef liblldb_Host_Time_h_ -#define liblldb_Host_Time_h_ +#ifndef LLDB_HOST_TIME_H +#define LLDB_HOST_TIME_H #ifdef __ANDROID__ #include @@ -22,4 +22,4 @@ extern time_t timegm(struct tm *t); #include #endif -#endif // liblldb_Host_Time_h_ +#endif // LLDB_HOST_TIME_H diff --git a/gnu/llvm/lldb/include/lldb/Host/XML.h b/gnu/llvm/lldb/include/lldb/Host/XML.h index ca51d304dc8..a80f1e9e4d2 100644 --- a/gnu/llvm/lldb/include/lldb/Host/XML.h +++ b/gnu/llvm/lldb/include/lldb/Host/XML.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_XML_h_ -#define liblldb_XML_h_ +#ifndef LLDB_HOST_XML_H +#define LLDB_HOST_XML_H #include "lldb/Host/Config.h" @@ -179,4 +179,4 @@ protected: } // namespace lldb_private -#endif // liblldb_XML_h_ +#endif // LLDB_HOST_XML_H diff --git a/gnu/llvm/lldb/include/lldb/Host/common/GetOptInc.h b/gnu/llvm/lldb/include/lldb/Host/common/GetOptInc.h index c69f7227a5c..3fb9add4795 100644 --- a/gnu/llvm/lldb/include/lldb/Host/common/GetOptInc.h +++ b/gnu/llvm/lldb/include/lldb/Host/common/GetOptInc.h @@ -1,4 +1,13 @@ -#pragma once +//===-- GetOptInc.h ---------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_HOST_COMMON_GETOPTINC_H +#define LLDB_HOST_COMMON_GETOPTINC_H #include "lldb/lldb-defines.h" @@ -50,3 +59,5 @@ int getopt_long(int argc, char *const *argv, const char *optstring, int getopt_long_only(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *longindex); #endif + +#endif // LLDB_HOST_COMMON_GETOPTINC_H diff --git a/gnu/llvm/lldb/include/lldb/Host/common/NativeBreakpointList.h b/gnu/llvm/lldb/include/lldb/Host/common/NativeBreakpointList.h index c2725b2df95..21d2f096370 100644 --- a/gnu/llvm/lldb/include/lldb/Host/common/NativeBreakpointList.h +++ b/gnu/llvm/lldb/include/lldb/Host/common/NativeBreakpointList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_NativeBreakpointList_h_ -#define liblldb_NativeBreakpointList_h_ +#ifndef LLDB_HOST_COMMON_NATIVEBREAKPOINTLIST_H +#define LLDB_HOST_COMMON_NATIVEBREAKPOINTLIST_H #include "lldb/lldb-private-forward.h" #include "lldb/lldb-types.h" @@ -23,4 +23,4 @@ struct HardwareBreakpoint { using HardwareBreakpointMap = std::map; } -#endif // ifndef liblldb_NativeBreakpointList_h_ +#endif // LLDB_HOST_COMMON_NATIVEBREAKPOINTLIST_H diff --git a/gnu/llvm/lldb/include/lldb/Host/common/NativeProcessProtocol.h b/gnu/llvm/lldb/include/lldb/Host/common/NativeProcessProtocol.h index 2d48717c4fb..2faab6f587c 100644 --- a/gnu/llvm/lldb/include/lldb/Host/common/NativeProcessProtocol.h +++ b/gnu/llvm/lldb/include/lldb/Host/common/NativeProcessProtocol.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_NativeProcessProtocol_h_ -#define liblldb_NativeProcessProtocol_h_ +#ifndef LLDB_HOST_COMMON_NATIVEPROCESSPROTOCOL_H +#define LLDB_HOST_COMMON_NATIVEPROCESSPROTOCOL_H #include "NativeBreakpointList.h" #include "NativeThreadProtocol.h" @@ -379,16 +379,10 @@ public: /// \param[in] traceid /// The user id of the tracing instance. /// - /// \param[in] config - /// The thread id of the tracing instance, in case configuration - /// for a specific thread is needed should be specified in the - /// config. - /// - /// \param[out] error - /// Status indicates what went wrong. - /// /// \param[out] config - /// The actual configuration being used for tracing. + /// The configuration being used for tracing. + /// + /// \return A status indicating what went wrong. virtual Status GetTraceConfig(lldb::user_id_t traceid, TraceOptions &config) { return Status("Not implemented"); } @@ -475,4 +469,4 @@ private: }; } // namespace lldb_private -#endif // #ifndef liblldb_NativeProcessProtocol_h_ +#endif // LLDB_HOST_COMMON_NATIVEPROCESSPROTOCOL_H diff --git a/gnu/llvm/lldb/include/lldb/Host/common/NativeRegisterContext.h b/gnu/llvm/lldb/include/lldb/Host/common/NativeRegisterContext.h index 6bba8f2a5d2..3b54d4ae1e0 100644 --- a/gnu/llvm/lldb/include/lldb/Host/common/NativeRegisterContext.h +++ b/gnu/llvm/lldb/include/lldb/Host/common/NativeRegisterContext.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_NativeRegisterContext_h_ -#define liblldb_NativeRegisterContext_h_ +#ifndef LLDB_HOST_COMMON_NATIVEREGISTERCONTEXT_H +#define LLDB_HOST_COMMON_NATIVEREGISTERCONTEXT_H #include "lldb/Host/common/NativeWatchpointList.h" #include "lldb/lldb-private.h" @@ -170,9 +170,11 @@ protected: private: // For RegisterContext only - DISALLOW_COPY_AND_ASSIGN(NativeRegisterContext); + NativeRegisterContext(const NativeRegisterContext &) = delete; + const NativeRegisterContext & + operator=(const NativeRegisterContext &) = delete; }; } // namespace lldb_private -#endif // liblldb_NativeRegisterContext_h_ +#endif // LLDB_HOST_COMMON_NATIVEREGISTERCONTEXT_H diff --git a/gnu/llvm/lldb/include/lldb/Host/common/NativeThreadProtocol.h b/gnu/llvm/lldb/include/lldb/Host/common/NativeThreadProtocol.h index 36ae67933f5..8d4c03549bb 100644 --- a/gnu/llvm/lldb/include/lldb/Host/common/NativeThreadProtocol.h +++ b/gnu/llvm/lldb/include/lldb/Host/common/NativeThreadProtocol.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_NativeThreadProtocol_h_ -#define liblldb_NativeThreadProtocol_h_ +#ifndef LLDB_HOST_COMMON_NATIVETHREADPROTOCOL_H +#define LLDB_HOST_COMMON_NATIVETHREADPROTOCOL_H #include @@ -53,4 +53,4 @@ protected: }; } -#endif // #ifndef liblldb_NativeThreadProtocol_h_ +#endif // LLDB_HOST_COMMON_NATIVETHREADPROTOCOL_H diff --git a/gnu/llvm/lldb/include/lldb/Host/common/NativeWatchpointList.h b/gnu/llvm/lldb/include/lldb/Host/common/NativeWatchpointList.h index c83ba1eaadc..66f93bf1c8f 100644 --- a/gnu/llvm/lldb/include/lldb/Host/common/NativeWatchpointList.h +++ b/gnu/llvm/lldb/include/lldb/Host/common/NativeWatchpointList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_NativeWatchpointList_h_ -#define liblldb_NativeWatchpointList_h_ +#ifndef LLDB_HOST_COMMON_NATIVEWATCHPOINTLIST_H +#define LLDB_HOST_COMMON_NATIVEWATCHPOINTLIST_H #include "lldb/Utility/Status.h" #include "lldb/lldb-private-forward.h" @@ -38,4 +38,4 @@ private: }; } -#endif // ifndef liblldb_NativeWatchpointList_h_ +#endif // LLDB_HOST_COMMON_NATIVEWATCHPOINTLIST_H diff --git a/gnu/llvm/lldb/include/lldb/Host/common/TCPSocket.h b/gnu/llvm/lldb/include/lldb/Host/common/TCPSocket.h index faf3bb693c3..b782c9e6096 100644 --- a/gnu/llvm/lldb/include/lldb/Host/common/TCPSocket.h +++ b/gnu/llvm/lldb/include/lldb/Host/common/TCPSocket.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_TCPSocket_h_ -#define liblldb_TCPSocket_h_ +#ifndef LLDB_HOST_COMMON_TCPSOCKET_H +#define LLDB_HOST_COMMON_TCPSOCKET_H #include "lldb/Host/Socket.h" #include "lldb/Host/SocketAddress.h" @@ -57,4 +57,4 @@ private: }; } -#endif // ifndef liblldb_TCPSocket_h_ +#endif // LLDB_HOST_COMMON_TCPSOCKET_H diff --git a/gnu/llvm/lldb/include/lldb/Host/common/UDPSocket.h b/gnu/llvm/lldb/include/lldb/Host/common/UDPSocket.h index b7b6db67d10..bae707e345d 100644 --- a/gnu/llvm/lldb/include/lldb/Host/common/UDPSocket.h +++ b/gnu/llvm/lldb/include/lldb/Host/common/UDPSocket.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_UDPSocket_h_ -#define liblldb_UDPSocket_h_ +#ifndef LLDB_HOST_COMMON_UDPSOCKET_H +#define LLDB_HOST_COMMON_UDPSOCKET_H #include "lldb/Host/Socket.h" @@ -16,8 +16,8 @@ class UDPSocket : public Socket { public: UDPSocket(bool should_close, bool child_processes_inherit); - static Status Connect(llvm::StringRef name, bool child_processes_inherit, - Socket *&socket); + static llvm::Expected> + Connect(llvm::StringRef name, bool child_processes_inherit); std::string GetRemoteConnectionURI() const override; @@ -33,4 +33,4 @@ private: }; } -#endif // ifndef liblldb_UDPSocket_h_ +#endif // LLDB_HOST_COMMON_UDPSOCKET_H diff --git a/gnu/llvm/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h b/gnu/llvm/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h index 217ca5bf1fc..3941414f8ab 100644 --- a/gnu/llvm/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h +++ b/gnu/llvm/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h @@ -6,11 +6,12 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_macosx_HostInfoMacOSX_h_ -#define lldb_Host_macosx_HostInfoMacOSX_h_ +#ifndef LLDB_HOST_MACOSX_HOSTINFOMACOSX_H +#define LLDB_HOST_MACOSX_HOSTINFOMACOSX_H #include "lldb/Host/posix/HostInfoPosix.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/XcodeSDK.h" #include "llvm/Support/VersionTuple.h" namespace lldb_private { @@ -31,7 +32,11 @@ public: static bool GetOSBuildString(std::string &s); static bool GetOSKernelDescription(std::string &s); static FileSpec GetProgramFileSpec(); + static FileSpec GetXcodeContentsDirectory(); + static FileSpec GetXcodeDeveloperDirectory(); + /// Query xcrun to find an Xcode SDK directory. + static llvm::StringRef GetXcodeSDKPath(XcodeSDK sdk); protected: static bool ComputeSupportExeDirectory(FileSpec &file_spec); static void ComputeHostArchitectureSupport(ArchSpec &arch_32, diff --git a/gnu/llvm/lldb/include/lldb/Host/macosx/HostThreadMacOSX.h b/gnu/llvm/lldb/include/lldb/Host/macosx/HostThreadMacOSX.h index 4247de6da12..4e41119d97c 100644 --- a/gnu/llvm/lldb/include/lldb/Host/macosx/HostThreadMacOSX.h +++ b/gnu/llvm/lldb/include/lldb/Host/macosx/HostThreadMacOSX.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_macosx_HostThreadMacOSX_h_ -#define lldb_Host_macosx_HostThreadMacOSX_h_ +#ifndef LLDB_HOST_MACOSX_HOSTTHREADMACOSX_H +#define LLDB_HOST_MACOSX_HOSTTHREADMACOSX_H #include "lldb/Host/posix/HostThreadPosix.h" diff --git a/gnu/llvm/lldb/include/lldb/Host/openbsd/HostInfoOpenBSD.h b/gnu/llvm/lldb/include/lldb/Host/openbsd/HostInfoOpenBSD.h index 366157851be..7ec1d5fc360 100644 --- a/gnu/llvm/lldb/include/lldb/Host/openbsd/HostInfoOpenBSD.h +++ b/gnu/llvm/lldb/include/lldb/Host/openbsd/HostInfoOpenBSD.h @@ -16,16 +16,11 @@ namespace lldb_private { class HostInfoOpenBSD : public HostInfoPosix { - friend class HostInfoBase; - public: static llvm::VersionTuple GetOSVersion(); static bool GetOSBuildString(std::string &s); static bool GetOSKernelDescription(std::string &s); static FileSpec GetProgramFileSpec(); - -protected: - static bool ComputeSupportExeDirectory(FileSpec &file_spec); }; } diff --git a/gnu/llvm/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h b/gnu/llvm/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h index b25fc47c56b..3ee8f9d9133 100644 --- a/gnu/llvm/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h +++ b/gnu/llvm/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Host_posix_ConnectionFileDescriptorPosix_h_ -#define liblldb_Host_posix_ConnectionFileDescriptorPosix_h_ +#ifndef LLDB_HOST_POSIX_CONNECTIONFILEDESCRIPTORPOSIX_H +#define LLDB_HOST_POSIX_CONNECTIONFILEDESCRIPTORPOSIX_H #include #include @@ -116,9 +116,11 @@ protected: private: void InitializeSocket(Socket *socket); - DISALLOW_COPY_AND_ASSIGN(ConnectionFileDescriptor); + ConnectionFileDescriptor(const ConnectionFileDescriptor &) = delete; + const ConnectionFileDescriptor & + operator=(const ConnectionFileDescriptor &) = delete; }; } // namespace lldb_private -#endif // liblldb_ConnectionFileDescriptor_h_ +#endif // LLDB_HOST_POSIX_CONNECTIONFILEDESCRIPTORPOSIX_H diff --git a/gnu/llvm/lldb/include/lldb/Host/posix/DomainSocket.h b/gnu/llvm/lldb/include/lldb/Host/posix/DomainSocket.h index e407ce16bbc..35c33811f60 100644 --- a/gnu/llvm/lldb/include/lldb/Host/posix/DomainSocket.h +++ b/gnu/llvm/lldb/include/lldb/Host/posix/DomainSocket.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DomainSocket_h_ -#define liblldb_DomainSocket_h_ +#ifndef LLDB_HOST_POSIX_DOMAINSOCKET_H +#define LLDB_HOST_POSIX_DOMAINSOCKET_H #include "lldb/Host/Socket.h" @@ -34,4 +34,4 @@ private: }; } -#endif // ifndef liblldb_DomainSocket_h_ +#endif // LLDB_HOST_POSIX_DOMAINSOCKET_H diff --git a/gnu/llvm/lldb/include/lldb/Host/posix/HostInfoPosix.h b/gnu/llvm/lldb/include/lldb/Host/posix/HostInfoPosix.h index 26910132f3c..825c79f53ec 100644 --- a/gnu/llvm/lldb/include/lldb/Host/posix/HostInfoPosix.h +++ b/gnu/llvm/lldb/include/lldb/Host/posix/HostInfoPosix.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_posix_HostInfoPosix_h_ -#define lldb_Host_posix_HostInfoPosix_h_ +#ifndef LLDB_HOST_POSIX_HOSTINFOPOSIX_H +#define LLDB_HOST_POSIX_HOSTINFOPOSIX_H #include "lldb/Host/HostInfoBase.h" #include "lldb/Utility/FileSpec.h" diff --git a/gnu/llvm/lldb/include/lldb/Host/posix/HostProcessPosix.h b/gnu/llvm/lldb/include/lldb/Host/posix/HostProcessPosix.h index a313358631b..5def1b77eef 100644 --- a/gnu/llvm/lldb/include/lldb/Host/posix/HostProcessPosix.h +++ b/gnu/llvm/lldb/include/lldb/Host/posix/HostProcessPosix.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_HostProcesPosix_h_ -#define lldb_Host_HostProcesPosix_h_ +#ifndef LLDB_HOST_POSIX_HOSTPROCESSPOSIX_H +#define LLDB_HOST_POSIX_HOSTPROCESSPOSIX_H #include "lldb/Host/HostNativeProcessBase.h" #include "lldb/Utility/Status.h" @@ -39,4 +39,4 @@ public: } // namespace lldb_private -#endif // lldb_Host_HostProcesPosix_h_ +#endif // LLDB_HOST_POSIX_HOSTPROCESSPOSIX_H diff --git a/gnu/llvm/lldb/include/lldb/Host/posix/HostThreadPosix.h b/gnu/llvm/lldb/include/lldb/Host/posix/HostThreadPosix.h index 54012e15ad9..6c8e09fc110 100644 --- a/gnu/llvm/lldb/include/lldb/Host/posix/HostThreadPosix.h +++ b/gnu/llvm/lldb/include/lldb/Host/posix/HostThreadPosix.h @@ -6,15 +6,16 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_posix_HostThreadPosix_h_ -#define lldb_Host_posix_HostThreadPosix_h_ +#ifndef LLDB_HOST_POSIX_HOSTTHREADPOSIX_H +#define LLDB_HOST_POSIX_HOSTTHREADPOSIX_H #include "lldb/Host/HostNativeThreadBase.h" namespace lldb_private { class HostThreadPosix : public HostNativeThreadBase { - DISALLOW_COPY_AND_ASSIGN(HostThreadPosix); + HostThreadPosix(const HostThreadPosix &) = delete; + const HostThreadPosix &operator=(const HostThreadPosix &) = delete; public: HostThreadPosix(); @@ -29,4 +30,4 @@ public: } // namespace lldb_private -#endif // lldb_Host_posix_HostThreadPosix_h_ +#endif // LLDB_HOST_POSIX_HOSTTHREADPOSIX_H diff --git a/gnu/llvm/lldb/include/lldb/Host/posix/LockFilePosix.h b/gnu/llvm/lldb/include/lldb/Host/posix/LockFilePosix.h index 63333bff4cd..870f9a2f525 100644 --- a/gnu/llvm/lldb/include/lldb/Host/posix/LockFilePosix.h +++ b/gnu/llvm/lldb/include/lldb/Host/posix/LockFilePosix.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Host_posix_LockFilePosix_h_ -#define liblldb_Host_posix_LockFilePosix_h_ +#ifndef LLDB_HOST_POSIX_LOCKFILEPOSIX_H +#define LLDB_HOST_POSIX_LOCKFILEPOSIX_H #include "lldb/Host/LockFileBase.h" @@ -32,4 +32,4 @@ protected: } // namespace lldb_private -#endif // liblldb_Host_posix_LockFilePosix_h_ +#endif // LLDB_HOST_POSIX_LOCKFILEPOSIX_H diff --git a/gnu/llvm/lldb/include/lldb/Host/posix/PipePosix.h b/gnu/llvm/lldb/include/lldb/Host/posix/PipePosix.h index df341f2fc89..77c0e2f7ef4 100644 --- a/gnu/llvm/lldb/include/lldb/Host/posix/PipePosix.h +++ b/gnu/llvm/lldb/include/lldb/Host/posix/PipePosix.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Host_posix_PipePosix_h_ -#define liblldb_Host_posix_PipePosix_h_ +#ifndef LLDB_HOST_POSIX_PIPEPOSIX_H +#define LLDB_HOST_POSIX_PIPEPOSIX_H #if defined(__cplusplus) #include "lldb/Host/PipeBase.h" @@ -77,4 +77,4 @@ private: } // namespace lldb_private #endif // #if defined(__cplusplus) -#endif // liblldb_Host_posix_PipePosix_h_ +#endif // LLDB_HOST_POSIX_PIPEPOSIX_H diff --git a/gnu/llvm/lldb/include/lldb/Host/posix/ProcessLauncherPosixFork.h b/gnu/llvm/lldb/include/lldb/Host/posix/ProcessLauncherPosixFork.h index 15e2d6d23b8..427fb5b4f48 100644 --- a/gnu/llvm/lldb/include/lldb/Host/posix/ProcessLauncherPosixFork.h +++ b/gnu/llvm/lldb/include/lldb/Host/posix/ProcessLauncherPosixFork.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Host_posix_ProcessLauncherPosixFork_h_ -#define lldb_Host_posix_ProcessLauncherPosixFork_h_ +#ifndef LLDB_HOST_POSIX_PROCESSLAUNCHERPOSIXFORK_H +#define LLDB_HOST_POSIX_PROCESSLAUNCHERPOSIXFORK_H #include "lldb/Host/ProcessLauncher.h" diff --git a/gnu/llvm/lldb/include/lldb/Host/windows/ConnectionGenericFileWindows.h b/gnu/llvm/lldb/include/lldb/Host/windows/ConnectionGenericFileWindows.h index 8856708df94..d8f06a7162b 100644 --- a/gnu/llvm/lldb/include/lldb/Host/windows/ConnectionGenericFileWindows.h +++ b/gnu/llvm/lldb/include/lldb/Host/windows/ConnectionGenericFileWindows.h @@ -56,7 +56,9 @@ private: std::string m_uri; - DISALLOW_COPY_AND_ASSIGN(ConnectionGenericFile); + ConnectionGenericFile(const ConnectionGenericFile &) = delete; + const ConnectionGenericFile & + operator=(const ConnectionGenericFile &) = delete; }; } diff --git a/gnu/llvm/lldb/include/lldb/Host/windows/HostThreadWindows.h b/gnu/llvm/lldb/include/lldb/Host/windows/HostThreadWindows.h index be3f7fe13d6..63d0d73faad 100644 --- a/gnu/llvm/lldb/include/lldb/Host/windows/HostThreadWindows.h +++ b/gnu/llvm/lldb/include/lldb/Host/windows/HostThreadWindows.h @@ -16,7 +16,8 @@ namespace lldb_private { class HostThreadWindows : public HostNativeThreadBase { - DISALLOW_COPY_AND_ASSIGN(HostThreadWindows); + HostThreadWindows(const HostThreadWindows &) = delete; + const HostThreadWindows &operator=(const HostThreadWindows &) = delete; public: HostThreadWindows(); diff --git a/gnu/llvm/lldb/include/lldb/Initialization/SystemInitializer.h b/gnu/llvm/lldb/include/lldb/Initialization/SystemInitializer.h index e616ad1ee81..4426bfb224e 100644 --- a/gnu/llvm/lldb/include/lldb/Initialization/SystemInitializer.h +++ b/gnu/llvm/lldb/include/lldb/Initialization/SystemInitializer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_INITIALIZATION_SYSTEM_INITIALIZER_H -#define LLDB_INITIALIZATION_SYSTEM_INITIALIZER_H +#ifndef LLDB_INITIALIZATION_SYSTEMINITIALIZER_H +#define LLDB_INITIALIZATION_SYSTEMINITIALIZER_H #include "llvm/Support/Error.h" diff --git a/gnu/llvm/lldb/include/lldb/Initialization/SystemInitializerCommon.h b/gnu/llvm/lldb/include/lldb/Initialization/SystemInitializerCommon.h index ad7e58e50bb..3a508168087 100644 --- a/gnu/llvm/lldb/include/lldb/Initialization/SystemInitializerCommon.h +++ b/gnu/llvm/lldb/include/lldb/Initialization/SystemInitializerCommon.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_INITIALIZATION_SYSTEM_INITIALIZER_COMMON_H -#define LLDB_INITIALIZATION_SYSTEM_INITIALIZER_COMMON_H +#ifndef LLDB_INITIALIZATION_SYSTEMINITIALIZERCOMMON_H +#define LLDB_INITIALIZATION_SYSTEMINITIALIZERCOMMON_H #include "SystemInitializer.h" @@ -31,4 +31,4 @@ public: } // namespace lldb_private -#endif // LLDB_INITIALIZATION_SYSTEM_INITIALIZER_COMMON_H +#endif // LLDB_INITIALIZATION_SYSTEMINITIALIZERCOMMON_H diff --git a/gnu/llvm/lldb/include/lldb/Initialization/SystemLifetimeManager.h b/gnu/llvm/lldb/include/lldb/Initialization/SystemLifetimeManager.h index 2e99b86dbdb..27e1a22b19d 100644 --- a/gnu/llvm/lldb/include/lldb/Initialization/SystemLifetimeManager.h +++ b/gnu/llvm/lldb/include/lldb/Initialization/SystemLifetimeManager.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_INITIALIZATION_SYSTEM_LIFETIME_MANAGER_H -#define LLDB_INITIALIZATION_SYSTEM_LIFETIME_MANAGER_H +#ifndef LLDB_INITIALIZATION_SYSTEMLIFETIMEMANAGER_H +#define LLDB_INITIALIZATION_SYSTEMLIFETIMEMANAGER_H #include "lldb/Initialization/SystemInitializer.h" #include "lldb/lldb-private-types.h" diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/CommandAlias.h b/gnu/llvm/lldb/include/lldb/Interpreter/CommandAlias.h index 1e186d77f8e..26826db6270 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/CommandAlias.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/CommandAlias.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandAlias_h_ -#define liblldb_CommandAlias_h_ +#ifndef LLDB_INTERPRETER_COMMANDALIAS_H +#define LLDB_INTERPRETER_COMMANDALIAS_H #include @@ -81,4 +81,4 @@ private: }; } // namespace lldb_private -#endif // liblldb_CommandAlias_h_ +#endif // LLDB_INTERPRETER_COMMANDALIAS_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/CommandCompletions.h b/gnu/llvm/lldb/include/lldb/Interpreter/CommandCompletions.h index 275cc7e7c14..39d1c98eaa3 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/CommandCompletions.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/CommandCompletions.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_CommandCompletions_h_ -#define lldb_CommandCompletions_h_ +#ifndef LLDB_INTERPRETER_COMMANDCOMPLETIONS_H +#define LLDB_INTERPRETER_COMMANDCOMPLETIONS_H #include @@ -23,13 +23,6 @@ namespace lldb_private { class TildeExpressionResolver; class CommandCompletions { public: - // This is the command completion callback that is used to complete the - // argument of the option it is bound to (in the OptionDefinition table - // below). Return the total number of matches. - typedef void (*CompletionCallback)(CommandInterpreter &interpreter, - CompletionRequest &request, - // A search filter to limit the search... - lldb_private::SearchFilter *searcher); enum CommonCompletionTypes { eNoCompletion = 0u, eSourceFileCompletion = (1u << 0), @@ -41,15 +34,13 @@ public: ePlatformPluginCompletion = (1u << 6), eArchitectureCompletion = (1u << 7), eVariablePathCompletion = (1u << 8), + eRegisterCompletion = (1u << 9), + eBreakpointCompletion = (1u << 10), + eProcessPluginCompletion = (1u << 11), // This item serves two purposes. It is the last element in the enum, so // you can add custom enums starting from here in your Option class. Also // if you & in this bit the base code will not process the option. - eCustomCompletion = (1u << 9) - }; - - struct CommonCompletionElement { - uint32_t type; - CompletionCallback callback; + eCustomCompletion = (1u << 12) }; static bool InvokeCommonCompletionCallbacks( @@ -94,99 +85,17 @@ public: static void VariablePath(CommandInterpreter &interpreter, CompletionRequest &request, SearchFilter *searcher); - // The Completer class is a convenient base class for building searchers that - // go along with the SearchFilter passed to the standard Completer functions. - class Completer : public Searcher { - public: - Completer(CommandInterpreter &interpreter, CompletionRequest &request); - - ~Completer() override; - - CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context, - Address *addr) override = 0; - - lldb::SearchDepth GetDepth() override = 0; - - virtual void DoCompletion(SearchFilter *filter) = 0; - - protected: - CommandInterpreter &m_interpreter; - CompletionRequest &m_request; - - private: - DISALLOW_COPY_AND_ASSIGN(Completer); - }; - - // SourceFileCompleter implements the source file completer - class SourceFileCompleter : public Completer { - public: - SourceFileCompleter(CommandInterpreter &interpreter, - bool include_support_files, CompletionRequest &request); - - lldb::SearchDepth GetDepth() override; - - Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, - Address *addr) override; - - void DoCompletion(SearchFilter *filter) override; - - private: - bool m_include_support_files; - FileSpecList m_matching_files; - const char *m_file_name; - const char *m_dir_name; - - DISALLOW_COPY_AND_ASSIGN(SourceFileCompleter); - }; - - // ModuleCompleter implements the module completer - class ModuleCompleter : public Completer { - public: - ModuleCompleter(CommandInterpreter &interpreter, - CompletionRequest &request); - - lldb::SearchDepth GetDepth() override; - - Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, - Address *addr) override; - - void DoCompletion(SearchFilter *filter) override; - - private: - const char *m_file_name; - const char *m_dir_name; - - DISALLOW_COPY_AND_ASSIGN(ModuleCompleter); - }; - - // SymbolCompleter implements the symbol completer - class SymbolCompleter : public Completer { - public: - SymbolCompleter(CommandInterpreter &interpreter, - CompletionRequest &request); - - lldb::SearchDepth GetDepth() override; - - Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, - Address *addr) override; - - void DoCompletion(SearchFilter *filter) override; - - private: - RegularExpression m_regex; - typedef std::set collection; - collection m_match_set; + static void Registers(CommandInterpreter &interpreter, + CompletionRequest &request, SearchFilter *searcher); - DISALLOW_COPY_AND_ASSIGN(SymbolCompleter); - }; + static void Breakpoints(CommandInterpreter &interpreter, + CompletionRequest &request, SearchFilter *searcher); -private: - static CommonCompletionElement g_common_completions[]; + static void ProcessPluginNames(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher); }; } // namespace lldb_private -#endif // lldb_CommandCompletions_h_ +#endif // LLDB_INTERPRETER_COMMANDCOMPLETIONS_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/CommandHistory.h b/gnu/llvm/lldb/include/lldb/Interpreter/CommandHistory.h index c1386f84fe2..fbb42247f11 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/CommandHistory.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/CommandHistory.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandHistory_h_ -#define liblldb_CommandHistory_h_ +#ifndef LLDB_INTERPRETER_COMMANDHISTORY_H +#define LLDB_INTERPRETER_COMMANDHISTORY_H #include #include @@ -46,7 +46,8 @@ public: static const char g_repeat_char = '!'; private: - DISALLOW_COPY_AND_ASSIGN(CommandHistory); + CommandHistory(const CommandHistory &) = delete; + const CommandHistory &operator=(const CommandHistory &) = delete; typedef std::vector History; mutable std::recursive_mutex m_mutex; @@ -55,4 +56,4 @@ private: } // namespace lldb_private -#endif // liblldb_CommandHistory_h_ +#endif // LLDB_INTERPRETER_COMMANDHISTORY_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/CommandInterpreter.h b/gnu/llvm/lldb/include/lldb/Interpreter/CommandInterpreter.h index d08951e608c..8a9dce7a19b 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/CommandInterpreter.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/CommandInterpreter.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandInterpreter_h_ -#define liblldb_CommandInterpreter_h_ +#ifndef LLDB_INTERPRETER_COMMANDINTERPRETER_H +#define LLDB_INTERPRETER_COMMANDINTERPRETER_H #include "lldb/Core/Debugger.h" #include "lldb/Core/IOHandler.h" @@ -26,6 +26,32 @@ #include namespace lldb_private { +class CommandInterpreter; + +class CommandInterpreterRunResult { +public: + CommandInterpreterRunResult() + : m_num_errors(0), m_result(lldb::eCommandInterpreterResultSuccess) {} + + uint32_t GetNumErrors() const { return m_num_errors; } + + lldb::CommandInterpreterResult GetResult() const { return m_result; } + + bool IsResult(lldb::CommandInterpreterResult result) { + return m_result == result; + } + +protected: + friend CommandInterpreter; + + void IncrementNumberOfErrors() { m_num_errors++; } + + void SetResult(lldb::CommandInterpreterResult result) { m_result = result; } + +private: + int m_num_errors; + lldb::CommandInterpreterResult m_result; +}; class CommandInterpreterRunOptions { public: @@ -144,6 +170,20 @@ public: m_add_to_history = add_to_history ? eLazyBoolYes : eLazyBoolNo; } + bool GetAutoHandleEvents() const { + return DefaultToYes(m_auto_handle_events); + } + + void SetAutoHandleEvents(bool auto_handle_events) { + m_auto_handle_events = auto_handle_events ? eLazyBoolYes : eLazyBoolNo; + } + + bool GetSpawnThread() const { return DefaultToNo(m_spawn_thread); } + + void SetSpawnThread(bool spawn_thread) { + m_spawn_thread = spawn_thread ? eLazyBoolYes : eLazyBoolNo; + } + LazyBool m_stop_on_continue; LazyBool m_stop_on_error; LazyBool m_stop_on_crash; @@ -152,6 +192,8 @@ public: LazyBool m_print_results; LazyBool m_print_errors; LazyBool m_add_to_history; + LazyBool m_auto_handle_events; + LazyBool m_spawn_thread; private: static bool DefaultToYes(LazyBool flag) { @@ -426,8 +468,8 @@ public: bool IsActive(); - void RunCommandInterpreter(bool auto_handle_events, bool spawn_thread, - CommandInterpreterRunOptions &options); + CommandInterpreterRunResult + RunCommandInterpreter(CommandInterpreterRunOptions &options); void GetLLDBCommandsFromIOHandler(const char *prompt, IOHandlerDelegate &delegate, @@ -452,6 +494,10 @@ public: bool GetEchoCommentCommands() const; void SetEchoCommentCommands(bool enable); + const CommandObject::CommandMap &GetUserCommands() const { + return m_user_dict; + } + /// Specify if the command interpreter should allow that the user can /// specify a custom exit code when calling 'quit'. void AllowExitCodeOnQuit(bool allow); @@ -474,16 +520,10 @@ public: bool GetStopCmdSourceOnError() const; - uint32_t GetNumErrors() const { return m_num_errors; } - - bool GetQuitRequested() const { return m_quit_requested; } - lldb::IOHandlerSP GetIOHandler(bool force_create = false, CommandInterpreterRunOptions *options = nullptr); - bool GetStoppedForCrash() const { return m_stopped_for_crash; } - bool GetSpaceReplPrompts() const; protected: @@ -574,9 +614,7 @@ private: // the user has been told uint32_t m_command_source_depth; std::vector m_command_source_flags; - uint32_t m_num_errors; - bool m_quit_requested; - bool m_stopped_for_crash; + CommandInterpreterRunResult m_result; // The exit code the user has requested when calling the 'quit' command. // No value means the user hasn't set a custom exit code so far. @@ -587,4 +625,4 @@ private: } // namespace lldb_private -#endif // liblldb_CommandInterpreter_h_ +#endif // LLDB_INTERPRETER_COMMANDINTERPRETER_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/CommandObject.h b/gnu/llvm/lldb/include/lldb/Interpreter/CommandObject.h index f4dc2d606dd..cc4d40b23c3 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/CommandObject.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/CommandObject.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObject_h_ -#define liblldb_CommandObject_h_ +#ifndef LLDB_INTERPRETER_COMMANDOBJECT_H +#define LLDB_INTERPRETER_COMMANDOBJECT_H #include #include @@ -40,7 +40,7 @@ int AddNamesMatchingPartialString( const bool add_all = cmd_str.empty(); for (auto iter = in_map.begin(), end = in_map.end(); iter != end; iter++) { - if (add_all || (iter->first.find(cmd_str, 0) == 0)) { + if (add_all || (iter->first.find(std::string(cmd_str), 0) == 0)) { ++number_added; matches.AppendString(iter->first.c_str()); if (descriptions) @@ -411,4 +411,4 @@ protected: } // namespace lldb_private -#endif // liblldb_CommandObject_h_ +#endif // LLDB_INTERPRETER_COMMANDOBJECT_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/CommandObjectMultiword.h b/gnu/llvm/lldb/include/lldb/Interpreter/CommandObjectMultiword.h index 72ec8a9c5ca..6b383f8cfb3 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/CommandObjectMultiword.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/CommandObjectMultiword.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectMultiword_h_ -#define liblldb_CommandObjectMultiword_h_ +#ifndef LLDB_INTERPRETER_COMMANDOBJECTMULTIWORD_H +#define LLDB_INTERPRETER_COMMANDOBJECTMULTIWORD_H #include "lldb/Interpreter/CommandObject.h" #include "lldb/Utility/CompletionRequest.h" @@ -131,4 +131,4 @@ protected: } // namespace lldb_private -#endif // liblldb_CommandObjectMultiword_h_ +#endif // LLDB_INTERPRETER_COMMANDOBJECTMULTIWORD_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/CommandObjectRegexCommand.h b/gnu/llvm/lldb/include/lldb/Interpreter/CommandObjectRegexCommand.h index 7800d5de1b3..01d7c6d118d 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/CommandObjectRegexCommand.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/CommandObjectRegexCommand.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectRegexCommand_h_ -#define liblldb_CommandObjectRegexCommand_h_ +#ifndef LLDB_INTERPRETER_COMMANDOBJECTREGEXCOMMAND_H +#define LLDB_INTERPRETER_COMMANDOBJECTREGEXCOMMAND_H #include @@ -51,9 +51,11 @@ protected: bool m_is_removable; private: - DISALLOW_COPY_AND_ASSIGN(CommandObjectRegexCommand); + CommandObjectRegexCommand(const CommandObjectRegexCommand &) = delete; + const CommandObjectRegexCommand & + operator=(const CommandObjectRegexCommand &) = delete; }; } // namespace lldb_private -#endif // liblldb_CommandObjectRegexCommand_h_ +#endif // LLDB_INTERPRETER_COMMANDOBJECTREGEXCOMMAND_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/CommandOptionValidators.h b/gnu/llvm/lldb/include/lldb/Interpreter/CommandOptionValidators.h index 5483c150955..218cc87fdf2 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/CommandOptionValidators.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/CommandOptionValidators.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandOptionValidators_h_ -#define liblldb_CommandOptionValidators_h_ +#ifndef LLDB_INTERPRETER_COMMANDOPTIONVALIDATORS_H +#define LLDB_INTERPRETER_COMMANDOPTIONVALIDATORS_H #include "lldb/lldb-private-types.h" @@ -25,4 +25,4 @@ class PosixPlatformCommandOptionValidator : public OptionValidator { } // namespace lldb_private -#endif // liblldb_CommandOptionValidators_h_ +#endif // LLDB_INTERPRETER_COMMANDOPTIONVALIDATORS_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/CommandReturnObject.h b/gnu/llvm/lldb/include/lldb/Interpreter/CommandReturnObject.h index 8af76e07e5a..a7c2eea5766 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/CommandReturnObject.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/CommandReturnObject.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandReturnObject_h_ -#define liblldb_CommandReturnObject_h_ +#ifndef LLDB_INTERPRETER_COMMANDRETURNOBJECT_H +#define LLDB_INTERPRETER_COMMANDRETURNOBJECT_H #include "lldb/Core/StreamFile.h" #include "lldb/Utility/StreamString.h" @@ -16,6 +16,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/WithColor.h" #include @@ -23,21 +24,21 @@ namespace lldb_private { class CommandReturnObject { public: - CommandReturnObject(); + CommandReturnObject(bool colors); ~CommandReturnObject(); llvm::StringRef GetOutputData() { lldb::StreamSP stream_sp(m_out_stream.GetStreamAtIndex(eStreamStringIndex)); if (stream_sp) - return static_pointer_cast(stream_sp)->GetString(); + return std::static_pointer_cast(stream_sp)->GetString(); return llvm::StringRef(); } llvm::StringRef GetErrorData() { lldb::StreamSP stream_sp(m_err_stream.GetStreamAtIndex(eStreamStringIndex)); if (stream_sp) - return static_pointer_cast(stream_sp)->GetString(); + return std::static_pointer_cast(stream_sp)->GetString(); return llvm::StringRef(); } @@ -45,7 +46,7 @@ public: // Make sure we at least have our normal string stream output stream lldb::StreamSP stream_sp(m_out_stream.GetStreamAtIndex(eStreamStringIndex)); if (!stream_sp) { - stream_sp.reset(new StreamString()); + stream_sp = std::make_shared(); m_out_stream.SetStreamAtIndex(eStreamStringIndex, stream_sp); } return m_out_stream; @@ -55,7 +56,7 @@ public: // Make sure we at least have our normal string stream output stream lldb::StreamSP stream_sp(m_err_stream.GetStreamAtIndex(eStreamStringIndex)); if (!stream_sp) { - stream_sp.reset(new StreamString()); + stream_sp = std::make_shared(); m_err_stream.SetStreamAtIndex(eStreamStringIndex, stream_sp); } return m_err_stream; @@ -157,4 +158,4 @@ private: } // namespace lldb_private -#endif // liblldb_CommandReturnObject_h_ +#endif // LLDB_INTERPRETER_COMMANDRETURNOBJECT_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupArchitecture.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupArchitecture.h index 4b7f9fe92e3..1eadf45bae4 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupArchitecture.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupArchitecture.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionGroupArchitecture_h_ -#define liblldb_OptionGroupArchitecture_h_ +#ifndef LLDB_INTERPRETER_OPTIONGROUPARCHITECTURE_H +#define LLDB_INTERPRETER_OPTIONGROUPARCHITECTURE_H #include "lldb/Interpreter/Options.h" #include "lldb/Utility/ArchSpec.h" @@ -42,4 +42,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionGroupArchitecture_h_ +#endif // LLDB_INTERPRETER_OPTIONGROUPARCHITECTURE_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupBoolean.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupBoolean.h index 77490457528..061e3134085 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupBoolean.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupBoolean.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionGroupBoolean_h_ -#define liblldb_OptionGroupBoolean_h_ +#ifndef LLDB_INTERPRETER_OPTIONGROUPBOOLEAN_H +#define LLDB_INTERPRETER_OPTIONGROUPBOOLEAN_H #include "lldb/Interpreter/OptionValueBoolean.h" #include "lldb/Interpreter/Options.h" @@ -48,4 +48,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionGroupBoolean_h_ +#endif // LLDB_INTERPRETER_OPTIONGROUPBOOLEAN_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupFile.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupFile.h index cce3714e98b..374cf10ea30 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupFile.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupFile.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionGroupFile_h_ -#define liblldb_OptionGroupFile_h_ +#ifndef LLDB_INTERPRETER_OPTIONGROUPFILE_H +#define LLDB_INTERPRETER_OPTIONGROUPFILE_H #include "lldb/Interpreter/OptionValueFileSpec.h" #include "lldb/Interpreter/OptionValueFileSpecList.h" @@ -78,4 +78,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionGroupFile_h_ +#endif // LLDB_INTERPRETER_OPTIONGROUPFILE_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupFormat.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupFormat.h index 1b5020a392c..62c6f97c621 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupFormat.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupFormat.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionGroupFormat_h_ -#define liblldb_OptionGroupFormat_h_ +#ifndef LLDB_INTERPRETER_OPTIONGROUPFORMAT_H +#define LLDB_INTERPRETER_OPTIONGROUPFORMAT_H #include "lldb/Interpreter/OptionValueFormat.h" #include "lldb/Interpreter/OptionValueSInt64.h" @@ -78,4 +78,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionGroupFormat_h_ +#endif // LLDB_INTERPRETER_OPTIONGROUPFORMAT_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupOutputFile.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupOutputFile.h index 82d68b7c164..a71998f3bc1 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupOutputFile.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupOutputFile.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionGroupOutputFile_h_ -#define liblldb_OptionGroupOutputFile_h_ +#ifndef LLDB_INTERPRETER_OPTIONGROUPOUTPUTFILE_H +#define LLDB_INTERPRETER_OPTIONGROUPOUTPUTFILE_H #include "lldb/Interpreter/OptionValueBoolean.h" #include "lldb/Interpreter/OptionValueFileSpec.h" @@ -45,4 +45,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionGroupOutputFile_h_ +#endif // LLDB_INTERPRETER_OPTIONGROUPOUTPUTFILE_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupPlatform.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupPlatform.h index ea5a3f39ef8..99945e5246f 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupPlatform.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupPlatform.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionGroupPlatform_h_ -#define liblldb_OptionGroupPlatform_h_ +#ifndef LLDB_INTERPRETER_OPTIONGROUPPLATFORM_H +#define LLDB_INTERPRETER_OPTIONGROUPPLATFORM_H #include "lldb/Interpreter/Options.h" #include "lldb/Utility/ConstString.h" @@ -70,4 +70,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionGroupPlatform_h_ +#endif // LLDB_INTERPRETER_OPTIONGROUPPLATFORM_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupPythonClassWithDict.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupPythonClassWithDict.h index 2229c1aa08a..d4c924a4415 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupPythonClassWithDict.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupPythonClassWithDict.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionGroupPythonClassWithDict_h_ -#define liblldb_OptionGroupPythonClassWithDict_h_ +#ifndef LLDB_INTERPRETER_OPTIONGROUPPYTHONCLASSWITHDICT_H +#define LLDB_INTERPRETER_OPTIONGROUPPYTHONCLASSWITHDICT_H #include "lldb/lldb-types.h" #include "lldb/Interpreter/Options.h" @@ -60,4 +60,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionGroupPythonClassWithDict_h_ +#endif // LLDB_INTERPRETER_OPTIONGROUPPYTHONCLASSWITHDICT_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupString.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupString.h index ce105895405..1a3b5bdd88e 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupString.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupString.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionGroupString_h_ -#define liblldb_OptionGroupString_h_ +#ifndef LLDB_INTERPRETER_OPTIONGROUPSTRING_H +#define LLDB_INTERPRETER_OPTIONGROUPSTRING_H #include "lldb/Interpreter/OptionValueString.h" #include "lldb/Interpreter/Options.h" @@ -45,4 +45,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionGroupString_h_ +#endif // LLDB_INTERPRETER_OPTIONGROUPSTRING_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupUInt64.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupUInt64.h index 12f08a38c53..783c4b632f0 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupUInt64.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupUInt64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionGroupUInt64_h_ -#define liblldb_OptionGroupUInt64_h_ +#ifndef LLDB_INTERPRETER_OPTIONGROUPUINT64_H +#define LLDB_INTERPRETER_OPTIONGROUPUINT64_H #include "lldb/Interpreter/OptionValueUInt64.h" #include "lldb/Interpreter/Options.h" @@ -46,4 +46,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionGroupUInt64_h_ +#endif // LLDB_INTERPRETER_OPTIONGROUPUINT64_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupUUID.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupUUID.h index 22fc3a100c7..b1c779f7b5a 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupUUID.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupUUID.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionGroupUUID_h_ -#define liblldb_OptionGroupUUID_h_ +#ifndef LLDB_INTERPRETER_OPTIONGROUPUUID_H +#define LLDB_INTERPRETER_OPTIONGROUPUUID_H #include "lldb/Interpreter/OptionValueUUID.h" #include "lldb/Interpreter/Options.h" @@ -38,4 +38,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionGroupUUID_h_ +#endif // LLDB_INTERPRETER_OPTIONGROUPUUID_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h index 5a1bbc9e7b6..1ad53321d26 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionGroupValueObjectDisplay_h_ -#define liblldb_OptionGroupValueObjectDisplay_h_ +#ifndef LLDB_INTERPRETER_OPTIONGROUPVALUEOBJECTDISPLAY_H +#define LLDB_INTERPRETER_OPTIONGROUPVALUEOBJECTDISPLAY_H #include "lldb/Core/ValueObject.h" #include "lldb/Interpreter/Options.h" @@ -55,4 +55,4 @@ public: } // namespace lldb_private -#endif // liblldb_OptionGroupValueObjectDisplay_h_ +#endif // LLDB_INTERPRETER_OPTIONGROUPVALUEOBJECTDISPLAY_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupVariable.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupVariable.h index 0c042f4c1cd..252ca3b42c5 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupVariable.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupVariable.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionGroupVariable_h_ -#define liblldb_OptionGroupVariable_h_ +#ifndef LLDB_INTERPRETER_OPTIONGROUPVARIABLE_H +#define LLDB_INTERPRETER_OPTIONGROUPVARIABLE_H #include "lldb/Interpreter/OptionValueString.h" #include "lldb/Interpreter/Options.h" @@ -41,9 +41,10 @@ public: OptionValueString summary_string; // a summary string private: - DISALLOW_COPY_AND_ASSIGN(OptionGroupVariable); + OptionGroupVariable(const OptionGroupVariable &) = delete; + const OptionGroupVariable &operator=(const OptionGroupVariable &) = delete; }; } // namespace lldb_private -#endif // liblldb_OptionGroupVariable_h_ +#endif // LLDB_INTERPRETER_OPTIONGROUPVARIABLE_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h index 3729c000b8e..6a6c8638aed 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionGroupWatchpoint_h_ -#define liblldb_OptionGroupWatchpoint_h_ +#ifndef LLDB_INTERPRETER_OPTIONGROUPWATCHPOINT_H +#define LLDB_INTERPRETER_OPTIONGROUPWATCHPOINT_H #include "lldb/Interpreter/Options.h" @@ -46,9 +46,11 @@ public: bool watch_type_specified; private: - DISALLOW_COPY_AND_ASSIGN(OptionGroupWatchpoint); + OptionGroupWatchpoint(const OptionGroupWatchpoint &) = delete; + const OptionGroupWatchpoint & + operator=(const OptionGroupWatchpoint &) = delete; }; } // namespace lldb_private -#endif // liblldb_OptionGroupWatchpoint_h_ +#endif // LLDB_INTERPRETER_OPTIONGROUPWATCHPOINT_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValue.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValue.h index 44c7f621a58..5b07427094b 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValue.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValue.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValue_h_ -#define liblldb_OptionValue_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUE_H +#define LLDB_INTERPRETER_OPTIONVALUE_H #include "lldb/Core/FormatEntity.h" #include "lldb/Utility/CompletionRequest.h" @@ -326,4 +326,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionValue_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUE_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueArch.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueArch.h index 3923e3d3dba..7b63c68fddb 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueArch.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueArch.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValueArch_h_ -#define liblldb_OptionValueArch_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUEARCH_H +#define LLDB_INTERPRETER_OPTIONVALUEARCH_H #include "lldb/Interpreter/OptionValue.h" #include "lldb/Utility/ArchSpec.h" @@ -81,4 +81,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionValueArch_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUEARCH_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueArgs.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueArgs.h index 0254b9aa7e1..25f7fdde0bf 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueArgs.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueArgs.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValueArgs_h_ -#define liblldb_OptionValueArgs_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUEARGS_H +#define LLDB_INTERPRETER_OPTIONVALUEARGS_H #include "lldb/Interpreter/OptionValueArray.h" @@ -28,4 +28,4 @@ public: } // namespace lldb_private -#endif // liblldb_OptionValueArgs_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUEARGS_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueArray.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueArray.h index 10f3bf5f729..000351c2f58 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueArray.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueArray.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValueArray_h_ -#define liblldb_OptionValueArray_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUEARRAY_H +#define LLDB_INTERPRETER_OPTIONVALUEARRAY_H #include @@ -125,4 +125,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionValueArray_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUEARRAY_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueBoolean.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueBoolean.h index 42b2ca4d284..d221f6d034c 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueBoolean.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueBoolean.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValueBoolean_h_ -#define liblldb_OptionValueBoolean_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUEBOOLEAN_H +#define LLDB_INTERPRETER_OPTIONVALUEBOOLEAN_H #include "lldb/Interpreter/OptionValue.h" @@ -85,4 +85,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionValueBoolean_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUEBOOLEAN_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueChar.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueChar.h index d8661363751..8d0aa91d707 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueChar.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueChar.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValueChar_h_ -#define liblldb_OptionValueChar_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUECHAR_H +#define LLDB_INTERPRETER_OPTIONVALUECHAR_H #include "lldb/Interpreter/OptionValue.h" @@ -68,4 +68,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionValueChar_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUECHAR_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueDictionary.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueDictionary.h index 8785d38f542..1bc45252607 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueDictionary.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueDictionary.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValueDictionary_h_ -#define liblldb_OptionValueDictionary_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUEDICTIONARY_H +#define LLDB_INTERPRETER_OPTIONVALUEDICTIONARY_H #include @@ -81,4 +81,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionValueDictionary_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUEDICTIONARY_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueEnumeration.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueEnumeration.h index eb19737f865..26ba7ad5f64 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueEnumeration.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueEnumeration.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValueEnumeration_h_ -#define liblldb_OptionValueEnumeration_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUEENUMERATION_H +#define LLDB_INTERPRETER_OPTIONVALUEENUMERATION_H #include "lldb/Core/UniqueCStringMap.h" #include "lldb/Interpreter/OptionValue.h" @@ -83,4 +83,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionValueEnumeration_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUEENUMERATION_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueFileSpec.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueFileSpec.h index a6df1814907..2b18c9533f9 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueFileSpec.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueFileSpec.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValueFileSpec_h_ -#define liblldb_OptionValueFileSpec_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUEFILESPEC_H +#define LLDB_INTERPRETER_OPTIONVALUEFILESPEC_H #include "lldb/Interpreter/OptionValue.h" @@ -86,4 +86,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionValueFileSpec_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUEFILESPEC_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h index 5607437fd0d..7b762bf6b30 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValueFileSpecList_h_ -#define liblldb_OptionValueFileSpecList_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUEFILESPECLIST_H +#define LLDB_INTERPRETER_OPTIONVALUEFILESPECLIST_H #include @@ -74,4 +74,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionValueFileSpecList_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUEFILESPECLIST_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueFormat.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueFormat.h index 020f4aeda17..6904c93a2f3 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueFormat.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueFormat.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValueFormat_h_ -#define liblldb_OptionValueFormat_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUEFORMAT_H +#define LLDB_INTERPRETER_OPTIONVALUEFORMAT_H #include "lldb/Interpreter/OptionValue.h" @@ -63,4 +63,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionValueFormat_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUEFORMAT_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h index 419ff5c03e3..beb5d6843a9 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValueFormatEntity_h_ -#define liblldb_OptionValueFormatEntity_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUEFORMATENTITY_H +#define LLDB_INTERPRETER_OPTIONVALUEFORMATENTITY_H #include "lldb/Core/FormatEntity.h" #include "lldb/Interpreter/OptionValue.h" @@ -64,4 +64,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionValueFormatEntity_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUEFORMATENTITY_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueLanguage.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueLanguage.h index 505dc89e920..f4ca2fd69ab 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueLanguage.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueLanguage.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValueLanguage_h_ -#define liblldb_OptionValueLanguage_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUELANGUAGE_H +#define LLDB_INTERPRETER_OPTIONVALUELANGUAGE_H #include "lldb/Interpreter/OptionValue.h" #include "lldb/lldb-enumerations.h" @@ -66,4 +66,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionValueLanguage_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUELANGUAGE_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValuePathMappings.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValuePathMappings.h index 35c2af45bc9..18f5cbaf433 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValuePathMappings.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValuePathMappings.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValuePathMappings_h_ -#define liblldb_OptionValuePathMappings_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUEPATHMAPPINGS_H +#define LLDB_INTERPRETER_OPTIONVALUEPATHMAPPINGS_H #include "lldb/Interpreter/OptionValue.h" #include "lldb/Target/PathMappingList.h" @@ -58,4 +58,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionValuePathMappings_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUEPATHMAPPINGS_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueProperties.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueProperties.h index 980f01183ef..76f09cc7712 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueProperties.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueProperties.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValueProperties_h_ -#define liblldb_OptionValueProperties_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUEPROPERTIES_H +#define LLDB_INTERPRETER_OPTIONVALUEPROPERTIES_H #include @@ -218,4 +218,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionValueProperties_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUEPROPERTIES_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueRegex.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueRegex.h index 8c10dacb031..b09b8414d5b 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueRegex.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueRegex.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValueRegex_h_ -#define liblldb_OptionValueRegex_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUEREGEX_H +#define LLDB_INTERPRETER_OPTIONVALUEREGEX_H #include "lldb/Interpreter/OptionValue.h" #include "lldb/Utility/RegularExpression.h" @@ -17,7 +17,8 @@ namespace lldb_private { class OptionValueRegex : public OptionValue { public: OptionValueRegex(const char *value = nullptr) - : OptionValue(), m_regex(llvm::StringRef::withNullAsEmpty(value)) {} + : OptionValue(), m_regex(llvm::StringRef::withNullAsEmpty(value)), + m_default_regex_str(llvm::StringRef::withNullAsEmpty(value).str()) {} ~OptionValueRegex() override = default; @@ -36,7 +37,7 @@ public: VarSetOperationType = eVarSetOperationAssign) = delete; bool Clear() override { - m_regex = RegularExpression(); + m_regex = RegularExpression(m_default_regex_str); m_value_was_set = false; return true; } @@ -59,8 +60,9 @@ public: protected: RegularExpression m_regex; + std::string m_default_regex_str; }; } // namespace lldb_private -#endif // liblldb_OptionValueRegex_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUEREGEX_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueSInt64.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueSInt64.h index c2e8ff43a99..fbabaaeb2ff 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueSInt64.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueSInt64.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValueSInt64_h_ -#define liblldb_OptionValueSInt64_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUESINT64_H +#define LLDB_INTERPRETER_OPTIONVALUESINT64_H #include "lldb/Interpreter/OptionValue.h" @@ -102,4 +102,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionValueSInt64_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUESINT64_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueString.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueString.h index d9e76d8b58f..cd371c56702 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueString.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueString.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValueString_h_ -#define liblldb_OptionValueString_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUESTRING_H +#define LLDB_INTERPRETER_OPTIONVALUESTRING_H #include @@ -136,4 +136,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionValueString_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUESTRING_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueUInt64.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueUInt64.h index 5978cdb4434..0096e87de36 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueUInt64.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueUInt64.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValueUInt64_h_ -#define liblldb_OptionValueUInt64_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUEUINT64_H +#define LLDB_INTERPRETER_OPTIONVALUEUINT64_H #include "lldb/Interpreter/OptionValue.h" @@ -79,4 +79,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionValueUInt64_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUEUINT64_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueUUID.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueUUID.h index 576440d8051..2fb8caa3aa5 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueUUID.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValueUUID.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValueUUID_h_ -#define liblldb_OptionValueUUID_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUEUUID_H +#define LLDB_INTERPRETER_OPTIONVALUEUUID_H #include "lldb/Utility/UUID.h" #include "lldb/Interpreter/OptionValue.h" @@ -61,4 +61,4 @@ protected: } // namespace lldb_private -#endif // liblldb_OptionValueUUID_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUEUUID_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValues.h b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValues.h index d90b2867a4b..36e7c192d60 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/OptionValues.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/OptionValues.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OptionValues_h_ -#define liblldb_OptionValues_h_ +#ifndef LLDB_INTERPRETER_OPTIONVALUES_H +#define LLDB_INTERPRETER_OPTIONVALUES_H #include "lldb/Interpreter/OptionValue.h" #include "lldb/Interpreter/OptionValueArch.h" @@ -30,4 +30,4 @@ #include "lldb/Interpreter/OptionValueUInt64.h" #include "lldb/Interpreter/OptionValueUUID.h" -#endif // liblldb_OptionValues_h_ +#endif // LLDB_INTERPRETER_OPTIONVALUES_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/Options.h b/gnu/llvm/lldb/include/lldb/Interpreter/Options.h index d07c2560ef2..ebceaea8383 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/Options.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/Options.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Options_h_ -#define liblldb_Options_h_ +#ifndef LLDB_INTERPRETER_OPTIONS_H +#define LLDB_INTERPRETER_OPTIONS_H #include #include @@ -43,7 +43,7 @@ typedef std::vector OptionElementVector; static inline bool isprint8(int ch) { if (ch & 0xffffff00u) return false; - return isprint(ch); + return llvm::isPrint(ch); } /// \class Options Options.h "lldb/Interpreter/Options.h" @@ -328,4 +328,4 @@ public: } // namespace lldb_private -#endif // liblldb_Options_h_ +#endif // LLDB_INTERPRETER_OPTIONS_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/Property.h b/gnu/llvm/lldb/include/lldb/Interpreter/Property.h index 76264832705..97ec7ca1d4a 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/Property.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/Property.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Property_h_ -#define liblldb_Property_h_ +#ifndef LLDB_INTERPRETER_PROPERTY_H +#define LLDB_INTERPRETER_PROPERTY_H #include "lldb/Interpreter/OptionValue.h" #include "lldb/Utility/ConstString.h" @@ -75,4 +75,4 @@ protected: } // namespace lldb_private -#endif // liblldb_Property_h_ +#endif // LLDB_INTERPRETER_PROPERTY_H diff --git a/gnu/llvm/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/gnu/llvm/lldb/include/lldb/Interpreter/ScriptInterpreter.h index 1784c93adba..491923e6a6c 100644 --- a/gnu/llvm/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/gnu/llvm/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -6,19 +6,19 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ScriptInterpreter_h_ -#define liblldb_ScriptInterpreter_h_ - -#include "lldb/lldb-private.h" +#ifndef LLDB_INTERPRETER_SCRIPTINTERPRETER_H +#define LLDB_INTERPRETER_SCRIPTINTERPRETER_H #include "lldb/Breakpoint/BreakpointOptions.h" +#include "lldb/Core/Communication.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Core/SearchFilter.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Host/PseudoTerminal.h" #include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StructuredData.h" - -#include "lldb/Host/PseudoTerminal.h" +#include "lldb/lldb-private.h" namespace lldb_private { @@ -29,7 +29,38 @@ public: virtual ~ScriptInterpreterLocker() = default; private: - DISALLOW_COPY_AND_ASSIGN(ScriptInterpreterLocker); + ScriptInterpreterLocker(const ScriptInterpreterLocker &) = delete; + const ScriptInterpreterLocker & + operator=(const ScriptInterpreterLocker &) = delete; +}; + +class ScriptInterpreterIORedirect { +public: + /// Create an IO redirect. If IO is enabled, this will redirects the output + /// to the command return object if set or to the debugger otherwise. If IO + /// is disabled, it will redirect all IO to /dev/null. + static llvm::Expected> + Create(bool enable_io, Debugger &debugger, CommandReturnObject *result); + + ~ScriptInterpreterIORedirect(); + + lldb::FileSP GetInputFile() const { return m_input_file_sp; } + lldb::FileSP GetOutputFile() const { return m_output_file_sp->GetFileSP(); } + lldb::FileSP GetErrorFile() const { return m_error_file_sp->GetFileSP(); } + + /// Flush our output and error file handles. + void Flush(); + +private: + ScriptInterpreterIORedirect(std::unique_ptr input, + std::unique_ptr output); + ScriptInterpreterIORedirect(Debugger &debugger, CommandReturnObject *result); + + lldb::FileSP m_input_file_sp; + lldb::StreamFileSP m_output_file_sp; + lldb::StreamFileSP m_error_file_sp; + Communication m_communication; + bool m_disconnect; }; class ScriptInterpreter : public PluginInterface { @@ -467,8 +498,6 @@ public: const char *GetScriptInterpreterPtyName(); - int GetMasterFileDescriptor(); - virtual llvm::Expected GetMaxPositionalArgumentsForCallable(const llvm::StringRef &callable_name) { return llvm::createStringError( @@ -488,4 +517,4 @@ protected: } // namespace lldb_private -#endif // liblldb_ScriptInterpreter_h_ +#endif // LLDB_INTERPRETER_SCRIPTINTERPRETER_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/ArmUnwindInfo.h b/gnu/llvm/lldb/include/lldb/Symbol/ArmUnwindInfo.h index a74b4442df1..24f9f1a0a61 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/ArmUnwindInfo.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/ArmUnwindInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ArmUnwindInfo_h_ -#define liblldb_ArmUnwindInfo_h_ +#ifndef LLDB_SYMBOL_ARMUNWINDINFO_H +#define LLDB_SYMBOL_ARMUNWINDINFO_H #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/DataExtractor.h" @@ -65,4 +65,4 @@ private: } // namespace lldb_private -#endif // liblldb_ArmUnwindInfo_h_ +#endif // LLDB_SYMBOL_ARMUNWINDINFO_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/Block.h b/gnu/llvm/lldb/include/lldb/Symbol/Block.h index c2760dddf45..de94556d3f2 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/Block.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/Block.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Block_h_ -#define liblldb_Block_h_ +#ifndef LLDB_SYMBOL_BLOCK_H +#define LLDB_SYMBOL_BLOCK_H #include "lldb/Core/AddressRange.h" #include "lldb/Symbol/CompilerType.h" @@ -40,7 +40,7 @@ namespace lldb_private { /// blocks. class Block : public UserID, public SymbolContextScope { public: - typedef RangeArray RangeList; + typedef RangeVector RangeList; typedef RangeList::Entry Range; /// Construct with a User ID \a uid, \a depth. @@ -376,9 +376,10 @@ protected: Block *GetSiblingForChild(const Block *child_block) const; private: - DISALLOW_COPY_AND_ASSIGN(Block); + Block(const Block &) = delete; + const Block &operator=(const Block &) = delete; }; } // namespace lldb_private -#endif // liblldb_Block_h_ +#endif // LLDB_SYMBOL_BLOCK_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/CallFrameInfo.h b/gnu/llvm/lldb/include/lldb/Symbol/CallFrameInfo.h index 765ddb41ab0..7db8722baaf 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/CallFrameInfo.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/CallFrameInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CallFrameInfo_h_ -#define liblldb_CallFrameInfo_h_ +#ifndef LLDB_SYMBOL_CALLFRAMEINFO_H +#define LLDB_SYMBOL_CALLFRAMEINFO_H #include "lldb/Core/Address.h" @@ -25,4 +25,4 @@ public: } // namespace lldb_private -#endif // liblldb_CallFrameInfo_h_ +#endif // LLDB_SYMBOL_CALLFRAMEINFO_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/CompactUnwindInfo.h b/gnu/llvm/lldb/include/lldb/Symbol/CompactUnwindInfo.h index 2646661ec23..e622c5fde22 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/CompactUnwindInfo.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/CompactUnwindInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CompactUnwindInfo_h_ -#define liblldb_CompactUnwindInfo_h_ +#ifndef LLDB_SYMBOL_COMPACTUNWINDINFO_H +#define LLDB_SYMBOL_COMPACTUNWINDINFO_H #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/UnwindPlan.h" @@ -164,4 +164,4 @@ private: } // namespace lldb_private -#endif // liblldb_CompactUnwindInfo_h_ +#endif // LLDB_SYMBOL_COMPACTUNWINDINFO_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/CompileUnit.h b/gnu/llvm/lldb/include/lldb/Symbol/CompileUnit.h index aec5cc7c874..256148f20d1 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/CompileUnit.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/CompileUnit.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CompUnit_h_ -#define liblldb_CompUnit_h_ +#ifndef LLDB_SYMBOL_COMPILEUNIT_H +#define LLDB_SYMBOL_COMPILEUNIT_H #include "lldb/Core/FileSpecList.h" #include "lldb/Core/ModuleChild.h" @@ -447,9 +447,10 @@ private: (1u << 6) ///< Have we parsed the debug macros already? }; - DISALLOW_COPY_AND_ASSIGN(CompileUnit); + CompileUnit(const CompileUnit &) = delete; + const CompileUnit &operator=(const CompileUnit &) = delete; }; } // namespace lldb_private -#endif // liblldb_CompUnit_h_ +#endif // LLDB_SYMBOL_COMPILEUNIT_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/CompilerDecl.h b/gnu/llvm/lldb/include/lldb/Symbol/CompilerDecl.h index 4fd269d4730..67290b9be06 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/CompilerDecl.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/CompilerDecl.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CompilerDecl_h_ -#define liblldb_CompilerDecl_h_ +#ifndef LLDB_SYMBOL_COMPILERDECL_H +#define LLDB_SYMBOL_COMPILERDECL_H #include "lldb/Symbol/CompilerType.h" #include "lldb/Utility/ConstString.h" @@ -94,4 +94,4 @@ bool operator!=(const CompilerDecl &lhs, const CompilerDecl &rhs); } // namespace lldb_private -#endif // #ifndef liblldb_CompilerDecl_h_ +#endif // LLDB_SYMBOL_COMPILERDECL_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/CompilerDeclContext.h b/gnu/llvm/lldb/include/lldb/Symbol/CompilerDeclContext.h index 6db6f4d3f62..87d4ca30884 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/CompilerDeclContext.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/CompilerDeclContext.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CompilerDeclContext_h_ -#define liblldb_CompilerDeclContext_h_ +#ifndef LLDB_SYMBOL_COMPILERDECLCONTEXT_H +#define LLDB_SYMBOL_COMPILERDECLCONTEXT_H #include @@ -38,7 +38,7 @@ public: /// This constructor should only be called from the respective TypeSystem /// implementation. /// - /// \see lldb_private::ClangASTContext::CreateDeclContext(clang::DeclContext*) + /// \see lldb_private::TypeSystemClang::CreateDeclContext(clang::DeclContext*) CompilerDeclContext(TypeSystem *type_system, void *decl_ctx) : m_type_system(type_system), m_opaque_decl_ctx(decl_ctx) {} @@ -126,4 +126,4 @@ bool operator!=(const CompilerDeclContext &lhs, const CompilerDeclContext &rhs); } // namespace lldb_private -#endif // #ifndef liblldb_CompilerDeclContext_h_ +#endif // LLDB_SYMBOL_COMPILERDECLCONTEXT_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/CompilerType.h b/gnu/llvm/lldb/include/lldb/Symbol/CompilerType.h index 37e826291c8..280966a327e 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/CompilerType.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/CompilerType.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CompilerType_h_ -#define liblldb_CompilerType_h_ +#ifndef LLDB_SYMBOL_COMPILERTYPE_H +#define LLDB_SYMBOL_COMPILERTYPE_H #include #include @@ -37,34 +37,37 @@ public: /// This constructor should only be called from the respective TypeSystem /// implementation. /// - /// \see lldb_private::ClangASTContext::GetType(clang::QualType) + /// \see lldb_private::TypeSystemClang::GetType(clang::QualType) CompilerType(TypeSystem *type_system, lldb::opaque_compiler_type_t type) - : m_type(type), m_type_system(type_system) {} + : m_type(type), m_type_system(type_system) { + assert(Verify() && "verification failed"); + } CompilerType(const CompilerType &rhs) : m_type(rhs.m_type), m_type_system(rhs.m_type_system) {} CompilerType() = default; - // Operators - + /// Operators. + /// \{ const CompilerType &operator=(const CompilerType &rhs) { m_type = rhs.m_type; m_type_system = rhs.m_type_system; return *this; } - // Tests - - explicit operator bool() const { - return m_type != nullptr && m_type_system != nullptr; - } - bool operator<(const CompilerType &rhs) const { if (m_type_system == rhs.m_type_system) return m_type < rhs.m_type; return m_type_system < rhs.m_type_system; } + /// \} + + /// Tests. + /// \{ + explicit operator bool() const { + return m_type != nullptr && m_type_system != nullptr; + } bool IsValid() const { return m_type != nullptr && m_type_system != nullptr; } @@ -115,8 +118,9 @@ public: bool IsPolymorphicClass() const; - bool IsPossibleDynamicType(CompilerType *target_type, // Can pass nullptr - bool check_cplusplus, bool check_objc) const; + /// \param target_type Can pass nullptr. + bool IsPossibleDynamicType(CompilerType *target_type, bool check_cplusplus, + bool check_objc) const; bool IsPointerToScalarType() const; @@ -136,23 +140,22 @@ public: bool IsTypedefType() const; bool IsVoidType() const; + /// \} - // Type Completion - + /// Type Completion. + /// \{ bool GetCompleteType() const; + /// \} - // AST related queries - + /// AST related queries. + /// \{ size_t GetPointerByteSize() const; + /// \} - // Accessors - + /// Accessors. + /// \{ TypeSystem *GetTypeSystem() const { return m_type_system; } - ConstString GetConstQualifiedTypeName() const; - - ConstString GetConstTypeName() const; - ConstString GetTypeName() const; ConstString GetDisplayTypeName() const; @@ -170,9 +173,10 @@ public: lldb::opaque_compiler_type_t type); unsigned GetTypeQualifiers() const; + /// \} - // Creating related types - + /// Creating related types. + /// \{ CompilerType GetArrayElementType(uint64_t *stride = nullptr) const; CompilerType GetArrayType(uint64_t size) const; @@ -181,8 +185,8 @@ public: CompilerType GetFullyUnqualifiedType() const; - // 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. + /// 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() const; CompilerType GetFunctionArgumentTypeAtIndex(size_t idx) const; @@ -193,62 +197,65 @@ public: TypeMemberFunctionImpl GetMemberFunctionAtIndex(size_t idx); - // If this type is a reference to a type (L value or R value reference), - // return a new type with the reference removed, else return the current type - // itself. + /// If this type is a reference to a type (L value or R value reference), + /// return a new type with the reference removed, else return the current type + /// itself. CompilerType GetNonReferenceType() const; - // If this type is a pointer type, return the type that the pointer points - // to, else return an invalid type. + /// If this type is a pointer type, return the type that the pointer points + /// to, else return an invalid type. CompilerType GetPointeeType() const; - // Return a new CompilerType that is a pointer to this type + /// Return a new CompilerType that is a pointer to this type CompilerType GetPointerType() const; - // Return a new CompilerType that is a L value reference to this type if this - // type is valid and the type system supports L value references, else return - // an invalid type. + /// Return a new CompilerType that is a L value reference to this type if this + /// type is valid and the type system supports L value references, else return + /// an invalid type. CompilerType GetLValueReferenceType() const; - // Return a new CompilerType that is a R value reference to this type if this - // type is valid and the type system supports R value references, else return - // an invalid type. + /// Return a new CompilerType that is a R value reference to this type if this + /// type is valid and the type system supports R value references, else return + /// an invalid type. CompilerType GetRValueReferenceType() const; - // Return a new CompilerType adds a const modifier to this type if this type - // is valid and the type system supports const modifiers, else return an - // invalid type. + /// Return a new CompilerType adds a const modifier to this type if this type + /// is valid and the type system supports const modifiers, else return an + /// invalid type. CompilerType AddConstModifier() const; - // Return a new CompilerType adds a volatile modifier to this type if this - // type is valid and the type system supports volatile modifiers, else return - // an invalid type. + /// Return a new CompilerType adds a volatile modifier to this type if this + /// type is valid and the type system supports volatile modifiers, else return + /// an invalid type. CompilerType AddVolatileModifier() const; - // Return a new CompilerType that is the atomic type of this type. If this - // type is not valid or the type system doesn't support atomic types, this - // returns an invalid type. + /// Return a new CompilerType that is the atomic type of this type. If this + /// type is not valid or the type system doesn't support atomic types, this + /// returns an invalid type. CompilerType GetAtomicType() const; - // Return a new CompilerType adds a restrict modifier to this type if this - // type is valid and the type system supports restrict modifiers, else return - // an invalid type. + /// Return a new CompilerType adds a restrict modifier to this type if this + /// type is valid and the type system supports restrict modifiers, else return + /// an invalid type. CompilerType AddRestrictModifier() const; - // Create a typedef to this type using "name" as the name of the typedef this - // type is valid and the type system supports typedefs, else return an - // invalid type. + /// Create a typedef to this type using "name" as the name of the typedef this + /// type is valid and the type system supports typedefs, else return an + /// invalid type. + /// \param payload The typesystem-specific \p lldb::Type payload. CompilerType CreateTypedef(const char *name, - const CompilerDeclContext &decl_ctx) const; + const CompilerDeclContext &decl_ctx, + uint32_t payload) const; - // If the current object represents a typedef type, get the underlying type + /// If the current object represents a typedef type, get the underlying type CompilerType GetTypedefedType() const; - // Create related types using the current type's AST + /// Create related types using the current type's AST CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const; + /// \} - // Exploring the type - + /// Exploring the type. + /// \{ struct IntegralTemplateArgument; /// Return the size of the type in bytes. @@ -260,7 +267,8 @@ public: lldb::Format GetFormat() const; - llvm::Optional GetTypeBitAlign(ExecutionContextScope *exe_scope) const; + llvm::Optional + GetTypeBitAlign(ExecutionContextScope *exe_scope) const; uint32_t GetNumChildren(bool omit_empty_base_classes, const ExecutionContext *exe_ctx) const; @@ -269,12 +277,11 @@ public: static lldb::BasicType GetBasicTypeEnumeration(ConstString name); - // If this type is an enumeration, iterate through all of its enumerators - // using a callback. If the callback returns true, keep iterating, else abort - // the iteration. + /// If this type is an enumeration, iterate through all of its enumerators + /// using a callback. If the callback returns true, keep iterating, else abort + /// the iteration. void ForEachEnumerator( - std::function const &callback) const; uint32_t GetNumFields() const; @@ -309,17 +316,17 @@ public: bool &child_is_deref_of_parent, ValueObject *valobj, uint64_t &language_flags) const; - // Lookup a child given a name. This function will match base class names and - // member member names in "clang_type" only, not descendants. + /// 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(const char *name, bool omit_empty_base_classes) const; - // 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. + /// 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(const char *name, bool omit_empty_base_classes, std::vector &child_indexes) const; @@ -329,7 +336,7 @@ public: lldb::TemplateArgumentKind GetTemplateArgumentKind(size_t idx) const; CompilerType GetTypeTemplateArgument(size_t idx) const; - // Returns the value of the template argument and its type. + /// Returns the value of the template argument and its type. llvm::Optional GetIntegralTemplateArgument(size_t idx) const; @@ -338,9 +345,10 @@ public: LazyBool ShouldPrintAsOneLiner(ValueObject *valobj) const; bool IsMeaninglessWithoutDynamicResolution() const; + /// \} - // Dumping types - + /// Dumping types. + /// \{ #ifndef NDEBUG /// Convenience LLVM-style dump method for use in the debugger only. /// Don't call this function from actual code. @@ -362,19 +370,33 @@ public: const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size); - void DumpTypeDescription() const; // Dump to stdout + /// Dump to stdout. + void DumpTypeDescription(lldb::DescriptionLevel level = + lldb::eDescriptionLevelFull) const; - void DumpTypeDescription(Stream *s) const; + /// Print a description of the type to a stream. The exact implementation + /// varies, but the expectation is that eDescriptionLevelFull returns a + /// source-like representation of the type, whereas eDescriptionLevelVerbose + /// does a dump of the underlying AST if applicable. + void DumpTypeDescription(Stream *s, lldb::DescriptionLevel level = + lldb::eDescriptionLevelFull) const; + /// \} bool GetValueAsScalar(const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, Scalar &value) const; - void Clear() { m_type = nullptr; m_type_system = nullptr; } private: +#ifndef NDEBUG + /// If the type is valid, ask the TypeSystem to verify the integrity + /// of the type to catch CompilerTypes that mix and match invalid + /// TypeSystem/Opaque type pairs. + bool Verify() const; +#endif + lldb::opaque_compiler_type_t m_type = nullptr; TypeSystem *m_type_system = nullptr; }; @@ -389,4 +411,4 @@ struct CompilerType::IntegralTemplateArgument { } // namespace lldb_private -#endif // liblldb_CompilerType_h_ +#endif // LLDB_SYMBOL_COMPILERTYPE_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/DWARFCallFrameInfo.h b/gnu/llvm/lldb/include/lldb/Symbol/DWARFCallFrameInfo.h index 104075f28df..f85bc7e844a 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/DWARFCallFrameInfo.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/DWARFCallFrameInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFCallFrameInfo_h_ -#define liblldb_DWARFCallFrameInfo_h_ +#ifndef LLDB_SYMBOL_DWARFCALLFRAMEINFO_H +#define LLDB_SYMBOL_DWARFCALLFRAMEINFO_H #include #include @@ -166,4 +166,4 @@ private: } // namespace lldb_private -#endif // liblldb_DWARFCallFrameInfo_h_ +#endif // LLDB_SYMBOL_DWARFCALLFRAMEINFO_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/DebugMacros.h b/gnu/llvm/lldb/include/lldb/Symbol/DebugMacros.h index da46c8b23c1..0ea70f5deb8 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/DebugMacros.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/DebugMacros.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DebugMacros_h_ -#define liblldb_DebugMacros_h_ +#ifndef LLDB_SYMBOL_DEBUGMACROS_H +#define LLDB_SYMBOL_DEBUGMACROS_H #include #include @@ -27,7 +27,6 @@ public: INVALID, DEFINE, UNDEF, START_FILE, END_FILE, INDIRECT }; -public: static DebugMacroEntry CreateDefineEntry(uint32_t line, const char *str); static DebugMacroEntry CreateUndefEntry(uint32_t line, const char *str); @@ -89,11 +88,12 @@ public: } private: - DISALLOW_COPY_AND_ASSIGN(DebugMacros); + DebugMacros(const DebugMacros &) = delete; + const DebugMacros &operator=(const DebugMacros &) = delete; std::vector m_macro_entries; }; } // namespace lldb_private -#endif // liblldb_DebugMacros_h_ +#endif // LLDB_SYMBOL_DEBUGMACROS_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/DeclVendor.h b/gnu/llvm/lldb/include/lldb/Symbol/DeclVendor.h index 748c0c8ac96..67dcaf1734b 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/DeclVendor.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/DeclVendor.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DeclVendor_h_ -#define liblldb_DeclVendor_h_ +#ifndef LLDB_SYMBOL_DECLVENDOR_H +#define LLDB_SYMBOL_DECLVENDOR_H #include "lldb/lldb-defines.h" @@ -67,7 +67,8 @@ public: private: // For DeclVendor only - DISALLOW_COPY_AND_ASSIGN(DeclVendor); + DeclVendor(const DeclVendor &) = delete; + const DeclVendor &operator=(const DeclVendor &) = delete; const DeclVendorKind m_kind; }; diff --git a/gnu/llvm/lldb/include/lldb/Symbol/Declaration.h b/gnu/llvm/lldb/include/lldb/Symbol/Declaration.h index a751d6ba039..7f19f45411a 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/Declaration.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/Declaration.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Declaration_h_ -#define liblldb_Declaration_h_ +#ifndef LLDB_SYMBOL_DECLARATION_H +#define LLDB_SYMBOL_DECLARATION_H #include "lldb/Utility/FileSpec.h" #include "lldb/lldb-private.h" @@ -202,4 +202,4 @@ bool operator==(const Declaration &lhs, const Declaration &rhs); } // namespace lldb_private -#endif // liblldb_Declaration_h_ +#endif // LLDB_SYMBOL_DECLARATION_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/FuncUnwinders.h b/gnu/llvm/lldb/include/lldb/Symbol/FuncUnwinders.h index c49f6b0fa94..2e841b3b34b 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/FuncUnwinders.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/FuncUnwinders.h @@ -1,5 +1,5 @@ -#ifndef liblldb_FuncUnwinders_h -#define liblldb_FuncUnwinders_h +#ifndef LLDB_SYMBOL_FUNCUNWINDERS_H +#define LLDB_SYMBOL_FUNCUNWINDERS_H #include "lldb/Core/AddressRange.h" #include "lldb/lldb-private-enumerations.h" @@ -149,10 +149,11 @@ private: Address m_first_non_prologue_insn; - DISALLOW_COPY_AND_ASSIGN(FuncUnwinders); + FuncUnwinders(const FuncUnwinders &) = delete; + const FuncUnwinders &operator=(const FuncUnwinders &) = delete; }; // class FuncUnwinders } // namespace lldb_private -#endif // liblldb_FuncUnwinders_h +#endif // LLDB_SYMBOL_FUNCUNWINDERS_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/Function.h b/gnu/llvm/lldb/include/lldb/Symbol/Function.h index f675b5fdffa..300d829219d 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/Function.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/Function.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Function_h_ -#define liblldb_Function_h_ +#ifndef LLDB_SYMBOL_FUNCTION_H +#define LLDB_SYMBOL_FUNCTION_H #include "lldb/Core/AddressRange.h" #include "lldb/Core/Mangled.h" @@ -17,6 +17,8 @@ #include "lldb/Utility/UserID.h" #include "llvm/ADT/ArrayRef.h" +#include + namespace lldb_private { class ExecutionContext; @@ -113,10 +115,11 @@ public: virtual size_t MemorySize() const; protected: - // Member variables. - ConstString m_name; ///< Function method name (not a mangled name). - Declaration m_declaration; ///< Information describing where this function - ///information was defined. + /// Function method name (not a mangled name). + ConstString m_name; + + /// Information describing where this function information was defined. + Declaration m_declaration; }; /// \class InlineFunctionInfo Function.h "lldb/Symbol/Function.h" @@ -199,11 +202,11 @@ public: /// The stream to which to dump the object description. void Dump(Stream *s, bool show_fullpaths) const; - void DumpStopContext(Stream *s, lldb::LanguageType language) const; + void DumpStopContext(Stream *s) const; - ConstString GetName(lldb::LanguageType language) const; + ConstString GetName() const; - ConstString GetDisplayName(lldb::LanguageType language) const; + ConstString GetDisplayName() const; /// Get accessor for the call site declaration information. /// @@ -240,9 +243,10 @@ public: size_t MemorySize() const override; private: - // Member variables. - Mangled m_mangled; ///< Mangled inlined function name (can be empty if there - ///is no mangled information). + /// Mangled inlined function name (can be empty if there is no mangled + /// information). + Mangled m_mangled; + Declaration m_call_decl; }; @@ -266,6 +270,7 @@ using CallSiteParameterArray = llvm::SmallVector; /// in the call graph between two functions, or to evaluate DW_OP_entry_value. class CallEdge { public: + enum class AddrType : uint8_t { Call, AfterCall }; virtual ~CallEdge() {} /// Get the callee's definition. @@ -281,23 +286,50 @@ public: /// 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; } + /// Return an address in the caller. This can either be the address of the + /// call instruction, or the address of the instruction after the call. + std::pair GetCallerAddress(Function &caller, + Target &target) const { + return {caller_address_type, + GetLoadAddress(caller_address, caller, target)}; + } + + bool IsTailCall() const { return is_tail_call; } /// Get the call site parameters available at this call edge. llvm::ArrayRef GetCallSiteParameters() const { return parameters; } + /// Non-tail-calls go first, sorted by the return address. They are followed + /// by tail calls, which have no specific order. + std::pair GetSortKey() const { + return {is_tail_call, GetUnresolvedReturnPCAddress()}; + } + protected: - CallEdge(lldb::addr_t return_pc, CallSiteParameterArray &¶meters) - : return_pc(return_pc), parameters(std::move(parameters)) {} + CallEdge(AddrType caller_address_type, lldb::addr_t caller_address, + bool is_tail_call, CallSiteParameterArray &¶meters) + : caller_address(caller_address), + caller_address_type(caller_address_type), is_tail_call(is_tail_call), + parameters(std::move(parameters)) {} + + /// Helper that finds the load address of \p unresolved_pc, a file address + /// which refers to an instruction within \p caller. + static lldb::addr_t GetLoadAddress(lldb::addr_t unresolved_pc, + Function &caller, Target &target); + + /// Like \ref GetReturnPCAddress, but returns an unresolved file address. + lldb::addr_t GetUnresolvedReturnPCAddress() const { + return caller_address_type == AddrType::AfterCall && !is_tail_call + ? caller_address + : LLDB_INVALID_ADDRESS; + } - /// 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; +private: + lldb::addr_t caller_address; + AddrType caller_address_type; + bool is_tail_call; CallSiteParameterArray parameters; }; @@ -309,9 +341,11 @@ class DirectCallEdge : public CallEdge { public: /// Construct a call edge using a symbol name to identify the callee, and a /// return PC within the calling function to identify a specific call site. - DirectCallEdge(const char *symbol_name, lldb::addr_t return_pc, + DirectCallEdge(const char *symbol_name, AddrType caller_address_type, + lldb::addr_t caller_address, bool is_tail_call, CallSiteParameterArray &¶meters) - : CallEdge(return_pc, std::move(parameters)) { + : CallEdge(caller_address_type, caller_address, is_tail_call, + std::move(parameters)) { lazy_callee.symbol_name = symbol_name; } @@ -340,9 +374,11 @@ class IndirectCallEdge : public CallEdge { public: /// Construct a call edge using a DWARFExpression to identify the callee, and /// a return PC within the calling function to identify a specific call site. - IndirectCallEdge(DWARFExpression call_target, lldb::addr_t return_pc, + IndirectCallEdge(DWARFExpression call_target, AddrType caller_address_type, + lldb::addr_t caller_address, bool is_tail_call, CallSiteParameterArray &¶meters) - : CallEdge(return_pc, std::move(parameters)), + : CallEdge(caller_address_type, caller_address, is_tail_call, + std::move(parameters)), call_target(std::move(call_target)) {} Function *GetCallee(ModuleList &images, ExecutionContext &exe_ctx) override; @@ -602,34 +638,55 @@ public: protected: enum { - flagsCalculatedPrologueSize = - (1 << 0) ///< Have we already tried to calculate the prologue size? + /// Whether we already tried to calculate the prologue size. + flagsCalculatedPrologueSize = (1 << 0) }; - // Member variables. - CompileUnit *m_comp_unit; ///< The compile unit that owns this function. - lldb::user_id_t - m_type_uid; ///< The user ID of for the prototype Type for this function. - Type *m_type; ///< The function prototype type for this function that include - ///the function info (FunctionInfo), return type and parameters. - Mangled m_mangled; ///< The mangled function name if any, if empty, there is - ///no mangled information. - Block m_block; ///< All lexical blocks contained in this function. - AddressRange m_range; ///< The function address range that covers the widest - ///range needed to contain all blocks - DWARFExpression m_frame_base; ///< The frame base expression for variables - ///that are relative to the frame pointer. + /// The compile unit that owns this function. + CompileUnit *m_comp_unit; + + /// The user ID of for the prototype Type for this function. + lldb::user_id_t m_type_uid; + + /// The function prototype type for this function that includes the function + /// info (FunctionInfo), return type and parameters. + Type *m_type; + + /// The mangled function name if any. If empty, there is no mangled + /// information. + Mangled m_mangled; + + /// All lexical blocks contained in this function. + Block m_block; + + /// The function address range that covers the widest range needed to contain + /// all blocks + AddressRange m_range; + + /// The frame base expression for variables that are relative to the frame + /// pointer. + DWARFExpression m_frame_base; + 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. + /// Compute the prologue size once and cache it. + uint32_t m_prologue_byte_size; + + /// Exclusive lock that controls read/write access to m_call_edges and + /// m_call_edges_resolved. + std::mutex m_call_edges_lock; + + /// Whether call site info has been parsed. + bool m_call_edges_resolved = false; + + /// Outgoing call edges. + std::vector> m_call_edges; + private: - DISALLOW_COPY_AND_ASSIGN(Function); + Function(const Function &) = delete; + const Function &operator=(const Function &) = delete; }; } // namespace lldb_private -#endif // liblldb_Function_h_ +#endif // LLDB_SYMBOL_FUNCTION_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/LineEntry.h b/gnu/llvm/lldb/include/lldb/Symbol/LineEntry.h index 32ffef72ee5..7e56ef81476 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/LineEntry.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/LineEntry.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_LineEntry_h_ -#define liblldb_LineEntry_h_ +#ifndef LLDB_SYMBOL_LINEENTRY_H +#define LLDB_SYMBOL_LINEENTRY_H #include "lldb/Core/AddressRange.h" #include "lldb/Utility/FileSpec.h" @@ -118,7 +118,7 @@ struct LineEntry { /// range. /// /// If the initial LineEntry this method is called on is a line #0, only the - /// range of contiuous LineEntries with line #0 will be included in the + /// range of continuous LineEntries with line #0 will be included in the /// complete range. /// /// @param[in] include_inlined_functions @@ -173,4 +173,4 @@ bool operator<(const LineEntry &lhs, const LineEntry &rhs); } // namespace lldb_private -#endif // liblldb_LineEntry_h_ +#endif // LLDB_SYMBOL_LINEENTRY_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/LineTable.h b/gnu/llvm/lldb/include/lldb/Symbol/LineTable.h index 043f3eb895c..d66b58ca4c6 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/LineTable.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/LineTable.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_LineTable_h_ -#define liblldb_LineTable_h_ +#ifndef LLDB_SYMBOL_LINETABLE_H +#define LLDB_SYMBOL_LINETABLE_H #include "lldb/Core/ModuleChild.h" #include "lldb/Core/Section.h" @@ -29,7 +29,8 @@ public: virtual void Clear() = 0; private: - DISALLOW_COPY_AND_ASSIGN(LineSequence); + LineSequence(const LineSequence &) = delete; + const LineSequence &operator=(const LineSequence &) = delete; }; /// \class LineTable LineTable.h "lldb/Symbol/LineTable.h" @@ -42,6 +43,13 @@ public: /// The compile unit to which this line table belongs. LineTable(CompileUnit *comp_unit); + /// Construct with entries found in \a sequences. + /// + /// \param[in] sequences + /// Unsorted list of line sequences. + LineTable(CompileUnit *comp_unit, + std::vector> &&sequences); + /// Destructor. ~LineTable(); @@ -64,11 +72,11 @@ public: bool is_epilogue_begin, bool is_terminal_entry); // Used to instantiate the LineSequence helper class - LineSequence *CreateLineSequenceContainer(); + static std::unique_ptr CreateLineSequenceContainer(); // Append an entry to a caller-provided collection that will later be // inserted in this line table. - void AppendLineEntryToSequence(LineSequence *sequence, lldb::addr_t file_addr, + static void AppendLineEntryToSequence(LineSequence *sequence, 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, @@ -176,7 +184,7 @@ public: /// The number of line table entries in this line table. uint32_t GetSize() const; - typedef lldb_private::RangeArray + typedef lldb_private::RangeVector FileAddressRanges; /// Gets all contiguous file address ranges for the entire line table. @@ -259,6 +267,8 @@ protected: public: LessThanBinaryPredicate(LineTable *line_table); bool operator()(const LineTable::Entry &, const LineTable::Entry &) const; + bool operator()(const std::unique_ptr &, + const std::unique_ptr &) const; protected: LineTable *m_line_table; @@ -328,9 +338,10 @@ protected: bool ConvertEntryAtIndexToLineEntry(uint32_t idx, LineEntry &line_entry); private: - DISALLOW_COPY_AND_ASSIGN(LineTable); + LineTable(const LineTable &) = delete; + const LineTable &operator=(const LineTable &) = delete; }; } // namespace lldb_private -#endif // liblldb_LineTable_h_ +#endif // LLDB_SYMBOL_LINETABLE_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/LocateSymbolFile.h b/gnu/llvm/lldb/include/lldb/Symbol/LocateSymbolFile.h index 0ff834df9c4..93b76e53f41 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/LocateSymbolFile.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/LocateSymbolFile.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Symbols_h_ -#define liblldb_Symbols_h_ +#ifndef LLDB_SYMBOL_LOCATESYMBOLFILE_H +#define LLDB_SYMBOL_LOCATESYMBOLFILE_H #include @@ -55,4 +55,4 @@ public: } // namespace lldb_private -#endif // liblldb_Symbols_h_ +#endif // LLDB_SYMBOL_LOCATESYMBOLFILE_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/ObjectContainer.h b/gnu/llvm/lldb/include/lldb/Symbol/ObjectContainer.h index 9310fdc18d9..1e01e93da9d 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/ObjectContainer.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/ObjectContainer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ObjectContainer_h_ -#define liblldb_ObjectContainer_h_ +#ifndef LLDB_SYMBOL_OBJECTCONTAINER_H +#define LLDB_SYMBOL_OBJECTCONTAINER_H #include "lldb/Core/ModuleChild.h" #include "lldb/Core/PluginInterface.h" @@ -167,9 +167,10 @@ protected: m_data; ///< The data for this object file so things can be parsed lazily. private: - DISALLOW_COPY_AND_ASSIGN(ObjectContainer); + ObjectContainer(const ObjectContainer &) = delete; + const ObjectContainer &operator=(const ObjectContainer &) = delete; }; } // namespace lldb_private -#endif // liblldb_ObjectContainer_h_ +#endif // LLDB_SYMBOL_OBJECTCONTAINER_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/ObjectFile.h b/gnu/llvm/lldb/include/lldb/Symbol/ObjectFile.h index 841a38e5b15..e814015c0bf 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/ObjectFile.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/ObjectFile.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ObjectFile_h_ -#define liblldb_ObjectFile_h_ +#ifndef LLDB_SYMBOL_OBJECTFILE_H +#define LLDB_SYMBOL_OBJECTFILE_H #include "lldb/Core/FileSpecList.h" #include "lldb/Core/ModuleChild.h" @@ -172,10 +172,10 @@ public: lldb::addr_t header_addr, lldb::DataBufferSP &file_data_sp); - static size_t GetModuleSpecifications(const FileSpec &file, - lldb::offset_t file_offset, - lldb::offset_t file_size, - ModuleSpecList &specs); + static size_t + GetModuleSpecifications(const FileSpec &file, lldb::offset_t file_offset, + lldb::offset_t file_size, ModuleSpecList &specs, + lldb::DataBufferSP data_sp = lldb::DataBufferSP()); static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp, @@ -686,7 +686,8 @@ protected: uint64_t Offset); private: - DISALLOW_COPY_AND_ASSIGN(ObjectFile); + ObjectFile(const ObjectFile &) = delete; + const ObjectFile &operator=(const ObjectFile &) = delete; }; } // namespace lldb_private @@ -703,4 +704,4 @@ template <> struct format_provider { }; } // namespace llvm -#endif // liblldb_ObjectFile_h_ +#endif // LLDB_SYMBOL_OBJECTFILE_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/SourceModule.h b/gnu/llvm/lldb/include/lldb/Symbol/SourceModule.h index b12ff01a519..7799b6504b1 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/SourceModule.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/SourceModule.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SourceModule_h_ -#define liblldb_SourceModule_h_ +#ifndef LLDB_SYMBOL_SOURCEMODULE_H +#define LLDB_SYMBOL_SOURCEMODULE_H #include "lldb/Utility/ConstString.h" #include diff --git a/gnu/llvm/lldb/include/lldb/Symbol/Symbol.h b/gnu/llvm/lldb/include/lldb/Symbol/Symbol.h index 36f89c044ea..3a235f260ba 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/Symbol.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/Symbol.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Symbol_h_ -#define liblldb_Symbol_h_ +#ifndef LLDB_SYMBOL_SYMBOL_H +#define LLDB_SYMBOL_SYMBOL_H #include "lldb/Core/AddressRange.h" #include "lldb/Core/Mangled.h" @@ -267,4 +267,4 @@ protected: } // namespace lldb_private -#endif // liblldb_Symbol_h_ +#endif // LLDB_SYMBOL_SYMBOL_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/SymbolContext.h b/gnu/llvm/lldb/include/lldb/Symbol/SymbolContext.h index 4c7b727fe61..cc49ce51c71 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/SymbolContext.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/SymbolContext.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SymbolContext_h_ -#define liblldb_SymbolContext_h_ +#ifndef LLDB_SYMBOL_SYMBOLCONTEXT_H +#define LLDB_SYMBOL_SYMBOLCONTEXT_H #include #include @@ -475,4 +475,4 @@ bool operator!=(const SymbolContextList &lhs, const SymbolContextList &rhs); } // namespace lldb_private -#endif // liblldb_SymbolContext_h_ +#endif // LLDB_SYMBOL_SYMBOLCONTEXT_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/SymbolContextScope.h b/gnu/llvm/lldb/include/lldb/Symbol/SymbolContextScope.h index a626302053d..3b244caed33 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/SymbolContextScope.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/SymbolContextScope.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SymbolContextScope_h_ -#define liblldb_SymbolContextScope_h_ +#ifndef LLDB_SYMBOL_SYMBOLCONTEXTSCOPE_H +#define LLDB_SYMBOL_SYMBOLCONTEXTSCOPE_H #include "lldb/lldb-private.h" @@ -100,4 +100,4 @@ public: } // namespace lldb_private -#endif // liblldb_SymbolContextScope_h_ +#endif // LLDB_SYMBOL_SYMBOLCONTEXTSCOPE_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/SymbolFile.h b/gnu/llvm/lldb/include/lldb/Symbol/SymbolFile.h index fdd812eb516..9f5806915dc 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/SymbolFile.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/SymbolFile.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SymbolFile_h_ -#define liblldb_SymbolFile_h_ +#ifndef LLDB_SYMBOL_SYMBOLFILE_H +#define LLDB_SYMBOL_SYMBOLFILE_H #include "lldb/Core/PluginInterface.h" #include "lldb/Symbol/CompilerDecl.h" @@ -18,6 +18,7 @@ #include "lldb/Symbol/Type.h" #include "lldb/Symbol/TypeList.h" #include "lldb/Symbol/TypeSystem.h" +#include "lldb/Utility/XcodeSDK.h" #include "lldb/lldb-private.h" #include "llvm/ADT/DenseSet.h" #include "llvm/Support/Errc.h" @@ -128,6 +129,8 @@ public: Symtab *GetSymtab(); virtual lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) = 0; + /// Return the Xcode SDK comp_unit was compiled against. + virtual XcodeSDK ParseXcodeSDK(CompileUnit &comp_unit) { return {}; } virtual size_t ParseFunctions(CompileUnit &comp_unit) = 0; virtual bool ParseLineTable(CompileUnit &comp_unit) = 0; virtual bool ParseDebugMacros(CompileUnit &comp_unit) = 0; @@ -136,12 +139,16 @@ public: /// \p comp_unit. Recursively also descends into the referenced external /// modules of any encountered compilation unit. /// + /// This function can be used to traverse Clang -gmodules debug + /// information, which is stored in DWARF files separate from the + /// object files. + /// /// \param comp_unit /// When this SymbolFile consists of multiple auxilliary /// SymbolFiles, for example, a Darwin debug map that references /// multiple .o files, comp_unit helps choose the auxilliary /// file. In most other cases comp_unit's symbol file is - /// identiacal with *this. + /// identical with *this. /// /// \param[in] lambda /// The lambda that should be applied to every function. The lambda can @@ -182,7 +189,7 @@ public: }; /// 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 + /// optional \p ExecutionContext. 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, @@ -208,21 +215,21 @@ public: SymbolContextList &sc_list); virtual void DumpClangAST(Stream &s) {} - virtual void - FindGlobalVariables(ConstString name, - const CompilerDeclContext *parent_decl_ctx, - uint32_t max_matches, VariableList &variables); + virtual void FindGlobalVariables(ConstString name, + const CompilerDeclContext &parent_decl_ctx, + uint32_t max_matches, + VariableList &variables); virtual void FindGlobalVariables(const RegularExpression ®ex, uint32_t max_matches, VariableList &variables); virtual void FindFunctions(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, lldb::FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list); virtual void FindFunctions(const RegularExpression ®ex, bool include_inlines, SymbolContextList &sc_list); virtual void - FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx, + FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types); @@ -251,8 +258,7 @@ public: GetTypeSystemForLanguage(lldb::LanguageType language); virtual CompilerDeclContext - FindNamespace(ConstString name, - const CompilerDeclContext *parent_decl_ctx) { + FindNamespace(ConstString name, const CompilerDeclContext &parent_decl_ctx) { return CompilerDeclContext(); } @@ -311,9 +317,10 @@ protected: bool m_calculated_abilities; private: - DISALLOW_COPY_AND_ASSIGN(SymbolFile); + SymbolFile(const SymbolFile &) = delete; + const SymbolFile &operator=(const SymbolFile &) = delete; }; } // namespace lldb_private -#endif // liblldb_SymbolFile_h_ +#endif // LLDB_SYMBOL_SYMBOLFILE_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/SymbolVendor.h b/gnu/llvm/lldb/include/lldb/Symbol/SymbolVendor.h index 96c6ea5c733..c9c59a3fc1b 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/SymbolVendor.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/SymbolVendor.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SymbolVendor_h_ -#define liblldb_SymbolVendor_h_ +#ifndef LLDB_SYMBOL_SYMBOLVENDOR_H +#define LLDB_SYMBOL_SYMBOLVENDOR_H #include @@ -52,9 +52,10 @@ protected: private: // For SymbolVendor only - DISALLOW_COPY_AND_ASSIGN(SymbolVendor); + SymbolVendor(const SymbolVendor &) = delete; + const SymbolVendor &operator=(const SymbolVendor &) = delete; }; } // namespace lldb_private -#endif // liblldb_SymbolVendor_h_ +#endif // LLDB_SYMBOL_SYMBOLVENDOR_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/Symtab.h b/gnu/llvm/lldb/include/lldb/Symbol/Symtab.h index f121bef1bfb..c232925eec7 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/Symtab.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/Symtab.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Symtab_h_ -#define liblldb_Symtab_h_ +#ifndef LLDB_SYMBOL_SYMTAB_H +#define LLDB_SYMBOL_SYMTAB_H #include "lldb/Core/UniqueCStringMap.h" #include "lldb/Symbol/Symbol.h" @@ -224,9 +224,10 @@ private: const char *decl_context, const std::set &class_contexts); - DISALLOW_COPY_AND_ASSIGN(Symtab); + Symtab(const Symtab &) = delete; + const Symtab &operator=(const Symtab &) = delete; }; } // namespace lldb_private -#endif // liblldb_Symtab_h_ +#endif // LLDB_SYMBOL_SYMTAB_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/TaggedASTType.h b/gnu/llvm/lldb/include/lldb/Symbol/TaggedASTType.h index 043a9138e07..f02f99258a3 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/TaggedASTType.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/TaggedASTType.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_TaggedASTType_h_ -#define liblldb_TaggedASTType_h_ +#ifndef LLDB_SYMBOL_TAGGEDASTTYPE_H +#define LLDB_SYMBOL_TAGGEDASTTYPE_H #include "lldb/Symbol/CompilerType.h" diff --git a/gnu/llvm/lldb/include/lldb/Symbol/Type.h b/gnu/llvm/lldb/include/lldb/Symbol/Type.h index 95a3bc49751..8735d016bb2 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/Type.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/Type.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Type_h_ -#define liblldb_Type_h_ +#ifndef LLDB_SYMBOL_TYPE_H +#define LLDB_SYMBOL_TYPE_H #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerType.h" @@ -97,13 +97,14 @@ public: llvm::Optional byte_size, SymbolContextScope *context, lldb::user_id_t encoding_uid, EncodingDataType encoding_uid_type, const Declaration &decl, const CompilerType &compiler_qual_type, - ResolveState compiler_type_resolve_state); + ResolveState compiler_type_resolve_state, uint32_t opaque_payload = 0); // This makes an invalid type. Used for functions that return a Type when // they get an error. Type(); - void Dump(Stream *s, bool show_context); + void Dump(Stream *s, bool show_context, + lldb::DescriptionLevel level = lldb::eDescriptionLevelFull); void DumpTypeName(Stream *s); @@ -196,11 +197,11 @@ public: uint32_t GetEncodingMask(); - bool IsCompleteObjCClass() { return m_is_complete_objc_class; } - - void SetIsCompleteObjCClass(bool is_complete_objc_class) { - m_is_complete_objc_class = is_complete_objc_class; - } + typedef uint32_t Payload; + /// Return the language-specific payload. + Payload GetPayload() { return m_payload; } + /// Return the language-specific payload. + void SetPayload(Payload opaque_payload) { m_payload = opaque_payload; } protected: ConstString m_name; @@ -215,11 +216,12 @@ protected: Declaration m_decl; CompilerType m_compiler_type; ResolveState m_compiler_type_resolve_state; - bool m_is_complete_objc_class; + /// Language-specific flags. + Payload m_payload; Type *GetEncodingType(); - bool ResolveClangType(ResolveState compiler_type_resolve_state); + bool ResolveCompilerType(ResolveState compiler_type_resolve_state); }; // the two classes here are used by the public API as a backend to the SBType @@ -510,4 +512,4 @@ private: } // namespace lldb_private -#endif // liblldb_Type_h_ +#endif // LLDB_SYMBOL_TYPE_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/TypeList.h b/gnu/llvm/lldb/include/lldb/Symbol/TypeList.h index 38342b6d6f4..03390858025 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/TypeList.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/TypeList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_TypeList_h_ -#define liblldb_TypeList_h_ +#ifndef LLDB_SYMBOL_TYPELIST_H +#define LLDB_SYMBOL_TYPELIST_H #include "lldb/Symbol/Type.h" #include "lldb/Utility/Iterable.h" @@ -63,9 +63,10 @@ private: collection m_types; - DISALLOW_COPY_AND_ASSIGN(TypeList); + TypeList(const TypeList &) = delete; + const TypeList &operator=(const TypeList &) = delete; }; } // namespace lldb_private -#endif // liblldb_TypeList_h_ +#endif // LLDB_SYMBOL_TYPELIST_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/TypeMap.h b/gnu/llvm/lldb/include/lldb/Symbol/TypeMap.h index e7d2b254cbf..ede54c1a09d 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/TypeMap.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/TypeMap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_TypeMap_h_ -#define liblldb_TypeMap_h_ +#ifndef LLDB_SYMBOL_TYPEMAP_H +#define LLDB_SYMBOL_TYPEMAP_H #include "lldb/Symbol/Type.h" #include "lldb/Utility/Iterable.h" @@ -26,7 +26,8 @@ public: void Clear(); - void Dump(Stream *s, bool show_context); + void Dump(Stream *s, bool show_context, + lldb::DescriptionLevel level = lldb::eDescriptionLevelFull); TypeMap FindTypes(ConstString name); @@ -66,9 +67,10 @@ private: collection m_types; - DISALLOW_COPY_AND_ASSIGN(TypeMap); + TypeMap(const TypeMap &) = delete; + const TypeMap &operator=(const TypeMap &) = delete; }; } // namespace lldb_private -#endif // liblldb_TypeMap_h_ +#endif // LLDB_SYMBOL_TYPEMAP_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/TypeSystem.h b/gnu/llvm/lldb/include/lldb/Symbol/TypeSystem.h index 91f751acf6c..e188f29354b 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/TypeSystem.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/TypeSystem.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_TypeSystem_h_ -#define liblldb_TypeSystem_h_ +#ifndef LLDB_SYMBOL_TYPESYSTEM_H +#define LLDB_SYMBOL_TYPESYSTEM_H #include #include @@ -129,6 +129,11 @@ public: void *other_opaque_decl_ctx) = 0; // Tests +#ifndef NDEBUG + /// Verify the integrity of the type to catch CompilerTypes that mix + /// and match invalid TypeSystem/Opaque type pairs. + virtual bool Verify(lldb::opaque_compiler_type_t type) = 0; +#endif virtual bool IsArrayType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size, @@ -199,6 +204,8 @@ public: virtual ConstString GetTypeName(lldb::opaque_compiler_type_t type) = 0; + virtual ConstString GetDisplayTypeName(lldb::opaque_compiler_type_t type) = 0; + virtual uint32_t GetTypeInfo(lldb::opaque_compiler_type_t type, CompilerType *pointee_or_element_compiler_type) = 0; @@ -252,9 +259,12 @@ public: virtual CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type); + /// \param opaque_payload The m_payload field of Type, which may + /// carry TypeSystem-specific extra information. virtual CompilerType CreateTypedef(lldb::opaque_compiler_type_t type, const char *name, - const CompilerDeclContext &decl_ctx); + const CompilerDeclContext &decl_ctx, + uint32_t opaque_payload); // Exploring the type @@ -364,11 +374,18 @@ public: uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope) = 0; - virtual void - DumpTypeDescription(lldb::opaque_compiler_type_t type) = 0; // Dump to stdout + /// Dump the type to stdout. + virtual void DumpTypeDescription( + lldb::opaque_compiler_type_t type, + lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) = 0; - virtual void DumpTypeDescription(lldb::opaque_compiler_type_t type, - Stream *s) = 0; + /// Print a description of the type to a stream. The exact implementation + /// varies, but the expectation is that eDescriptionLevelFull returns a + /// source-like representation of the type, whereas eDescriptionLevelVerbose + /// does a dump of the underlying AST if applicable. + virtual void DumpTypeDescription( + lldb::opaque_compiler_type_t type, Stream *s, + lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) = 0; // TODO: These methods appear unused. Should they be removed? @@ -380,7 +397,7 @@ public: lldb::offset_t data_offset, size_t data_byte_size) = 0; - // TODO: Determine if these methods should move to ClangASTContext. + // TODO: Determine if these methods should move to TypeSystemClang. virtual bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type) = 0; @@ -509,4 +526,4 @@ protected: } // namespace lldb_private -#endif // liblldb_TypeSystem_h_ +#endif // LLDB_SYMBOL_TYPESYSTEM_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/UnwindPlan.h b/gnu/llvm/lldb/include/lldb/Symbol/UnwindPlan.h index fa41ba5d056..8902b5f4eaa 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/UnwindPlan.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/UnwindPlan.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_UnwindPlan_h -#define liblldb_UnwindPlan_h +#ifndef LLDB_SYMBOL_UNWINDPLAN_H +#define LLDB_SYMBOL_UNWINDPLAN_H #include #include @@ -320,7 +320,6 @@ public: } m_value; }; // class FAValue - public: Row(); Row(const UnwindPlan::Row &rhs) = default; @@ -375,7 +374,6 @@ public: collection m_register_locations; }; // class Row -public: typedef std::shared_ptr RowSP; UnwindPlan(lldb::RegisterKind reg_kind) @@ -540,4 +538,4 @@ private: } // namespace lldb_private -#endif // liblldb_UnwindPlan_h +#endif // LLDB_SYMBOL_UNWINDPLAN_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/UnwindTable.h b/gnu/llvm/lldb/include/lldb/Symbol/UnwindTable.h index c1dc519c4b2..9548b1f3fce 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/UnwindTable.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/UnwindTable.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_UnwindTable_h -#define liblldb_UnwindTable_h +#ifndef LLDB_SYMBOL_UNWINDTABLE_H +#define LLDB_SYMBOL_UNWINDTABLE_H #include #include @@ -79,9 +79,10 @@ private: std::unique_ptr m_compact_unwind_up; std::unique_ptr m_arm_unwind_up; - DISALLOW_COPY_AND_ASSIGN(UnwindTable); + UnwindTable(const UnwindTable &) = delete; + const UnwindTable &operator=(const UnwindTable &) = delete; }; } // namespace lldb_private -#endif // liblldb_UnwindTable_h +#endif // LLDB_SYMBOL_UNWINDTABLE_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/Variable.h b/gnu/llvm/lldb/include/lldb/Symbol/Variable.h index 30f57f1f911..66abdc0b311 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/Variable.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/Variable.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Variable_h_ -#define liblldb_Variable_h_ +#ifndef LLDB_SYMBOL_VARIABLE_H +#define LLDB_SYMBOL_VARIABLE_H #include "lldb/Core/Mangled.h" #include "lldb/Expression/DWARFExpression.h" @@ -141,4 +141,4 @@ private: } // namespace lldb_private -#endif // liblldb_Variable_h_ +#endif // LLDB_SYMBOL_VARIABLE_H diff --git a/gnu/llvm/lldb/include/lldb/Symbol/VariableList.h b/gnu/llvm/lldb/include/lldb/Symbol/VariableList.h index 87f98668a8a..9fea628a81b 100644 --- a/gnu/llvm/lldb/include/lldb/Symbol/VariableList.h +++ b/gnu/llvm/lldb/include/lldb/Symbol/VariableList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_VariableList_h_ -#define liblldb_VariableList_h_ +#ifndef LLDB_SYMBOL_VARIABLELIST_H +#define LLDB_SYMBOL_VARIABLELIST_H #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/Variable.h" @@ -80,9 +80,10 @@ protected: private: // For VariableList only - DISALLOW_COPY_AND_ASSIGN(VariableList); + VariableList(const VariableList &) = delete; + const VariableList &operator=(const VariableList &) = delete; }; } // namespace lldb_private -#endif // liblldb_VariableList_h_ +#endif // LLDB_SYMBOL_VARIABLELIST_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ABI.h b/gnu/llvm/lldb/include/lldb/Target/ABI.h index 1aff1e2f781..b252e4b54f0 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ABI.h +++ b/gnu/llvm/lldb/include/lldb/Target/ABI.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ABI_h_ -#define liblldb_ABI_h_ +#ifndef LLDB_TARGET_ABI_H +#define LLDB_TARGET_ABI_H #include "lldb/Core/PluginInterface.h" #include "lldb/Symbol/UnwindPlan.h" @@ -126,7 +126,7 @@ public: llvm::MCRegisterInfo &GetMCRegisterInfo() { return *m_mc_register_info_up; } - virtual void AugmentRegisterInfo(RegisterInfo &info); + virtual void AugmentRegisterInfo(RegisterInfo &info) = 0; virtual bool GetPointerReturnRegister(const char *&name) { return false; } @@ -138,10 +138,6 @@ protected: assert(m_mc_register_info_up && "ABI must have MCRegisterInfo"); } - bool GetRegisterInfoByName(ConstString name, RegisterInfo &info); - - virtual const RegisterInfo *GetRegisterInfoArray(uint32_t &count) = 0; - /// Utility function to construct a MCRegisterInfo using the ArchSpec triple. /// Plugins wishing to customize the construction can construct the /// MCRegisterInfo themselves. @@ -152,9 +148,44 @@ protected: std::unique_ptr m_mc_register_info_up; private: - DISALLOW_COPY_AND_ASSIGN(ABI); + ABI(const ABI &) = delete; + const ABI &operator=(const ABI &) = delete; +}; + +class RegInfoBasedABI : public ABI { +public: + void AugmentRegisterInfo(RegisterInfo &info) override; + +protected: + using ABI::ABI; + + bool GetRegisterInfoByName(ConstString name, RegisterInfo &info); + + virtual const RegisterInfo *GetRegisterInfoArray(uint32_t &count) = 0; +}; + +class MCBasedABI : public ABI { +public: + void AugmentRegisterInfo(RegisterInfo &info) override; + + /// If the register name is of the form "[]" then change + /// the name to "[]". Otherwise, leave the name unchanged. + static void MapRegisterName(std::string ®, llvm::StringRef from_prefix, + llvm::StringRef to_prefix); +protected: + using ABI::ABI; + + /// Return eh_frame and dwarf numbers for the given register. + virtual std::pair GetEHAndDWARFNums(llvm::StringRef reg); + + /// Return the generic number of the given register. + virtual uint32_t GetGenericNum(llvm::StringRef reg) = 0; + + /// For the given (capitalized) lldb register name, return the name of this + /// register in the MCRegisterInfo struct. + virtual std::string GetMCName(std::string reg) { return reg; } }; } // namespace lldb_private -#endif // liblldb_ABI_h_ +#endif // LLDB_TARGET_ABI_H diff --git a/gnu/llvm/lldb/include/lldb/Target/AssertFrameRecognizer.h b/gnu/llvm/lldb/include/lldb/Target/AssertFrameRecognizer.h new file mode 100644 index 00000000000..2ecc957d2a2 --- /dev/null +++ b/gnu/llvm/lldb/include/lldb/Target/AssertFrameRecognizer.h @@ -0,0 +1,54 @@ +//===-- AssertFrameRecognizer.cpp -------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_TARGET_ASSERTFRAMERECOGNIZER_H +#define LLDB_TARGET_ASSERTFRAMERECOGNIZER_H + +#include "lldb/Target/Process.h" +#include "lldb/Target/StackFrameRecognizer.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/FileSpec.h" + +#include + +namespace lldb_private { + +/// Registers the assert stack frame recognizer. +/// +/// \param[in] process +/// The process that is currently asserting. This will give us information on +/// the target and the platform. +void RegisterAssertFrameRecognizer(Process *process); + +/// \class AssertRecognizedStackFrame +/// +/// Holds the stack frame where the assert is called from. +class AssertRecognizedStackFrame : public RecognizedStackFrame { +public: + AssertRecognizedStackFrame(lldb::StackFrameSP most_relevant_frame_sp); + lldb::StackFrameSP GetMostRelevantFrame() override; + +private: + lldb::StackFrameSP m_most_relevant_frame; +}; + +/// \class AssertFrameRecognizer +/// +/// When a thread stops, it checks depending on the platform if the top frame is +/// an abort stack frame. If so, it looks for an assert stack frame in the upper +/// frames and set it as the most relavant frame when found. +class AssertFrameRecognizer : public StackFrameRecognizer { +public: + std::string GetName() override { return "Assert StackFrame Recognizer"; } + lldb::RecognizedStackFrameSP + RecognizeFrame(lldb::StackFrameSP frame_sp) override; +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_ASSERTFRAMERECOGNIZER_H diff --git a/gnu/llvm/lldb/include/lldb/Target/DynamicLoader.h b/gnu/llvm/lldb/include/lldb/Target/DynamicLoader.h index ac72b98e5e1..d3ce1b05ed5 100644 --- a/gnu/llvm/lldb/include/lldb/Target/DynamicLoader.h +++ b/gnu/llvm/lldb/include/lldb/Target/DynamicLoader.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DynamicLoader_h_ -#define liblldb_DynamicLoader_h_ +#ifndef LLDB_TARGET_DYNAMICLOADER_H +#define LLDB_TARGET_DYNAMICLOADER_H #include "lldb/Core/PluginInterface.h" #include "lldb/Utility/FileSpec.h" @@ -310,9 +310,10 @@ protected: *m_process; ///< The process that this dynamic loader plug-in is tracking. private: - DISALLOW_COPY_AND_ASSIGN(DynamicLoader); + DynamicLoader(const DynamicLoader &) = delete; + const DynamicLoader &operator=(const DynamicLoader &) = delete; }; } // namespace lldb_private -#endif // liblldb_DynamicLoader_h_ +#endif // LLDB_TARGET_DYNAMICLOADER_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ExecutionContext.h b/gnu/llvm/lldb/include/lldb/Target/ExecutionContext.h index 0819357fab3..169d56ac9b6 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ExecutionContext.h +++ b/gnu/llvm/lldb/include/lldb/Target/ExecutionContext.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ExecutionContext_h_ -#define liblldb_ExecutionContext_h_ +#ifndef LLDB_TARGET_EXECUTIONCONTEXT_H +#define LLDB_TARGET_EXECUTIONCONTEXT_H #include @@ -565,4 +565,4 @@ protected: } // namespace lldb_private -#endif // liblldb_ExecutionContext_h_ +#endif // LLDB_TARGET_EXECUTIONCONTEXT_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ExecutionContextScope.h b/gnu/llvm/lldb/include/lldb/Target/ExecutionContextScope.h index 0121ce61a1d..d7003e9a572 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ExecutionContextScope.h +++ b/gnu/llvm/lldb/include/lldb/Target/ExecutionContextScope.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ExecutionContextScope_h_ -#define liblldb_ExecutionContextScope_h_ +#ifndef LLDB_TARGET_EXECUTIONCONTEXTSCOPE_H +#define LLDB_TARGET_EXECUTIONCONTEXTSCOPE_H #include "lldb/lldb-private.h" @@ -55,4 +55,4 @@ public: } // namespace lldb_private -#endif // liblldb_ExecutionContextScope_h_ +#endif // LLDB_TARGET_EXECUTIONCONTEXTSCOPE_H diff --git a/gnu/llvm/lldb/include/lldb/Target/InstrumentationRuntime.h b/gnu/llvm/lldb/include/lldb/Target/InstrumentationRuntime.h index 4cee76d657b..dd4da26c215 100644 --- a/gnu/llvm/lldb/include/lldb/Target/InstrumentationRuntime.h +++ b/gnu/llvm/lldb/include/lldb/Target/InstrumentationRuntime.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_InstrumentationRuntime_h_ -#define liblldb_InstrumentationRuntime_h_ +#ifndef LLDB_TARGET_INSTRUMENTATIONRUNTIME_H +#define LLDB_TARGET_INSTRUMENTATIONRUNTIME_H #include #include @@ -92,4 +92,4 @@ public: } // namespace lldb_private -#endif // liblldb_InstrumentationRuntime_h_ +#endif // LLDB_TARGET_INSTRUMENTATIONRUNTIME_H diff --git a/gnu/llvm/lldb/include/lldb/Target/InstrumentationRuntimeStopInfo.h b/gnu/llvm/lldb/include/lldb/Target/InstrumentationRuntimeStopInfo.h index 6c2a8ad8741..2cbf27d7b34 100644 --- a/gnu/llvm/lldb/include/lldb/Target/InstrumentationRuntimeStopInfo.h +++ b/gnu/llvm/lldb/include/lldb/Target/InstrumentationRuntimeStopInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_InstrumentationRuntimeStopInfo_h_ -#define liblldb_InstrumentationRuntimeStopInfo_h_ +#ifndef LLDB_TARGET_INSTRUMENTATIONRUNTIMESTOPINFO_H +#define LLDB_TARGET_INSTRUMENTATIONRUNTIMESTOPINFO_H #include @@ -39,4 +39,4 @@ private: } // namespace lldb_private -#endif // liblldb_InstrumentationRuntimeStopInfo_h_ +#endif // LLDB_TARGET_INSTRUMENTATIONRUNTIMESTOPINFO_H diff --git a/gnu/llvm/lldb/include/lldb/Target/JITLoader.h b/gnu/llvm/lldb/include/lldb/Target/JITLoader.h index 1bafd828f78..790fdfaf854 100644 --- a/gnu/llvm/lldb/include/lldb/Target/JITLoader.h +++ b/gnu/llvm/lldb/include/lldb/Target/JITLoader.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_JITLoader_h_ -#define liblldb_JITLoader_h_ +#ifndef LLDB_TARGET_JITLOADER_H +#define LLDB_TARGET_JITLOADER_H #include @@ -65,4 +65,4 @@ protected: } // namespace lldb_private -#endif // liblldb_JITLoader_h_ +#endif // LLDB_TARGET_JITLOADER_H diff --git a/gnu/llvm/lldb/include/lldb/Target/JITLoaderList.h b/gnu/llvm/lldb/include/lldb/Target/JITLoaderList.h index 4cc3a9ecb91..f8d34d21a80 100644 --- a/gnu/llvm/lldb/include/lldb/Target/JITLoaderList.h +++ b/gnu/llvm/lldb/include/lldb/Target/JITLoaderList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_JITLoaderList_h_ -#define liblldb_JITLoaderList_h_ +#ifndef LLDB_TARGET_JITLOADERLIST_H +#define LLDB_TARGET_JITLOADERLIST_H #include #include @@ -45,4 +45,4 @@ private: } // namespace lldb_private -#endif // liblldb_JITLoaderList_h_ +#endif // LLDB_TARGET_JITLOADERLIST_H diff --git a/gnu/llvm/lldb/include/lldb/Target/Language.h b/gnu/llvm/lldb/include/lldb/Target/Language.h index e00b042ac25..9dc9df363d7 100644 --- a/gnu/llvm/lldb/include/lldb/Target/Language.h +++ b/gnu/llvm/lldb/include/lldb/Target/Language.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Language_h_ -#define liblldb_Language_h_ +#ifndef LLDB_TARGET_LANGUAGE_H +#define LLDB_TARGET_LANGUAGE_H #include #include @@ -180,10 +180,6 @@ public: GetPossibleFormattersMatches(ValueObject &valobj, lldb::DynamicValueType use_dynamic); - virtual lldb_private::formatters::StringPrinter::EscapingHelper - GetStringPrinterEscapingHelper( - lldb_private::formatters::StringPrinter::GetPrintableElementType); - virtual std::unique_ptr GetTypeScavenger(); virtual const char *GetLanguageSpecificTypeLookupHelp(); @@ -274,9 +270,10 @@ protected: Language(); private: - DISALLOW_COPY_AND_ASSIGN(Language); + Language(const Language &) = delete; + const Language &operator=(const Language &) = delete; }; } // namespace lldb_private -#endif // liblldb_Language_h_ +#endif // LLDB_TARGET_LANGUAGE_H diff --git a/gnu/llvm/lldb/include/lldb/Target/LanguageRuntime.h b/gnu/llvm/lldb/include/lldb/Target/LanguageRuntime.h index 73c8dfa3874..b0b9b919911 100644 --- a/gnu/llvm/lldb/include/lldb/Target/LanguageRuntime.h +++ b/gnu/llvm/lldb/include/lldb/Target/LanguageRuntime.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_LanguageRuntime_h_ -#define liblldb_LanguageRuntime_h_ +#ifndef LLDB_TARGET_LANGUAGERUNTIME_H +#define LLDB_TARGET_LANGUAGERUNTIME_H #include "lldb/Breakpoint/BreakpointResolver.h" #include "lldb/Breakpoint/BreakpointResolverName.h" @@ -21,8 +21,6 @@ #include "lldb/lldb-private.h" #include "lldb/lldb-public.h" -#include "clang/Basic/TargetOptions.h" - namespace lldb_private { class ExceptionSearchFilter : public SearchFilter { @@ -53,7 +51,7 @@ protected: LanguageRuntime *m_language_runtime; lldb::SearchFilterSP m_filter_sp; - lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override; + lldb::SearchFilterSP DoCreateCopy() override; void UpdateModuleListIfNeeded(); }; @@ -136,7 +134,8 @@ public: virtual DeclVendor *GetDeclVendor() { return nullptr; } virtual lldb::BreakpointResolverSP - CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) = 0; + CreateExceptionResolver(const lldb::BreakpointSP &bkpt, + bool catch_bp, bool throw_bp) = 0; virtual lldb::SearchFilterSP CreateExceptionSearchFilter() { return m_process->GetTarget().GetSearchFilterForModule(nullptr); @@ -154,7 +153,7 @@ public: /// Identify whether a name is a runtime value that should not be hidden by /// from the user interface. - virtual bool IsWhitelistedRuntimeValue(ConstString name) { return false; } + virtual bool IsAllowedRuntimeValue(ConstString name) { return false; } virtual llvm::Optional GetRuntimeType(CompilerType base_type) { return llvm::None; @@ -162,13 +161,6 @@ public: virtual void ModulesDidLoad(const ModuleList &module_list) {} - // Called by the Clang expression evaluation engine to allow runtimes to - // alter the set of target options provided to the compiler. If the options - // prototype is modified, runtimes must return true, false otherwise. - virtual bool GetOverrideExprOptions(clang::TargetOptions &prototype) { - return false; - } - // Called by ClangExpressionParser::PrepareForExecution to query for any // custom LLVM IR passes that need to be run before an expression is // assembled and run. @@ -193,9 +185,10 @@ protected: Process *m_process; private: - DISALLOW_COPY_AND_ASSIGN(LanguageRuntime); + LanguageRuntime(const LanguageRuntime &) = delete; + const LanguageRuntime &operator=(const LanguageRuntime &) = delete; }; } // namespace lldb_private -#endif // liblldb_LanguageRuntime_h_ +#endif // LLDB_TARGET_LANGUAGERUNTIME_H diff --git a/gnu/llvm/lldb/include/lldb/Target/Memory.h b/gnu/llvm/lldb/include/lldb/Target/Memory.h index e62b8ef9c77..b3ad22aff16 100644 --- a/gnu/llvm/lldb/include/lldb/Target/Memory.h +++ b/gnu/llvm/lldb/include/lldb/Target/Memory.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Memory_h_ -#define liblldb_Memory_h_ +#ifndef LLDB_TARGET_MEMORY_H +#define LLDB_TARGET_MEMORY_H #include "lldb/Utility/RangeMap.h" #include "lldb/lldb-private.h" @@ -45,7 +45,7 @@ public: protected: typedef std::map BlockMap; - typedef RangeArray InvalidRanges; + typedef RangeVector InvalidRanges; typedef Range AddrRange; // Classes that inherit from MemoryCache can see and modify these std::recursive_mutex m_mutex; @@ -59,7 +59,8 @@ protected: uint32_t m_L2_cache_line_byte_size; private: - DISALLOW_COPY_AND_ASSIGN(MemoryCache); + MemoryCache(const MemoryCache &) = delete; + const MemoryCache &operator=(const MemoryCache &) = delete; }; @@ -135,9 +136,10 @@ protected: PermissionsToBlockMap m_memory_map; private: - DISALLOW_COPY_AND_ASSIGN(AllocatedMemoryCache); + AllocatedMemoryCache(const AllocatedMemoryCache &) = delete; + const AllocatedMemoryCache &operator=(const AllocatedMemoryCache &) = delete; }; } // namespace lldb_private -#endif // liblldb_Memory_h_ +#endif // LLDB_TARGET_MEMORY_H diff --git a/gnu/llvm/lldb/include/lldb/Target/MemoryHistory.h b/gnu/llvm/lldb/include/lldb/Target/MemoryHistory.h index 501751c55e8..db1e8680599 100644 --- a/gnu/llvm/lldb/include/lldb/Target/MemoryHistory.h +++ b/gnu/llvm/lldb/include/lldb/Target/MemoryHistory.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_MemoryHistory_h_ -#define liblldb_MemoryHistory_h_ +#ifndef LLDB_TARGET_MEMORYHISTORY_H +#define LLDB_TARGET_MEMORYHISTORY_H #include @@ -30,4 +30,4 @@ public: } // namespace lldb_private -#endif // liblldb_MemoryHistory_h_ +#endif // LLDB_TARGET_MEMORYHISTORY_H diff --git a/gnu/llvm/lldb/include/lldb/Target/MemoryRegionInfo.h b/gnu/llvm/lldb/include/lldb/Target/MemoryRegionInfo.h index 07e50188843..a22da8d72b8 100644 --- a/gnu/llvm/lldb/include/lldb/Target/MemoryRegionInfo.h +++ b/gnu/llvm/lldb/include/lldb/Target/MemoryRegionInfo.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_MemoryRegionInfo_h -#define lldb_MemoryRegionInfo_h +#ifndef LLDB_TARGET_MEMORYREGIONINFO_H +#define LLDB_TARGET_MEMORYREGIONINFO_H #include "lldb/Utility/ConstString.h" #include "lldb/Utility/RangeMap.h" @@ -143,4 +143,4 @@ struct format_provider { }; } -#endif // #ifndef lldb_MemoryRegionInfo_h +#endif // LLDB_TARGET_MEMORYREGIONINFO_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ModuleCache.h b/gnu/llvm/lldb/include/lldb/Target/ModuleCache.h index 11961691139..9dc0e090319 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ModuleCache.h +++ b/gnu/llvm/lldb/include/lldb/Target/ModuleCache.h @@ -71,4 +71,4 @@ private: } // namespace lldb_private -#endif // utility_ModuleCache_h_ +#endif // LLDB_TARGET_MODULECACHE_H diff --git a/gnu/llvm/lldb/include/lldb/Target/OperatingSystem.h b/gnu/llvm/lldb/include/lldb/Target/OperatingSystem.h index c75d1ca2e5f..6db5c0a01f3 100644 --- a/gnu/llvm/lldb/include/lldb/Target/OperatingSystem.h +++ b/gnu/llvm/lldb/include/lldb/Target/OperatingSystem.h @@ -7,9 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_OperatingSystem_h_ -#define liblldb_OperatingSystem_h_ - +#ifndef LLDB_TARGET_OPERATINGSYSTEM_H +#define LLDB_TARGET_OPERATINGSYSTEM_H #include "lldb/Core/PluginInterface.h" #include "lldb/lldb-private.h" @@ -70,9 +69,10 @@ protected: Process *m_process; ///< The process that this dynamic loader plug-in is tracking. private: - DISALLOW_COPY_AND_ASSIGN(OperatingSystem); + OperatingSystem(const OperatingSystem &) = delete; + const OperatingSystem &operator=(const OperatingSystem &) = delete; }; } // namespace lldb_private -#endif // liblldb_OperatingSystem_h_ +#endif // LLDB_TARGET_OPERATINGSYSTEM_H diff --git a/gnu/llvm/lldb/include/lldb/Target/PathMappingList.h b/gnu/llvm/lldb/include/lldb/Target/PathMappingList.h index d1759667f1f..9e1e6eb26eb 100644 --- a/gnu/llvm/lldb/include/lldb/Target/PathMappingList.h +++ b/gnu/llvm/lldb/include/lldb/Target/PathMappingList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PathMappingList_h_ -#define liblldb_PathMappingList_h_ +#ifndef LLDB_TARGET_PATHMAPPINGLIST_H +#define LLDB_TARGET_PATHMAPPINGLIST_H #include #include @@ -125,4 +125,4 @@ protected: } // namespace lldb_private -#endif // liblldb_PathMappingList_h_ +#endif // LLDB_TARGET_PATHMAPPINGLIST_H diff --git a/gnu/llvm/lldb/include/lldb/Target/Platform.h b/gnu/llvm/lldb/include/lldb/Target/Platform.h index 72b6be21b77..277fcf68cb0 100644 --- a/gnu/llvm/lldb/include/lldb/Target/Platform.h +++ b/gnu/llvm/lldb/include/lldb/Target/Platform.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Platform_h_ -#define liblldb_Platform_h_ +#ifndef LLDB_TARGET_PLATFORM_H +#define LLDB_TARGET_PLATFORM_H #include #include @@ -23,6 +23,7 @@ #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/Utility/Timeout.h" #include "lldb/Utility/UserIDResolver.h" #include "lldb/lldb-private-forward.h" @@ -32,8 +33,8 @@ namespace lldb_private { class ProcessInstanceInfo; -class ProcessInstanceInfoList; class ProcessInstanceInfoMatch; +typedef std::vector ProcessInstanceInfoList; class ModuleCache; enum MmapFlags { eMmapFlagsPrivate = 1, eMmapFlagsAnon = 2 }; @@ -49,6 +50,9 @@ public: FileSpec GetModuleCacheDirectory() const; bool SetModuleCacheDirectory(const FileSpec &dir_spec); + +private: + void SetDefaultModuleCacheDirectory(const FileSpec &dir_spec); }; typedef std::shared_ptr PlatformPropertiesSP; @@ -297,11 +301,10 @@ public: LocateExecutableScriptingResources(Target *target, Module &module, Stream *feedback_stream); - virtual Status GetSharedModule(const ModuleSpec &module_spec, - Process *process, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, - bool *did_create_ptr); + virtual Status GetSharedModule( + const ModuleSpec &module_spec, Process *process, + lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr); virtual bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec); @@ -368,9 +371,13 @@ public: virtual lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url, llvm::StringRef plugin_name, - lldb_private::Debugger &debugger, - lldb_private::Target *target, - lldb_private::Status &error); + Debugger &debugger, Target *target, + Status &error); + + virtual lldb::ProcessSP + ConnectProcessSynchronous(llvm::StringRef connect_url, + llvm::StringRef plugin_name, Debugger &debugger, + Stream &stream, Target *target, Status &error); /// Attach to an existing process using a process ID. /// @@ -823,7 +830,33 @@ public: virtual size_t ConnectToWaitingProcesses(lldb_private::Debugger &debugger, lldb_private::Status &error); + /// Gather all of crash informations into a structured data dictionary. + /// + /// If the platform have a crashed process with crash information entries, + /// gather all the entries into an structured data dictionary or return a + /// nullptr. This dictionary is generic and extensible, as it contains an + /// array for each different type of crash information. + /// + /// \param[in] process + /// The crashed process. + /// + /// \return + /// A structured data dictionary containing at each entry, the crash + /// information type as the entry key and the matching an array as the + /// entry value. \b nullptr if not implemented or if the process has no + /// crash information entry. \b error if an error occured. + virtual llvm::Expected + FetchExtendedCrashInformation(lldb_private::Process &process) { + return nullptr; + } + protected: + /// Private implementation of connecting to a process. If the stream is set + /// we connect synchronously. + lldb::ProcessSP DoConnectProcess(llvm::StringRef connect_url, + llvm::StringRef plugin_name, + Debugger &debugger, Stream *stream, + Target *target, Status &error); bool m_is_host; // Set to true when we are able to actually set the OS version while being // connected. For remote platforms, we might set the version ahead of time @@ -904,7 +937,8 @@ private: FileSpec GetModuleCacheRoot(); - DISALLOW_COPY_AND_ASSIGN(Platform); + Platform(const Platform &) = delete; + const Platform &operator=(const Platform &) = delete; }; class PlatformList { @@ -971,7 +1005,8 @@ protected: lldb::PlatformSP m_selected_platform_sp; private: - DISALLOW_COPY_AND_ASSIGN(PlatformList); + PlatformList(const PlatformList &) = delete; + const PlatformList &operator=(const PlatformList &) = delete; }; class OptionGroupPlatformRSync : public lldb_private::OptionGroup { @@ -996,7 +1031,9 @@ public: bool m_ignores_remote_hostname; private: - DISALLOW_COPY_AND_ASSIGN(OptionGroupPlatformRSync); + OptionGroupPlatformRSync(const OptionGroupPlatformRSync &) = delete; + const OptionGroupPlatformRSync & + operator=(const OptionGroupPlatformRSync &) = delete; }; class OptionGroupPlatformSSH : public lldb_private::OptionGroup { @@ -1019,7 +1056,9 @@ public: std::string m_ssh_opts; private: - DISALLOW_COPY_AND_ASSIGN(OptionGroupPlatformSSH); + OptionGroupPlatformSSH(const OptionGroupPlatformSSH &) = delete; + const OptionGroupPlatformSSH & + operator=(const OptionGroupPlatformSSH &) = delete; }; class OptionGroupPlatformCaching : public lldb_private::OptionGroup { @@ -1041,9 +1080,11 @@ public: std::string m_cache_dir; private: - DISALLOW_COPY_AND_ASSIGN(OptionGroupPlatformCaching); + OptionGroupPlatformCaching(const OptionGroupPlatformCaching &) = delete; + const OptionGroupPlatformCaching & + operator=(const OptionGroupPlatformCaching &) = delete; }; } // namespace lldb_private -#endif // liblldb_Platform_h_ +#endif // LLDB_TARGET_PLATFORM_H diff --git a/gnu/llvm/lldb/include/lldb/Target/Process.h b/gnu/llvm/lldb/include/lldb/Target/Process.h index 2ba996d4995..bf9b64547ed 100644 --- a/gnu/llvm/lldb/include/lldb/Target/Process.h +++ b/gnu/llvm/lldb/include/lldb/Target/Process.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Process_h_ -#define liblldb_Process_h_ +#ifndef LLDB_TARGET_PROCESS_H +#define LLDB_TARGET_PROCESS_H #include "lldb/Host/Config.h" @@ -37,6 +37,7 @@ #include "lldb/Target/Memory.h" #include "lldb/Target/QueueList.h" #include "lldb/Target/ThreadList.h" +#include "lldb/Target/ThreadPlanStack.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/Event.h" @@ -57,7 +58,11 @@ namespace lldb_private { template struct Range; -// ProcessProperties +class ProcessExperimentalProperties : public Properties { +public: + ProcessExperimentalProperties(); +}; + class ProcessProperties : public Properties { public: // Pass nullptr for "process" if the ProcessProperties are to be the global @@ -81,11 +86,15 @@ public: bool GetDetachKeepsStopped() const; void SetDetachKeepsStopped(bool keep_stopped); bool GetWarningsOptimization() const; + bool GetWarningsUnsupportedLanguage() const; bool GetStopOnExec() const; std::chrono::seconds GetUtilityExpressionTimeout() const; + bool GetOSPluginReportsAllThreads() const; + void SetOSPluginReportsAllThreads(bool does_report); protected: Process *m_process; // Can be nullptr for global ProcessProperties + std::unique_ptr m_experimental_properties_up; }; typedef std::shared_ptr ProcessPropertiesSP; @@ -139,7 +148,9 @@ public: return (m_plugin_name.empty() ? nullptr : m_plugin_name.c_str()); } - void SetProcessPluginName(llvm::StringRef plugin) { m_plugin_name = plugin; } + void SetProcessPluginName(llvm::StringRef plugin) { + m_plugin_name = std::string(plugin); + } void Clear() { ProcessInstanceInfo::Clear(); @@ -380,7 +391,7 @@ public: }; /// Process warning types. - enum Warnings { eWarningsOptimization = 1 }; + enum Warnings { eWarningsOptimization = 1, eWarningsUnsupportedLanguage = 2 }; typedef Range LoadRange; // We use a read/write lock to allow on or more clients to access the process @@ -441,6 +452,8 @@ public: void Dump(Stream *s) const override; + virtual bool ShouldStop(Event *event_ptr, bool &found_valid_stopinfo); + void DoOnRemoval(Event *event_ptr) override; static const Process::ProcessEventData * @@ -486,7 +499,8 @@ public: int m_update_state; bool m_interrupted; - DISALLOW_COPY_AND_ASSIGN(ProcessEventData); + ProcessEventData(const ProcessEventData &) = delete; + const ProcessEventData &operator=(const ProcessEventData &) = delete; }; /// Construct with a shared pointer to a target, and the Process listener. @@ -723,7 +737,7 @@ public: /// /// \return /// Returns an error object. - virtual Status ConnectRemote(Stream *strm, llvm::StringRef remote_url); + virtual Status ConnectRemote(llvm::StringRef remote_url); bool GetShouldDetach() const { return m_should_detach; } @@ -911,7 +925,7 @@ public: /// /// \return /// Returns an error object. - virtual Status DoConnectRemote(Stream *strm, llvm::StringRef remote_url) { + virtual Status DoConnectRemote(llvm::StringRef remote_url) { Status error; error.SetErrorString("remote connections are not supported"); return error; @@ -1265,7 +1279,7 @@ public: /// LLDB_INVALID_ADDRESS. /// /// \return - /// A StructureDataSP object which, if non-empty, will contain the + /// A StructuredDataSP object which, if non-empty, will contain the /// information the DynamicLoader needs to get the initial scan of /// solibs resolved. virtual lldb_private::StructuredData::ObjectSP @@ -1309,9 +1323,14 @@ public: /// pre-computed. void PrintWarningOptimization(const SymbolContext &sc); + /// Print a user-visible warning about a function written in a + /// language that this version of LLDB doesn't support. + /// + /// \see PrintWarningOptimization + void PrintWarningUnsupportedLanguage(const SymbolContext &sc); + virtual bool GetProcessInfo(ProcessInstanceInfo &info); -public: /// Get the exit status for a process. /// /// \return @@ -2196,6 +2215,75 @@ public: void SetDynamicCheckers(DynamicCheckerFunctions *dynamic_checkers); +/// Prune ThreadPlanStacks for unreported threads. +/// +/// \param[in] tid +/// The tid whose Plan Stack we are seeking to prune. +/// +/// \return +/// \b true if the TID is found or \b false if not. +bool PruneThreadPlansForTID(lldb::tid_t tid); + +/// Prune ThreadPlanStacks for all unreported threads. +void PruneThreadPlans(); + + /// Find the thread plan stack associated with thread with \a tid. + /// + /// \param[in] tid + /// The tid whose Plan Stack we are seeking. + /// + /// \return + /// Returns a ThreadPlan if the TID is found or nullptr if not. + ThreadPlanStack *FindThreadPlans(lldb::tid_t tid); + + /// Dump the thread plans associated with thread with \a tid. + /// + /// \param[in/out] strm + /// The stream to which to dump the output + /// + /// \param[in] tid + /// The tid whose Plan Stack we are dumping + /// + /// \param[in] desc_level + /// How much detail to dump + /// + /// \param[in] internal + /// If \b true dump all plans, if false only user initiated plans + /// + /// \param[in] condense_trivial + /// If true, only dump a header if the plan stack is just the base plan. + /// + /// \param[in] skip_unreported_plans + /// If true, only dump a plan if it is currently backed by an + /// lldb_private::Thread *. + /// + /// \return + /// Returns \b true if TID was found, \b false otherwise + bool DumpThreadPlansForTID(Stream &strm, lldb::tid_t tid, + lldb::DescriptionLevel desc_level, bool internal, + bool condense_trivial, bool skip_unreported_plans); + + /// Dump all the thread plans for this process. + /// + /// \param[in/out] strm + /// The stream to which to dump the output + /// + /// \param[in] desc_level + /// How much detail to dump + /// + /// \param[in] internal + /// If \b true dump all plans, if false only user initiated plans + /// + /// \param[in] condense_trivial + /// If true, only dump a header if the plan stack is just the base plan. + /// + /// \param[in] skip_unreported_plans + /// If true, skip printing all thread plan stacks that don't currently + /// have a backing lldb_private::Thread *. + void DumpThreadPlans(Stream &strm, lldb::DescriptionLevel desc_level, + bool internal, bool condense_trivial, + bool skip_unreported_plans); + /// Call this to set the lldb in the mode where it breaks on new thread /// creations, and then auto-restarts. This is useful when you are trying /// to run only one thread, but either that thread or the kernel is creating @@ -2665,6 +2753,10 @@ protected: ///see them. This is usually the same as ///< m_thread_list_real, but might be different if there is an OS plug-in ///creating memory threads + ThreadPlanStackMap m_thread_plans; ///< This is the list of thread plans for + /// threads in m_thread_list, as well as + /// threads we knew existed, but haven't + /// determined that they have died yet. ThreadList m_extended_thread_list; ///< Owner for extended threads that may be ///generated, cleared on natural stops uint32_t m_extended_thread_stop_id; ///< The natural stop id when @@ -2843,10 +2935,11 @@ private: void ControlPrivateStateThread(uint32_t signal); - DISALLOW_COPY_AND_ASSIGN(Process); + Process(const Process &) = delete; + const Process &operator=(const Process &) = delete; }; -/// RAII guard that should be aquired when an utility function is called within +/// RAII guard that should be acquired when an utility function is called within /// a given process. class UtilityFunctionScope { Process *m_process; @@ -2864,4 +2957,4 @@ public: } // namespace lldb_private -#endif // liblldb_Process_h_ +#endif // LLDB_TARGET_PROCESS_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ProcessStructReader.h b/gnu/llvm/lldb/include/lldb/Target/ProcessStructReader.h index ade29c0a7cf..0a91bef8048 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ProcessStructReader.h +++ b/gnu/llvm/lldb/include/lldb/Target/ProcessStructReader.h @@ -101,4 +101,4 @@ public: }; } -#endif // utility_ProcessStructReader_h_ +#endif // LLDB_TARGET_PROCESSSTRUCTREADER_H diff --git a/gnu/llvm/lldb/include/lldb/Target/Queue.h b/gnu/llvm/lldb/include/lldb/Target/Queue.h index 10b9e024207..058d46a75a8 100644 --- a/gnu/llvm/lldb/include/lldb/Target/Queue.h +++ b/gnu/llvm/lldb/include/lldb/Target/Queue.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Queue_h_ -#define liblldb_Queue_h_ +#ifndef LLDB_TARGET_QUEUE_H +#define LLDB_TARGET_QUEUE_H #include #include @@ -144,9 +144,10 @@ private: // dispatch_queue_t for this Queue lldb::QueueKind m_kind; - DISALLOW_COPY_AND_ASSIGN(Queue); + Queue(const Queue &) = delete; + const Queue &operator=(const Queue &) = delete; }; } // namespace lldb_private -#endif // liblldb_Queue_h_ +#endif // LLDB_TARGET_QUEUE_H diff --git a/gnu/llvm/lldb/include/lldb/Target/QueueItem.h b/gnu/llvm/lldb/include/lldb/Target/QueueItem.h index dfae3b84726..64d3d23b398 100644 --- a/gnu/llvm/lldb/include/lldb/Target/QueueItem.h +++ b/gnu/llvm/lldb/include/lldb/Target/QueueItem.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_QueueItem_h_ -#define liblldb_QueueItem_h_ +#ifndef LLDB_TARGET_QUEUEITEM_H +#define LLDB_TARGET_QUEUEITEM_H #include #include @@ -159,9 +159,10 @@ protected: std::string m_target_queue_label; private: - DISALLOW_COPY_AND_ASSIGN(QueueItem); + QueueItem(const QueueItem &) = delete; + const QueueItem &operator=(const QueueItem &) = delete; }; } // namespace lldb_private -#endif // liblldb_QueueItem_h_ +#endif // LLDB_TARGET_QUEUEITEM_H diff --git a/gnu/llvm/lldb/include/lldb/Target/QueueList.h b/gnu/llvm/lldb/include/lldb/Target/QueueList.h index 761107e41de..7c74a6a99ac 100644 --- a/gnu/llvm/lldb/include/lldb/Target/QueueList.h +++ b/gnu/llvm/lldb/include/lldb/Target/QueueList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_QueueList_h_ -#define liblldb_QueueList_h_ +#ifndef LLDB_TARGET_QUEUELIST_H +#define LLDB_TARGET_QUEUELIST_H #include #include @@ -107,4 +107,4 @@ private: } // namespace lldb_private -#endif // liblldb_QueueList_h_ +#endif // LLDB_TARGET_QUEUELIST_H diff --git a/gnu/llvm/lldb/include/lldb/Target/RegisterCheckpoint.h b/gnu/llvm/lldb/include/lldb/Target/RegisterCheckpoint.h index 4f9654f7634..d2bcc614f58 100644 --- a/gnu/llvm/lldb/include/lldb/Target/RegisterCheckpoint.h +++ b/gnu/llvm/lldb/include/lldb/Target/RegisterCheckpoint.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterCheckpoint_h_ -#define liblldb_RegisterCheckpoint_h_ +#ifndef LLDB_TARGET_REGISTERCHECKPOINT_H +#define LLDB_TARGET_REGISTERCHECKPOINT_H #include "lldb/Target/StackID.h" #include "lldb/Utility/UserID.h" @@ -45,9 +45,10 @@ protected: Reason m_reason; // Make RegisterCheckpointSP if you wish to share the data in this class. - DISALLOW_COPY_AND_ASSIGN(RegisterCheckpoint); + RegisterCheckpoint(const RegisterCheckpoint &) = delete; + const RegisterCheckpoint &operator=(const RegisterCheckpoint &) = delete; }; } // namespace lldb_private -#endif // liblldb_RegisterCheckpoint_h_ +#endif // LLDB_TARGET_REGISTERCHECKPOINT_H diff --git a/gnu/llvm/lldb/include/lldb/Target/RegisterContext.h b/gnu/llvm/lldb/include/lldb/Target/RegisterContext.h index d6212dd49dd..5e795e59f94 100644 --- a/gnu/llvm/lldb/include/lldb/Target/RegisterContext.h +++ b/gnu/llvm/lldb/include/lldb/Target/RegisterContext.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContext_h_ -#define liblldb_RegisterContext_h_ +#ifndef LLDB_TARGET_REGISTERCONTEXT_H +#define LLDB_TARGET_REGISTERCONTEXT_H #include "lldb/Target/ExecutionContextScope.h" #include "lldb/lldb-private.h" @@ -39,6 +39,8 @@ public: virtual const RegisterSet *GetRegisterSet(size_t reg_set) = 0; + virtual lldb::ByteOrder GetByteOrder(); + virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value) = 0; @@ -105,7 +107,7 @@ public: /// The equivalent register number in the eRegisterKindLLDB /// numbering scheme, if possible, else LLDB_INVALID_REGNUM. virtual uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, - uint32_t num) = 0; + uint32_t num); // Subclasses can override these functions if desired virtual uint32_t NumSupportedHardwareBreakpoints(); @@ -201,9 +203,10 @@ protected: uint32_t m_stop_id; // The stop ID that any data in this context is valid for private: // For RegisterContext only - DISALLOW_COPY_AND_ASSIGN(RegisterContext); + RegisterContext(const RegisterContext &) = delete; + const RegisterContext &operator=(const RegisterContext &) = delete; }; } // namespace lldb_private -#endif // liblldb_RegisterContext_h_ +#endif // LLDB_TARGET_REGISTERCONTEXT_H diff --git a/gnu/llvm/lldb/include/lldb/Target/RegisterContextUnwind.h b/gnu/llvm/lldb/include/lldb/Target/RegisterContextUnwind.h new file mode 100644 index 00000000000..fa96c3e42c7 --- /dev/null +++ b/gnu/llvm/lldb/include/lldb/Target/RegisterContextUnwind.h @@ -0,0 +1,259 @@ +//===-- RegisterContextUnwind.h ---------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_TARGET_REGISTERCONTEXTUNWIND_H +#define LLDB_TARGET_REGISTERCONTEXTUNWIND_H + +#include + +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/RegisterNumber.h" +#include "lldb/Target/UnwindLLDB.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class UnwindLLDB; + +class RegisterContextUnwind : public lldb_private::RegisterContext { +public: + typedef std::shared_ptr SharedPtr; + + RegisterContextUnwind(lldb_private::Thread &thread, + const SharedPtr &next_frame, + lldb_private::SymbolContext &sym_ctx, + uint32_t frame_number, + lldb_private::UnwindLLDB &unwind_lldb); + + ~RegisterContextUnwind() override = default; + + void InvalidateAllRegisters() override; + + size_t GetRegisterCount() override; + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override; + + bool ReadRegister(const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue &value) override; + + bool WriteRegister(const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue &value) override; + + bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + + bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + + bool IsValid() const; + + bool IsTrapHandlerFrame() const; + + bool GetCFA(lldb::addr_t &cfa); + + bool GetStartPC(lldb::addr_t &start_pc); + + bool ReadPC(lldb::addr_t &start_pc); + +private: + enum FrameType { + eNormalFrame, + eTrapHandlerFrame, + eDebuggerFrame, // a debugger inferior function call frame; we get caller's + // registers from debugger + eSkipFrame, // The unwind resulted in a bogus frame but may get back on + // track so we don't want to give up yet + eNotAValidFrame // this frame is invalid for some reason - most likely it is + // past the top (end) of the stack + }; + + // UnwindLLDB needs to pass around references to RegisterLocations + friend class UnwindLLDB; + + // Returns true if we have an unwind loop -- the same stack frame unwinding + // multiple times. + bool CheckIfLoopingStack(); + + // Indicates whether this frame is frame zero -- the currently + // executing frame -- or not. + bool IsFrameZero() const; + + void InitializeZerothFrame(); + + void InitializeNonZerothFrame(); + + SharedPtr GetNextFrame() const; + + SharedPtr GetPrevFrame() const; + + // A SkipFrame occurs when the unwind out of frame 0 didn't go right -- we've + // got one bogus frame at frame #1. + // There is a good chance we'll get back on track if we follow the frame + // pointer chain (or whatever is appropriate + // on this ABI) so we allow one invalid frame to be in the stack. Ideally + // we'll mark this frame specially at some + // point and indicate to the user that the unwinder had a hiccup. Often when + // this happens we will miss a frame of + // the program's actual stack in the unwind and we want to flag that for the + // user somehow. + bool IsSkipFrame() const; + + /// Determines if a SymbolContext is a trap handler or not + /// + /// Given a SymbolContext, determines if this is a trap handler function + /// aka asynchronous signal handler. + /// + /// \return + /// Returns true if the SymbolContext is a trap handler. + bool IsTrapHandlerSymbol(lldb_private::Process *process, + const lldb_private::SymbolContext &m_sym_ctx) const; + + /// Check if the given unwind plan indicates a signal trap handler, and + /// update frame type and symbol context if so. + void PropagateTrapHandlerFlagFromUnwindPlan(lldb::UnwindPlanSP unwind_plan); + + // Provide a location for where THIS function saved the CALLER's register + // value + // Or a frame "below" this one saved it, i.e. a function called by this one, + // preserved a register that this + // function didn't modify/use. + // + // The RegisterLocation type may be set to eRegisterNotAvailable -- this will + // happen for a volatile register + // being queried mid-stack. Instead of floating frame 0's contents of that + // register up the stack (which may + // or may not be the value of that reg when the function was executing), we + // won't return any value. + // + // If a non-volatile register (a "preserved" register) is requested mid-stack + // and no frames "below" the requested + // stack have saved the register anywhere, it is safe to assume that frame 0's + // register values are still the same + // as the requesting frame's. + lldb_private::UnwindLLDB::RegisterSearchResult + SavedLocationForRegister(uint32_t lldb_regnum, + lldb_private::UnwindLLDB::RegisterLocation ®loc); + + bool ReadRegisterValueFromRegisterLocation( + lldb_private::UnwindLLDB::RegisterLocation regloc, + const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue &value); + + bool WriteRegisterValueToRegisterLocation( + lldb_private::UnwindLLDB::RegisterLocation regloc, + const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue &value); + + /// If the unwind has to the caller frame has failed, try something else + /// + /// If lldb is using an assembly language based UnwindPlan for a frame and + /// the unwind to the caller frame fails, try falling back to a generic + /// UnwindPlan (architecture default unwindplan) to see if that might work + /// better. This is mostly helping to work around problems where the + /// assembly language inspection fails on hand-written assembly code. + /// + /// \return + /// Returns true if a fallback unwindplan was found & was installed. + bool TryFallbackUnwindPlan(); + + /// Switch to the fallback unwind plan unconditionally without any safety + /// checks that it is providing better results than the normal unwind plan. + /// + /// The only time it is valid to call this method is if the full unwindplan is + /// found to be fundamentally incorrect/impossible. + /// + /// Returns true if it was able to install the fallback unwind plan. + bool ForceSwitchToFallbackUnwindPlan(); + + // Get the contents of a general purpose (address-size) register for this + // frame + // (usually retrieved from the next frame) + bool ReadGPRValue(lldb::RegisterKind register_kind, uint32_t regnum, + lldb::addr_t &value); + + bool ReadGPRValue(const RegisterNumber ®_num, 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(); + + lldb::UnwindPlanSP GetFullUnwindPlanForFrame(); + + void UnwindLogMsg(const char *fmt, ...) __attribute__((format(printf, 2, 3))); + + void UnwindLogMsgVerbose(const char *fmt, ...) + __attribute__((format(printf, 2, 3))); + + bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp, + int &valid_pc_offset); + + lldb::addr_t GetReturnAddressHint(int32_t plan_offset); + + lldb_private::Thread &m_thread; + + /// + // The following tell us how to retrieve the CALLER's register values (ie the + // "previous" frame, aka the frame above) + // i.e. where THIS frame saved them + /// + + lldb::UnwindPlanSP m_fast_unwind_plan_sp; // may be NULL + lldb::UnwindPlanSP m_full_unwind_plan_sp; + lldb::UnwindPlanSP m_fallback_unwind_plan_sp; // may be NULL + + bool m_all_registers_available; // Can we retrieve all regs or just + // nonvolatile regs? + 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; + + int m_current_offset; // how far into the function we've executed; -1 if + // unknown + // 0 if no instructions have been executed yet. + + int m_current_offset_backed_up_one; // how far into the function we've + // executed; -1 if unknown + // 0 if no instructions have been executed yet. + // On architectures where the return address on the stack points + // to the instruction after the CALL, this value will have 1 + // subtracted from it. Else a function that ends in a CALL will + // have an offset pointing into the next function's address range. + // m_current_pc has the actual address of the "current" pc. + + lldb_private::SymbolContext &m_sym_ctx; + bool m_sym_ctx_valid; // if ResolveSymbolContextForAddress fails, don't try to + // use m_sym_ctx + + uint32_t m_frame_number; // What stack frame this RegisterContext is + + std::map + m_registers; // where to find reg values for this frame + + lldb_private::UnwindLLDB &m_parent_unwind; // The UnwindLLDB that is creating + // this RegisterContextUnwind + + RegisterContextUnwind(const RegisterContextUnwind &) = delete; + const RegisterContextUnwind & + operator=(const RegisterContextUnwind &) = delete; +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_REGISTERCONTEXTUNWIND_H diff --git a/gnu/llvm/lldb/include/lldb/Target/RegisterNumber.h b/gnu/llvm/lldb/include/lldb/Target/RegisterNumber.h index 0bef0c13f37..362812bcffd 100644 --- a/gnu/llvm/lldb/include/lldb/Target/RegisterNumber.h +++ b/gnu/llvm/lldb/include/lldb/Target/RegisterNumber.h @@ -56,4 +56,4 @@ private: const char *m_name; }; -#endif // liblldb_RegisterNumber_h +#endif // LLDB_TARGET_REGISTERNUMBER_H diff --git a/gnu/llvm/lldb/include/lldb/Target/RemoteAwarePlatform.h b/gnu/llvm/lldb/include/lldb/Target/RemoteAwarePlatform.h index 55d5ff673f1..5741dbe027b 100644 --- a/gnu/llvm/lldb/include/lldb/Target/RemoteAwarePlatform.h +++ b/gnu/llvm/lldb/include/lldb/Target/RemoteAwarePlatform.h @@ -22,6 +22,10 @@ public: bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec) override; + Status + ResolveExecutable(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr) override; + lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags, uint32_t mode, Status &error) override; diff --git a/gnu/llvm/lldb/include/lldb/Target/SectionLoadHistory.h b/gnu/llvm/lldb/include/lldb/Target/SectionLoadHistory.h index 71b5d0c4274..dd024301d0c 100644 --- a/gnu/llvm/lldb/include/lldb/Target/SectionLoadHistory.h +++ b/gnu/llvm/lldb/include/lldb/Target/SectionLoadHistory.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SectionLoadHistory_h_ -#define liblldb_SectionLoadHistory_h_ +#ifndef LLDB_TARGET_SECTIONLOADHISTORY_H +#define LLDB_TARGET_SECTIONLOADHISTORY_H #include #include @@ -75,9 +75,10 @@ protected: mutable std::recursive_mutex m_mutex; private: - DISALLOW_COPY_AND_ASSIGN(SectionLoadHistory); + SectionLoadHistory(const SectionLoadHistory &) = delete; + const SectionLoadHistory &operator=(const SectionLoadHistory &) = delete; }; } // namespace lldb_private -#endif // liblldb_SectionLoadHistory_h_ +#endif // LLDB_TARGET_SECTIONLOADHISTORY_H diff --git a/gnu/llvm/lldb/include/lldb/Target/SectionLoadList.h b/gnu/llvm/lldb/include/lldb/Target/SectionLoadList.h index caefa00ec1d..e8535e7ac51 100644 --- a/gnu/llvm/lldb/include/lldb/Target/SectionLoadList.h +++ b/gnu/llvm/lldb/include/lldb/Target/SectionLoadList.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SectionLoadList_h_ -#define liblldb_SectionLoadList_h_ +#ifndef LLDB_TARGET_SECTIONLOADLIST_H +#define LLDB_TARGET_SECTIONLOADLIST_H #include #include @@ -70,4 +70,4 @@ protected: } // namespace lldb_private -#endif // liblldb_SectionLoadList_h_ +#endif // LLDB_TARGET_SECTIONLOADLIST_H diff --git a/gnu/llvm/lldb/include/lldb/Target/StackFrame.h b/gnu/llvm/lldb/include/lldb/Target/StackFrame.h index 1c6a2b48116..905c56c9126 100644 --- a/gnu/llvm/lldb/include/lldb/Target/StackFrame.h +++ b/gnu/llvm/lldb/include/lldb/Target/StackFrame.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StackFrame_h_ -#define liblldb_StackFrame_h_ +#ifndef LLDB_TARGET_STACKFRAME_H +#define LLDB_TARGET_STACKFRAME_H #include #include @@ -367,12 +367,6 @@ public: /// may have limited support for inspecting variables. bool IsArtificial() const; - /// Query whether this frame behaves like the zeroth frame, in the sense - /// that its pc value might not immediately follow a call (and thus might - /// be the first address of its function). True for actual frame zero as - /// well as any other frame with the same trait. - bool BehavesLikeZerothFrame() const; - /// Query this frame to find what frame it is in this Thread's /// StackFrameList. /// @@ -517,6 +511,11 @@ private: bool m_cfa_is_valid; // Does this frame have a CFA? Different from CFA == // LLDB_INVALID_ADDRESS Kind m_stack_frame_kind; + + // Whether this frame behaves like the zeroth frame, in the sense + // that its pc value might not immediately follow a call (and thus might + // be the first address of its function). True for actual frame zero as + // well as any other frame with the same trait. bool m_behaves_like_zeroth_frame; lldb::VariableListSP m_variable_list_sp; ValueObjectList m_variable_list_value_objects; // Value objects for each @@ -526,9 +525,10 @@ private: StreamString m_disassembly; std::recursive_mutex m_mutex; - DISALLOW_COPY_AND_ASSIGN(StackFrame); + StackFrame(const StackFrame &) = delete; + const StackFrame &operator=(const StackFrame &) = delete; }; } // namespace lldb_private -#endif // liblldb_StackFrame_h_ +#endif // LLDB_TARGET_STACKFRAME_H diff --git a/gnu/llvm/lldb/include/lldb/Target/StackFrameList.h b/gnu/llvm/lldb/include/lldb/Target/StackFrameList.h index 5eb79195017..1b0b986d705 100644 --- a/gnu/llvm/lldb/include/lldb/Target/StackFrameList.h +++ b/gnu/llvm/lldb/include/lldb/Target/StackFrameList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StackFrameList_h_ -#define liblldb_StackFrameList_h_ +#ifndef LLDB_TARGET_STACKFRAMELIST_H +#define LLDB_TARGET_STACKFRAMELIST_H #include #include @@ -94,7 +94,7 @@ protected: void GetFramesUpTo(uint32_t end_idx); - void GetOnlyConcreteFramesUpTo(uint32_t end_idx, Unwind *unwinder); + void GetOnlyConcreteFramesUpTo(uint32_t end_idx, Unwind &unwinder); void SynthesizeTailCallFrames(StackFrame &next_frame); @@ -155,9 +155,10 @@ protected: const bool m_show_inlined_frames; private: - DISALLOW_COPY_AND_ASSIGN(StackFrameList); + StackFrameList(const StackFrameList &) = delete; + const StackFrameList &operator=(const StackFrameList &) = delete; }; } // namespace lldb_private -#endif // liblldb_StackFrameList_h_ +#endif // LLDB_TARGET_STACKFRAMELIST_H diff --git a/gnu/llvm/lldb/include/lldb/Target/StackFrameRecognizer.h b/gnu/llvm/lldb/include/lldb/Target/StackFrameRecognizer.h index 2021ac5215f..9c9105ac04e 100644 --- a/gnu/llvm/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/gnu/llvm/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -6,12 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StackFrameRecognizer_h_ -#define liblldb_StackFrameRecognizer_h_ +#ifndef LLDB_TARGET_STACKFRAMERECOGNIZER_H +#define LLDB_TARGET_STACKFRAMERECOGNIZER_H #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectList.h" #include "lldb/Symbol/VariableList.h" +#include "lldb/Target/StopInfo.h" #include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private-forward.h" #include "lldb/lldb-public.h" @@ -33,10 +34,14 @@ public: virtual lldb::ValueObjectSP GetExceptionObject() { return lldb::ValueObjectSP(); } + virtual lldb::StackFrameSP GetMostRelevantFrame() { return nullptr; }; virtual ~RecognizedStackFrame(){}; + std::string GetStopDescription() { return m_stop_desc; } + protected: lldb::ValueObjectListSP m_arguments; + std::string m_stop_desc; }; /// \class StackFrameRecognizer @@ -85,7 +90,9 @@ public: lldb::StackFrameSP frame) override; private: - DISALLOW_COPY_AND_ASSIGN(ScriptedStackFrameRecognizer); + ScriptedStackFrameRecognizer(const ScriptedStackFrameRecognizer &) = delete; + const ScriptedStackFrameRecognizer & + operator=(const ScriptedStackFrameRecognizer &) = delete; }; /// \class StackFrameRecognizerManager @@ -97,7 +104,7 @@ class StackFrameRecognizerManager { public: static void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, - ConstString symbol, + llvm::ArrayRef symbols, bool first_instruction_only = true); static void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, @@ -105,10 +112,11 @@ public: lldb::RegularExpressionSP symbol, bool first_instruction_only = true); - static void ForEach( - std::function const &callback); + static void + ForEach(std::function symbols, + bool regexp)> const &callback); static bool RemoveRecognizerWithID(uint32_t recognizer_id); @@ -158,4 +166,4 @@ class ValueObjectRecognizerSynthesizedValue : public ValueObject { } // namespace lldb_private -#endif // liblldb_StackFrameRecognizer_h_ +#endif // LLDB_TARGET_STACKFRAMERECOGNIZER_H diff --git a/gnu/llvm/lldb/include/lldb/Target/StackID.h b/gnu/llvm/lldb/include/lldb/Target/StackID.h index a649a4faa93..827ed1be7c0 100644 --- a/gnu/llvm/lldb/include/lldb/Target/StackID.h +++ b/gnu/llvm/lldb/include/lldb/Target/StackID.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StackID_h_ -#define liblldb_StackID_h_ +#ifndef LLDB_TARGET_STACKID_H +#define LLDB_TARGET_STACKID_H #include "lldb/Core/AddressRange.h" #include "lldb/lldb-private.h" @@ -96,4 +96,4 @@ bool operator<(const StackID &lhs, const StackID &rhs); } // namespace lldb_private -#endif // liblldb_StackID_h_ +#endif // LLDB_TARGET_STACKID_H diff --git a/gnu/llvm/lldb/include/lldb/Target/StopInfo.h b/gnu/llvm/lldb/include/lldb/Target/StopInfo.h index 61e1fbd4bd4..4378d2d6379 100644 --- a/gnu/llvm/lldb/include/lldb/Target/StopInfo.h +++ b/gnu/llvm/lldb/include/lldb/Target/StopInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StopInfo_h_ -#define liblldb_StopInfo_h_ +#ifndef LLDB_TARGET_STOPINFO_H +#define LLDB_TARGET_STOPINFO_H #include @@ -183,9 +183,10 @@ protected: private: friend class Thread; - DISALLOW_COPY_AND_ASSIGN(StopInfo); + StopInfo(const StopInfo &) = delete; + const StopInfo &operator=(const StopInfo &) = delete; }; } // namespace lldb_private -#endif // liblldb_StopInfo_h_ +#endif // LLDB_TARGET_STOPINFO_H diff --git a/gnu/llvm/lldb/include/lldb/Target/StructuredDataPlugin.h b/gnu/llvm/lldb/include/lldb/Target/StructuredDataPlugin.h index b20bdb3b263..09241d5281f 100644 --- a/gnu/llvm/lldb/include/lldb/Target/StructuredDataPlugin.h +++ b/gnu/llvm/lldb/include/lldb/Target/StructuredDataPlugin.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef StructuredDataPlugin_h -#define StructuredDataPlugin_h +#ifndef LLDB_TARGET_STRUCTUREDDATAPLUGIN_H +#define LLDB_TARGET_STRUCTUREDDATAPLUGIN_H #include "lldb/Core/PluginInterface.h" #include "lldb/Utility/StructuredData.h" @@ -162,7 +162,8 @@ protected: private: lldb::ProcessWP m_process_wp; - DISALLOW_COPY_AND_ASSIGN(StructuredDataPlugin); + StructuredDataPlugin(const StructuredDataPlugin &) = delete; + const StructuredDataPlugin &operator=(const StructuredDataPlugin &) = delete; }; } diff --git a/gnu/llvm/lldb/include/lldb/Target/SystemRuntime.h b/gnu/llvm/lldb/include/lldb/Target/SystemRuntime.h index b45f882d36b..4f07d7ab52e 100644 --- a/gnu/llvm/lldb/include/lldb/Target/SystemRuntime.h +++ b/gnu/llvm/lldb/include/lldb/Target/SystemRuntime.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SystemRuntime_h_ -#define liblldb_SystemRuntime_h_ +#ifndef LLDB_TARGET_SYSTEMRUNTIME_H +#define LLDB_TARGET_SYSTEMRUNTIME_H #include @@ -300,9 +300,10 @@ protected: std::vector m_types; private: - DISALLOW_COPY_AND_ASSIGN(SystemRuntime); + SystemRuntime(const SystemRuntime &) = delete; + const SystemRuntime &operator=(const SystemRuntime &) = delete; }; } // namespace lldb_private -#endif // liblldb_SystemRuntime_h_ +#endif // LLDB_TARGET_SYSTEMRUNTIME_H diff --git a/gnu/llvm/lldb/include/lldb/Target/Target.h b/gnu/llvm/lldb/include/lldb/Target/Target.h index 1e9153c401e..280ce6359c7 100644 --- a/gnu/llvm/lldb/include/lldb/Target/Target.h +++ b/gnu/llvm/lldb/include/lldb/Target/Target.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Target_h_ -#define liblldb_Target_h_ +#ifndef LLDB_TARGET_TARGET_H +#define LLDB_TARGET_TARGET_H #include #include @@ -36,6 +36,8 @@ namespace lldb_private { +class ClangModulesDeclVendor; + OptionEnumValues GetDynamicValueTypes(); enum InlineStrategy { @@ -62,7 +64,6 @@ enum LoadDependentFiles { eLoadDependentsNo, }; -// TargetProperties class TargetExperimentalProperties : public Properties { public: TargetExperimentalProperties(); @@ -133,6 +134,8 @@ public: bool GetEnableAutoApplyFixIts() const; + uint64_t GetNumberOfRetriesWithFixits() const; + bool GetEnableNotifyAboutFixIts() const; bool GetEnableSaveObjects() const; @@ -202,11 +205,16 @@ public: bool GetInjectLocalVariables(ExecutionContext *exe_ctx) const; void SetInjectLocalVariables(ExecutionContext *exe_ctx, bool b); - + void SetRequireHardwareBreakpoints(bool b); bool GetRequireHardwareBreakpoints() const; + bool GetAutoInstallMainExecutable() const; + + void UpdateLaunchInfoFromProperties(); + + private: // Callbacks for m_launch_info. void Arg0ValueChangedCallback(); @@ -219,9 +227,12 @@ private: void DisableASLRValueChangedCallback(); void DisableSTDIOValueChangedCallback(); + Environment ComputeEnvironment() const; + // Member variables. ProcessLaunchInfo m_launch_info; std::unique_ptr m_experimental_properties_up; + Target *m_target; }; class EvaluateExpressionOptions { @@ -371,6 +382,12 @@ public: bool GetAutoApplyFixIts() const { return m_auto_apply_fixits; } + void SetRetriesWithFixIts(uint64_t number_of_retries) { + m_retries_with_fixits = number_of_retries; + } + + uint64_t GetRetriesWithFixIts() const { return m_retries_with_fixits; } + bool IsForUtilityExpr() const { return m_running_utility_expression; } void SetIsForUtilityExpr(bool b) { m_running_utility_expression = b; } @@ -392,6 +409,7 @@ private: bool m_ansi_color_errors = false; bool m_result_is_internal = false; bool m_auto_apply_fixits = true; + uint64_t m_retries_with_fixits = 1; /// True if the executed code should be treated as utility code that is only /// used by LLDB internally. bool m_running_utility_expression = false; @@ -467,7 +485,8 @@ public: lldb::TargetSP m_target_sp; ModuleList m_module_list; - DISALLOW_COPY_AND_ASSIGN(TargetEventData); + TargetEventData(const TargetEventData &) = delete; + const TargetEventData &operator=(const TargetEventData &) = delete; }; ~Target() override; @@ -940,7 +959,7 @@ public: /// /// \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. + /// selected platform is not compatible with the architecture 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). @@ -1054,8 +1073,6 @@ public: const char *name, Status &error); - lldb::ClangASTImporterSP GetClangASTImporter(); - // Install any files through the platform that need be to installed prior to // launching or attaching. Status Install(ProcessLaunchInfo *launch_info); @@ -1093,11 +1110,6 @@ public: lldb::ExpressionVariableSP GetPersistentVariable(ConstString name); - /// Return the next available number for numbered persistent variables. - unsigned GetNextPersistentVariableIndex() { - return m_next_persistent_variable_index++; - } - lldb::addr_t GetPersistentSymbol(ConstString name); /// This method will return the address of the starting function for @@ -1302,8 +1314,7 @@ protected: typedef std::map REPLMap; REPLMap m_repl_map; - lldb::ClangASTImporterSP m_ast_importer_sp; - lldb::ClangModulesDeclVendorUP m_clang_modules_decl_vendor_up; + std::unique_ptr m_clang_modules_decl_vendor_up; lldb::SourceManagerUP m_source_manager_up; @@ -1359,9 +1370,10 @@ private: void FinalizeFileActions(ProcessLaunchInfo &info); - DISALLOW_COPY_AND_ASSIGN(Target); + Target(const Target &) = delete; + const Target &operator=(const Target &) = delete; }; } // namespace lldb_private -#endif // liblldb_Target_h_ +#endif // LLDB_TARGET_TARGET_H diff --git a/gnu/llvm/lldb/include/lldb/Target/TargetList.h b/gnu/llvm/lldb/include/lldb/Target/TargetList.h index 50a7a321ead..5ed0344f175 100644 --- a/gnu/llvm/lldb/include/lldb/Target/TargetList.h +++ b/gnu/llvm/lldb/include/lldb/Target/TargetList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_TargetList_h_ -#define liblldb_TargetList_h_ +#ifndef LLDB_TARGET_TARGETLIST_H +#define LLDB_TARGET_TARGETLIST_H #include #include @@ -206,9 +206,10 @@ private: lldb::PlatformSP &platform_sp, lldb::TargetSP &target_sp, bool is_dummy_target); - DISALLOW_COPY_AND_ASSIGN(TargetList); + TargetList(const TargetList &) = delete; + const TargetList &operator=(const TargetList &) = delete; }; } // namespace lldb_private -#endif // liblldb_TargetList_h_ +#endif // LLDB_TARGET_TARGETLIST_H diff --git a/gnu/llvm/lldb/include/lldb/Target/Thread.h b/gnu/llvm/lldb/include/lldb/Target/Thread.h index cdc8d39251c..205a0d965c6 100644 --- a/gnu/llvm/lldb/include/lldb/Target/Thread.h +++ b/gnu/llvm/lldb/include/lldb/Target/Thread.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Thread_h_ -#define liblldb_Thread_h_ +#ifndef LLDB_TARGET_THREAD_H +#define LLDB_TARGET_THREAD_H #include #include @@ -28,6 +28,8 @@ namespace lldb_private { +class ThreadPlanStack; + class ThreadProperties : public Properties { public: ThreadProperties(bool is_global); @@ -111,7 +113,8 @@ public: lldb::ThreadSP m_thread_sp; StackID m_stack_id; - DISALLOW_COPY_AND_ASSIGN(ThreadEventData); + ThreadEventData(const ThreadEventData &) = delete; + const ThreadEventData &operator=(const ThreadEventData &) = delete; }; struct ThreadStateCheckpoint { @@ -119,7 +122,7 @@ public: // bit of data. lldb::StopInfoSP stop_info_sp; // You have to restore the stop info or you // might continue with the wrong signals. - std::vector m_completed_plan_stack; + size_t m_completed_plan_checkpoint; lldb::RegisterCheckpointSP register_backup_sp; // You need to restore the registers, of course... uint32_t current_inlined_depth; @@ -177,8 +180,6 @@ public: /// to force the thread to run (e.g. the "thread continue" command, or are /// resetting the state /// (e.g. in SBThread::Resume()), then pass true to override_suspend. - /// \return - /// The User resume state for this thread. void SetResumeState(lldb::StateType state, bool override_suspend = false) { if (m_resume_state == lldb::eStateSuspended && !override_suspend) return; @@ -216,6 +217,12 @@ public: virtual void RefreshStateAfterStop() = 0; + void SelectMostRelevantFrame(); + + std::string GetStopDescription(); + + std::string GetStopDescriptionRaw(); + void WillStop(); bool ShouldStop(Event *event_ptr); @@ -908,7 +915,7 @@ public: /// /// \return /// A pointer to the next executed plan. - ThreadPlan *GetCurrentPlan(); + ThreadPlan *GetCurrentPlan() const; /// Unwinds the thread stack for the innermost expression plan currently /// on the thread plan stack. @@ -923,14 +930,14 @@ public: /// /// \return /// A pointer to the last completed plan. - lldb::ThreadPlanSP GetCompletedPlan(); + lldb::ThreadPlanSP GetCompletedPlan() const; /// Gets the outer-most return value from the completed plans /// /// \return /// A ValueObjectSP, either empty if there is no return value, /// or containing the return value. - lldb::ValueObjectSP GetReturnValueObject(); + lldb::ValueObjectSP GetReturnValueObject() const; /// Gets the outer-most expression variable from the completed plans /// @@ -938,7 +945,7 @@ public: /// A ExpressionVariableSP, either empty if there is no /// plan completed an expression during the current stop /// or the expression variable that was made for the completed expression. - lldb::ExpressionVariableSP GetExpressionVariable(); + lldb::ExpressionVariableSP GetExpressionVariable() const; /// Checks whether the given plan is in the completed plans for this /// stop. @@ -949,7 +956,7 @@ public: /// \return /// Returns true if the input plan is in the completed plan stack, /// false otherwise. - bool IsThreadPlanDone(ThreadPlan *plan); + bool IsThreadPlanDone(ThreadPlan *plan) const; /// Checks whether the given plan is in the discarded plans for this /// stop. @@ -960,14 +967,14 @@ public: /// \return /// Returns true if the input plan is in the discarded plan stack, /// false otherwise. - bool WasThreadPlanDiscarded(ThreadPlan *plan); + bool WasThreadPlanDiscarded(ThreadPlan *plan) const; /// Check if we have completed plan to override breakpoint stop reason /// /// \return /// Returns true if completed plan stack is not empty /// false otherwise. - bool CompletedPlanOverridesBreakpoint(); + bool CompletedPlanOverridesBreakpoint() const; /// Queues a generic thread plan. /// @@ -1013,16 +1020,6 @@ public: /// otherwise. bool DiscardUserThreadPlansUpToIndex(uint32_t thread_index); - /// Prints the current plan stack. - /// - /// \param[in] s - /// The stream to which to dump the plan stack info. - /// - void DumpThreadPlans( - Stream *s, - lldb::DescriptionLevel desc_level = lldb::eDescriptionLevelVerbose, - bool include_internal = true, bool ignore_boring = false) const; - virtual bool CheckpointThreadState(ThreadStateCheckpoint &saved_state); virtual bool @@ -1151,7 +1148,7 @@ public: /// Some Thread subclasses may maintain a token to help with providing /// an extended backtrace. The SystemRuntime plugin will set/request this. /// - /// \param [in] token + /// \param [in] token The extended backtrace token. virtual void SetExtendedBacktraceToken(uint64_t token) {} /// Gets the extended backtrace token for this thread @@ -1181,17 +1178,17 @@ protected: // be called by classes that derive from Thread in their destructor. virtual void DestroyThread(); - void PushPlan(lldb::ThreadPlanSP &plan_sp); + ThreadPlanStack &GetPlans() const; + + void PushPlan(lldb::ThreadPlanSP plan_sp); void PopPlan(); void DiscardPlan(); - ThreadPlan *GetPreviousPlan(ThreadPlan *plan); + ThreadPlan *GetPreviousPlan(ThreadPlan *plan) const; - typedef std::vector plan_stack; - - virtual lldb_private::Unwind *GetUnwinder(); + virtual Unwind &GetUnwinder(); // Check to see whether the thread is still at the last breakpoint hit that // stopped it. @@ -1215,7 +1212,7 @@ protected: m_temporary_resume_state = new_state; } - void FunctionOptimizationWarning(lldb_private::StackFrame *frame); + void FrameSelectedCallback(lldb_private::StackFrame *frame); // Classes that inherit from Process can see and modify these lldb::ProcessWP m_process_wp; ///< The process that owns this thread. @@ -1234,13 +1231,6 @@ protected: lldb::StateType m_state; ///< The state of our process. mutable std::recursive_mutex m_state_mutex; ///< Multithreaded protection for m_state. - plan_stack m_plan_stack; ///< The stack of plans this thread is executing. - plan_stack m_completed_plan_stack; ///< Plans that have been completed by this - ///stop. They get deleted when the thread - ///resumes. - plan_stack m_discarded_plan_stack; ///< Plans that have been discarded by this - ///stop. They get deleted when the thread - ///resumes. mutable std::recursive_mutex m_frame_mutex; ///< Multithreaded protection for m_state. lldb::StackFrameListSP m_curr_frames_sp; ///< The stack frames that get lazily @@ -1261,20 +1251,19 @@ protected: bool m_destroy_called; // This is used internally to make sure derived Thread // classes call DestroyThread. LazyBool m_override_should_notify; + mutable std::unique_ptr m_null_plan_stack_up; private: bool m_extended_info_fetched; // Have we tried to retrieve the m_extended_info // for this thread? StructuredData::ObjectSP m_extended_info; // The extended info for this thread -private: - bool PlanIsBasePlan(ThreadPlan *plan_ptr); - void BroadcastSelectedFrameChange(StackID &new_frame_id); - DISALLOW_COPY_AND_ASSIGN(Thread); + Thread(const Thread &) = delete; + const Thread &operator=(const Thread &) = delete; }; } // namespace lldb_private -#endif // liblldb_Thread_h_ +#endif // LLDB_TARGET_THREAD_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadCollection.h b/gnu/llvm/lldb/include/lldb/Target/ThreadCollection.h index 29ea827203e..40dc938976f 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadCollection.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadCollection.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadCollection_h_ -#define liblldb_ThreadCollection_h_ +#ifndef LLDB_TARGET_THREADCOLLECTION_H +#define LLDB_TARGET_THREADCOLLECTION_H #include #include @@ -56,4 +56,4 @@ protected: } // namespace lldb_private -#endif // liblldb_ThreadCollection_h_ +#endif // LLDB_TARGET_THREADCOLLECTION_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadList.h b/gnu/llvm/lldb/include/lldb/Target/ThreadList.h index 64ddf5aea50..6af04f8ffc3 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadList.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadList_h_ -#define liblldb_ThreadList_h_ +#ifndef LLDB_TARGET_THREADLIST_H +#define LLDB_TARGET_THREADLIST_H #include #include @@ -156,4 +156,4 @@ private: } // namespace lldb_private -#endif // liblldb_ThreadList_h_ +#endif // LLDB_TARGET_THREADLIST_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlan.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlan.h index ff87ed23cda..8c2f9776eeb 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadPlan.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlan.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadPlan_h_ -#define liblldb_ThreadPlan_h_ +#ifndef LLDB_TARGET_THREADPLAN_H +#define LLDB_TARGET_THREADPLAN_H #include #include @@ -251,7 +251,7 @@ namespace lldb_private { // However, if the plan doesn't want to be // the stop reason, then it can call SetPlanComplete and pass in "false" for // the "success" parameter. In that case, -// the real stop reason will be used instead. One exapmle of this is the +// the real stop reason will be used instead. One example of this is the // "StepRangeStepIn" thread plan. If it stops // because of a crash or breakpoint hit, it wants to unship itself, because it // isn't so useful to have step in keep going @@ -369,16 +369,16 @@ public: /// /// \return /// A pointer to the thread plan's owning thread. - Thread &GetThread() { return m_thread; } + Thread &GetThread(); - const Thread &GetThread() const { return m_thread; } + Target &GetTarget(); - Target &GetTarget() { return m_thread.GetProcess()->GetTarget(); } - - const Target &GetTarget() const { return m_thread.GetProcess()->GetTarget(); } + const Target &GetTarget() const; /// Print a description of this thread to the stream \a s. - /// \a thread. + /// \a thread. Don't expect that the result of GetThread is valid in + /// the description method. This might get called when the underlying + /// Thread has not been reported, so we only know the TID and not the thread. /// /// \param[in] s /// The stream to which to print the description. @@ -461,8 +461,12 @@ public: virtual void WillPop(); // This pushes a plan onto the plan stack of the current plan's thread. + // Also sets the plans to private and not master plans. A plan pushed by + // another thread plan is never either of the above. void PushPlan(lldb::ThreadPlanSP &thread_plan_sp) { - m_thread.PushPlan(thread_plan_sp); + GetThread().PushPlan(thread_plan_sp); + thread_plan_sp->SetPrivate(false); + thread_plan_sp->SetIsMasterPlan(false); } ThreadPlanKind GetKind() const { return m_kind; } @@ -493,7 +497,9 @@ public: // original stop reason so that stopping and calling a few functions won't // lose the history of the run. This call can be implemented to get you back // to the real stop info. - virtual lldb::StopInfoSP GetRealStopInfo() { return m_thread.GetStopInfo(); } + virtual lldb::StopInfoSP GetRealStopInfo() { + return GetThread().GetStopInfo(); + } // If the completion of the thread plan stepped out of a function, the return // value of the function might have been captured by the thread plan @@ -556,17 +562,17 @@ protected: // This is mostly a formal requirement, it allows us to make the Thread's // GetPreviousPlan protected, but only friend ThreadPlan to thread. - ThreadPlan *GetPreviousPlan() { return m_thread.GetPreviousPlan(this); } + ThreadPlan *GetPreviousPlan() { return GetThread().GetPreviousPlan(this); } // This forwards the private Thread::GetPrivateStopInfo which is generally // what ThreadPlan's need to know. lldb::StopInfoSP GetPrivateStopInfo() { - return m_thread.GetPrivateStopInfo(); + return GetThread().GetPrivateStopInfo(); } void SetStopInfo(lldb::StopInfoSP stop_reason_sp) { - m_thread.SetStopInfo(stop_reason_sp); + GetThread().SetStopInfo(stop_reason_sp); } void CachePlanExplainsStop(bool does_explain) { @@ -582,7 +588,8 @@ protected: bool IsUsuallyUnexplainedStopReason(lldb::StopReason); Status m_status; - Thread &m_thread; + Process &m_process; + lldb::tid_t m_tid; Vote m_stop_vote; Vote m_run_vote; bool m_takes_iteration_count; @@ -593,6 +600,9 @@ private: // For ThreadPlan only static lldb::user_id_t GetNextID(); + Thread *m_thread; // Stores a cached value of the thread, which is set to + // nullptr when the thread resumes. Don't use this anywhere + // but ThreadPlan::GetThread(). ThreadPlanKind m_kind; std::string m_name; std::recursive_mutex m_plan_complete_mutex; @@ -605,8 +615,8 @@ private: lldb::ThreadPlanTracerSP m_tracer_sp; -private: - DISALLOW_COPY_AND_ASSIGN(ThreadPlan); + ThreadPlan(const ThreadPlan &) = delete; + const ThreadPlan &operator=(const ThreadPlan &) = delete; }; // ThreadPlanNull: @@ -641,9 +651,10 @@ protected: lldb::StateType GetPlanRunState() override; - DISALLOW_COPY_AND_ASSIGN(ThreadPlanNull); + ThreadPlanNull(const ThreadPlanNull &) = delete; + const ThreadPlanNull &operator=(const ThreadPlanNull &) = delete; }; } // namespace lldb_private -#endif // liblldb_ThreadPlan_h_ +#endif // LLDB_TARGET_THREADPLAN_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanBase.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanBase.h index bc92a06229a..48058a9b40a 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanBase.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanBase.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadPlanFundamental_h_ -#define liblldb_ThreadPlanFundamental_h_ +#ifndef LLDB_TARGET_THREADPLANBASE_H +#define LLDB_TARGET_THREADPLANBASE_H #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" @@ -47,9 +47,10 @@ private: friend lldb::ThreadPlanSP Thread::QueueFundamentalPlan(bool abort_other_plans); - DISALLOW_COPY_AND_ASSIGN(ThreadPlanBase); + ThreadPlanBase(const ThreadPlanBase &) = delete; + const ThreadPlanBase &operator=(const ThreadPlanBase &) = delete; }; } // namespace lldb_private -#endif // liblldb_ThreadPlanFundamental_h_ +#endif // LLDB_TARGET_THREADPLANBASE_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanCallFunction.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanCallFunction.h index 685160a5678..5b432e5e604 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanCallFunction.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanCallFunction.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadPlanCallFunction_h_ -#define liblldb_ThreadPlanCallFunction_h_ +#ifndef LLDB_TARGET_THREADPLANCALLFUNCTION_H +#define LLDB_TARGET_THREADPLANCALLFUNCTION_H #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" @@ -146,9 +146,11 @@ protected: private: CompilerType m_return_type; - DISALLOW_COPY_AND_ASSIGN(ThreadPlanCallFunction); + ThreadPlanCallFunction(const ThreadPlanCallFunction &) = delete; + const ThreadPlanCallFunction & + operator=(const ThreadPlanCallFunction &) = delete; }; } // namespace lldb_private -#endif // liblldb_ThreadPlanCallFunction_h_ +#endif // LLDB_TARGET_THREADPLANCALLFUNCTION_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanCallFunctionUsingABI.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanCallFunctionUsingABI.h index c21e4d3cf3f..af343d8a663 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanCallFunctionUsingABI.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanCallFunctionUsingABI.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadPlanCallFunctionUsingABI_h_ -#define liblldb_ThreadPlanCallFunctionUsingABI_h_ +#ifndef LLDB_TARGET_THREADPLANCALLFUNCTIONUSINGABI_H +#define LLDB_TARGET_THREADPLANCALLFUNCTIONUSINGABI_H #include "lldb/Target/ABI.h" #include "lldb/Target/Thread.h" @@ -44,9 +44,12 @@ protected: private: llvm::Type &m_return_type; - DISALLOW_COPY_AND_ASSIGN(ThreadPlanCallFunctionUsingABI); + ThreadPlanCallFunctionUsingABI(const ThreadPlanCallFunctionUsingABI &) = + delete; + const ThreadPlanCallFunctionUsingABI & + operator=(const ThreadPlanCallFunctionUsingABI &) = delete; }; } // namespace lldb_private -#endif // liblldb_ThreadPlanCallFunctionUsingABI_h_ +#endif // LLDB_TARGET_THREADPLANCALLFUNCTIONUSINGABI_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanCallOnFunctionExit.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanCallOnFunctionExit.h index ad3ee6e0e8f..1dd6a04408e 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanCallOnFunctionExit.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanCallOnFunctionExit.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef ThreadPlanCallOnFunctionExit_h -#define ThreadPlanCallOnFunctionExit_h +#ifndef LLDB_TARGET_THREADPLANCALLONFUNCTIONEXIT_H +#define LLDB_TARGET_THREADPLANCALLONFUNCTIONEXIT_H #include "lldb/Target/ThreadPlan.h" @@ -50,4 +50,4 @@ private: }; } -#endif /* ThreadPlanCallOnFunctionExit_h */ +#endif // LLDB_TARGET_THREADPLANCALLONFUNCTIONEXIT_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h index 63721558241..adaea6c7056 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadPlanCallUserExpression_h_ -#define liblldb_ThreadPlanCallUserExpression_h_ +#ifndef LLDB_TARGET_THREADPLANCALLUSEREXPRESSION_H +#define LLDB_TARGET_THREADPLANCALLUSEREXPRESSION_H #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" @@ -56,9 +56,11 @@ private: m_result_var_sp; // If we are left to manage the materialization, // then stuff the result expression variable here. - DISALLOW_COPY_AND_ASSIGN(ThreadPlanCallUserExpression); + ThreadPlanCallUserExpression(const ThreadPlanCallUserExpression &) = delete; + const ThreadPlanCallUserExpression & + operator=(const ThreadPlanCallUserExpression &) = delete; }; } // namespace lldb_private -#endif // liblldb_ThreadPlanCallUserExpression_h_ +#endif // LLDB_TARGET_THREADPLANCALLUSEREXPRESSION_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanPython.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanPython.h index 0ee559b1296..27bf3a560b1 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanPython.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanPython.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadPlan_Python_h_ -#define liblldb_ThreadPlan_Python_h_ +#ifndef LLDB_TARGET_THREADPLANPYTHON_H +#define LLDB_TARGET_THREADPLANPYTHON_H #include @@ -55,6 +55,8 @@ protected: bool DoPlanExplainsStop(Event *event_ptr) override; lldb::StateType GetPlanRunState() override; + + ScriptInterpreter *GetScriptInterpreter(); private: std::string m_class_name; @@ -66,9 +68,10 @@ private: StructuredData::ObjectSP m_implementation_sp; bool m_did_push; - DISALLOW_COPY_AND_ASSIGN(ThreadPlanPython); + ThreadPlanPython(const ThreadPlanPython &) = delete; + const ThreadPlanPython &operator=(const ThreadPlanPython &) = delete; }; } // namespace lldb_private -#endif // liblldb_ThreadPlan_Python_h_ +#endif // LLDB_TARGET_THREADPLANPYTHON_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanRunToAddress.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanRunToAddress.h index d82a9fad548..10b8ec658cd 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanRunToAddress.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanRunToAddress.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadPlanRunToAddress_h_ -#define liblldb_ThreadPlanRunToAddress_h_ +#ifndef LLDB_TARGET_THREADPLANRUNTOADDRESS_H +#define LLDB_TARGET_THREADPLANRUNTOADDRESS_H #include @@ -59,9 +59,11 @@ private: std::vector m_break_ids; // This is the breakpoint we are // using to stop us at m_address. - DISALLOW_COPY_AND_ASSIGN(ThreadPlanRunToAddress); + ThreadPlanRunToAddress(const ThreadPlanRunToAddress &) = delete; + const ThreadPlanRunToAddress & + operator=(const ThreadPlanRunToAddress &) = delete; }; } // namespace lldb_private -#endif // liblldb_ThreadPlanRunToAddress_h_ +#endif // LLDB_TARGET_THREADPLANRUNTOADDRESS_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h index dfcbbb355c5..54b30291c39 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadPlanShouldStopHere_h_ -#define liblldb_ThreadPlanShouldStopHere_h_ +#ifndef LLDB_TARGET_THREADPLANSHOULDSTOPHERE_H +#define LLDB_TARGET_THREADPLANSHOULDSTOPHERE_H #include "lldb/Target/ThreadPlan.h" @@ -130,9 +130,11 @@ protected: lldb_private::Flags m_flags; private: - DISALLOW_COPY_AND_ASSIGN(ThreadPlanShouldStopHere); + ThreadPlanShouldStopHere(const ThreadPlanShouldStopHere &) = delete; + const ThreadPlanShouldStopHere & + operator=(const ThreadPlanShouldStopHere &) = delete; }; } // namespace lldb_private -#endif // liblldb_ThreadPlanShouldStopHere_h_ +#endif // LLDB_TARGET_THREADPLANSHOULDSTOPHERE_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStack.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStack.h new file mode 100644 index 00000000000..f1874136cad --- /dev/null +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStack.h @@ -0,0 +1,173 @@ +//===-- ThreadPlanStack.h ---------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_TARGET_THREADPLANSTACK_H +#define LLDB_TARGET_THREADPLANSTACK_H + +#include +#include +#include +#include + +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/lldb-private-forward.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +// The ThreadPlans have a thread for use when they are asked all the ThreadPlan +// state machine questions, but they should never cache any pointers from their +// owning lldb_private::Thread. That's because we want to be able to detach +// them from an owning thread, then reattach them by TID. +// The ThreadPlanStack holds the ThreadPlans for a given TID. All its methods +// are private, and it should only be accessed through the owning thread. When +// it is detached from a thread, all you can do is reattach it or delete it. +class ThreadPlanStack { + friend class lldb_private::Thread; + +public: + ThreadPlanStack(const Thread &thread, bool make_empty = false); + ~ThreadPlanStack() {} + + enum StackKind { ePlans, eCompletedPlans, eDiscardedPlans }; + + using PlanStack = std::vector; + + void DumpThreadPlans(Stream &s, lldb::DescriptionLevel desc_level, + bool include_internal) const; + + size_t CheckpointCompletedPlans(); + + void RestoreCompletedPlanCheckpoint(size_t checkpoint); + + void DiscardCompletedPlanCheckpoint(size_t checkpoint); + + void ThreadDestroyed(Thread *thread); + + void EnableTracer(bool value, bool single_stepping); + + void SetTracer(lldb::ThreadPlanTracerSP &tracer_sp); + + void PushPlan(lldb::ThreadPlanSP new_plan_sp); + + lldb::ThreadPlanSP PopPlan(); + + lldb::ThreadPlanSP DiscardPlan(); + + // If the input plan is nullptr, discard all plans. Otherwise make sure this + // plan is in the stack, and if so discard up to and including it. + void DiscardPlansUpToPlan(ThreadPlan *up_to_plan_ptr); + + void DiscardAllPlans(); + + void DiscardConsultingMasterPlans(); + + lldb::ThreadPlanSP GetCurrentPlan() const; + + lldb::ThreadPlanSP GetCompletedPlan(bool skip_private = true) const; + + lldb::ThreadPlanSP GetPlanByIndex(uint32_t plan_idx, + bool skip_private = true) const; + + lldb::ValueObjectSP GetReturnValueObject() const; + + lldb::ExpressionVariableSP GetExpressionVariable() const; + + bool AnyPlans() const; + + bool AnyCompletedPlans() const; + + bool AnyDiscardedPlans() const; + + bool IsPlanDone(ThreadPlan *plan) const; + + bool WasPlanDiscarded(ThreadPlan *plan) const; + + ThreadPlan *GetPreviousPlan(ThreadPlan *current_plan) const; + + ThreadPlan *GetInnermostExpression() const; + + void WillResume(); + +private: + const PlanStack &GetStackOfKind(ThreadPlanStack::StackKind kind) const; + + void PrintOneStack(Stream &s, llvm::StringRef stack_name, + const PlanStack &stack, lldb::DescriptionLevel desc_level, + bool include_internal) const; + + PlanStack m_plans; ///< The stack of plans this thread is executing. + PlanStack m_completed_plans; ///< Plans that have been completed by this + /// stop. They get deleted when the thread + /// resumes. + PlanStack m_discarded_plans; ///< Plans that have been discarded by this + /// stop. They get deleted when the thread + /// resumes. + size_t m_completed_plan_checkpoint = 0; // Monotonically increasing token for + // completed plan checkpoints. + std::unordered_map m_completed_plan_store; +}; + +class ThreadPlanStackMap { +public: + ThreadPlanStackMap(Process &process) : m_process(process) {} + ~ThreadPlanStackMap() {} + + // Prune the map using the current_threads list. + void Update(ThreadList ¤t_threads, bool delete_missing, + bool check_for_new = true); + + void AddThread(Thread &thread) { + lldb::tid_t tid = thread.GetID(); + m_plans_list.emplace(tid, thread); + } + + bool RemoveTID(lldb::tid_t tid) { + auto result = m_plans_list.find(tid); + if (result == m_plans_list.end()) + return false; + result->second.ThreadDestroyed(nullptr); + m_plans_list.erase(result); + return true; + } + + ThreadPlanStack *Find(lldb::tid_t tid) { + auto result = m_plans_list.find(tid); + if (result == m_plans_list.end()) + return nullptr; + else + return &result->second; + } + + void Clear() { + for (auto plan : m_plans_list) + plan.second.ThreadDestroyed(nullptr); + m_plans_list.clear(); + } + + // Implements Process::DumpThreadPlans + void DumpPlans(Stream &strm, lldb::DescriptionLevel desc_level, bool internal, + bool ignore_boring, bool skip_unreported); + + // Implements Process::DumpThreadPlansForTID + bool DumpPlansForTID(Stream &strm, lldb::tid_t tid, + lldb::DescriptionLevel desc_level, bool internal, + bool ignore_boring, bool skip_unreported); + + bool PrunePlansForTID(lldb::tid_t tid); + +private: + Process &m_process; + using PlansList = std::unordered_map; + PlansList m_plans_list; +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_THREADPLANSTACK_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepInRange.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepInRange.h index a120c98fb36..59b5721998b 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepInRange.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepInRange.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadPlanStepInRange_h_ -#define liblldb_ThreadPlanStepInRange_h_ +#ifndef LLDB_TARGET_THREADPLANSTEPINRANGE_H +#define LLDB_TARGET_THREADPLANSTEPINRANGE_H #include "lldb/Core/AddressRange.h" #include "lldb/Target/StackID.h" @@ -49,6 +49,12 @@ public: bool IsVirtualStep() override; + // Plans that are implementing parts of a step in might need to follow the + // behavior of this plan w.r.t. StepThrough. They can get that from here. + static uint32_t GetDefaultFlagsValue() { + return s_default_flag_values; + } + protected: static bool DefaultShouldStopHereCallback(ThreadPlan *current_plan, Flags &flags, @@ -99,9 +105,11 @@ private: bool m_virtual_step; // true if we've just done a "virtual step", i.e. just // moved the inline stack depth. ConstString m_step_into_target; - DISALLOW_COPY_AND_ASSIGN(ThreadPlanStepInRange); + ThreadPlanStepInRange(const ThreadPlanStepInRange &) = delete; + const ThreadPlanStepInRange & + operator=(const ThreadPlanStepInRange &) = delete; }; } // namespace lldb_private -#endif // liblldb_ThreadPlanStepInRange_h_ +#endif // LLDB_TARGET_THREADPLANSTEPINRANGE_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepInstruction.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepInstruction.h index 127de417f6e..760bc4886fa 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepInstruction.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepInstruction.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadPlanStepInstruction_h_ -#define liblldb_ThreadPlanStepInstruction_h_ +#ifndef LLDB_TARGET_THREADPLANSTEPINSTRUCTION_H +#define LLDB_TARGET_THREADPLANSTEPINSTRUCTION_H #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" @@ -49,9 +49,11 @@ private: StackID m_stack_id; StackID m_parent_frame_id; - DISALLOW_COPY_AND_ASSIGN(ThreadPlanStepInstruction); + ThreadPlanStepInstruction(const ThreadPlanStepInstruction &) = delete; + const ThreadPlanStepInstruction & + operator=(const ThreadPlanStepInstruction &) = delete; }; } // namespace lldb_private -#endif // liblldb_ThreadPlanStepInstruction_h_ +#endif // LLDB_TARGET_THREADPLANSTEPINSTRUCTION_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepOut.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepOut.h index 576b416c3f2..5c39232fd2e 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepOut.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepOut.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadPlanStepOut_h_ -#define liblldb_ThreadPlanStepOut_h_ +#ifndef LLDB_TARGET_THREADPLANSTEPOUT_H +#define LLDB_TARGET_THREADPLANSTEPOUT_H #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" @@ -85,9 +85,10 @@ private: void CalculateReturnValue(); - DISALLOW_COPY_AND_ASSIGN(ThreadPlanStepOut); + ThreadPlanStepOut(const ThreadPlanStepOut &) = delete; + const ThreadPlanStepOut &operator=(const ThreadPlanStepOut &) = delete; }; } // namespace lldb_private -#endif // liblldb_ThreadPlanStepOut_h_ +#endif // LLDB_TARGET_THREADPLANSTEPOUT_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h index 7df7049b568..86f7798487c 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadPlanStepOverBreakpoint_h_ -#define liblldb_ThreadPlanStepOverBreakpoint_h_ +#ifndef LLDB_TARGET_THREADPLANSTEPOVERBREAKPOINT_H +#define LLDB_TARGET_THREADPLANSTEPOVERBREAKPOINT_H #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" @@ -47,9 +47,11 @@ private: bool m_auto_continue; bool m_reenabled_breakpoint_site; - DISALLOW_COPY_AND_ASSIGN(ThreadPlanStepOverBreakpoint); + ThreadPlanStepOverBreakpoint(const ThreadPlanStepOverBreakpoint &) = delete; + const ThreadPlanStepOverBreakpoint & + operator=(const ThreadPlanStepOverBreakpoint &) = delete; }; } // namespace lldb_private -#endif // liblldb_ThreadPlanStepOverBreakpoint_h_ +#endif // LLDB_TARGET_THREADPLANSTEPOVERBREAKPOINT_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepOverRange.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepOverRange.h index 30763e3861f..8585ac62f09 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepOverRange.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepOverRange.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadPlanStepOverRange_h_ -#define liblldb_ThreadPlanStepOverRange_h_ +#ifndef LLDB_TARGET_THREADPLANSTEPOVERRANGE_H +#define LLDB_TARGET_THREADPLANSTEPOVERRANGE_H #include "lldb/Core/AddressRange.h" #include "lldb/Target/StackID.h" @@ -45,9 +45,11 @@ private: bool m_first_resume; - DISALLOW_COPY_AND_ASSIGN(ThreadPlanStepOverRange); + ThreadPlanStepOverRange(const ThreadPlanStepOverRange &) = delete; + const ThreadPlanStepOverRange & + operator=(const ThreadPlanStepOverRange &) = delete; }; } // namespace lldb_private -#endif // liblldb_ThreadPlanStepOverRange_h_ +#endif // LLDB_TARGET_THREADPLANSTEPOVERRANGE_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepRange.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepRange.h index 28209623a1e..2fe88527710 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepRange.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepRange.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadPlanStepRange_h_ -#define liblldb_ThreadPlanStepRange_h_ +#ifndef LLDB_TARGET_THREADPLANSTEPRANGE_H +#define LLDB_TARGET_THREADPLANSTEPRANGE_H #include "lldb/Core/AddressRange.h" #include "lldb/Target/StackID.h" @@ -86,9 +86,10 @@ protected: private: std::vector m_instruction_ranges; - DISALLOW_COPY_AND_ASSIGN(ThreadPlanStepRange); + ThreadPlanStepRange(const ThreadPlanStepRange &) = delete; + const ThreadPlanStepRange &operator=(const ThreadPlanStepRange &) = delete; }; } // namespace lldb_private -#endif // liblldb_ThreadPlanStepRange_h_ +#endif // LLDB_TARGET_THREADPLANSTEPRANGE_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepThrough.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepThrough.h index 0d0621227b5..89262258e87 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepThrough.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepThrough.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadPlanStepThrough_h_ -#define liblldb_ThreadPlanStepThrough_h_ +#ifndef LLDB_TARGET_THREADPLANSTEPTHROUGH_H +#define LLDB_TARGET_THREADPLANSTEPTHROUGH_H #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" @@ -53,9 +53,11 @@ private: StackID m_return_stack_id; bool m_stop_others; - DISALLOW_COPY_AND_ASSIGN(ThreadPlanStepThrough); + ThreadPlanStepThrough(const ThreadPlanStepThrough &) = delete; + const ThreadPlanStepThrough & + operator=(const ThreadPlanStepThrough &) = delete; }; } // namespace lldb_private -#endif // liblldb_ThreadPlanStepThrough_h_ +#endif // LLDB_TARGET_THREADPLANSTEPTHROUGH_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepUntil.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepUntil.h index 9a5934a36d7..27e1f85e9cb 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepUntil.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanStepUntil.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadPlanStepUntil_h_ -#define liblldb_ThreadPlanStepUntil_h_ +#ifndef LLDB_TARGET_THREADPLANSTEPUNTIL_H +#define LLDB_TARGET_THREADPLANSTEPUNTIL_H #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" @@ -59,9 +59,10 @@ private: // Need an appropriate marker for the current stack so we can tell step out // from step in. - DISALLOW_COPY_AND_ASSIGN(ThreadPlanStepUntil); + ThreadPlanStepUntil(const ThreadPlanStepUntil &) = delete; + const ThreadPlanStepUntil &operator=(const ThreadPlanStepUntil &) = delete; }; } // namespace lldb_private -#endif // liblldb_ThreadPlanStepUntil_h_ +#endif // LLDB_TARGET_THREADPLANSTEPUNTIL_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanTracer.h b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanTracer.h index 80b08078e97..677a2c0dd93 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadPlanTracer.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadPlanTracer.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadPlanTracer_h_ -#define liblldb_ThreadPlanTracer_h_ +#ifndef LLDB_TARGET_THREADPLANTRACER_H +#define LLDB_TARGET_THREADPLANTRACER_H #include "lldb/Symbol/TaggedASTType.h" #include "lldb/Target/Thread.h" @@ -57,9 +57,12 @@ public: } bool SingleStepEnabled() { return m_single_step; } + + Thread &GetThread(); protected: - Thread &m_thread; + Process &m_process; + lldb::tid_t m_tid; Stream *GetLogStream(); @@ -71,6 +74,7 @@ private: bool m_single_step; bool m_enabled; lldb::StreamSP m_stream_sp; + Thread *m_thread; }; class ThreadPlanAssemblyTracer : public ThreadPlanTracer { @@ -96,4 +100,4 @@ private: } // namespace lldb_private -#endif // liblldb_ThreadPlanTracer_h_ +#endif // LLDB_TARGET_THREADPLANTRACER_H diff --git a/gnu/llvm/lldb/include/lldb/Target/ThreadSpec.h b/gnu/llvm/lldb/include/lldb/Target/ThreadSpec.h index 05e7dcdb38d..8c22d53185f 100644 --- a/gnu/llvm/lldb/include/lldb/Target/ThreadSpec.h +++ b/gnu/llvm/lldb/include/lldb/Target/ThreadSpec.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadSpec_h_ -#define liblldb_ThreadSpec_h_ +#ifndef LLDB_TARGET_THREADSPEC_H +#define LLDB_TARGET_THREADSPEC_H #include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private.h" @@ -46,9 +46,11 @@ public: void SetTID(lldb::tid_t tid) { m_tid = tid; } - void SetName(llvm::StringRef name) { m_name = name; } + void SetName(llvm::StringRef name) { m_name = std::string(name); } - void SetQueueName(llvm::StringRef queue_name) { m_queue_name = queue_name; } + void SetQueueName(llvm::StringRef queue_name) { + m_queue_name = std::string(queue_name); + } uint32_t GetIndex() const { return m_index; } @@ -126,4 +128,4 @@ private: } // namespace lldb_private -#endif // liblldb_ThreadSpec_h_ +#endif // LLDB_TARGET_THREADSPEC_H diff --git a/gnu/llvm/lldb/include/lldb/Target/UnixSignals.h b/gnu/llvm/lldb/include/lldb/Target/UnixSignals.h index 120ffdd7ae2..cc24b76e4c3 100644 --- a/gnu/llvm/lldb/include/lldb/Target/UnixSignals.h +++ b/gnu/llvm/lldb/include/lldb/Target/UnixSignals.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_UnixSignals_h_ -#define lldb_UnixSignals_h_ +#ifndef LLDB_TARGET_UNIXSIGNALS_H +#define LLDB_TARGET_UNIXSIGNALS_H #include #include @@ -126,4 +126,4 @@ protected: }; } // Namespace lldb -#endif // lldb_UnixSignals_h_ +#endif // LLDB_TARGET_UNIXSIGNALS_H diff --git a/gnu/llvm/lldb/include/lldb/Target/Unwind.h b/gnu/llvm/lldb/include/lldb/Target/Unwind.h index 652918ddad4..783b7103e8f 100644 --- a/gnu/llvm/lldb/include/lldb/Target/Unwind.h +++ b/gnu/llvm/lldb/include/lldb/Target/Unwind.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Unwind_h_ -#define liblldb_Unwind_h_ +#ifndef LLDB_TARGET_UNWIND_H +#define LLDB_TARGET_UNWIND_H #include @@ -77,9 +77,10 @@ protected: std::recursive_mutex m_unwind_mutex; private: - DISALLOW_COPY_AND_ASSIGN(Unwind); + Unwind(const Unwind &) = delete; + const Unwind &operator=(const Unwind &) = delete; }; } // namespace lldb_private -#endif // liblldb_Unwind_h_ +#endif // LLDB_TARGET_UNWIND_H diff --git a/gnu/llvm/lldb/include/lldb/Target/UnwindAssembly.h b/gnu/llvm/lldb/include/lldb/Target/UnwindAssembly.h index a70aef6e93c..abfd3877439 100644 --- a/gnu/llvm/lldb/include/lldb/Target/UnwindAssembly.h +++ b/gnu/llvm/lldb/include/lldb/Target/UnwindAssembly.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_UnwindAssembly_h_ -#define utility_UnwindAssembly_h_ +#ifndef LLDB_TARGET_UNWINDASSEMBLY_H +#define LLDB_TARGET_UNWINDASSEMBLY_H #include "lldb/Core/PluginInterface.h" #include "lldb/Utility/ArchSpec.h" @@ -45,9 +45,10 @@ protected: private: UnwindAssembly() = delete; - DISALLOW_COPY_AND_ASSIGN(UnwindAssembly); + UnwindAssembly(const UnwindAssembly &) = delete; + const UnwindAssembly &operator=(const UnwindAssembly &) = delete; }; } // namespace lldb_private -#endif // utility_UnwindAssembly_h_ +#endif // LLDB_TARGET_UNWINDASSEMBLY_H diff --git a/gnu/llvm/lldb/include/lldb/Target/UnwindLLDB.h b/gnu/llvm/lldb/include/lldb/Target/UnwindLLDB.h new file mode 100644 index 00000000000..c7c9cfbccba --- /dev/null +++ b/gnu/llvm/lldb/include/lldb/Target/UnwindLLDB.h @@ -0,0 +1,159 @@ +//===-- UnwindLLDB.h --------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_TARGET_UNWINDLLDB_H +#define LLDB_TARGET_UNWINDLLDB_H + +#include + +#include "lldb/Symbol/FuncUnwinders.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Unwind.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/lldb-public.h" + +namespace lldb_private { + +class RegisterContextUnwind; + +class UnwindLLDB : public lldb_private::Unwind { +public: + UnwindLLDB(lldb_private::Thread &thread); + + ~UnwindLLDB() override = default; + + enum RegisterSearchResult { + eRegisterFound = 0, + eRegisterNotFound, + eRegisterIsVolatile + }; + +protected: + friend class lldb_private::RegisterContextUnwind; + + struct RegisterLocation { + enum RegisterLocationTypes { + eRegisterNotSaved = 0, // register was not preserved by callee. If + // volatile reg, is unavailable + eRegisterSavedAtMemoryLocation, // register is saved at a specific word of + // target mem (target_memory_location) + eRegisterInRegister, // register is available in a (possible other) + // register (register_number) + eRegisterSavedAtHostMemoryLocation, // register is saved at a word in + // lldb's address space + eRegisterValueInferred, // register val was computed (and is in + // inferred_value) + eRegisterInLiveRegisterContext // register value is in a live (stack frame + // #0) register + }; + int type; + union { + lldb::addr_t target_memory_location; + uint32_t + register_number; // in eRegisterKindLLDB register numbering system + void *host_memory_location; + uint64_t inferred_value; // eRegisterValueInferred - e.g. stack pointer == + // cfa + offset + } location; + }; + + void DoClear() override { + m_frames.clear(); + m_candidate_frame.reset(); + m_unwind_complete = false; + } + + uint32_t DoGetFrameCount() override; + + bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, + lldb::addr_t &start_pc, + bool &behaves_like_zeroth_frame) override; + + lldb::RegisterContextSP + DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override; + + typedef std::shared_ptr RegisterContextLLDBSP; + + // Needed to retrieve the "next" frame (e.g. frame 2 needs to retrieve frame + // 1's RegisterContextUnwind) + // The RegisterContext for frame_num must already exist or this returns an + // empty shared pointer. + RegisterContextLLDBSP GetRegisterContextForFrameNum(uint32_t frame_num); + + // Iterate over the RegisterContextUnwind's in our m_frames vector, look for + // the first one that has a saved location for this reg. + bool SearchForSavedLocationForRegister( + uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, + uint32_t starting_frame_num, bool pc_register); + + /// Provide the list of user-specified trap handler functions + /// + /// The Platform is one source of trap handler function names; that + /// may be augmented via a setting. The setting needs to be converted + /// into an array of ConstStrings before it can be used - we only want + /// to do that once per thread so it's here in the UnwindLLDB object. + /// + /// \return + /// Vector of ConstStrings of trap handler function names. May be + /// empty. + const std::vector &GetUserSpecifiedTrapHandlerFunctionNames() { + return m_user_supplied_trap_handler_functions; + } + +private: + struct Cursor { + lldb::addr_t start_pc; // The start address of the function/symbol for this + // frame - current pc if unknown + lldb::addr_t cfa; // The canonical frame address for this stack frame + lldb_private::SymbolContext sctx; // A symbol context we'll contribute to & + // provide to the StackFrame creation + RegisterContextLLDBSP + reg_ctx_lldb_sp; // These are all RegisterContextUnwind's + + Cursor() + : start_pc(LLDB_INVALID_ADDRESS), cfa(LLDB_INVALID_ADDRESS), sctx(), + reg_ctx_lldb_sp() {} + + private: + Cursor(const Cursor &) = delete; + const Cursor &operator=(const Cursor &) = delete; + }; + + typedef std::shared_ptr CursorSP; + std::vector m_frames; + CursorSP m_candidate_frame; + bool m_unwind_complete; // If this is true, we've enumerated all the frames in + // the stack, and m_frames.size() is the + // number of frames, etc. Otherwise we've only gone as far as directly asked, + // and m_frames.size() + // is how far we've currently gone. + + std::vector m_user_supplied_trap_handler_functions; + + // Check if Full UnwindPlan of First frame is valid or not. + // If not then try Fallback UnwindPlan of the frame. If Fallback + // UnwindPlan succeeds then update the Full UnwindPlan with the + // Fallback UnwindPlan. + void UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi); + + CursorSP GetOneMoreFrame(ABI *abi); + + bool AddOneMoreFrame(ABI *abi); + + bool AddFirstFrame(); + + // For UnwindLLDB only + UnwindLLDB(const UnwindLLDB &) = delete; + const UnwindLLDB &operator=(const UnwindLLDB &) = delete; +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_UNWINDLLDB_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/AnsiTerminal.h b/gnu/llvm/lldb/include/lldb/Utility/AnsiTerminal.h index 21375e3821c..c391adb2cf8 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/AnsiTerminal.h +++ b/gnu/llvm/lldb/include/lldb/Utility/AnsiTerminal.h @@ -1,3 +1,7 @@ +#ifndef LLDB_UTILITY_ANSITERMINAL_H + +#define LLDB_UTILITY_ANSITERMINAL_H + //===---------------------AnsiTerminal.h ------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -111,7 +115,7 @@ inline std::string FormatAnsiTerminalCodes(llvm::StringRef format, llvm::StringRef left, right; std::tie(left, right) = format.split(tok_hdr); - fmt.append(left); + fmt += left; if (left == format && right.empty()) { // The header was not found. Just exit. @@ -138,3 +142,5 @@ inline std::string FormatAnsiTerminalCodes(llvm::StringRef format, } } } // namespace lldb_private + +#endif diff --git a/gnu/llvm/lldb/include/lldb/Utility/ArchSpec.h b/gnu/llvm/lldb/include/lldb/Utility/ArchSpec.h index f3fdc7e56d9..5466e573c1a 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/ArchSpec.h +++ b/gnu/llvm/lldb/include/lldb/Utility/ArchSpec.h @@ -16,6 +16,7 @@ #include "lldb/lldb-private-enumerations.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" +#include "llvm/Support/YAMLTraits.h" #include #include #include @@ -179,7 +180,6 @@ public: eCore_x86_64_x86_64, eCore_x86_64_x86_64h, // Haswell enabled x86_64 - eCore_x86_64_amd64, eCore_hexagon_generic, eCore_hexagon_hexagonv4, eCore_hexagon_hexagonv5, @@ -189,6 +189,10 @@ public: eCore_arc, // little endian ARC + eCore_avr, + + eCore_wasm32, + kNumCores, kCore_invalid, @@ -538,4 +542,16 @@ bool ParseMachCPUDashSubtypeTriple(llvm::StringRef triple_str, ArchSpec &arch); } // namespace lldb_private -#endif // #ifndef LLDB_UTILITY_ARCHSPEC_H +namespace llvm { +namespace yaml { +template <> struct ScalarTraits { + static void output(const lldb_private::ArchSpec &, void *, raw_ostream &); + static StringRef input(StringRef, void *, lldb_private::ArchSpec &); + static QuotingType mustQuote(StringRef S) { return QuotingType::Double; } +}; +} // namespace yaml +} // namespace llvm + +LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::ArchSpec) + +#endif // LLDB_UTILITY_ARCHSPEC_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/Args.h b/gnu/llvm/lldb/include/lldb/Utility/Args.h index 1308f4038db..2cce7d0c697 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/Args.h +++ b/gnu/llvm/lldb/include/lldb/Utility/Args.h @@ -14,6 +14,7 @@ #include "lldb/lldb-types.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/YAMLTraits.h" #include #include #include @@ -34,6 +35,9 @@ public: struct ArgEntry { private: friend class Args; + friend struct llvm::yaml::MappingTraits; + friend struct llvm::yaml::MappingTraits; + std::unique_ptr ptr; char quote; @@ -283,6 +287,8 @@ public: char quote_char); private: + friend struct llvm::yaml::MappingTraits; + std::vector m_entries; std::vector m_argv; }; @@ -373,4 +379,28 @@ private: } // namespace lldb_private +namespace llvm { +namespace yaml { +template <> struct MappingTraits { + class NormalizedArgEntry { + public: + NormalizedArgEntry(IO &) {} + NormalizedArgEntry(IO &, lldb_private::Args::ArgEntry &entry) + : value(entry.ref()), quote(entry.quote) {} + lldb_private::Args::ArgEntry denormalize(IO &) { + return lldb_private::Args::ArgEntry(value, quote); + } + StringRef value; + uint8_t quote; + }; + static void mapping(IO &io, lldb_private::Args::ArgEntry &v); +}; +template <> struct MappingTraits { + static void mapping(IO &io, lldb_private::Args &v); +}; +} // namespace yaml +} // namespace llvm + +LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::Args::ArgEntry) + #endif // LLDB_UTILITY_ARGS_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/Baton.h b/gnu/llvm/lldb/include/lldb/Utility/Baton.h index c42867489c6..010f8da4386 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/Baton.h +++ b/gnu/llvm/lldb/include/lldb/Utility/Baton.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Baton_h_ -#define lldb_Baton_h_ +#ifndef LLDB_UTILITY_BATON_H +#define LLDB_UTILITY_BATON_H #include "lldb/lldb-enumerations.h" #include "lldb/lldb-public.h" @@ -76,4 +76,4 @@ protected: } // namespace lldb_private -#endif // lldb_Baton_h_ +#endif // LLDB_UTILITY_BATON_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/Broadcaster.h b/gnu/llvm/lldb/include/lldb/Utility/Broadcaster.h index ead597d626d..03995454ecb 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/Broadcaster.h +++ b/gnu/llvm/lldb/include/lldb/Utility/Broadcaster.h @@ -259,19 +259,6 @@ public: void CheckInWithManager(); /// Broadcast an event which has no associated data. - /// - /// \param[in] event_type - /// The element from the enum defining this broadcaster's events - /// that is being broadcast. - /// - /// \param[in] event_data - /// User event data that will be owned by the lldb::Event that - /// is created internally. - /// - /// \param[in] unique - /// If true, then only add an event of this type if there isn't - /// one already in the queue. - /// void BroadcastEvent(lldb::EventSP &event_sp) { m_broadcaster_sp->BroadcastEvent(event_sp); } @@ -308,7 +295,7 @@ public: /// different from what is requested in \a event_mask, and to track this the /// actual event bits that are acquired get returned. /// - /// \param[in] listener + /// \param[in] listener_sp /// The Listener object that wants to monitor the events that /// get broadcast by this object. /// @@ -347,9 +334,6 @@ public: /// \param[in] event_mask /// A bit mask that indicates which events the listener is /// asking to monitor. - /// - /// \return - /// The NULL terminated C string name of this Broadcaster. void SetEventName(uint32_t event_mask, const char *name) { m_broadcaster_sp->SetEventName(event_mask, name); } @@ -367,7 +351,7 @@ public: /// (assuming \a listener was listening to this object) for other listener /// objects to use. /// - /// \param[in] listener + /// \param[in] listener_sp /// A Listener object that previously called AddListener. /// /// \param[in] event_mask @@ -389,7 +373,7 @@ public: /// now go to the hijacking listener. Only one hijack can occur at a time. /// If we need more than this we will have to implement a Listener stack. /// - /// \param[in] listener + /// \param[in] listener_sp /// A Listener object. You do not need to call StartListeningForEvents /// for this broadcaster (that would fail anyway since the event bits /// would most likely be taken by the listener(s) you are usurping. @@ -530,7 +514,8 @@ protected: std::vector m_hijacking_masks; private: - DISALLOW_COPY_AND_ASSIGN(BroadcasterImpl); + BroadcasterImpl(const BroadcasterImpl &) = delete; + const BroadcasterImpl &operator=(const BroadcasterImpl &) = delete; }; typedef std::shared_ptr BroadcasterImplSP; @@ -549,7 +534,8 @@ private: /// The name of this broadcaster object. const ConstString m_broadcaster_name; - DISALLOW_COPY_AND_ASSIGN(Broadcaster); + Broadcaster(const Broadcaster &) = delete; + const Broadcaster &operator=(const Broadcaster &) = delete; }; } // namespace lldb_private diff --git a/gnu/llvm/lldb/include/lldb/Utility/CompletionRequest.h b/gnu/llvm/lldb/include/lldb/Utility/CompletionRequest.h index 570f626ac54..1fbc96944e8 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/CompletionRequest.h +++ b/gnu/llvm/lldb/include/lldb/Utility/CompletionRequest.h @@ -17,16 +17,21 @@ namespace lldb_private { enum class CompletionMode { - // The current token has been completed. + /// The current token has been completed. The client should indicate this + /// to the user (usually this is done by adding a trailing space behind the + /// token). + /// Example: "command sub" -> "command subcommand " (note the trailing space). Normal, - // The current token has been partially completed. This means that we found - // a completion, but that the completed token is still incomplete. Examples - // for this are file paths, where we want to complete "/bi" to "/bin/", but - // the file path token is still incomplete after the completion. Clients - // should not indicate to the user that this is a full completion (e.g. by - // not inserting the usual trailing space after a successful completion). + /// The current token has been partially completed. This means that we found + /// a completion, but that the token is still incomplete. Examples + /// for this are file paths, where we want to complete "/bi" to "/bin/", but + /// the file path token is still incomplete after the completion. Clients + /// should not indicate to the user that this is a full completion (e.g. by + /// not inserting the usual trailing space after a successful completion). + /// Example: "file /us" -> "file /usr/" (note the missing trailing space). Partial, - // The full line has been rewritten by the completion. + /// The full line has been rewritten by the completion. + /// Example: "alias name" -> "other_command full_name". RewriteLine, }; @@ -35,7 +40,12 @@ public: /// A single completion and all associated data. class Completion { + /// The actual text that should be completed. The meaning of this text + /// is defined by the CompletionMode. + /// \see m_mode std::string m_completion; + /// The description that should be displayed to the user alongside the + /// completion text. std::string m_descripton; CompletionMode m_mode; @@ -53,9 +63,12 @@ public: }; private: + /// List of found completions. std::vector m_results; - /// List of added completions so far. Used to filter out duplicates. + /// A set of the unique keys of all found completions so far. Used to filter + /// out duplicates. + /// \see CompletionResult::Completion::GetUniqueKey llvm::StringSet<> m_added_values; public: @@ -102,7 +115,19 @@ public: CompletionRequest(llvm::StringRef command_line, unsigned raw_cursor_pos, CompletionResult &result); - llvm::StringRef GetRawLine() const { return m_command; } + /// Returns the raw user input used to create this CompletionRequest cut off + /// at the cursor position. The cursor will be at the end of the raw line. + llvm::StringRef GetRawLine() const { + return m_command.substr(0, GetRawCursorPos()); + } + + /// Returns the full raw user input used to create this CompletionRequest. + /// This string is not cut off at the cursor position and will include + /// characters behind the cursor position. + /// + /// You should most likely *not* use this function unless the characters + /// behind the cursor position influence the completion. + llvm::StringRef GetRawLineWithUnusedSuffix() const { return m_command; } unsigned GetRawCursorPos() const { return m_raw_cursor_pos; } @@ -135,8 +160,8 @@ public: /// the suggested completion is stored, so the given string can be free'd /// afterwards. /// - /// \param match The suggested completion. - /// \param completion An optional description of the completion string. The + /// \param completion The suggested completion. + /// \param description An optional description of the completion string. The /// description will be displayed to the user alongside the completion. /// \param mode The CompletionMode for this completion. void AddCompletion(llvm::StringRef completion, @@ -148,7 +173,7 @@ public: /// Adds a possible completion string if the completion would complete the /// current argument. /// - /// \param match The suggested completion. + /// \param completion The suggested completion. /// \param description An optional description of the completion string. The /// description will be displayed to the user alongside the completion. template @@ -178,7 +203,7 @@ public: /// The number of completions and descriptions must be identical. /// /// \param completions The list of completions. - /// \param completions The list of descriptions. + /// \param descriptions The list of descriptions. /// /// \see AddCompletion void AddCompletions(const StringList &completions, diff --git a/gnu/llvm/lldb/include/lldb/Utility/Connection.h b/gnu/llvm/lldb/include/lldb/Utility/Connection.h index 9e66dee1363..39e6e40191b 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/Connection.h +++ b/gnu/llvm/lldb/include/lldb/Utility/Connection.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Connection_h_ -#define liblldb_Connection_h_ +#ifndef LLDB_UTILITY_CONNECTION_H +#define LLDB_UTILITY_CONNECTION_H #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" @@ -125,7 +125,7 @@ public: /// Subclasses must override this function. /// /// \param[in] dst - /// A desination buffer that must be at least \a dst_len bytes + /// A destination buffer that must be at least \a dst_len bytes /// long. /// /// \param[in] dst_len @@ -175,9 +175,10 @@ public: private: // For Connection only - DISALLOW_COPY_AND_ASSIGN(Connection); + Connection(const Connection &) = delete; + const Connection &operator=(const Connection &) = delete; }; } // namespace lldb_private -#endif // liblldb_Connection_h_ +#endif // LLDB_UTILITY_CONNECTION_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/ConstString.h b/gnu/llvm/lldb/include/lldb/Utility/ConstString.h index 74750459d16..1e55b2ebb95 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/ConstString.h +++ b/gnu/llvm/lldb/include/lldb/Utility/ConstString.h @@ -6,12 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ConstString_h_ -#define liblldb_ConstString_h_ +#ifndef LLDB_UTILITY_CONSTSTRING_H +#define LLDB_UTILITY_CONSTSTRING_H -#include "llvm/ADT/StringRef.h" #include "llvm/ADT/DenseMapInfo.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/YAMLTraits.h" #include @@ -481,6 +482,21 @@ template <> struct DenseMapInfo { } }; /// \} + +namespace yaml { +template <> struct ScalarTraits { + static void output(const lldb_private::ConstString &, void *, raw_ostream &); + static StringRef input(StringRef, void *, lldb_private::ConstString &); + static QuotingType mustQuote(StringRef S) { return QuotingType::Double; } +}; +} // namespace yaml + +inline raw_ostream &operator<<(raw_ostream &os, lldb_private::ConstString s) { + os << s.GetStringRef(); + return os; } +} // namespace llvm + +LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::ConstString) -#endif // liblldb_ConstString_h_ +#endif // LLDB_UTILITY_CONSTSTRING_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/DataBuffer.h b/gnu/llvm/lldb/include/lldb/Utility/DataBuffer.h index 523569301e8..302b1330795 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/DataBuffer.h +++ b/gnu/llvm/lldb/include/lldb/Utility/DataBuffer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DataBuffer_h_ -#define liblldb_DataBuffer_h_ +#ifndef LLDB_UTILITY_DATABUFFER_H +#define LLDB_UTILITY_DATABUFFER_H #if defined(__cplusplus) #include @@ -79,7 +79,21 @@ public: } }; +class DataBufferUnowned : public DataBuffer { +public: + DataBufferUnowned(uint8_t *bytes, lldb::offset_t size) + : m_bytes(bytes), m_size(size) {} + + uint8_t *GetBytes() override { return m_bytes; } + const uint8_t *GetBytes() const override { return m_bytes; } + lldb::offset_t GetByteSize() const override { return m_size; } + +private: + uint8_t *m_bytes; + lldb::offset_t m_size; +}; + } // namespace lldb_private #endif /// #if defined(__cplusplus) -#endif /// lldb_DataBuffer_h_ +#endif // LLDB_UTILITY_DATABUFFER_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/DataBufferHeap.h b/gnu/llvm/lldb/include/lldb/Utility/DataBufferHeap.h index 2a64694d7f2..ace526bf0a4 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/DataBufferHeap.h +++ b/gnu/llvm/lldb/include/lldb/Utility/DataBufferHeap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DataBufferHeap_h_ -#define liblldb_DataBufferHeap_h_ +#ifndef LLDB_UTILITY_DATABUFFERHEAP_H +#define LLDB_UTILITY_DATABUFFERHEAP_H #include "lldb/Utility/DataBuffer.h" #include "lldb/lldb-types.h" @@ -109,4 +109,4 @@ private: } // namespace lldb_private -#endif // liblldb_DataBufferHeap_h_ +#endif // LLDB_UTILITY_DATABUFFERHEAP_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/DataBufferLLVM.h b/gnu/llvm/lldb/include/lldb/Utility/DataBufferLLVM.h index d4c11074306..4dc800c348c 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/DataBufferLLVM.h +++ b/gnu/llvm/lldb/include/lldb/Utility/DataBufferLLVM.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_CORE_DATABUFFERLLVM_H -#define LLDB_CORE_DATABUFFERLLVM_H +#ifndef LLDB_UTILITY_DATABUFFERLLVM_H +#define LLDB_UTILITY_DATABUFFERLLVM_H #include "lldb/Utility/DataBuffer.h" #include "lldb/lldb-types.h" diff --git a/gnu/llvm/lldb/include/lldb/Utility/DataEncoder.h b/gnu/llvm/lldb/include/lldb/Utility/DataEncoder.h index f4964b250b9..8edec54c36f 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/DataEncoder.h +++ b/gnu/llvm/lldb/include/lldb/Utility/DataEncoder.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DataEncoder_h_ -#define liblldb_DataEncoder_h_ +#ifndef LLDB_UTILITY_DATAENCODER_H +#define LLDB_UTILITY_DATAENCODER_H #if defined(__cplusplus) @@ -225,7 +225,6 @@ private: /// The total number of bytes of data this object refers to. size_t GetByteSize() const { return m_end - m_start; } -private: /// A pointer to the first byte of data. uint8_t *m_start; @@ -243,10 +242,11 @@ private: /// be shared among multiple instances mutable lldb::DataBufferSP m_data_sp; - DISALLOW_COPY_AND_ASSIGN(DataEncoder); + DataEncoder(const DataEncoder &) = delete; + const DataEncoder &operator=(const DataEncoder &) = delete; }; } // namespace lldb_private #endif // #if defined (__cplusplus) -#endif // #ifndef liblldb_DataEncoder_h_ +#endif // LLDB_UTILITY_DATAENCODER_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/DataExtractor.h b/gnu/llvm/lldb/include/lldb/Utility/DataExtractor.h index bf0d1055cf4..0210af5cf6d 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/DataExtractor.h +++ b/gnu/llvm/lldb/include/lldb/Utility/DataExtractor.h @@ -9,12 +9,14 @@ #ifndef LLDB_UTILITY_DATAEXTRACTOR_H #define LLDB_UTILITY_DATAEXTRACTOR_H +#include "lldb/Utility/Endian.h" #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/Support/DataExtractor.h" +#include "llvm/Support/SwapByteOrder.h" #include #include @@ -535,13 +537,13 @@ public: uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset) const; - /// Extract an signed integer of size \a byte_size from \a *offset_ptr, then - /// extract and signe extend the bitfield from this value if \a + /// Extract an signed integer of size \a size from \a *offset_ptr, then + /// extract and sign-extend the bitfield from this value if \a /// bitfield_bit_size is non-zero. /// - /// Extract a single signed integer value (sign extending if required) and + /// Extract a single signed integer value (sign-extending if required) and /// update the offset pointed to by \a offset_ptr. The size of the extracted - /// integer is specified by the \a byte_size argument. \a byte_size must + /// integer is specified by the \a size argument. \a size must /// have a value greater than or equal to one and less than or equal to /// eight since the return value is 64 bits wide. /// @@ -573,24 +575,6 @@ public: uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset) const; - /// Extract an pointer from \a *offset_ptr. - /// - /// Extract a single pointer from the data and update the offset pointed to - /// by \a offset_ptr. The size of the extracted pointer comes from the \a - /// m_addr_size member variable and should be set correctly prior to - /// extracting any pointer values. - /// - /// \param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// \return - /// The extracted pointer value as a 64 integer. - uint64_t GetPointer(lldb::offset_t *offset_ptr) const; - /// Get the current byte order value. /// /// \return @@ -997,19 +981,33 @@ public: } protected: + template T Get(lldb::offset_t *offset_ptr, T fail_value) const { + constexpr size_t src_size = sizeof(T); + T val = fail_value; + + const T *src = static_cast(GetData(offset_ptr, src_size)); + if (!src) + return val; + + memcpy(&val, src, src_size); + if (m_byte_order != endian::InlHostByteOrder()) + llvm::sys::swapByteOrder(val); + + return val; + } + // Member variables const uint8_t *m_start; ///< A pointer to the first byte of data. const uint8_t *m_end; ///< A pointer to the byte that is past the end of the data. lldb::ByteOrder m_byte_order; ///< The byte order of the data we are extracting from. - uint32_t m_addr_size; ///< The address size to use when extracting pointers or - /// addresses - mutable lldb::DataBufferSP m_data_sp; ///< The shared pointer to data that can - /// be shared among multiple instances + uint32_t m_addr_size; ///< The address size to use when extracting addresses. + /// The shared pointer to data that can be shared among multiple instances + lldb::DataBufferSP m_data_sp; const uint32_t m_target_byte_size; }; } // namespace lldb_private -#endif // liblldb_DataExtractor_h_ +#endif // LLDB_UTILITY_DATAEXTRACTOR_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/Endian.h b/gnu/llvm/lldb/include/lldb/Utility/Endian.h index cead5f8603d..1d1f8fa333b 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/Endian.h +++ b/gnu/llvm/lldb/include/lldb/Utility/Endian.h @@ -30,4 +30,4 @@ inline lldb::ByteOrder InlHostByteOrder() { } } -#endif // liblldb_host_endian_h_ +#endif // LLDB_UTILITY_ENDIAN_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/Environment.h b/gnu/llvm/lldb/include/lldb/Utility/Environment.h index 398b3bae310..e2af2eb2463 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/Environment.h +++ b/gnu/llvm/lldb/include/lldb/Utility/Environment.h @@ -50,6 +50,7 @@ public: using Base::erase; using Base::find; using Base::insert; + using Base::insert_or_assign; using Base::lookup; using Base::size; using Base::try_emplace; @@ -68,7 +69,8 @@ public: } std::pair insert(llvm::StringRef KeyEqValue) { - return insert(KeyEqValue.split('=')); + auto Split = KeyEqValue.split('='); + return insert(std::make_pair(Split.first, std::string(Split.second))); } void insert(const_iterator first, const_iterator last); @@ -92,4 +94,4 @@ template <> struct format_provider { }; } // namespace llvm -#endif // #ifndef LLDB_UTILITY_ENVIRONMENT_H +#endif // LLDB_UTILITY_ENVIRONMENT_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/Event.h b/gnu/llvm/lldb/include/lldb/Utility/Event.h index dd5d08024ce..06c02629d44 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/Event.h +++ b/gnu/llvm/lldb/include/lldb/Utility/Event.h @@ -48,7 +48,8 @@ public: private: virtual void DoOnRemoval(Event *event_ptr) {} - DISALLOW_COPY_AND_ASSIGN(EventData); + EventData(const EventData &) = delete; + const EventData &operator=(const EventData &) = delete; }; // lldb::EventDataBytes @@ -92,7 +93,8 @@ public: private: std::string m_bytes; - DISALLOW_COPY_AND_ASSIGN(EventDataBytes); + EventDataBytes(const EventDataBytes &) = delete; + const EventDataBytes &operator=(const EventDataBytes &) = delete; }; class EventDataReceipt : public EventData { @@ -169,7 +171,9 @@ private: StructuredData::ObjectSP m_object_sp; lldb::StructuredDataPluginSP m_plugin_sp; - DISALLOW_COPY_AND_ASSIGN(EventDataStructuredData); + EventDataStructuredData(const EventDataStructuredData &) = delete; + const EventDataStructuredData & + operator=(const EventDataStructuredData &) = delete; }; // lldb::Event @@ -242,7 +246,8 @@ private: uint32_t m_type; // The bit describing this event lldb::EventDataSP m_data_sp; // User specific data for this event - DISALLOW_COPY_AND_ASSIGN(Event); + Event(const Event &) = delete; + const Event &operator=(const Event &) = delete; Event() = delete; }; diff --git a/gnu/llvm/lldb/include/lldb/Utility/FileSpec.h b/gnu/llvm/lldb/include/lldb/Utility/FileSpec.h index 533426671cc..f7cbeb24710 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/FileSpec.h +++ b/gnu/llvm/lldb/include/lldb/Utility/FileSpec.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_FileSpec_h_ -#define liblldb_FileSpec_h_ +#ifndef LLDB_UTILITY_FILESPEC_H +#define LLDB_UTILITY_FILESPEC_H #include #include @@ -18,6 +18,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Path.h" +#include "llvm/Support/YAMLTraits.h" #include #include @@ -397,6 +398,8 @@ public: ConstString GetLastPathComponent() const; protected: + friend struct llvm::yaml::MappingTraits; + // Convenience method for setting the file without changing the style. void SetFile(llvm::StringRef path); @@ -410,6 +413,8 @@ protected: /// Dump a FileSpec object to a stream Stream &operator<<(Stream &s, const FileSpec &f); +/// Prevent ODR violations with traits for llvm::sys::path::Style. +LLVM_YAML_STRONG_TYPEDEF(FileSpec::Style, FileSpecStyle) } // namespace lldb_private namespace llvm { @@ -436,6 +441,16 @@ template <> struct format_provider { static void format(const lldb_private::FileSpec &F, llvm::raw_ostream &Stream, StringRef Style); }; + +namespace yaml { +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &io, lldb_private::FileSpecStyle &style); +}; + +template <> struct MappingTraits { + static void mapping(IO &io, lldb_private::FileSpec &f); +}; +} // namespace yaml } // namespace llvm -#endif // liblldb_FileSpec_h_ +#endif // LLDB_UTILITY_FILESPEC_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/Flags.h b/gnu/llvm/lldb/include/lldb/Utility/Flags.h index 254a5ec443c..19f750639e9 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/Flags.h +++ b/gnu/llvm/lldb/include/lldb/Utility/Flags.h @@ -29,7 +29,7 @@ public: /// Constructs this object with \a mask as the initial value for all of the /// flags. /// - /// \param[in] mask + /// \param[in] flags /// The initial value for all flags. Flags(ValueType flags = 0) : m_flags(flags) {} @@ -116,4 +116,4 @@ protected: } // namespace lldb_private -#endif // liblldb_Flags_h_ +#endif // LLDB_UTILITY_FLAGS_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/GDBRemote.h b/gnu/llvm/lldb/include/lldb/Utility/GDBRemote.h index 21b2c8cd73c..f5749b7e6ea 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/GDBRemote.h +++ b/gnu/llvm/lldb/include/lldb/Utility/GDBRemote.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemote_h_ -#define liblldb_GDBRemote_h_ +#ifndef LLDB_UTILITY_GDBREMOTE_H +#define LLDB_UTILITY_GDBREMOTE_H #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Reproducer.h" @@ -155,4 +155,4 @@ template <> struct MappingTraits { } // namespace yaml } // namespace llvm -#endif // liblldb_GDBRemote_h_ +#endif // LLDB_UTILITY_GDBREMOTE_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/IOObject.h b/gnu/llvm/lldb/include/lldb/Utility/IOObject.h index 16ed580abf7..9b2b9cfcfec 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/IOObject.h +++ b/gnu/llvm/lldb/include/lldb/Utility/IOObject.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Host_Common_IOObject_h_ -#define liblldb_Host_Common_IOObject_h_ +#ifndef LLDB_UTILITY_IOOBJECT_H +#define LLDB_UTILITY_IOOBJECT_H #include #include @@ -45,7 +45,8 @@ protected: FDType m_fd_type; private: - DISALLOW_COPY_AND_ASSIGN(IOObject); + IOObject(const IOObject &) = delete; + const IOObject &operator=(const IOObject &) = delete; }; } // namespace lldb_private diff --git a/gnu/llvm/lldb/include/lldb/Utility/Iterable.h b/gnu/llvm/lldb/include/lldb/Utility/Iterable.h index d9c61aa958c..3f9b8b1e4c5 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/Iterable.h +++ b/gnu/llvm/lldb/include/lldb/Utility/Iterable.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Iterable_h_ -#define liblldb_Iterable_h_ +#ifndef LLDB_UTILITY_ITERABLE_H +#define LLDB_UTILITY_ITERABLE_H #include @@ -194,4 +194,4 @@ private: } // namespace lldb_private -#endif // liblldb_Iterable_h_ +#endif // LLDB_UTILITY_ITERABLE_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/LLDBAssert.h b/gnu/llvm/lldb/include/lldb/Utility/LLDBAssert.h index 7008dd82496..845af1d4cc2 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/LLDBAssert.h +++ b/gnu/llvm/lldb/include/lldb/Utility/LLDBAssert.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_LLDBAssert_h_ -#define utility_LLDBAssert_h_ +#ifndef LLDB_UTILITY_LLDBASSERT_H +#define LLDB_UTILITY_LLDBASSERT_H #ifdef LLDB_CONFIGURATION_DEBUG #define lldbassert(x) assert(x) @@ -22,4 +22,4 @@ void lldb_assert(bool expression, const char *expr_text, const char *func, const char *file, unsigned int line); } -#endif // utility_LLDBAssert_h_ +#endif // LLDB_UTILITY_LLDBASSERT_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/Listener.h b/gnu/llvm/lldb/include/lldb/Utility/Listener.h index 17fc47880e8..9d96e36c5ab 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/Listener.h +++ b/gnu/llvm/lldb/include/lldb/Utility/Listener.h @@ -145,7 +145,8 @@ private: // bool exact); // For Listener only - DISALLOW_COPY_AND_ASSIGN(Listener); + Listener(const Listener &) = delete; + const Listener &operator=(const Listener &) = delete; }; } // namespace lldb_private diff --git a/gnu/llvm/lldb/include/lldb/Utility/Predicate.h b/gnu/llvm/lldb/include/lldb/Utility/Predicate.h index cbccc3e91a8..a17ac05f6e5 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/Predicate.h +++ b/gnu/llvm/lldb/include/lldb/Utility/Predicate.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Predicate_h_ -#define liblldb_Predicate_h_ +#ifndef LLDB_UTILITY_PREDICATE_H +#define LLDB_UTILITY_PREDICATE_H #include #include @@ -221,9 +221,10 @@ private: m_condition.notify_all(); } - DISALLOW_COPY_AND_ASSIGN(Predicate); + Predicate(const Predicate &) = delete; + const Predicate &operator=(const Predicate &) = delete; }; } // namespace lldb_private -#endif // liblldb_Predicate_h_ +#endif // LLDB_UTILITY_PREDICATE_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/ProcessInfo.h b/gnu/llvm/lldb/include/lldb/Utility/ProcessInfo.h index 9188bf3b709..ec91060cda5 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/ProcessInfo.h +++ b/gnu/llvm/lldb/include/lldb/Utility/ProcessInfo.h @@ -9,13 +9,13 @@ #ifndef LLDB_UTILITY_PROCESSINFO_H #define LLDB_UTILITY_PROCESSINFO_H -// LLDB headers #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/Environment.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/NameMatches.h" - +#include "lldb/Utility/Reproducer.h" +#include "llvm/Support/YAMLTraits.h" #include namespace lldb_private { @@ -89,6 +89,7 @@ public: const Environment &GetEnvironment() const { return m_environment; } protected: + template friend struct llvm::yaml::MappingTraits; FileSpec m_executable; std::string m_arg0; // argv[0] if supported. If empty, then use m_executable. // Not all process plug-ins support specifying an argv[0] that differs from @@ -150,46 +151,13 @@ public: bool verbose) const; protected: + friend struct llvm::yaml::MappingTraits; uint32_t m_euid; uint32_t m_egid; lldb::pid_t m_parent_pid; }; -class ProcessInstanceInfoList { -public: - ProcessInstanceInfoList() = default; - - void Clear() { m_infos.clear(); } - - size_t GetSize() { return m_infos.size(); } - - void Append(const ProcessInstanceInfo &info) { m_infos.push_back(info); } - - llvm::StringRef GetProcessNameAtIndex(size_t idx) { - return ((idx < m_infos.size()) ? m_infos[idx].GetNameAsStringRef() : ""); - } - - lldb::pid_t GetProcessIDAtIndex(size_t idx) { - return ((idx < m_infos.size()) ? m_infos[idx].GetProcessID() : 0); - } - - bool GetInfoAtIndex(size_t idx, ProcessInstanceInfo &info) { - if (idx < m_infos.size()) { - info = m_infos[idx]; - return true; - } - return false; - } - - // You must ensure "idx" is valid before calling this function - const ProcessInstanceInfo &GetProcessInfoAtIndex(size_t idx) const { - assert(idx < m_infos.size()); - return m_infos[idx]; - } - -protected: - std::vector m_infos; -}; +typedef std::vector ProcessInstanceInfoList; // ProcessInstanceInfoMatch // @@ -248,6 +216,52 @@ protected: bool m_match_all_users; }; +namespace repro { +class ProcessInfoRecorder : public AbstractRecorder { +public: + ProcessInfoRecorder(const FileSpec &filename, std::error_code &ec) + : AbstractRecorder(filename, ec) {} + + static llvm::Expected> + Create(const FileSpec &filename); + + void Record(const ProcessInstanceInfoList &process_infos); +}; + +class ProcessInfoProvider : public repro::Provider { +public: + struct Info { + static const char *name; + static const char *file; + }; + + ProcessInfoProvider(const FileSpec &directory) : Provider(directory) {} + + ProcessInfoRecorder *GetNewProcessInfoRecorder(); + + void Keep() override; + void Discard() override; + + static char ID; + +private: + std::unique_ptr m_stream_up; + std::vector> m_process_info_recorders; +}; + +llvm::Optional GetReplayProcessInstanceInfoList(); + +} // namespace repro } // namespace lldb_private -#endif // #ifndef LLDB_UTILITY_PROCESSINFO_H +LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::ProcessInstanceInfo) + +namespace llvm { +namespace yaml { +template <> struct MappingTraits { + static void mapping(IO &io, lldb_private::ProcessInstanceInfo &PII); +}; +} // namespace yaml +} // namespace llvm + +#endif // LLDB_UTILITY_PROCESSINFO_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/RangeMap.h b/gnu/llvm/lldb/include/lldb/Utility/RangeMap.h index 9e030735183..fb24c5a4347 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/RangeMap.h +++ b/gnu/llvm/lldb/include/lldb/Utility/RangeMap.h @@ -122,220 +122,13 @@ template struct Range { } }; -// A range array class where you get to define the type of the ranges -// that the collection contains. - -template class RangeArray { +template class RangeVector { public: typedef B BaseType; typedef S SizeType; typedef Range Entry; typedef llvm::SmallVector Collection; - RangeArray() = default; - - ~RangeArray() = default; - - void Append(const Entry &entry) { m_entries.push_back(entry); } - - void Append(B base, S size) { m_entries.emplace_back(base, size); } - - bool RemoveEntrtAtIndex(uint32_t idx) { - if (idx < m_entries.size()) { - m_entries.erase(m_entries.begin() + idx); - return true; - } - return false; - } - - 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; - 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 CombineConsecutiveRanges() { -#ifdef ASSERT_RANGEMAP_ARE_SORTED - assert(IsSorted()); -#endif - // Can't combine if ranges if we have zero or one range - if (m_entries.size() > 1) { - // The list should be sorted prior to calling this function - 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->DoesAdjoinOrIntersect(*pos)) { - 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->DoesAdjoinOrIntersect(*pos)) - minimal_ranges.back().SetRangeEnd( - std::max(prev->GetRangeEnd(), 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); - } - } - } - - BaseType GetMinRangeBase(BaseType fail_value) const { -#ifdef ASSERT_RANGEMAP_ARE_SORTED - assert(IsSorted()); -#endif - if (m_entries.empty()) - return fail_value; - // m_entries must be sorted, so if we aren't empty, we grab the first - // range's base - return m_entries.front().GetRangeBase(); - } - - BaseType GetMaxRangeEnd(BaseType fail_value) const { -#ifdef ASSERT_RANGEMAP_ARE_SORTED - assert(IsSorted()); -#endif - if (m_entries.empty()) - return fail_value; - // m_entries must be sorted, so if we aren't empty, we grab the last - // range's end - return m_entries.back().GetRangeEnd(); - } - - void Slide(BaseType slide) { - typename Collection::iterator pos, end; - for (pos = m_entries.begin(), end = m_entries.end(); pos != end; ++pos) - pos->Slide(slide); - } - - 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]; } - - Entry *Back() { return (m_entries.empty() ? nullptr : &m_entries.back()); } - - const Entry *Back() const { - return (m_entries.empty() ? nullptr : &m_entries.back()); - } - - 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; - } - - const Entry *FindEntryThatContains(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 &(*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; - } - -protected: - Collection m_entries; -}; - -template class RangeVector { -public: - typedef B BaseType; - typedef S SizeType; - typedef Range Entry; - typedef std::vector Collection; - RangeVector() = default; ~RangeVector() = default; @@ -601,19 +394,31 @@ struct RangeData : public Range { RangeData(B base, S size, DataType d) : Range(base, size), data(d) {} }; +// We can treat the vector as a flattened Binary Search Tree, augmenting it +// with upper bounds (max of range endpoints) for every index allows us to +// query for range containment quicker. +template +struct AugmentedRangeData : public RangeData { + B upper_bound; + + AugmentedRangeData(const RangeData &rd) + : RangeData(rd), upper_bound() {} +}; + template > class RangeDataVector { public: typedef lldb_private::Range Range; typedef RangeData Entry; - typedef llvm::SmallVector Collection; + typedef AugmentedRangeData AugmentedEntry; + typedef llvm::SmallVector Collection; RangeDataVector(Compare compare = Compare()) : m_compare(compare) {} ~RangeDataVector() = default; - void Append(const Entry &entry) { m_entries.push_back(entry); } + void Append(const Entry &entry) { m_entries.emplace_back(entry); } void Sort() { if (m_entries.size() > 1) @@ -625,13 +430,13 @@ public: return a.size < b.size; return compare(a.data, b.data); }); + if (!m_entries.empty()) + ComputeUpperBounds(0, m_entries.size()); } #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) @@ -701,26 +506,20 @@ public: } uint32_t FindEntryIndexThatContains(B addr) const { - const Entry *entry = FindEntryThatContains(addr); + const AugmentedEntry *entry = + static_cast(FindEntryThatContains(addr)); if (entry) return std::distance(m_entries.begin(), entry); return UINT32_MAX; } - uint32_t FindEntryIndexesThatContain(B addr, - std::vector &indexes) const { + uint32_t FindEntryIndexesThatContain(B addr, std::vector &indexes) { #ifdef ASSERT_RANGEMAP_ARE_SORTED assert(IsSorted()); #endif - // Search the entries until the first entry that has a larger base address - // than `addr`. As m_entries is sorted by their base address, all following - // entries can't contain `addr` as their base address is already larger. - for (const auto &entry : m_entries) { - if (entry.Contains(addr)) - indexes.push_back(entry.data); - else if (entry.GetRangeBase() > addr) - break; - } + if (!m_entries.empty()) + FindEntryIndexesThatContain(addr, 0, m_entries.size(), indexes); + return indexes.size(); } @@ -806,6 +605,54 @@ public: protected: Collection m_entries; Compare m_compare; + +private: + // Compute extra information needed for search + B ComputeUpperBounds(size_t lo, size_t hi) { + size_t mid = (lo + hi) / 2; + AugmentedEntry &entry = m_entries[mid]; + + entry.upper_bound = entry.base + entry.size; + + if (lo < mid) + entry.upper_bound = + std::max(entry.upper_bound, ComputeUpperBounds(lo, mid)); + + if (mid + 1 < hi) + entry.upper_bound = + std::max(entry.upper_bound, ComputeUpperBounds(mid + 1, hi)); + + return entry.upper_bound; + } + + // This is based on the augmented tree implementation found at + // https://en.wikipedia.org/wiki/Interval_tree#Augmented_tree + void FindEntryIndexesThatContain(B addr, size_t lo, size_t hi, + std::vector &indexes) { + size_t mid = (lo + hi) / 2; + const AugmentedEntry &entry = m_entries[mid]; + + // addr is greater than the rightmost point of any interval below mid + // so there are cannot be any matches. + if (addr > entry.upper_bound) + return; + + // Recursively search left subtree + if (lo < mid) + FindEntryIndexesThatContain(addr, lo, mid, indexes); + + // If addr is smaller than the start of the current interval it + // cannot contain it nor can any of its right subtree. + if (addr < entry.base) + return; + + if (entry.Contains(addr)) + indexes.push_back(entry.data); + + // Recursively search right subtree + if (mid + 1 < hi) + FindEntryIndexesThatContain(addr, mid + 1, hi, indexes); + } }; // A simple range with data class where you get to define the type of diff --git a/gnu/llvm/lldb/include/lldb/Utility/RegisterValue.h b/gnu/llvm/lldb/include/lldb/Utility/RegisterValue.h index eeb3ce52a82..c9f295a8d95 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/RegisterValue.h +++ b/gnu/llvm/lldb/include/lldb/Utility/RegisterValue.h @@ -26,7 +26,8 @@ struct RegisterInfo; class RegisterValue { public: - enum { kMaxRegisterByteSize = 64u }; + // big enough to support up to 256 byte AArch64 SVE + enum { kMaxRegisterByteSize = 256u }; enum Type { eTypeInvalid, @@ -259,9 +260,10 @@ protected: Scalar m_scalar; struct { - uint8_t bytes[kMaxRegisterByteSize]; // This must be big enough to hold any - // register for any supported target. - uint8_t length; + mutable uint8_t + bytes[kMaxRegisterByteSize]; // This must be big enough to hold any + // register for any supported target. + uint16_t length; lldb::ByteOrder byte_order; } buffer; }; diff --git a/gnu/llvm/lldb/include/lldb/Utility/RegularExpression.h b/gnu/llvm/lldb/include/lldb/Utility/RegularExpression.h index 6acc203d8e7..415f1b58b11 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/RegularExpression.h +++ b/gnu/llvm/lldb/include/lldb/Utility/RegularExpression.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegularExpression_h_ -#define liblldb_RegularExpression_h_ +#ifndef LLDB_UTILITY_REGULAREXPRESSION_H +#define LLDB_UTILITY_REGULAREXPRESSION_H #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" @@ -91,4 +91,4 @@ private: } // namespace lldb_private -#endif // liblldb_RegularExpression_h_ +#endif // LLDB_UTILITY_REGULAREXPRESSION_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/Reproducer.h b/gnu/llvm/lldb/include/lldb/Utility/Reproducer.h index 0d23fe8571f..ab673e5e001 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/Reproducer.h +++ b/gnu/llvm/lldb/include/lldb/Utility/Reproducer.h @@ -27,6 +27,7 @@ class Reproducer; enum class ReproducerMode { Capture, Replay, + PassiveReplay, Off, }; @@ -98,6 +99,8 @@ public: return m_collector; } + void recordInterestingDirectory(const llvm::Twine &dir); + void Keep() override { auto mapping = GetRoot().CopyByAppendingPathComponent(Info::file); // Temporary files that are removed during execution can cause copy errors. @@ -132,7 +135,7 @@ public: static char ID; }; -/// Provider for the LLDB current working directroy. +/// Provider for the LLDB current working directory. /// /// When the reproducer is kept, it writes lldb's current working directory to /// a file named cwd.txt in the reproducer root. @@ -142,8 +145,11 @@ public: llvm::SmallString<128> cwd; if (std::error_code EC = llvm::sys::fs::current_path(cwd)) return; - m_cwd = cwd.str(); + m_cwd = std::string(cwd.str()); } + + void Update(llvm::StringRef path) { m_cwd = std::string(path); } + struct Info { static const char *name; static const char *file; @@ -153,6 +159,9 @@ public: static char ID; }; +/// The recorder is a small object handed out by a provider to record data. It +/// is commonly used in combination with a MultiProvider which is meant to +/// record information for multiple instances of the same source of data. class AbstractRecorder { protected: AbstractRecorder(const FileSpec &filename, std::error_code &ec) @@ -175,6 +184,7 @@ protected: bool m_record; }; +/// Recorder that records its data as text to a file. class DataRecorder : public AbstractRecorder { public: DataRecorder(const FileSpec &filename, std::error_code &ec) @@ -193,24 +203,88 @@ public: } }; -class CommandProvider : public Provider { +/// Recorder that records its data as YAML to a file. +class YamlRecorder : public AbstractRecorder { +public: + YamlRecorder(const FileSpec &filename, std::error_code &ec) + : AbstractRecorder(filename, ec) {} + + static llvm::Expected> + Create(const FileSpec &filename); + + template void Record(const T &t) { + if (!m_record) + return; + llvm::yaml::Output yout(m_os); + // The YAML traits are defined as non-const because they are used for + // serialization and deserialization. The cast is safe because + // serialization doesn't modify the object. + yout << const_cast(t); + m_os.flush(); + } +}; + +/// The MultiProvider is a provider that hands out recorder which can be used +/// to capture data for different instances of the same object. The recorders +/// can be passed around or stored as an instance member. +/// +/// The Info::file for the MultiProvider contains an index of files for every +/// recorder. Use the MultiLoader to read the index and get the individual +/// files. +template +class MultiProvider : public repro::Provider { +public: + MultiProvider(const FileSpec &directory) : Provider(directory) {} + + T *GetNewRecorder() { + std::size_t i = m_recorders.size() + 1; + std::string filename = (llvm::Twine(V::Info::name) + llvm::Twine("-") + + llvm::Twine(i) + llvm::Twine(".yaml")) + .str(); + auto recorder_or_error = + T::Create(this->GetRoot().CopyByAppendingPathComponent(filename)); + if (!recorder_or_error) { + llvm::consumeError(recorder_or_error.takeError()); + return nullptr; + } + + m_recorders.push_back(std::move(*recorder_or_error)); + return m_recorders.back().get(); + } + + void Keep() override { + std::vector files; + for (auto &recorder : m_recorders) { + recorder->Stop(); + files.push_back(recorder->GetFilename().GetPath()); + } + + FileSpec file = this->GetRoot().CopyByAppendingPathComponent(V::Info::file); + std::error_code ec; + llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text); + if (ec) + return; + llvm::yaml::Output yout(os); + yout << files; + } + + void Discard() override { m_recorders.clear(); } + +private: + std::vector> m_recorders; +}; + +class CommandProvider : public MultiProvider { public: struct Info { static const char *name; static const char *file; }; - CommandProvider(const FileSpec &directory) : Provider(directory) {} - - DataRecorder *GetNewDataRecorder(); - - void Keep() override; - void Discard() override; + CommandProvider(const FileSpec &directory) + : MultiProvider(directory) {} static char ID; - -private: - std::vector> m_data_recorders; }; /// The generator is responsible for the logic needed to generate a @@ -231,6 +305,12 @@ public: /// might need to clean up files already written to disk. void Discard(); + /// Enable or disable auto generate. + void SetAutoGenerate(bool b); + + /// Return whether auto generate is enabled. + bool IsAutoGenerate() const; + /// Create and register a new provider. template T *Create() { std::unique_ptr provider = std::make_unique(m_root); @@ -272,11 +352,14 @@ private: /// Flag to ensure that we never call both keep and discard. bool m_done = false; + + /// Flag to auto generate a reproducer when it would otherwise be discarded. + bool m_auto_generate = false; }; class Loader final { public: - Loader(FileSpec root); + Loader(FileSpec root, bool passive = false); template FileSpec GetFile() { if (!HasFile(T::file)) @@ -298,12 +381,15 @@ public: const FileSpec &GetRoot() const { return m_root; } + bool IsPassiveReplay() const { return m_passive_replay; } + private: bool HasFile(llvm::StringRef file); FileSpec m_root; std::vector m_files; bool m_loaded; + bool m_passive_replay; }; /// The reproducer enables clients to obtain access to the Generator and @@ -331,7 +417,7 @@ public: protected: llvm::Error SetCapture(llvm::Optional root); - llvm::Error SetReplay(llvm::Optional root); + llvm::Error SetReplay(llvm::Optional root, bool passive = false); private: static llvm::Optional &InstanceImpl(); @@ -342,6 +428,8 @@ private: mutable std::mutex m_mutex; }; +/// Loader for data captured with the MultiProvider. It will read the index and +/// return the path to the files in the index. template class MultiLoader { public: MultiLoader(std::vector files) : m_files(files) {} diff --git a/gnu/llvm/lldb/include/lldb/Utility/ReproducerInstrumentation.h b/gnu/llvm/lldb/include/lldb/Utility/ReproducerInstrumentation.h index 75d66045758..5fc33ad1a17 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/ReproducerInstrumentation.h +++ b/gnu/llvm/lldb/include/lldb/Utility/ReproducerInstrumentation.h @@ -5,8 +5,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_UTILITY_REPRODUCER_INSTRUMENTATION_H -#define LLDB_UTILITY_REPRODUCER_INSTRUMENTATION_H +#ifndef LLDB_UTILITY_REPRODUCERINSTRUMENTATION_H +#define LLDB_UTILITY_REPRODUCERINSTRUMENTATION_H #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" @@ -16,7 +16,6 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/ErrorHandling.h" -#include #include #include @@ -32,6 +31,11 @@ inline void stringify_append(llvm::raw_string_ostream &ss, const T &t) { ss << &t; } +template +inline void stringify_append(llvm::raw_string_ostream &ss, T *t) { + ss << reinterpret_cast(t); +} + template inline void stringify_append(llvm::raw_string_ostream &ss, const T *t) { ss << reinterpret_cast(t); @@ -43,6 +47,12 @@ inline void stringify_append(llvm::raw_string_ostream &ss, ss << '\"' << t << '\"'; } +template <> +inline void stringify_append(llvm::raw_string_ostream &ss, + const std::nullptr_t &t) { + ss << "\"nullptr\""; +} + template inline void stringify_helper(llvm::raw_string_ostream &ss, const Head &head) { stringify_append(ss, head); @@ -69,120 +79,146 @@ template inline std::string stringify_args(const Ts &... ts) { // #define LLDB_REPRO_INSTR_TRACE #define LLDB_REGISTER_CONSTRUCTOR(Class, Signature) \ - R.Register(&construct::doit, "", #Class, \ - #Class, #Signature) + R.Register(&construct::record, "", \ + #Class, #Class, #Signature) + #define LLDB_REGISTER_METHOD(Result, Class, Method, Signature) \ R.Register( \ - &invoke::method<(&Class::Method)>::doit, \ + &invoke::method<(&Class::Method)>::record, \ #Result, #Class, #Method, #Signature) + #define LLDB_REGISTER_METHOD_CONST(Result, Class, Method, Signature) \ - R.Register(&invoke::method_const<( \ - &Class::Method)>::doit, \ + R.Register(&invoke::method<(&Class::Method)>::record, \ #Result, #Class, #Method, #Signature) + #define LLDB_REGISTER_STATIC_METHOD(Result, Class, Method, Signature) \ - R.Register( \ - static_cast(&Class::Method), #Result, #Class, \ - #Method, #Signature) + R.Register(&invoke::method<(&Class::Method)>::record, \ + #Result, #Class, #Method, #Signature) + +#define LLDB_REGISTER_CHAR_PTR_METHOD_STATIC(Result, Class, Method) \ + R.Register( \ + &invoke::method<(&Class::Method)>::record, \ + &invoke_char_ptr::method<(&Class::Method)>::record, \ + #Result, #Class, #Method, "(char*, size_t"); + +#define LLDB_REGISTER_CHAR_PTR_METHOD(Result, Class, Method) \ + R.Register(&invoke::method<( \ + &Class::Method)>::record, \ + &invoke_char_ptr::method<( \ + &Class::Method)>::record, \ + #Result, #Class, #Method, "(char*, size_t"); + +#define LLDB_REGISTER_CHAR_PTR_METHOD_CONST(Result, Class, Method) \ + R.Register(&invoke::method<(&Class::Method)>::record, \ + &invoke_char_ptr::method<(&Class::Method)>::record, \ + #Result, #Class, #Method, "(char*, size_t"); + +#define LLDB_CONSTRUCT_(T, Class, ...) \ + lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION); \ + lldb_private::repro::construct::handle(LLDB_GET_INSTRUMENTATION_DATA(), \ + _recorder, Class, __VA_ARGS__); #define LLDB_RECORD_CONSTRUCTOR(Class, Signature, ...) \ - lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \ - stringify_args(__VA_ARGS__)); \ - if (lldb_private::repro::InstrumentationData data = \ - LLDB_GET_INSTRUMENTATION_DATA()) { \ - sb_recorder.Record(data.GetSerializer(), data.GetRegistry(), \ - &lldb_private::repro::construct::doit, \ - __VA_ARGS__); \ - sb_recorder.RecordResult(this); \ - } + LLDB_CONSTRUCT_(Class Signature, this, __VA_ARGS__) #define LLDB_RECORD_CONSTRUCTOR_NO_ARGS(Class) \ - lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION); \ - if (lldb_private::repro::InstrumentationData data = \ + LLDB_CONSTRUCT_(Class(), this, lldb_private::repro::EmptyArg()) + +#define LLDB_RECORD_(T1, T2, ...) \ + lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION, \ + stringify_args(__VA_ARGS__)); \ + if (lldb_private::repro::InstrumentationData _data = \ LLDB_GET_INSTRUMENTATION_DATA()) { \ - sb_recorder.Record(data.GetSerializer(), data.GetRegistry(), \ - &lldb_private::repro::construct::doit); \ - sb_recorder.RecordResult(this); \ + if (lldb_private::repro::Serializer *_serializer = \ + _data.GetSerializer()) { \ + _recorder.Record(*_serializer, _data.GetRegistry(), \ + &lldb_private::repro::invoke::method::record, \ + __VA_ARGS__); \ + } else if (lldb_private::repro::Deserializer *_deserializer = \ + _data.GetDeserializer()) { \ + if (_recorder.ShouldCapture()) { \ + return lldb_private::repro::invoke::method::replay( \ + _recorder, *_deserializer, _data.GetRegistry()); \ + } \ + } \ } #define LLDB_RECORD_METHOD(Result, Class, Method, Signature, ...) \ - lldb_private::repro::Recorder sb_recorder( \ - LLVM_PRETTY_FUNCTION, stringify_args(*this, __VA_ARGS__)); \ - if (lldb_private::repro::InstrumentationData data = \ - LLDB_GET_INSTRUMENTATION_DATA()) { \ - sb_recorder.Record( \ - data.GetSerializer(), data.GetRegistry(), \ - &lldb_private::repro::invoke::method<( \ - &Class::Method)>::doit, \ - this, __VA_ARGS__); \ - } + LLDB_RECORD_(Result(Class::*) Signature, (&Class::Method), this, __VA_ARGS__) #define LLDB_RECORD_METHOD_CONST(Result, Class, Method, Signature, ...) \ - lldb_private::repro::Recorder sb_recorder( \ - LLVM_PRETTY_FUNCTION, stringify_args(*this, __VA_ARGS__)); \ - if (lldb_private::repro::InstrumentationData data = \ - LLDB_GET_INSTRUMENTATION_DATA()) { \ - sb_recorder.Record( \ - data.GetSerializer(), data.GetRegistry(), \ - &lldb_private::repro::invoke::method_const<(&Class::Method)>::doit, \ - this, __VA_ARGS__); \ - } + LLDB_RECORD_(Result(Class::*) Signature const, (&Class::Method), this, \ + __VA_ARGS__) #define LLDB_RECORD_METHOD_NO_ARGS(Result, Class, Method) \ - lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \ - stringify_args(*this)); \ - if (lldb_private::repro::InstrumentationData data = \ - LLDB_GET_INSTRUMENTATION_DATA()) { \ - sb_recorder.Record(data.GetSerializer(), data.GetRegistry(), \ - &lldb_private::repro::invoke::method<(&Class::Method)>::doit, \ - this); \ - } + LLDB_RECORD_(Result (Class::*)(), (&Class::Method), this) #define LLDB_RECORD_METHOD_CONST_NO_ARGS(Result, Class, Method) \ - lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \ - stringify_args(*this)); \ - if (lldb_private::repro::InstrumentationData data = \ - LLDB_GET_INSTRUMENTATION_DATA()) { \ - sb_recorder.Record( \ - data.GetSerializer(), data.GetRegistry(), \ - &lldb_private::repro::invoke::method_const<(&Class::Method)>::doit, \ - this); \ - } + LLDB_RECORD_(Result (Class::*)() const, (&Class::Method), this) #define LLDB_RECORD_STATIC_METHOD(Result, Class, Method, Signature, ...) \ - lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \ - stringify_args(__VA_ARGS__)); \ - if (lldb_private::repro::InstrumentationData data = \ - LLDB_GET_INSTRUMENTATION_DATA()) { \ - sb_recorder.Record(data.GetSerializer(), data.GetRegistry(), \ - static_cast(&Class::Method), \ - __VA_ARGS__); \ - } + LLDB_RECORD_(Result(*) Signature, (&Class::Method), __VA_ARGS__) #define LLDB_RECORD_STATIC_METHOD_NO_ARGS(Result, Class, Method) \ - lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION); \ - if (lldb_private::repro::InstrumentationData data = \ + LLDB_RECORD_(Result (*)(), (&Class::Method), lldb_private::repro::EmptyArg()) + +#define LLDB_RECORD_CHAR_PTR_(T1, T2, StrOut, ...) \ + lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION, \ + stringify_args(__VA_ARGS__)); \ + if (lldb_private::repro::InstrumentationData _data = \ LLDB_GET_INSTRUMENTATION_DATA()) { \ - sb_recorder.Record(data.GetSerializer(), data.GetRegistry(), \ - static_cast(&Class::Method)); \ + if (lldb_private::repro::Serializer *_serializer = \ + _data.GetSerializer()) { \ + _recorder.Record(*_serializer, _data.GetRegistry(), \ + &lldb_private::repro::invoke::method<(T2)>::record, \ + __VA_ARGS__); \ + } else if (lldb_private::repro::Deserializer *_deserializer = \ + _data.GetDeserializer()) { \ + if (_recorder.ShouldCapture()) { \ + return lldb_private::repro::invoke_char_ptr::method::replay( \ + _recorder, *_deserializer, _data.GetRegistry(), StrOut); \ + } \ + } \ } -#define LLDB_RECORD_RESULT(Result) sb_recorder.RecordResult(Result); +#define LLDB_RECORD_CHAR_PTR_METHOD(Result, Class, Method, Signature, StrOut, \ + ...) \ + LLDB_RECORD_CHAR_PTR_(Result(Class::*) Signature, (&Class::Method), StrOut, \ + this, __VA_ARGS__) + +#define LLDB_RECORD_CHAR_PTR_METHOD_CONST(Result, Class, Method, Signature, \ + StrOut, ...) \ + LLDB_RECORD_CHAR_PTR_(Result(Class::*) Signature const, (&Class::Method), \ + StrOut, this, __VA_ARGS__) + +#define LLDB_RECORD_CHAR_PTR_STATIC_METHOD(Result, Class, Method, Signature, \ + StrOut, ...) \ + LLDB_RECORD_CHAR_PTR_(Result(*) Signature, (&Class::Method), StrOut, \ + __VA_ARGS__) + +#define LLDB_RECORD_RESULT(Result) _recorder.RecordResult(Result, true); /// The LLDB_RECORD_DUMMY macro is special because it doesn't actually record /// anything. It's used to track API boundaries when we cannot record for /// technical reasons. #define LLDB_RECORD_DUMMY(Result, Class, Method, Signature, ...) \ - lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \ - stringify_args(__VA_ARGS__)); + lldb_private::repro::Recorder _recorder; + #define LLDB_RECORD_DUMMY_NO_ARGS(Result, Class, Method) \ - lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION); + lldb_private::repro::Recorder _recorder; namespace lldb_private { namespace repro { +template +struct is_trivially_serializable + : std::integral_constant::value || + std::is_enum::value> {}; + /// Mapping between serialized indices and their corresponding objects. /// /// This class is used during replay to map indices back to in-memory objects. @@ -205,19 +241,24 @@ public: } /// Adds a pointer to an object to the mapping for the given index. - template void AddObjectForIndex(unsigned idx, T *object) { + template T *AddObjectForIndex(unsigned idx, T *object) { AddObjectForIndexImpl( idx, static_cast( const_cast::type *>(object))); + return object; } /// Adds a reference to an object to the mapping for the given index. - template void AddObjectForIndex(unsigned idx, T &object) { + template T &AddObjectForIndex(unsigned idx, T &object) { AddObjectForIndexImpl( idx, static_cast( const_cast::type *>(&object))); + return object; } + /// Get all objects sorted by their index. + std::vector GetAllObjects() const; + private: /// Helper method that does the actual lookup. The void* result is later cast /// by the caller. @@ -238,11 +279,11 @@ struct ReferenceTag {}; struct ValueTag {}; struct FundamentalPointerTag {}; struct FundamentalReferenceTag {}; -struct NotImplementedTag {}; /// Return the deserialization tag for the given type T. template struct serializer_tag { - typedef typename std::conditional::value, ValueTag, NotImplementedTag>::type type; + typedef typename std::conditional::value, + ValueTag, ReferenceTag>::type type; }; template struct serializer_tag { typedef @@ -275,27 +316,37 @@ public: /// Deserialize and interpret value as T. template T Deserialize() { + T t = Read(typename serializer_tag::type()); #ifdef LLDB_REPRO_INSTR_TRACE - llvm::errs() << "Deserializing with " << LLVM_PRETTY_FUNCTION << "\n"; + llvm::errs() << "Deserializing with " << LLVM_PRETTY_FUNCTION << " -> " + << stringify_args(t) << "\n"; #endif - return Read(typename serializer_tag::type()); + return t; + } + + template const T &HandleReplayResult(const T &t) { + unsigned result = Deserialize(); + if (is_trivially_serializable::value) + return t; + // We need to make a copy as the original object might go out of scope. + return *m_index_to_object.AddObjectForIndex(result, new T(t)); } /// Store the returned value in the index-to-object mapping. - template void HandleReplayResult(const T &t) { + template T &HandleReplayResult(T &t) { unsigned result = Deserialize(); - if (std::is_fundamental::value) - return; + if (is_trivially_serializable::value) + return t; // We need to make a copy as the original object might go out of scope. - m_index_to_object.AddObjectForIndex(result, new T(t)); + return *m_index_to_object.AddObjectForIndex(result, new T(t)); } /// Store the returned value in the index-to-object mapping. - template void HandleReplayResult(T *t) { + template T *HandleReplayResult(T *t) { unsigned result = Deserialize(); - if (std::is_fundamental::value) - return; - m_index_to_object.AddObjectForIndex(result, t); + if (is_trivially_serializable::value) + return t; + return m_index_to_object.AddObjectForIndex(result, t); } /// All returned types are recorded, even when the function returns a void. @@ -306,12 +357,11 @@ public: (void)result; } -private: - template T Read(NotImplementedTag) { - m_buffer = m_buffer.drop_front(sizeof(T)); - return T(); + std::vector GetAllObjects() const { + return m_index_to_object.GetAllObjects(); } +private: template T Read(ValueTag) { assert(HasData(sizeof(T))); T t; @@ -362,7 +412,11 @@ private: /// Partial specialization for C-style strings. We read the string value /// instead of treating it as pointer. template <> const char *Deserializer::Deserialize(); +template <> const char **Deserializer::Deserialize(); +template <> const uint8_t *Deserializer::Deserialize(); +template <> const void *Deserializer::Deserialize(); template <> char *Deserializer::Deserialize(); +template <> void *Deserializer::Deserialize(); /// Helpers to auto-synthesize function replay code. It deserializes the replay /// function's arguments one by one and finally calls the corresponding @@ -404,7 +458,11 @@ struct DefaultReplayer : public Replayer { DefaultReplayer(Result (*f)(Args...)) : Replayer(), f(f) {} void operator()(Deserializer &deserializer) const override { - deserializer.HandleReplayResult( + Replay(deserializer); + } + + Result Replay(Deserializer &deserializer) const { + return deserializer.HandleReplayResult( DeserializationHelper::template deserialized::doit( deserializer, f)); } @@ -419,6 +477,10 @@ struct DefaultReplayer : public Replayer { DefaultReplayer(void (*f)(Args...)) : Replayer(), f(f) {} void operator()(Deserializer &deserializer) const override { + Replay(deserializer); + } + + void Replay(Deserializer &deserializer) const { DeserializationHelper::template deserialized::doit( deserializer, f); deserializer.HandleReplayResultVoid(); @@ -474,18 +536,25 @@ public: /// Replay functions from a buffer. bool Replay(llvm::StringRef buffer); + /// Replay functions from a deserializer. + bool Replay(Deserializer &deserializer); + /// Returns the ID for a given function address. unsigned GetID(uintptr_t addr); + /// Get the replayer matching the given ID. + Replayer *GetReplayer(unsigned id); + + std::string GetSignature(unsigned id); + + void CheckID(unsigned expected, unsigned actual); + protected: /// Register the given replayer for a function (and the ID mapping). void DoRegister(uintptr_t RunID, std::unique_ptr replayer, SignatureStr signature); private: - std::string GetSignature(unsigned id); - Replayer *GetReplayer(unsigned id); - /// Mapping of function addresses to replayers and their ID. std::map, unsigned>> m_replayers; @@ -494,37 +563,6 @@ private: std::map> m_ids; }; -/// To be used as the "Runtime ID" of a constructor. It also invokes the -/// constructor when called. -template struct construct; -template struct construct { - static Class *doit(Args... args) { return new Class(args...); } -}; - -/// To be used as the "Runtime ID" of a member function. It also invokes the -/// member function when called. -template struct invoke; -template -struct invoke { - template struct method { - static Result doit(Class *c, Args... args) { return (c->*m)(args...); } - }; -}; - -template -struct invoke { - template struct method_const { - static Result doit(Class *c, Args... args) { return (c->*m)(args...); } - }; -}; - -template -struct invoke { - template struct method { - static void doit(Class *c, Args... args) { (c->*m)(args...); } - }; -}; - /// Maps an object to an index for serialization. Indices are unique and /// incremented for every new object. /// @@ -561,6 +599,10 @@ private: /// fundamental types (in which case we serialize its value) and pointer to /// objects (in which case we serialize their index). template void Serialize(T *t) { +#ifdef LLDB_REPRO_INSTR_TRACE + llvm::errs() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> " + << stringify_args(t) << "\n"; +#endif if (std::is_fundamental::value) { Serialize(*t); } else { @@ -573,7 +615,11 @@ private: /// fundamental types (in which case we serialize its value) and references /// to objects (in which case we serialize their index). template void Serialize(T &t) { - if (std::is_fundamental::value) { +#ifdef LLDB_REPRO_INSTR_TRACE + llvm::errs() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> " + << stringify_args(t) << "\n"; +#endif + if (is_trivially_serializable::value) { m_stream.write(reinterpret_cast(&t), sizeof(T)); } else { unsigned idx = m_tracker.GetIndexForObject(&t); @@ -581,14 +627,43 @@ private: } } + void Serialize(const void *v) { + // FIXME: Support void* + } + void Serialize(void *v) { // FIXME: Support void* - llvm_unreachable("void* is currently unsupported."); } void Serialize(const char *t) { - m_stream << t; - m_stream.write(0x0); +#ifdef LLDB_REPRO_INSTR_TRACE + llvm::errs() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> " + << stringify_args(t) << "\n"; +#endif + const size_t size = t ? strlen(t) : std::numeric_limits::max(); + Serialize(size); + if (t) { + m_stream << t; + m_stream.write(0x0); + } + } + + void Serialize(const char **t) { + size_t size = 0; + if (!t) { + Serialize(size); + return; + } + + // Compute the size of the array. + const char *const *temp = t; + while (*temp++) + size++; + Serialize(size); + + // Serialize the content of the array. + while (*t) + Serialize(*t++); } /// Serialization stream. @@ -596,24 +671,46 @@ private: /// Mapping of objects to indices. ObjectToIndex m_tracker; -}; +}; // namespace repro class InstrumentationData { public: - InstrumentationData() : m_serializer(nullptr), m_registry(nullptr){}; - InstrumentationData(Serializer &serializer, Registry ®istry) - : m_serializer(&serializer), m_registry(®istry){}; - - Serializer &GetSerializer() { return *m_serializer; } + Serializer *GetSerializer() { return m_serializer; } + Deserializer *GetDeserializer() { return m_deserializer; } Registry &GetRegistry() { return *m_registry; } - operator bool() { return m_serializer != nullptr && m_registry != nullptr; } + operator bool() { + return (m_serializer != nullptr || m_deserializer != nullptr) && + m_registry != nullptr; + } + + static void Initialize(Serializer &serializer, Registry ®istry); + static void Initialize(Deserializer &serializer, Registry ®istry); + static InstrumentationData &Instance(); + +protected: + friend llvm::optional_detail::OptionalStorage; + friend llvm::Optional; + + InstrumentationData() + : m_serializer(nullptr), m_deserializer(nullptr), m_registry(nullptr) {} + InstrumentationData(Serializer &serializer, Registry ®istry) + : m_serializer(&serializer), m_deserializer(nullptr), + m_registry(®istry) {} + InstrumentationData(Deserializer &deserializer, Registry ®istry) + : m_serializer(nullptr), m_deserializer(&deserializer), + m_registry(®istry) {} private: + static llvm::Optional &InstanceImpl(); + Serializer *m_serializer; + Deserializer *m_deserializer; Registry *m_registry; }; +struct EmptyArg {}; + /// RAII object that records function invocations and their return value. /// /// API calls are only captured when the API boundary is crossed. Once we're in @@ -628,7 +725,8 @@ private: /// this class is also used for logging. class Recorder { public: - Recorder(llvm::StringRef pretty_func = {}, std::string &&pretty_args = {}); + Recorder(); + Recorder(llvm::StringRef pretty_func, std::string &&pretty_args = {}); ~Recorder(); /// Records a single function call. @@ -679,9 +777,26 @@ public: m_result_recorded = true; } + /// Specializations for the no-argument methods. These are passed an empty + /// dummy argument so the same variadic macro can be used. These methods + /// strip the arguments before forwarding them. + template + void Record(Serializer &serializer, Registry ®istry, Result (*f)(), + const EmptyArg &arg) { + Record(serializer, registry, f); + } + /// Record the result of a function call. - template Result RecordResult(Result &&r) { - UpdateBoundary(); + template + Result RecordResult(Result &&r, bool update_boundary) { + // When recording the result from the LLDB_RECORD_RESULT macro, we need to + // update the boundary so we capture the copy constructor. However, when + // called to record the this pointer of the (copy) constructor, the + // boundary should not be toggled, because it is called from the + // LLDB_RECORD_CONSTRUCTOR macro, which might be followed by other API + // calls. + if (update_boundary) + UpdateBoundary(); if (m_serializer && ShouldCapture()) { assert(!m_result_recorded); m_serializer->SerializeAll(r); @@ -690,14 +805,41 @@ public: return std::forward(r); } + template + Result Replay(Deserializer &deserializer, Registry ®istry, uintptr_t addr, + bool update_boundary) { + unsigned actual_id = registry.GetID(addr); + unsigned id = deserializer.Deserialize(); + registry.CheckID(id, actual_id); + return ReplayResult( + static_cast *>(registry.GetReplayer(id)) + ->Replay(deserializer), + update_boundary); + } + + void Replay(Deserializer &deserializer, Registry ®istry, uintptr_t addr) { + unsigned actual_id = registry.GetID(addr); + unsigned id = deserializer.Deserialize(); + registry.CheckID(id, actual_id); + registry.GetReplayer(id)->operator()(deserializer); + } + + template + Result ReplayResult(Result &&r, bool update_boundary) { + if (update_boundary) + UpdateBoundary(); + return std::forward(r); + } + + bool ShouldCapture() { return m_local_boundary; } + private: + template friend struct replay; void UpdateBoundary() { if (m_local_boundary) g_global_boundary = false; } - bool ShouldCapture() { return m_local_boundary; } - #ifdef LLDB_REPRO_INSTR_TRACE void Log(unsigned id) { llvm::errs() << "Recording " << id << ": " << m_pretty_func << " (" @@ -721,7 +863,197 @@ private: static bool g_global_boundary; }; +/// To be used as the "Runtime ID" of a constructor. It also invokes the +/// constructor when called. +template struct construct; +template struct construct { + static Class *handle(lldb_private::repro::InstrumentationData data, + lldb_private::repro::Recorder &recorder, Class *c, + const EmptyArg &) { + return handle(data, recorder, c); + } + + static Class *handle(lldb_private::repro::InstrumentationData data, + lldb_private::repro::Recorder &recorder, Class *c, + Args... args) { + if (!data) + return nullptr; + + if (Serializer *serializer = data.GetSerializer()) { + recorder.Record(*serializer, data.GetRegistry(), &record, args...); + recorder.RecordResult(c, false); + } else if (Deserializer *deserializer = data.GetDeserializer()) { + if (recorder.ShouldCapture()) { + replay(recorder, *deserializer, data.GetRegistry()); + } + } + + return nullptr; + } + + static Class *record(Args... args) { return new Class(args...); } + + static Class *replay(Recorder &recorder, Deserializer &deserializer, + Registry ®istry) { + return recorder.Replay( + deserializer, registry, uintptr_t(&record), false); + } +}; + +/// To be used as the "Runtime ID" of a member function. It also invokes the +/// member function when called. +template struct invoke; +template +struct invoke { + template struct method { + static Result record(Class *c, Args... args) { return (c->*m)(args...); } + + static Result replay(Recorder &recorder, Deserializer &deserializer, + Registry ®istry) { + return recorder.Replay( + deserializer, registry, uintptr_t(&record), true); + } + }; +}; + +template +struct invoke { + template struct method { + static void record(Class *c, Args... args) { (c->*m)(args...); } + static void replay(Recorder &recorder, Deserializer &deserializer, + Registry ®istry) { + recorder.Replay(deserializer, registry, uintptr_t(&record)); + } + }; +}; + +template +struct invoke { + template struct method { + static Result record(Class *c, Args... args) { return (c->*m)(args...); } + static Result replay(Recorder &recorder, Deserializer &deserializer, + Registry ®istry) { + return recorder.Replay( + deserializer, registry, uintptr_t(&record), true); + } + }; +}; + +template +struct invoke { + template struct method { + static void record(Class *c, Args... args) { return (c->*m)(args...); } + static void replay(Recorder &recorder, Deserializer &deserializer, + Registry ®istry) { + recorder.Replay(deserializer, registry, uintptr_t(&record)); + } + }; +}; + +template struct replay; + +template +struct replay { + template struct method {}; +}; + +template +struct invoke { + template struct method { + static Result record(Args... args) { return (*m)(args...); } + static Result replay(Recorder &recorder, Deserializer &deserializer, + Registry ®istry) { + return recorder.Replay(deserializer, registry, + uintptr_t(&record), true); + } + }; +}; + +template struct invoke { + template struct method { + static void record(Args... args) { return (*m)(args...); } + static void replay(Recorder &recorder, Deserializer &deserializer, + Registry ®istry) { + recorder.Replay(deserializer, registry, uintptr_t(&record)); + } + }; +}; + +/// Special handling for functions returning strings as (char*, size_t). +/// { + +/// For inline replay, we ignore the arguments and use the ones from the +/// serializer instead. This doesn't work for methods that use a char* and a +/// size to return a string. For one these functions have a custom replayer to +/// prevent override the input buffer. Furthermore, the template-generated +/// deserialization is not easy to hook into. +/// +/// The specializations below hand-implement the serialization logic for the +/// inline replay. Instead of using the function from the registry, it uses the +/// one passed into the macro. +template struct invoke_char_ptr; +template +struct invoke_char_ptr { + template struct method { + static Result record(Class *c, char *s, size_t l) { + char *buffer = reinterpret_cast(calloc(l, sizeof(char))); + return (c->*m)(buffer, l); + } + + static Result replay(Recorder &recorder, Deserializer &deserializer, + Registry ®istry, char *str) { + deserializer.Deserialize(); + Class *c = deserializer.Deserialize(); + deserializer.Deserialize(); + size_t l = deserializer.Deserialize(); + return recorder.ReplayResult( + std::move(deserializer.HandleReplayResult((c->*m)(str, l))), true); + } + }; +}; + +template struct invoke_char_ptr; +template +struct invoke_char_ptr { + template struct method { + static Result record(Class *c, char *s, size_t l) { + char *buffer = reinterpret_cast(calloc(l, sizeof(char))); + return (c->*m)(buffer, l); + } + + static Result replay(Recorder &recorder, Deserializer &deserializer, + Registry ®istry, char *str) { + deserializer.Deserialize(); + Class *c = deserializer.Deserialize(); + deserializer.Deserialize(); + size_t l = deserializer.Deserialize(); + return recorder.ReplayResult( + std::move(deserializer.HandleReplayResult((c->*m)(str, l))), true); + } + }; +}; + +template +struct invoke_char_ptr { + template struct method { + static Result record(char *s, size_t l) { + char *buffer = reinterpret_cast(calloc(l, sizeof(char))); + return (*m)(buffer, l); + } + + static Result replay(Recorder &recorder, Deserializer &deserializer, + Registry ®istry, char *str) { + deserializer.Deserialize(); + deserializer.Deserialize(); + size_t l = deserializer.Deserialize(); + return recorder.ReplayResult( + std::move(deserializer.HandleReplayResult((*m)(str, l))), true); + } + }; +}; +/// } + } // namespace repro } // namespace lldb_private -#endif // LLDB_UTILITY_REPRODUCER_INSTRUMENTATION_H +#endif // LLDB_UTILITY_REPRODUCERINSTRUMENTATION_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/Scalar.h b/gnu/llvm/lldb/include/lldb/Utility/Scalar.h index 69c948ec622..f215fa71c84 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/Scalar.h +++ b/gnu/llvm/lldb/include/lldb/Utility/Scalar.h @@ -83,20 +83,11 @@ public: Scalar(double v) : m_type(e_double), m_float(v) { m_float = llvm::APFloat(v); } - Scalar(long double v, bool ieee_quad) - : m_type(e_long_double), m_float(static_cast(0)), - m_ieee_quad(ieee_quad) { - if (ieee_quad) - m_float = - llvm::APFloat(llvm::APFloat::IEEEquad(), - llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, - (reinterpret_cast(&v))->x)); - else - m_float = - llvm::APFloat(llvm::APFloat::x87DoubleExtended(), - llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, - (reinterpret_cast(&v))->x)); - } + Scalar(long double v) + : m_type(e_long_double), + m_float(llvm::APFloat::x87DoubleExtended(), + llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, + (reinterpret_cast(&v))->x)) {} Scalar(llvm::APInt v) : m_type(), m_float(static_cast(0)) { m_integer = llvm::APInt(v); m_type = GetBestTypeForBitSize(m_integer.getBitWidth(), true); @@ -115,7 +106,10 @@ public: bool ClearBit(uint32_t bit); - const void *GetBytes() const; + /// Store the binary representation of this value into the given storage. + /// Exactly GetByteSize() bytes will be stored, and the buffer must be large + /// enough to hold this data. + void GetBytes(llvm::MutableArrayRef storage) const; size_t GetByteSize() const; @@ -131,7 +125,7 @@ public: m_integer.clearAllBits(); } - const char *GetTypeAsCString() const; + const char *GetTypeAsCString() const { return GetValueTypeAsCString(m_type); } void GetValue(Stream *s, bool show_type) const; @@ -139,8 +133,8 @@ public: return (m_type >= e_sint) && (m_type <= e_long_double); } - /// Convert integer to \p type, limited to \p bits size. - void TruncOrExtendTo(Scalar::Type type, uint16_t bits); + /// Convert to an integer with \p bits and the given signedness. + void TruncOrExtendTo(uint16_t bits, bool sign); bool Promote(Scalar::Type type); @@ -162,16 +156,6 @@ public: // automagically by the compiler, so no temporary objects will need to be // created. As a result, we currently don't need a variety of overloaded set // value accessors. - Scalar &operator=(const int i); - Scalar &operator=(unsigned int v); - Scalar &operator=(long v); - Scalar &operator=(unsigned long v); - Scalar &operator=(long long v); - Scalar &operator=(unsigned long long v); - Scalar &operator=(float v); - Scalar &operator=(double v); - Scalar &operator=(long double v); - Scalar &operator=(llvm::APInt v); Scalar &operator+=(const Scalar &rhs); Scalar &operator<<=(const Scalar &rhs); // Shift left Scalar &operator>>=(const Scalar &rhs); // Shift right (arithmetic) @@ -204,7 +188,7 @@ public: unsigned char UChar(unsigned char fail_value = 0) const; - signed char SChar(char fail_value = 0) const; + signed char SChar(signed char fail_value = 0) const; unsigned short UShort(unsigned short fail_value = 0) const; @@ -220,7 +204,7 @@ public: unsigned long long ULongLong(unsigned long long fail_value = 0) const; - llvm::APInt SInt128(llvm::APInt &fail_value) const; + llvm::APInt SInt128(const llvm::APInt &fail_value) const; llvm::APInt UInt128(const llvm::APInt &fail_value) const; @@ -282,7 +266,8 @@ protected: Scalar::Type m_type; llvm::APInt m_integer; llvm::APFloat m_float; - bool m_ieee_quad = false; + + template T GetAs(T fail_value) const; private: friend const Scalar operator+(const Scalar &lhs, const Scalar &rhs); diff --git a/gnu/llvm/lldb/include/lldb/Utility/SelectHelper.h b/gnu/llvm/lldb/include/lldb/Utility/SelectHelper.h index ec37f194d32..63f1fe6421c 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/SelectHelper.h +++ b/gnu/llvm/lldb/include/lldb/Utility/SelectHelper.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SelectHelper_h_ -#define liblldb_SelectHelper_h_ +#ifndef LLDB_UTILITY_SELECTHELPER_H +#define LLDB_UTILITY_SELECTHELPER_H #include "lldb/Utility/Status.h" #include "lldb/lldb-types.h" @@ -68,4 +68,4 @@ protected: llvm::Optional m_end_time; }; -#endif // liblldb_SelectHelper_h_ +#endif // LLDB_UTILITY_SELECTHELPER_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/SharedCluster.h b/gnu/llvm/lldb/include/lldb/Utility/SharedCluster.h index 71bbb334cff..375c1c131a0 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/SharedCluster.h +++ b/gnu/llvm/lldb/include/lldb/Utility/SharedCluster.h @@ -6,90 +6,54 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_SharedCluster_h_ -#define utility_SharedCluster_h_ +#ifndef LLDB_UTILITY_SHAREDCLUSTER_H +#define LLDB_UTILITY_SHAREDCLUSTER_H #include "lldb/Utility/LLDBAssert.h" -#include "lldb/Utility/SharingPtr.h" - -#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include #include namespace lldb_private { -namespace imp { -template -class shared_ptr_refcount : public lldb_private::imp::shared_count { -public: - template - shared_ptr_refcount(Y *in) : shared_count(0), manager(in) {} - - shared_ptr_refcount() : shared_count(0) {} - - ~shared_ptr_refcount() override {} - - void on_zero_shared() override { manager->DecrementRefCount(); } - -private: - T *manager; -}; - -} // namespace imp - -template class ClusterManager { +template +class ClusterManager : public std::enable_shared_from_this> { public: - ClusterManager() : m_objects(), m_external_ref(0), m_mutex() {} + static std::shared_ptr Create() { + return std::shared_ptr(new ClusterManager()); + } ~ClusterManager() { - for (typename llvm::SmallPtrSet::iterator pos = m_objects.begin(), - end = m_objects.end(); - pos != end; ++pos) { - T *object = *pos; - delete object; - } - - // Decrement refcount should have been called on this ClusterManager, and - // it should have locked the mutex, now we will unlock it before we destroy - // it... - m_mutex.unlock(); + for (T *obj : m_objects) + delete obj; } void ManageObject(T *new_object) { std::lock_guard guard(m_mutex); - m_objects.insert(new_object); + assert(!llvm::is_contained(m_objects, new_object) && + "ManageObject called twice for the same object?"); + m_objects.push_back(new_object); } - typename lldb_private::SharingPtr GetSharedPointer(T *desired_object) { - { - std::lock_guard guard(m_mutex); - m_external_ref++; - if (0 == m_objects.count(desired_object)) { - lldbassert(false && "object not found in shared cluster when expected"); - desired_object = nullptr; - } + std::shared_ptr GetSharedPointer(T *desired_object) { + std::lock_guard guard(m_mutex); + auto this_sp = this->shared_from_this(); + if (!llvm::is_contained(m_objects, desired_object)) { + lldbassert(false && "object not found in shared cluster when expected"); + desired_object = nullptr; } - return typename lldb_private::SharingPtr( - desired_object, new imp::shared_ptr_refcount(this)); + return {std::move(this_sp), desired_object}; } private: - void DecrementRefCount() { - m_mutex.lock(); - m_external_ref--; - if (m_external_ref == 0) - delete this; - else - m_mutex.unlock(); - } - - friend class imp::shared_ptr_refcount; + ClusterManager() : m_objects(), m_mutex() {} - llvm::SmallPtrSet m_objects; - int m_external_ref; + llvm::SmallVector m_objects; std::mutex m_mutex; }; } // namespace lldb_private -#endif // utility_SharedCluster_h_ +#endif // LLDB_UTILITY_SHAREDCLUSTER_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/Status.h b/gnu/llvm/lldb/include/lldb/Utility/Status.h index 36f52922c9b..9babad18edc 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/Status.h +++ b/gnu/llvm/lldb/include/lldb/Utility/Status.h @@ -111,7 +111,7 @@ public: /// Set accessor from a kern_return_t. /// - /// Set accesssor for the error value to \a err and the error type to \c + /// Set accessor for the error value to \a err and the error type to \c /// MachKernel. /// /// \param[in] err @@ -123,9 +123,9 @@ public: int SetExpressionErrorWithFormat(lldb::ExpressionResults, const char *format, ...) __attribute__((format(printf, 3, 4))); - /// Set accesssor with an error value and type. + /// Set accessor with an error value and type. /// - /// Set accesssor for the error value to \a err and the error type to \a + /// Set accessor for the error value to \a err and the error type to \a /// type. /// /// \param[in] err @@ -217,4 +217,4 @@ template <> struct format_provider { } \ } while (0); -#endif // #ifndef LLDB_UTILITY_STATUS_H +#endif // LLDB_UTILITY_STATUS_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/Stream.h b/gnu/llvm/lldb/include/lldb/Utility/Stream.h index 18a16a3461c..e7f065a1fc7 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/Stream.h +++ b/gnu/llvm/lldb/include/lldb/Utility/Stream.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Stream_h_ -#define liblldb_Stream_h_ +#ifndef LLDB_UTILITY_STREAM_H +#define LLDB_UTILITY_STREAM_H #include "lldb/Utility/Flags.h" #include "lldb/lldb-defines.h" @@ -56,12 +56,13 @@ public: /// /// Construct with dump flags \a flags and the default address size. \a /// flags can be any of the above enumeration logical OR'ed together. - Stream(uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order); + Stream(uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order, + bool colors = false); /// Construct a default Stream, not binary, host byte order and host addr /// size. /// - Stream(); + Stream(bool colors = false); // FIXME: Streams should not be copyable. Stream(const Stream &other) : m_forwarder(*this) { (*this) = other; } @@ -270,10 +271,8 @@ public: /// optional string following the indentation spaces. /// /// \param[in] s - /// A C string to print following the indentation. If nullptr, just - /// output the indentation characters. - size_t Indent(const char *s = nullptr); - size_t Indent(llvm::StringRef s); + /// A string to print following the indentation. + size_t Indent(llvm::StringRef s = ""); /// Decrement the current indentation level. void IndentLess(unsigned amount = 2); @@ -405,8 +404,10 @@ protected: } public: - RawOstreamForward(Stream &target) - : llvm::raw_ostream(/*unbuffered*/ true), m_target(target) {} + RawOstreamForward(Stream &target, bool colors = false) + : llvm::raw_ostream(/*unbuffered*/ true), m_target(target) { + enable_colors(colors); + } }; RawOstreamForward m_forwarder; }; @@ -461,4 +462,4 @@ void DumpAddressRange(llvm::raw_ostream &s, uint64_t lo_addr, uint64_t hi_addr, } // namespace lldb_private -#endif // liblldb_Stream_h_ +#endif // LLDB_UTILITY_STREAM_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/StreamCallback.h b/gnu/llvm/lldb/include/lldb/Utility/StreamCallback.h index 6dbee67ecca..d6d74fb8479 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/StreamCallback.h +++ b/gnu/llvm/lldb/include/lldb/Utility/StreamCallback.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StreamCallback_h_ -#define liblldb_StreamCallback_h_ +#ifndef LLDB_UTILITY_STREAMCALLBACK_H +#define LLDB_UTILITY_STREAMCALLBACK_H #include "lldb/lldb-types.h" #include "llvm/Support/raw_ostream.h" @@ -32,4 +32,4 @@ private: } // namespace lldb_private -#endif // liblldb_StreamCallback_h +#endif // LLDB_UTILITY_STREAMCALLBACK_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/StreamString.h b/gnu/llvm/lldb/include/lldb/Utility/StreamString.h index 581e102d4e8..b0be0f7dd76 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/StreamString.h +++ b/gnu/llvm/lldb/include/lldb/Utility/StreamString.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StreamString_h_ -#define liblldb_StreamString_h_ +#ifndef LLDB_UTILITY_STREAMSTRING_H +#define LLDB_UTILITY_STREAMSTRING_H #include "lldb/Utility/Stream.h" #include "lldb/lldb-enumerations.h" @@ -51,4 +51,4 @@ protected: } // namespace lldb_private -#endif // liblldb_StreamString_h_ +#endif // LLDB_UTILITY_STREAMSTRING_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/StreamTee.h b/gnu/llvm/lldb/include/lldb/Utility/StreamTee.h index 92e94d4494f..2995bc07f42 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/StreamTee.h +++ b/gnu/llvm/lldb/include/lldb/Utility/StreamTee.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StreamTee_h_ -#define liblldb_StreamTee_h_ +#ifndef LLDB_UTILITY_STREAMTEE_H +#define LLDB_UTILITY_STREAMTEE_H #include @@ -19,7 +19,8 @@ namespace lldb_private { class StreamTee : public Stream { public: - StreamTee() : Stream(), m_streams_mutex(), m_streams() {} + StreamTee(bool colors = false) + : Stream(colors), m_streams_mutex(), m_streams() {} StreamTee(lldb::StreamSP &stream_sp) : Stream(), m_streams_mutex(), m_streams() { @@ -137,4 +138,4 @@ protected: } // namespace lldb_private -#endif // liblldb_StreamTee_h_ +#endif // LLDB_UTILITY_STREAMTEE_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/StringExtractor.h b/gnu/llvm/lldb/include/lldb/Utility/StringExtractor.h index 293fef2fbe6..6a5bb24779a 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/StringExtractor.h +++ b/gnu/llvm/lldb/include/lldb/Utility/StringExtractor.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_StringExtractor_h_ -#define utility_StringExtractor_h_ +#ifndef LLDB_UTILITY_STRINGEXTRACTOR_H +#define LLDB_UTILITY_STRINGEXTRACTOR_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" @@ -26,7 +26,7 @@ public: virtual ~StringExtractor(); void Reset(llvm::StringRef str) { - m_packet = str; + m_packet = std::string(str); m_index = 0; } @@ -118,4 +118,4 @@ protected: uint64_t m_index; }; -#endif // utility_StringExtractor_h_ +#endif // LLDB_UTILITY_STRINGEXTRACTOR_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/StringLexer.h b/gnu/llvm/lldb/include/lldb/Utility/StringLexer.h index 533fd4fb896..52f98e860da 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/StringLexer.h +++ b/gnu/llvm/lldb/include/lldb/Utility/StringLexer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_StringLexer_h_ -#define utility_StringLexer_h_ +#ifndef LLDB_UTILITY_STRINGLEXER_H +#define LLDB_UTILITY_STRINGLEXER_H #include #include @@ -53,4 +53,4 @@ private: } // namespace lldb_private -#endif // #ifndef utility_StringLexer_h_ +#endif // LLDB_UTILITY_STRINGLEXER_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/StringList.h b/gnu/llvm/lldb/include/lldb/Utility/StringList.h index 0b1d955678b..591a1586159 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/StringList.h +++ b/gnu/llvm/lldb/include/lldb/Utility/StringList.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StringList_h_ -#define liblldb_StringList_h_ +#ifndef LLDB_UTILITY_STRINGLIST_H +#define LLDB_UTILITY_STRINGLIST_H #include "llvm/ADT/StringRef.h" @@ -132,4 +132,4 @@ private: } // namespace lldb_private -#endif // liblldb_StringList_h_ +#endif // LLDB_UTILITY_STRINGLIST_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/StructuredData.h b/gnu/llvm/lldb/include/lldb/Utility/StructuredData.h index 01b14fc3d4d..14c82e66967 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/StructuredData.h +++ b/gnu/llvm/lldb/include/lldb/Utility/StructuredData.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StructuredData_h_ -#define liblldb_StructuredData_h_ +#ifndef LLDB_UTILITY_STRUCTUREDDATA_H +#define LLDB_UTILITY_STRUCTUREDDATA_H #include "llvm/ADT/StringRef.h" #include "llvm/Support/JSON.h" @@ -339,7 +339,7 @@ public: explicit String(llvm::StringRef S) : Object(lldb::eStructuredDataTypeString), m_value(S) {} - void SetValue(llvm::StringRef S) { m_value = S; } + void SetValue(llvm::StringRef S) { m_value = std::string(S); } llvm::StringRef GetValue() { return m_value; } @@ -553,4 +553,4 @@ public: } // namespace lldb_private -#endif // liblldb_StructuredData_h_ +#endif // LLDB_UTILITY_STRUCTUREDDATA_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/TildeExpressionResolver.h b/gnu/llvm/lldb/include/lldb/Utility/TildeExpressionResolver.h index 196fdfcf9ab..3253767ffd7 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/TildeExpressionResolver.h +++ b/gnu/llvm/lldb/include/lldb/Utility/TildeExpressionResolver.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_UTILITY_TILDE_EXPRESSION_RESOLVER_H -#define LLDB_UTILITY_TILDE_EXPRESSION_RESOLVER_H +#ifndef LLDB_UTILITY_TILDEEXPRESSIONRESOLVER_H +#define LLDB_UTILITY_TILDEEXPRESSIONRESOLVER_H #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" @@ -61,4 +61,4 @@ public: }; } -#endif // #ifndef LLDB_UTILITY_TILDE_EXPRESSION_RESOLVER_H +#endif // LLDB_UTILITY_TILDEEXPRESSIONRESOLVER_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/Timeout.h b/gnu/llvm/lldb/include/lldb/Utility/Timeout.h index 202b747fd48..80e20151557 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/Timeout.h +++ b/gnu/llvm/lldb/include/lldb/Utility/Timeout.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Timeout_h_ -#define liblldb_Timeout_h_ +#ifndef LLDB_UTILITY_TIMEOUT_H +#define LLDB_UTILITY_TIMEOUT_H #include "llvm/ADT/Optional.h" #include "llvm/Support/Chrono.h" @@ -67,4 +67,4 @@ struct format_provider, void> { }; } -#endif // liblldb_Timeout_h_ +#endif // LLDB_UTILITY_TIMEOUT_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/Timer.h b/gnu/llvm/lldb/include/lldb/Utility/Timer.h index ad9421a75b1..f97315b2db0 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/Timer.h +++ b/gnu/llvm/lldb/include/lldb/Utility/Timer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Timer_h_ -#define liblldb_Timer_h_ +#ifndef LLDB_UTILITY_TIMER_H +#define LLDB_UTILITY_TIMER_H #include "lldb/lldb-defines.h" #include "llvm/Support/Chrono.h" @@ -34,7 +34,8 @@ public: std::atomic m_count; std::atomic m_next; - DISALLOW_COPY_AND_ASSIGN(Category); + Category(const Category &) = delete; + const Category &operator=(const Category &) = delete; }; /// Default constructor. @@ -66,9 +67,10 @@ protected: static std::atomic g_display_depth; private: - DISALLOW_COPY_AND_ASSIGN(Timer); + Timer(const Timer &) = delete; + const Timer &operator=(const Timer &) = delete; }; } // namespace lldb_private -#endif // liblldb_Timer_h_ +#endif // LLDB_UTILITY_TIMER_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/TraceOptions.h b/gnu/llvm/lldb/include/lldb/Utility/TraceOptions.h index d5e21ccd8ba..97aad33899b 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/TraceOptions.h +++ b/gnu/llvm/lldb/include/lldb/Utility/TraceOptions.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_TraceOptions_h_ -#define liblldb_TraceOptions_h_ +#ifndef LLDB_UTILITY_TRACEOPTIONS_H +#define LLDB_UTILITY_TRACEOPTIONS_H #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" @@ -57,4 +57,4 @@ private: }; } -#endif // liblldb_TraceOptions_h_ +#endif // LLDB_UTILITY_TRACEOPTIONS_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/UUID.h b/gnu/llvm/lldb/include/lldb/Utility/UUID.h index 0284357be44..5327719094c 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/UUID.h +++ b/gnu/llvm/lldb/include/lldb/Utility/UUID.h @@ -63,18 +63,13 @@ public: std::string GetAsString(llvm::StringRef separator = "-") const; - size_t SetFromStringRef(llvm::StringRef str, uint32_t num_uuid_bytes = 16); + bool SetFromStringRef(llvm::StringRef str); // Same as SetFromStringRef, but if the resultant UUID is all 0 bytes, set the // UUID to invalid. - size_t SetFromOptionalStringRef(llvm::StringRef str, - uint32_t num_uuid_bytes = 16); - - // Decode as many UUID bytes (up to 16) as possible from the C string "cstr" - // This is used for auto completion where a partial UUID might have been - // typed in. It - /// Decode as many UUID bytes (up to 16) as possible from the C - /// string \a cstr. + bool SetFromOptionalStringRef(llvm::StringRef str); + + /// Decode as many UUID bytes as possible from the C string \a cstr. /// /// \param[in] str /// An llvm::StringRef that points at a UUID string value (no leading @@ -88,8 +83,7 @@ public: /// The original string, with all decoded bytes removed. static llvm::StringRef DecodeUUIDBytesFromString(llvm::StringRef str, - llvm::SmallVectorImpl &uuid_bytes, - uint32_t num_uuid_bytes = 16); + llvm::SmallVectorImpl &uuid_bytes); private: UUID(llvm::ArrayRef bytes) : m_bytes(bytes.begin(), bytes.end()) {} diff --git a/gnu/llvm/lldb/include/lldb/Utility/UriParser.h b/gnu/llvm/lldb/include/lldb/Utility/UriParser.h index 4a3f01230e1..6a64c3d747b 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/UriParser.h +++ b/gnu/llvm/lldb/include/lldb/Utility/UriParser.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_UriParser_h_ -#define utility_UriParser_h_ +#ifndef LLDB_UTILITY_URIPARSER_H +#define LLDB_UTILITY_URIPARSER_H #include "llvm/ADT/StringRef.h" @@ -28,4 +28,4 @@ public: }; } -#endif // utility_UriParser_h_ +#endif // LLDB_UTILITY_URIPARSER_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/UserID.h b/gnu/llvm/lldb/include/lldb/Utility/UserID.h index 2dc5cdb23d0..9fc6985a5a9 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/UserID.h +++ b/gnu/llvm/lldb/include/lldb/Utility/UserID.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_UserID_h_ -#define liblldb_UserID_h_ +#ifndef LLDB_UTILITY_USERID_H +#define LLDB_UTILITY_USERID_H #include "lldb/lldb-defines.h" #include "lldb/lldb-types.h" @@ -90,4 +90,4 @@ Stream &operator<<(Stream &strm, const UserID &uid); } // namespace lldb_private -#endif // liblldb_UserID_h_ +#endif // LLDB_UTILITY_USERID_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/UserIDResolver.h b/gnu/llvm/lldb/include/lldb/Utility/UserIDResolver.h index bca82a11b66..e0f7b69cc07 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/UserIDResolver.h +++ b/gnu/llvm/lldb/include/lldb/Utility/UserIDResolver.h @@ -53,4 +53,4 @@ private: } // namespace lldb_private -#endif // #ifndef LLDB_HOST_USERIDRESOLVER_H +#endif // LLDB_UTILITY_USERIDRESOLVER_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/VASPrintf.h b/gnu/llvm/lldb/include/lldb/Utility/VASPrintf.h index 582645fd229..a4b5f7ddae2 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/VASPrintf.h +++ b/gnu/llvm/lldb/include/lldb/Utility/VASPrintf.h @@ -17,4 +17,4 @@ namespace lldb_private { bool VASprintf(llvm::SmallVectorImpl &buf, const char *fmt, va_list args); } -#endif // #ifdef LLDB_UTILITY_VASPRINTF_H +#endif // LLDB_UTILITY_VASPRINTF_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/VMRange.h b/gnu/llvm/lldb/include/lldb/Utility/VMRange.h index 72f859b6758..4b01cd86da2 100644 --- a/gnu/llvm/lldb/include/lldb/Utility/VMRange.h +++ b/gnu/llvm/lldb/include/lldb/Utility/VMRange.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_VMRange_h_ -#define liblldb_VMRange_h_ +#ifndef LLDB_UTILITY_VMRANGE_H +#define LLDB_UTILITY_VMRANGE_H #include "lldb/lldb-types.h" #include "llvm/Support/raw_ostream.h" @@ -101,4 +101,4 @@ bool operator>=(const VMRange &lhs, const VMRange &rhs); } // namespace lldb_private -#endif // liblldb_VMRange_h_ +#endif // LLDB_UTILITY_VMRANGE_H diff --git a/gnu/llvm/lldb/include/lldb/Utility/XcodeSDK.h b/gnu/llvm/lldb/include/lldb/Utility/XcodeSDK.h new file mode 100644 index 00000000000..307fe7f4679 --- /dev/null +++ b/gnu/llvm/lldb/include/lldb/Utility/XcodeSDK.h @@ -0,0 +1,96 @@ +//===-- XcodeSDK.h ----------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_UTILITY_SDK_H +#define LLDB_UTILITY_SDK_H + +#include "lldb/lldb-forward.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/VersionTuple.h" +#include + +namespace llvm { +class Triple; +} + +namespace lldb_private { + +/// An abstraction for Xcode-style SDKs that works like \ref ArchSpec. +class XcodeSDK { + std::string m_name; + +public: + /// Different types of Xcode SDKs. + enum Type : int { + MacOSX = 0, + iPhoneSimulator, + iPhoneOS, + AppleTVSimulator, + AppleTVOS, + WatchSimulator, + watchOS, + bridgeOS, + Linux, + unknown = -1 + }; + static constexpr int numSDKTypes = Linux + 1; + + /// A parsed SDK directory name. + struct Info { + Type type = unknown; + llvm::VersionTuple version; + bool internal = false; + + Info() = default; + bool operator<(const Info &other) const; + bool operator==(const Info &other) const; + }; + + + /// Default constructor, constructs an empty string. + XcodeSDK() = default; + /// Construct an XcodeSDK object from a specification. + XcodeSDK(Info info); + /// Initialize an XcodeSDK object with an SDK name. The SDK name is the last + /// directory component of a path one would pass to clang's -isysroot + /// parameter. For example, "MacOSX.10.14.sdk". + XcodeSDK(std::string &&name) : m_name(std::move(name)) {} + static XcodeSDK GetAnyMacOS() { return XcodeSDK("MacOSX.sdk"); } + + /// The merge function follows a strict order to maintain monotonicity: + /// 1. SDK with the higher SDKType wins. + /// 2. The newer SDK wins. + void Merge(XcodeSDK other); + + XcodeSDK &operator=(XcodeSDK other); + XcodeSDK(const XcodeSDK&) = default; + bool operator==(XcodeSDK other); + + /// Return parsed SDK type and version number. + Info Parse() const; + bool IsAppleInternalSDK() const; + llvm::VersionTuple GetVersion() const; + Type GetType() const; + llvm::StringRef GetString() const; + /// Whether this Xcode SDK supports Swift. + bool SupportsSwift() const; + + /// Whether LLDB feels confident importing Clang modules from this SDK. + static bool SDKSupportsModules(Type type, llvm::VersionTuple version); + static bool SDKSupportsModules(Type desired_type, const FileSpec &sdk_path); + /// Return the canonical SDK name, such as "macosx" for the macOS SDK. + static std::string GetCanonicalName(Info info); + /// Return the best-matching SDK type for a specific triple. + static XcodeSDK::Type GetSDKTypeForTriple(const llvm::Triple &triple); + + static std::string FindXcodeContentsDirectoryInPath(llvm::StringRef path); +}; + +} // namespace lldb_private + +#endif diff --git a/gnu/llvm/lldb/include/lldb/lldb-defines.h b/gnu/llvm/lldb/include/lldb/lldb-defines.h index b87964403f7..fea8079779a 100644 --- a/gnu/llvm/lldb/include/lldb/lldb-defines.h +++ b/gnu/llvm/lldb/include/lldb/lldb-defines.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_lldb_defines_h_ -#define LLDB_lldb_defines_h_ +#ifndef LLDB_LLDB_DEFINES_H +#define LLDB_LLDB_DEFINES_H #include "lldb/lldb-types.h" @@ -133,15 +133,4 @@ #define UNUSED_IF_ASSERT_DISABLED(x) ((void)(x)) -#if defined(__cplusplus) - -/// \def DISALLOW_COPY_AND_ASSIGN(TypeName) -/// Macro definition for easily disallowing copy constructor and -/// assignment operators in C++ classes. -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName &) = delete; \ - const TypeName &operator=(const TypeName &) = delete - -#endif // #if defined(__cplusplus) - -#endif // LLDB_lldb_defines_h_ +#endif // LLDB_LLDB_DEFINES_H diff --git a/gnu/llvm/lldb/include/lldb/lldb-enumerations.h b/gnu/llvm/lldb/include/lldb/lldb-enumerations.h index 8cbb459ee1e..b3e8d604913 100644 --- a/gnu/llvm/lldb/include/lldb/lldb-enumerations.h +++ b/gnu/llvm/lldb/include/lldb/lldb-enumerations.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_lldb_enumerations_h_ -#define LLDB_lldb_enumerations_h_ +#ifndef LLDB_LLDB_ENUMERATIONS_H +#define LLDB_LLDB_ENUMERATIONS_H #include @@ -269,7 +269,8 @@ enum ExpressionResults { eExpressionHitBreakpoint, eExpressionTimedOut, eExpressionResultUnavailable, - eExpressionStoppedForDebug + eExpressionStoppedForDebug, + eExpressionThreadVanished }; enum SearchDepth { @@ -590,6 +591,7 @@ enum CommandArgumentType { eArgTypeWatchType, eArgRawInput, eArgTypeCommand, + eArgTypeColumnNum, eArgTypeLastArg // Always keep this entry as the last entry in this // enumeration!! }; @@ -694,6 +696,7 @@ enum SectionType { eSectionTypeDWARFDebugRngListsDwo, eSectionTypeDWARFDebugLocDwo, eSectionTypeDWARFDebugLocListsDwo, + eSectionTypeDWARFDebugTuIndex, }; FLAGS_ENUM(EmulateInstructionOptions){ @@ -1079,6 +1082,20 @@ enum TypeSummaryCapping { eTypeSummaryCapped = true, eTypeSummaryUncapped = false }; + +/// The result from a command interpreter run. +enum CommandInterpreterResult { + /// Command interpreter finished successfully. + eCommandInterpreterResultSuccess, + /// Stopped because the corresponding option was set and the inferior + /// crashed. + eCommandInterpreterResultInferiorCrash, + /// Stopped because the corresponding option was set and a command returned + /// an error. + eCommandInterpreterResultCommandError, + /// Stopped because quit was requested. + eCommandInterpreterResultQuitRequested, +}; } // namespace lldb -#endif // LLDB_lldb_enumerations_h_ +#endif // LLDB_LLDB_ENUMERATIONS_H diff --git a/gnu/llvm/lldb/include/lldb/lldb-forward.h b/gnu/llvm/lldb/include/lldb/lldb-forward.h index d2371f94f4b..4fd2a07dd61 100644 --- a/gnu/llvm/lldb/include/lldb/lldb-forward.h +++ b/gnu/llvm/lldb/include/lldb/lldb-forward.h @@ -6,25 +6,26 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_lldb_forward_h_ -#define LLDB_lldb_forward_h_ +#ifndef LLDB_LLDB_FORWARD_H +#define LLDB_LLDB_FORWARD_H #if defined(__cplusplus) -#include "lldb/Utility/SharingPtr.h" +#include // lldb forward declarations namespace lldb_private { class ABI; +class ASTResultSynthesizer; +class ASTStructExtractor; class Address; class AddressRange; class AddressResolver; class ArchSpec; -class ArmUnwindInfo; +class Architecture; class Args; -class ASTResultSynthesizer; -class ASTStructExtractor; +class ArmUnwindInfo; class Baton; class Block; class Breakpoint; @@ -44,16 +45,8 @@ class BreakpointSiteList; class BroadcastEventSpec; class Broadcaster; class BroadcasterManager; +class CXXSyntheticChildren; class CallFrameInfo; -class ClangASTContext; -class ClangASTImporter; -class ClangASTMetadata; -class ClangASTSource; -class ClangExpressionDeclMap; -class ClangExpressionParser; -class ClangExpressionVariable; -class ClangModulesDeclVendor; -class ClangPersistentVariables; class CommandInterpreter; class CommandInterpreterRunOptions; class CommandObject; @@ -61,15 +54,13 @@ class CommandObjectMultiword; class CommandReturnObject; class Communication; class CompactUnwindInfo; -struct CompilerContext; +class CompileUnit; class CompilerDecl; class CompilerDeclContext; class CompilerType; -class CompileUnit; class Connection; class ConnectionFileDescriptor; class ConstString; -class CXXSyntheticChildren; class DWARFCallFrameInfo; class DWARFDataExtractor; class DWARFExpression; @@ -85,7 +76,7 @@ class DynamicCheckerFunctions; class DynamicLoader; class Editline; class EmulateInstruction; -class Status; +class Environment; class EvaluateExpressionOptions; class Event; class EventData; @@ -94,26 +85,26 @@ class ExecutionContext; class ExecutionContextRef; class ExecutionContextScope; class Expression; +class ExpressionTypeSystemHelper; class ExpressionVariable; class ExpressionVariableList; -class ExpressionTypeSystemHelper; class File; class FileSpec; class FileSpecList; class Flags; -class TypeCategoryImpl; class FormatManager; class FormattersMatchCandidate; class FuncUnwinders; class Function; +class FunctionCaller; class FunctionInfo; +class IOHandler; +class IOObject; +class IRExecutionUnit; class InlineFunctionInfo; class Instruction; class InstructionList; class InstrumentationRuntime; -class IOHandler; -class IOObject; -class IRExecutionUnit; class JITLoader; class JITLoaderList; class Language; @@ -131,15 +122,13 @@ class Module; class ModuleList; class ModuleSpec; class ModuleSpecList; -struct NameSearchContext; class ObjectContainer; -class OptionGroup; -class OptionGroupOptions; -class OptionGroupPlatform; class ObjectFile; class ObjectFileJITDelegate; class OperatingSystem; -class Options; +class OptionGroup; +class OptionGroupOptions; +class OptionGroupPlatform; class OptionValue; class OptionValueArch; class OptionValueArgs; @@ -151,8 +140,8 @@ class OptionValueEnumeration; class OptionValueFileSpec; class OptionValueFileSpecList; class OptionValueFormat; -class OptionValueLanguage; class OptionValueFormatEntity; +class OptionValueLanguage; class OptionValuePathMappings; class OptionValueProperties; class OptionValueRegex; @@ -160,31 +149,32 @@ class OptionValueSInt64; class OptionValueString; class OptionValueUInt64; class OptionValueUUID; +class Options; class PathMappingList; -class FunctionCaller; class PersistentExpressionState; class Platform; class Process; class ProcessAttachInfo; -class ProcessModID; class ProcessInfo; class ProcessInstanceInfo; -class ProcessInstanceInfoList; class ProcessInstanceInfoMatch; class ProcessLaunchInfo; +class ProcessModID; class Property; -struct PropertyDefinition; +class Queue; +class QueueImpl; +class QueueItem; +class REPL; class RecognizedStackFrame; class RegisterCheckpoint; class RegisterContext; class RegisterValue; class RegularExpression; -class REPL; class RichManglingContext; class Scalar; class ScriptInterpreter; class ScriptInterpreterLocker; -struct ScriptSummaryFormat; +class ScriptedSyntheticChildren; class SearchFilter; class Section; class SectionList; @@ -198,21 +188,17 @@ class StackFrameList; class StackFrameRecognizer; class StackFrameRecognizerManager; class StackID; +class Status; class StopInfo; class Stoppoint; class StoppointCallbackContext; class StoppointLocation; class Stream; -template class StreamBuffer; class StreamFile; class StreamString; class StringList; -struct StringSummaryFormat; class StructuredDataImpl; class StructuredDataPlugin; -class SystemRuntime; -class TypeSummaryImpl; -class TypeSummaryOptions; class Symbol; class SymbolContext; class SymbolContextList; @@ -224,12 +210,7 @@ class SymbolVendor; class Symtab; class SyntheticChildren; class SyntheticChildrenFrontEnd; -class TypeFilterImpl; -class TypeSystem; -class ScriptedSyntheticChildren; -class Queue; -class QueueItem; -class QueueImpl; +class SystemRuntime; class Target; class TargetList; class TargetProperties; @@ -249,17 +230,22 @@ class ThreadSpec; class TraceOptions; class Type; class TypeAndOrName; +class TypeCategoryImpl; class TypeCategoryMap; +class TypeEnumMemberImpl; +class TypeEnumMemberListImpl; +class TypeFilterImpl; +class TypeFormatImpl; class TypeImpl; class TypeList; -class TypeMap; class TypeListImpl; -class TypeMemberImpl; +class TypeMap; class TypeMemberFunctionImpl; -class TypeEnumMemberImpl; -class TypeEnumMemberListImpl; -class TypeFormatImpl; +class TypeMemberImpl; class TypeNameSpecifierImpl; +class TypeSummaryImpl; +class TypeSummaryOptions; +class TypeSystem; class UUID; class UnixSignals; class Unwind; @@ -283,7 +269,12 @@ class VariableList; class Watchpoint; class WatchpointList; class WatchpointOptions; +struct CompilerContext; struct LineEntry; +struct PropertyDefinition; +struct ScriptSummaryFormat; +struct StringSummaryFormat; +template class StreamBuffer; } // namespace lldb_private @@ -299,17 +290,12 @@ typedef std::shared_ptr BreakpointSiteSP; typedef std::weak_ptr BreakpointSiteWP; typedef std::shared_ptr BreakpointLocationSP; typedef std::weak_ptr BreakpointLocationWP; -typedef std::shared_ptr BreakpointPreconditionSP; +typedef std::shared_ptr + BreakpointPreconditionSP; typedef std::shared_ptr BreakpointResolverSP; typedef std::shared_ptr BroadcasterSP; typedef std::shared_ptr BroadcasterManagerSP; typedef std::weak_ptr BroadcasterManagerWP; -typedef std::unique_ptr ClangASTContextUP; -typedef std::shared_ptr ClangASTImporterSP; -typedef std::unique_ptr - ClangModulesDeclVendorUP; -typedef std::unique_ptr - ClangPersistentVariablesUP; typedef std::shared_ptr UserExpressionSP; typedef std::shared_ptr CommandObjectSP; typedef std::shared_ptr CommunicationSP; @@ -467,7 +453,7 @@ typedef std::weak_ptr UnixSignalsWP; typedef std::shared_ptr UnwindAssemblySP; typedef std::shared_ptr UnwindPlanSP; typedef std::shared_ptr UtilityFunctionSP; -typedef lldb_private::SharingPtr ValueObjectSP; +typedef std::shared_ptr ValueObjectSP; typedef std::shared_ptr ValueSP; typedef std::shared_ptr ValueListSP; typedef std::shared_ptr VariableSP; @@ -477,13 +463,5 @@ 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_ +#endif // LLDB_LLDB_FORWARD_H diff --git a/gnu/llvm/lldb/include/lldb/lldb-private-defines.h b/gnu/llvm/lldb/include/lldb/lldb-private-defines.h index 737d9ef2434..d66e6ef1518 100644 --- a/gnu/llvm/lldb/include/lldb/lldb-private-defines.h +++ b/gnu/llvm/lldb/include/lldb/lldb-private-defines.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_lldb_private_defines_h_ -#define liblldb_lldb_private_defines_h_ +#ifndef LLDB_LLDB_PRIVATE_DEFINES_H +#define LLDB_LLDB_PRIVATE_DEFINES_H #if defined(__cplusplus) @@ -33,4 +33,4 @@ #endif // #if defined(__cplusplus) -#endif // liblldb_lldb_private_defines_h_ +#endif // LLDB_LLDB_PRIVATE_DEFINES_H diff --git a/gnu/llvm/lldb/include/lldb/lldb-private-enumerations.h b/gnu/llvm/lldb/include/lldb/lldb-private-enumerations.h index 9b7879c05f9..7009d1b4fba 100644 --- a/gnu/llvm/lldb/include/lldb/lldb-private-enumerations.h +++ b/gnu/llvm/lldb/include/lldb/lldb-private-enumerations.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_lldb_private_enumerations_h_ -#define LLDB_lldb_private_enumerations_h_ +#ifndef LLDB_LLDB_PRIVATE_ENUMERATIONS_H +#define LLDB_LLDB_PRIVATE_ENUMERATIONS_H #include "llvm/ADT/StringRef.h" #include "llvm/Support/FormatProviders.h" @@ -148,18 +148,6 @@ enum ExecutionPolicy { eExecutionPolicyTopLevel // used for top-level code }; -// Ways that the FormatManager picks a particular format for a type -enum FormatterChoiceCriterion { - eFormatterChoiceCriterionDirectChoice = 0x00000000, - eFormatterChoiceCriterionStrippedPointerReference = 0x00000001, - eFormatterChoiceCriterionNavigatedTypedefs = 0x00000002, - eFormatterChoiceCriterionRegularExpressionSummary = 0x00000004, - eFormatterChoiceCriterionRegularExpressionFilter = 0x00000004, - eFormatterChoiceCriterionLanguagePlugin = 0x00000008, - eFormatterChoiceCriterionStrippedBitField = 0x00000010, - eFormatterChoiceCriterionWentToStaticValue = 0x00000020 -}; - // Synchronicity behavior of scripted commands enum ScriptedCommandSynchronicity { eScriptedCommandSynchronicitySynchronous, @@ -267,4 +255,4 @@ template <> struct format_provider { }; } -#endif // LLDB_lldb_private_enumerations_h_ +#endif // LLDB_LLDB_PRIVATE_ENUMERATIONS_H diff --git a/gnu/llvm/lldb/include/lldb/lldb-private-forward.h b/gnu/llvm/lldb/include/lldb/lldb-private-forward.h index 330070745ad..b5944cba8f2 100644 --- a/gnu/llvm/lldb/include/lldb/lldb-private-forward.h +++ b/gnu/llvm/lldb/include/lldb/lldb-private-forward.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_lldb_private_forward_h_ -#define LLDB_lldb_private_forward_h_ +#ifndef LLDB_LLDB_PRIVATE_FORWARD_H +#define LLDB_LLDB_PRIVATE_FORWARD_H namespace lldb_private { // forward decls. @@ -18,4 +18,4 @@ class ResumeActionList; class UnixSignals; } -#endif // #ifndef LLDB_lldb_private_forward_h_ +#endif // LLDB_LLDB_PRIVATE_FORWARD_H diff --git a/gnu/llvm/lldb/include/lldb/lldb-private-interfaces.h b/gnu/llvm/lldb/include/lldb/lldb-private-interfaces.h index 27a2c4c3f27..1568e7a3cb5 100644 --- a/gnu/llvm/lldb/include/lldb/lldb-private-interfaces.h +++ b/gnu/llvm/lldb/include/lldb/lldb-private-interfaces.h @@ -6,21 +6,23 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_lldb_private_interfaces_h_ -#define liblldb_lldb_private_interfaces_h_ +#ifndef LLDB_LLDB_PRIVATE_INTERFACES_H +#define LLDB_LLDB_PRIVATE_INTERFACES_H #if defined(__cplusplus) #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" -#include "lldb/lldb-types.h" - #include "lldb/lldb-private-enumerations.h" - +#include "lldb/lldb-types.h" +#include #include namespace lldb_private { -typedef lldb::ABISP (*ABICreateInstance)(lldb::ProcessSP process_sp, const ArchSpec &arch); +typedef lldb::ABISP (*ABICreateInstance)(lldb::ProcessSP process_sp, + const ArchSpec &arch); +typedef std::unique_ptr (*ArchitectureCreateInstance)( + const ArchSpec &arch); typedef Disassembler *(*DisassemblerCreateInstance)(const ArchSpec &arch, const char *flavor); typedef DynamicLoader *(*DynamicLoaderCreateInstance)(Process *process, @@ -107,4 +109,4 @@ typedef void (*DebuggerInitializeCallback)(Debugger &debugger); #endif // #if defined(__cplusplus) -#endif // liblldb_lldb_private_interfaces_h_ +#endif // LLDB_LLDB_PRIVATE_INTERFACES_H diff --git a/gnu/llvm/lldb/include/lldb/lldb-private-types.h b/gnu/llvm/lldb/include/lldb/lldb-private-types.h index bff47117721..fb8c2db2e21 100644 --- a/gnu/llvm/lldb/include/lldb/lldb-private-types.h +++ b/gnu/llvm/lldb/include/lldb/lldb-private-types.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_lldb_private_types_h_ -#define liblldb_lldb_private_types_h_ +#ifndef LLDB_LLDB_PRIVATE_TYPES_H +#define LLDB_LLDB_PRIVATE_TYPES_H #if defined(__cplusplus) @@ -28,38 +28,42 @@ class ExecutionContext; typedef llvm::sys::DynamicLibrary (*LoadPluginCallbackType)( const lldb::DebuggerSP &debugger_sp, const FileSpec &spec, Status &error); -// Every register is described in detail including its name, alternate name -// (optional), encoding, size in bytes and the default display format. +/// Every register is described in detail including its name, alternate name +/// (optional), encoding, size in bytes and the default display format. struct RegisterInfo { - const char *name; // Name of this register, can't be NULL - const char *alt_name; // Alternate name of this register, can be NULL - uint32_t byte_size; // Size in bytes of the register - uint32_t byte_offset; // The byte offset in the register context data where - // this register's value is found. - // This is optional, and can be 0 if a particular RegisterContext does not - // need to address its registers by byte offset. - lldb::Encoding encoding; // Encoding of the register bits - lldb::Format format; // Default display format - uint32_t kinds[lldb::kNumRegisterKinds]; // Holds all of the various register - // numbers for all register kinds - uint32_t *value_regs; // List of registers (terminated with - // LLDB_INVALID_REGNUM). If this value is not null, - // all registers in this list will be read first, at - // which point the value for this register will be - // valid. For example, the value list for ah would be - // eax (x86) or rax (x64). - uint32_t *invalidate_regs; // List of registers (terminated with - // LLDB_INVALID_REGNUM). If this value is not - // null, all registers in this list will be - // invalidated when the value of this register - // changes. For example, the invalidate list for - // eax would be rax ax, ah, and al. - const uint8_t *dynamic_size_dwarf_expr_bytes; // A DWARF expression that when - // evaluated gives - // the byte size of this register. - size_t dynamic_size_dwarf_len; // The length of the DWARF expression in bytes - // in the dynamic_size_dwarf_expr_bytes - // member. + /// Name of this register, can't be NULL. + const char *name; + /// Alternate name of this register, can be NULL. + const char *alt_name; + /// Size in bytes of the register. + uint32_t byte_size; + /// The byte offset in the register context data where this register's + /// value is found. + /// This is optional, and can be 0 if a particular RegisterContext does not + /// need to address its registers by byte offset. + uint32_t byte_offset; + /// Encoding of the register bits. + lldb::Encoding encoding; + /// Default display format. + lldb::Format format; + /// Holds all of the various register numbers for all register kinds. + uint32_t kinds[lldb::kNumRegisterKinds]; // + /// List of registers (terminated with LLDB_INVALID_REGNUM). If this value is + /// not null, all registers in this list will be read first, at which point + /// the value for this register will be valid. For example, the value list + /// for ah would be eax (x86) or rax (x64). + uint32_t *value_regs; // + /// List of registers (terminated with LLDB_INVALID_REGNUM). If this value is + /// not null, all registers in this list will be invalidated when the value of + /// this register changes. For example, the invalidate list for eax would be + /// rax ax, ah, and al. + uint32_t *invalidate_regs; + /// A DWARF expression that when evaluated gives the byte size of this + /// register. + const uint8_t *dynamic_size_dwarf_expr_bytes; + /// The length of the DWARF expression in bytes in the + /// dynamic_size_dwarf_expr_bytes member. + size_t dynamic_size_dwarf_len; llvm::ArrayRef data(const uint8_t *context_base) const { return llvm::ArrayRef(context_base + byte_offset, byte_size); @@ -71,17 +75,20 @@ struct RegisterInfo { } }; -// Registers are grouped into register sets +/// Registers are grouped into register sets struct RegisterSet { - const char *name; // Name of this register set - const char *short_name; // A short name for this register set - size_t num_registers; // The number of registers in REGISTERS array below - const uint32_t *registers; // An array of register indices in this set. The - // values in this array are - // *indices* (not register numbers) into a particular RegisterContext's - // register array. For example, if eax is defined at index 4 for a - // particular RegisterContext, eax would be included in this RegisterSet by - // adding the value 4. Not by adding the value lldb_eax_i386. + /// Name of this register set. + const char *name; + /// A short name for this register set. + const char *short_name; + /// The number of registers in REGISTERS array below. + size_t num_registers; + /// An array of register indices in this set. The values in this array are + /// *indices* (not register numbers) into a particular RegisterContext's + /// register array. For example, if eax is defined at index 4 for a + /// particular RegisterContext, eax would be included in this RegisterSet by + /// adding the value 4. Not by adding the value lldb_eax_i386. + const uint32_t *registers; }; struct OptionEnumValueElement { @@ -101,22 +108,30 @@ struct OptionValidator { }; struct OptionDefinition { - uint32_t usage_mask; // Used to mark options that can be used together. If (1 - // << n & usage_mask) != 0 - // then this option belongs to option set n. - bool required; // This option is required (in the current usage level) - const char *long_option; // Full name for this option. - 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. - 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 - const char *usage_text; // Full text explaining what this options does and - // what (if any) argument to - // pass it. + /// Used to mark options that can be used together. If + /// `(1 << n & usage_mask) != 0` then this option belongs to option set n. + uint32_t usage_mask; + /// This option is required (in the current usage level). + bool required; + /// Full name for this option. + const char *long_option; + /// Single character for this option. + int short_option; + /// no_argument, required_argument or optional_argument + int option_has_arg; + /// If non-NULL, option is valid iff |validator->IsValid()|, otherwise + /// always valid. + OptionValidator *validator; + /// If not empty, an array of enum values. + OptionEnumValues enum_values; + /// The kind of completion for this option. + /// Contains values of the CommandCompletions::CommonCompletionTypes enum. + uint32_t completion_type; + /// Type of argument this option takes. + lldb::CommandArgumentType argument_type; + /// Full text explaining what this options does and what (if any) argument to + /// pass it. + const char *usage_text; }; typedef struct type128 { uint64_t x[2]; } type128; @@ -126,4 +141,4 @@ typedef struct type256 { uint64_t x[4]; } type256; #endif // #if defined(__cplusplus) -#endif // liblldb_lldb_private_types_h_ +#endif // LLDB_LLDB_PRIVATE_TYPES_H diff --git a/gnu/llvm/lldb/include/lldb/lldb-private.h b/gnu/llvm/lldb/include/lldb/lldb-private.h index 24954ad2a1f..d65773aecd6 100644 --- a/gnu/llvm/lldb/include/lldb/lldb-private.h +++ b/gnu/llvm/lldb/include/lldb/lldb-private.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_lldb_private_h_ -#define lldb_lldb_private_h_ +#ifndef LLDB_LLDB_PRIVATE_H +#define LLDB_LLDB_PRIVATE_H #if defined(__cplusplus) @@ -25,4 +25,4 @@ const char *GetVersion(); #endif // defined(__cplusplus) -#endif // lldb_lldb_private_h_ +#endif // LLDB_LLDB_PRIVATE_H diff --git a/gnu/llvm/lldb/include/lldb/lldb-public.h b/gnu/llvm/lldb/include/lldb/lldb-public.h index 449062f832f..840edc6603e 100644 --- a/gnu/llvm/lldb/include/lldb/lldb-public.h +++ b/gnu/llvm/lldb/include/lldb/lldb-public.h @@ -6,12 +6,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_lldb_h_ -#define LLDB_lldb_h_ +#ifndef LLDB_LLDB_PUBLIC_H +#define LLDB_LLDB_PUBLIC_H #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" -#endif // LLDB_lldb_h_ +#endif // LLDB_LLDB_PUBLIC_H diff --git a/gnu/llvm/lldb/include/lldb/lldb-types.h b/gnu/llvm/lldb/include/lldb/lldb-types.h index 414a9f30805..c3e2f07acc4 100644 --- a/gnu/llvm/lldb/include/lldb/lldb-types.h +++ b/gnu/llvm/lldb/include/lldb/lldb-types.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_lldb_types_h_ -#define LLDB_lldb_types_h_ +#ifndef LLDB_LLDB_TYPES_H +#define LLDB_LLDB_TYPES_H #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" @@ -91,4 +91,4 @@ typedef void *opaque_compiler_type_t; typedef uint64_t queue_id_t; } // namespace lldb -#endif // LLDB_lldb_types_h_ +#endif // LLDB_LLDB_TYPES_H diff --git a/gnu/llvm/lldb/include/lldb/lldb-versioning.h b/gnu/llvm/lldb/include/lldb/lldb-versioning.h index 702ebd19a3e..d9a0e6bf283 100644 --- a/gnu/llvm/lldb/include/lldb/lldb-versioning.h +++ b/gnu/llvm/lldb/include/lldb/lldb-versioning.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_lldb_versioning_h_ -#define LLDB_lldb_versioning_h_ +#ifndef LLDB_LLDB_VERSIONING_H +#define LLDB_LLDB_VERSIONING_H // LLDB API version #define LLDB_API_MAJOR_VERSION 1 @@ -1539,4 +1539,4 @@ // defined(LLDB_API_MINOR_VERSION_WANTED) && defined // (LLDB_API_MAJOR_VERSION) -#endif // LLDB_lldb_versioning_h_ +#endif // LLDB_LLDB_VERSIONING_H diff --git a/gnu/llvm/lldb/include/lldb/module.modulemap b/gnu/llvm/lldb/include/lldb/module.modulemap index e040df8f913..7feea8ee99c 100644 --- a/gnu/llvm/lldb/include/lldb/module.modulemap +++ b/gnu/llvm/lldb/include/lldb/module.modulemap @@ -49,12 +49,16 @@ module lldb_Host { module SocketAddress { header "Host/SocketAddress.h" export * } module Socket { header "Host/Socket.h" export * } module StringConvert { textual header "Host/StringConvert.h" export * } - module TaskPool { header "Host/TaskPool.h" export * } module Terminal { header "Host/Terminal.h" export * } module ThreadLauncher { header "Host/ThreadLauncher.h" export * } module Time { header "Host/Time.h" export * } module XML { header "Host/XML.h" export * } + module common { + umbrella "Host/common" + module * { export * } + } + export * } diff --git a/gnu/llvm/lldb/packages/Python/lldbconfig/__init__.py b/gnu/llvm/lldb/packages/Python/lldbconfig/__init__.py new file mode 100644 index 00000000000..6c43d709df7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbconfig/__init__.py @@ -0,0 +1 @@ +INITIALIZE = True diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/__init__.py b/gnu/llvm/lldb/packages/Python/lldbsuite/__init__.py index 4b59e4119b2..195b2683f7b 100644 --- a/gnu/llvm/lldb/packages/Python/lldbsuite/__init__.py +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/__init__.py @@ -20,10 +20,6 @@ def find_lldb_root(): # lldbsuite.lldb_root refers to the root of the git/svn source checkout lldb_root = find_lldb_root() -# lldbsuite.lldb_test_root refers to the root of the python test tree -lldb_test_root = os.path.join( - lldb_root, - "packages", - "Python", - "lldbsuite", - "test") +# lldbsuite.lldb_test_src_root refers to the root of the python test case tree +# (i.e. the actual unit tests). +lldb_test_root = os.path.join(lldb_root, "test", "API") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/configuration.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/configuration.py index 09fc646f96e..84de0130f99 100644 --- a/gnu/llvm/lldb/packages/Python/lldbsuite/test/configuration.py +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/configuration.py @@ -42,8 +42,10 @@ lldb_framework_path = None count = 1 # The 'arch' and 'compiler' can be specified via command line. -arch = None # Must be initialized after option parsing -compiler = None # Must be initialized after option parsing +arch = None +compiler = None +dsymutil = None +sdkroot = None # The overriden dwarf verison. dwarf_version = 0 @@ -55,6 +57,9 @@ settings = [('target.prefer-dynamic-value', 'no-dynamic-values')] # Path to the FileCheck testing tool. Not optional. filecheck = None +# Path to the yaml2obj tool. Not optional. +yaml2obj = None + # The arch might dictate some specific CFLAGS to be passed to the toolchain to build # the inferior programs. The global variable cflags_extras provides a hook to do # just that. @@ -87,7 +92,6 @@ session_file_format = 'fnmac' # Set this flag if there is any session info dumped during the test run. sdir_has_content = False - # svn_info stores the output from 'svn info lldb.base.dir'. svn_info = '' @@ -97,7 +101,7 @@ verbose = 0 # By default, search from the script directory. # We can't use sys.path[0] to determine the script directory # because it doesn't work under a debugger -testdirs = [os.path.dirname(os.path.realpath(__file__))] +testdirs = [lldbsuite.lldb_test_root] # Separator string. separator = '-' * 70 @@ -117,18 +121,13 @@ lldb_module_cache_dir = None # The clang module cache directory used by clang. clang_module_cache_dir = None -# The only directory to scan for tests. If multiple test directories are -# specified, and an exclusive test subdirectory is specified, the latter option -# takes precedence. -exclusive_test_subdir = None - # Test results handling globals -results_filename = None -results_formatter_name = None -results_formatter_object = None -results_formatter_options = None test_result = None +# Reproducers +capture_path = None +replay_path = None + # Test rerun configuration vars rerun_all_issues = False @@ -136,6 +135,13 @@ rerun_all_issues = False # same base name. all_tests = set() +# LLDB library directory. +lldb_libs_dir = None + +# A plugin whose tests will be enabled, like intel-pt. +enabled_plugins = [] + + def shouldSkipBecauseOfCategories(test_categories): if use_categories: if len(test_categories) == 0 or len( @@ -149,40 +155,31 @@ def shouldSkipBecauseOfCategories(test_categories): return False -def get_absolute_path_to_exclusive_test_subdir(): +def get_filecheck_path(): """ - If an exclusive test subdirectory is specified, return its absolute path. - Otherwise return None. + Get the path to the FileCheck testing tool. """ - test_directory = os.path.dirname(os.path.realpath(__file__)) - - if not exclusive_test_subdir: - return - - if len(exclusive_test_subdir) > 0: - test_subdir = os.path.join(test_directory, exclusive_test_subdir) - if os.path.isdir(test_subdir): - return test_subdir - - print('specified test subdirectory {} is not a valid directory\n' - .format(test_subdir)) - + if filecheck and os.path.lexists(filecheck): + return filecheck -def get_absolute_path_to_root_test_dir(): +def get_yaml2obj_path(): """ - If an exclusive test subdirectory is specified, return its absolute path. - Otherwise, return the absolute path of the root test directory. + Get the path to the yaml2obj tool. """ - test_subdir = get_absolute_path_to_exclusive_test_subdir() - if test_subdir: - return test_subdir - - return os.path.dirname(os.path.realpath(__file__)) + if yaml2obj and os.path.lexists(yaml2obj): + return yaml2obj +def is_reproducer_replay(): + """ + Returns true when dotest is being replayed from a reproducer. Never use + this method to guard SB API calls as it will cause a divergence between + capture and replay. + """ + return replay_path is not None -def get_filecheck_path(): +def is_reproducer(): """ - Get the path to the FileCheck testing tool. + Returns true when dotest is capturing a reproducer or is being replayed + from a reproducer. Use this method to guard SB API calls. """ - if filecheck and os.path.lexists(filecheck): - return filecheck + return capture_path or replay_path diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/decorators.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/decorators.py index ec17cb7c256..534bcbf59ac 100644 --- a/gnu/llvm/lldb/packages/Python/lldbsuite/test/decorators.py +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/decorators.py @@ -158,7 +158,8 @@ def _decorateTest(mode, debug_info=None, swig_version=None, py_version=None, macos_version=None, - remote=None, dwarf_version=None): + remote=None, dwarf_version=None, + setting=None): def fn(self): skip_for_os = _match_decorator_property( lldbplatform.translate(oslist), self.getPlatform()) @@ -172,7 +173,7 @@ def _decorateTest(mode, skip_for_debug_info = _match_decorator_property( debug_info, self.getDebugInfo()) skip_for_triple = _match_decorator_property( - triple, lldb.DBG.GetSelectedPlatform().GetTriple()) + triple, lldb.selected_platform.GetTriple()) skip_for_remote = _match_decorator_property( remote, lldb.remote_platform is not None) @@ -196,6 +197,8 @@ def _decorateTest(mode, skip_for_dwarf_version = (dwarf_version is None) or ( _check_expected_version(dwarf_version[0], dwarf_version[1], self.getDwarfVersion())) + skip_for_setting = (setting is None) or ( + setting in configuration.settings) # For the test to be skipped, all specified (e.g. not None) parameters must be True. # An unspecified parameter means "any", so those are marked skip by default. And we skip @@ -210,7 +213,8 @@ def _decorateTest(mode, (py_version, skip_for_py_version, "python version"), (macos_version, skip_for_macos_version, "macOS version"), (remote, skip_for_remote, "platform locality (remote/local)"), - (dwarf_version, skip_for_dwarf_version, "dwarf version")] + (dwarf_version, skip_for_dwarf_version, "dwarf version"), + (setting, skip_for_setting, "setting")] reasons = [] final_skip_result = True for this_condition in conditions: @@ -254,7 +258,8 @@ def expectedFailureAll(bugnumber=None, debug_info=None, swig_version=None, py_version=None, macos_version=None, - remote=None, dwarf_version=None): + remote=None, dwarf_version=None, + setting=None): return _decorateTest(DecorateMode.Xfail, bugnumber=bugnumber, oslist=oslist, hostoslist=hostoslist, @@ -263,7 +268,8 @@ def expectedFailureAll(bugnumber=None, debug_info=debug_info, swig_version=swig_version, py_version=py_version, macos_version=None, - remote=remote,dwarf_version=dwarf_version) + remote=remote,dwarf_version=dwarf_version, + setting=setting) # provide a function to skip on defined oslist, compiler version, and archs @@ -279,7 +285,8 @@ def skipIf(bugnumber=None, debug_info=None, swig_version=None, py_version=None, macos_version=None, - remote=None, dwarf_version=None): + remote=None, dwarf_version=None, + setting=None): return _decorateTest(DecorateMode.Skip, bugnumber=bugnumber, oslist=oslist, hostoslist=hostoslist, @@ -288,7 +295,8 @@ def skipIf(bugnumber=None, debug_info=debug_info, swig_version=swig_version, py_version=py_version, macos_version=macos_version, - remote=remote, dwarf_version=dwarf_version) + remote=remote, dwarf_version=dwarf_version, + setting=setting) def _skip_for_android(reason, api_levels, archs): @@ -403,14 +411,15 @@ def expectedFailureOS( debug_info=debug_info) -def expectedFailureDarwin(bugnumber=None, compilers=None, debug_info=None): +def expectedFailureDarwin(bugnumber=None, compilers=None, debug_info=None, archs=None): # For legacy reasons, we support both "darwin" and "macosx" as OS X # triples. return expectedFailureOS( lldbplatform.darwin_all, bugnumber, compilers, - debug_info=debug_info) + debug_info=debug_info, + archs=archs) def expectedFailureAndroid(bugnumber=None, api_levels=None, archs=None): @@ -543,6 +552,16 @@ def skipIfNoSBHeaders(func): return skipTestIfFn(are_sb_headers_missing)(func) +def skipIfRosetta(bugnumber): + """Skip a test when running the testsuite on macOS under the Rosetta translation layer.""" + def is_running_rosetta(self): + if not lldbplatformutil.getPlatform() in ['darwin', 'macosx']: + return "not on macOS" + if (platform.uname()[5] == "arm") and (self.getArchitecture() == "x86_64"): + return "skipped under Rosetta" + return None + return skipTestIfFn(is_running_rosetta) + def skipIfiOSSimulator(func): """Decorate the item to skip tests that should be skipped on the iOS Simulator.""" def is_ios_simulator(): @@ -694,7 +713,7 @@ def skipUnlessHasCallSiteInfo(func): f = tempfile.NamedTemporaryFile() cmd = "echo 'int main() {}' | " \ - "%s -g -glldb -O1 -Xclang -femit-debug-entry-values -S -emit-llvm -x c -o %s -" % (compiler_path, f.name) + "%s -g -glldb -O1 -S -emit-llvm -x c -o %s -" % (compiler_path, f.name) if os.popen(cmd).close() is not None: return "Compiler can't compile with call site info enabled" @@ -711,6 +730,9 @@ def skipUnlessThreadSanitizer(func): """Decorate the item to skip test unless Clang -fsanitize=thread is supported.""" def is_compiler_clang_with_thread_sanitizer(self): + if is_running_under_asan(): + return "Thread sanitizer tests are disabled when runing under ASAN" + compiler_path = self.getCompiler() compiler = os.path.basename(compiler_path) if not compiler.startswith("clang"): @@ -734,6 +756,9 @@ def skipUnlessUndefinedBehaviorSanitizer(func): """Decorate the item to skip test unless -fsanitize=undefined is supported.""" def is_compiler_clang_with_ubsan(self): + if is_running_under_asan(): + return "Undefined behavior sanitizer tests are disabled when runing under ASAN" + # Write out a temp file which exhibits UB. inputf = tempfile.NamedTemporaryFile(suffix='.c', mode='w') inputf.write('int main() { int x = 0; return x / x; }\n') @@ -777,10 +802,21 @@ def skipUnlessUndefinedBehaviorSanitizer(func): return skipTestIfFn(is_compiler_clang_with_ubsan)(func) +def is_running_under_asan(): + if ('ASAN_OPTIONS' in os.environ): + return "ASAN unsupported" + return None + def skipUnlessAddressSanitizer(func): """Decorate the item to skip test unless Clang -fsanitize=thread is supported.""" def is_compiler_with_address_sanitizer(self): + # Also don't run tests that use address sanitizer inside an + # address-sanitized LLDB. The tests don't support that + # configuration. + if is_running_under_asan(): + return "Address sanitizer tests are disabled when runing under ASAN" + compiler_path = self.getCompiler() compiler = os.path.basename(compiler_path) f = tempfile.NamedTemporaryFile() @@ -795,6 +831,10 @@ def skipUnlessAddressSanitizer(func): return None return skipTestIfFn(is_compiler_with_address_sanitizer)(func) +def skipIfAsan(func): + """Skip this test if the environment is set up to run LLDB *itself* under ASAN.""" + return skipTestIfFn(is_running_under_asan)(func) + def _get_bool_config_skip_if_decorator(key): config = lldb.SBDebugger.GetBuildConfiguration() value_node = config.GetValueForKey(key) @@ -839,10 +879,10 @@ def skipUnlessFeature(feature): return "%s is not supported on this system." % feature return skipTestIfFn(is_feature_enabled) -def skipIfAsan(func): - """Skip this test if the environment is set up to run LLDB itself under ASAN.""" - def is_asan(): - if ('ASAN_OPTIONS' in os.environ): - return "ASAN unsupported" +def skipIfReproducer(func): + """Skip this test if the environment is set up to run LLDB with reproducers.""" + def is_reproducer(): + if configuration.capture_path or configuration.replay_path: + return "reproducers unsupported" return None - return skipTestIfFn(is_asan)(func) + return skipTestIfFn(is_reproducer)(func) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/dotest.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/dotest.py index 560e47dc58d..67f227cad71 100644 --- a/gnu/llvm/lldb/packages/Python/lldbsuite/test/dotest.py +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/dotest.py @@ -49,9 +49,6 @@ from . import test_result from lldbsuite.test_event.event_builder import EventBuilder from ..support import seven -def get_dotest_invocation(): - return ' '.join(sys.argv) - def is_exe(fpath): """Returns true if fpath is an executable.""" @@ -220,7 +217,6 @@ def parseOptionsAndInitTestdirs(): parser = dotest_args.create_parser() args = parser.parse_args() except: - print(get_dotest_invocation()) raise if args.unset_env_varnames: @@ -243,10 +239,6 @@ def parseOptionsAndInitTestdirs(): if args.set_inferior_env_vars: lldbtest_config.inferior_env = ' '.join(args.set_inferior_env_vars) - # Only print the args if being verbose. - if args.v: - print(get_dotest_invocation()) - if args.h: do_help = True @@ -275,18 +267,22 @@ def parseOptionsAndInitTestdirs(): break if args.dsymutil: - os.environ['DSYMUTIL'] = args.dsymutil + configuration.dsymutil = args.dsymutil elif platform_system == 'Darwin': - os.environ['DSYMUTIL'] = seven.get_command_output( + configuration.dsymutil = seven.get_command_output( 'xcrun -find -toolchain default dsymutil') + + # The lldb-dotest script produced by the CMake build passes in a path to a + # working FileCheck and yaml2obj binary. So does one specific Xcode + # project target. However, when invoking dotest.py directly, a valid + # --filecheck and --yaml2obj option needs to be given. if args.filecheck: - # The lldb-dotest script produced by the CMake build passes in a path - # to a working FileCheck binary. So does one specific Xcode project - # target. However, when invoking dotest.py directly, a valid --filecheck - # option needs to be given. configuration.filecheck = os.path.abspath(args.filecheck) + if args.yaml2obj: + configuration.yaml2obj = os.path.abspath(args.yaml2obj) + if not configuration.get_filecheck_path(): logging.warning('No valid FileCheck executable; some tests may fail...') logging.warning('(Double-check the --filecheck argument to dotest.py)') @@ -302,19 +298,12 @@ def parseOptionsAndInitTestdirs(): # Set SDKROOT if we are using an Apple SDK if platform_system == 'Darwin' and args.apple_sdk: - os.environ['SDKROOT'] = seven.get_command_output( + configuration.sdkroot = seven.get_command_output( 'xcrun --sdk "%s" --show-sdk-path 2> /dev/null' % (args.apple_sdk)) if args.arch: configuration.arch = args.arch - if configuration.arch.startswith( - 'arm') and platform_system == 'Darwin' and not args.apple_sdk: - os.environ['SDKROOT'] = seven.get_command_output( - 'xcrun --sdk iphoneos.internal --show-sdk-path 2> /dev/null') - if not os.path.exists(os.environ['SDKROOT']): - os.environ['SDKROOT'] = seven.get_command_output( - 'xcrun --sdk iphoneos --show-sdk-path 2> /dev/null') else: configuration.arch = platform_machine @@ -349,7 +338,8 @@ def parseOptionsAndInitTestdirs(): logging.error('"%s" is not a setting in the form "key=value"', setting[0]) sys.exit(-1) - configuration.settings.append(setting[0].split('=', 1)) + setting_list = setting[0].split('=', 1) + configuration.settings.append((setting_list[0], setting_list[1])) if args.d: sys.stdout.write( @@ -377,7 +367,10 @@ def parseOptionsAndInitTestdirs(): args.executable) sys.exit(-1) - if args.server: + if args.server and args.out_of_tree_debugserver: + logging.warning('Both --server and --out-of-tree-debugserver are set') + + if args.server and not args.out_of_tree_debugserver: os.environ['LLDB_DEBUGSERVER_PATH'] = args.server if args.excluded: @@ -415,18 +408,16 @@ def parseOptionsAndInitTestdirs(): if do_help: usage(parser) - if args.results_file: - configuration.results_filename = args.results_file + # Reproducer arguments + if args.capture_path and args.replay_path: + logging.error('Cannot specify both a capture and a replay path.') + sys.exit(-1) - if args.results_formatter: - configuration.results_formatter_name = args.results_formatter - if args.results_formatter_options: - configuration.results_formatter_options = args.results_formatter_options + if args.capture_path: + configuration.capture_path = args.capture_path - # Default to using the BasicResultsFormatter if no formatter is specified. - if configuration.results_formatter_name is None: - configuration.results_formatter_name = ( - "lldbsuite.test_event.formatter.results_formatter.ResultsFormatter") + if args.replay_path: + configuration.replay_path = args.replay_path # rerun-related arguments configuration.rerun_all_issues = args.rerun_all_issues @@ -450,7 +441,11 @@ def parseOptionsAndInitTestdirs(): configuration.clang_module_cache_dir = os.path.join( configuration.test_build_dir, 'module-cache-clang') - os.environ['CLANG_MODULE_CACHE_DIR'] = configuration.clang_module_cache_dir + if args.lldb_libs_dir: + configuration.lldb_libs_dir = args.lldb_libs_dir + + if args.enabled_plugins: + configuration.enabled_plugins = args.enabled_plugins # Gather all the dirs passed on the command line. if len(args.args) > 0: @@ -461,16 +456,10 @@ def parseOptionsAndInitTestdirs(): def setupTestResults(): """Sets up test results-related objects based on arg settings.""" - # Setup the results formatter configuration. - formatter_config = formatter.FormatterConfig() - formatter_config.filename = configuration.results_filename - formatter_config.formatter_name = configuration.results_formatter_name - formatter_config.formatter_options = ( - configuration.results_formatter_options) # Create the results formatter. formatter_spec = formatter.create_results_formatter( - formatter_config) + "lldbsuite.test_event.formatter.results_formatter.ResultsFormatter") if formatter_spec is not None and formatter_spec.formatter is not None: configuration.results_formatter_object = formatter_spec.formatter @@ -501,12 +490,12 @@ def setupSysPath(): sys.exit(-1) os.environ["LLDB_TEST"] = scriptPath + os.environ["LLDB_TEST_SRC"] = lldbsuite.lldb_test_root # Set up the root build directory. - builddir = configuration.test_build_dir if not configuration.test_build_dir: raise Exception("test_build_dir is not set") - os.environ["LLDB_BUILD"] = os.path.abspath(configuration.test_build_dir) + configuration.test_build_dir = os.path.abspath(configuration.test_build_dir) # Set up the LLDB_SRC environment variable, so that the tests can locate # the LLDB source code. @@ -559,10 +548,7 @@ def setupSysPath(): # confusingly, this is the "bin" directory lldbLibDir = os.path.dirname(lldbtest_config.lldbExec) os.environ["LLDB_LIB_DIR"] = lldbLibDir - lldbImpLibDir = os.path.join( - lldbLibDir, - '..', - 'lib') if sys.platform.startswith('win32') else lldbLibDir + lldbImpLibDir = configuration.lldb_libs_dir os.environ["LLDB_IMPLIB_DIR"] = lldbImpLibDir print("LLDB library dir:", os.environ["LLDB_LIB_DIR"]) print("LLDB import library dir:", os.environ["LLDB_IMPLIB_DIR"]) @@ -773,16 +759,6 @@ def visit(prefix, dir, names): raise -def setSetting(setting, value): - import lldb - ci = lldb.DBG.GetCommandInterpreter() - res = lldb.SBCommandReturnObject() - cmd = 'setting set %s %s'%(setting, value) - print(cmd) - ci.HandleCommand(cmd, res, False) - if not res.Succeeded(): - raise Exception('failed to run "%s"'%cmd) - # ======================================== # # # # Execution of the test driver starts here # @@ -808,6 +784,8 @@ def checkDsymForUUIDIsNotOn(): def exitTestSuite(exitCode=None): + # lldb.py does SBDebugger.Initialize(). + # Call SBDebugger.Terminate() on exit. import lldb lldb.SBDebugger.Terminate() if exitCode: @@ -930,7 +908,7 @@ def checkWatchpointSupport(): def checkDebugInfoSupport(): import lldb - platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2] + platform = lldb.selected_platform.GetTriple().split('-')[2] compiler = configuration.compiler skipped = [] for cat in test_categories.debug_info_categories: @@ -960,17 +938,26 @@ def run_suite(): setupSysPath() - - # For the time being, let's bracket the test runner within the - # lldb.SBDebugger.Initialize()/Terminate() pair. + import lldbconfig + if configuration.capture_path or configuration.replay_path: + lldbconfig.INITIALIZE = False import lldb + if configuration.capture_path: + lldb.SBReproducer.Capture(configuration.capture_path) + lldb.SBReproducer.SetAutoGenerate(True) + elif configuration.replay_path: + lldb.SBReproducer.PassiveReplay(configuration.replay_path) + + if not lldbconfig.INITIALIZE: + lldb.SBDebugger.Initialize() + + # Use host platform by default. + lldb.selected_platform = lldb.SBPlatform.GetHostPlatform() + # Now we can also import lldbutil from lldbsuite.test import lldbutil - # Create a singleton SBDebugger in the lldb namespace. - lldb.DBG = lldb.SBDebugger.Create() - if configuration.lldb_platform_name: print("Setting up remote platform '%s'" % (configuration.lldb_platform_name)) @@ -1019,7 +1006,7 @@ def run_suite(): if not lldb.remote_platform.SetWorkingDirectory( configuration.lldb_platform_working_dir): raise Exception("failed to set working directory '%s'" % configuration.lldb_platform_working_dir) - lldb.DBG.SetSelectedPlatform(lldb.remote_platform) + lldb.selected_platform = lldb.remote_platform else: lldb.remote_platform = None configuration.lldb_platform_working_dir = None @@ -1027,10 +1014,9 @@ def run_suite(): # Set up the working directory. # Note that it's not dotest's job to clean this directory. - build_dir = configuration.test_build_dir - lldbutil.mkdir_p(build_dir) + lldbutil.mkdir_p(configuration.test_build_dir) - target_platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2] + target_platform = lldb.selected_platform.GetTriple().split('-')[2] checkLibcxxSupport() checkLibstdcxxSupport() @@ -1050,15 +1036,7 @@ def run_suite(): "netbsd" in target_platform or "windows" in target_platform) - # Collect tests from the specified testing directories. If a test - # subdirectory filter is explicitly specified, limit the search to that - # subdirectory. - exclusive_test_subdir = configuration.get_absolute_path_to_exclusive_test_subdir() - if exclusive_test_subdir: - dirs_to_search = [exclusive_test_subdir] - else: - dirs_to_search = configuration.testdirs - for testdir in dirs_to_search: + for testdir in configuration.testdirs: for (dirpath, dirnames, filenames) in os.walk(testdir): visit('Test', dirpath, filenames) @@ -1066,10 +1044,6 @@ def run_suite(): # Now that we have loaded all the test cases, run the whole test suite. # - # Set any user-overridden settings. - for key, value in configuration.settings: - setSetting(key, value) - # Install the control-c handler. unittest2.signals.installHandler() @@ -1080,7 +1054,6 @@ def run_suite(): "\nSession logs for test failures/errors/unexpected successes" " will go into directory '%s'\n" % configuration.sdir_name) - sys.stderr.write("Command invoked: %s\n" % get_dotest_invocation()) # # Invoke the default TextTestRunner to run the test suite @@ -1091,8 +1064,6 @@ def run_suite(): print("compiler=%s" % configuration.compiler) # Iterating over all possible architecture and compiler combinations. - os.environ["ARCH"] = configuration.arch - os.environ["CC"] = configuration.compiler configString = "arch=%s compiler=%s" % (configuration.arch, configuration.compiler) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/dotest_args.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/dotest_args.py index 7ec5fa2a78e..05dd523e744 100644 --- a/gnu/llvm/lldb/packages/Python/lldbsuite/test/dotest_args.py +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/dotest_args.py @@ -41,7 +41,7 @@ def create_parser(): group.add_argument('-C', '--compiler', metavar='compiler', dest='compiler', help=textwrap.dedent( '''Specify the compiler(s) used to build the inferior executables. The compiler path can be an executable basename or a full path to a compiler executable. This option can be specified multiple times.''')) if sys.platform == 'darwin': - group.add_argument('--apple-sdk', metavar='apple_sdk', dest='apple_sdk', default="macosx", help=textwrap.dedent( + group.add_argument('--apple-sdk', metavar='apple_sdk', dest='apple_sdk', default="", help=textwrap.dedent( '''Specify the name of the Apple SDK (macosx, macosx.internal, iphoneos, iphoneos.internal, or path to SDK) and use the appropriate tools from that SDK's toolchain.''')) # FIXME? This won't work for different extra flags according to each arch. group.add_argument( @@ -51,7 +51,7 @@ def create_parser(): suggestions: do not lump the "-A arch1 -A arch2" together such that the -E option applies to only one of the architectures''')) group.add_argument('--dsymutil', metavar='dsymutil', dest='dsymutil', help=textwrap.dedent('Specify which dsymutil to use.')) - + group.add_argument('--yaml2obj', metavar='yaml2obj', dest='yaml2obj', help=textwrap.dedent('Specify which yaml2obj binary to use.')) group.add_argument('--filecheck', metavar='filecheck', dest='filecheck', help=textwrap.dedent('Specify which FileCheck binary to use.')) # Test filtering options @@ -172,6 +172,18 @@ def create_parser(): dest='clang_module_cache_dir', metavar='The clang module cache directory used by Clang', help='The clang module cache directory used in the Make files by Clang while building tests. Defaults to /module-cache-clang.') + group.add_argument( + '--lldb-libs-dir', + dest='lldb_libs_dir', + metavar='path', + help='The path to LLDB library directory (containing liblldb)') + group.add_argument( + '--enable-plugin', + dest='enabled_plugins', + action='append', + type=str, + metavar='A plugin whose tests will be enabled', + help='A plugin whose tests will be enabled. The only currently supported plugin is intel-pt.') # Configuration options group = parser.add_argument_group('Remote platform options') @@ -191,6 +203,17 @@ def create_parser(): metavar='platform-working-dir', help='The directory to use on the remote platform.') + # Reproducer options + group = parser.add_argument_group('Reproducer options') + group.add_argument( + '--capture-path', + metavar='reproducer path', + help='The reproducer capture path') + group.add_argument( + '--replay-path', + metavar='reproducer path', + help='The reproducer replay path') + # Test-suite behaviour group = parser.add_argument_group('Runtime behaviour options') X('-d', 'Suspend the process after launch to wait indefinitely for a debugger to attach') @@ -221,28 +244,6 @@ def create_parser(): help='(Windows only) When LLDB crashes, display the Windows crash dialog.') group.set_defaults(disable_crash_dialog=True) - # Test results support. - group = parser.add_argument_group('Test results options') - group.add_argument( - '--results-file', - action='store', - help=('Specifies the file where test results will be written ' - 'according to the results-formatter class used')) - group.add_argument( - '--results-formatter', - action='store', - help=('Specifies the full package/module/class name used to translate ' - 'test events into some kind of meaningful report, written to ' - 'the designated output results file-like object')) - group.add_argument( - '--results-formatter-option', - '-O', - action='append', - dest='results_formatter_options', - help=('Specify an option to pass to the formatter. ' - 'Use --results-formatter-option="--option1=val1" ' - 'syntax. Note the "=" is critical, don\'t include whitespace.')) - # Re-run related arguments group = parser.add_argument_group('Test Re-run Options') group.add_argument( diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lldbinline.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lldbinline.py index 22668b673fd..0d1cb24a54d 100644 --- a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lldbinline.py +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lldbinline.py @@ -82,7 +82,9 @@ class CommandParser: class InlineTest(TestBase): - # Internal implementation + + def getBuildDirBasename(self): + return self.__class__.__name__ + "." + self.testMethodName def BuildMakefile(self): makefilePath = self.getBuildArtifact("Makefile") @@ -90,7 +92,6 @@ class InlineTest(TestBase): return categories = {} - for f in os.listdir(self.getSourceDir()): t = source_type(f) if t: @@ -99,33 +100,36 @@ class InlineTest(TestBase): else: categories[t] = [f] - makefile = open(makefilePath, 'w+') + with open(makefilePath, 'w+') as makefile: + for t in list(categories.keys()): + line = t + " := " + " ".join(categories[t]) + makefile.write(line + "\n") - for t in list(categories.keys()): - line = t + " := " + " ".join(categories[t]) - makefile.write(line + "\n") + if ('OBJCXX_SOURCES' in list(categories.keys())) or \ + ('OBJC_SOURCES' in list(categories.keys())): + makefile.write( + "LDFLAGS = $(CFLAGS) -lobjc -framework Foundation\n") - if ('OBJCXX_SOURCES' in list(categories.keys())) or ( - 'OBJC_SOURCES' in list(categories.keys())): - makefile.write( - "LDFLAGS = $(CFLAGS) -lobjc -framework Foundation\n") + if ('CXX_SOURCES' in list(categories.keys())): + makefile.write("CXXFLAGS += -std=c++11\n") - if ('CXX_SOURCES' in list(categories.keys())): - makefile.write("CXXFLAGS += -std=c++11\n") - - makefile.write("include Makefile.rules\n") - makefile.write("\ncleanup:\n\trm -f Makefile *.d\n\n") - makefile.flush() - makefile.close() + makefile.write("include Makefile.rules\n") def _test(self): self.BuildMakefile() - self.build() + self.build(dictionary=self._build_dict) self.do_test() def execute_user_command(self, __command): exec(__command, globals(), locals()) + def _get_breakpoint_ids(self, thread): + ids = set() + for i in range(0, thread.GetStopReasonDataCount(), 2): + ids.add(thread.GetStopReasonDataAtIndex(i)) + self.assertGreater(len(ids), 0) + return sorted(ids) + def do_test(self): exe = self.getBuildArtifact("a.out") source_files = [f for f in os.listdir(self.getSourceDir()) @@ -137,14 +141,16 @@ class InlineTest(TestBase): parser.set_breakpoints(target) process = target.LaunchSimple(None, None, self.get_process_working_directory()) + self.assertIsNotNone(process, PROCESS_IS_VALID) + hit_breakpoints = 0 while lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint): hit_breakpoints += 1 thread = lldbutil.get_stopped_thread( process, lldb.eStopReasonBreakpoint) - breakpoint_id = thread.GetStopReasonDataAtIndex(0) - parser.handle_breakpoint(self, breakpoint_id) + for bp_id in self._get_breakpoint_ids(thread): + parser.handle_breakpoint(self, bp_id) process.Continue() self.assertTrue(hit_breakpoints > 0, @@ -154,8 +160,6 @@ class InlineTest(TestBase): lldb.eStateExited], PROCESS_EXITED) - # Utilities for testcases - def check_expression(self, expression, expected_result, use_summary=True): value = self.frame().EvaluateExpression(expression) self.assertTrue(value.IsValid(), expression + "returned a valid value") @@ -181,24 +185,26 @@ def ApplyDecoratorsToFunction(func, decorators): return tmp -def MakeInlineTest(__file, __globals, decorators=None): +def MakeInlineTest(__file, __globals, decorators=None, name=None, + build_dict=None): # Adjust the filename if it ends in .pyc. We want filenames to # reflect the source python file, not the compiled variant. if __file is not None and __file.endswith(".pyc"): # Strip the trailing "c" __file = __file[0:-1] - # Derive the test name from the current file name - file_basename = os.path.basename(__file) - - test_name, _ = os.path.splitext(file_basename) + if name is None: + # Derive the test name from the current file name + file_basename = os.path.basename(__file) + name, _ = os.path.splitext(file_basename) test_func = ApplyDecoratorsToFunction(InlineTest._test, decorators) # Build the test case - test_class = type(test_name, (InlineTest,), dict(test=test_func, name=test_name)) + test_class = type(name, (InlineTest,), dict(test=test_func, + name=name, _build_dict=build_dict)) # Add the test case to the globals, and hide InlineTest - __globals.update({test_name: test_class}) + __globals.update({name: test_class}) # Keep track of the original test filename so we report it # correctly in test results. diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py index 02946f0398b..44659cac4c7 100644 --- a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py @@ -57,7 +57,7 @@ def _run_adb_command(cmd, device_id): def target_is_android(): if not hasattr(target_is_android, 'result'): - triple = lldb.DBG.GetSelectedPlatform().GetTriple() + triple = lldb.selected_platform.GetTriple() match = re.match(".*-.*-.*-android", triple) target_is_android.result = match is not None return target_is_android.result @@ -129,7 +129,7 @@ def getDarwinOSTriples(): def getPlatform(): """Returns the target platform which the tests are running on.""" - triple = lldb.DBG.GetSelectedPlatform().GetTriple() + triple = lldb.selected_platform.GetTriple() if triple is None: # It might be an unconnected remote platform. return '' @@ -166,19 +166,20 @@ def findMainThreadCheckerDylib(): class _PlatformContext(object): """Value object class which contains platform-specific options.""" - def __init__(self, shlib_environment_var, shlib_prefix, shlib_extension): + def __init__(self, shlib_environment_var, shlib_path_separator, shlib_prefix, shlib_extension): self.shlib_environment_var = shlib_environment_var + self.shlib_path_separator = shlib_path_separator self.shlib_prefix = shlib_prefix self.shlib_extension = shlib_extension def createPlatformContext(): if platformIsDarwin(): - return _PlatformContext('DYLD_LIBRARY_PATH', 'lib', 'dylib') + return _PlatformContext('DYLD_LIBRARY_PATH', ':', 'lib', 'dylib') elif getPlatform() in ("freebsd", "linux", "netbsd"): - return _PlatformContext('LD_LIBRARY_PATH', 'lib', 'so') + return _PlatformContext('LD_LIBRARY_PATH', ':', 'lib', 'so') else: - return None + return _PlatformContext('PATH', ';', '', 'dll') def hasChattyStderr(test_case): diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lldbtest.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lldbtest.py index 2b83d26d234..9c32bdb42e2 100644 --- a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lldbtest.py +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -1,7 +1,7 @@ """ LLDB module which provides the abstract base class of lldb test case. -The concrete subclass can override lldbtest.TesBase in order to inherit the +The concrete subclass can override lldbtest.TestBase in order to inherit the common behavior for unitest.TestCase.setUp/tearDown implemented in this file. The subclass should override the attribute mydir in order for the python runtime @@ -498,13 +498,17 @@ class Base(unittest2.TestCase): mydir = TestBase.compute_mydir(__file__) ''' # /abs/path/to/packages/group/subdir/mytest.py -> group/subdir - rel_prefix = test_file[len(os.environ["LLDB_TEST"]) + 1:] + rel_prefix = test_file[len(os.environ["LLDB_TEST_SRC"]) + 1:] return os.path.dirname(rel_prefix) def TraceOn(self): """Returns True if we are in trace mode (tracing detailed test execution).""" return traceAlways + def trace(self, *args,**kwargs): + with recording(self, self.TraceOn()) as sbuf: + print(*args, file=sbuf, **kwargs) + @classmethod def setUpClass(cls): """ @@ -518,14 +522,15 @@ class Base(unittest2.TestCase): # Save old working directory. cls.oldcwd = os.getcwd() - # Change current working directory if ${LLDB_TEST} is defined. - # See also dotest.py which sets up ${LLDB_TEST}. - if ("LLDB_TEST" in os.environ): - full_dir = os.path.join(os.environ["LLDB_TEST"], + # Change current working directory if ${LLDB_TEST_SRC} is defined. + # See also dotest.py which sets up ${LLDB_TEST_SRC}. + if ("LLDB_TEST_SRC" in os.environ): + full_dir = os.path.join(os.environ["LLDB_TEST_SRC"], cls.mydir) if traceAlways: print("Change dir to:", full_dir, file=sys.stderr) os.chdir(full_dir) + lldb.SBReproducer.SetWorkingDirectory(full_dir) # Set platform context. cls.platformContext = lldbplatformutil.createPlatformContext() @@ -571,6 +576,7 @@ class Base(unittest2.TestCase): # confirm that the file is writeable host_log_path = "{}-host.log".format(log_basename) open(host_log_path, 'w').close() + self.log_files.append(host_log_path) log_enable = "log enable -Tpn -f {} ".format(host_log_path) for channel_with_categories in lldbtest_config.channels: @@ -597,6 +603,7 @@ class Base(unittest2.TestCase): if lldb.remote_platform is None: server_log_path = "{}-server.log".format(log_basename) open(server_log_path, 'w').close() + self.log_files.append(server_log_path) os.environ["LLDB_DEBUGSERVER_LOG_FILE"] = server_log_path # Communicate channels to lldb-server @@ -618,12 +625,13 @@ class Base(unittest2.TestCase): # Retrieve the server log (if any) from the remote system. It is assumed the server log # is writing to the "server.log" file in the current test directory. This can be # achieved by setting LLDB_DEBUGSERVER_LOG_FILE="server.log" when starting remote - # platform. If the remote logging is not enabled, then just let the Get() command silently - # fail. + # platform. if lldb.remote_platform: - lldb.remote_platform.Get( - lldb.SBFileSpec("server.log"), lldb.SBFileSpec( - self.getLogBasenameForCurrentTest() + "-server.log")) + server_log_path = self.getLogBasenameForCurrentTest() + "-server.log" + if lldb.remote_platform.Get( + lldb.SBFileSpec("server.log"), + lldb.SBFileSpec(server_log_path)).Success(): + self.log_files.append(server_log_path) def setPlatformWorkingDir(self): if not lldb.remote_platform or not configuration.lldb_platform_working_dir: @@ -642,7 +650,7 @@ class Base(unittest2.TestCase): lldb.remote_platform.SetWorkingDirectory(remote_test_dir) # This function removes all files from the current working directory while leaving - # the directories in place. The cleaup is required to reduce the disk space required + # the directories in place. The cleanup is required to reduce the disk space required # by the test suite while leaving the directories untouched is neccessary because # sub-directories might belong to an other test def clean_working_directory(): @@ -656,21 +664,27 @@ class Base(unittest2.TestCase): def getSourceDir(self): """Return the full path to the current test.""" - return os.path.join(os.environ["LLDB_TEST"], self.mydir) + return os.path.join(os.environ["LLDB_TEST_SRC"], self.mydir) def getBuildDirBasename(self): return self.__class__.__module__ + "." + self.testMethodName def getBuildDir(self): """Return the full path to the current test.""" - return os.path.join(os.environ["LLDB_BUILD"], self.mydir, + return os.path.join(configuration.test_build_dir, self.mydir, self.getBuildDirBasename()) + def getReproducerDir(self): + """Return the full path to the reproducer if enabled.""" + if configuration.capture_path: + return configuration.capture_path + if configuration.replay_path: + return configuration.replay_path + return None def makeBuildDir(self): """Create the test-specific working directory, deleting any previous contents.""" - # See also dotest.py which sets up ${LLDB_BUILD}. bdir = self.getBuildDir() if os.path.isdir(bdir): shutil.rmtree(bdir) @@ -684,14 +698,31 @@ class Base(unittest2.TestCase): """Return absolute path to a file in the test's source directory.""" return os.path.join(self.getSourceDir(), name) + def getReproducerArtifact(self, name): + lldbutil.mkdir_p(self.getReproducerDir()) + return os.path.join(self.getReproducerDir(), name) + + def getReproducerRemappedPath(self, path): + assert configuration.replay_path + assert os.path.isabs(path) + path = os.path.relpath(path, '/') + return os.path.join(configuration.replay_path, 'root', path) + @classmethod def setUpCommands(cls): commands = [ + # First of all, clear all settings to have clean state of global properties. + "settings clear -all", + # Disable Spotlight lookup. The testsuite creates # different binaries with the same UUID, because they only # differ in the debug info, which is not being hashed. "settings set symbols.enable-external-lookup false", + # Disable fix-its by default so that incorrect expressions in tests don't + # pass just because Clang thinks it has a fix-it. + "settings set target.auto-apply-fixits false", + # Testsuite runs in parallel and the host can have also other load. "settings set plugin.process.gdb-remote.packet-timeout 60", @@ -699,6 +730,11 @@ class Base(unittest2.TestCase): configuration.lldb_module_cache_dir), "settings set use-color false", ] + + # Set any user-overridden settings. + for setting, value in configuration.settings: + commands.append('setting set %s %s'%(setting, value)) + # Make sure that a sanitizer LLDB's environment doesn't get passed on. if cls.platformContext and cls.platformContext.shlib_environment_var in os.environ: commands.append('settings set target.env-vars {}='.format( @@ -767,11 +803,12 @@ class Base(unittest2.TestCase): # List of forked process PIDs self.forkedProcessPids = [] - # Create a string buffer to record the session info, to be dumped into a - # test case specific file if test failure is encountered. - self.log_basename = self.getLogBasenameForCurrentTest() + # List of log files produced by the current test. + self.log_files = [] + + session_file = self.getLogBasenameForCurrentTest()+".log" + self.log_files.append(session_file) - session_file = "{}.log".format(self.log_basename) # Python 3 doesn't support unbuffered I/O in text mode. Open buffered. self.session = encoded_file.open(session_file, "utf-8", mode="w") @@ -799,11 +836,11 @@ class Base(unittest2.TestCase): # set environment variable names for finding shared libraries self.dylibPath = self.platformContext.shlib_environment_var - # Create the debugger instance if necessary. - try: - self.dbg = lldb.DBG - except AttributeError: - self.dbg = lldb.SBDebugger.Create() + # Create the debugger instance. + self.dbg = lldb.SBDebugger.Create() + # Copy selected platform from a global instance if it exists. + if lldb.selected_platform is not None: + self.dbg.SetSelectedPlatform(lldb.selected_platform) if not self.dbg: raise Exception('Invalid debugger instance') @@ -857,17 +894,15 @@ class Base(unittest2.TestCase): del self.subprocesses[:] # Ensure any forked processes are cleaned up for pid in self.forkedProcessPids: - if os.path.exists("/proc/" + str(pid)): + try: os.kill(pid, signal.SIGTERM) + except OSError: + pass + del self.forkedProcessPids[:] def spawnSubprocess(self, executable, args=[], install_remote=True): """ Creates a subprocess.Popen object with the specified executable and arguments, saves it in self.subprocesses, and returns the object. - NOTE: if using this function, ensure you also call: - - self.addTearDownHook(self.cleanupSubprocesses) - - otherwise the test suite will leak processes. """ proc = _RemoteProcess( install_remote) if lldb.remote_platform else _LocalProcess(self.TraceOn()) @@ -877,11 +912,6 @@ class Base(unittest2.TestCase): def forkSubprocess(self, executable, args=[]): """ Fork a subprocess with its own group ID. - NOTE: if using this function, ensure you also call: - - self.addTearDownHook(self.cleanupSubprocesses) - - otherwise the test suite will leak processes. """ child_pid = os.fork() if child_pid == 0: @@ -930,12 +960,12 @@ class Base(unittest2.TestCase): # ======================================================================= def setTearDownCleanup(self, dictionary=None): - """Register a cleanup action at tearDown() time with a dictinary""" + """Register a cleanup action at tearDown() time with a dictionary""" self.dict = dictionary self.doTearDownCleanup = True def addTearDownCleanup(self, dictionary): - """Add a cleanup action at tearDown() time with a dictinary""" + """Add a cleanup action at tearDown() time with a dictionary""" self.dicts.append(dictionary) self.doTearDownCleanups = True @@ -985,9 +1015,6 @@ class Base(unittest2.TestCase): def tearDown(self): """Fixture for unittest test case teardown.""" - #import traceback - # traceback.print_stack() - self.deletePexpectChild() # Check and run any hook functions. @@ -1014,6 +1041,14 @@ class Base(unittest2.TestCase): for dict in reversed(self.dicts): self.cleanup(dictionary=dict) + # Remove subprocesses created by the test. + self.cleanupSubprocesses() + + # This must be the last statement, otherwise teardown hooks or other + # lines might depend on this still being active. + lldb.SBDebugger.Destroy(self.dbg) + del self.dbg + # ========================================================= # Various callbacks to allow introspection of test progress # ========================================================= @@ -1089,7 +1124,7 @@ class Base(unittest2.TestCase): /--.. """ - dname = os.path.join(os.environ["LLDB_TEST"], + dname = os.path.join(os.environ["LLDB_TEST_SRC"], os.environ["LLDB_SESSION_DIRNAME"]) if not os.path.isdir(dname): os.mkdir(dname) @@ -1135,7 +1170,7 @@ class Base(unittest2.TestCase): # We are here because self.tearDown() detected that this test instance # either errored or failed. The lldb.test_result singleton contains - # two lists (erros and failures) which get populated by the unittest + # two lists (errors and failures) which get populated by the unittest # framework. Look over there for stack trace information. # # The lists contain 2-tuples of TestCase instances and strings holding @@ -1178,14 +1213,13 @@ class Base(unittest2.TestCase): del self.session # process the log files - log_files_for_this_test = glob.glob(self.log_basename + "*") - if prefix != 'Success' or lldbtest_config.log_success: # keep all log files, rename them to include prefix + src_log_basename = self.getLogBasenameForCurrentTest(None) dst_log_basename = self.getLogBasenameForCurrentTest(prefix) - for src in log_files_for_this_test: + for src in self.log_files: if os.path.isfile(src): - dst = src.replace(self.log_basename, dst_log_basename) + dst = src.replace(src_log_basename, dst_log_basename) if os.name == "nt" and os.path.isfile(dst): # On Windows, renaming a -> b will throw an exception if # b exists. On non-Windows platforms it silently @@ -1199,8 +1233,9 @@ class Base(unittest2.TestCase): os.rename(src, dst) else: # success! (and we don't want log files) delete log files - for log_file in log_files_for_this_test: - remove_file(log_file) + for log_file in self.log_files: + if os.path.isfile(log_file): + remove_file(log_file) # ==================================================== # Config. methods supported through a plugin interface @@ -1227,6 +1262,8 @@ class Base(unittest2.TestCase): arch = module.getArchitecture() if arch == 'amd64': arch = 'x86_64' + if arch in ['armv7l', 'armv8l'] : + arch = 'arm' return arch def getLldbArchitecture(self): @@ -1399,7 +1436,7 @@ class Base(unittest2.TestCase): stdflag = self.getstdFlag() stdlibflag = self.getstdlibFlag() - lib_dir = os.environ["LLDB_LIB_DIR"] + lib_dir = configuration.lldb_libs_dir if self.hasDarwinFramework(): d = {'CXX_SOURCES': sources, 'EXE': exe_name, @@ -1426,7 +1463,7 @@ class Base(unittest2.TestCase): os.path.join( os.environ["LLDB_SRC"], "include")), - 'LD_EXTRAS': "-L%s/../lib -llldb -Wl,-rpath,%s/../lib" % (lib_dir, lib_dir)} + 'LD_EXTRAS': "-L%s -llldb -Wl,-rpath,%s" % (lib_dir, lib_dir)} if self.TraceOn(): print( "Building LLDB Driver (%s) from sources %s" % @@ -1439,7 +1476,7 @@ class Base(unittest2.TestCase): stdflag = self.getstdFlag() - lib_dir = os.environ["LLDB_LIB_DIR"] + lib_dir = configuration.lldb_libs_dir if self.hasDarwinFramework(): d = {'DYLIB_CXX_SOURCES': sources, 'DYLIB_NAME': lib_name, @@ -1464,7 +1501,7 @@ class Base(unittest2.TestCase): os.path.join( os.environ["LLDB_SRC"], "include")), - 'LD_EXTRAS': "-shared -L%s/../lib -llldb -Wl,-rpath,%s/../lib" % (lib_dir, lib_dir)} + 'LD_EXTRAS': "-shared -L%s -llldb -Wl,-rpath,%s" % (lib_dir, lib_dir)} if self.TraceOn(): print( "Building LLDB Library (%s) from sources %s" % @@ -1591,20 +1628,6 @@ class Base(unittest2.TestCase): return os.environ["CC"] - def findYaml2obj(self): - """ - Get the path to the yaml2obj executable, which can be used to create - test object files from easy to write yaml instructions. - - Throws an Exception if the executable cannot be found. - """ - # Tries to find yaml2obj at the same folder as clang - clang_dir = os.path.dirname(self.findBuiltClang()) - path = distutils.spawn.find_executable("yaml2obj", clang_dir) - if path is not None: - return path - raise Exception("yaml2obj executable not found") - def yaml2obj(self, yaml_path, obj_path): """ @@ -1612,8 +1635,10 @@ class Base(unittest2.TestCase): Throws subprocess.CalledProcessError if the object could not be created. """ - yaml2obj = self.findYaml2obj() - command = [yaml2obj, "-o=%s" % obj_path, yaml_path] + yaml2obj_bin = configuration.get_yaml2obj_path() + if not yaml2obj_bin: + self.assertTrue(False, "No valid FileCheck executable specified") + command = [yaml2obj_bin, "-o=%s" % obj_path, yaml_path] system([command]) def getBuildFlags( @@ -1843,9 +1868,6 @@ class TestBase(Base): self.addTearDownHook(lambda: os.remove(src)) def setUp(self): - #import traceback - # traceback.print_stack() - # Works with the test driver to conditionally skip tests via # decorators. Base.setUp(self) @@ -1964,9 +1986,6 @@ class TestBase(Base): return self.getBuildDir() def tearDown(self): - #import traceback - # traceback.print_stack() - # Ensure all the references to SB objects have gone away so that we can # be sure that all test-specific resources have been freed before we # attempt to delete the targets. @@ -1983,17 +2002,21 @@ class TestBase(Base): process = target.GetProcess() if process: rc = self.invoke(process, "Kill") - self.assertTrue(rc.Success(), PROCESS_KILLED) + assert rc.Success() for target in targets: self.dbg.DeleteTarget(target) + # Modules are not orphaned during reproducer replay because they're + # leaked on purpose. + if not configuration.is_reproducer(): + # Assert that all targets are deleted. + assert self.dbg.GetNumTargets() == 0 + # Assert that the global module cache is empty. + assert lldb.SBModule.GetNumberAllocatedModules() == 0 + # Do this last, to make sure it's in reverse order from how we setup. Base.tearDown(self) - # This must be the last statement, otherwise teardown hooks or other - # lines might depend on this still being active. - del self.dbg - def switch_to_thread_with_stop_reason(self, stop_reason): """ Run the 'thread list' command, and select the thread with stop reason as @@ -2117,13 +2140,27 @@ class TestBase(Base): return match_object - def check_completion_with_desc(self, str_input, match_desc_pairs): + def check_completion_with_desc(self, str_input, match_desc_pairs, enforce_order=False): + """ + Checks that when the given input is completed at the given list of + completions and descriptions is returned. + :param str_input: The input that should be completed. The completion happens at the end of the string. + :param match_desc_pairs: A list of pairs that indicate what completions have to be in the list of + completions returned by LLDB. The first element of the pair is the completion + string that LLDB should generate and the second element the description. + :param enforce_order: True iff the order in which the completions are returned by LLDB + should match the order of the match_desc_pairs pairs. + """ interp = self.dbg.GetCommandInterpreter() match_strings = lldb.SBStringList() description_strings = lldb.SBStringList() num_matches = interp.HandleCompletionWithDescriptions(str_input, len(str_input), 0, -1, match_strings, description_strings) self.assertEqual(len(description_strings), len(match_strings)) + # The index of the last matched description in description_strings or + # -1 if no description has been matched yet. + last_found_index = -1 + out_of_order_errors = "" missing_pairs = [] for pair in match_desc_pairs: found_pair = False @@ -2132,20 +2169,35 @@ class TestBase(Base): description_candidate = description_strings.GetStringAtIndex(i) if match_candidate == pair[0] and description_candidate == pair[1]: found_pair = True + if enforce_order and last_found_index > i: + new_err = ("Found completion " + pair[0] + " at index " + + str(i) + " in returned completion list but " + + "should have been after completion " + + match_strings.GetStringAtIndex(last_found_index) + + " (index:" + str(last_found_index) + ")\n") + out_of_order_errors += new_err + last_found_index = i break if not found_pair: missing_pairs.append(pair) + error_msg = "" + got_failure = False if len(missing_pairs): - error_msg = "Missing pairs:\n" + got_failure = True + error_msg += "Missing pairs:\n" for pair in missing_pairs: error_msg += " [" + pair[0] + ":" + pair[1] + "]\n" + if len(out_of_order_errors): + got_failure = True + error_msg += out_of_order_errors + if got_failure: error_msg += "Got the following " + str(num_matches) + " completions back:\n" for i in range(num_matches + 1): match_candidate = match_strings.GetStringAtIndex(i) description_candidate = description_strings.GetStringAtIndex(i) - error_msg += "[" + match_candidate + ":" + description_candidate + "]\n" - self.assertEqual(0, len(missing_pairs), error_msg) + error_msg += "[" + match_candidate + ":" + description_candidate + "] index " + str(i) + "\n" + self.assertFalse(got_failure, error_msg) def complete_exactly(self, str_input, patterns): self.complete_from_to(str_input, patterns, True) @@ -2261,6 +2313,7 @@ FileCheck output: substrs=None, trace=False, error=False, + ordered=True, matching=True, exe=True, inHistory=False): @@ -2273,6 +2326,10 @@ FileCheck output: 'startstr', matches the substrings contained in 'substrs', and regexp matches the patterns contained in 'patterns'. + When matching is true and ordered is true, which are both the default, + the strings in the substrs array have to appear in the command output + in the order in which they appear in the array. + If the keyword argument error is set to True, it signifies that the API client is expecting the command to fail. In this case, the error stream from running the command is retrieved and compared against the golden @@ -2341,8 +2398,11 @@ FileCheck output: # Look for sub strings, if specified. keepgoing = matched if matching else not matched if substrs and keepgoing: + start = 0 for substr in substrs: - matched = output.find(substr) != -1 + index = output[start:].find(substr) + start = start + index if ordered and matching else 0 + matched = index != -1 with recording(self, trace) as sbuf: print("%s sub string: %s" % (heading, substr), file=sbuf) print("Matched" if matched else "Not matched", file=sbuf) @@ -2364,7 +2424,8 @@ FileCheck output: break self.assertTrue(matched if matching else not matched, - msg if msg else EXP_MSG(str, output, exe)) + msg + "\nCommand output:\n" + EXP_MSG(str, output, exe) + if msg else EXP_MSG(str, output, exe)) def expect_expr( self, @@ -2372,7 +2433,6 @@ FileCheck output: result_summary=None, result_value=None, result_type=None, - error_msg=None, ): """ Evaluates the given expression and verifies the result. @@ -2380,24 +2440,28 @@ FileCheck output: :param result_summary: The summary that the expression should have. None if the summary should not be checked. :param result_value: The value that the expression should have. None if the value should not be checked. :param result_type: The type that the expression result should have. None if the type should not be checked. - :param error_msg: The error message the expression should return. None if the error output should not be checked. """ self.assertTrue(expr.strip() == expr, "Expression contains trailing/leading whitespace: '" + expr + "'") frame = self.frame() - eval_result = frame.EvaluateExpression(expr) + options = lldb.SBExpressionOptions() - if error_msg: - self.assertFalse(eval_result.IsValid()) - self.assertEqual(error_msg, eval_result.GetError().GetCString()) - return + # Disable fix-its that tests don't pass by accident. + options.SetAutoApplyFixIts(False) + + # Set the usual default options for normal expressions. + options.SetIgnoreBreakpoints(True) - if not eval_result.GetError().Success(): - self.assertTrue(eval_result.GetError().Success(), - "Unexpected failure with msg: " + eval_result.GetError().GetCString()) + if self.frame().IsValid(): + options.SetLanguage(frame.GuessLanguage()) + eval_result = self.frame().EvaluateExpression(expr, options) + else: + eval_result = self.target().EvaluateExpression(expr, options) + + self.assertSuccess(eval_result.GetError()) if result_type: - self.assertEqual(result_type, eval_result.GetTypeName()) + self.assertEqual(result_type, eval_result.GetDisplayTypeName()) if result_value: self.assertEqual(result_value, eval_result.GetValue()) @@ -2446,6 +2510,13 @@ FileCheck output: err = platform.Run(shell_command) return (err, shell_command.GetStatus(), shell_command.GetOutput()) + """Assert that an lldb.SBError is in the "success" state.""" + def assertSuccess(self, obj, msg=None): + if not obj.Success(): + error = obj.GetCString() + self.fail(self._formatMessage(msg, + "'{}' is not success".format(error))) + # ================================================= # Misc. helper methods for debugging test execution # ================================================= diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lldbutil.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lldbutil.py index 006362a4479..25fcd5f29ee 100644 --- a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lldbutil.py +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lldbutil.py @@ -775,7 +775,7 @@ def run_to_breakpoint_do_run(test, target, bkpt, launch_info = None, launch_info = target.GetLaunchInfo() launch_info.SetWorkingDirectory(test.get_process_working_directory()) - if extra_images and lldb.remote_platform: + if extra_images: environ = test.registerSharedLibrariesWithTarget(target, extra_images) launch_info.SetEnvironmentEntries(environ, True) @@ -788,6 +788,8 @@ def run_to_breakpoint_do_run(test, target, bkpt, launch_info = None, test.assertFalse(error.Fail(), "Process launch failed: %s" % (error.GetCString())) + test.assertEqual(process.GetState(), lldb.eStateStopped) + # Frame #0 should be at our breakpoint. threads = get_threads_stopped_at_breakpoint( process, bkpt) @@ -797,7 +799,7 @@ def run_to_breakpoint_do_run(test, target, bkpt, launch_info = None, test.assertEqual(num_threads, 1, "Expected 1 thread to stop at breakpoint, %d did."%(num_threads)) else: test.assertGreater(num_threads, 0, "No threads stopped at breakpoint") - + thread = threads[0] return (target, process, thread, bkpt) @@ -1062,7 +1064,7 @@ def print_stacktraces(process, string_buffer=False): return output.getvalue() -def expect_state_changes(test, listener, process, states, timeout=5): +def expect_state_changes(test, listener, process, states, timeout=30): """Listens for state changed events on the listener and makes sure they match what we expect. Stop-and-restart events (where GetRestartedFromEvent() returns true) are ignored.""" diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/make/Makefile.rules b/gnu/llvm/lldb/packages/Python/lldbsuite/test/make/Makefile.rules index f25d062ca43..5316c51899c 100644 --- a/gnu/llvm/lldb/packages/Python/lldbsuite/test/make/Makefile.rules +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/make/Makefile.rules @@ -41,6 +41,13 @@ MAKEFILE_RULES := $(lastword $(MAKEFILE_LIST)) THIS_FILE_DIR := $(shell dirname $(MAKEFILE_RULES)) LLDB_BASE_DIR := $(THIS_FILE_DIR)/../../../../../ +# The test harness invokes the test Makefiles with an explicit 'all' +# target, but its handy to be able to recursively call this Makefile +# without specifying a goal. You almost certainly want to build 'all', +# and not only the first target defined in this file (which might vary +# according to variable values). +.DEFAULT_GOAL := all + #---------------------------------------------------------------------- # If OS is not defined, use 'uname -s' to determine the OS name. # @@ -99,52 +106,54 @@ ifneq "$(TRIPLE)" "" TRIPLE_ENV =$(word 4, $(triple_space)) ifeq "$(TRIPLE_VENDOR)" "apple" ifeq "$(TRIPLE_OS)" "ios" - CODESIGN := codesign - ifeq "$(SDKROOT)" "" - # Set SDKROOT if it wasn't set - ifneq (,$(findstring arm,$(ARCH))) - SDKROOT = $(shell xcrun --sdk iphoneos --show-sdk-path) - ifeq "$(TRIPLE_VERSION)" "" - TRIPLE_VERSION =$(shell echo $(notdir $(SDKROOT)) | sed -e 's/.*\([0-9]\.[0-9]\).*/\1/') - endif - ARCH_CFLAGS :=-mios-version-min=$(TRIPLE_VERSION) -isysroot "$(SDKROOT)" - else - ifeq "$(TRIPLE_ENV)" "macabi" - SDKROOT = $(shell xcrun --sdk macosx --show-sdk-path) - else - SDKROOT = $(shell xcrun --sdk iphonesimulator --show-sdk-path) - endif - ifeq "$(TRIPLE_VERSION)" "" - TRIPLE_VERSION =$(shell echo $(notdir $(SDKROOT)) | sed -e 's/.*\([0-9]\.[0-9]\).*/\1/') - endif - ifeq "$(TRIPLE_ENV)" "macabi" - ARCH_CFLAGS :=-mios-version-min=$(TRIPLE_VERSION) -isysroot "$(SDKROOT)" - else - ARCH_CFLAGS :=-mios-simulator-version-min=$(TRIPLE_VERSION) -isysroot "$(SDKROOT)" - endif - endif + ifeq "$(TRIPLE_ENV)" "simulator" + SDK_NAME := iphonesimulator + else + ifeq "$(TRIPLE_ENV)" "macabi" + SDK_NAME := macosx + else + SDK_NAME := iphoneos + endif + endif + endif + ifeq "$(TRIPLE_OS)" "tvos" + ifeq "$(TRIPLE_ENV)" "simulator" + SDK_NAME := appletvsimulator + else + SDK_NAME := appletvos endif endif ifeq "$(TRIPLE_OS)" "watchos" - CODESIGN := codesign - ifeq "$(SDKROOT)" "" - # Set SDKROOT if it wasn't set - ifneq (,$(findstring arm,$(ARCH))) - SDKROOT = $(shell xcrun --sdk watchos --show-sdk-path) - ifeq "$(TRIPLE_VERSION)" "" - TRIPLE_VERSION =$(shell echo $(notdir $(SDKROOT)) | sed -e 's/.*\([0-9]\.[0-9]\).*/\1/') - endif - ARCH_CFLAGS :=-mwatchos-version-min=$(TRIPLE_VERSION) -isysroot "$(SDKROOT)" - else - SDKROOT = $(shell xcrun --sdk watchsimulator --show-sdk-path) - ifeq "$(TRIPLE_VERSION)" "" - TRIPLE_VERSION =$(shell echo $(notdir $(SDKROOT)) | sed -e 's/.*\([0-9]\.[0-9]\).*/\1/') - endif - ARCH_CFLAGS :=-mwatchos-simulator-version-min=$(TRIPLE_VERSION) -isysroot "$(SDKROOT)" - endif + ifeq "$(TRIPLE_ENV)" "simulator" + SDK_NAME := watchsimulator + else + SDK_NAME := watchos endif endif + ifneq "$(TRIPLE_OS)" "macosx" + ifeq "$(TRIPLE_ENV)" "" + CODESIGN := codesign + endif + endif + + ifeq "$(SDKROOT)" "" + SDKROOT := $(shell xcrun --sdk $(SDK_NAME) --show-sdk-path) + endif + ifeq "$(TRIPLE_VERSION)" "" + ifeq "$(SDK_NAME)" "" + $(error "SDK_NAME is empty") + endif + TRIPLE_VERSION := $(shell xcrun --sdk $(SDK_NAME) --show-sdk-version) + endif + ifeq "$(TRIPLE_ENV)" "simulator" + ARCH_CFLAGS := -m$(TRIPLE_OS)-simulator-version-min=$(TRIPLE_VERSION) + else + ifneq "$(TRIPLE_OS)" "macosx" + ARCH_CFLAGS := -m$(TRIPLE_OS)-version-min=$(TRIPLE_VERSION) + endif + endif endif + ARCH_CFLAGS += -target $(TRIPLE) endif ifeq "$(OS)" "Android" include $(THIS_FILE_DIR)/Android.rules @@ -288,7 +297,7 @@ ifndef NO_TEST_COMMON_H CFLAGS += -include $(THIS_FILE_DIR)/test_common.h endif -CFLAGS += $(NO_LIMIT_DEBUG_INFO_FLAGS) $(ARCH_CFLAGS) $(CFLAGS_EXTRAS) +CFLAGS += $(NO_LIMIT_DEBUG_INFO_FLAGS) $(ARCH_CFLAGS) # If the OS is Windows, we need to pass -gdwarf to clang, otherwise it will build # with codeview by default but all the tests rely on dwarf. @@ -298,7 +307,7 @@ endif # Use this one if you want to build one part of the result without debug information: ifeq "$(OS)" "Darwin" - CFLAGS_NO_DEBUG = -O0 $(ARCHFLAG) $(ARCH) $(FRAMEWORK_INCLUDES) $(ARCH_CFLAGS) $(CFLAGS_EXTRAS) + CFLAGS_NO_DEBUG = -O0 $(ARCHFLAG) $(ARCH) $(FRAMEWORK_INCLUDES) $(ARCH_CFLAGS) $(CFLAGS_EXTRAS) -isysroot "$(SDKROOT)" else CFLAGS_NO_DEBUG = -O0 $(ARCHFLAG)$(ARCH) $(FRAMEWORK_INCLUDES) $(ARCH_CFLAGS) $(CFLAGS_EXTRAS) endif @@ -328,6 +337,7 @@ ifeq "$(MAKE_GMODULES)" "YES" CXXFLAGS += $(MANDATORY_MODULE_BUILD_CFLAGS) endif +CFLAGS += $(CFLAGS_EXTRAS) CXXFLAGS += -std=c++11 $(CFLAGS) $(ARCH_CXXFLAGS) $(CXXFLAGS_EXTRAS) LD = $(CC) LDFLAGS ?= $(CFLAGS) @@ -467,7 +477,7 @@ endif # Additional system libraries #---------------------------------------------------------------------- ifeq (1,$(USE_LIBDL)) - ifneq ($(OS),NetBSD) + ifeq (,$(filter $(OS), NetBSD Windows_NT)) LDFLAGS += -ldl endif endif diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/make/dylib.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/make/dylib.h new file mode 100644 index 00000000000..50abcdbca9a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/make/dylib.h @@ -0,0 +1,55 @@ +#ifndef LLDB_TEST_DYLIB_H +#define LLDB_TEST_DYLIB_H + +#include + +#ifdef _WIN32 +#include + +#define dylib_get_symbol(handle, name) GetProcAddress((HMODULE)handle, name) +#define dylib_close(handle) (!FreeLibrary((HMODULE)handle)) +#else +#include + +#define dylib_get_symbol(handle, name) dlsym(handle, name) +#define dylib_close(handle) dlclose(handle) +#endif + + +inline void *dylib_open(const char *name) { + char dylib_prefix[] = +#ifdef _WIN32 + ""; +#else + "lib"; +#endif + char dylib_suffix[] = +#ifdef _WIN32 + ".dll"; +#elif defined(__APPLE__) + ".dylib"; +#else + ".so"; +#endif + char fullname[1024]; + snprintf(fullname, sizeof(fullname), "%s%s%s", dylib_prefix, name, dylib_suffix); +#ifdef _WIN32 + return LoadLibraryA(fullname); +#else + return dlopen(fullname, RTLD_NOW); +#endif +} + +inline const char *dylib_last_error() { +#ifndef _WIN32 + return dlerror(); +#else + DWORD err = GetLastError(); + char *msg; + FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char *)&msg, 0, NULL); + return msg; +#endif +} + +#endif diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/make/test_common.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/make/test_common.h index 529d0952ed3..aa8960e1c0a 100644 --- a/gnu/llvm/lldb/packages/Python/lldbsuite/test/make/test_common.h +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/make/test_common.h @@ -1,13 +1,18 @@ // This header is included in all the test programs (C and C++) and provides a // hook for dealing with platform-specifics. + #if defined(_WIN32) || defined(_WIN64) -#ifdef COMPILING_LLDB_TEST_DLL -#define LLDB_TEST_API __declspec(dllexport) +#define LLDB_DYLIB_EXPORT __declspec(dllexport) +#define LLDB_DYLIB_IMPORT __declspec(dllimport) #else -#define LLDB_TEST_API __declspec(dllimport) +#define LLDB_DYLIB_EXPORT +#define LLDB_DYLIB_IMPORT #endif + +#ifdef COMPILING_LLDB_TEST_DLL +#define LLDB_TEST_API LLDB_DYLIB_EXPORT #else -#define LLDB_TEST_API +#define LLDB_TEST_API LLDB_DYLIB_IMPORT #endif #if defined(_WIN32) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/plugins/builder_base.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/plugins/builder_base.py index aede03da14c..a8114b3e059 100644 --- a/gnu/llvm/lldb/packages/Python/lldbsuite/test/plugins/builder_base.py +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/plugins/builder_base.py @@ -21,17 +21,18 @@ import sys # Our imports import lldbsuite.test.lldbtest as lldbtest import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test import configuration from lldbsuite.test_event import build_exception def getArchitecture(): """Returns the architecture in effect the test suite is running with.""" - return os.environ["ARCH"] if "ARCH" in os.environ else "" + return configuration.arch if configuration.arch else "" def getCompiler(): """Returns the compiler in effect the test suite is running with.""" - compiler = os.environ.get("CC", "clang") + compiler = configuration.compiler if configuration.compiler else "clang" compiler = lldbutil.which(compiler) return os.path.realpath(compiler) @@ -61,12 +62,12 @@ def getMake(test_subdir, test_name): # Construct the base make invocation. lldb_test = os.environ["LLDB_TEST"] - lldb_build = os.environ["LLDB_BUILD"] - if not (lldb_test and lldb_build and test_subdir and test_name and - (not os.path.isabs(test_subdir))): + lldb_test_src = os.environ["LLDB_TEST_SRC"] + if not (lldb_test and lldb_test_src and configuration.test_build_dir and test_subdir and + test_name and (not os.path.isabs(test_subdir))): raise Exception("Could not derive test directories") - build_dir = os.path.join(lldb_build, test_subdir, test_name) - src_dir = os.path.join(lldb_test, test_subdir) + build_dir = os.path.join(configuration.test_build_dir, test_subdir, test_name) + src_dir = os.path.join(lldb_test_src, test_subdir) # This is a bit of a hack to make inline testcases work. makefile = os.path.join(src_dir, "Makefile") if not os.path.isfile(makefile): @@ -85,8 +86,8 @@ def getArchSpec(architecture): used for the make system. """ arch = architecture if architecture else None - if not arch and "ARCH" in os.environ: - arch = os.environ["ARCH"] + if not arch and configuration.arch: + arch = configuration.arch return ("ARCH=" + arch) if arch else "" @@ -97,8 +98,8 @@ def getCCSpec(compiler): used for the make system. """ cc = compiler if compiler else None - if not cc and "CC" in os.environ: - cc = os.environ["CC"] + if not cc and configuration.compiler: + cc = configuration.compiler if cc: return "CC=\"%s\"" % cc else: @@ -109,28 +110,28 @@ def getDsymutilSpec(): Helper function to return the key-value string to specify the dsymutil used for the make system. """ - if "DSYMUTIL" in os.environ: - return "DSYMUTIL={}".format(os.environ["DSYMUTIL"]) - return ""; + if configuration.dsymutil: + return "DSYMUTIL={}".format(configuration.dsymutil) + return "" def getSDKRootSpec(): """ Helper function to return the key-value string to specify the SDK root used for the make system. """ - if "SDKROOT" in os.environ: - return "SDKROOT={}".format(os.environ["SDKROOT"]) - return ""; + if configuration.sdkroot: + return "SDKROOT={}".format(configuration.sdkroot) + return "" def getModuleCacheSpec(): """ Helper function to return the key-value string to specify the clang module cache used for the make system. """ - if "CLANG_MODULE_CACHE_DIR" in os.environ: + if configuration.clang_module_cache_dir: return "CLANG_MODULE_CACHE_DIR={}".format( - os.environ["CLANG_MODULE_CACHE_DIR"]) - return ""; + configuration.clang_module_cache_dir) + return "" def getCmdLine(d): """ @@ -253,7 +254,7 @@ def buildGModules( getModuleCacheSpec(), getCmdLine(dictionary)]) - lldbtest.system(commands, sender=sender) + runBuildCommands(commands, sender=sender) # True signifies that we can handle building with gmodules. return True diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/plugins/builder_darwin.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/plugins/builder_darwin.py index e109f91945e..e9fc8257dea 100644 --- a/gnu/llvm/lldb/packages/Python/lldbsuite/test/plugins/builder_darwin.py +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/plugins/builder_darwin.py @@ -16,7 +16,11 @@ def buildDsym( ["MAKE_DSYM=YES", getArchSpec(architecture), getCCSpec(compiler), - "all", getCmdLine(dictionary)]) + getDsymutilSpec(), + getSDKRootSpec(), + getModuleCacheSpec(), + "all", + getCmdLine(dictionary)]) runBuildCommands(commands, sender=sender) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/test_categories.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/test_categories.py index 05ce2a15d84..177c50ee17c 100644 --- a/gnu/llvm/lldb/packages/Python/lldbsuite/test/test_categories.py +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/test_categories.py @@ -35,8 +35,10 @@ all_categories = { 'stresstest': 'Tests related to stressing lldb limits', 'flakey': 'Flakey test cases, i.e. tests that do not reliably pass at each execution', 'darwin-log': 'Darwin log tests', + 'std-module': 'Tests related to importing the std module', 'watchpoint': 'Watchpoint-related tests', 'lldb-vscode': 'Visual Studio Code debug adaptor tests', + 'lldb-server': 'Tests related to lldb-server', } diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/test_runner/README.txt b/gnu/llvm/lldb/packages/Python/lldbsuite/test/test_runner/README.txt index bb40870e796..b90bf4c7341 100644 --- a/gnu/llvm/lldb/packages/Python/lldbsuite/test/test_runner/README.txt +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/test_runner/README.txt @@ -1,5 +1,5 @@ This directory contains source and tests for the lldb test runner architecture. This directory is not for lldb python tests. It -is the test runner. The tests under this diretory are test-runner +is the test runner. The tests under this directory are test-runner tests (i.e. tests that verify the test runner itself runs properly). diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-server/.categories b/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-server/.categories new file mode 100644 index 00000000000..1966eb022b4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-server/.categories @@ -0,0 +1 @@ +lldb-server diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-server/registers-target-xml-reading/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-server/registers-target-xml-reading/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-server/registers-target-xml-reading/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py new file mode 100644 index 00000000000..530e2ce8002 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py @@ -0,0 +1,69 @@ + + +import gdbremote_testcase +import textwrap +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +import re +import xml.etree.ElementTree as ET + +class TestGdbRemoteTargetXmlPacket(gdbremote_testcase.GdbRemoteTestCaseBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureNetBSD + @llgs_test + def test_g_target_xml_returns_correct_data(self): + self.init_llgs_test() + self.build() + self.set_inferior_startup_launch() + + procs = self.prep_debug_monitor_and_inferior() + + OFFSET = 0 + LENGTH = 0x1ffff0 + self.test_sequence.add_log_lines([ + "read packet: $qXfer:features:read:target.xml:{:x},{:x}#00".format( + OFFSET, + LENGTH), + { + "direction": "send", + "regex": re.compile("^\$l(.+)#[0-9a-fA-F]{2}$"), + "capture": {1: "target_xml"} + }], + True) + context = self.expect_gdbremote_sequence() + + target_xml = context.get("target_xml") + + root = ET.fromstring(target_xml) + self.assertIsNotNone(root) + self.assertEqual(root.tag, "target") + + architecture = root.find("architecture") + self.assertIsNotNone(architecture) + self.assertEqual(architecture.text, self.getArchitecture()) + + feature = root.find("feature") + self.assertIsNotNone(feature) + + target_xml_registers = feature.findall("reg") + self.assertTrue(len(target_xml_registers) > 0) + + # registers info collected by qRegisterInfo + self.add_register_info_collection_packets() + context = self.expect_gdbremote_sequence() + self.assertIsNotNone(context) + q_info_registers = self.parse_register_info_packets(context) + + self.assertTrue(len(target_xml_registers) == len(q_info_registers)) + for register in zip(target_xml_registers, q_info_registers): + xml_info_reg = register[0] + q_info_reg = register[1] + self.assertEqual(q_info_reg["name"], xml_info_reg.get("name")) + self.assertEqual(q_info_reg["set"], xml_info_reg.get("group")) + self.assertEqual(q_info_reg["format"], xml_info_reg.get("format")) + self.assertEqual(q_info_reg["bitsize"], xml_info_reg.get("bitsize")) + self.assertEqual(q_info_reg["offset"], xml_info_reg.get("offset")) + self.assertEqual(q_info_reg["encoding"], xml_info_reg.get("encoding")) \ No newline at end of file diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-server/registers-target-xml-reading/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-server/registers-target-xml-reading/main.cpp new file mode 100644 index 00000000000..237c8ce1817 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-server/registers-target-xml-reading/main.cpp @@ -0,0 +1 @@ +int main() {} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py index 199b80c8f6f..c1b33c220b4 100644 --- a/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py @@ -2,6 +2,7 @@ from lldbsuite.test.lldbtest import * import os import vscode +import time class VSCodeTestCaseBase(TestBase): @@ -12,8 +13,10 @@ class VSCodeTestCaseBase(TestBase): '''Create the Visual Studio Code debug adaptor''' self.assertTrue(os.path.exists(self.lldbVSCodeExec), 'lldb-vscode must exist') + log_file_path = self.getBuildArtifact('vscode.txt') self.vscode = vscode.DebugAdaptor( - executable=self.lldbVSCodeExec, init_commands=self.setUpCommands()) + executable=self.lldbVSCodeExec, init_commands=self.setUpCommands(), + log_file=log_file_path) def build_and_create_debug_adaptor(self): self.build() @@ -22,8 +25,7 @@ class VSCodeTestCaseBase(TestBase): def set_source_breakpoints(self, source_path, lines, condition=None, hitCondition=None): '''Sets source breakpoints and returns an array of strings containing - the breakpoint location IDs ("1.1", "1.2") for each breakpoint - that was set. + the breakpoint IDs ("1", "2") for each breakpoint that was set. ''' response = self.vscode.request_setBreakpoints( source_path, lines, condition=condition, hitCondition=hitCondition) @@ -32,17 +34,14 @@ class VSCodeTestCaseBase(TestBase): breakpoints = response['body']['breakpoints'] breakpoint_ids = [] for breakpoint in breakpoints: - response_id = breakpoint['id'] - bp_id = response_id >> 32 - bp_loc_id = response_id & 0xffffffff - breakpoint_ids.append('%i.%i' % (bp_id, bp_loc_id)) + breakpoint_ids.append('%i' % (breakpoint['id'])) return breakpoint_ids def set_function_breakpoints(self, functions, condition=None, hitCondition=None): '''Sets breakpoints by function name given an array of function names - and returns an array of strings containing the breakpoint location - IDs ("1.1", "1.2") for each breakpoint that was set. + and returns an array of strings containing the breakpoint IDs + ("1", "2") for each breakpoint that was set. ''' response = self.vscode.request_setFunctionBreakpoints( functions, condition=condition, hitCondition=hitCondition) @@ -51,18 +50,21 @@ class VSCodeTestCaseBase(TestBase): breakpoints = response['body']['breakpoints'] breakpoint_ids = [] for breakpoint in breakpoints: - response_id = breakpoint['id'] - bp_id = response_id >> 32 - bp_loc_id = response_id & 0xffffffff - breakpoint_ids.append('%i.%i' % (bp_id, bp_loc_id)) + breakpoint_ids.append('%i' % (breakpoint['id'])) return breakpoint_ids + def waitUntil(self, condition): + while True: + if condition(): + break + time.sleep(0.5) + def verify_breakpoint_hit(self, breakpoint_ids): '''Wait for the process we are debugging to stop, and verify we hit any breakpoint location in the "breakpoint_ids" array. - "breakpoint_ids" should be a list of breakpoint location ID strings - (["1.1", "2.1"]). The return value from - self.set_source_breakpoints() can be passed to this function''' + "breakpoint_ids" should be a list of breakpoint ID strings + (["1", "2"]). The return value from self.set_source_breakpoints() + or self.set_function_breakpoints() can be passed to this function''' stopped_events = self.vscode.wait_for_stopped() for stopped_event in stopped_events: if 'body' in stopped_event: @@ -73,14 +75,21 @@ class VSCodeTestCaseBase(TestBase): continue if 'description' not in body: continue - # Description is "breakpoint 1.1", so look for any location id - # ("1.1") in the description field as verification that one of - # the breakpoint locations was hit + # Descriptions for breakpoints will be in the form + # "breakpoint 1.1", so look for any description that matches + # ("breakpoint 1.") in the description field as verification + # that one of the breakpoint locations was hit. VSCode doesn't + # allow breakpoints to have multiple locations, but LLDB does. + # So when looking at the description we just want to make sure + # the right breakpoint matches and not worry about the actual + # location. description = body['description'] + print("description: %s" % (description)) for breakpoint_id in breakpoint_ids: - if breakpoint_id in description: - return True - return False + match_desc = 'breakpoint %s.' % (breakpoint_id) + if match_desc in description: + return + self.assertTrue(False, "breakpoint not hit") def verify_exception_breakpoint_hit(self, filter_label): '''Wait for the process we are debugging to stop, and verify the stop @@ -133,7 +142,7 @@ class VSCodeTestCaseBase(TestBase): key, key_path, d)) return value - def get_stackFrames_and_totalFramesCount(self, threadId=None, startFrame=None, + def get_stackFrames_and_totalFramesCount(self, threadId=None, startFrame=None, levels=None, dump=False): response = self.vscode.request_stackTrace(threadId=threadId, startFrame=startFrame, @@ -177,6 +186,9 @@ class VSCodeTestCaseBase(TestBase): def get_console(self, timeout=0.0): return self.vscode.get_output('console', timeout=timeout) + def collect_console(self, duration): + return self.vscode.collect_output('console', duration=duration) + def get_local_as_int(self, name, threadId=None): value = self.vscode.get_local_variable_value(name, threadId=threadId) if value.startswith('0x'): @@ -228,23 +240,25 @@ class VSCodeTestCaseBase(TestBase): def continue_to_exit(self, exitCode=0): self.vscode.request_continue() stopped_events = self.vscode.wait_for_stopped() - self.assertTrue(len(stopped_events) == 1, - "expecting single 'exited' event") - self.assertTrue(stopped_events[0]['event'] == 'exited', + self.assertEquals(len(stopped_events), 1, + "stopped_events = {}".format(stopped_events)) + self.assertEquals(stopped_events[0]['event'], 'exited', 'make sure program ran to completion') - self.assertTrue(stopped_events[0]['body']['exitCode'] == exitCode, + self.assertEquals(stopped_events[0]['body']['exitCode'], exitCode, 'exitCode == %i' % (exitCode)) def attach(self, program=None, pid=None, waitFor=None, trace=None, initCommands=None, preRunCommands=None, stopCommands=None, - exitCommands=None, attachCommands=None): + exitCommands=None, attachCommands=None, coreFile=None, + disconnectAutomatically=True, terminateCommands=None): '''Build the default Makefile target, create the VSCode debug adaptor, and attach to the process. ''' # Make sure we disconnect and terminate the VSCode debug adaptor even # if we throw an exception during the test case. def cleanup(): - self.vscode.request_disconnect(terminateDebuggee=True) + if disconnectAutomatically: + self.vscode.request_disconnect(terminateDebuggee=True) self.vscode.terminate() # Execute the cleanup function during test case tear down. @@ -255,7 +269,8 @@ class VSCodeTestCaseBase(TestBase): program=program, pid=pid, waitFor=waitFor, trace=trace, initCommands=initCommands, preRunCommands=preRunCommands, stopCommands=stopCommands, exitCommands=exitCommands, - attachCommands=attachCommands) + attachCommands=attachCommands, terminateCommands=terminateCommands, + coreFile=coreFile) if not (response and response['success']): self.assertTrue(response['success'], 'attach failed (%s)' % (response['message'])) @@ -264,15 +279,17 @@ class VSCodeTestCaseBase(TestBase): stopOnEntry=False, disableASLR=True, disableSTDIO=False, shellExpandArguments=False, trace=False, initCommands=None, preRunCommands=None, - stopCommands=None, exitCommands=None,sourcePath= None, - debuggerRoot=None, launchCommands=None): + stopCommands=None, exitCommands=None, terminateCommands=None, + sourcePath=None, debuggerRoot=None, launchCommands=None, + sourceMap=None, disconnectAutomatically=True): '''Sending launch request to vscode ''' # Make sure we disconnect and terminate the VSCode debug adapter, # if we throw an exception during the test case def cleanup(): - self.vscode.request_disconnect(terminateDebuggee=True) + if disconnectAutomatically: + self.vscode.request_disconnect(terminateDebuggee=True) self.vscode.terminate() # Execute the cleanup function during test case tear down. @@ -294,9 +311,11 @@ class VSCodeTestCaseBase(TestBase): preRunCommands=preRunCommands, stopCommands=stopCommands, exitCommands=exitCommands, + terminateCommands=terminateCommands, sourcePath=sourcePath, debuggerRoot=debuggerRoot, - launchCommands=launchCommands) + launchCommands=launchCommands, + sourceMap=sourceMap) if not (response and response['success']): self.assertTrue(response['success'], 'launch failed (%s)' % (response['message'])) @@ -306,7 +325,8 @@ class VSCodeTestCaseBase(TestBase): disableSTDIO=False, shellExpandArguments=False, trace=False, initCommands=None, preRunCommands=None, stopCommands=None, exitCommands=None, - sourcePath=None, debuggerRoot=None): + terminateCommands=None, sourcePath=None, + debuggerRoot=None): '''Build the default Makefile target, create the VSCode debug adaptor, and launch the process. ''' @@ -316,4 +336,4 @@ class VSCodeTestCaseBase(TestBase): self.launch(program, args, cwd, env, stopOnEntry, disableASLR, disableSTDIO, shellExpandArguments, trace, initCommands, preRunCommands, stopCommands, exitCommands, - sourcePath, debuggerRoot) + terminateCommands, sourcePath, debuggerRoot) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py index 1110ad36c0f..6b1c1c961b5 100644 --- a/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py @@ -10,6 +10,7 @@ import string import subprocess import sys import threading +import time def dump_memory(base_addr, data, num_per_line, outfile): @@ -111,6 +112,8 @@ class DebugCommunication(object): self.exit_status = None self.initialize_body = None self.thread_stop_reasons = {} + self.breakpoint_events = [] + self.module_events = {} self.sequence = 1 self.threads = None self.recv_thread.start() @@ -131,6 +134,9 @@ class DebugCommunication(object): if command['seq'] != response['request_seq']: raise ValueError('seq mismatch in response') + def get_active_modules(self): + return self.module_events + def get_output(self, category, timeout=0.0, clear=True): self.output_condition.acquire() output = None @@ -147,6 +153,15 @@ class DebugCommunication(object): self.output_condition.release() return output + def collect_output(self, category, duration, clear=True): + end_time = time.time() + duration + collected_output = "" + while end_time > time.time(): + output = self.get_output(category, timeout=0.25, clear=clear) + if output: + collected_output += output + return collected_output if collected_output else None + def enqueue_recv_packet(self, packet): self.recv_condition.acquire() self.recv_packets.append(packet) @@ -160,7 +175,7 @@ class DebugCommunication(object): indicate a new packet is available. Returns True if the caller should keep calling this function for more packets. ''' - # If EOF, notify the read thread by enqueing a None. + # If EOF, notify the read thread by enqueuing a None. if not packet: self.enqueue_recv_packet(None) return False @@ -186,7 +201,7 @@ class DebugCommunication(object): self.output[category] = output self.output_condition.notify() self.output_condition.release() - # no need to add 'output' packets to our packets list + # no need to add 'output' event packets to our packets list return keepGoing elif event == 'process': # When a new process is attached or launched, remember the @@ -200,6 +215,22 @@ class DebugCommunication(object): self._process_stopped() tid = body['threadId'] self.thread_stop_reasons[tid] = body + elif event == 'breakpoint': + # Breakpoint events come in when a breakpoint has locations + # added or removed. Keep track of them so we can look for them + # in tests. + self.breakpoint_events.append(packet) + # no need to add 'breakpoint' event packets to our packets list + return keepGoing + elif event == 'module': + reason = body['reason'] + if (reason == 'new' or reason == 'changed'): + self.module_events[body['module']['name']] = body['module'] + elif reason == 'removed': + if body['module']['name'] in self.module_events: + self.module_events.pop(body['module']['name']) + return keepGoing + elif packet_type == 'response': if packet['command'] == 'disconnect': keepGoing = False @@ -442,7 +473,8 @@ class DebugCommunication(object): def request_attach(self, program=None, pid=None, waitFor=None, trace=None, initCommands=None, preRunCommands=None, stopCommands=None, exitCommands=None, - attachCommands=None): + attachCommands=None, terminateCommands=None, + coreFile=None): args_dict = {} if pid is not None: args_dict['pid'] = pid @@ -461,8 +493,12 @@ class DebugCommunication(object): args_dict['stopCommands'] = stopCommands if exitCommands: args_dict['exitCommands'] = exitCommands + if terminateCommands: + args_dict['terminateCommands'] = terminateCommands if attachCommands: args_dict['attachCommands'] = attachCommands + if coreFile: + args_dict['coreFile'] = coreFile command_dict = { 'command': 'attach', 'type': 'request', @@ -561,8 +597,9 @@ class DebugCommunication(object): stopOnEntry=False, disableASLR=True, disableSTDIO=False, shellExpandArguments=False, trace=False, initCommands=None, preRunCommands=None, - stopCommands=None, exitCommands=None, sourcePath=None, - debuggerRoot=None, launchCommands=None): + stopCommands=None, exitCommands=None, + terminateCommands=None ,sourcePath=None, + debuggerRoot=None, launchCommands=None, sourceMap=None): args_dict = { 'program': program } @@ -591,12 +628,16 @@ class DebugCommunication(object): args_dict['stopCommands'] = stopCommands if exitCommands: args_dict['exitCommands'] = exitCommands + if terminateCommands: + args_dict['terminateCommands'] = terminateCommands if sourcePath: args_dict['sourcePath'] = sourcePath if debuggerRoot: args_dict['debuggerRoot'] = debuggerRoot if launchCommands: args_dict['launchCommands'] = launchCommands + if sourceMap: + args_dict['sourceMap'] = sourceMap command_dict = { 'command': 'launch', 'type': 'request', @@ -719,6 +760,16 @@ class DebugCommunication(object): } return self.send_recv(command_dict) + def request_getCompileUnits(self, moduleId): + args_dict = {'moduleId': moduleId} + command_dict = { + 'command': 'getCompileUnits', + 'type': 'request', + 'arguments': args_dict + } + response = self.send_recv(command_dict) + return response + def request_completions(self, text): args_dict = { 'text': text, @@ -780,7 +831,7 @@ class DebugCommunication(object): self.threads = body['threads'] for thread in self.threads: # Copy the thread dictionary so we can add key/value pairs to - # it without affecfting the original info from the "threads" + # it without affecting the original info from the "threads" # command. tid = thread['id'] if tid in self.thread_stop_reasons: @@ -839,13 +890,17 @@ class DebugCommunication(object): class DebugAdaptor(DebugCommunication): - def __init__(self, executable=None, port=None, init_commands=[]): + def __init__(self, executable=None, port=None, init_commands=[], log_file=None): self.process = None if executable is not None: + adaptor_env = os.environ.copy() + if log_file: + adaptor_env['LLDBVSCODE_LOG'] = log_file self.process = subprocess.Popen([executable], stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + stderr=subprocess.PIPE, + env=adaptor_env) DebugCommunication.__init__(self, self.process.stdout, self.process.stdin, init_commands) elif port is not None: @@ -889,7 +944,8 @@ def run_vscode(dbg, args, options): initCommands=options.initCmds, preRunCommands=options.preRunCmds, stopCommands=options.stopCmds, - exitCommands=options.exitCmds) + exitCommands=options.exitCmds, + terminateCommands=options.terminateCmds) else: response = dbg.request_launch(options.program, args=args, @@ -900,7 +956,8 @@ def run_vscode(dbg, args, options): initCommands=options.initCmds, preRunCommands=options.preRunCmds, stopCommands=options.stopCmds, - exitCommands=options.exitCmds) + exitCommands=options.exitCmds, + terminateCommands=options.terminateCmds) if response['success']: if options.sourceBreakpoints: @@ -1006,7 +1063,7 @@ def main(): dest='attach', default=False, help=('Specify this option to attach to a process by name. The ' - 'process name is the basanme of the executable specified with ' + 'process name is the basename of the executable specified with ' 'the --program option.')) parser.add_option( @@ -1073,6 +1130,15 @@ def main(): help=('Specify a LLDB command that will be executed when the process ' 'exits. Can be specified more than once.')) + parser.add_option( + '--terminateCommand', + type='string', + action='append', + dest='terminateCmds', + default=[], + help=('Specify a LLDB command that will be executed when the debugging ' + 'session is terminated. Can be specified more than once.')) + parser.add_option( '--env', type='string', diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test_event/formatter/__init__.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test_event/formatter/__init__.py index 1fe6ecd3ef8..d6609d353c8 100644 --- a/gnu/llvm/lldb/packages/Python/lldbsuite/test_event/formatter/__init__.py +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test_event/formatter/__init__.py @@ -17,17 +17,6 @@ import sys # LLDB modules -# Ignore method count on DTOs. -# pylint: disable=too-few-public-methods -class FormatterConfig(object): - """Provides formatter configuration info to create_results_formatter().""" - - def __init__(self): - self.filename = None - self.formatter_name = None - self.formatter_options = None - - # Ignore method count on DTOs. # pylint: disable=too-few-public-methods class CreatedFormatter(object): @@ -38,7 +27,7 @@ class CreatedFormatter(object): self.cleanup_func = cleanup_func -def create_results_formatter(config): +def create_results_formatter(formatter_name): """Sets up a test results formatter. @param config an instance of FormatterConfig @@ -47,75 +36,31 @@ def create_results_formatter(config): @return an instance of CreatedFormatter. """ - default_formatter_name = None - results_file_object = None - cleanup_func = None - - if config.filename: - # Open the results file for writing. - if config.filename == 'stdout': - results_file_object = sys.stdout - cleanup_func = None - elif config.filename == 'stderr': - results_file_object = sys.stderr - cleanup_func = None - else: - results_file_object = open(config.filename, "w") - cleanup_func = results_file_object.close - default_formatter_name = ( - "lldbsuite.test_event.formatter.xunit.XunitFormatter") - - # If we have a results formatter name specified and we didn't specify - # a results file, we should use stdout. - if config.formatter_name is not None and results_file_object is None: - # Use stdout. - results_file_object = sys.stdout - cleanup_func = None - - if results_file_object: - # We care about the formatter. Choose user-specified or, if - # none specified, use the default for the output type. - if config.formatter_name: - formatter_name = config.formatter_name - else: - formatter_name = default_formatter_name - - # Create an instance of the class. - # First figure out the package/module. - components = formatter_name.split(".") - module = importlib.import_module(".".join(components[:-1])) - - # Create the class name we need to load. - cls = getattr(module, components[-1]) - - # Handle formatter options for the results formatter class. - formatter_arg_parser = cls.arg_parser() - if config.formatter_options and len(config.formatter_options) > 0: - command_line_options = config.formatter_options - else: - command_line_options = [] - - formatter_options = formatter_arg_parser.parse_args( - command_line_options) - - # Create the TestResultsFormatter given the processed options. - results_formatter_object = cls( - results_file_object, - formatter_options) - - def shutdown_formatter(): - """Shuts down the formatter when it is no longer needed.""" - # Tell the formatter to write out anything it may have - # been saving until the very end (e.g. xUnit results - # can't complete its output until this point). - results_formatter_object.send_terminate_as_needed() - - # And now close out the output file-like object. - if cleanup_func is not None: - cleanup_func() - - return CreatedFormatter( - results_formatter_object, - shutdown_formatter) - else: - return None + # Create an instance of the class. + # First figure out the package/module. + components = formatter_name.split(".") + module = importlib.import_module(".".join(components[:-1])) + + # Create the class name we need to load. + cls = getattr(module, components[-1]) + + # Handle formatter options for the results formatter class. + formatter_arg_parser = cls.arg_parser() + command_line_options = [] + + formatter_options = formatter_arg_parser.parse_args( + command_line_options) + + # Create the TestResultsFormatter given the processed options. + results_formatter_object = cls(sys.stdout, formatter_options) + + def shutdown_formatter(): + """Shuts down the formatter when it is no longer needed.""" + # Tell the formatter to write out anything it may have + # been saving until the very end (e.g. xUnit results + # can't complete its output until this point). + results_formatter_object.send_terminate_as_needed() + + return CreatedFormatter( + results_formatter_object, + shutdown_formatter) diff --git a/gnu/llvm/lldb/scripts/analyze-project-deps.py b/gnu/llvm/lldb/scripts/analyze-project-deps.py index c6e3263a2f2..a120260abfe 100755 --- a/gnu/llvm/lldb/scripts/analyze-project-deps.py +++ b/gnu/llvm/lldb/scripts/analyze-project-deps.py @@ -109,7 +109,7 @@ def expand(path_queue, path_lengths, cycles, src_map): next_len = path_lengths.pop(0) + 1 last_component = cur_path[-1] - for item in src_map[last_component]: + for item in src_map.get(last_component, []): if item.startswith("clang"): continue diff --git a/gnu/llvm/lldb/scripts/reproducer-replay.py b/gnu/llvm/lldb/scripts/reproducer-replay.py new file mode 100755 index 00000000000..4dd34705834 --- /dev/null +++ b/gnu/llvm/lldb/scripts/reproducer-replay.py @@ -0,0 +1,119 @@ +#! /usr/bin/env python3 + +from multiprocessing import Pool +import multiprocessing +import argparse +import tempfile +import logging +import os +import subprocess + + +def run_reproducer(path): + proc = subprocess.Popen([LLDB, '--replay', path], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + reason = None + try: + outs, errs = proc.communicate(timeout=TIMEOUT) + success = proc.returncode == 0 + result = 'PASSED' if success else 'FAILED' + if not success: + outs = outs.decode() + errs = errs.decode() + # Do some pattern matching to find out the cause of the failure. + if 'Encountered unexpected packet during replay' in errs: + reason = 'Unexpected packet' + elif 'Assertion failed' in errs: + reason = 'Assertion failed' + elif 'UNREACHABLE' in errs: + reason = 'Unreachable executed' + elif 'Segmentation fault' in errs: + reason = 'Segmentation fault' + elif 'Illegal instruction' in errs: + reason = 'Illegal instruction' + else: + reason = f'Exit code {proc.returncode}' + except subprocess.TimeoutExpired: + proc.kill() + success = False + outs, errs = proc.communicate() + result = 'TIMEOUT' + + if not FAILURE_ONLY or not success: + reason_str = f' ({reason})' if reason else '' + print(f'{result}: {path}{reason_str}') + if VERBOSE: + if outs: + print(outs) + if errs: + print(errs) + + +def find_reproducers(path): + for root, dirs, files in os.walk(path): + for dir in dirs: + _, extension = os.path.splitext(dir) + if dir.startswith('Test') and extension == '.py': + yield os.path.join(root, dir) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description='LLDB API Test Replay Driver. ' + 'Replay one or more reproducers in parallel using the specified LLDB driver. ' + 'The script will look for reproducers generated by the API lit test suite. ' + 'To generate the reproducers, pass --param \'lldb-run-with-repro=capture\' to lit.' + ) + parser.add_argument( + '-j', + '--threads', + type=int, + default=multiprocessing.cpu_count(), + help='Number of threads. The number of CPU threads if not specified.') + parser.add_argument( + '-t', + '--timeout', + type=int, + default=60, + help='Replay timeout in seconds. 60 seconds if not specified.') + parser.add_argument( + '-p', + '--path', + type=str, + default=os.getcwd(), + help= + 'Path to the directory containing the reproducers. The current working directory if not specified.' + ) + parser.add_argument('-l', + '--lldb', + type=str, + required=True, + help='Path to the LLDB command line driver') + parser.add_argument('-v', + '--verbose', + help='Print replay output.', + action='store_true') + parser.add_argument('--failure-only', + help='Only log failures.', + action='store_true') + args = parser.parse_args() + + global LLDB + global TIMEOUT + global VERBOSE + global FAILURE_ONLY + LLDB = args.lldb + TIMEOUT = args.timeout + VERBOSE = args.verbose + FAILURE_ONLY = args.failure_only + + print( + f'Replaying reproducers in {args.path} with {args.threads} threads and a {args.timeout} seconds timeout' + ) + + try: + pool = Pool(args.threads) + pool.map(run_reproducer, find_reproducers(args.path)) + except KeyboardInterrupt: + print('Interrupted') diff --git a/gnu/llvm/lldb/scripts/verify_api.py b/gnu/llvm/lldb/scripts/verify_api.py index d422cded8c2..f3f0748023b 100755 --- a/gnu/llvm/lldb/scripts/verify_api.py +++ b/gnu/llvm/lldb/scripts/verify_api.py @@ -48,7 +48,7 @@ def verify_api(all_args): type='string', action='append', dest='archs', - help='architecure to use when checking the api') + help='architecture to use when checking the api') parser.add_option( '-r', '--api-regex', diff --git a/gnu/llvm/lldb/source/API/CMakeLists.txt b/gnu/llvm/lldb/source/API/CMakeLists.txt index e0ecf29b502..ce6a7ec830f 100644 --- a/gnu/llvm/lldb/source/API/CMakeLists.txt +++ b/gnu/llvm/lldb/source/API/CMakeLists.txt @@ -29,12 +29,14 @@ add_lldb_library(liblldb SHARED ${option_framework} SBBreakpointOptionCommon.cpp SBBroadcaster.cpp SBCommandInterpreter.cpp + SBCommandInterpreterRunOptions.cpp SBCommandReturnObject.cpp SBCommunication.cpp SBCompileUnit.cpp SBData.cpp SBDebugger.cpp SBDeclaration.cpp + SBEnvironment.cpp SBError.cpp SBEvent.cpp SBExecutionContext.cpp @@ -119,6 +121,11 @@ if(LLDB_ENABLE_PYTHON AND (BUILD_SHARED_LIBS OR LLVM_LINK_LLVM_DYLIB) AND UNIX A set_property(TARGET liblldb APPEND PROPERTY INSTALL_RPATH "\$ORIGIN/../../../../lib${LLVM_LIBDIR_SUFFIX}") endif() +if(PYTHON_RPATH) + set_property(TARGET liblldb APPEND PROPERTY INSTALL_RPATH "${PYTHON_RPATH}") + set_property(TARGET liblldb APPEND PROPERTY BUILD_RPATH "${PYTHON_RPATH}") +endif() + if (MSVC) set_source_files_properties(SBReproducer.cpp PROPERTIES COMPILE_FLAGS /bigobj) endif() diff --git a/gnu/llvm/lldb/source/API/SBAddress.cpp b/gnu/llvm/lldb/source/API/SBAddress.cpp index dcde25b7791..6444a006c0f 100644 --- a/gnu/llvm/lldb/source/API/SBAddress.cpp +++ b/gnu/llvm/lldb/source/API/SBAddress.cpp @@ -1,4 +1,4 @@ -//===-- SBAddress.cpp -------------------------------------------*- C++ -*-===// +//===-- SBAddress.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -52,7 +52,7 @@ SBAddress::SBAddress(lldb::addr_t load_addr, lldb::SBTarget &target) SetLoadAddress(load_addr, target); } -SBAddress::~SBAddress() {} +SBAddress::~SBAddress() = default; const SBAddress &SBAddress::operator=(const SBAddress &rhs) { LLDB_RECORD_METHOD(const lldb::SBAddress &, @@ -89,7 +89,7 @@ SBAddress::operator bool() const { void SBAddress::Clear() { LLDB_RECORD_METHOD_NO_ARGS(void, SBAddress, Clear); - m_opaque_up.reset(new Address()); + m_opaque_up = std::make_unique
(); } void SBAddress::SetAddress(lldb::SBSection section, lldb::addr_t offset) { @@ -105,7 +105,7 @@ void SBAddress::SetAddress(const Address *lldb_object_ptr) { if (lldb_object_ptr) ref() = *lldb_object_ptr; else - m_opaque_up.reset(new Address()); + m_opaque_up = std::make_unique
(); } lldb::addr_t SBAddress::GetFileAddress() const { @@ -187,7 +187,7 @@ const Address *SBAddress::operator->() const { return m_opaque_up.get(); } Address &SBAddress::ref() { if (m_opaque_up == nullptr) - m_opaque_up.reset(new Address()); + m_opaque_up = std::make_unique
(); return *m_opaque_up; } diff --git a/gnu/llvm/lldb/source/API/SBAttachInfo.cpp b/gnu/llvm/lldb/source/API/SBAttachInfo.cpp index 838385c104a..b21589cf270 100644 --- a/gnu/llvm/lldb/source/API/SBAttachInfo.cpp +++ b/gnu/llvm/lldb/source/API/SBAttachInfo.cpp @@ -1,4 +1,4 @@ -//===-- SBAttachInfo.cpp ----------------------------------------*- C++ -*-===// +//===-- SBAttachInfo.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -54,7 +54,7 @@ SBAttachInfo::SBAttachInfo(const SBAttachInfo &rhs) m_opaque_sp = clone(rhs.m_opaque_sp); } -SBAttachInfo::~SBAttachInfo() {} +SBAttachInfo::~SBAttachInfo() = default; lldb_private::ProcessAttachInfo &SBAttachInfo::ref() { return *m_opaque_sp; } diff --git a/gnu/llvm/lldb/source/API/SBBlock.cpp b/gnu/llvm/lldb/source/API/SBBlock.cpp index f333d1d7b5f..a5fee445d5c 100644 --- a/gnu/llvm/lldb/source/API/SBBlock.cpp +++ b/gnu/llvm/lldb/source/API/SBBlock.cpp @@ -1,4 +1,4 @@ -//===-- SBBlock.cpp ---------------------------------------------*- C++ -*-===// +//===-- SBBlock.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -71,13 +71,7 @@ const char *SBBlock::GetInlinedName() const { const InlineFunctionInfo *inlined_info = m_opaque_ptr->GetInlinedFunctionInfo(); if (inlined_info) { - Function *function = m_opaque_ptr->CalculateSymbolContextFunction(); - LanguageType language; - if (function) - language = function->GetLanguage(); - else - language = lldb::eLanguageTypeUnknown; - return inlined_info->GetName(language).AsCString(nullptr); + return inlined_info->GetName().AsCString(nullptr); } } return nullptr; diff --git a/gnu/llvm/lldb/source/API/SBBreakpoint.cpp b/gnu/llvm/lldb/source/API/SBBreakpoint.cpp index 8159b851d58..eb75bf8b33f 100644 --- a/gnu/llvm/lldb/source/API/SBBreakpoint.cpp +++ b/gnu/llvm/lldb/source/API/SBBreakpoint.cpp @@ -1,4 +1,4 @@ -//===-- SBBreakpoint.cpp ----------------------------------------*- C++ -*-===// +//===-- SBBreakpoint.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -652,19 +652,28 @@ SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) { bool SBBreakpoint::AddName(const char *new_name) { LLDB_RECORD_METHOD(bool, SBBreakpoint, AddName, (const char *), new_name); + SBError status = AddNameWithErrorHandling(new_name); + return status.Success(); +} + +SBError SBBreakpoint::AddNameWithErrorHandling(const char *new_name) { + LLDB_RECORD_METHOD(SBError, SBBreakpoint, AddNameWithErrorHandling, + (const char *), new_name); + BreakpointSP bkpt_sp = GetSP(); + SBError status; if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); - Status error; // Think I'm just going to swallow the error here, it's - // probably more annoying to have to provide it. + Status error; bkpt_sp->GetTarget().AddNameToBreakpoint(bkpt_sp, new_name, error); - if (error.Fail()) - return false; + status.SetError(error); + } else { + status.SetErrorString("invalid breakpoint"); } - return true; + return LLDB_RECORD_RESULT(status); } void SBBreakpoint::RemoveName(const char *name_to_remove) { @@ -873,7 +882,7 @@ SBBreakpointList::SBBreakpointList(SBTarget &target) LLDB_RECORD_CONSTRUCTOR(SBBreakpointList, (lldb::SBTarget &), target); } -SBBreakpointList::~SBBreakpointList() {} +SBBreakpointList::~SBBreakpointList() = default; size_t SBBreakpointList::GetSize() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(size_t, SBBreakpointList, GetSize); @@ -1015,6 +1024,8 @@ void RegisterMethods(Registry &R) { LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, SetScriptCallbackBody, (const char *)); LLDB_REGISTER_METHOD(bool, SBBreakpoint, AddName, (const char *)); + LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, AddNameWithErrorHandling, + (const char *)); LLDB_REGISTER_METHOD(void, SBBreakpoint, RemoveName, (const char *)); LLDB_REGISTER_METHOD(bool, SBBreakpoint, MatchesName, (const char *)); LLDB_REGISTER_METHOD(void, SBBreakpoint, GetNames, (lldb::SBStringList &)); diff --git a/gnu/llvm/lldb/source/API/SBBreakpointLocation.cpp b/gnu/llvm/lldb/source/API/SBBreakpointLocation.cpp index 2b62a69a21e..e29f3fd9c50 100644 --- a/gnu/llvm/lldb/source/API/SBBreakpointLocation.cpp +++ b/gnu/llvm/lldb/source/API/SBBreakpointLocation.cpp @@ -1,4 +1,4 @@ -//===-- SBBreakpointLocation.cpp --------------------------------*- C++ -*-===// +//===-- SBBreakpointLocation.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -59,7 +59,7 @@ operator=(const SBBreakpointLocation &rhs) { return LLDB_RECORD_RESULT(*this); } -SBBreakpointLocation::~SBBreakpointLocation() {} +SBBreakpointLocation::~SBBreakpointLocation() = default; BreakpointLocationSP SBBreakpointLocation::GetSP() const { return m_opaque_wp.lock(); diff --git a/gnu/llvm/lldb/source/API/SBBreakpointName.cpp b/gnu/llvm/lldb/source/API/SBBreakpointName.cpp index 5bd7732ebb6..3995defcf97 100644 --- a/gnu/llvm/lldb/source/API/SBBreakpointName.cpp +++ b/gnu/llvm/lldb/source/API/SBBreakpointName.cpp @@ -1,4 +1,4 @@ -//===-- SBBreakpointName.cpp ----------------------------------------*- C++ -*-===// +//===-- SBBreakpointName.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -115,7 +115,7 @@ SBBreakpointName::SBBreakpointName(SBTarget &sb_target, const char *name) { LLDB_RECORD_CONSTRUCTOR(SBBreakpointName, (lldb::SBTarget &, const char *), sb_target, name); - m_impl_up.reset(new SBBreakpointNameImpl(sb_target, name)); + m_impl_up = std::make_unique(sb_target, name); // Call FindBreakpointName here to make sure the name is valid, reset if not: BreakpointName *bp_name = GetBreakpointName(); if (!bp_name) @@ -133,7 +133,8 @@ SBBreakpointName::SBBreakpointName(SBBreakpoint &sb_bkpt, const char *name) { BreakpointSP bkpt_sp = sb_bkpt.GetSP(); Target &target = bkpt_sp->GetTarget(); - m_impl_up.reset(new SBBreakpointNameImpl(target.shared_from_this(), name)); + m_impl_up = + std::make_unique(target.shared_from_this(), name); // Call FindBreakpointName here to make sure the name is valid, reset if not: BreakpointName *bp_name = GetBreakpointName(); @@ -154,8 +155,8 @@ SBBreakpointName::SBBreakpointName(const SBBreakpointName &rhs) { if (!rhs.m_impl_up) return; else - m_impl_up.reset(new SBBreakpointNameImpl(rhs.m_impl_up->GetTarget(), - rhs.m_impl_up->GetName())); + m_impl_up = std::make_unique( + rhs.m_impl_up->GetTarget(), rhs.m_impl_up->GetName()); } SBBreakpointName::~SBBreakpointName() = default; @@ -171,8 +172,8 @@ operator=(const SBBreakpointName &rhs) { return LLDB_RECORD_RESULT(*this); } - m_impl_up.reset(new SBBreakpointNameImpl(rhs.m_impl_up->GetTarget(), - rhs.m_impl_up->GetName())); + m_impl_up = std::make_unique(rhs.m_impl_up->GetTarget(), + rhs.m_impl_up->GetName()); return LLDB_RECORD_RESULT(*this); } diff --git a/gnu/llvm/lldb/source/API/SBBreakpointOptionCommon.cpp b/gnu/llvm/lldb/source/API/SBBreakpointOptionCommon.cpp index 870b4b941ad..2ee47ff7795 100644 --- a/gnu/llvm/lldb/source/API/SBBreakpointOptionCommon.cpp +++ b/gnu/llvm/lldb/source/API/SBBreakpointOptionCommon.cpp @@ -1,4 +1,4 @@ -//===-- SBBreakpointOptionCommon.cpp --------------------------------*- C++ -*-===// +//===-- SBBreakpointOptionCommon.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/API/SBBreakpointOptionCommon.h b/gnu/llvm/lldb/source/API/SBBreakpointOptionCommon.h index 52049e4e758..0ceb90290de 100644 --- a/gnu/llvm/lldb/source/API/SBBreakpointOptionCommon.h +++ b/gnu/llvm/lldb/source/API/SBBreakpointOptionCommon.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SBBreakpointOptionCommons_h_ -#define LLDB_SBBreakpointOptionCommons_h_ +#ifndef LLDB_SOURCE_API_SBBREAKPOINTOPTIONCOMMON_H +#define LLDB_SOURCE_API_SBBREAKPOINTOPTIONCOMMON_H #include "lldb/API/SBDefines.h" #include "lldb/Utility/Baton.h" @@ -33,4 +33,4 @@ public: }; } // namespace lldb -#endif // LLDB_SBBreakpointOptionCommons_h_ +#endif // LLDB_SOURCE_API_SBBREAKPOINTOPTIONCOMMON_H diff --git a/gnu/llvm/lldb/source/API/SBBroadcaster.cpp b/gnu/llvm/lldb/source/API/SBBroadcaster.cpp index e1efdf7baf6..d42d7ce2a53 100644 --- a/gnu/llvm/lldb/source/API/SBBroadcaster.cpp +++ b/gnu/llvm/lldb/source/API/SBBroadcaster.cpp @@ -1,4 +1,4 @@ -//===-- SBBroadcaster.cpp ---------------------------------------*- C++ -*-===// +//===-- SBBroadcaster.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/API/SBCommandInterpreter.cpp b/gnu/llvm/lldb/source/API/SBCommandInterpreter.cpp index 6e5ebe6a7de..f4f19577b36 100644 --- a/gnu/llvm/lldb/source/API/SBCommandInterpreter.cpp +++ b/gnu/llvm/lldb/source/API/SBCommandInterpreter.cpp @@ -1,4 +1,4 @@ -//===-- SBCommandInterpreter.cpp --------------------------------*- C++ -*-===// +//===-- SBCommandInterpreter.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -17,6 +17,7 @@ #include "lldb/API/SBBroadcaster.h" #include "lldb/API/SBCommandInterpreter.h" +#include "lldb/API/SBCommandInterpreterRunOptions.h" #include "lldb/API/SBCommandReturnObject.h" #include "lldb/API/SBEvent.h" #include "lldb/API/SBExecutionContext.h" @@ -31,122 +32,6 @@ using namespace lldb; using namespace lldb_private; -SBCommandInterpreterRunOptions::SBCommandInterpreterRunOptions() { - LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBCommandInterpreterRunOptions); - - m_opaque_up.reset(new CommandInterpreterRunOptions()); -} - -SBCommandInterpreterRunOptions::~SBCommandInterpreterRunOptions() = default; - -bool SBCommandInterpreterRunOptions::GetStopOnContinue() const { - LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions, - GetStopOnContinue); - - return m_opaque_up->GetStopOnContinue(); -} - -void SBCommandInterpreterRunOptions::SetStopOnContinue(bool stop_on_continue) { - LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetStopOnContinue, - (bool), stop_on_continue); - - m_opaque_up->SetStopOnContinue(stop_on_continue); -} - -bool SBCommandInterpreterRunOptions::GetStopOnError() const { - LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions, - GetStopOnError); - - return m_opaque_up->GetStopOnError(); -} - -void SBCommandInterpreterRunOptions::SetStopOnError(bool stop_on_error) { - LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetStopOnError, - (bool), stop_on_error); - - m_opaque_up->SetStopOnError(stop_on_error); -} - -bool SBCommandInterpreterRunOptions::GetStopOnCrash() const { - LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions, - GetStopOnCrash); - - return m_opaque_up->GetStopOnCrash(); -} - -void SBCommandInterpreterRunOptions::SetStopOnCrash(bool stop_on_crash) { - LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetStopOnCrash, - (bool), stop_on_crash); - - m_opaque_up->SetStopOnCrash(stop_on_crash); -} - -bool SBCommandInterpreterRunOptions::GetEchoCommands() const { - LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions, - GetEchoCommands); - - return m_opaque_up->GetEchoCommands(); -} - -void SBCommandInterpreterRunOptions::SetEchoCommands(bool echo_commands) { - LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetEchoCommands, - (bool), echo_commands); - - m_opaque_up->SetEchoCommands(echo_commands); -} - -bool SBCommandInterpreterRunOptions::GetEchoCommentCommands() const { - LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions, - GetEchoCommentCommands); - - return m_opaque_up->GetEchoCommentCommands(); -} - -void SBCommandInterpreterRunOptions::SetEchoCommentCommands(bool echo) { - LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, - SetEchoCommentCommands, (bool), echo); - - m_opaque_up->SetEchoCommentCommands(echo); -} - -bool SBCommandInterpreterRunOptions::GetPrintResults() const { - LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions, - GetPrintResults); - - return m_opaque_up->GetPrintResults(); -} - -void SBCommandInterpreterRunOptions::SetPrintResults(bool print_results) { - LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetPrintResults, - (bool), print_results); - - m_opaque_up->SetPrintResults(print_results); -} - -bool SBCommandInterpreterRunOptions::GetAddToHistory() const { - LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions, - GetAddToHistory); - - return m_opaque_up->GetAddToHistory(); -} - -void SBCommandInterpreterRunOptions::SetAddToHistory(bool add_to_history) { - LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetAddToHistory, - (bool), add_to_history); - - m_opaque_up->SetAddToHistory(add_to_history); -} - -lldb_private::CommandInterpreterRunOptions * -SBCommandInterpreterRunOptions::get() const { - return m_opaque_up.get(); -} - -lldb_private::CommandInterpreterRunOptions & -SBCommandInterpreterRunOptions::ref() const { - return *m_opaque_up; -} - class CommandPluginInterfaceImplementation : public CommandObjectParsed { public: CommandPluginInterfaceImplementation(CommandInterpreter &interpreter, @@ -154,22 +39,41 @@ public: lldb::SBCommandPluginInterface *backend, const char *help = nullptr, const char *syntax = nullptr, - uint32_t flags = 0) + uint32_t flags = 0, + const char *auto_repeat_command = "") : CommandObjectParsed(interpreter, name, help, syntax, flags), - m_backend(backend) {} + m_backend(backend) { + m_auto_repeat_command = + auto_repeat_command == nullptr + ? llvm::None + : llvm::Optional(auto_repeat_command); + } bool IsRemovable() const override { return true; } + /// More documentation is available in lldb::CommandObject::GetRepeatCommand, + /// but in short, if nullptr is returned, the previous command will be + /// repeated, and if an empty string is returned, no commands will be + /// executed. + const char *GetRepeatCommand(Args ¤t_command_args, + uint32_t index) override { + if (!m_auto_repeat_command) + return nullptr; + else + return m_auto_repeat_command->c_str(); + } + protected: bool DoExecute(Args &command, CommandReturnObject &result) override { SBCommandReturnObject sb_return(result); SBCommandInterpreter sb_interpreter(&m_interpreter); SBDebugger debugger_sb(m_interpreter.GetDebugger().shared_from_this()); bool ret = m_backend->DoExecute( - debugger_sb, (char **)command.GetArgumentVector(), sb_return); + debugger_sb, command.GetArgumentVector(), sb_return); return ret; } std::shared_ptr m_backend; + llvm::Optional m_auto_repeat_command; }; SBCommandInterpreter::SBCommandInterpreter(CommandInterpreter *interpreter) @@ -681,14 +585,8 @@ lldb::SBCommand SBCommandInterpreter::AddCommand( (const char *, lldb::SBCommandPluginInterface *, const char *), name, impl, help); - lldb::CommandObjectSP new_command_sp; - new_command_sp = std::make_shared( - *m_opaque_ptr, name, impl, help); - - if (new_command_sp && - m_opaque_ptr->AddUserCommand(name, new_command_sp, true)) - return LLDB_RECORD_RESULT(lldb::SBCommand(new_command_sp)); - return LLDB_RECORD_RESULT(lldb::SBCommand()); + return LLDB_RECORD_RESULT(AddCommand(name, impl, help, /*syntax=*/nullptr, + /*auto_repeat_command=*/"")) } lldb::SBCommand @@ -699,10 +597,22 @@ SBCommandInterpreter::AddCommand(const char *name, (const char *, lldb::SBCommandPluginInterface *, const char *, const char *), name, impl, help, syntax); + return LLDB_RECORD_RESULT( + AddCommand(name, impl, help, syntax, /*auto_repeat_command=*/"")) +} + +lldb::SBCommand SBCommandInterpreter::AddCommand( + const char *name, lldb::SBCommandPluginInterface *impl, const char *help, + const char *syntax, const char *auto_repeat_command) { + LLDB_RECORD_METHOD(lldb::SBCommand, SBCommandInterpreter, AddCommand, + (const char *, lldb::SBCommandPluginInterface *, + const char *, const char *, const char *), + name, impl, help, syntax, auto_repeat_command); lldb::CommandObjectSP new_command_sp; new_command_sp = std::make_shared( - *m_opaque_ptr, name, impl, help, syntax); + *m_opaque_ptr, name, impl, help, syntax, /*flags=*/0, + auto_repeat_command); if (new_command_sp && m_opaque_ptr->AddUserCommand(name, new_command_sp, true)) @@ -783,17 +693,8 @@ lldb::SBCommand SBCommand::AddCommand(const char *name, lldb::SBCommand, SBCommand, AddCommand, (const char *, lldb::SBCommandPluginInterface *, const char *), name, impl, help); - - if (!IsValid()) - return LLDB_RECORD_RESULT(lldb::SBCommand()); - if (!m_opaque_sp->IsMultiwordObject()) - return LLDB_RECORD_RESULT(lldb::SBCommand()); - lldb::CommandObjectSP new_command_sp; - new_command_sp = std::make_shared( - m_opaque_sp->GetCommandInterpreter(), name, impl, help); - if (new_command_sp && m_opaque_sp->LoadSubCommand(name, new_command_sp)) - return LLDB_RECORD_RESULT(lldb::SBCommand(new_command_sp)); - return LLDB_RECORD_RESULT(lldb::SBCommand()); + return LLDB_RECORD_RESULT(AddCommand(name, impl, help, /*syntax=*/nullptr, + /*auto_repeat_command=*/"")) } lldb::SBCommand SBCommand::AddCommand(const char *name, @@ -803,6 +704,18 @@ lldb::SBCommand SBCommand::AddCommand(const char *name, (const char *, lldb::SBCommandPluginInterface *, const char *, const char *), name, impl, help, syntax); + return LLDB_RECORD_RESULT( + AddCommand(name, impl, help, syntax, /*auto_repeat_command=*/"")) +} + +lldb::SBCommand SBCommand::AddCommand(const char *name, + lldb::SBCommandPluginInterface *impl, + const char *help, const char *syntax, + const char *auto_repeat_command) { + LLDB_RECORD_METHOD(lldb::SBCommand, SBCommand, AddCommand, + (const char *, lldb::SBCommandPluginInterface *, + const char *, const char *, const char *), + name, impl, help, syntax, auto_repeat_command); if (!IsValid()) return LLDB_RECORD_RESULT(lldb::SBCommand()); @@ -810,7 +723,8 @@ lldb::SBCommand SBCommand::AddCommand(const char *name, return LLDB_RECORD_RESULT(lldb::SBCommand()); lldb::CommandObjectSP new_command_sp; new_command_sp = std::make_shared( - m_opaque_sp->GetCommandInterpreter(), name, impl, help, syntax); + m_opaque_sp->GetCommandInterpreter(), name, impl, help, syntax, + /*flags=*/0, auto_repeat_command); if (new_command_sp && m_opaque_sp->LoadSubCommand(name, new_command_sp)) return LLDB_RECORD_RESULT(lldb::SBCommand(new_command_sp)); return LLDB_RECORD_RESULT(lldb::SBCommand()); @@ -832,37 +746,7 @@ void SBCommand::SetFlags(uint32_t flags) { namespace lldb_private { namespace repro { -template <> -void RegisterMethods(Registry &R) { - LLDB_REGISTER_CONSTRUCTOR(SBCommandInterpreterRunOptions, ()); - LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions, - GetStopOnContinue, ()); - LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, - SetStopOnContinue, (bool)); - LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions, - GetStopOnError, ()); - LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetStopOnError, - (bool)); - LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions, - GetStopOnCrash, ()); - LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetStopOnCrash, - (bool)); - LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions, - GetEchoCommands, ()); - LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetEchoCommands, - (bool)); - LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions, - GetEchoCommentCommands, ()); - LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, - SetEchoCommentCommands, (bool)); - LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions, - GetPrintResults, ()); - LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetPrintResults, - (bool)); - LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions, - GetAddToHistory, ()); - LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetAddToHistory, - (bool)); +template <> void RegisterMethods(Registry &R) { LLDB_REGISTER_CONSTRUCTOR(SBCommandInterpreter, (lldb_private::CommandInterpreter *)); LLDB_REGISTER_CONSTRUCTOR(SBCommandInterpreter, @@ -946,6 +830,9 @@ void RegisterMethods(Registry &R) { LLDB_REGISTER_METHOD(lldb::SBCommand, SBCommandInterpreter, AddCommand, (const char *, lldb::SBCommandPluginInterface *, const char *, const char *)); + LLDB_REGISTER_METHOD(lldb::SBCommand, SBCommandInterpreter, AddCommand, + (const char *, lldb::SBCommandPluginInterface *, + const char *, const char *, const char *)); LLDB_REGISTER_CONSTRUCTOR(SBCommand, ()); LLDB_REGISTER_METHOD(bool, SBCommand, IsValid, ()); LLDB_REGISTER_METHOD_CONST(bool, SBCommand, operator bool, ()); @@ -962,9 +849,11 @@ void RegisterMethods(Registry &R) { LLDB_REGISTER_METHOD(lldb::SBCommand, SBCommand, AddCommand, (const char *, lldb::SBCommandPluginInterface *, const char *, const char *)); + LLDB_REGISTER_METHOD(lldb::SBCommand, SBCommand, AddCommand, + (const char *, lldb::SBCommandPluginInterface *, + const char *, const char *, const char *)); LLDB_REGISTER_METHOD(uint32_t, SBCommand, GetFlags, ()); LLDB_REGISTER_METHOD(void, SBCommand, SetFlags, (uint32_t)); } - } } diff --git a/gnu/llvm/lldb/source/API/SBCommandInterpreterRunOptions.cpp b/gnu/llvm/lldb/source/API/SBCommandInterpreterRunOptions.cpp new file mode 100644 index 00000000000..fcfbf5e5401 --- /dev/null +++ b/gnu/llvm/lldb/source/API/SBCommandInterpreterRunOptions.cpp @@ -0,0 +1,272 @@ +//===-- SBCommandInterpreterRunOptions.cpp --------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/lldb-types.h" + +#include "SBReproducerPrivate.h" + +#include "lldb/API/SBCommandInterpreterRunOptions.h" +#include "lldb/Interpreter/CommandInterpreter.h" + +#include + +using namespace lldb; +using namespace lldb_private; + +SBCommandInterpreterRunOptions::SBCommandInterpreterRunOptions() { + LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBCommandInterpreterRunOptions); + + m_opaque_up = std::make_unique(); +} + +SBCommandInterpreterRunOptions::~SBCommandInterpreterRunOptions() = default; + +bool SBCommandInterpreterRunOptions::GetStopOnContinue() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions, + GetStopOnContinue); + + return m_opaque_up->GetStopOnContinue(); +} + +void SBCommandInterpreterRunOptions::SetStopOnContinue(bool stop_on_continue) { + LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetStopOnContinue, + (bool), stop_on_continue); + + m_opaque_up->SetStopOnContinue(stop_on_continue); +} + +bool SBCommandInterpreterRunOptions::GetStopOnError() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions, + GetStopOnError); + + return m_opaque_up->GetStopOnError(); +} + +void SBCommandInterpreterRunOptions::SetStopOnError(bool stop_on_error) { + LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetStopOnError, + (bool), stop_on_error); + + m_opaque_up->SetStopOnError(stop_on_error); +} + +bool SBCommandInterpreterRunOptions::GetStopOnCrash() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions, + GetStopOnCrash); + + return m_opaque_up->GetStopOnCrash(); +} + +void SBCommandInterpreterRunOptions::SetStopOnCrash(bool stop_on_crash) { + LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetStopOnCrash, + (bool), stop_on_crash); + + m_opaque_up->SetStopOnCrash(stop_on_crash); +} + +bool SBCommandInterpreterRunOptions::GetEchoCommands() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions, + GetEchoCommands); + + return m_opaque_up->GetEchoCommands(); +} + +void SBCommandInterpreterRunOptions::SetEchoCommands(bool echo_commands) { + LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetEchoCommands, + (bool), echo_commands); + + m_opaque_up->SetEchoCommands(echo_commands); +} + +bool SBCommandInterpreterRunOptions::GetEchoCommentCommands() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions, + GetEchoCommentCommands); + + return m_opaque_up->GetEchoCommentCommands(); +} + +void SBCommandInterpreterRunOptions::SetEchoCommentCommands(bool echo) { + LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, + SetEchoCommentCommands, (bool), echo); + + m_opaque_up->SetEchoCommentCommands(echo); +} + +bool SBCommandInterpreterRunOptions::GetPrintResults() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions, + GetPrintResults); + + return m_opaque_up->GetPrintResults(); +} + +void SBCommandInterpreterRunOptions::SetPrintResults(bool print_results) { + LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetPrintResults, + (bool), print_results); + + m_opaque_up->SetPrintResults(print_results); +} + +bool SBCommandInterpreterRunOptions::GetAddToHistory() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions, + GetAddToHistory); + + return m_opaque_up->GetAddToHistory(); +} + +void SBCommandInterpreterRunOptions::SetAddToHistory(bool add_to_history) { + LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetAddToHistory, + (bool), add_to_history); + + m_opaque_up->SetAddToHistory(add_to_history); +} + +bool SBCommandInterpreterRunOptions::GetAutoHandleEvents() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions, + GetAutoHandleEvents); + + return m_opaque_up->GetAutoHandleEvents(); +} + +void SBCommandInterpreterRunOptions::SetAutoHandleEvents( + bool auto_handle_events) { + LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetAutoHandleEvents, + (bool), auto_handle_events); + + m_opaque_up->SetAutoHandleEvents(auto_handle_events); +} + +bool SBCommandInterpreterRunOptions::GetSpawnThread() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions, + GetSpawnThread); + + return m_opaque_up->GetSpawnThread(); +} + +void SBCommandInterpreterRunOptions::SetSpawnThread(bool spawn_thread) { + LLDB_RECORD_METHOD(void, SBCommandInterpreterRunOptions, SetSpawnThread, + (bool), spawn_thread); + + m_opaque_up->SetSpawnThread(spawn_thread); +} + +lldb_private::CommandInterpreterRunOptions * +SBCommandInterpreterRunOptions::get() const { + return m_opaque_up.get(); +} + +lldb_private::CommandInterpreterRunOptions & +SBCommandInterpreterRunOptions::ref() const { + return *m_opaque_up; +} + +SBCommandInterpreterRunResult::SBCommandInterpreterRunResult() + : m_opaque_up(new CommandInterpreterRunResult()) + +{ + LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBCommandInterpreterRunResult); +} + +SBCommandInterpreterRunResult::SBCommandInterpreterRunResult( + const SBCommandInterpreterRunResult &rhs) + : m_opaque_up(new CommandInterpreterRunResult()) { + LLDB_RECORD_CONSTRUCTOR(SBCommandInterpreterRunResult, + (const lldb::SBCommandInterpreterRunResult &), rhs); + + *m_opaque_up = *rhs.m_opaque_up; +} + +SBCommandInterpreterRunResult::SBCommandInterpreterRunResult( + const CommandInterpreterRunResult &rhs) + : m_opaque_up() { + m_opaque_up = std::make_unique(rhs); +} + +SBCommandInterpreterRunResult::~SBCommandInterpreterRunResult() = default; + +SBCommandInterpreterRunResult &SBCommandInterpreterRunResult::operator=( + const SBCommandInterpreterRunResult &rhs) { + LLDB_RECORD_METHOD(lldb::SBCommandInterpreterRunResult &, + SBCommandInterpreterRunResult, + operator=,(const lldb::SBCommandInterpreterRunResult &), + rhs); + + if (this == &rhs) + return *this; + *m_opaque_up = *rhs.m_opaque_up; + return LLDB_RECORD_RESULT(*this); +} + +int SBCommandInterpreterRunResult::GetNumberOfErrors() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(int, SBCommandInterpreterRunResult, + GetNumberOfErrors); + + return m_opaque_up->GetNumErrors(); +} + +lldb::CommandInterpreterResult +SBCommandInterpreterRunResult::GetResult() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::CommandInterpreterResult, + SBCommandInterpreterRunResult, GetResult); + + return m_opaque_up->GetResult(); +} + +namespace lldb_private { +namespace repro { + +template <> void RegisterMethods(Registry &R) { + LLDB_REGISTER_CONSTRUCTOR(SBCommandInterpreterRunOptions, ()); + LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions, + GetStopOnContinue, ()); + LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetStopOnContinue, + (bool)); + LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions, + GetStopOnError, ()); + LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetStopOnError, + (bool)); + LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions, + GetStopOnCrash, ()); + LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetStopOnCrash, + (bool)); + LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions, + GetEchoCommands, ()); + LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetEchoCommands, + (bool)); + LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions, + GetEchoCommentCommands, ()); + LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, + SetEchoCommentCommands, (bool)); + LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions, + GetPrintResults, ()); + LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetPrintResults, + (bool)); + LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions, + GetAddToHistory, ()); + LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetAddToHistory, + (bool)); + LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions, + GetAutoHandleEvents, ()); + LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, + SetAutoHandleEvents, (bool)); + LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions, + GetSpawnThread, ()); + LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetSpawnThread, + (bool)); + LLDB_REGISTER_CONSTRUCTOR(SBCommandInterpreterRunResult, ()); + LLDB_REGISTER_CONSTRUCTOR(SBCommandInterpreterRunResult, + (const lldb::SBCommandInterpreterRunResult &)); + LLDB_REGISTER_METHOD(lldb::SBCommandInterpreterRunResult &, + SBCommandInterpreterRunResult, + operator=,(const lldb::SBCommandInterpreterRunResult &)); + LLDB_REGISTER_METHOD_CONST(int, SBCommandInterpreterRunResult, + GetNumberOfErrors, ()); + LLDB_REGISTER_METHOD_CONST(lldb::CommandInterpreterResult, + SBCommandInterpreterRunResult, GetResult, ()); +} + +} // namespace repro +} // namespace lldb_private diff --git a/gnu/llvm/lldb/source/API/SBCommandReturnObject.cpp b/gnu/llvm/lldb/source/API/SBCommandReturnObject.cpp index eec1383df87..fddf90b6648 100644 --- a/gnu/llvm/lldb/source/API/SBCommandReturnObject.cpp +++ b/gnu/llvm/lldb/source/API/SBCommandReturnObject.cpp @@ -1,4 +1,4 @@ -//===-- SBCommandReturnObject.cpp -------------------------------*- C++ -*-===// +//===-- SBCommandReturnObject.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -22,7 +22,7 @@ using namespace lldb_private; class lldb_private::SBCommandReturnObjectImpl { public: SBCommandReturnObjectImpl() - : m_ptr(new CommandReturnObject()), m_owned(true) {} + : m_ptr(new CommandReturnObject(false)), m_owned(true) {} SBCommandReturnObjectImpl(CommandReturnObject &ref) : m_ptr(&ref), m_owned(false) {} SBCommandReturnObjectImpl(const SBCommandReturnObjectImpl &rhs) diff --git a/gnu/llvm/lldb/source/API/SBCommunication.cpp b/gnu/llvm/lldb/source/API/SBCommunication.cpp index 90df70bde72..d55ecd35b55 100644 --- a/gnu/llvm/lldb/source/API/SBCommunication.cpp +++ b/gnu/llvm/lldb/source/API/SBCommunication.cpp @@ -1,4 +1,4 @@ -//===-- SBCommunication.cpp -------------------------------------*- C++ -*-===// +//===-- SBCommunication.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -63,7 +63,7 @@ ConnectionStatus SBCommunication::Connect(const char *url) { if (m_opaque) { if (!m_opaque->HasConnection()) - m_opaque->SetConnection(Host::CreateDefaultConnection(url).release()); + m_opaque->SetConnection(Host::CreateDefaultConnection(url)); return m_opaque->Connect(url, nullptr); } return eConnectionStatusNoConnection; @@ -79,7 +79,8 @@ ConnectionStatus SBCommunication::AdoptFileDesriptor(int fd, bool owns_fd) { if (m_opaque->IsConnected()) m_opaque->Disconnect(); } - m_opaque->SetConnection(new ConnectionFileDescriptor(fd, owns_fd)); + m_opaque->SetConnection( + std::make_unique(fd, owns_fd)); if (m_opaque->IsConnected()) status = eConnectionStatusSuccess; else diff --git a/gnu/llvm/lldb/source/API/SBCompileUnit.cpp b/gnu/llvm/lldb/source/API/SBCompileUnit.cpp index d52040d850a..765957d680c 100644 --- a/gnu/llvm/lldb/source/API/SBCompileUnit.cpp +++ b/gnu/llvm/lldb/source/API/SBCompileUnit.cpp @@ -1,4 +1,4 @@ -//===-- SBCompileUnit.cpp ---------------------------------------*- C++ -*-===// +//===-- SBCompileUnit.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/API/SBData.cpp b/gnu/llvm/lldb/source/API/SBData.cpp index 528cd8d43ec..daf313ad55c 100644 --- a/gnu/llvm/lldb/source/API/SBData.cpp +++ b/gnu/llvm/lldb/source/API/SBData.cpp @@ -1,4 +1,4 @@ -//===-- SBData.cpp ----------------------------------------------*- C++ -*-===// +//===-- SBData.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -41,7 +41,7 @@ const SBData &SBData::operator=(const SBData &rhs) { return LLDB_RECORD_RESULT(*this); } -SBData::~SBData() {} +SBData::~SBData() = default; void SBData::SetOpaque(const lldb::DataExtractorSP &data_sp) { m_opaque_sp = data_sp; diff --git a/gnu/llvm/lldb/source/API/SBDebugger.cpp b/gnu/llvm/lldb/source/API/SBDebugger.cpp index b7ac8047f8e..5f62987f37d 100644 --- a/gnu/llvm/lldb/source/API/SBDebugger.cpp +++ b/gnu/llvm/lldb/source/API/SBDebugger.cpp @@ -1,4 +1,4 @@ -//===-- SBDebugger.cpp ------------------------------------------*- C++ -*-===// +//===-- SBDebugger.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -15,6 +15,7 @@ #include "lldb/API/SBBroadcaster.h" #include "lldb/API/SBCommandInterpreter.h" +#include "lldb/API/SBCommandInterpreterRunOptions.h" #include "lldb/API/SBCommandReturnObject.h" #include "lldb/API/SBError.h" #include "lldb/API/SBEvent.h" @@ -312,7 +313,7 @@ SBError SBDebugger::SetInputFile(SBFile file) { repro::DataRecorder *recorder = nullptr; if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) - recorder = g->GetOrCreate().GetNewDataRecorder(); + recorder = g->GetOrCreate().GetNewRecorder(); FileSP file_sp = file.m_opaque_sp; @@ -596,8 +597,9 @@ SBSourceManager SBDebugger::GetSourceManager() { } bool SBDebugger::GetDefaultArchitecture(char *arch_name, size_t arch_name_len) { - LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, GetDefaultArchitecture, - (char *, size_t), "", arch_name_len); + LLDB_RECORD_CHAR_PTR_STATIC_METHOD(bool, SBDebugger, GetDefaultArchitecture, + (char *, size_t), arch_name, "", + arch_name_len); if (arch_name && arch_name_len) { ArchSpec default_arch = Target::GetDefaultArchitecture(); @@ -1165,9 +1167,9 @@ void SBDebugger::RunCommandInterpreter(bool auto_handle_events, if (m_opaque_sp) { CommandInterpreterRunOptions options; - - m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter( - auto_handle_events, spawn_thread, options); + options.SetAutoHandleEvents(auto_handle_events); + options.SetSpawnThread(spawn_thread); + m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter(options); } } @@ -1185,15 +1187,35 @@ void SBDebugger::RunCommandInterpreter(bool auto_handle_events, quit_requested, stopped_for_crash); if (m_opaque_sp) { + options.SetAutoHandleEvents(auto_handle_events); + options.SetSpawnThread(spawn_thread); CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter(); - interp.RunCommandInterpreter(auto_handle_events, spawn_thread, - options.ref()); - num_errors = interp.GetNumErrors(); - quit_requested = interp.GetQuitRequested(); - stopped_for_crash = interp.GetStoppedForCrash(); + CommandInterpreterRunResult result = + interp.RunCommandInterpreter(options.ref()); + num_errors = result.GetNumErrors(); + quit_requested = + result.IsResult(lldb::eCommandInterpreterResultQuitRequested); + stopped_for_crash = + result.IsResult(lldb::eCommandInterpreterResultInferiorCrash); } } +SBCommandInterpreterRunResult SBDebugger::RunCommandInterpreter( + const SBCommandInterpreterRunOptions &options) { + LLDB_RECORD_METHOD(lldb::SBCommandInterpreterRunResult, SBDebugger, + RunCommandInterpreter, + (const lldb::SBCommandInterpreterRunOptions &), options); + + if (!m_opaque_sp) + return LLDB_RECORD_RESULT(SBCommandInterpreterRunResult()); + + CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter(); + CommandInterpreterRunResult result = + interp.RunCommandInterpreter(options.ref()); + + return LLDB_RECORD_RESULT(SBCommandInterpreterRunResult(result)); +} + SBError SBDebugger::RunREPL(lldb::LanguageType language, const char *repl_options) { LLDB_RECORD_METHOD(lldb::SBError, SBDebugger, RunREPL, @@ -1282,7 +1304,7 @@ SBDebugger::GetInternalVariableValue(const char *var_name, if (value_sp) { StreamString value_strm; value_sp->DumpValue(&exe_ctx, value_strm, OptionValue::eDumpOptionValue); - const std::string &value_str = value_strm.GetString(); + const std::string &value_str = std::string(value_strm.GetString()); if (!value_str.empty()) { StringList string_list; string_list.SplitIntoLines(value_str); @@ -1374,6 +1396,18 @@ bool SBDebugger::GetUseColor() const { return (m_opaque_sp ? m_opaque_sp->GetUseColor() : false); } +bool SBDebugger::SetUseSourceCache(bool value) { + LLDB_RECORD_METHOD(bool, SBDebugger, SetUseSourceCache, (bool), value); + + return (m_opaque_sp ? m_opaque_sp->SetUseSourceCache(value) : false); +} + +bool SBDebugger::GetUseSourceCache() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, GetUseSourceCache); + + return (m_opaque_sp ? m_opaque_sp->GetUseSourceCache() : false); +} + bool SBDebugger::GetDescription(SBStream &description) { LLDB_RECORD_METHOD(bool, SBDebugger, GetDescription, (lldb::SBStream &), description); @@ -1627,46 +1661,38 @@ static SBError SetFileRedirect(SBDebugger *, SBFile file) { return SBError(); } static SBError SetFileRedirect(SBDebugger *, FileSP file) { return SBError(); } -static bool GetDefaultArchitectureRedirect(char *arch_name, - size_t arch_name_len) { - // The function is writing to its argument. Without the redirect it would - // write into the replay buffer. - char buffer[1024]; - return SBDebugger::GetDefaultArchitecture(buffer, arch_name_len); -} - template <> void RegisterMethods(Registry &R) { // Custom implementation. - R.Register(&invoke::method<&SBDebugger::SetErrorFileHandle>::doit, + R.Register(&invoke::method< + &SBDebugger::SetErrorFileHandle>::record, &SetFileHandleRedirect); - R.Register(&invoke::method<&SBDebugger::SetOutputFileHandle>::doit, + R.Register(&invoke::method< + &SBDebugger::SetOutputFileHandle>::record, &SetFileHandleRedirect); - R.Register(static_cast( - &SBDebugger::GetDefaultArchitecture), - &GetDefaultArchitectureRedirect); R.Register(&invoke::method<&SBDebugger::SetInputFile>::doit, + SBFile)>::method<&SBDebugger::SetInputFile>::record, &SetFileRedirect); R.Register(&invoke::method<&SBDebugger::SetOutputFile>::doit, + SBFile)>::method<&SBDebugger::SetOutputFile>::record, &SetFileRedirect); R.Register(&invoke::method<&SBDebugger::SetErrorFile>::doit, + SBFile)>::method<&SBDebugger::SetErrorFile>::record, &SetFileRedirect); R.Register(&invoke::method<&SBDebugger::SetInputFile>::doit, + FileSP)>::method<&SBDebugger::SetInputFile>::record, &SetFileRedirect); R.Register(&invoke::method<&SBDebugger::SetOutputFile>::doit, + FileSP)>::method<&SBDebugger::SetOutputFile>::record, &SetFileRedirect); R.Register(&invoke::method<&SBDebugger::SetErrorFile>::doit, + FileSP)>::method<&SBDebugger::SetErrorFile>::record, &SetFileRedirect); + LLDB_REGISTER_CHAR_PTR_METHOD_STATIC(bool, SBDebugger, + GetDefaultArchitecture); + LLDB_REGISTER_CONSTRUCTOR(SBDebugger, ()); LLDB_REGISTER_CONSTRUCTOR(SBDebugger, (const lldb::DebuggerSP &)); LLDB_REGISTER_CONSTRUCTOR(SBDebugger, (const lldb::SBDebugger &)); @@ -1816,6 +1842,9 @@ template <> void RegisterMethods(Registry &R) { (lldb::SBTypeNameSpecifier)); LLDB_REGISTER_METHOD(bool, SBDebugger, EnableLog, (const char *, const char **)); + LLDB_REGISTER_METHOD(lldb::SBCommandInterpreterRunResult, SBDebugger, + RunCommandInterpreter, + (const lldb::SBCommandInterpreterRunOptions &)); } } // namespace repro diff --git a/gnu/llvm/lldb/source/API/SBDeclaration.cpp b/gnu/llvm/lldb/source/API/SBDeclaration.cpp index 50db1770c61..f1066d63c06 100644 --- a/gnu/llvm/lldb/source/API/SBDeclaration.cpp +++ b/gnu/llvm/lldb/source/API/SBDeclaration.cpp @@ -1,4 +1,4 @@ -//===-- SBDeclaration.cpp ----------------------------------------*- C++-*-===// +//===-- SBDeclaration.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -50,7 +50,7 @@ void SBDeclaration::SetDeclaration( ref() = lldb_object_ref; } -SBDeclaration::~SBDeclaration() {} +SBDeclaration::~SBDeclaration() = default; bool SBDeclaration::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDeclaration, IsValid); @@ -148,7 +148,7 @@ const lldb_private::Declaration *SBDeclaration::operator->() const { lldb_private::Declaration &SBDeclaration::ref() { if (m_opaque_up == nullptr) - m_opaque_up.reset(new lldb_private::Declaration()); + m_opaque_up = std::make_unique(); return *m_opaque_up; } diff --git a/gnu/llvm/lldb/source/API/SBEnvironment.cpp b/gnu/llvm/lldb/source/API/SBEnvironment.cpp new file mode 100644 index 00000000000..d4de89c3256 --- /dev/null +++ b/gnu/llvm/lldb/source/API/SBEnvironment.cpp @@ -0,0 +1,155 @@ +//===-- SBEnvironment.cpp -------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/API/SBEnvironment.h" +#include "SBReproducerPrivate.h" +#include "Utils.h" +#include "lldb/API/SBStringList.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Environment.h" + +using namespace lldb; +using namespace lldb_private; + +SBEnvironment::SBEnvironment() : m_opaque_up(new Environment()) { + LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBEnvironment); +} + +SBEnvironment::SBEnvironment(const SBEnvironment &rhs) + : m_opaque_up(clone(rhs.m_opaque_up)) { + LLDB_RECORD_CONSTRUCTOR(SBEnvironment, (const lldb::SBEnvironment &), rhs); +} + +SBEnvironment::SBEnvironment(Environment rhs) + : m_opaque_up(new Environment(std::move(rhs))) {} + +SBEnvironment::~SBEnvironment() = default; + +const SBEnvironment &SBEnvironment::operator=(const SBEnvironment &rhs) { + LLDB_RECORD_METHOD(const lldb::SBEnvironment &, + SBEnvironment, operator=,(const lldb::SBEnvironment &), + rhs); + + if (this != &rhs) + m_opaque_up = clone(rhs.m_opaque_up); + return LLDB_RECORD_RESULT(*this); +} + +size_t SBEnvironment::GetNumValues() { + LLDB_RECORD_METHOD_NO_ARGS(size_t, SBEnvironment, GetNumValues); + + return m_opaque_up->size(); +} + +const char *SBEnvironment::Get(const char *name) { + LLDB_RECORD_METHOD(const char *, SBEnvironment, Get, (const char *), name); + + auto entry = m_opaque_up->find(name); + if (entry == m_opaque_up->end()) { + return nullptr; + } + return ConstString(entry->second).AsCString(""); +} + +const char *SBEnvironment::GetNameAtIndex(size_t index) { + LLDB_RECORD_METHOD(const char *, SBEnvironment, GetNameAtIndex, (size_t), + index); + + if (index >= GetNumValues()) + return nullptr; + return ConstString(std::next(m_opaque_up->begin(), index)->first()) + .AsCString(""); +} + +const char *SBEnvironment::GetValueAtIndex(size_t index) { + LLDB_RECORD_METHOD(const char *, SBEnvironment, GetValueAtIndex, (size_t), + index); + + if (index >= GetNumValues()) + return nullptr; + return ConstString(std::next(m_opaque_up->begin(), index)->second) + .AsCString(""); +} + +bool SBEnvironment::Set(const char *name, const char *value, bool overwrite) { + LLDB_RECORD_METHOD(bool, SBEnvironment, Set, + (const char *, const char *, bool), name, value, + overwrite); + + if (overwrite) { + m_opaque_up->insert_or_assign(name, std::string(value)); + return true; + } + return m_opaque_up->try_emplace(name, std::string(value)).second; +} + +bool SBEnvironment::Unset(const char *name) { + LLDB_RECORD_METHOD(bool, SBEnvironment, Unset, (const char *), name); + + return m_opaque_up->erase(name); +} + +SBStringList SBEnvironment::GetEntries() { + LLDB_RECORD_METHOD_NO_ARGS(lldb::SBStringList, SBEnvironment, GetEntries); + + SBStringList entries; + for (const auto &KV : *m_opaque_up) { + entries.AppendString(Environment::compose(KV).c_str()); + } + return LLDB_RECORD_RESULT(entries); +} + +void SBEnvironment::PutEntry(const char *name_and_value) { + LLDB_RECORD_METHOD(void, SBEnvironment, PutEntry, (const char *), + name_and_value); + + auto split = llvm::StringRef(name_and_value).split('='); + m_opaque_up->insert_or_assign(split.first.str(), split.second.str()); +} + +void SBEnvironment::SetEntries(const SBStringList &entries, bool append) { + LLDB_RECORD_METHOD(void, SBEnvironment, SetEntries, + (const lldb::SBStringList &, bool), entries, append); + + if (!append) + m_opaque_up->clear(); + for (size_t i = 0; i < entries.GetSize(); i++) { + PutEntry(entries.GetStringAtIndex(i)); + } +} + +void SBEnvironment::Clear() { + LLDB_RECORD_METHOD_NO_ARGS(void, SBEnvironment, Clear); + + m_opaque_up->clear(); +} + +Environment &SBEnvironment::ref() const { return *m_opaque_up; } + +namespace lldb_private { +namespace repro { +template <> void RegisterMethods(Registry &R) { + LLDB_REGISTER_CONSTRUCTOR(SBEnvironment, ()); + LLDB_REGISTER_CONSTRUCTOR(SBEnvironment, (const lldb::SBEnvironment &)); + LLDB_REGISTER_METHOD(const lldb::SBEnvironment &, + SBEnvironment, operator=,(const lldb::SBEnvironment &)); + LLDB_REGISTER_METHOD(size_t, SBEnvironment, GetNumValues, ()); + LLDB_REGISTER_METHOD(const char *, SBEnvironment, Get, (const char *)); + LLDB_REGISTER_METHOD(const char *, SBEnvironment, GetNameAtIndex, (size_t)); + LLDB_REGISTER_METHOD(const char *, SBEnvironment, GetValueAtIndex, (size_t)); + LLDB_REGISTER_METHOD(bool, SBEnvironment, Set, + (const char *, const char *, bool)); + LLDB_REGISTER_METHOD(bool, SBEnvironment, Unset, (const char *)); + LLDB_REGISTER_METHOD(lldb::SBStringList, SBEnvironment, GetEntries, ()); + LLDB_REGISTER_METHOD(void, SBEnvironment, PutEntry, (const char *)); + LLDB_REGISTER_METHOD(void, SBEnvironment, SetEntries, + (const lldb::SBStringList &, bool)); + LLDB_REGISTER_METHOD(void, SBEnvironment, Clear, ()); +} +} // namespace repro +} // namespace lldb_private diff --git a/gnu/llvm/lldb/source/API/SBError.cpp b/gnu/llvm/lldb/source/API/SBError.cpp index 7256e8e55de..67c7663d358 100644 --- a/gnu/llvm/lldb/source/API/SBError.cpp +++ b/gnu/llvm/lldb/source/API/SBError.cpp @@ -1,4 +1,4 @@ -//===-- SBError.cpp ---------------------------------------------*- C++ -*-===// +//===-- SBError.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,7 +25,7 @@ SBError::SBError(const SBError &rhs) : m_opaque_up() { m_opaque_up = clone(rhs.m_opaque_up); } -SBError::~SBError() {} +SBError::~SBError() = default; const SBError &SBError::operator=(const SBError &rhs) { LLDB_RECORD_METHOD(const lldb::SBError &, @@ -149,7 +149,7 @@ SBError::operator bool() const { void SBError::CreateIfNeeded() { if (m_opaque_up == nullptr) - m_opaque_up.reset(new Status()); + m_opaque_up = std::make_unique(); } lldb_private::Status *SBError::operator->() { return m_opaque_up.get(); } diff --git a/gnu/llvm/lldb/source/API/SBEvent.cpp b/gnu/llvm/lldb/source/API/SBEvent.cpp index fb2ad10ddcf..2776ec49c09 100644 --- a/gnu/llvm/lldb/source/API/SBEvent.cpp +++ b/gnu/llvm/lldb/source/API/SBEvent.cpp @@ -1,4 +1,4 @@ -//===-- SBEvent.cpp ---------------------------------------------*- C++ -*-===// +//===-- SBEvent.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -58,7 +58,7 @@ const SBEvent &SBEvent::operator=(const SBEvent &rhs) { return LLDB_RECORD_RESULT(*this); } -SBEvent::~SBEvent() {} +SBEvent::~SBEvent() = default; const char *SBEvent::GetDataFlavor() { LLDB_RECORD_METHOD_NO_ARGS(const char *, SBEvent, GetDataFlavor); diff --git a/gnu/llvm/lldb/source/API/SBExecutionContext.cpp b/gnu/llvm/lldb/source/API/SBExecutionContext.cpp index 1224c2abe98..caf02b4164e 100644 --- a/gnu/llvm/lldb/source/API/SBExecutionContext.cpp +++ b/gnu/llvm/lldb/source/API/SBExecutionContext.cpp @@ -1,5 +1,4 @@ -//===-- SBExecutionContext.cpp ------------------------------------*- C++ -//-*-===// +//===-- SBExecutionContext.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -66,7 +65,7 @@ SBExecutionContext::SBExecutionContext(const lldb::SBFrame &frame) m_exe_ctx_sp->SetFrameSP(frame.GetFrameSP()); } -SBExecutionContext::~SBExecutionContext() {} +SBExecutionContext::~SBExecutionContext() = default; const SBExecutionContext &SBExecutionContext:: operator=(const lldb::SBExecutionContext &rhs) { diff --git a/gnu/llvm/lldb/source/API/SBExpressionOptions.cpp b/gnu/llvm/lldb/source/API/SBExpressionOptions.cpp index 8c34194abf1..217e8ad5c21 100644 --- a/gnu/llvm/lldb/source/API/SBExpressionOptions.cpp +++ b/gnu/llvm/lldb/source/API/SBExpressionOptions.cpp @@ -1,5 +1,4 @@ -//===-- SBExpressionOptions.cpp ---------------------------------------------*- -//C++ -*-===// +//===-- SBExpressionOptions.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -40,7 +39,7 @@ operator=(const SBExpressionOptions &rhs) { return LLDB_RECORD_RESULT(*this); } -SBExpressionOptions::~SBExpressionOptions() {} +SBExpressionOptions::~SBExpressionOptions() = default; bool SBExpressionOptions::GetCoerceResultToId() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBExpressionOptions, @@ -238,6 +237,20 @@ void SBExpressionOptions::SetAutoApplyFixIts(bool b) { return m_opaque_up->SetAutoApplyFixIts(b); } +uint64_t SBExpressionOptions::GetRetriesWithFixIts() { + LLDB_RECORD_METHOD_NO_ARGS(uint64_t, SBExpressionOptions, + GetRetriesWithFixIts); + + return m_opaque_up->GetRetriesWithFixIts(); +} + +void SBExpressionOptions::SetRetriesWithFixIts(uint64_t retries) { + LLDB_RECORD_METHOD(void, SBExpressionOptions, SetRetriesWithFixIts, + (uint64_t), retries); + + return m_opaque_up->SetRetriesWithFixIts(retries); +} + bool SBExpressionOptions::GetTopLevel() { LLDB_RECORD_METHOD_NO_ARGS(bool, SBExpressionOptions, GetTopLevel); @@ -330,6 +343,9 @@ void RegisterMethods(Registry &R) { LLDB_REGISTER_METHOD(void, SBExpressionOptions, SetTopLevel, (bool)); LLDB_REGISTER_METHOD(bool, SBExpressionOptions, GetAllowJIT, ()); LLDB_REGISTER_METHOD(void, SBExpressionOptions, SetAllowJIT, (bool)); + LLDB_REGISTER_METHOD(uint64_t, SBExpressionOptions, GetRetriesWithFixIts, ()); + LLDB_REGISTER_METHOD(void, SBExpressionOptions, SetRetriesWithFixIts, + (uint64_t)); } } diff --git a/gnu/llvm/lldb/source/API/SBFile.cpp b/gnu/llvm/lldb/source/API/SBFile.cpp index 277402f31ab..41ccdbe76b9 100644 --- a/gnu/llvm/lldb/source/API/SBFile.cpp +++ b/gnu/llvm/lldb/source/API/SBFile.cpp @@ -1,4 +1,4 @@ -//===-- SBFile.cpp ------------------------------------------*- C++ -*-===// +//===-- SBFile.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -14,22 +14,39 @@ using namespace lldb; using namespace lldb_private; -SBFile::~SBFile() {} +SBFile::~SBFile() = default; SBFile::SBFile(FileSP file_sp) : m_opaque_sp(file_sp) { - LLDB_RECORD_DUMMY(void, SBfile, SBFile, (FileSP), file_sp); + // We have no way to capture the incoming FileSP as the class isn't + // instrumented, so pretend that it's always null. + LLDB_RECORD_CONSTRUCTOR(SBFile, (lldb::FileSP), nullptr); +} + +SBFile::SBFile(const SBFile &rhs) : m_opaque_sp(rhs.m_opaque_sp) { + LLDB_RECORD_CONSTRUCTOR(SBFile, (const lldb::SBFile&), rhs); +} + +SBFile &SBFile ::operator=(const SBFile &rhs) { + LLDB_RECORD_METHOD(lldb::SBFile &, + SBFile, operator=,(const lldb::SBFile &), rhs); + + if (this != &rhs) + m_opaque_sp = rhs.m_opaque_sp; + return LLDB_RECORD_RESULT(*this); } SBFile::SBFile() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBFile); } SBFile::SBFile(FILE *file, bool transfer_ownership) { - LLDB_RECORD_DUMMY(void, SBFile, (FILE *, bool), file, transfer_ownership); + LLDB_RECORD_CONSTRUCTOR(SBFile, (FILE *, bool), file, transfer_ownership); + m_opaque_sp = std::make_shared(file, transfer_ownership); } SBFile::SBFile(int fd, const char *mode, bool transfer_owndership) { - LLDB_RECORD_DUMMY(void, SBFile, (int, const char *, bool), fd, mode, - transfer_owndership); + LLDB_RECORD_CONSTRUCTOR(SBFile, (int, const char *, bool), fd, mode, + transfer_owndership); + auto options = File::GetOptionsFromMode(mode); if (!options) { llvm::consumeError(options.takeError()); @@ -40,8 +57,9 @@ SBFile::SBFile(int fd, const char *mode, bool transfer_owndership) { } SBError SBFile::Read(uint8_t *buf, size_t num_bytes, size_t *bytes_read) { - LLDB_RECORD_DUMMY(lldb::SBError, SBFile, Read, (uint8_t *, size_t, size_t *), - buf, num_bytes, bytes_read); + LLDB_RECORD_METHOD(lldb::SBError, SBFile, Read, (uint8_t *, size_t, size_t *), + buf, num_bytes, bytes_read); + SBError error; if (!m_opaque_sp) { error.SetErrorString("invalid SBFile"); @@ -56,9 +74,10 @@ SBError SBFile::Read(uint8_t *buf, size_t num_bytes, size_t *bytes_read) { SBError SBFile::Write(const uint8_t *buf, size_t num_bytes, size_t *bytes_written) { - LLDB_RECORD_DUMMY(lldb::SBError, SBFile, Write, - (const uint8_t *, size_t, size_t *), buf, num_bytes, - bytes_written); + LLDB_RECORD_METHOD(lldb::SBError, SBFile, Write, + (const uint8_t *, size_t, size_t *), buf, num_bytes, + bytes_written); + SBError error; if (!m_opaque_sp) { error.SetErrorString("invalid SBFile"); @@ -73,6 +92,7 @@ SBError SBFile::Write(const uint8_t *buf, size_t num_bytes, SBError SBFile::Flush() { LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBFile, Flush); + SBError error; if (!m_opaque_sp) { error.SetErrorString("invalid SBFile"); @@ -119,9 +139,15 @@ namespace repro { template <> void RegisterMethods(Registry &R) { LLDB_REGISTER_CONSTRUCTOR(SBFile, ()); LLDB_REGISTER_CONSTRUCTOR(SBFile, (FileSP)); + LLDB_REGISTER_CONSTRUCTOR(SBFile, (const SBFile&)); LLDB_REGISTER_CONSTRUCTOR(SBFile, (FILE *, bool)); LLDB_REGISTER_CONSTRUCTOR(SBFile, (int, const char *, bool)); + LLDB_REGISTER_METHOD(SBFile&, SBFile, operator=,(const SBFile&)); LLDB_REGISTER_METHOD(lldb::SBError, SBFile, Flush, ()); + LLDB_REGISTER_METHOD(lldb::SBError, SBFile, Read, + (uint8_t *, size_t, size_t *)); + LLDB_REGISTER_METHOD(lldb::SBError, SBFile, Write, + (const uint8_t *, size_t, size_t *)); LLDB_REGISTER_METHOD_CONST(bool, SBFile, IsValid, ()); LLDB_REGISTER_METHOD_CONST(bool, SBFile, operator bool,()); LLDB_REGISTER_METHOD_CONST(bool, SBFile, operator!,()); diff --git a/gnu/llvm/lldb/source/API/SBFileSpec.cpp b/gnu/llvm/lldb/source/API/SBFileSpec.cpp index 2e7eba42bc9..7bfb665df4f 100644 --- a/gnu/llvm/lldb/source/API/SBFileSpec.cpp +++ b/gnu/llvm/lldb/source/API/SBFileSpec.cpp @@ -1,4 +1,4 @@ -//===-- SBFileSpec.cpp ------------------------------------------*- C++ -*-===// +//===-- SBFileSpec.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -51,7 +51,7 @@ SBFileSpec::SBFileSpec(const char *path, bool resolve) FileSystem::Instance().Resolve(*m_opaque_up); } -SBFileSpec::~SBFileSpec() {} +SBFileSpec::~SBFileSpec() = default; const SBFileSpec &SBFileSpec::operator=(const SBFileSpec &rhs) { LLDB_RECORD_METHOD(const lldb::SBFileSpec &, @@ -143,8 +143,8 @@ void SBFileSpec::SetDirectory(const char *directory) { } uint32_t SBFileSpec::GetPath(char *dst_path, size_t dst_len) const { - LLDB_RECORD_DUMMY(uint32_t, SBFileSpec, GetPath, (char *, size_t), - dst_path, dst_len); + LLDB_RECORD_CHAR_PTR_METHOD_CONST(uint32_t, SBFileSpec, GetPath, + (char *, size_t), dst_path, "", dst_len); uint32_t result = m_opaque_up->GetPath(dst_path, dst_len); @@ -213,10 +213,10 @@ void RegisterMethods(Registry &R) { LLDB_REGISTER_METHOD_CONST(const char *, SBFileSpec, GetDirectory, ()); LLDB_REGISTER_METHOD(void, SBFileSpec, SetFilename, (const char *)); LLDB_REGISTER_METHOD(void, SBFileSpec, SetDirectory, (const char *)); - LLDB_REGISTER_METHOD_CONST(uint32_t, SBFileSpec, GetPath, (char *, size_t)); LLDB_REGISTER_METHOD_CONST(bool, SBFileSpec, GetDescription, (lldb::SBStream &)); LLDB_REGISTER_METHOD(void, SBFileSpec, AppendPathComponent, (const char *)); + LLDB_REGISTER_CHAR_PTR_METHOD_CONST(uint32_t, SBFileSpec, GetPath); } } diff --git a/gnu/llvm/lldb/source/API/SBFileSpecList.cpp b/gnu/llvm/lldb/source/API/SBFileSpecList.cpp index 3143964b38c..7afa3436327 100644 --- a/gnu/llvm/lldb/source/API/SBFileSpecList.cpp +++ b/gnu/llvm/lldb/source/API/SBFileSpecList.cpp @@ -1,4 +1,4 @@ -//===-- SBFileSpecList.cpp --------------------------------------*- C++ -*-===// +//===-- SBFileSpecList.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -32,7 +32,7 @@ SBFileSpecList::SBFileSpecList(const SBFileSpecList &rhs) : m_opaque_up() { m_opaque_up = clone(rhs.m_opaque_up); } -SBFileSpecList::~SBFileSpecList() {} +SBFileSpecList::~SBFileSpecList() = default; const SBFileSpecList &SBFileSpecList::operator=(const SBFileSpecList &rhs) { LLDB_RECORD_METHOD(const lldb::SBFileSpecList &, diff --git a/gnu/llvm/lldb/source/API/SBFrame.cpp b/gnu/llvm/lldb/source/API/SBFrame.cpp index af42be9ac75..81782dbf838 100644 --- a/gnu/llvm/lldb/source/API/SBFrame.cpp +++ b/gnu/llvm/lldb/source/API/SBFrame.cpp @@ -1,4 +1,4 @@ -//===-- SBFrame.cpp ---------------------------------------------*- C++ -*-===// +//===-- SBFrame.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -354,15 +354,15 @@ bool SBFrame::SetPC(addr_t new_pc) { std::unique_lock lock; ExecutionContext exe_ctx(m_opaque_sp.get(), lock); - StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) { - ret_val = frame->GetRegisterContext()->SetPC(new_pc); + if (StackFrame *frame = exe_ctx.GetFramePtr()) { + if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) { + ret_val = reg_ctx_sp->SetPC(new_pc); + } } } } @@ -377,15 +377,15 @@ addr_t SBFrame::GetSP() const { std::unique_lock lock; ExecutionContext exe_ctx(m_opaque_sp.get(), lock); - StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) { - addr = frame->GetRegisterContext()->GetSP(); + if (StackFrame *frame = exe_ctx.GetFramePtr()) { + if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) { + addr = reg_ctx_sp->GetSP(); + } } } } @@ -400,15 +400,16 @@ addr_t SBFrame::GetFP() const { std::unique_lock lock; ExecutionContext exe_ctx(m_opaque_sp.get(), lock); - StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) - addr = frame->GetRegisterContext()->GetFP(); + if (StackFrame *frame = exe_ctx.GetFramePtr()) { + if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) { + addr = reg_ctx_sp->GetFP(); + } + } } } @@ -1225,8 +1226,7 @@ const char *SBFrame::GetFunctionName() const { if (inlined_block) { const InlineFunctionInfo *inlined_info = inlined_block->GetInlinedFunctionInfo(); - name = - inlined_info->GetName(sc.function->GetLanguage()).AsCString(); + name = inlined_info->GetName().AsCString(); } } @@ -1269,8 +1269,7 @@ const char *SBFrame::GetDisplayFunctionName() { if (inlined_block) { const InlineFunctionInfo *inlined_info = inlined_block->GetInlinedFunctionInfo(); - name = inlined_info->GetDisplayName(sc.function->GetLanguage()) - .AsCString(); + name = inlined_info->GetDisplayName().AsCString(); } } diff --git a/gnu/llvm/lldb/source/API/SBFunction.cpp b/gnu/llvm/lldb/source/API/SBFunction.cpp index 1770bede2f4..e49513bd0da 100644 --- a/gnu/llvm/lldb/source/API/SBFunction.cpp +++ b/gnu/llvm/lldb/source/API/SBFunction.cpp @@ -1,4 +1,4 @@ -//===-- SBFunction.cpp ------------------------------------------*- C++ -*-===// +//===-- SBFunction.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -69,9 +69,7 @@ const char *SBFunction::GetDisplayName() const { const char *cstr = nullptr; if (m_opaque_ptr) - cstr = m_opaque_ptr->GetMangled() - .GetDisplayDemangledName(m_opaque_ptr->GetLanguage()) - .AsCString(); + cstr = m_opaque_ptr->GetMangled().GetDisplayDemangledName().AsCString(); return cstr; } @@ -128,20 +126,15 @@ SBInstructionList SBFunction::GetInstructions(SBTarget target, SBInstructionList sb_instructions; if (m_opaque_ptr) { - ExecutionContext exe_ctx; TargetSP target_sp(target.GetSP()); std::unique_lock lock; - if (target_sp) { - lock = std::unique_lock(target_sp->GetAPIMutex()); - target_sp->CalculateExecutionContext(exe_ctx); - exe_ctx.SetProcessSP(target_sp->GetProcessSP()); - } ModuleSP module_sp( m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule()); - if (module_sp) { + if (target_sp && module_sp) { + lock = std::unique_lock(target_sp->GetAPIMutex()); const bool prefer_file_cache = false; sb_instructions.SetDisassembler(Disassembler::DisassembleRange( - module_sp->GetArchitecture(), nullptr, flavor, exe_ctx, + module_sp->GetArchitecture(), nullptr, flavor, *target_sp, m_opaque_ptr->GetAddressRange(), prefer_file_cache)); } } diff --git a/gnu/llvm/lldb/source/API/SBHostOS.cpp b/gnu/llvm/lldb/source/API/SBHostOS.cpp index 6ac8717237e..9d3d119e4c2 100644 --- a/gnu/llvm/lldb/source/API/SBHostOS.cpp +++ b/gnu/llvm/lldb/source/API/SBHostOS.cpp @@ -1,4 +1,4 @@ -//===-- SBHostOS.cpp --------------------------------------------*- C++ -*-===// +//===-- SBHostOS.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/API/SBInstruction.cpp b/gnu/llvm/lldb/source/API/SBInstruction.cpp index a9ef9fb59d2..207e81272e5 100644 --- a/gnu/llvm/lldb/source/API/SBInstruction.cpp +++ b/gnu/llvm/lldb/source/API/SBInstruction.cpp @@ -1,4 +1,4 @@ -//===-- SBInstruction.cpp ---------------------------------------*- C++ -*-===// +//===-- SBInstruction.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -89,7 +89,7 @@ const SBInstruction &SBInstruction::operator=(const SBInstruction &rhs) { return LLDB_RECORD_RESULT(*this); } -SBInstruction::~SBInstruction() {} +SBInstruction::~SBInstruction() = default; bool SBInstruction::IsValid() { LLDB_RECORD_METHOD_NO_ARGS(bool, SBInstruction, IsValid); diff --git a/gnu/llvm/lldb/source/API/SBInstructionList.cpp b/gnu/llvm/lldb/source/API/SBInstructionList.cpp index 8b3855c0883..a0c6fbe7e33 100644 --- a/gnu/llvm/lldb/source/API/SBInstructionList.cpp +++ b/gnu/llvm/lldb/source/API/SBInstructionList.cpp @@ -1,4 +1,4 @@ -//===-- SBInstructionList.cpp -----------------------------------*- C++ -*-===// +//===-- SBInstructionList.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -42,7 +42,7 @@ operator=(const SBInstructionList &rhs) { return LLDB_RECORD_RESULT(*this); } -SBInstructionList::~SBInstructionList() {} +SBInstructionList::~SBInstructionList() = default; bool SBInstructionList::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBInstructionList, IsValid); diff --git a/gnu/llvm/lldb/source/API/SBLanguageRuntime.cpp b/gnu/llvm/lldb/source/API/SBLanguageRuntime.cpp index 04bd08fb739..33c900d20c3 100644 --- a/gnu/llvm/lldb/source/API/SBLanguageRuntime.cpp +++ b/gnu/llvm/lldb/source/API/SBLanguageRuntime.cpp @@ -1,4 +1,4 @@ -//===-- SBLanguageRuntime.cpp -----------------------------------*- C++ -*-===// +//===-- SBLanguageRuntime.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/API/SBLaunchInfo.cpp b/gnu/llvm/lldb/source/API/SBLaunchInfo.cpp index 5c5e69704c7..ba13072e8f9 100644 --- a/gnu/llvm/lldb/source/API/SBLaunchInfo.cpp +++ b/gnu/llvm/lldb/source/API/SBLaunchInfo.cpp @@ -1,4 +1,4 @@ -//===-- SBLaunchInfo.cpp ----------------------------------------*- C++ -*-===// +//===-- SBLaunchInfo.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,6 +9,7 @@ #include "lldb/API/SBLaunchInfo.h" #include "SBReproducerPrivate.h" +#include "lldb/API/SBEnvironment.h" #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBListener.h" #include "lldb/Host/ProcessLaunchInfo.h" @@ -43,7 +44,21 @@ SBLaunchInfo::SBLaunchInfo(const char **argv) m_opaque_sp->GetArguments().SetArguments(argv); } -SBLaunchInfo::~SBLaunchInfo() {} +SBLaunchInfo::SBLaunchInfo(const SBLaunchInfo &rhs) { + LLDB_RECORD_CONSTRUCTOR(SBLaunchInfo, (const lldb::SBLaunchInfo &), rhs); + + m_opaque_sp = rhs.m_opaque_sp; +} + +SBLaunchInfo &SBLaunchInfo::operator=(const SBLaunchInfo &rhs) { + LLDB_RECORD_METHOD(SBLaunchInfo &, + SBLaunchInfo, operator=,(const lldb::SBLaunchInfo &), rhs); + + m_opaque_sp = rhs.m_opaque_sp; + return LLDB_RECORD_RESULT(*this); +} + +SBLaunchInfo::~SBLaunchInfo() = default; const lldb_private::ProcessLaunchInfo &SBLaunchInfo::ref() const { return *m_opaque_sp; @@ -168,15 +183,26 @@ const char *SBLaunchInfo::GetEnvironmentEntryAtIndex(uint32_t idx) { void SBLaunchInfo::SetEnvironmentEntries(const char **envp, bool append) { LLDB_RECORD_METHOD(void, SBLaunchInfo, SetEnvironmentEntries, (const char **, bool), envp, append); + SetEnvironment(SBEnvironment(Environment(envp)), append); +} - Environment env(envp); +void SBLaunchInfo::SetEnvironment(const SBEnvironment &env, bool append) { + LLDB_RECORD_METHOD(void, SBLaunchInfo, SetEnvironment, + (const lldb::SBEnvironment &, bool), env, append); + Environment &refEnv = env.ref(); if (append) - m_opaque_sp->GetEnvironment().insert(env.begin(), env.end()); + m_opaque_sp->GetEnvironment().insert(refEnv.begin(), refEnv.end()); else - m_opaque_sp->GetEnvironment() = env; + m_opaque_sp->GetEnvironment() = refEnv; m_opaque_sp->RegenerateEnvp(); } +SBEnvironment SBLaunchInfo::GetEnvironment() { + LLDB_RECORD_METHOD_NO_ARGS(lldb::SBEnvironment, SBLaunchInfo, GetEnvironment); + return LLDB_RECORD_RESULT( + SBEnvironment(Environment(m_opaque_sp->GetEnvironment()))); +} + void SBLaunchInfo::Clear() { LLDB_RECORD_METHOD_NO_ARGS(void, SBLaunchInfo, Clear); @@ -322,6 +348,9 @@ namespace repro { template <> void RegisterMethods(Registry &R) { LLDB_REGISTER_CONSTRUCTOR(SBLaunchInfo, (const char **)); + LLDB_REGISTER_CONSTRUCTOR(SBLaunchInfo, (const lldb::SBLaunchInfo &)); + LLDB_REGISTER_METHOD(SBLaunchInfo &, + SBLaunchInfo, operator=,(const lldb::SBLaunchInfo &)); LLDB_REGISTER_METHOD(lldb::pid_t, SBLaunchInfo, GetProcessID, ()); LLDB_REGISTER_METHOD(uint32_t, SBLaunchInfo, GetUserID, ()); LLDB_REGISTER_METHOD(uint32_t, SBLaunchInfo, GetGroupID, ()); @@ -373,6 +402,9 @@ void RegisterMethods(Registry &R) { ()); LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetDetachOnError, (bool)); LLDB_REGISTER_METHOD_CONST(bool, SBLaunchInfo, GetDetachOnError, ()); + LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetEnvironment, + (const lldb::SBEnvironment &, bool)); + LLDB_REGISTER_METHOD(lldb::SBEnvironment, SBLaunchInfo, GetEnvironment, ()); } } diff --git a/gnu/llvm/lldb/source/API/SBLineEntry.cpp b/gnu/llvm/lldb/source/API/SBLineEntry.cpp index 66884f76339..cefbe3ee1a1 100644 --- a/gnu/llvm/lldb/source/API/SBLineEntry.cpp +++ b/gnu/llvm/lldb/source/API/SBLineEntry.cpp @@ -1,4 +1,4 @@ -//===-- SBLineEntry.cpp -----------------------------------------*- C++ -*-===// +//===-- SBLineEntry.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -48,7 +48,7 @@ void SBLineEntry::SetLineEntry(const lldb_private::LineEntry &lldb_object_ref) { m_opaque_up = std::make_unique(lldb_object_ref); } -SBLineEntry::~SBLineEntry() {} +SBLineEntry::~SBLineEntry() = default; SBAddress SBLineEntry::GetStartAddress() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBAddress, SBLineEntry, @@ -163,7 +163,7 @@ const lldb_private::LineEntry *SBLineEntry::operator->() const { lldb_private::LineEntry &SBLineEntry::ref() { if (m_opaque_up == nullptr) - m_opaque_up.reset(new lldb_private::LineEntry()); + m_opaque_up = std::make_unique(); return *m_opaque_up; } diff --git a/gnu/llvm/lldb/source/API/SBListener.cpp b/gnu/llvm/lldb/source/API/SBListener.cpp index 4fe90f6f686..f3463268b3b 100644 --- a/gnu/llvm/lldb/source/API/SBListener.cpp +++ b/gnu/llvm/lldb/source/API/SBListener.cpp @@ -1,4 +1,4 @@ -//===-- SBListener.cpp ------------------------------------------*- C++ -*-===// +//===-- SBListener.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -48,7 +48,7 @@ const lldb::SBListener &SBListener::operator=(const lldb::SBListener &rhs) { SBListener::SBListener(const lldb::ListenerSP &listener_sp) : m_opaque_sp(listener_sp), m_unused_ptr(nullptr) {} -SBListener::~SBListener() {} +SBListener::~SBListener() = default; bool SBListener::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBListener, IsValid); diff --git a/gnu/llvm/lldb/source/API/SBMemoryRegionInfo.cpp b/gnu/llvm/lldb/source/API/SBMemoryRegionInfo.cpp index d25570f51ce..2a28b99c72d 100644 --- a/gnu/llvm/lldb/source/API/SBMemoryRegionInfo.cpp +++ b/gnu/llvm/lldb/source/API/SBMemoryRegionInfo.cpp @@ -1,4 +1,4 @@ -//===-- SBMemoryRegionInfo.cpp ----------------------------------*- C++ -*-===// +//===-- SBMemoryRegionInfo.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -46,7 +46,7 @@ operator=(const SBMemoryRegionInfo &rhs) { return LLDB_RECORD_RESULT(*this); } -SBMemoryRegionInfo::~SBMemoryRegionInfo() {} +SBMemoryRegionInfo::~SBMemoryRegionInfo() = default; void SBMemoryRegionInfo::Clear() { LLDB_RECORD_METHOD_NO_ARGS(void, SBMemoryRegionInfo, Clear); diff --git a/gnu/llvm/lldb/source/API/SBMemoryRegionInfoList.cpp b/gnu/llvm/lldb/source/API/SBMemoryRegionInfoList.cpp index 32a3afb84af..0f3f9c1b817 100644 --- a/gnu/llvm/lldb/source/API/SBMemoryRegionInfoList.cpp +++ b/gnu/llvm/lldb/source/API/SBMemoryRegionInfoList.cpp @@ -1,4 +1,4 @@ -//===-- SBMemoryRegionInfoList.cpp ------------------------------*- C++ -*-===// +//===-- SBMemoryRegionInfoList.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -82,7 +82,7 @@ SBMemoryRegionInfoList::SBMemoryRegionInfoList( (const lldb::SBMemoryRegionInfoList &), rhs); } -SBMemoryRegionInfoList::~SBMemoryRegionInfoList() {} +SBMemoryRegionInfoList::~SBMemoryRegionInfoList() = default; const SBMemoryRegionInfoList &SBMemoryRegionInfoList:: operator=(const SBMemoryRegionInfoList &rhs) { diff --git a/gnu/llvm/lldb/source/API/SBModule.cpp b/gnu/llvm/lldb/source/API/SBModule.cpp index 4e9dfb0c1e6..c30529b37eb 100644 --- a/gnu/llvm/lldb/source/API/SBModule.cpp +++ b/gnu/llvm/lldb/source/API/SBModule.cpp @@ -1,4 +1,4 @@ -//===-- SBModule.cpp --------------------------------------------*- C++ -*-===// +//===-- SBModule.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -75,7 +75,7 @@ const SBModule &SBModule::operator=(const SBModule &rhs) { return LLDB_RECORD_RESULT(*this); } -SBModule::~SBModule() {} +SBModule::~SBModule() = default; bool SBModule::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBModule, IsValid); @@ -401,8 +401,8 @@ lldb::SBSymbolContextList SBModule::FindFunctions(const char *name, const bool symbols_ok = true; const bool inlines_ok = true; FunctionNameType type = static_cast(name_type_mask); - module_sp->FindFunctions(ConstString(name), nullptr, type, symbols_ok, - inlines_ok, *sb_sc_list); + module_sp->FindFunctions(ConstString(name), CompilerDeclContext(), type, + symbols_ok, inlines_ok, *sb_sc_list); } return LLDB_RECORD_RESULT(sb_sc_list); } @@ -417,8 +417,8 @@ SBValueList SBModule::FindGlobalVariables(SBTarget &target, const char *name, ModuleSP module_sp(GetSP()); if (name && module_sp) { VariableList variable_list; - module_sp->FindGlobalVariables(ConstString(name), nullptr, max_matches, - variable_list); + module_sp->FindGlobalVariables(ConstString(name), CompilerDeclContext(), + max_matches, variable_list); for (const VariableSP &var_sp : variable_list) { lldb::ValueObjectSP valobj_sp; TargetSP target_sp(target.GetSP()); @@ -683,6 +683,13 @@ lldb::SBAddress SBModule::GetObjectFileEntryPointAddress() const { return LLDB_RECORD_RESULT(sb_addr); } +uint32_t SBModule::GetNumberAllocatedModules() { + LLDB_RECORD_STATIC_METHOD_NO_ARGS(uint32_t, SBModule, + GetNumberAllocatedModules); + + return Module::GetNumberAllocatedModules(); +} + namespace lldb_private { namespace repro { @@ -757,6 +764,8 @@ void RegisterMethods(Registry &R) { GetObjectFileHeaderAddress, ()); LLDB_REGISTER_METHOD_CONST(lldb::SBAddress, SBModule, GetObjectFileEntryPointAddress, ()); + LLDB_REGISTER_STATIC_METHOD(uint32_t, SBModule, GetNumberAllocatedModules, + ()); } } diff --git a/gnu/llvm/lldb/source/API/SBModuleSpec.cpp b/gnu/llvm/lldb/source/API/SBModuleSpec.cpp index a5e9ad26fac..5d88272a399 100644 --- a/gnu/llvm/lldb/source/API/SBModuleSpec.cpp +++ b/gnu/llvm/lldb/source/API/SBModuleSpec.cpp @@ -1,4 +1,4 @@ -//===-- SBModuleSpec.cpp ----------------------------------------*- C++ -*-===// +//===-- SBModuleSpec.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -38,7 +38,7 @@ const SBModuleSpec &SBModuleSpec::operator=(const SBModuleSpec &rhs) { return LLDB_RECORD_RESULT(*this); } -SBModuleSpec::~SBModuleSpec() {} +SBModuleSpec::~SBModuleSpec() = default; bool SBModuleSpec::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBModuleSpec, IsValid); @@ -169,7 +169,7 @@ SBModuleSpecList &SBModuleSpecList::operator=(const SBModuleSpecList &rhs) { return LLDB_RECORD_RESULT(*this); } -SBModuleSpecList::~SBModuleSpecList() {} +SBModuleSpecList::~SBModuleSpecList() = default; SBModuleSpecList SBModuleSpecList::GetModuleSpecifications(const char *path) { LLDB_RECORD_STATIC_METHOD(lldb::SBModuleSpecList, SBModuleSpecList, diff --git a/gnu/llvm/lldb/source/API/SBPlatform.cpp b/gnu/llvm/lldb/source/API/SBPlatform.cpp index f3708d8e084..7ac852488ff 100644 --- a/gnu/llvm/lldb/source/API/SBPlatform.cpp +++ b/gnu/llvm/lldb/source/API/SBPlatform.cpp @@ -1,4 +1,4 @@ -//===-- SBPlatform.cpp ------------------------------------------*- C++ -*-===// +//===-- SBPlatform.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,9 +8,11 @@ #include "lldb/API/SBPlatform.h" #include "SBReproducerPrivate.h" +#include "lldb/API/SBEnvironment.h" #include "lldb/API/SBError.h" #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBLaunchInfo.h" +#include "lldb/API/SBPlatform.h" #include "lldb/API/SBUnixSignals.h" #include "lldb/Host/File.h" #include "lldb/Target/Platform.h" @@ -36,7 +38,7 @@ struct PlatformConnectOptions { m_url = url; } - ~PlatformConnectOptions() {} + ~PlatformConnectOptions() = default; std::string m_url; std::string m_rsync_options; @@ -54,7 +56,7 @@ struct PlatformShellCommand { m_command = shell_command; } - ~PlatformShellCommand() {} + ~PlatformShellCommand() = default; std::string m_command; std::string m_working_dir; @@ -80,14 +82,16 @@ SBPlatformConnectOptions::SBPlatformConnectOptions( SBPlatformConnectOptions::~SBPlatformConnectOptions() { delete m_opaque_ptr; } -void SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) { +SBPlatformConnectOptions &SBPlatformConnectOptions:: +operator=(const SBPlatformConnectOptions &rhs) { LLDB_RECORD_METHOD( - void, + SBPlatformConnectOptions &, SBPlatformConnectOptions, operator=,( const lldb::SBPlatformConnectOptions &), rhs); *m_opaque_ptr = *rhs.m_opaque_ptr; + return LLDB_RECORD_RESULT(*this); } const char *SBPlatformConnectOptions::GetURL() { @@ -174,6 +178,18 @@ SBPlatformShellCommand::SBPlatformShellCommand( *m_opaque_ptr = *rhs.m_opaque_ptr; } +SBPlatformShellCommand &SBPlatformShellCommand:: +operator=(const SBPlatformShellCommand &rhs) { + + LLDB_RECORD_METHOD( + SBPlatformShellCommand &, + SBPlatformShellCommand, operator=,(const lldb::SBPlatformShellCommand &), + rhs); + + *m_opaque_ptr = *rhs.m_opaque_ptr; + return LLDB_RECORD_RESULT(*this); +} + SBPlatformShellCommand::~SBPlatformShellCommand() { delete m_opaque_ptr; } void SBPlatformShellCommand::Clear() { @@ -273,7 +289,30 @@ SBPlatform::SBPlatform(const char *platform_name) : m_opaque_sp() { m_opaque_sp = Platform::Create(ConstString(platform_name), error); } -SBPlatform::~SBPlatform() {} +SBPlatform::SBPlatform(const SBPlatform &rhs) { + LLDB_RECORD_CONSTRUCTOR(SBPlatform, (const lldb::SBPlatform &), rhs); + + m_opaque_sp = rhs.m_opaque_sp; +} + +SBPlatform &SBPlatform::operator=(const SBPlatform &rhs) { + LLDB_RECORD_METHOD(SBPlatform &, + SBPlatform, operator=,(const lldb::SBPlatform &), rhs); + + m_opaque_sp = rhs.m_opaque_sp; + return LLDB_RECORD_RESULT(*this); +} + +SBPlatform::~SBPlatform() = default; + +SBPlatform SBPlatform::GetHostPlatform() { + LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBPlatform, SBPlatform, + GetHostPlatform); + + SBPlatform host_platform; + host_platform.m_opaque_sp = Platform::GetHostPlatform(); + return LLDB_RECORD_RESULT(host_platform); +} bool SBPlatform::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBPlatform, IsValid); @@ -615,6 +654,17 @@ SBUnixSignals SBPlatform::GetUnixSignals() const { return LLDB_RECORD_RESULT(SBUnixSignals()); } +SBEnvironment SBPlatform::GetEnvironment() { + LLDB_RECORD_METHOD_NO_ARGS(lldb::SBEnvironment, SBPlatform, GetEnvironment); + PlatformSP platform_sp(GetSP()); + + if (platform_sp) { + return LLDB_RECORD_RESULT(SBEnvironment(platform_sp->GetEnvironment())); + } + + return LLDB_RECORD_RESULT(SBEnvironment()); +} + namespace lldb_private { namespace repro { @@ -624,7 +674,7 @@ void RegisterMethods(Registry &R) { LLDB_REGISTER_CONSTRUCTOR(SBPlatformConnectOptions, (const lldb::SBPlatformConnectOptions &)); LLDB_REGISTER_METHOD( - void, + SBPlatformConnectOptions &, SBPlatformConnectOptions, operator=,( const lldb::SBPlatformConnectOptions &)); LLDB_REGISTER_METHOD(const char *, SBPlatformConnectOptions, GetURL, ()); @@ -645,6 +695,9 @@ void RegisterMethods(Registry &R) { LLDB_REGISTER_CONSTRUCTOR(SBPlatformShellCommand, (const char *)); LLDB_REGISTER_CONSTRUCTOR(SBPlatformShellCommand, (const lldb::SBPlatformShellCommand &)); + LLDB_REGISTER_METHOD( + SBPlatformShellCommand &, + SBPlatformShellCommand, operator=,(const lldb::SBPlatformShellCommand &)); LLDB_REGISTER_METHOD(void, SBPlatformShellCommand, Clear, ()); LLDB_REGISTER_METHOD(const char *, SBPlatformShellCommand, GetCommand, ()); LLDB_REGISTER_METHOD(void, SBPlatformShellCommand, SetCommand, @@ -666,6 +719,9 @@ template <> void RegisterMethods(Registry &R) { LLDB_REGISTER_CONSTRUCTOR(SBPlatform, ()); LLDB_REGISTER_CONSTRUCTOR(SBPlatform, (const char *)); + LLDB_REGISTER_CONSTRUCTOR(SBPlatform, (const lldb::SBPlatform &)); + LLDB_REGISTER_METHOD(SBPlatform &, + SBPlatform, operator=,(const lldb::SBPlatform &)); LLDB_REGISTER_METHOD_CONST(bool, SBPlatform, IsValid, ()); LLDB_REGISTER_METHOD_CONST(bool, SBPlatform, operator bool, ()); LLDB_REGISTER_METHOD(void, SBPlatform, Clear, ()); @@ -700,8 +756,11 @@ void RegisterMethods(Registry &R) { (const char *)); LLDB_REGISTER_METHOD(lldb::SBError, SBPlatform, SetFilePermissions, (const char *, uint32_t)); + LLDB_REGISTER_METHOD(lldb::SBEnvironment, SBPlatform, GetEnvironment, ()); LLDB_REGISTER_METHOD_CONST(lldb::SBUnixSignals, SBPlatform, GetUnixSignals, ()); + LLDB_REGISTER_STATIC_METHOD(lldb::SBPlatform, SBPlatform, GetHostPlatform, + ()); } } diff --git a/gnu/llvm/lldb/source/API/SBProcess.cpp b/gnu/llvm/lldb/source/API/SBProcess.cpp index 45aaa0bd2d8..d7b7fd7caca 100644 --- a/gnu/llvm/lldb/source/API/SBProcess.cpp +++ b/gnu/llvm/lldb/source/API/SBProcess.cpp @@ -1,4 +1,4 @@ -//===-- SBProcess.cpp -------------------------------------------*- C++ -*-===// +//===-- SBProcess.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,6 +18,7 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/StreamFile.h" +#include "lldb/Core/StructuredDataImpl.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -74,7 +75,7 @@ const SBProcess &SBProcess::operator=(const SBProcess &rhs) { } // Destructor -SBProcess::~SBProcess() {} +SBProcess::~SBProcess() = default; const char *SBProcess::GetBroadcasterClassName() { LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBProcess, @@ -270,8 +271,8 @@ size_t SBProcess::PutSTDIN(const char *src, size_t src_len) { } size_t SBProcess::GetSTDOUT(char *dst, size_t dst_len) const { - LLDB_RECORD_METHOD_CONST(size_t, SBProcess, GetSTDOUT, (char *, size_t), dst, - dst_len); + LLDB_RECORD_CHAR_PTR_METHOD_CONST(size_t, SBProcess, GetSTDOUT, + (char *, size_t), dst, "", dst_len); size_t bytes_read = 0; ProcessSP process_sp(GetSP()); @@ -284,8 +285,8 @@ size_t SBProcess::GetSTDOUT(char *dst, size_t dst_len) const { } size_t SBProcess::GetSTDERR(char *dst, size_t dst_len) const { - LLDB_RECORD_METHOD_CONST(size_t, SBProcess, GetSTDERR, (char *, size_t), dst, - dst_len); + LLDB_RECORD_CHAR_PTR_METHOD_CONST(size_t, SBProcess, GetSTDERR, + (char *, size_t), dst, "", dst_len); size_t bytes_read = 0; ProcessSP process_sp(GetSP()); @@ -298,8 +299,8 @@ size_t SBProcess::GetSTDERR(char *dst, size_t dst_len) const { } size_t SBProcess::GetAsyncProfileData(char *dst, size_t dst_len) const { - LLDB_RECORD_METHOD_CONST(size_t, SBProcess, GetAsyncProfileData, - (char *, size_t), dst, dst_len); + LLDB_RECORD_CHAR_PTR_METHOD_CONST(size_t, SBProcess, GetAsyncProfileData, + (char *, size_t), dst, "", dst_len); size_t bytes_read = 0; ProcessSP process_sp(GetSP()); @@ -1010,6 +1011,30 @@ bool SBProcess::GetDescription(SBStream &description) { return true; } +SBStructuredData SBProcess::GetExtendedCrashInformation() { + LLDB_RECORD_METHOD_NO_ARGS(lldb::SBStructuredData, SBProcess, + GetExtendedCrashInformation); + SBStructuredData data; + ProcessSP process_sp(GetSP()); + if (!process_sp) + return LLDB_RECORD_RESULT(data); + + PlatformSP platform_sp = process_sp->GetTarget().GetPlatform(); + + if (!platform_sp) + return LLDB_RECORD_RESULT(data); + + auto expected_data = + platform_sp->FetchExtendedCrashInformation(*process_sp.get()); + + if (!expected_data) + return LLDB_RECORD_RESULT(data); + + StructuredData::ObjectSP fetched_data = *expected_data; + data.m_impl_up->SetObjectSP(fetched_data); + return LLDB_RECORD_RESULT(data); +} + uint32_t SBProcess::GetNumSupportedHardwareWatchpoints(lldb::SBError &sb_error) const { LLDB_RECORD_METHOD_CONST(uint32_t, SBProcess, @@ -1313,10 +1338,6 @@ void RegisterMethods(Registry &R) { (lldb::tid_t, lldb::addr_t)); LLDB_REGISTER_METHOD_CONST(lldb::SBTarget, SBProcess, GetTarget, ()); LLDB_REGISTER_METHOD(size_t, SBProcess, PutSTDIN, (const char *, size_t)); - LLDB_REGISTER_METHOD_CONST(size_t, SBProcess, GetSTDOUT, (char *, size_t)); - LLDB_REGISTER_METHOD_CONST(size_t, SBProcess, GetSTDERR, (char *, size_t)); - LLDB_REGISTER_METHOD_CONST(size_t, SBProcess, GetAsyncProfileData, - (char *, size_t)); LLDB_REGISTER_METHOD(lldb::SBTrace, SBProcess, StartTrace, (lldb::SBTraceOptions &, lldb::SBError &)); LLDB_REGISTER_METHOD_CONST(void, SBProcess, ReportEventState, @@ -1389,6 +1410,8 @@ void RegisterMethods(Registry &R) { LLDB_REGISTER_METHOD(lldb::addr_t, SBProcess, ReadPointerFromMemory, (lldb::addr_t, lldb::SBError &)); LLDB_REGISTER_METHOD(bool, SBProcess, GetDescription, (lldb::SBStream &)); + LLDB_REGISTER_METHOD(lldb::SBStructuredData, SBProcess, + GetExtendedCrashInformation, ()); LLDB_REGISTER_METHOD_CONST(uint32_t, SBProcess, GetNumSupportedHardwareWatchpoints, (lldb::SBError &)); @@ -1416,6 +1439,10 @@ void RegisterMethods(Registry &R) { LLDB_REGISTER_METHOD(lldb::SBMemoryRegionInfoList, SBProcess, GetMemoryRegions, ()); LLDB_REGISTER_METHOD(lldb::SBProcessInfo, SBProcess, GetProcessInfo, ()); + + LLDB_REGISTER_CHAR_PTR_METHOD_CONST(size_t, SBProcess, GetSTDOUT); + LLDB_REGISTER_CHAR_PTR_METHOD_CONST(size_t, SBProcess, GetSTDERR); + LLDB_REGISTER_CHAR_PTR_METHOD_CONST(size_t, SBProcess, GetAsyncProfileData); } } diff --git a/gnu/llvm/lldb/source/API/SBProcessInfo.cpp b/gnu/llvm/lldb/source/API/SBProcessInfo.cpp index be242ec5872..29a9c7b24b5 100644 --- a/gnu/llvm/lldb/source/API/SBProcessInfo.cpp +++ b/gnu/llvm/lldb/source/API/SBProcessInfo.cpp @@ -1,4 +1,4 @@ -//===-- SBProcessInfo.cpp ---------------------------------------*- C++ -*-===// +//===-- SBProcessInfo.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,7 +25,7 @@ SBProcessInfo::SBProcessInfo(const SBProcessInfo &rhs) : m_opaque_up() { m_opaque_up = clone(rhs.m_opaque_up); } -SBProcessInfo::~SBProcessInfo() {} +SBProcessInfo::~SBProcessInfo() = default; SBProcessInfo &SBProcessInfo::operator=(const SBProcessInfo &rhs) { LLDB_RECORD_METHOD(lldb::SBProcessInfo &, @@ -39,7 +39,7 @@ SBProcessInfo &SBProcessInfo::operator=(const SBProcessInfo &rhs) { ProcessInstanceInfo &SBProcessInfo::ref() { if (m_opaque_up == nullptr) { - m_opaque_up.reset(new ProcessInstanceInfo()); + m_opaque_up = std::make_unique(); } return *m_opaque_up; } diff --git a/gnu/llvm/lldb/source/API/SBQueue.cpp b/gnu/llvm/lldb/source/API/SBQueue.cpp index 7d1581c42f6..2e6571392ea 100644 --- a/gnu/llvm/lldb/source/API/SBQueue.cpp +++ b/gnu/llvm/lldb/source/API/SBQueue.cpp @@ -1,4 +1,4 @@ -//===-- SBQueue.cpp ---------------------------------------------*- C++ -*-===// +//===-- SBQueue.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -47,7 +47,7 @@ public: m_pending_items_fetched = rhs.m_pending_items_fetched; } - ~QueueImpl() {} + ~QueueImpl() = default; bool IsValid() { return m_queue_wp.lock() != nullptr; } @@ -243,7 +243,7 @@ const lldb::SBQueue &SBQueue::operator=(const lldb::SBQueue &rhs) { return LLDB_RECORD_RESULT(*this); } -SBQueue::~SBQueue() {} +SBQueue::~SBQueue() = default; bool SBQueue::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBQueue, IsValid); diff --git a/gnu/llvm/lldb/source/API/SBQueueItem.cpp b/gnu/llvm/lldb/source/API/SBQueueItem.cpp index 5f2cbd1bdbf..0f92e2e0412 100644 --- a/gnu/llvm/lldb/source/API/SBQueueItem.cpp +++ b/gnu/llvm/lldb/source/API/SBQueueItem.cpp @@ -1,4 +1,4 @@ -//===-- SBQueueItem.cpp -----------------------------------------*- C++ -*-===// +//===-- SBQueueItem.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/API/SBReproducer.cpp b/gnu/llvm/lldb/source/API/SBReproducer.cpp index 3d2de072744..0eb3429c4fe 100644 --- a/gnu/llvm/lldb/source/API/SBReproducer.cpp +++ b/gnu/llvm/lldb/source/API/SBReproducer.cpp @@ -1,4 +1,4 @@ -//===-- SBReproducer.cpp ----------------------------------------*- C++ -*-===// +//===-- SBReproducer.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -15,6 +15,7 @@ #include "lldb/API/SBBlock.h" #include "lldb/API/SBBreakpoint.h" #include "lldb/API/SBCommandInterpreter.h" +#include "lldb/API/SBCommandInterpreterRunOptions.h" #include "lldb/API/SBData.h" #include "lldb/API/SBDebugger.h" #include "lldb/API/SBDeclaration.h" @@ -40,14 +41,15 @@ SBRegistry::SBRegistry() { RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); + RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); - RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); + RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); @@ -58,6 +60,7 @@ SBRegistry::SBRegistry() { RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); + RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); @@ -68,9 +71,9 @@ SBRegistry::SBRegistry() { RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); + RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); - RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); @@ -95,8 +98,8 @@ SBRegistry::SBRegistry() { RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); - RegisterMethods(R); RegisterMethods(R); + RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); RegisterMethods(R); @@ -111,6 +114,12 @@ const char *SBReproducer::Capture() { error = llvm::toString(std::move(e)); return error.c_str(); } + + if (auto *g = lldb_private::repro::Reproducer::Instance().GetGenerator()) { + auto &p = g->GetOrCreate(); + InstrumentationData::Initialize(p.GetSerializer(), p.GetRegistry()); + } + return nullptr; } @@ -121,6 +130,35 @@ const char *SBReproducer::Capture(const char *path) { error = llvm::toString(std::move(e)); return error.c_str(); } + + if (auto *g = lldb_private::repro::Reproducer::Instance().GetGenerator()) { + auto &p = g->GetOrCreate(); + InstrumentationData::Initialize(p.GetSerializer(), p.GetRegistry()); + } + + return nullptr; +} + +const char *SBReproducer::PassiveReplay(const char *path) { + static std::string error; + if (auto e = Reproducer::Initialize(ReproducerMode::PassiveReplay, + FileSpec(path))) { + error = llvm::toString(std::move(e)); + return error.c_str(); + } + + if (auto *l = lldb_private::repro::Reproducer::Instance().GetLoader()) { + FileSpec file = l->GetFile(); + auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath()); + if (!error_or_file) { + error = + "unable to read SB API data: " + error_or_file.getError().message(); + return error.c_str(); + } + static ReplayData r(std::move(*error_or_file)); + InstrumentationData::Initialize(r.GetDeserializer(), r.GetRegistry()); + } + return nullptr; } @@ -178,6 +216,15 @@ bool SBReproducer::Generate() { return false; } +bool SBReproducer::SetAutoGenerate(bool b) { + auto &r = Reproducer::Instance(); + if (auto generator = r.GetGenerator()) { + generator->SetAutoGenerate(b); + return true; + } + return false; +} + const char *SBReproducer::GetPath() { static std::string path; auto &r = Reproducer::Instance(); @@ -185,6 +232,12 @@ const char *SBReproducer::GetPath() { return path.c_str(); } +void SBReproducer::SetWorkingDirectory(const char *path) { + if (auto *g = lldb_private::repro::Reproducer::Instance().GetGenerator()) { + g->GetOrCreate().Update(path); + } +} + char lldb_private::repro::SBProvider::ID = 0; const char *SBProvider::Info::name = "sbapi"; const char *SBProvider::Info::file = "sbapi.bin"; diff --git a/gnu/llvm/lldb/source/API/SBReproducerPrivate.h b/gnu/llvm/lldb/source/API/SBReproducerPrivate.h index edd06941398..a4c6eb94627 100644 --- a/gnu/llvm/lldb/source/API/SBReproducerPrivate.h +++ b/gnu/llvm/lldb/source/API/SBReproducerPrivate.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_API_SBREPRODUCER_PRIVATE_H -#define LLDB_API_SBREPRODUCER_PRIVATE_H +#ifndef LLDB_SOURCE_API_SBREPRODUCERPRIVATE_H +#define LLDB_SOURCE_API_SBREPRODUCERPRIVATE_H #include "lldb/API/SBReproducer.h" @@ -20,7 +20,7 @@ #include "llvm/ADT/DenseMap.h" #define LLDB_GET_INSTRUMENTATION_DATA() \ - lldb_private::repro::GetInstrumentationData() + lldb_private::repro::InstrumentationData::Instance() namespace lldb_private { namespace repro { @@ -55,17 +55,19 @@ private: SBRegistry m_registry; }; -inline InstrumentationData GetInstrumentationData() { - if (!lldb_private::repro::Reproducer::Initialized()) - return {}; - - if (auto *g = lldb_private::repro::Reproducer::Instance().GetGenerator()) { - auto &p = g->GetOrCreate(); - return {p.GetSerializer(), p.GetRegistry()}; - } +class ReplayData { +public: + ReplayData(std::unique_ptr memory_buffer) + : m_memory_buffer(std::move(memory_buffer)), m_registry(), + m_deserializer(m_memory_buffer->getBuffer()) {} + Deserializer &GetDeserializer() { return m_deserializer; } + Registry &GetRegistry() { return m_registry; } - return {}; -} +private: + std::unique_ptr m_memory_buffer; + SBRegistry m_registry; + Deserializer m_deserializer; +}; template void RegisterMethods(Registry &R); diff --git a/gnu/llvm/lldb/source/API/SBSection.cpp b/gnu/llvm/lldb/source/API/SBSection.cpp index 14e1e14f59a..bb56fa18d9c 100644 --- a/gnu/llvm/lldb/source/API/SBSection.cpp +++ b/gnu/llvm/lldb/source/API/SBSection.cpp @@ -1,4 +1,4 @@ -//===-- SBSection.cpp -------------------------------------------*- C++ -*-===// +//===-- SBSection.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -44,7 +44,7 @@ const SBSection &SBSection::operator=(const SBSection &rhs) { return LLDB_RECORD_RESULT(*this); } -SBSection::~SBSection() {} +SBSection::~SBSection() = default; bool SBSection::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBSection, IsValid); @@ -281,7 +281,7 @@ bool SBSection::GetDescription(SBStream &description) { const addr_t file_addr = section_sp->GetFileAddress(); strm.Printf("[0x%16.16" PRIx64 "-0x%16.16" PRIx64 ") ", file_addr, file_addr + section_sp->GetByteSize()); - section_sp->DumpName(&strm); + section_sp->DumpName(strm.AsRawOstream()); } else { strm.PutCString("No value"); } diff --git a/gnu/llvm/lldb/source/API/SBSourceManager.cpp b/gnu/llvm/lldb/source/API/SBSourceManager.cpp index 9c4ce3c7f4e..43c3443672f 100644 --- a/gnu/llvm/lldb/source/API/SBSourceManager.cpp +++ b/gnu/llvm/lldb/source/API/SBSourceManager.cpp @@ -1,4 +1,4 @@ -//===-- SBSourceManager.cpp -------------------------------------*- C++ -*-===// +//===-- SBSourceManager.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -75,13 +75,13 @@ SBSourceManager::SBSourceManager(const SBDebugger &debugger) { LLDB_RECORD_CONSTRUCTOR(SBSourceManager, (const lldb::SBDebugger &), debugger); - m_opaque_up.reset(new SourceManagerImpl(debugger.get_sp())); + m_opaque_up = std::make_unique(debugger.get_sp()); } SBSourceManager::SBSourceManager(const SBTarget &target) { LLDB_RECORD_CONSTRUCTOR(SBSourceManager, (const lldb::SBTarget &), target); - m_opaque_up.reset(new SourceManagerImpl(target.GetSP())); + m_opaque_up = std::make_unique(target.GetSP()); } SBSourceManager::SBSourceManager(const SBSourceManager &rhs) { @@ -91,7 +91,7 @@ SBSourceManager::SBSourceManager(const SBSourceManager &rhs) { if (&rhs == this) return; - m_opaque_up.reset(new SourceManagerImpl(*(rhs.m_opaque_up.get()))); + m_opaque_up = std::make_unique(*(rhs.m_opaque_up.get())); } const lldb::SBSourceManager &SBSourceManager:: @@ -100,11 +100,11 @@ operator=(const lldb::SBSourceManager &rhs) { SBSourceManager, operator=,(const lldb::SBSourceManager &), rhs); - m_opaque_up.reset(new SourceManagerImpl(*(rhs.m_opaque_up.get()))); + m_opaque_up = std::make_unique(*(rhs.m_opaque_up.get())); return LLDB_RECORD_RESULT(*this); } -SBSourceManager::~SBSourceManager() {} +SBSourceManager::~SBSourceManager() = default; size_t SBSourceManager::DisplaySourceLinesWithLineNumbers( const SBFileSpec &file, uint32_t line, uint32_t context_before, diff --git a/gnu/llvm/lldb/source/API/SBStream.cpp b/gnu/llvm/lldb/source/API/SBStream.cpp index d57634d2947..eb81153084e 100644 --- a/gnu/llvm/lldb/source/API/SBStream.cpp +++ b/gnu/llvm/lldb/source/API/SBStream.cpp @@ -1,4 +1,4 @@ -//===-- SBStream.cpp ----------------------------------------*- C++ -*-===// +//===-- SBStream.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -26,7 +26,7 @@ SBStream::SBStream() : m_opaque_up(new StreamString()), m_is_file(false) { SBStream::SBStream(SBStream &&rhs) : m_opaque_up(std::move(rhs.m_opaque_up)), m_is_file(rhs.m_is_file) {} -SBStream::~SBStream() {} +SBStream::~SBStream() = default; bool SBStream::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBStream, IsValid); @@ -60,6 +60,12 @@ size_t SBStream::GetSize() { return static_cast(m_opaque_up.get())->GetSize(); } +void SBStream::Print(const char *str) { + LLDB_RECORD_METHOD(void, SBStream, Print, (const char *), str); + + Printf("%s", str); +} + void SBStream::Printf(const char *format, ...) { if (!format) return; @@ -81,7 +87,8 @@ void SBStream::RedirectToFile(const char *path, bool append) { // 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) - local_data = static_cast(m_opaque_up.get())->GetString(); + local_data = std::string( + static_cast(m_opaque_up.get())->GetString()); } auto open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate; if (append) @@ -129,7 +136,8 @@ void SBStream::RedirectToFile(FileSP file_sp) { // 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) - local_data = static_cast(m_opaque_up.get())->GetString(); + local_data = std::string( + static_cast(m_opaque_up.get())->GetString()); } m_opaque_up = std::make_unique(file_sp); @@ -150,7 +158,8 @@ void SBStream::RedirectToFileDescriptor(int fd, bool transfer_fh_ownership) { // 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) - local_data = static_cast(m_opaque_up.get())->GetString(); + local_data = std::string( + static_cast(m_opaque_up.get())->GetString()); } m_opaque_up = std::make_unique(fd, transfer_fh_ownership); @@ -168,7 +177,7 @@ lldb_private::Stream *SBStream::get() { return m_opaque_up.get(); } lldb_private::Stream &SBStream::ref() { if (m_opaque_up == nullptr) - m_opaque_up.reset(new StreamString()); + m_opaque_up = std::make_unique(); return *m_opaque_up; } @@ -201,6 +210,7 @@ void RegisterMethods(Registry &R) { LLDB_REGISTER_METHOD(void, SBStream, RedirectToFileHandle, (FILE *, bool)); LLDB_REGISTER_METHOD(void, SBStream, RedirectToFileDescriptor, (int, bool)); LLDB_REGISTER_METHOD(void, SBStream, Clear, ()); + LLDB_REGISTER_METHOD(void, SBStream, Print, (const char *)); } } diff --git a/gnu/llvm/lldb/source/API/SBStringList.cpp b/gnu/llvm/lldb/source/API/SBStringList.cpp index ac07b8faac4..d9b03692ec0 100644 --- a/gnu/llvm/lldb/source/API/SBStringList.cpp +++ b/gnu/llvm/lldb/source/API/SBStringList.cpp @@ -1,4 +1,4 @@ -//===-- SBStringList.cpp ----------------------------------------*- C++ -*-===// +//===-- SBStringList.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -39,7 +39,7 @@ const SBStringList &SBStringList::operator=(const SBStringList &rhs) { return LLDB_RECORD_RESULT(*this); } -SBStringList::~SBStringList() {} +SBStringList::~SBStringList() = default; const lldb_private::StringList *SBStringList::operator->() const { return m_opaque_up.get(); @@ -66,7 +66,7 @@ void SBStringList::AppendString(const char *str) { if (IsValid()) m_opaque_up->AppendString(str); else - m_opaque_up.reset(new lldb_private::StringList(str)); + m_opaque_up = std::make_unique(str); } } @@ -78,7 +78,7 @@ void SBStringList::AppendList(const char **strv, int strc) { if (IsValid()) m_opaque_up->AppendList(strv, strc); else - m_opaque_up.reset(new lldb_private::StringList(strv, strc)); + m_opaque_up = std::make_unique(strv, strc); } } @@ -88,14 +88,14 @@ void SBStringList::AppendList(const SBStringList &strings) { if (strings.IsValid()) { if (!IsValid()) - m_opaque_up.reset(new lldb_private::StringList()); + m_opaque_up = std::make_unique(); m_opaque_up->AppendList(*(strings.m_opaque_up)); } } void SBStringList::AppendList(const StringList &strings) { if (!IsValid()) - m_opaque_up.reset(new lldb_private::StringList()); + m_opaque_up = std::make_unique(); m_opaque_up->AppendList(strings); } diff --git a/gnu/llvm/lldb/source/API/SBStructuredData.cpp b/gnu/llvm/lldb/source/API/SBStructuredData.cpp index 6b973e82c85..2ae3005fd8d 100644 --- a/gnu/llvm/lldb/source/API/SBStructuredData.cpp +++ b/gnu/llvm/lldb/source/API/SBStructuredData.cpp @@ -1,4 +1,4 @@ -//===-- SBStructuredData.cpp ------------------------------------*- C++ -*-===// +//===-- SBStructuredData.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -45,7 +45,7 @@ SBStructuredData::SBStructuredData(lldb_private::StructuredDataImpl *impl) (lldb_private::StructuredDataImpl *), impl); } -SBStructuredData::~SBStructuredData() {} +SBStructuredData::~SBStructuredData() = default; SBStructuredData &SBStructuredData:: operator=(const lldb::SBStructuredData &rhs) { @@ -126,10 +126,10 @@ 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; @@ -141,7 +141,7 @@ bool SBStructuredData::GetKeys(lldb::SBStringList &keys) const { 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()); @@ -196,8 +196,8 @@ bool SBStructuredData::GetBooleanValue(bool fail_value) const { } size_t SBStructuredData::GetStringValue(char *dst, size_t dst_len) const { - LLDB_RECORD_METHOD_CONST(size_t, SBStructuredData, GetStringValue, - (char *, size_t), dst, dst_len); + LLDB_RECORD_CHAR_PTR_METHOD_CONST(size_t, SBStructuredData, GetStringValue, + (char *, size_t), dst, "", dst_len); return (m_impl_up ? m_impl_up->GetStringValue(dst, dst_len) : 0); } @@ -205,11 +205,9 @@ size_t SBStructuredData::GetStringValue(char *dst, size_t dst_len) const { namespace lldb_private { namespace repro { -template <> -void RegisterMethods(Registry &R) { +template <> void RegisterMethods(Registry &R) { LLDB_REGISTER_CONSTRUCTOR(SBStructuredData, ()); - LLDB_REGISTER_CONSTRUCTOR(SBStructuredData, - (const lldb::SBStructuredData &)); + LLDB_REGISTER_CONSTRUCTOR(SBStructuredData, (const lldb::SBStructuredData &)); LLDB_REGISTER_CONSTRUCTOR(SBStructuredData, (const lldb::EventSP &)); LLDB_REGISTER_CONSTRUCTOR(SBStructuredData, (lldb_private::StructuredDataImpl *)); @@ -236,12 +234,10 @@ void RegisterMethods(Registry &R) { GetItemAtIndex, (size_t)); LLDB_REGISTER_METHOD_CONST(uint64_t, SBStructuredData, GetIntegerValue, (uint64_t)); - LLDB_REGISTER_METHOD_CONST(double, SBStructuredData, GetFloatValue, - (double)); + LLDB_REGISTER_METHOD_CONST(double, SBStructuredData, GetFloatValue, (double)); LLDB_REGISTER_METHOD_CONST(bool, SBStructuredData, GetBooleanValue, (bool)); - LLDB_REGISTER_METHOD_CONST(size_t, SBStructuredData, GetStringValue, - (char *, size_t)); + LLDB_REGISTER_CHAR_PTR_METHOD_CONST(size_t, SBStructuredData, GetStringValue); } -} -} +} // namespace repro +} // namespace lldb_private diff --git a/gnu/llvm/lldb/source/API/SBSymbol.cpp b/gnu/llvm/lldb/source/API/SBSymbol.cpp index 6cc90e0ee36..e4f2f351827 100644 --- a/gnu/llvm/lldb/source/API/SBSymbol.cpp +++ b/gnu/llvm/lldb/source/API/SBSymbol.cpp @@ -1,4 +1,4 @@ -//===-- SBSymbol.cpp --------------------------------------------*- C++ -*-===// +//===-- SBSymbol.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -68,9 +68,7 @@ const char *SBSymbol::GetDisplayName() const { const char *name = nullptr; if (m_opaque_ptr) - name = m_opaque_ptr->GetMangled() - .GetDisplayDemangledName(m_opaque_ptr->GetLanguage()) - .AsCString(); + name = m_opaque_ptr->GetMangled().GetDisplayDemangledName().AsCString(); return name; } @@ -126,22 +124,17 @@ SBInstructionList SBSymbol::GetInstructions(SBTarget target, SBInstructionList sb_instructions; if (m_opaque_ptr) { - ExecutionContext exe_ctx; TargetSP target_sp(target.GetSP()); std::unique_lock lock; - if (target_sp) { + if (target_sp && m_opaque_ptr->ValueIsAddress()) { lock = std::unique_lock(target_sp->GetAPIMutex()); - - target_sp->CalculateExecutionContext(exe_ctx); - } - if (m_opaque_ptr->ValueIsAddress()) { const Address &symbol_addr = m_opaque_ptr->GetAddressRef(); ModuleSP module_sp = symbol_addr.GetModule(); if (module_sp) { AddressRange symbol_range(symbol_addr, m_opaque_ptr->GetByteSize()); const bool prefer_file_cache = false; sb_instructions.SetDisassembler(Disassembler::DisassembleRange( - module_sp->GetArchitecture(), nullptr, flavor_string, exe_ctx, + module_sp->GetArchitecture(), nullptr, flavor_string, *target_sp, symbol_range, prefer_file_cache)); } } diff --git a/gnu/llvm/lldb/source/API/SBSymbolContext.cpp b/gnu/llvm/lldb/source/API/SBSymbolContext.cpp index 6e01e5535c3..488d4988490 100644 --- a/gnu/llvm/lldb/source/API/SBSymbolContext.cpp +++ b/gnu/llvm/lldb/source/API/SBSymbolContext.cpp @@ -1,4 +1,4 @@ -//===-- SBSymbolContext.cpp -------------------------------------*- C++ -*-===// +//===-- SBSymbolContext.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -37,7 +37,7 @@ SBSymbolContext::SBSymbolContext(const SBSymbolContext &rhs) : m_opaque_up() { m_opaque_up = clone(rhs.m_opaque_up); } -SBSymbolContext::~SBSymbolContext() {} +SBSymbolContext::~SBSymbolContext() = default; const SBSymbolContext &SBSymbolContext::operator=(const SBSymbolContext &rhs) { LLDB_RECORD_METHOD(const lldb::SBSymbolContext &, @@ -185,13 +185,13 @@ const lldb_private::SymbolContext &SBSymbolContext::operator*() const { lldb_private::SymbolContext &SBSymbolContext::operator*() { if (m_opaque_up == nullptr) - m_opaque_up.reset(new SymbolContext); + m_opaque_up = std::make_unique(); return *m_opaque_up; } lldb_private::SymbolContext &SBSymbolContext::ref() { if (m_opaque_up == nullptr) - m_opaque_up.reset(new SymbolContext); + m_opaque_up = std::make_unique(); return *m_opaque_up; } diff --git a/gnu/llvm/lldb/source/API/SBSymbolContextList.cpp b/gnu/llvm/lldb/source/API/SBSymbolContextList.cpp index 915d04a0282..9db84dc1bf4 100644 --- a/gnu/llvm/lldb/source/API/SBSymbolContextList.cpp +++ b/gnu/llvm/lldb/source/API/SBSymbolContextList.cpp @@ -1,4 +1,4 @@ -//===-- SBSymbolContextList.cpp ---------------------------------*- C++ -*-===// +//===-- SBSymbolContextList.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -28,7 +28,7 @@ SBSymbolContextList::SBSymbolContextList(const SBSymbolContextList &rhs) m_opaque_up = clone(rhs.m_opaque_up); } -SBSymbolContextList::~SBSymbolContextList() {} +SBSymbolContextList::~SBSymbolContextList() = default; const SBSymbolContextList &SBSymbolContextList:: operator=(const SBSymbolContextList &rhs) { diff --git a/gnu/llvm/lldb/source/API/SBTarget.cpp b/gnu/llvm/lldb/source/API/SBTarget.cpp index 312e4df7586..b84e9f10faf 100644 --- a/gnu/llvm/lldb/source/API/SBTarget.cpp +++ b/gnu/llvm/lldb/source/API/SBTarget.cpp @@ -1,4 +1,4 @@ -//===-- SBTarget.cpp --------------------------------------------*- C++ -*-===// +//===-- SBTarget.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,6 +13,7 @@ #include "lldb/API/SBBreakpoint.h" #include "lldb/API/SBDebugger.h" +#include "lldb/API/SBEnvironment.h" #include "lldb/API/SBEvent.h" #include "lldb/API/SBExpressionOptions.h" #include "lldb/API/SBFileSpec.h" @@ -118,7 +119,7 @@ const SBTarget &SBTarget::operator=(const SBTarget &rhs) { } // Destructor -SBTarget::~SBTarget() {} +SBTarget::~SBTarget() = default; bool SBTarget::EventIsTargetEvent(const SBEvent &event) { LLDB_RECORD_STATIC_METHOD(bool, SBTarget, EventIsTargetEvent, @@ -371,10 +372,19 @@ SBProcess SBTarget::Launch(SBListener &listener, char const **argv, Module *exe_module = target_sp->GetExecutableModulePointer(); if (exe_module) launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true); - if (argv) + if (argv) { launch_info.GetArguments().AppendArguments(argv); - if (envp) + } else { + auto default_launch_info = target_sp->GetProcessLaunchInfo(); + launch_info.GetArguments().AppendArguments( + default_launch_info.GetArguments()); + } + if (envp) { launch_info.GetEnvironment() = Environment(envp); + } else { + auto default_launch_info = target_sp->GetProcessLaunchInfo(); + launch_info.GetEnvironment() = default_launch_info.GetEnvironment(); + } if (listener.IsValid()) launch_info.SetListener(listener.GetSP()); @@ -556,7 +566,7 @@ lldb::SBProcess SBTarget::ConnectRemote(SBListener &listener, const char *url, if (process_sp) { sb_process.SetSP(process_sp); - error.SetError(process_sp->ConnectRemote(nullptr, url)); + error.SetError(process_sp->ConnectRemote(url)); } else { error.SetErrorString("unable to create lldb_private::Process"); } @@ -677,9 +687,9 @@ SBTarget::ResolveSymbolContextForAddress(const SBAddress &addr, size_t SBTarget::ReadMemory(const SBAddress addr, void *buf, size_t size, lldb::SBError &error) { - LLDB_RECORD_DUMMY(size_t, SBTarget, ReadMemory, - (const lldb::SBAddress, void *, size_t, lldb::SBError &), - addr, buf, size, error); + LLDB_RECORD_METHOD(size_t, SBTarget, ReadMemory, + (const lldb::SBAddress, void *, size_t, lldb::SBError &), + addr, buf, size, error); SBError sb_error; size_t bytes_read = 0; @@ -2054,21 +2064,22 @@ lldb::SBInstructionList SBTarget::ReadInstructions(lldb::SBAddress base_addr, lldb::SBInstructionList SBTarget::GetInstructions(lldb::SBAddress base_addr, const void *buf, size_t size) { - LLDB_RECORD_DUMMY(lldb::SBInstructionList, SBTarget, GetInstructions, - (lldb::SBAddress, const void *, size_t), base_addr, buf, - size); + LLDB_RECORD_METHOD(lldb::SBInstructionList, SBTarget, GetInstructions, + (lldb::SBAddress, const void *, size_t), base_addr, buf, + size); - return GetInstructionsWithFlavor(base_addr, nullptr, buf, size); + return LLDB_RECORD_RESULT( + GetInstructionsWithFlavor(base_addr, nullptr, buf, size)); } lldb::SBInstructionList SBTarget::GetInstructionsWithFlavor(lldb::SBAddress base_addr, const char *flavor_string, const void *buf, size_t size) { - LLDB_RECORD_DUMMY(lldb::SBInstructionList, SBTarget, - GetInstructionsWithFlavor, - (lldb::SBAddress, const char *, const void *, size_t), - base_addr, flavor_string, buf, size); + LLDB_RECORD_METHOD(lldb::SBInstructionList, SBTarget, + GetInstructionsWithFlavor, + (lldb::SBAddress, const char *, const void *, size_t), + base_addr, flavor_string, buf, size); SBInstructionList sb_instructions; @@ -2086,30 +2097,31 @@ SBTarget::GetInstructionsWithFlavor(lldb::SBAddress base_addr, UINT32_MAX, data_from_file)); } - return sb_instructions; + return LLDB_RECORD_RESULT(sb_instructions); } lldb::SBInstructionList SBTarget::GetInstructions(lldb::addr_t base_addr, const void *buf, size_t size) { - LLDB_RECORD_DUMMY(lldb::SBInstructionList, SBTarget, GetInstructions, - (lldb::addr_t, const void *, size_t), base_addr, buf, size); + LLDB_RECORD_METHOD(lldb::SBInstructionList, SBTarget, GetInstructions, + (lldb::addr_t, const void *, size_t), base_addr, buf, + size); - return GetInstructionsWithFlavor(ResolveLoadAddress(base_addr), nullptr, buf, - size); + return LLDB_RECORD_RESULT(GetInstructionsWithFlavor( + ResolveLoadAddress(base_addr), nullptr, buf, size)); } lldb::SBInstructionList SBTarget::GetInstructionsWithFlavor(lldb::addr_t base_addr, const char *flavor_string, const void *buf, size_t size) { - LLDB_RECORD_DUMMY(lldb::SBInstructionList, SBTarget, - GetInstructionsWithFlavor, - (lldb::addr_t, const char *, const void *, size_t), - base_addr, flavor_string, buf, size); + LLDB_RECORD_METHOD(lldb::SBInstructionList, SBTarget, + GetInstructionsWithFlavor, + (lldb::addr_t, const char *, const void *, size_t), + base_addr, flavor_string, buf, size); - return GetInstructionsWithFlavor(ResolveLoadAddress(base_addr), flavor_string, - buf, size); + return LLDB_RECORD_RESULT(GetInstructionsWithFlavor( + ResolveLoadAddress(base_addr), flavor_string, buf, size)); } SBError SBTarget::SetSectionLoadAddress(lldb::SBSection section, @@ -2328,16 +2340,6 @@ lldb::SBValue SBTarget::EvaluateExpression(const char *expr, Target *target = exe_ctx.GetTargetPtr(); if (target) { -#ifdef LLDB_CONFIGURATION_DEBUG - StreamString frame_description; - if (frame) - frame->DumpUsingSettingsFormat(&frame_description); - llvm::PrettyStackTraceFormat stack_trace( - "SBTarget::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = " - "%u) %s", - expr, options.GetFetchDynamicValue(), - frame_description.GetString().str().c_str()); -#endif target->EvaluateExpression(expr, frame, expr_value_sp, options.ref()); expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue()); @@ -2386,6 +2388,17 @@ void SBTarget::SetLaunchInfo(const lldb::SBLaunchInfo &launch_info) { m_opaque_sp->SetProcessLaunchInfo(launch_info.ref()); } +SBEnvironment SBTarget::GetEnvironment() { + LLDB_RECORD_METHOD_NO_ARGS(lldb::SBEnvironment, SBTarget, GetEnvironment); + TargetSP target_sp(GetSP()); + + if (target_sp) { + return LLDB_RECORD_RESULT(SBEnvironment(target_sp->GetEnvironment())); + } + + return LLDB_RECORD_RESULT(SBEnvironment()); +} + namespace lldb_private { namespace repro { @@ -2628,6 +2641,20 @@ void RegisterMethods(Registry &R) { LLDB_REGISTER_METHOD_CONST(lldb::SBLaunchInfo, SBTarget, GetLaunchInfo, ()); LLDB_REGISTER_METHOD(void, SBTarget, SetLaunchInfo, (const lldb::SBLaunchInfo &)); + LLDB_REGISTER_METHOD( + size_t, SBTarget, ReadMemory, + (const lldb::SBAddress, void *, size_t, lldb::SBError &)); + LLDB_REGISTER_METHOD(lldb::SBInstructionList, SBTarget, GetInstructions, + (lldb::SBAddress, const void *, size_t)); + LLDB_REGISTER_METHOD(lldb::SBInstructionList, SBTarget, + GetInstructionsWithFlavor, + (lldb::SBAddress, const char *, const void *, size_t)); + LLDB_REGISTER_METHOD(lldb::SBInstructionList, SBTarget, GetInstructions, + (lldb::addr_t, const void *, size_t)); + LLDB_REGISTER_METHOD(lldb::SBInstructionList, SBTarget, + GetInstructionsWithFlavor, + (lldb::addr_t, const char *, const void *, size_t)); + LLDB_REGISTER_METHOD(lldb::SBEnvironment, SBTarget, GetEnvironment, ()); } } diff --git a/gnu/llvm/lldb/source/API/SBThread.cpp b/gnu/llvm/lldb/source/API/SBThread.cpp index f7f748f5683..0d50aceee5e 100644 --- a/gnu/llvm/lldb/source/API/SBThread.cpp +++ b/gnu/llvm/lldb/source/API/SBThread.cpp @@ -1,4 +1,4 @@ -//===-- SBThread.cpp --------------------------------------------*- C++ -*-===// +//===-- SBThread.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -40,7 +40,6 @@ #include "lldb/Target/ThreadPlanStepInstruction.h" #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" @@ -86,7 +85,7 @@ const lldb::SBThread &SBThread::operator=(const SBThread &rhs) { } // Destructor -SBThread::~SBThread() {} +SBThread::~SBThread() = default; lldb::SBQueue SBThread::GetQueue() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBQueue, SBThread, GetQueue); @@ -292,14 +291,13 @@ SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) { GetStopReasonExtendedBacktraces, (lldb::InstrumentationRuntimeType), type); - ThreadCollectionSP threads; - threads = std::make_shared(); + SBThreadCollection threads; std::unique_lock lock; ExecutionContext exe_ctx(m_opaque_sp.get(), lock); if (!exe_ctx.HasThreadScope()) - return LLDB_RECORD_RESULT(threads); + return LLDB_RECORD_RESULT(SBThreadCollection()); ProcessSP process_sp = exe_ctx.GetProcessSP(); @@ -308,105 +306,38 @@ SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) { if (!info) return LLDB_RECORD_RESULT(threads); - return LLDB_RECORD_RESULT(process_sp->GetInstrumentationRuntime(type) - ->GetBacktracesFromExtendedStopInfo(info)); + threads = process_sp->GetInstrumentationRuntime(type) + ->GetBacktracesFromExtendedStopInfo(info); + return LLDB_RECORD_RESULT(threads); } size_t SBThread::GetStopDescription(char *dst, size_t dst_len) { - LLDB_RECORD_METHOD(size_t, SBThread, GetStopDescription, (char *, size_t), - dst, dst_len); + LLDB_RECORD_CHAR_PTR_METHOD(size_t, SBThread, GetStopDescription, + (char *, size_t), dst, "", dst_len); std::unique_lock lock; ExecutionContext exe_ctx(m_opaque_sp.get(), lock); - if (exe_ctx.HasThreadScope()) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { + if (dst) + *dst = 0; - StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); - if (stop_info_sp) { - const char *stop_desc = stop_info_sp->GetDescription(); - if (stop_desc) { - if (dst) - return ::snprintf(dst, dst_len, "%s", stop_desc); - else { - // NULL dst passed in, return the length needed to contain the - // description - return ::strlen(stop_desc) + 1; // Include the NULL byte for size - } - } else { - size_t stop_desc_len = 0; - switch (stop_info_sp->GetStopReason()) { - case eStopReasonTrace: - case eStopReasonPlanComplete: { - static char trace_desc[] = "step"; - stop_desc = trace_desc; - stop_desc_len = - sizeof(trace_desc); // Include the NULL byte for size - } break; - - case eStopReasonBreakpoint: { - static char bp_desc[] = "breakpoint hit"; - stop_desc = bp_desc; - stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size - } break; - - case eStopReasonWatchpoint: { - static char wp_desc[] = "watchpoint hit"; - stop_desc = wp_desc; - stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size - } break; - - case eStopReasonSignal: { - stop_desc = - exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString( - stop_info_sp->GetValue()); - if (stop_desc == nullptr || stop_desc[0] == '\0') { - static char signal_desc[] = "signal"; - stop_desc = signal_desc; - stop_desc_len = - sizeof(signal_desc); // Include the NULL byte for size - } - } break; - - case eStopReasonException: { - char exc_desc[] = "exception"; - stop_desc = exc_desc; - stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size - } break; - - case eStopReasonExec: { - char exc_desc[] = "exec"; - stop_desc = exc_desc; - stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size - } break; - - case eStopReasonThreadExiting: { - char limbo_desc[] = "thread exiting"; - stop_desc = limbo_desc; - stop_desc_len = sizeof(limbo_desc); - } break; - default: - break; - } + if (!exe_ctx.HasThreadScope()) + return 0; - if (stop_desc && stop_desc[0]) { - if (dst) - return ::snprintf(dst, dst_len, "%s", stop_desc) + - 1; // Include the NULL byte + Process::StopLocker stop_locker; + if (!stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + return 0; - if (stop_desc_len == 0) - stop_desc_len = ::strlen(stop_desc) + 1; // Include the NULL byte + std::string thread_stop_desc = exe_ctx.GetThreadPtr()->GetStopDescription(); + if (thread_stop_desc.empty()) + return 0; - return stop_desc_len; - } - } - } - } - } if (dst) - *dst = 0; - return 0; + return ::snprintf(dst, dst_len, "%s", thread_stop_desc.c_str()) + 1; + + // NULL dst passed in, return the length needed to contain the + // description. + return thread_stop_desc.size() + 1; // Include the NULL byte for size } SBValue SBThread::GetStopReturnValue() { @@ -970,23 +901,20 @@ SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) { SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, bool resume_immediately) { LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan, - (const char *, bool), script_class_name, + (const char *, bool), script_class_name, resume_immediately); lldb::SBStructuredData no_data; - return LLDB_RECORD_RESULT( - StepUsingScriptedThreadPlan(script_class_name, - no_data, - resume_immediately)); + return LLDB_RECORD_RESULT(StepUsingScriptedThreadPlan( + script_class_name, no_data, resume_immediately)); } SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, SBStructuredData &args_data, bool resume_immediately) { LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan, - (const char *, lldb::SBStructuredData &, bool), - script_class_name, args_data, - resume_immediately); + (const char *, lldb::SBStructuredData &, bool), + script_class_name, args_data, resume_immediately); SBError error; @@ -1444,8 +1372,6 @@ void RegisterMethods(Registry &R) { LLDB_REGISTER_METHOD(lldb::SBThreadCollection, SBThread, GetStopReasonExtendedBacktraces, (lldb::InstrumentationRuntimeType)); - LLDB_REGISTER_METHOD(size_t, SBThread, GetStopDescription, - (char *, size_t)); LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetStopReturnValue, ()); LLDB_REGISTER_METHOD_CONST(lldb::tid_t, SBThread, GetThreadID, ()); LLDB_REGISTER_METHOD_CONST(uint32_t, SBThread, GetIndexID, ()); @@ -1522,6 +1448,7 @@ void RegisterMethods(Registry &R) { LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetCurrentExceptionBacktrace, ()); LLDB_REGISTER_METHOD(bool, SBThread, SafeToCallFunctions, ()); + LLDB_REGISTER_CHAR_PTR_METHOD(size_t, SBThread, GetStopDescription); } } diff --git a/gnu/llvm/lldb/source/API/SBThreadCollection.cpp b/gnu/llvm/lldb/source/API/SBThreadCollection.cpp index 3c1cf986506..bfca864d6bc 100644 --- a/gnu/llvm/lldb/source/API/SBThreadCollection.cpp +++ b/gnu/llvm/lldb/source/API/SBThreadCollection.cpp @@ -1,4 +1,4 @@ -//===-- SBThreadCollection.cpp ----------------------------------*- C++ -*-===// +//===-- SBThreadCollection.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -38,7 +38,7 @@ operator=(const SBThreadCollection &rhs) { SBThreadCollection::SBThreadCollection(const ThreadCollectionSP &threads) : m_opaque_sp(threads) {} -SBThreadCollection::~SBThreadCollection() {} +SBThreadCollection::~SBThreadCollection() = default; void SBThreadCollection::SetOpaque(const lldb::ThreadCollectionSP &threads) { m_opaque_sp = threads; diff --git a/gnu/llvm/lldb/source/API/SBThreadPlan.cpp b/gnu/llvm/lldb/source/API/SBThreadPlan.cpp index eed4d1bfb9c..1a947bbc260 100644 --- a/gnu/llvm/lldb/source/API/SBThreadPlan.cpp +++ b/gnu/llvm/lldb/source/API/SBThreadPlan.cpp @@ -1,4 +1,4 @@ -//===-- SBThreadPlan.cpp ----------------------------------------*- C++ -*-===// +//===-- SBThreadPlan.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -96,7 +96,7 @@ const lldb::SBThreadPlan &SBThreadPlan::operator=(const SBThreadPlan &rhs) { return LLDB_RECORD_RESULT(*this); } // Destructor -SBThreadPlan::~SBThreadPlan() {} +SBThreadPlan::~SBThreadPlan() = default; lldb_private::ThreadPlan *SBThreadPlan::get() { return m_opaque_sp.get(); } @@ -237,7 +237,9 @@ SBThreadPlan SBThreadPlan::QueueThreadPlanForStepOverRange( if (plan_status.Fail()) error.SetErrorString(plan_status.AsCString()); - + else + plan.m_opaque_sp->SetPrivate(true); + return LLDB_RECORD_RESULT(plan); } else { return LLDB_RECORD_RESULT(SBThreadPlan()); @@ -281,6 +283,8 @@ SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address, if (plan_status.Fail()) error.SetErrorString(plan_status.AsCString()); + else + plan.m_opaque_sp->SetPrivate(true); return LLDB_RECORD_RESULT(plan); } else { @@ -321,6 +325,8 @@ SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, if (plan_status.Fail()) error.SetErrorString(plan_status.AsCString()); + else + plan.m_opaque_sp->SetPrivate(true); return LLDB_RECORD_RESULT(plan); } else { @@ -356,6 +362,8 @@ SBThreadPlan SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address, if (plan_status.Fail()) error.SetErrorString(plan_status.AsCString()); + else + plan.m_opaque_sp->SetPrivate(true); return LLDB_RECORD_RESULT(plan); } else { @@ -390,6 +398,8 @@ SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name, if (plan_status.Fail()) error.SetErrorString(plan_status.AsCString()); + else + plan.m_opaque_sp->SetPrivate(true); return LLDB_RECORD_RESULT(plan); } else { @@ -415,6 +425,8 @@ SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name, if (plan_status.Fail()) error.SetErrorString(plan_status.AsCString()); + else + plan.m_opaque_sp->SetPrivate(true); return LLDB_RECORD_RESULT(plan); } else { diff --git a/gnu/llvm/lldb/source/API/SBTrace.cpp b/gnu/llvm/lldb/source/API/SBTrace.cpp index 9b871e6781d..3fdabaa29ac 100644 --- a/gnu/llvm/lldb/source/API/SBTrace.cpp +++ b/gnu/llvm/lldb/source/API/SBTrace.cpp @@ -1,4 +1,4 @@ -//===-- SBTrace.cpp ---------------------------------------------*- C++ -*-===// +//===-- SBTrace.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/API/SBTraceOptions.cpp b/gnu/llvm/lldb/source/API/SBTraceOptions.cpp index a24cdd59af0..f1f5a63edf0 100644 --- a/gnu/llvm/lldb/source/API/SBTraceOptions.cpp +++ b/gnu/llvm/lldb/source/API/SBTraceOptions.cpp @@ -1,4 +1,4 @@ -//===-- SBTraceOptions.cpp --------------------------------------*- C++ -*-===// +//===-- SBTraceOptions.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/API/SBType.cpp b/gnu/llvm/lldb/source/API/SBType.cpp index 33b67ad4c00..852630f2d01 100644 --- a/gnu/llvm/lldb/source/API/SBType.cpp +++ b/gnu/llvm/lldb/source/API/SBType.cpp @@ -1,4 +1,4 @@ -//===-- SBType.cpp ----------------------------------------------*- C++ -*-===// +//===-- SBType.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -89,7 +89,7 @@ SBType &SBType::operator=(const SBType &rhs) { return LLDB_RECORD_RESULT(*this); } -SBType::~SBType() {} +SBType::~SBType() = default; TypeImpl &SBType::ref() { if (m_opaque_sp.get() == nullptr) @@ -589,7 +589,7 @@ SBTypeList &SBTypeList::operator=(const SBTypeList &rhs) { SBTypeList, operator=,(const lldb::SBTypeList &), rhs); if (this != &rhs) { - m_opaque_up.reset(new TypeListImpl()); + m_opaque_up = std::make_unique(); for (uint32_t i = 0, rhs_size = const_cast(rhs).GetSize(); i < rhs_size; i++) Append(const_cast(rhs).GetTypeAtIndex(i)); @@ -619,20 +619,20 @@ uint32_t SBTypeList::GetSize() { return m_opaque_up->GetSize(); } -SBTypeList::~SBTypeList() {} +SBTypeList::~SBTypeList() = default; SBTypeMember::SBTypeMember() : m_opaque_up() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBTypeMember); } -SBTypeMember::~SBTypeMember() {} +SBTypeMember::~SBTypeMember() = default; SBTypeMember::SBTypeMember(const SBTypeMember &rhs) : m_opaque_up() { LLDB_RECORD_CONSTRUCTOR(SBTypeMember, (const lldb::SBTypeMember &), rhs); if (this != &rhs) { if (rhs.IsValid()) - m_opaque_up.reset(new TypeMemberImpl(rhs.ref())); + m_opaque_up = std::make_unique(rhs.ref()); } } @@ -642,7 +642,7 @@ lldb::SBTypeMember &SBTypeMember::operator=(const lldb::SBTypeMember &rhs) { if (this != &rhs) { if (rhs.IsValid()) - m_opaque_up.reset(new TypeMemberImpl(rhs.ref())); + m_opaque_up = std::make_unique(rhs.ref()); } return LLDB_RECORD_RESULT(*this); } @@ -746,7 +746,7 @@ void SBTypeMember::reset(TypeMemberImpl *type_member_impl) { TypeMemberImpl &SBTypeMember::ref() { if (m_opaque_up == nullptr) - m_opaque_up.reset(new TypeMemberImpl()); + m_opaque_up = std::make_unique(); return *m_opaque_up; } @@ -756,7 +756,7 @@ SBTypeMemberFunction::SBTypeMemberFunction() : m_opaque_sp() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBTypeMemberFunction); } -SBTypeMemberFunction::~SBTypeMemberFunction() {} +SBTypeMemberFunction::~SBTypeMemberFunction() = default; SBTypeMemberFunction::SBTypeMemberFunction(const SBTypeMemberFunction &rhs) : m_opaque_sp(rhs.m_opaque_sp) { @@ -802,7 +802,7 @@ const char *SBTypeMemberFunction::GetDemangledName() { ConstString mangled_str = m_opaque_sp->GetMangledName(); if (mangled_str) { Mangled mangled(mangled_str); - return mangled.GetDemangledName(mangled.GuessLanguage()).GetCString(); + return mangled.GetDemangledName().GetCString(); } } return nullptr; diff --git a/gnu/llvm/lldb/source/API/SBTypeCategory.cpp b/gnu/llvm/lldb/source/API/SBTypeCategory.cpp index 1e449657509..9ce1a57ec4f 100644 --- a/gnu/llvm/lldb/source/API/SBTypeCategory.cpp +++ b/gnu/llvm/lldb/source/API/SBTypeCategory.cpp @@ -1,5 +1,4 @@ -//===-- SBTypeCategory.cpp ----------------------------------------*- C++ -//-*-===// +//===-- SBTypeCategory.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -40,7 +39,7 @@ SBTypeCategory::SBTypeCategory(const lldb::SBTypeCategory &rhs) LLDB_RECORD_CONSTRUCTOR(SBTypeCategory, (const lldb::SBTypeCategory &), rhs); } -SBTypeCategory::~SBTypeCategory() {} +SBTypeCategory::~SBTypeCategory() = default; bool SBTypeCategory::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBTypeCategory, IsValid); diff --git a/gnu/llvm/lldb/source/API/SBTypeEnumMember.cpp b/gnu/llvm/lldb/source/API/SBTypeEnumMember.cpp index bd0755a140c..43a4891b54b 100644 --- a/gnu/llvm/lldb/source/API/SBTypeEnumMember.cpp +++ b/gnu/llvm/lldb/source/API/SBTypeEnumMember.cpp @@ -1,4 +1,4 @@ -//===-- SBTypeEnumMember.cpp ---------------------------------- -*- C++ -*-===// +//===-- SBTypeEnumMember.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,7 +25,7 @@ SBTypeEnumMember::SBTypeEnumMember() : m_opaque_sp() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBTypeEnumMember); } -SBTypeEnumMember::~SBTypeEnumMember() {} +SBTypeEnumMember::~SBTypeEnumMember() = default; SBTypeEnumMember::SBTypeEnumMember( const lldb::TypeEnumMemberImplSP &enum_member_sp) @@ -141,7 +141,7 @@ operator=(const SBTypeEnumMemberList &rhs) { rhs); if (this != &rhs) { - m_opaque_up.reset(new TypeEnumMemberListImpl()); + m_opaque_up = std::make_unique(); for (uint32_t i = 0, rhs_size = const_cast(rhs).GetSize(); i < rhs_size; i++) @@ -176,7 +176,7 @@ uint32_t SBTypeEnumMemberList::GetSize() { return m_opaque_up->GetSize(); } -SBTypeEnumMemberList::~SBTypeEnumMemberList() {} +SBTypeEnumMemberList::~SBTypeEnumMemberList() = default; bool SBTypeEnumMember::GetDescription( lldb::SBStream &description, lldb::DescriptionLevel description_level) { diff --git a/gnu/llvm/lldb/source/API/SBTypeFilter.cpp b/gnu/llvm/lldb/source/API/SBTypeFilter.cpp index d40301b4c15..5f91a194f16 100644 --- a/gnu/llvm/lldb/source/API/SBTypeFilter.cpp +++ b/gnu/llvm/lldb/source/API/SBTypeFilter.cpp @@ -1,5 +1,4 @@ -//===-- SBTypeFilter.cpp ------------------------------------------*- C++ -//-*-===// +//===-- SBTypeFilter.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -31,7 +30,7 @@ SBTypeFilter::SBTypeFilter(const lldb::SBTypeFilter &rhs) LLDB_RECORD_CONSTRUCTOR(SBTypeFilter, (const lldb::SBTypeFilter &), rhs); } -SBTypeFilter::~SBTypeFilter() {} +SBTypeFilter::~SBTypeFilter() = default; bool SBTypeFilter::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBTypeFilter, IsValid); diff --git a/gnu/llvm/lldb/source/API/SBTypeFormat.cpp b/gnu/llvm/lldb/source/API/SBTypeFormat.cpp index 6024631e705..70289bef8db 100644 --- a/gnu/llvm/lldb/source/API/SBTypeFormat.cpp +++ b/gnu/llvm/lldb/source/API/SBTypeFormat.cpp @@ -1,5 +1,4 @@ -//===-- SBTypeFormat.cpp ------------------------------------------*- C++ -//-*-===// +//===-- SBTypeFormat.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -40,7 +39,7 @@ SBTypeFormat::SBTypeFormat(const lldb::SBTypeFormat &rhs) LLDB_RECORD_CONSTRUCTOR(SBTypeFormat, (const lldb::SBTypeFormat &), rhs); } -SBTypeFormat::~SBTypeFormat() {} +SBTypeFormat::~SBTypeFormat() = default; bool SBTypeFormat::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBTypeFormat, IsValid); diff --git a/gnu/llvm/lldb/source/API/SBTypeNameSpecifier.cpp b/gnu/llvm/lldb/source/API/SBTypeNameSpecifier.cpp index 895f6977565..3673a502453 100644 --- a/gnu/llvm/lldb/source/API/SBTypeNameSpecifier.cpp +++ b/gnu/llvm/lldb/source/API/SBTypeNameSpecifier.cpp @@ -1,5 +1,4 @@ -//===-- SBTypeNameSpecifier.cpp ------------------------------------*- C++ -//-*-===// +//===-- SBTypeNameSpecifier.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -45,7 +44,7 @@ SBTypeNameSpecifier::SBTypeNameSpecifier(const lldb::SBTypeNameSpecifier &rhs) (const lldb::SBTypeNameSpecifier &), rhs); } -SBTypeNameSpecifier::~SBTypeNameSpecifier() {} +SBTypeNameSpecifier::~SBTypeNameSpecifier() = default; bool SBTypeNameSpecifier::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBTypeNameSpecifier, IsValid); diff --git a/gnu/llvm/lldb/source/API/SBTypeSummary.cpp b/gnu/llvm/lldb/source/API/SBTypeSummary.cpp index 8ffb2343575..3800ae940c7 100644 --- a/gnu/llvm/lldb/source/API/SBTypeSummary.cpp +++ b/gnu/llvm/lldb/source/API/SBTypeSummary.cpp @@ -1,5 +1,4 @@ -//===-- SBTypeSummary.cpp -----------------------------------------*- C++ -//-*-===// +//===-- SBTypeSummary.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -22,7 +21,7 @@ using namespace lldb_private; SBTypeSummaryOptions::SBTypeSummaryOptions() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBTypeSummaryOptions); - m_opaque_up.reset(new TypeSummaryOptions()); + m_opaque_up = std::make_unique(); } SBTypeSummaryOptions::SBTypeSummaryOptions( @@ -33,7 +32,7 @@ SBTypeSummaryOptions::SBTypeSummaryOptions( m_opaque_up = clone(rhs.m_opaque_up); } -SBTypeSummaryOptions::~SBTypeSummaryOptions() {} +SBTypeSummaryOptions::~SBTypeSummaryOptions() = default; bool SBTypeSummaryOptions::IsValid() { LLDB_RECORD_METHOD_NO_ARGS(bool, SBTypeSummaryOptions, IsValid); @@ -112,9 +111,9 @@ SBTypeSummaryOptions::SBTypeSummaryOptions( void SBTypeSummaryOptions::SetOptions( const lldb_private::TypeSummaryOptions *lldb_object_ptr) { if (lldb_object_ptr) - m_opaque_up.reset(new TypeSummaryOptions(*lldb_object_ptr)); + m_opaque_up = std::make_unique(*lldb_object_ptr); else - m_opaque_up.reset(new TypeSummaryOptions()); + m_opaque_up = std::make_unique(); } SBTypeSummary::SBTypeSummary() : m_opaque_sp() { @@ -193,7 +192,7 @@ SBTypeSummary::SBTypeSummary(const lldb::SBTypeSummary &rhs) LLDB_RECORD_CONSTRUCTOR(SBTypeSummary, (const lldb::SBTypeSummary &), rhs); } -SBTypeSummary::~SBTypeSummary() {} +SBTypeSummary::~SBTypeSummary() = default; bool SBTypeSummary::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBTypeSummary, IsValid); diff --git a/gnu/llvm/lldb/source/API/SBTypeSynthetic.cpp b/gnu/llvm/lldb/source/API/SBTypeSynthetic.cpp index df6fce1269f..af5e167b9c2 100644 --- a/gnu/llvm/lldb/source/API/SBTypeSynthetic.cpp +++ b/gnu/llvm/lldb/source/API/SBTypeSynthetic.cpp @@ -1,5 +1,4 @@ -//===-- SBTypeSynthetic.cpp -----------------------------------------*- C++ -//-*-===// +//===-- SBTypeSynthetic.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -51,7 +50,7 @@ SBTypeSynthetic::SBTypeSynthetic(const lldb::SBTypeSynthetic &rhs) rhs); } -SBTypeSynthetic::~SBTypeSynthetic() {} +SBTypeSynthetic::~SBTypeSynthetic() = default; bool SBTypeSynthetic::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBTypeSynthetic, IsValid); diff --git a/gnu/llvm/lldb/source/API/SBUnixSignals.cpp b/gnu/llvm/lldb/source/API/SBUnixSignals.cpp index 277a92d21ae..a933f6d2233 100644 --- a/gnu/llvm/lldb/source/API/SBUnixSignals.cpp +++ b/gnu/llvm/lldb/source/API/SBUnixSignals.cpp @@ -1,5 +1,4 @@ -//===-- SBUnixSignals.cpp -------------------------------------------*- C++ -//-*-===// +//===-- SBUnixSignals.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -43,7 +42,7 @@ const SBUnixSignals &SBUnixSignals::operator=(const SBUnixSignals &rhs) { return LLDB_RECORD_RESULT(*this); } -SBUnixSignals::~SBUnixSignals() {} +SBUnixSignals::~SBUnixSignals() = default; UnixSignalsSP SBUnixSignals::GetSP() const { return m_opaque_wp.lock(); } diff --git a/gnu/llvm/lldb/source/API/SBValue.cpp b/gnu/llvm/lldb/source/API/SBValue.cpp index 396a9d3ea10..7485b0ee183 100644 --- a/gnu/llvm/lldb/source/API/SBValue.cpp +++ b/gnu/llvm/lldb/source/API/SBValue.cpp @@ -1,4 +1,4 @@ -//===-- SBValue.cpp ---------------------------------------------*- C++ -*-===// +//===-- SBValue.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -53,7 +53,7 @@ using namespace lldb_private; class ValueImpl { public: - ValueImpl() {} + ValueImpl() = default; ValueImpl(lldb::ValueObjectSP in_valobj_sp, lldb::DynamicValueType use_dynamic, bool use_synthetic, @@ -137,7 +137,7 @@ public: } if (m_use_synthetic) { - ValueObjectSP synthetic_sp = value_sp->GetSyntheticValue(m_use_synthetic); + ValueObjectSP synthetic_sp = value_sp->GetSyntheticValue(); if (synthetic_sp) value_sp = synthetic_sp; } @@ -201,7 +201,7 @@ private: class ValueLocker { public: - ValueLocker() {} + ValueLocker() = default; ValueObjectSP GetLockedSP(ValueImpl &in_value) { return in_value.GetSP(m_stop_locker, m_lock, m_lock_error); @@ -239,7 +239,7 @@ SBValue &SBValue::operator=(const SBValue &rhs) { return LLDB_RECORD_RESULT(*this); } -SBValue::~SBValue() {} +SBValue::~SBValue() = default; bool SBValue::IsValid() { LLDB_RECORD_METHOD_NO_ARGS(bool, SBValue, IsValid); @@ -1154,7 +1154,7 @@ bool SBValue::GetExpressionPath(SBStream &description) { ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); if (value_sp) { - value_sp->GetExpressionPath(description.ref(), false); + value_sp->GetExpressionPath(description.ref()); return true; } return false; @@ -1168,7 +1168,7 @@ bool SBValue::GetExpressionPath(SBStream &description, ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); if (value_sp) { - value_sp->GetExpressionPath(description.ref(), qualify_cxx_base_classes); + value_sp->GetExpressionPath(description.ref()); return true; } return false; @@ -1493,7 +1493,7 @@ lldb::SBWatchpoint SBValue::Watch(bool resolve_location, bool read, bool write, StreamString ss; // True to show fullpath for declaration file. decl.DumpStopContext(&ss, true); - watchpoint_sp->SetDeclInfo(ss.GetString()); + watchpoint_sp->SetDeclInfo(std::string(ss.GetString())); } } } diff --git a/gnu/llvm/lldb/source/API/SBValueList.cpp b/gnu/llvm/lldb/source/API/SBValueList.cpp index 7e909df260d..0fd2a591c32 100644 --- a/gnu/llvm/lldb/source/API/SBValueList.cpp +++ b/gnu/llvm/lldb/source/API/SBValueList.cpp @@ -1,4 +1,4 @@ -//===-- SBValueList.cpp -----------------------------------------*- C++ -*-===// +//===-- SBValueList.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -75,15 +75,15 @@ SBValueList::SBValueList(const SBValueList &rhs) : m_opaque_up() { LLDB_RECORD_CONSTRUCTOR(SBValueList, (const lldb::SBValueList &), rhs); if (rhs.IsValid()) - m_opaque_up.reset(new ValueListImpl(*rhs)); + m_opaque_up = std::make_unique(*rhs); } SBValueList::SBValueList(const ValueListImpl *lldb_object_ptr) : m_opaque_up() { if (lldb_object_ptr) - m_opaque_up.reset(new ValueListImpl(*lldb_object_ptr)); + m_opaque_up = std::make_unique(*lldb_object_ptr); } -SBValueList::~SBValueList() {} +SBValueList::~SBValueList() = default; bool SBValueList::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBValueList, IsValid); @@ -107,7 +107,7 @@ const SBValueList &SBValueList::operator=(const SBValueList &rhs) { if (this != &rhs) { if (rhs.IsValid()) - m_opaque_up.reset(new ValueListImpl(*rhs)); + m_opaque_up = std::make_unique(*rhs); else m_opaque_up.reset(); } @@ -173,7 +173,7 @@ uint32_t SBValueList::GetSize() const { void SBValueList::CreateIfNeeded() { if (m_opaque_up == nullptr) - m_opaque_up.reset(new ValueListImpl()); + m_opaque_up = std::make_unique(); } SBValue SBValueList::FindValueObjectByUID(lldb::user_id_t uid) { diff --git a/gnu/llvm/lldb/source/API/SBVariablesOptions.cpp b/gnu/llvm/lldb/source/API/SBVariablesOptions.cpp index bf0197cd960..4ef16364e62 100644 --- a/gnu/llvm/lldb/source/API/SBVariablesOptions.cpp +++ b/gnu/llvm/lldb/source/API/SBVariablesOptions.cpp @@ -1,5 +1,4 @@ -//===-- SBVariablesOptions.cpp --------------------------------------*- C++ -//-*-===// +//===-- SBVariablesOptions.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -98,7 +97,7 @@ operator=(const SBVariablesOptions &options) { SBVariablesOptions, operator=,(const lldb::SBVariablesOptions &), options); - m_opaque_up.reset(new VariablesOptionsImpl(options.ref())); + m_opaque_up = std::make_unique(options.ref()); return LLDB_RECORD_RESULT(*this); } diff --git a/gnu/llvm/lldb/source/API/SBWatchpoint.cpp b/gnu/llvm/lldb/source/API/SBWatchpoint.cpp index d0a36b71e5c..eba75dea8f8 100644 --- a/gnu/llvm/lldb/source/API/SBWatchpoint.cpp +++ b/gnu/llvm/lldb/source/API/SBWatchpoint.cpp @@ -1,4 +1,4 @@ -//===-- SBWatchpoint.cpp --------------------------------*- C++ -*-===// +//===-- SBWatchpoint.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -46,7 +46,7 @@ const SBWatchpoint &SBWatchpoint::operator=(const SBWatchpoint &rhs) { return LLDB_RECORD_RESULT(*this); } -SBWatchpoint::~SBWatchpoint() {} +SBWatchpoint::~SBWatchpoint() = default; watch_id_t SBWatchpoint::GetID() { LLDB_RECORD_METHOD_NO_ARGS(lldb::watch_id_t, SBWatchpoint, GetID); diff --git a/gnu/llvm/lldb/source/API/SystemInitializerFull.cpp b/gnu/llvm/lldb/source/API/SystemInitializerFull.cpp index 06f1a6cd3b7..7f95e7acf62 100644 --- a/gnu/llvm/lldb/source/API/SystemInitializerFull.cpp +++ b/gnu/llvm/lldb/source/API/SystemInitializerFull.cpp @@ -1,4 +1,4 @@ -//===-- SystemInitializerFull.cpp -------------------------------*- C++ -*-===// +//===-- SystemInitializerFull.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,119 +8,13 @@ #include "SystemInitializerFull.h" #include "lldb/API/SBCommandInterpreter.h" -#include "lldb/Host/Config.h" - -#if LLDB_ENABLE_PYTHON -#include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h" -#endif - -#if LLDB_ENABLE_LUA -#include "Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h" -#endif - #include "lldb/Core/Debugger.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Host/Config.h" #include "lldb/Host/Host.h" #include "lldb/Initialization/SystemInitializerCommon.h" #include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Utility/Timer.h" - -#include "Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h" -#include "Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h" -#include "Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h" -#include "Plugins/ABI/SysV-arc/ABISysV_arc.h" -#include "Plugins/ABI/SysV-arm/ABISysV_arm.h" -#include "Plugins/ABI/SysV-arm64/ABISysV_arm64.h" -#include "Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h" -#include "Plugins/ABI/SysV-i386/ABISysV_i386.h" -#include "Plugins/ABI/SysV-mips/ABISysV_mips.h" -#include "Plugins/ABI/SysV-mips64/ABISysV_mips64.h" -#include "Plugins/ABI/SysV-ppc/ABISysV_ppc.h" -#include "Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h" -#include "Plugins/ABI/SysV-s390x/ABISysV_s390x.h" -#include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h" -#include "Plugins/ABI/Windows-x86_64/ABIWindows_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" -#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h" -#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h" -#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h" -#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h" -#include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h" -#include "Plugins/Instruction/ARM/EmulateInstructionARM.h" -#include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h" -#include "Plugins/Instruction/MIPS/EmulateInstructionMIPS.h" -#include "Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h" -#include "Plugins/Instruction/PPC64/EmulateInstructionPPC64.h" -#include "Plugins/InstrumentationRuntime/ASan/ASanRuntime.h" -#include "Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.h" -#include "Plugins/InstrumentationRuntime/TSan/TSanRuntime.h" -#include "Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.h" -#include "Plugins/JITLoader/GDB/JITLoaderGDB.h" -#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" -#include "Plugins/Language/ObjC/ObjCLanguage.h" -#include "Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h" -#include "Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h" -#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h" -#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h" -#include "Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h" -#include "Plugins/MemoryHistory/asan/MemoryHistoryASan.h" -#include "Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h" -#include "Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h" -#include "Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h" -#include "Plugins/ObjectFile/ELF/ObjectFileELF.h" -#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h" -#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h" -#include "Plugins/OperatingSystem/Python/OperatingSystemPython.h" -#include "Plugins/Platform/Android/PlatformAndroid.h" -#include "Plugins/Platform/FreeBSD/PlatformFreeBSD.h" -#include "Plugins/Platform/Linux/PlatformLinux.h" -#include "Plugins/Platform/MacOSX/PlatformMacOSX.h" -#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h" -#include "Plugins/Platform/NetBSD/PlatformNetBSD.h" -#include "Plugins/Platform/OpenBSD/PlatformOpenBSD.h" -#include "Plugins/Platform/Windows/PlatformWindows.h" -#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h" -#include "Plugins/Process/elf-core/ProcessElfCore.h" -#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h" -#include "Plugins/Process/mach-core/ProcessMachCore.h" -#include "Plugins/Process/minidump/ProcessMinidump.h" -#include "Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h" -#include "Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h" -#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" -#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h" -#include "Plugins/SymbolFile/PDB/SymbolFilePDB.h" -#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h" -#include "Plugins/SymbolVendor/ELF/SymbolVendorELF.h" -#include "Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h" -#include "Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h" -#include "Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h" - -#if defined(__APPLE__) -#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h" -#include "Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h" -#include "Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h" -#include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h" -#include "Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.h" -#include "Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h" -#include "Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h" -#include "Plugins/Platform/MacOSX/PlatformiOSSimulator.h" -#include "Plugins/Process/MacOSX-Kernel/ProcessKDP.h" -#include "Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h" -#endif -#include "Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h" - -#if defined(__FreeBSD__) -#include "Plugins/Process/FreeBSD/ProcessFreeBSD.h" -#endif - -#if defined(_WIN32) -#include "Plugins/Process/Windows/Common/ProcessWindows.h" -#include "lldb/Host/windows/windows.h" -#endif - #include "llvm/Support/TargetSelect.h" #pragma clang diagnostic push @@ -130,174 +24,32 @@ #include -using namespace lldb_private; - -SystemInitializerFull::SystemInitializerFull() {} - -SystemInitializerFull::~SystemInitializerFull() {} +#define LLDB_PLUGIN(p) LLDB_PLUGIN_DECLARE(p) +#include "Plugins/Plugins.def" -#define LLDB_PROCESS_AArch64(op) \ - ABIMacOSX_arm64::op(); \ - ABISysV_arm64::op(); -#define LLDB_PROCESS_ARM(op) \ - ABIMacOSX_arm::op(); \ - ABISysV_arm::op(); -#define LLDB_PROCESS_ARC(op) \ - ABISysV_arc::op(); -#define LLDB_PROCESS_Hexagon(op) ABISysV_hexagon::op(); -#define LLDB_PROCESS_Mips(op) \ - ABISysV_mips::op(); \ - ABISysV_mips64::op(); -#define LLDB_PROCESS_PowerPC(op) \ - ABISysV_ppc::op(); \ - ABISysV_ppc64::op(); -#define LLDB_PROCESS_SystemZ(op) ABISysV_s390x::op(); -#define LLDB_PROCESS_X86(op) \ - ABIMacOSX_i386::op(); \ - ABISysV_i386::op(); \ - ABISysV_x86_64::op(); \ - ABIWindows_x86_64::op(); +using namespace lldb_private; -#define LLDB_PROCESS_AMDGPU(op) -#define LLDB_PROCESS_AVR(op) -#define LLDB_PROCESS_BPF(op) -#define LLDB_PROCESS_Lanai(op) -#define LLDB_PROCESS_MSP430(op) -#define LLDB_PROCESS_NVPTX(op) -#define LLDB_PROCESS_RISCV(op) -#define LLDB_PROCESS_Sparc(op) -#define LLDB_PROCESS_WebAssembly(op) -#define LLDB_PROCESS_XCore(op) +SystemInitializerFull::SystemInitializerFull() = default; +SystemInitializerFull::~SystemInitializerFull() = default; llvm::Error SystemInitializerFull::Initialize() { if (auto e = SystemInitializerCommon::Initialize()) return e; - breakpad::ObjectFileBreakpad::Initialize(); - ObjectFileELF::Initialize(); - ObjectFileMachO::Initialize(); - ObjectFilePECOFF::Initialize(); - - ObjectContainerBSDArchive::Initialize(); - ObjectContainerUniversalMachO::Initialize(); - - ScriptInterpreterNone::Initialize(); - -#if LLDB_ENABLE_PYTHON - OperatingSystemPython::Initialize(); -#endif - -#if LLDB_ENABLE_PYTHON - ScriptInterpreterPython::Initialize(); -#endif - -#if LLDB_ENABLE_LUA - ScriptInterpreterLua::Initialize(); -#endif - - platform_freebsd::PlatformFreeBSD::Initialize(); - platform_linux::PlatformLinux::Initialize(); - platform_netbsd::PlatformNetBSD::Initialize(); - platform_openbsd::PlatformOpenBSD::Initialize(); - PlatformWindows::Initialize(); - platform_android::PlatformAndroid::Initialize(); - PlatformRemoteiOS::Initialize(); - PlatformMacOSX::Initialize(); -#if defined(__APPLE__) - PlatformiOSSimulator::Initialize(); - PlatformDarwinKernel::Initialize(); -#endif - // Initialize LLVM and Clang llvm::InitializeAllTargets(); llvm::InitializeAllAsmPrinters(); llvm::InitializeAllTargetMCs(); llvm::InitializeAllDisassemblers(); - ClangASTContext::Initialize(); - -#define LLVM_TARGET(t) LLDB_PROCESS_ ## t(Initialize) -#include "llvm/Config/Targets.def" - - ArchitectureArm::Initialize(); - ArchitectureMips::Initialize(); - ArchitecturePPC64::Initialize(); - - DisassemblerLLVMC::Initialize(); - - JITLoaderGDB::Initialize(); - ProcessElfCore::Initialize(); - ProcessMachCore::Initialize(); - minidump::ProcessMinidump::Initialize(); - MemoryHistoryASan::Initialize(); - AddressSanitizerRuntime::Initialize(); - ThreadSanitizerRuntime::Initialize(); - UndefinedBehaviorSanitizerRuntime::Initialize(); - MainThreadCheckerRuntime::Initialize(); - - SymbolVendorELF::Initialize(); - breakpad::SymbolFileBreakpad::Initialize(); - SymbolFileDWARF::Initialize(); - SymbolFilePDB::Initialize(); - SymbolFileSymtab::Initialize(); - UnwindAssemblyInstEmulation::Initialize(); - UnwindAssembly_x86::Initialize(); - - EmulateInstructionARM::Initialize(); - EmulateInstructionARM64::Initialize(); - EmulateInstructionMIPS::Initialize(); - EmulateInstructionMIPS64::Initialize(); - EmulateInstructionPPC64::Initialize(); - - SymbolFileDWARFDebugMap::Initialize(); - ItaniumABILanguageRuntime::Initialize(); - AppleObjCRuntimeV2::Initialize(); - AppleObjCRuntimeV1::Initialize(); - SystemRuntimeMacOSX::Initialize(); - RenderScriptRuntime::Initialize(); - - CPlusPlusLanguage::Initialize(); - ObjCLanguage::Initialize(); - ObjCPlusPlusLanguage::Initialize(); - -#if defined(_WIN32) - ProcessWindows::Initialize(); -#endif -#if defined(__FreeBSD__) - ProcessFreeBSD::Initialize(); -#endif -#if defined(__APPLE__) - SymbolVendorMacOSX::Initialize(); - ProcessKDP::Initialize(); - PlatformAppleTVSimulator::Initialize(); - PlatformAppleWatchSimulator::Initialize(); - PlatformRemoteAppleTV::Initialize(); - PlatformRemoteAppleWatch::Initialize(); - PlatformRemoteAppleBridge::Initialize(); - DynamicLoaderDarwinKernel::Initialize(); -#endif - - // This plugin is valid on any host that talks to a Darwin remote. It - // shouldn't be limited to __APPLE__. - StructuredDataDarwinLog::Initialize(); - - // Platform agnostic plugins - platform_gdb_server::PlatformRemoteGDBServer::Initialize(); - - process_gdb_remote::ProcessGDBRemote::Initialize(); - DynamicLoaderMacOSXDYLD::Initialize(); - DynamicLoaderMacOS::Initialize(); - DynamicLoaderPOSIXDYLD::Initialize(); - DynamicLoaderStatic::Initialize(); - DynamicLoaderWindowsDYLD::Initialize(); +#define LLDB_PLUGIN(p) LLDB_PLUGIN_INITIALIZE(p); +#include "Plugins/Plugins.def" // Scan for any system or user LLDB plug-ins PluginManager::Initialize(); // The process settings need to know about installed plug-ins, so the - // Settings must be initialized - // AFTER PluginManager::Initialize is called. - + // Settings must be initialized AFTER PluginManager::Initialize is called. Debugger::SettingsInitialize(); return llvm::Error::success(); @@ -312,101 +64,8 @@ void SystemInitializerFull::Terminate() { // Terminate and unload and loaded system or user LLDB plug-ins PluginManager::Terminate(); - ClangASTContext::Terminate(); - - ArchitectureArm::Terminate(); - ArchitectureMips::Terminate(); - ArchitecturePPC64::Terminate(); - -#define LLVM_TARGET(t) LLDB_PROCESS_ ## t(Terminate) -#include "llvm/Config/Targets.def" - - DisassemblerLLVMC::Terminate(); - - JITLoaderGDB::Terminate(); - ProcessElfCore::Terminate(); - ProcessMachCore::Terminate(); - minidump::ProcessMinidump::Terminate(); - MemoryHistoryASan::Terminate(); - AddressSanitizerRuntime::Terminate(); - ThreadSanitizerRuntime::Terminate(); - UndefinedBehaviorSanitizerRuntime::Terminate(); - MainThreadCheckerRuntime::Terminate(); - SymbolVendorELF::Terminate(); - breakpad::SymbolFileBreakpad::Terminate(); - SymbolFileDWARF::Terminate(); - SymbolFilePDB::Terminate(); - SymbolFileSymtab::Terminate(); - UnwindAssembly_x86::Terminate(); - UnwindAssemblyInstEmulation::Terminate(); - - EmulateInstructionARM::Terminate(); - EmulateInstructionARM64::Terminate(); - EmulateInstructionMIPS::Terminate(); - EmulateInstructionMIPS64::Terminate(); - EmulateInstructionPPC64::Terminate(); - - SymbolFileDWARFDebugMap::Terminate(); - ItaniumABILanguageRuntime::Terminate(); - AppleObjCRuntimeV2::Terminate(); - AppleObjCRuntimeV1::Terminate(); - SystemRuntimeMacOSX::Terminate(); - RenderScriptRuntime::Terminate(); - - CPlusPlusLanguage::Terminate(); - ObjCLanguage::Terminate(); - ObjCPlusPlusLanguage::Terminate(); - -#if defined(__APPLE__) - DynamicLoaderDarwinKernel::Terminate(); - ProcessKDP::Terminate(); - SymbolVendorMacOSX::Terminate(); - PlatformAppleTVSimulator::Terminate(); - PlatformAppleWatchSimulator::Terminate(); - PlatformRemoteAppleTV::Terminate(); - PlatformRemoteAppleWatch::Terminate(); - PlatformRemoteAppleBridge::Terminate(); -#endif - -#if defined(__FreeBSD__) - ProcessFreeBSD::Terminate(); -#endif - Debugger::SettingsTerminate(); - - platform_gdb_server::PlatformRemoteGDBServer::Terminate(); - process_gdb_remote::ProcessGDBRemote::Terminate(); - StructuredDataDarwinLog::Terminate(); - - DynamicLoaderMacOSXDYLD::Terminate(); - DynamicLoaderMacOS::Terminate(); - DynamicLoaderPOSIXDYLD::Terminate(); - DynamicLoaderStatic::Terminate(); - DynamicLoaderWindowsDYLD::Terminate(); - -#if LLDB_ENABLE_PYTHON - OperatingSystemPython::Terminate(); -#endif - - platform_freebsd::PlatformFreeBSD::Terminate(); - platform_linux::PlatformLinux::Terminate(); - platform_netbsd::PlatformNetBSD::Terminate(); - platform_openbsd::PlatformOpenBSD::Terminate(); - PlatformWindows::Terminate(); - platform_android::PlatformAndroid::Terminate(); - PlatformMacOSX::Terminate(); - PlatformRemoteiOS::Terminate(); -#if defined(__APPLE__) - PlatformiOSSimulator::Terminate(); - PlatformDarwinKernel::Terminate(); -#endif - - breakpad::ObjectFileBreakpad::Terminate(); - ObjectFileELF::Terminate(); - ObjectFileMachO::Terminate(); - ObjectFilePECOFF::Terminate(); - - ObjectContainerBSDArchive::Terminate(); - ObjectContainerUniversalMachO::Terminate(); +#define LLDB_PLUGIN(p) LLDB_PLUGIN_TERMINATE(p); +#include "Plugins/Plugins.def" // Now shutdown the common parts, in reverse order. SystemInitializerCommon::Terminate(); diff --git a/gnu/llvm/lldb/source/API/SystemInitializerFull.h b/gnu/llvm/lldb/source/API/SystemInitializerFull.h index cd88bae9785..7cab6cb9753 100644 --- a/gnu/llvm/lldb/source/API/SystemInitializerFull.h +++ b/gnu/llvm/lldb/source/API/SystemInitializerFull.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_API_SYSTEM_INITIALIZER_FULL_H -#define LLDB_API_SYSTEM_INITIALIZER_FULL_H +#ifndef LLDB_SOURCE_API_SYSTEMINITIALIZERFULL_H +#define LLDB_SOURCE_API_SYSTEMINITIALIZERFULL_H #include "lldb/Initialization/SystemInitializerCommon.h" @@ -29,4 +29,4 @@ public: } // namespace lldb_private -#endif // LLDB_API_SYSTEM_INITIALIZER_FULL_H +#endif // LLDB_SOURCE_API_SYSTEMINITIALIZERFULL_H diff --git a/gnu/llvm/lldb/source/API/Utils.h b/gnu/llvm/lldb/source/API/Utils.h index ed81534d2d1..4201e825c44 100644 --- a/gnu/llvm/lldb/source/API/Utils.h +++ b/gnu/llvm/lldb/source/API/Utils.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_API_UTILS_H -#define LLDB_API_UTILS_H +#ifndef LLDB_SOURCE_API_UTILS_H +#define LLDB_SOURCE_API_UTILS_H #include "llvm/ADT/STLExtras.h" #include diff --git a/gnu/llvm/lldb/source/Breakpoint/Breakpoint.cpp b/gnu/llvm/lldb/source/Breakpoint/Breakpoint.cpp index 13acf4bb92e..317dfa23109 100644 --- a/gnu/llvm/lldb/source/Breakpoint/Breakpoint.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/Breakpoint.cpp @@ -1,4 +1,4 @@ -//===-- Breakpoint.cpp ------------------------------------------*- C++ -*-===// +//===-- Breakpoint.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -55,21 +55,29 @@ Breakpoint::Breakpoint(Target &target, SearchFilterSP &filter_sp, m_being_created = false; } -Breakpoint::Breakpoint(Target &new_target, Breakpoint &source_bp) +Breakpoint::Breakpoint(Target &new_target, const Breakpoint &source_bp) : m_being_created(true), m_hardware(source_bp.m_hardware), m_target(new_target), m_name_list(source_bp.m_name_list), m_options_up(new BreakpointOptions(*source_bp.m_options_up)), m_locations(*this), m_resolve_indirect_symbols(source_bp.m_resolve_indirect_symbols), - m_hit_count(0) { - // Now go through and copy the filter & resolver: - m_resolver_sp = source_bp.m_resolver_sp->CopyForBreakpoint(*this); - m_filter_sp = source_bp.m_filter_sp->CopyForBreakpoint(*this); -} + m_hit_count(0) {} // Destructor Breakpoint::~Breakpoint() = default; +BreakpointSP Breakpoint::CopyFromBreakpoint(TargetSP new_target, + const Breakpoint& bp_to_copy_from) { + if (!new_target) + return BreakpointSP(); + + BreakpointSP bp(new Breakpoint(*new_target, bp_to_copy_from)); + // Now go through and copy the filter & resolver: + bp->m_resolver_sp = bp_to_copy_from.m_resolver_sp->CopyForBreakpoint(bp); + bp->m_filter_sp = bp_to_copy_from.m_filter_sp->CreateCopy(new_target); + return bp; +} + // Serialization StructuredData::ObjectSP Breakpoint::SerializeToStructuredData() { // Serialize the resolver: @@ -120,8 +128,10 @@ StructuredData::ObjectSP Breakpoint::SerializeToStructuredData() { } lldb::BreakpointSP Breakpoint::CreateFromStructuredData( - Target &target, StructuredData::ObjectSP &object_data, Status &error) { + TargetSP target_sp, StructuredData::ObjectSP &object_data, Status &error) { BreakpointSP result_sp; + if (!target_sp) + return result_sp; StructuredData::Dictionary *breakpoint_dict = object_data->GetAsDictionary(); @@ -155,11 +165,11 @@ lldb::BreakpointSP Breakpoint::CreateFromStructuredData( SearchFilter::GetSerializationKey(), filter_dict); SearchFilterSP filter_sp; if (!success) - filter_sp = std::make_shared( - target.shared_from_this()); + filter_sp = + std::make_shared(target_sp); else { - filter_sp = SearchFilter::CreateFromStructuredData(target, *filter_dict, - create_error); + filter_sp = SearchFilter::CreateFromStructuredData(target_sp, *filter_dict, + create_error); if (create_error.Fail()) { error.SetErrorStringWithFormat( "Error creating breakpoint filter from data: %s.", @@ -170,6 +180,7 @@ lldb::BreakpointSP Breakpoint::CreateFromStructuredData( std::unique_ptr options_up; StructuredData::Dictionary *options_dict; + Target& target = *target_sp; success = breakpoint_dict->GetValueForKeyAsDictionary( BreakpointOptions::GetSerializationKey(), options_dict); if (success) { @@ -187,8 +198,8 @@ lldb::BreakpointSP Breakpoint::CreateFromStructuredData( success = breakpoint_dict->GetValueForKeyAsBoolean( Breakpoint::GetKey(OptionNames::Hardware), hardware); - result_sp = - target.CreateBreakpoint(filter_sp, resolver_sp, false, hardware, true); + result_sp = target.CreateBreakpoint(filter_sp, resolver_sp, false, + hardware, true); if (result_sp && options_up) { result_sp->m_options_up = std::move(options_up); diff --git a/gnu/llvm/lldb/source/Breakpoint/BreakpointID.cpp b/gnu/llvm/lldb/source/Breakpoint/BreakpointID.cpp index dc2e57cb085..293baf4ad1c 100644 --- a/gnu/llvm/lldb/source/Breakpoint/BreakpointID.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/BreakpointID.cpp @@ -1,4 +1,4 @@ -//===-- BreakpointID.cpp ----------------------------------------*- C++ -*-===// +//===-- BreakpointID.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -112,7 +112,7 @@ bool BreakpointID::StringIsBreakpointName(llvm::StringRef str, Status &error) { // Cannot contain ., -, or space. if (str.find_first_of(".- ") != llvm::StringRef::npos) { error.SetErrorStringWithFormat("Breakpoint names cannot contain " - "'.' or '-': \"%s\"", + "'.' or '-' or spaces: \"%s\"", str.str().c_str()); return false; } diff --git a/gnu/llvm/lldb/source/Breakpoint/BreakpointIDList.cpp b/gnu/llvm/lldb/source/Breakpoint/BreakpointIDList.cpp index de68c44ec6a..705bc5ee1c8 100644 --- a/gnu/llvm/lldb/source/Breakpoint/BreakpointIDList.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/BreakpointIDList.cpp @@ -1,4 +1,4 @@ -//===-- BreakpointIDList.cpp ------------------------------------*- C++ -*-===// +//===-- BreakpointIDList.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -144,7 +144,7 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target, result.SetStatus(eReturnStatusFailed); return; } else - names_found.insert(current_arg); + names_found.insert(std::string(current_arg)); } else if ((i + 2 < old_args.size()) && BreakpointID::IsRangeIdentifier(old_args[i + 1].ref()) && BreakpointID::IsValidIDExpression(current_arg) && diff --git a/gnu/llvm/lldb/source/Breakpoint/BreakpointList.cpp b/gnu/llvm/lldb/source/Breakpoint/BreakpointList.cpp index 5b23c633d14..a962703b951 100644 --- a/gnu/llvm/lldb/source/Breakpoint/BreakpointList.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/BreakpointList.cpp @@ -1,4 +1,4 @@ -//===-- BreakpointList.cpp --------------------------------------*- C++ -*-===// +//===-- BreakpointList.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Breakpoint/BreakpointLocation.cpp b/gnu/llvm/lldb/source/Breakpoint/BreakpointLocation.cpp index 7f08b08c605..93d54c051ee 100644 --- a/gnu/llvm/lldb/source/Breakpoint/BreakpointLocation.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/BreakpointLocation.cpp @@ -1,4 +1,4 @@ -//===-- BreakpointLocation.cpp ----------------------------------*- C++ -*-===// +//===-- BreakpointLocation.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -369,7 +369,7 @@ BreakpointOptions *BreakpointLocation::GetLocationOptions() { // potentially expensive and we don't want to do that for the simple case // where someone is just disabling the location. if (m_options_up == nullptr) - m_options_up.reset(new BreakpointOptions(false)); + m_options_up = std::make_unique(false); return m_options_up.get(); } @@ -597,7 +597,8 @@ void BreakpointLocation::GetDescription(Stream *s, s->EOL(); s->Indent(); s->Printf("resolved = %s\n", IsResolved() ? "true" : "false"); - + s->Indent(); + s->Printf("hardware = %s\n", IsHardware() ? "true" : "false"); s->Indent(); s->Printf("hit count = %-4u\n", GetHitCount()); @@ -608,8 +609,8 @@ void BreakpointLocation::GetDescription(Stream *s, } s->IndentLess(); } else if (level != eDescriptionLevelInitial) { - s->Printf(", %sresolved, hit count = %u ", (IsResolved() ? "" : "un"), - GetHitCount()); + s->Printf(", %sresolved, %shit count = %u ", (IsResolved() ? "" : "un"), + (IsHardware() ? "hardware, " : ""), GetHitCount()); if (m_options_up) { m_options_up->GetDescription(s, level); } diff --git a/gnu/llvm/lldb/source/Breakpoint/BreakpointLocationCollection.cpp b/gnu/llvm/lldb/source/Breakpoint/BreakpointLocationCollection.cpp index 76084adbd2a..1eb13cb12ba 100644 --- a/gnu/llvm/lldb/source/Breakpoint/BreakpointLocationCollection.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/BreakpointLocationCollection.cpp @@ -1,4 +1,4 @@ -//===-- BreakpointLocationCollection.cpp ------------------------*- C++ -*-===// +//===-- BreakpointLocationCollection.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Breakpoint/BreakpointLocationList.cpp b/gnu/llvm/lldb/source/Breakpoint/BreakpointLocationList.cpp index ee586127ee7..6d271864c44 100644 --- a/gnu/llvm/lldb/source/Breakpoint/BreakpointLocationList.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/BreakpointLocationList.cpp @@ -1,4 +1,4 @@ -//===-- BreakpointLocationList.cpp ------------------------------*- C++ -*-===// +//===-- BreakpointLocationList.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Breakpoint/BreakpointName.cpp b/gnu/llvm/lldb/source/Breakpoint/BreakpointName.cpp index 749fa86bca9..37903a00236 100644 --- a/gnu/llvm/lldb/source/Breakpoint/BreakpointName.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/BreakpointName.cpp @@ -1,4 +1,4 @@ -//===-- BreakpointName.cpp --------------------------------------*- C++ -*-===// +//===-- BreakpointName.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Breakpoint/BreakpointOptions.cpp b/gnu/llvm/lldb/source/Breakpoint/BreakpointOptions.cpp index 8fd16f420c0..0ce7b0f852e 100644 --- a/gnu/llvm/lldb/source/Breakpoint/BreakpointOptions.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/BreakpointOptions.cpp @@ -1,4 +1,4 @@ -//===-- BreakpointOptions.cpp -----------------------------------*- C++ -*-===// +//===-- BreakpointOptions.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -154,7 +154,7 @@ BreakpointOptions::BreakpointOptions(const BreakpointOptions &rhs) m_ignore_count(rhs.m_ignore_count), m_thread_spec_up(), m_auto_continue(rhs.m_auto_continue), m_set_flags(rhs.m_set_flags) { if (rhs.m_thread_spec_up != nullptr) - m_thread_spec_up.reset(new ThreadSpec(*rhs.m_thread_spec_up)); + m_thread_spec_up = std::make_unique(*rhs.m_thread_spec_up); m_condition_text = rhs.m_condition_text; m_condition_text_hash = rhs.m_condition_text_hash; } @@ -170,7 +170,7 @@ operator=(const BreakpointOptions &rhs) { m_one_shot = rhs.m_one_shot; m_ignore_count = rhs.m_ignore_count; if (rhs.m_thread_spec_up != nullptr) - m_thread_spec_up.reset(new ThreadSpec(*rhs.m_thread_spec_up)); + m_thread_spec_up = std::make_unique(*rhs.m_thread_spec_up); m_condition_text = rhs.m_condition_text; m_condition_text_hash = rhs.m_condition_text_hash; m_auto_continue = rhs.m_auto_continue; @@ -223,7 +223,8 @@ void BreakpointOptions::CopyOverSetOptions(const BreakpointOptions &incoming) } if (incoming.m_set_flags.Test(eThreadSpec) && incoming.m_thread_spec_up) { if (!m_thread_spec_up) - m_thread_spec_up.reset(new ThreadSpec(*incoming.m_thread_spec_up)); + m_thread_spec_up = + std::make_unique(*incoming.m_thread_spec_up); else *m_thread_spec_up = *incoming.m_thread_spec_up; m_set_flags.Set(eThreadSpec); @@ -509,7 +510,7 @@ const ThreadSpec *BreakpointOptions::GetThreadSpecNoCreate() const { ThreadSpec *BreakpointOptions::GetThreadSpec() { if (m_thread_spec_up == nullptr) { m_set_flags.Set(eThreadSpec); - m_thread_spec_up.reset(new ThreadSpec()); + m_thread_spec_up = std::make_unique(); } return m_thread_spec_up.get(); @@ -630,11 +631,11 @@ bool BreakpointOptions::BreakpointOptionsCallbackFunction( ExecutionContext exe_ctx(context->exe_ctx_ref); Target *target = exe_ctx.GetTargetPtr(); if (target) { - CommandReturnObject result; Debugger &debugger = target->GetDebugger(); + CommandReturnObject result(debugger.GetUseColor()); + // Rig up the results secondary output stream to the debugger's, so the // output will come out synchronously if the debugger is set up that way. - StreamSP output_stream(debugger.GetAsyncOutputStream()); StreamSP error_stream(debugger.GetAsyncErrorStream()); result.SetImmediateOutputStream(output_stream); diff --git a/gnu/llvm/lldb/source/Breakpoint/BreakpointPrecondition.cpp b/gnu/llvm/lldb/source/Breakpoint/BreakpointPrecondition.cpp index a387c75c835..24a38f0767f 100644 --- a/gnu/llvm/lldb/source/Breakpoint/BreakpointPrecondition.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/BreakpointPrecondition.cpp @@ -1,4 +1,4 @@ -//===-- BreakpointPrecondition.cpp ------------------------------*- C++ -*-===// +//===-- BreakpointPrecondition.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Breakpoint/BreakpointResolver.cpp b/gnu/llvm/lldb/source/Breakpoint/BreakpointResolver.cpp index e0a4e6ac671..7c03a0745ac 100644 --- a/gnu/llvm/lldb/source/Breakpoint/BreakpointResolver.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/BreakpointResolver.cpp @@ -1,4 +1,4 @@ -//===-- BreakpointResolver.cpp ----------------------------------*- C++ -*-===// +//===-- BreakpointResolver.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -60,7 +60,7 @@ BreakpointResolver::NameToResolverTy(llvm::StringRef name) { return UnknownResolver; } -BreakpointResolver::BreakpointResolver(Breakpoint *bkpt, +BreakpointResolver::BreakpointResolver(const BreakpointSP &bkpt, const unsigned char resolverTy, lldb::addr_t offset) : m_breakpoint(bkpt), m_offset(offset), SubclassID(resolverTy) {} @@ -163,7 +163,8 @@ StructuredData::DictionarySP BreakpointResolver::WrapOptionsDict( return type_dict_sp; } -void BreakpointResolver::SetBreakpoint(Breakpoint *bkpt) { +void BreakpointResolver::SetBreakpoint(const BreakpointSP &bkpt) { + assert(bkpt); m_breakpoint = bkpt; NotifyBreakpointSet(); } @@ -327,7 +328,7 @@ void BreakpointResolver::AddLocation(SearchFilter &filter, } BreakpointLocationSP bp_loc_sp(AddLocation(line_start)); - if (log && bp_loc_sp && !m_breakpoint->IsInternal()) { + if (log && bp_loc_sp && !GetBreakpoint()->IsInternal()) { StreamString s; bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); LLDB_LOGF(log, "Added location (skipped prologue: %s): %s \n", @@ -338,7 +339,7 @@ void BreakpointResolver::AddLocation(SearchFilter &filter, BreakpointLocationSP BreakpointResolver::AddLocation(Address loc_addr, bool *new_location) { loc_addr.Slide(m_offset); - return m_breakpoint->AddLocation(loc_addr, new_location); + return GetBreakpoint()->AddLocation(loc_addr, new_location); } void BreakpointResolver::SetOffset(lldb::addr_t offset) { diff --git a/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverAddress.cpp b/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverAddress.cpp index b98568098b4..2c56912b56a 100644 --- a/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverAddress.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverAddress.cpp @@ -1,4 +1,4 @@ -//===-- BreakpointResolverAddress.cpp ---------------------------*- C++ -*-===// +//===-- BreakpointResolverAddress.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -22,21 +22,19 @@ using namespace lldb_private; // BreakpointResolverAddress: BreakpointResolverAddress::BreakpointResolverAddress( - Breakpoint *bkpt, const Address &addr, const FileSpec &module_spec) + const BreakpointSP &bkpt, const Address &addr, const FileSpec &module_spec) : BreakpointResolver(bkpt, BreakpointResolver::AddressResolver), m_addr(addr), m_resolved_addr(LLDB_INVALID_ADDRESS), m_module_filespec(module_spec) {} -BreakpointResolverAddress::BreakpointResolverAddress(Breakpoint *bkpt, +BreakpointResolverAddress::BreakpointResolverAddress(const BreakpointSP &bkpt, const Address &addr) : BreakpointResolver(bkpt, BreakpointResolver::AddressResolver), m_addr(addr), m_resolved_addr(LLDB_INVALID_ADDRESS), m_module_filespec() { } -BreakpointResolverAddress::~BreakpointResolverAddress() {} - BreakpointResolver *BreakpointResolverAddress::CreateFromStructuredData( - Breakpoint *bkpt, const StructuredData::Dictionary &options_dict, + const BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict, Status &error) { llvm::StringRef module_name; lldb::addr_t addr_offset; @@ -100,7 +98,7 @@ void BreakpointResolverAddress::ResolveBreakpoint(SearchFilter &filter) { bool re_resolve = false; if (m_addr.GetSection() || m_module_filespec) re_resolve = true; - else if (m_breakpoint->GetNumLocations() == 0) + else if (GetBreakpoint()->GetNumLocations() == 0) re_resolve = true; if (re_resolve) @@ -113,7 +111,7 @@ void BreakpointResolverAddress::ResolveBreakpointInModules( bool re_resolve = false; if (m_addr.GetSection()) re_resolve = true; - else if (m_breakpoint->GetNumLocations() == 0) + else if (GetBreakpoint()->GetNumLocations() == 0) re_resolve = true; if (re_resolve) @@ -122,15 +120,16 @@ void BreakpointResolverAddress::ResolveBreakpointInModules( Searcher::CallbackReturn BreakpointResolverAddress::SearchCallback( SearchFilter &filter, SymbolContext &context, Address *addr) { - assert(m_breakpoint != nullptr); + BreakpointSP breakpoint_sp = GetBreakpoint(); + Breakpoint &breakpoint = *breakpoint_sp; if (filter.AddressPasses(m_addr)) { - if (m_breakpoint->GetNumLocations() == 0) { + if (breakpoint.GetNumLocations() == 0) { // If the address is just an offset, and we're given a module, see if we // can find the appropriate module loaded in the binary, and fix up // m_addr to use that. if (!m_addr.IsSectionOffset() && m_module_filespec) { - Target &target = m_breakpoint->GetTarget(); + Target &target = breakpoint.GetTarget(); ModuleSpec module_spec(m_module_filespec); ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec); if (module_sp) { @@ -140,9 +139,9 @@ Searcher::CallbackReturn BreakpointResolverAddress::SearchCallback( } } - m_resolved_addr = m_addr.GetLoadAddress(&m_breakpoint->GetTarget()); + m_resolved_addr = m_addr.GetLoadAddress(&breakpoint.GetTarget()); BreakpointLocationSP bp_loc_sp(AddLocation(m_addr)); - if (bp_loc_sp && !m_breakpoint->IsInternal()) { + if (bp_loc_sp && !breakpoint.IsInternal()) { StreamString s; bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); Log *log( @@ -150,9 +149,9 @@ Searcher::CallbackReturn BreakpointResolverAddress::SearchCallback( LLDB_LOGF(log, "Added location: %s\n", s.GetData()); } } else { - BreakpointLocationSP loc_sp = m_breakpoint->GetLocationAtIndex(0); + BreakpointLocationSP loc_sp = breakpoint.GetLocationAtIndex(0); lldb::addr_t cur_load_location = - m_addr.GetLoadAddress(&m_breakpoint->GetTarget()); + m_addr.GetLoadAddress(&breakpoint.GetTarget()); if (cur_load_location != m_resolved_addr) { m_resolved_addr = cur_load_location; loc_sp->ClearBreakpointSite(); @@ -169,7 +168,7 @@ lldb::SearchDepth BreakpointResolverAddress::GetDepth() { void BreakpointResolverAddress::GetDescription(Stream *s) { s->PutCString("address = "); - m_addr.Dump(s, m_breakpoint->GetTarget().GetProcessSP().get(), + m_addr.Dump(s, GetBreakpoint()->GetTarget().GetProcessSP().get(), Address::DumpStyleModuleWithFileAddress, Address::DumpStyleLoadAddress); } @@ -177,8 +176,8 @@ void BreakpointResolverAddress::GetDescription(Stream *s) { void BreakpointResolverAddress::Dump(Stream *s) const {} lldb::BreakpointResolverSP -BreakpointResolverAddress::CopyForBreakpoint(Breakpoint &breakpoint) { +BreakpointResolverAddress::CopyForBreakpoint(BreakpointSP &breakpoint) { lldb::BreakpointResolverSP ret_sp( - new BreakpointResolverAddress(&breakpoint, m_addr)); + new BreakpointResolverAddress(breakpoint, m_addr)); return ret_sp; } diff --git a/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp b/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp index 2b26f65816b..22a4b4ae33a 100644 --- a/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp @@ -1,4 +1,4 @@ -//===-- BreakpointResolverFileLine.cpp --------------------------*- C++ -*-===// +//===-- BreakpointResolverFileLine.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -20,7 +20,7 @@ using namespace lldb_private; // BreakpointResolverFileLine: BreakpointResolverFileLine::BreakpointResolverFileLine( - Breakpoint *bkpt, const FileSpec &file_spec, uint32_t line_no, + const BreakpointSP &bkpt, const FileSpec &file_spec, uint32_t line_no, uint32_t column, lldb::addr_t offset, bool check_inlines, bool skip_prologue, bool exact_match) : BreakpointResolver(bkpt, BreakpointResolver::FileLineResolver, offset), @@ -28,10 +28,8 @@ BreakpointResolverFileLine::BreakpointResolverFileLine( m_inlines(check_inlines), m_skip_prologue(skip_prologue), m_exact_match(exact_match) {} -BreakpointResolverFileLine::~BreakpointResolverFileLine() {} - BreakpointResolver *BreakpointResolverFileLine::CreateFromStructuredData( - Breakpoint *bkpt, const StructuredData::Dictionary &options_dict, + const BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict, Status &error) { llvm::StringRef filename; uint32_t line_no; @@ -202,8 +200,6 @@ Searcher::CallbackReturn BreakpointResolverFileLine::SearchCallback( SearchFilter &filter, SymbolContext &context, Address *addr) { SymbolContextList sc_list; - assert(m_breakpoint != nullptr); - // There is a tricky bit here. You can have two compilation units that // #include the same file, and in one of them the function at m_line_number // is used (and so code and a line entry for it is generated) but in the @@ -263,9 +259,9 @@ void BreakpointResolverFileLine::GetDescription(Stream *s) { void BreakpointResolverFileLine::Dump(Stream *s) const {} lldb::BreakpointResolverSP -BreakpointResolverFileLine::CopyForBreakpoint(Breakpoint &breakpoint) { +BreakpointResolverFileLine::CopyForBreakpoint(BreakpointSP &breakpoint) { lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileLine( - &breakpoint, m_file_spec, m_line_number, m_column, m_offset, m_inlines, + breakpoint, m_file_spec, m_line_number, m_column, GetOffset(), m_inlines, m_skip_prologue, m_exact_match)); return ret_sp; diff --git a/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp b/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp index 6b600a7cf12..62462b2f544 100644 --- a/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp @@ -1,4 +1,4 @@ -//===-- BreakpointResolverFileRegex.cpp -------------------------*- C++-*-===// +//===-- BreakpointResolverFileRegex.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -20,16 +20,14 @@ using namespace lldb_private; // BreakpointResolverFileRegex: BreakpointResolverFileRegex::BreakpointResolverFileRegex( - Breakpoint *bkpt, RegularExpression regex, + const lldb::BreakpointSP &bkpt, RegularExpression regex, const std::unordered_set &func_names, bool exact_match) : BreakpointResolver(bkpt, BreakpointResolver::FileRegexResolver), m_regex(std::move(regex)), m_exact_match(exact_match), m_function_names(func_names) {} -BreakpointResolverFileRegex::~BreakpointResolverFileRegex() {} - BreakpointResolver *BreakpointResolverFileRegex::CreateFromStructuredData( - Breakpoint *bkpt, const StructuredData::Dictionary &options_dict, + const lldb::BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict, Status &error) { bool success; @@ -65,7 +63,7 @@ BreakpointResolver *BreakpointResolverFileRegex::CreateFromStructuredData( "BRFR::CFSD: Malformed element %zu in the names array.", i); return nullptr; } - names_set.insert(name); + names_set.insert(std::string(name)); } } @@ -97,7 +95,6 @@ BreakpointResolverFileRegex::SerializeToStructuredData() { Searcher::CallbackReturn BreakpointResolverFileRegex::SearchCallback( SearchFilter &filter, SymbolContext &context, Address *addr) { - assert(m_breakpoint != nullptr); if (!context.target_sp) return eCallbackReturnContinue; @@ -144,7 +141,6 @@ Searcher::CallbackReturn BreakpointResolverFileRegex::SearchCallback( BreakpointResolver::SetSCMatchesByLine(filter, sc_list, skip_prologue, m_regex.GetText()); } - assert(m_breakpoint != nullptr); return Searcher::eCallbackReturnContinue; } @@ -161,9 +157,9 @@ void BreakpointResolverFileRegex::GetDescription(Stream *s) { void BreakpointResolverFileRegex::Dump(Stream *s) const {} lldb::BreakpointResolverSP -BreakpointResolverFileRegex::CopyForBreakpoint(Breakpoint &breakpoint) { +BreakpointResolverFileRegex::CopyForBreakpoint(BreakpointSP &breakpoint) { lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileRegex( - &breakpoint, m_regex, m_function_names, m_exact_match)); + breakpoint, m_regex, m_function_names, m_exact_match)); return ret_sp; } diff --git a/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverName.cpp b/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverName.cpp index ba9c88c7eae..25f5bb3f6ee 100644 --- a/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverName.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverName.cpp @@ -1,4 +1,4 @@ -//===-- BreakpointResolverName.cpp ------------------------------*- C++ -*-===// +//===-- BreakpointResolverName.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -23,8 +23,8 @@ using namespace lldb; using namespace lldb_private; -BreakpointResolverName::BreakpointResolverName( - Breakpoint *bkpt, const char *name_cstr, FunctionNameType name_type_mask, +BreakpointResolverName::BreakpointResolverName(const BreakpointSP &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), @@ -45,7 +45,7 @@ BreakpointResolverName::BreakpointResolverName( } BreakpointResolverName::BreakpointResolverName( - Breakpoint *bkpt, const char *names[], size_t num_names, + const BreakpointSP &bkpt, const char *names[], size_t num_names, FunctionNameType name_type_mask, LanguageType language, lldb::addr_t offset, bool skip_prologue) : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset), @@ -56,7 +56,7 @@ BreakpointResolverName::BreakpointResolverName( } } -BreakpointResolverName::BreakpointResolverName(Breakpoint *bkpt, +BreakpointResolverName::BreakpointResolverName(const BreakpointSP &bkpt, std::vector names, FunctionNameType name_type_mask, LanguageType language, @@ -70,7 +70,7 @@ BreakpointResolverName::BreakpointResolverName(Breakpoint *bkpt, } } -BreakpointResolverName::BreakpointResolverName(Breakpoint *bkpt, +BreakpointResolverName::BreakpointResolverName(const BreakpointSP &bkpt, RegularExpression func_regex, lldb::LanguageType language, lldb::addr_t offset, @@ -80,18 +80,16 @@ BreakpointResolverName::BreakpointResolverName(Breakpoint *bkpt, m_match_type(Breakpoint::Regexp), m_language(language), m_skip_prologue(skip_prologue) {} -BreakpointResolverName::~BreakpointResolverName() = default; - BreakpointResolverName::BreakpointResolverName( const BreakpointResolverName &rhs) - : BreakpointResolver(rhs.m_breakpoint, BreakpointResolver::NameResolver, - rhs.m_offset), + : BreakpointResolver(rhs.GetBreakpoint(), BreakpointResolver::NameResolver, + rhs.GetOffset()), m_lookups(rhs.m_lookups), m_class_name(rhs.m_class_name), m_regex(rhs.m_regex), m_match_type(rhs.m_match_type), m_language(rhs.m_language), m_skip_prologue(rhs.m_skip_prologue) {} BreakpointResolver *BreakpointResolverName::CreateFromStructuredData( - Breakpoint *bkpt, const StructuredData::Dictionary &options_dict, + const BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict, Status &error) { LanguageType language = eLanguageTypeUnknown; llvm::StringRef language_name; @@ -173,7 +171,7 @@ BreakpointResolver *BreakpointResolverName::CreateFromStructuredData( error.SetErrorString("BRN::CFSD: name mask entry is not an integer."); return nullptr; } - names.push_back(name); + names.push_back(std::string(name)); name_masks.push_back(static_cast(fnt)); } @@ -199,7 +197,7 @@ StructuredData::ObjectSP BreakpointResolverName::SerializeToStructuredData() { StructuredData::ArraySP name_masks_sp(new StructuredData::Array()); for (auto lookup : m_lookups) { names_sp->AddItem(StructuredData::StringSP( - new StructuredData::String(lookup.GetName().AsCString()))); + new StructuredData::String(lookup.GetName().GetStringRef()))); name_masks_sp->AddItem(StructuredData::IntegerSP( new StructuredData::Integer(lookup.GetNameTypeMask()))); } @@ -251,14 +249,6 @@ void BreakpointResolverName::AddNameLookup(ConstString name, Searcher::CallbackReturn BreakpointResolverName::SearchCallback(SearchFilter &filter, SymbolContext &context, Address *addr) { - SymbolContextList func_list; - // SymbolContextList sym_list; - - uint32_t i; - bool new_location; - Address break_addr; - assert(m_breakpoint != nullptr); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); if (m_class_name) { @@ -266,6 +256,8 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter, log->Warning("Class/method function specification not supported yet.\n"); return Searcher::eCallbackReturnStop; } + + SymbolContextList func_list; bool filter_by_cu = (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0; bool filter_by_language = (m_language != eLanguageTypeUnknown); @@ -278,8 +270,9 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter, for (const auto &lookup : m_lookups) { const size_t start_func_idx = func_list.GetSize(); context.module_sp->FindFunctions( - lookup.GetLookupName(), nullptr, lookup.GetNameTypeMask(), - include_symbols, include_inlines, func_list); + lookup.GetLookupName(), CompilerDeclContext(), + lookup.GetNameTypeMask(), include_symbols, include_inlines, + func_list); const size_t end_func_idx = func_list.GetSize(); @@ -333,66 +326,72 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter, } } + BreakpointSP breakpoint_sp = GetBreakpoint(); + Breakpoint &breakpoint = *breakpoint_sp; + Address break_addr; + // Remove any duplicates between the function list and the symbol list SymbolContext sc; - if (func_list.GetSize()) { - for (i = 0; i < func_list.GetSize(); i++) { - if (func_list.GetContextAtIndex(i, sc)) { - bool is_reexported = false; - - if (sc.block && sc.block->GetInlinedFunctionInfo()) { - if (!sc.block->GetStartAddress(break_addr)) - break_addr.Clear(); - } else if (sc.function) { - break_addr = sc.function->GetAddressRange().GetBaseAddress(); - if (m_skip_prologue && break_addr.IsValid()) { - const uint32_t prologue_byte_size = - sc.function->GetPrologueByteSize(); - if (prologue_byte_size) - break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size); - } - } else if (sc.symbol) { - if (sc.symbol->GetType() == eSymbolTypeReExported) { - const Symbol *actual_symbol = - sc.symbol->ResolveReExportedSymbol(m_breakpoint->GetTarget()); - if (actual_symbol) { - is_reexported = true; - break_addr = actual_symbol->GetAddress(); - } - } else { - break_addr = sc.symbol->GetAddress(); - } - - if (m_skip_prologue && break_addr.IsValid()) { - const uint32_t prologue_byte_size = - sc.symbol->GetPrologueByteSize(); - if (prologue_byte_size) - break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size); - else { - const Architecture *arch = - m_breakpoint->GetTarget().GetArchitecturePlugin(); - if (arch) - arch->AdjustBreakpointAddress(*sc.symbol, break_addr); - } - } + if (!func_list.GetSize()) + return Searcher::eCallbackReturnContinue; + + for (uint32_t i = 0; i < func_list.GetSize(); i++) { + if (!func_list.GetContextAtIndex(i, sc)) + continue; + + bool is_reexported = false; + + if (sc.block && sc.block->GetInlinedFunctionInfo()) { + if (!sc.block->GetStartAddress(break_addr)) + break_addr.Clear(); + } else if (sc.function) { + break_addr = sc.function->GetAddressRange().GetBaseAddress(); + if (m_skip_prologue && break_addr.IsValid()) { + const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize(); + if (prologue_byte_size) + break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size); + } + } else if (sc.symbol) { + if (sc.symbol->GetType() == eSymbolTypeReExported) { + const Symbol *actual_symbol = + sc.symbol->ResolveReExportedSymbol(breakpoint.GetTarget()); + if (actual_symbol) { + is_reexported = true; + break_addr = actual_symbol->GetAddress(); } + } else { + break_addr = sc.symbol->GetAddress(); + } - if (break_addr.IsValid()) { - if (filter.AddressPasses(break_addr)) { - BreakpointLocationSP bp_loc_sp( - AddLocation(break_addr, &new_location)); - bp_loc_sp->SetIsReExported(is_reexported); - if (bp_loc_sp && new_location && !m_breakpoint->IsInternal()) { - if (log) { - StreamString s; - bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); - LLDB_LOGF(log, "Added location: %s\n", s.GetData()); - } - } - } + if (m_skip_prologue && break_addr.IsValid()) { + const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize(); + if (prologue_byte_size) + break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size); + else { + const Architecture *arch = + breakpoint.GetTarget().GetArchitecturePlugin(); + if (arch) + arch->AdjustBreakpointAddress(*sc.symbol, break_addr); } } } + + if (!break_addr.IsValid()) + continue; + + if (!filter.AddressPasses(break_addr)) + continue; + + bool new_location; + BreakpointLocationSP bp_loc_sp(AddLocation(break_addr, &new_location)); + bp_loc_sp->SetIsReExported(is_reexported); + if (bp_loc_sp && new_location && !breakpoint.IsInternal()) { + if (log) { + StreamString s; + bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); + LLDB_LOGF(log, "Added location: %s\n", s.GetData()); + } + } } return Searcher::eCallbackReturnContinue; @@ -426,8 +425,8 @@ void BreakpointResolverName::GetDescription(Stream *s) { void BreakpointResolverName::Dump(Stream *s) const {} lldb::BreakpointResolverSP -BreakpointResolverName::CopyForBreakpoint(Breakpoint &breakpoint) { +BreakpointResolverName::CopyForBreakpoint(BreakpointSP &breakpoint) { lldb::BreakpointResolverSP ret_sp(new BreakpointResolverName(*this)); - ret_sp->SetBreakpoint(&breakpoint); + ret_sp->SetBreakpoint(breakpoint); return ret_sp; } diff --git a/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverScripted.cpp b/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverScripted.cpp index 288fd37c1c7..92297fbc7c4 100644 --- a/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverScripted.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverScripted.cpp @@ -1,4 +1,4 @@ -//===-- BreakpointResolverScripted.cpp ---------------------------*- C++ -*-===// +//===-- BreakpointResolverScripted.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -26,43 +26,42 @@ using namespace lldb_private; // BreakpointResolverScripted: BreakpointResolverScripted::BreakpointResolverScripted( - Breakpoint *bkpt, - const llvm::StringRef class_name, - lldb::SearchDepth depth, - StructuredDataImpl *args_data) + const BreakpointSP &bkpt, const llvm::StringRef class_name, + lldb::SearchDepth depth, StructuredDataImpl *args_data) : BreakpointResolver(bkpt, BreakpointResolver::PythonResolver), - m_class_name(class_name), m_depth(depth), m_args_ptr(args_data) { - CreateImplementationIfNeeded(); + m_class_name(std::string(class_name)), m_depth(depth), + m_args_ptr(args_data) { + CreateImplementationIfNeeded(bkpt); } -void BreakpointResolverScripted::CreateImplementationIfNeeded() { +void BreakpointResolverScripted::CreateImplementationIfNeeded( + BreakpointSP breakpoint_sp) { 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() - .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); - } + + if (!breakpoint_sp) + return; + + TargetSP target_sp = breakpoint_sp->GetTargetSP(); + ScriptInterpreter *script_interp = target_sp->GetDebugger() + .GetScriptInterpreter(); + if (!script_interp) + return; + + m_implementation_sp = script_interp->CreateScriptedBreakpointResolver( + m_class_name.c_str(), m_args_ptr, breakpoint_sp); } void BreakpointResolverScripted::NotifyBreakpointSet() { - CreateImplementationIfNeeded(); + CreateImplementationIfNeeded(GetBreakpoint()); } -BreakpointResolverScripted::~BreakpointResolverScripted() {} - BreakpointResolver * BreakpointResolverScripted::CreateFromStructuredData( - Breakpoint *bkpt, const StructuredData::Dictionary &options_dict, + const BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict, Status &error) { llvm::StringRef class_name; bool success; @@ -103,29 +102,27 @@ BreakpointResolverScripted::SerializeToStructuredData() { } ScriptInterpreter *BreakpointResolverScripted::GetScriptInterpreter() { - return m_breakpoint->GetTarget().GetDebugger().GetScriptInterpreter(); + return GetBreakpoint()->GetTarget().GetDebugger().GetScriptInterpreter(); } Searcher::CallbackReturn BreakpointResolverScripted::SearchCallback( SearchFilter &filter, SymbolContext &context, Address *addr) { - assert(m_breakpoint != nullptr); 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; + + return Searcher::eCallbackReturnStop; } lldb::SearchDepth BreakpointResolverScripted::GetDepth() { - assert(m_breakpoint != nullptr); lldb::SearchDepth depth = lldb::eSearchDepthModule; if (m_implementation_sp) { ScriptInterpreter *interp = GetScriptInterpreter(); @@ -153,11 +150,11 @@ void BreakpointResolverScripted::GetDescription(Stream *s) { void BreakpointResolverScripted::Dump(Stream *s) const {} lldb::BreakpointResolverSP -BreakpointResolverScripted::CopyForBreakpoint(Breakpoint &breakpoint) { +BreakpointResolverScripted::CopyForBreakpoint(BreakpointSP &breakpoint) { // 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, + new BreakpointResolverScripted(breakpoint, m_class_name, m_depth, nullptr)); return ret_sp; } diff --git a/gnu/llvm/lldb/source/Breakpoint/BreakpointSite.cpp b/gnu/llvm/lldb/source/Breakpoint/BreakpointSite.cpp index a757a01824c..a33fd0a1c46 100644 --- a/gnu/llvm/lldb/source/Breakpoint/BreakpointSite.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/BreakpointSite.cpp @@ -1,4 +1,4 @@ -//===-- BreakpointSite.cpp --------------------------------------*- C++ -*-===// +//===-- BreakpointSite.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -156,6 +156,13 @@ void BreakpointSite::BumpHitCounts() { } } +void BreakpointSite::SetHardwareIndex(uint32_t index) { + std::lock_guard guard(m_owners_mutex); + for (BreakpointLocationSP loc_sp : m_owners.BreakpointLocations()) { + loc_sp->SetHardwareIndex(index); + } +} + bool BreakpointSite::IntersectsRange(lldb::addr_t addr, size_t size, lldb::addr_t *intersect_addr, size_t *intersect_size, diff --git a/gnu/llvm/lldb/source/Breakpoint/BreakpointSiteList.cpp b/gnu/llvm/lldb/source/Breakpoint/BreakpointSiteList.cpp index 7a986fd8398..873ba6236a7 100644 --- a/gnu/llvm/lldb/source/Breakpoint/BreakpointSiteList.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/BreakpointSiteList.cpp @@ -1,4 +1,4 @@ -//===-- BreakpointSiteList.cpp ----------------------------------*- C++ -*-===// +//===-- BreakpointSiteList.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Breakpoint/Stoppoint.cpp b/gnu/llvm/lldb/source/Breakpoint/Stoppoint.cpp index 4cab975fe32..b5c8334333c 100644 --- a/gnu/llvm/lldb/source/Breakpoint/Stoppoint.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/Stoppoint.cpp @@ -1,4 +1,4 @@ -//===-- Stoppoint.cpp -------------------------------------------*- C++ -*-===// +//===-- Stoppoint.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Breakpoint/StoppointCallbackContext.cpp b/gnu/llvm/lldb/source/Breakpoint/StoppointCallbackContext.cpp index 584bf0060a4..640db8bb9c9 100644 --- a/gnu/llvm/lldb/source/Breakpoint/StoppointCallbackContext.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/StoppointCallbackContext.cpp @@ -1,4 +1,4 @@ -//===-- StoppointCallbackContext.cpp ----------------------------*- C++ -*-===// +//===-- StoppointCallbackContext.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Breakpoint/StoppointLocation.cpp b/gnu/llvm/lldb/source/Breakpoint/StoppointLocation.cpp index 8cc6791fa68..5bb4c785484 100644 --- a/gnu/llvm/lldb/source/Breakpoint/StoppointLocation.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/StoppointLocation.cpp @@ -1,4 +1,4 @@ -//===-- StoppointLocation.cpp -----------------------------------*- C++ -*-===// +//===-- StoppointLocation.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Breakpoint/Watchpoint.cpp b/gnu/llvm/lldb/source/Breakpoint/Watchpoint.cpp index 17dcda13e9b..df73c6a1723 100644 --- a/gnu/llvm/lldb/source/Breakpoint/Watchpoint.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/Watchpoint.cpp @@ -1,4 +1,4 @@ -//===-- Watchpoint.cpp ------------------------------------------*- C++ -*-===// +//===-- Watchpoint.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Breakpoint/WatchpointList.cpp b/gnu/llvm/lldb/source/Breakpoint/WatchpointList.cpp index b1c1e6f253e..a6f651e8495 100644 --- a/gnu/llvm/lldb/source/Breakpoint/WatchpointList.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/WatchpointList.cpp @@ -1,4 +1,4 @@ -//===-- WatchpointList.cpp --------------------------------------*- C++ -*-===// +//===-- WatchpointList.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Breakpoint/WatchpointOptions.cpp b/gnu/llvm/lldb/source/Breakpoint/WatchpointOptions.cpp index 026bf2f746a..f01f5ad3dd2 100644 --- a/gnu/llvm/lldb/source/Breakpoint/WatchpointOptions.cpp +++ b/gnu/llvm/lldb/source/Breakpoint/WatchpointOptions.cpp @@ -1,4 +1,4 @@ -//===-- WatchpointOptions.cpp -----------------------------------*- C++ -*-===// +//===-- WatchpointOptions.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -36,7 +36,7 @@ WatchpointOptions::WatchpointOptions(const WatchpointOptions &rhs) m_callback_is_synchronous(rhs.m_callback_is_synchronous), m_thread_spec_up() { if (rhs.m_thread_spec_up != nullptr) - m_thread_spec_up.reset(new ThreadSpec(*rhs.m_thread_spec_up)); + m_thread_spec_up = std::make_unique(*rhs.m_thread_spec_up); } // WatchpointOptions assignment operator @@ -46,7 +46,7 @@ operator=(const WatchpointOptions &rhs) { m_callback_baton_sp = rhs.m_callback_baton_sp; m_callback_is_synchronous = rhs.m_callback_is_synchronous; if (rhs.m_thread_spec_up != nullptr) - m_thread_spec_up.reset(new ThreadSpec(*rhs.m_thread_spec_up)); + m_thread_spec_up = std::make_unique(*rhs.m_thread_spec_up); return *this; } @@ -108,7 +108,7 @@ const ThreadSpec *WatchpointOptions::GetThreadSpecNoCreate() const { ThreadSpec *WatchpointOptions::GetThreadSpec() { if (m_thread_spec_up == nullptr) - m_thread_spec_up.reset(new ThreadSpec()); + m_thread_spec_up = std::make_unique(); return m_thread_spec_up.get(); } diff --git a/gnu/llvm/lldb/source/Commands/CommandCompletions.cpp b/gnu/llvm/lldb/source/Commands/CommandCompletions.cpp index d9bee66b442..48df7735720 100644 --- a/gnu/llvm/lldb/source/Commands/CommandCompletions.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandCompletions.cpp @@ -1,4 +1,4 @@ -//===-- CommandCompletions.cpp ----------------------------------*- C++ -*-===// +//===-- CommandCompletions.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,6 +18,7 @@ #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Variable.h" +#include "lldb/Target/RegisterContext.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/TildeExpressionResolver.h" @@ -27,19 +28,17 @@ using namespace lldb_private; -CommandCompletions::CommonCompletionElement - CommandCompletions::g_common_completions[] = { - {eCustomCompletion, nullptr}, - {eSourceFileCompletion, CommandCompletions::SourceFiles}, - {eDiskFileCompletion, CommandCompletions::DiskFiles}, - {eDiskDirectoryCompletion, CommandCompletions::DiskDirectories}, - {eSymbolCompletion, CommandCompletions::Symbols}, - {eModuleCompletion, CommandCompletions::Modules}, - {eSettingsNameCompletion, CommandCompletions::SettingsNames}, - {ePlatformPluginCompletion, CommandCompletions::PlatformPluginNames}, - {eArchitectureCompletion, CommandCompletions::ArchitectureNames}, - {eVariablePathCompletion, CommandCompletions::VariablePath}, - {eNoCompletion, nullptr} // This one has to be last in the list. +// This is the command completion callback that is used to complete the +// argument of the option it is bound to (in the OptionDefinition table +// below). +typedef void (*CompletionCallback)(CommandInterpreter &interpreter, + CompletionRequest &request, + // A search filter to limit the search... + lldb_private::SearchFilter *searcher); + +struct CommonCompletionElement { + uint32_t type; + CompletionCallback callback; }; bool CommandCompletions::InvokeCommonCompletionCallbacks( @@ -47,27 +46,245 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks( CompletionRequest &request, SearchFilter *searcher) { bool handled = false; - if (completion_mask & eCustomCompletion) - return false; + const CommonCompletionElement common_completions[] = { + {eSourceFileCompletion, CommandCompletions::SourceFiles}, + {eDiskFileCompletion, CommandCompletions::DiskFiles}, + {eDiskDirectoryCompletion, CommandCompletions::DiskDirectories}, + {eSymbolCompletion, CommandCompletions::Symbols}, + {eModuleCompletion, CommandCompletions::Modules}, + {eSettingsNameCompletion, CommandCompletions::SettingsNames}, + {ePlatformPluginCompletion, CommandCompletions::PlatformPluginNames}, + {eArchitectureCompletion, CommandCompletions::ArchitectureNames}, + {eVariablePathCompletion, CommandCompletions::VariablePath}, + {eRegisterCompletion, CommandCompletions::Registers}, + {eBreakpointCompletion, CommandCompletions::Breakpoints}, + {eProcessPluginCompletion, CommandCompletions::ProcessPluginNames}, + {eNoCompletion, nullptr} // This one has to be last in the list. + }; for (int i = 0;; i++) { - if (g_common_completions[i].type == eNoCompletion) + if (common_completions[i].type == eNoCompletion) break; - else if ((g_common_completions[i].type & completion_mask) == - g_common_completions[i].type && - g_common_completions[i].callback != nullptr) { + else if ((common_completions[i].type & completion_mask) == + common_completions[i].type && + common_completions[i].callback != nullptr) { handled = true; - g_common_completions[i].callback(interpreter, request, searcher); + common_completions[i].callback(interpreter, request, searcher); } } return handled; } +namespace { +// The Completer class is a convenient base class for building searchers that +// go along with the SearchFilter passed to the standard Completer functions. +class Completer : public Searcher { +public: + Completer(CommandInterpreter &interpreter, CompletionRequest &request) + : m_interpreter(interpreter), m_request(request) {} + + ~Completer() override = default; + + CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context, + Address *addr) override = 0; + + lldb::SearchDepth GetDepth() override = 0; + + virtual void DoCompletion(SearchFilter *filter) = 0; + +protected: + CommandInterpreter &m_interpreter; + CompletionRequest &m_request; + +private: + Completer(const Completer &) = delete; + const Completer &operator=(const Completer &) = delete; +}; +} // namespace + +// SourceFileCompleter implements the source file completer +namespace { +class SourceFileCompleter : public Completer { +public: + SourceFileCompleter(CommandInterpreter &interpreter, + CompletionRequest &request) + : Completer(interpreter, request), m_matching_files() { + FileSpec partial_spec(m_request.GetCursorArgumentPrefix()); + m_file_name = partial_spec.GetFilename().GetCString(); + m_dir_name = partial_spec.GetDirectory().GetCString(); + } + + lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthCompUnit; } + + Searcher::CallbackReturn SearchCallback(SearchFilter &filter, + SymbolContext &context, + Address *addr) override { + if (context.comp_unit != nullptr) { + const char *cur_file_name = + context.comp_unit->GetPrimaryFile().GetFilename().GetCString(); + const char *cur_dir_name = + context.comp_unit->GetPrimaryFile().GetDirectory().GetCString(); + + bool match = false; + if (m_file_name && cur_file_name && + strstr(cur_file_name, m_file_name) == cur_file_name) + match = true; + + if (match && m_dir_name && cur_dir_name && + strstr(cur_dir_name, m_dir_name) != cur_dir_name) + match = false; + + if (match) { + m_matching_files.AppendIfUnique(context.comp_unit->GetPrimaryFile()); + } + } + return Searcher::eCallbackReturnContinue; + } + + void DoCompletion(SearchFilter *filter) override { + filter->Search(*this); + // Now convert the filelist to completions: + for (size_t i = 0; i < m_matching_files.GetSize(); i++) { + m_request.AddCompletion( + m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString()); + } + } + +private: + FileSpecList m_matching_files; + const char *m_file_name; + const char *m_dir_name; + + SourceFileCompleter(const SourceFileCompleter &) = delete; + const SourceFileCompleter &operator=(const SourceFileCompleter &) = delete; +}; +} // namespace + +static bool regex_chars(const char comp) { + return llvm::StringRef("[](){}+.*|^$\\?").contains(comp); +} + +namespace { +class SymbolCompleter : public Completer { + +public: + SymbolCompleter(CommandInterpreter &interpreter, CompletionRequest &request) + : Completer(interpreter, request) { + std::string regex_str; + if (!m_request.GetCursorArgumentPrefix().empty()) { + regex_str.append("^"); + regex_str.append(std::string(m_request.GetCursorArgumentPrefix())); + } else { + // Match anything since the completion string is empty + regex_str.append("."); + } + std::string::iterator pos = + find_if(regex_str.begin() + 1, regex_str.end(), regex_chars); + while (pos < regex_str.end()) { + pos = regex_str.insert(pos, '\\'); + pos = find_if(pos + 2, regex_str.end(), regex_chars); + } + m_regex = RegularExpression(regex_str); + } + + lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } + + Searcher::CallbackReturn SearchCallback(SearchFilter &filter, + SymbolContext &context, + Address *addr) override { + if (context.module_sp) { + SymbolContextList sc_list; + const bool include_symbols = true; + const bool include_inlines = true; + context.module_sp->FindFunctions(m_regex, include_symbols, + include_inlines, sc_list); + + SymbolContext sc; + // Now add the functions & symbols to the list - only add if unique: + for (uint32_t i = 0; i < sc_list.GetSize(); i++) { + if (sc_list.GetContextAtIndex(i, sc)) { + ConstString func_name = sc.GetFunctionName(Mangled::ePreferDemangled); + // Ensure that the function name matches the regex. This is more than + // a sanity check. It is possible that the demangled function name + // does not start with the prefix, for example when it's in an + // anonymous namespace. + if (!func_name.IsEmpty() && m_regex.Execute(func_name.GetStringRef())) + m_match_set.insert(func_name); + } + } + } + return Searcher::eCallbackReturnContinue; + } + + void DoCompletion(SearchFilter *filter) override { + filter->Search(*this); + collection::iterator pos = m_match_set.begin(), end = m_match_set.end(); + for (pos = m_match_set.begin(); pos != end; pos++) + m_request.AddCompletion((*pos).GetCString()); + } + +private: + RegularExpression m_regex; + typedef std::set collection; + collection m_match_set; + + SymbolCompleter(const SymbolCompleter &) = delete; + const SymbolCompleter &operator=(const SymbolCompleter &) = delete; +}; +} // namespace + +namespace { +class ModuleCompleter : public Completer { +public: + ModuleCompleter(CommandInterpreter &interpreter, CompletionRequest &request) + : Completer(interpreter, request) { + FileSpec partial_spec(m_request.GetCursorArgumentPrefix()); + m_file_name = partial_spec.GetFilename().GetCString(); + m_dir_name = partial_spec.GetDirectory().GetCString(); + } + + lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } + + Searcher::CallbackReturn SearchCallback(SearchFilter &filter, + SymbolContext &context, + Address *addr) override { + if (context.module_sp) { + const char *cur_file_name = + context.module_sp->GetFileSpec().GetFilename().GetCString(); + const char *cur_dir_name = + context.module_sp->GetFileSpec().GetDirectory().GetCString(); + + bool match = false; + if (m_file_name && cur_file_name && + strstr(cur_file_name, m_file_name) == cur_file_name) + match = true; + + if (match && m_dir_name && cur_dir_name && + strstr(cur_dir_name, m_dir_name) != cur_dir_name) + match = false; + + if (match) { + m_request.AddCompletion(cur_file_name); + } + } + return Searcher::eCallbackReturnContinue; + } + + void DoCompletion(SearchFilter *filter) override { filter->Search(*this); } + +private: + const char *m_file_name; + const char *m_dir_name; + + ModuleCompleter(const ModuleCompleter &) = delete; + const ModuleCompleter &operator=(const ModuleCompleter &) = delete; +}; +} // namespace + void CommandCompletions::SourceFiles(CommandInterpreter &interpreter, CompletionRequest &request, SearchFilter *searcher) { - // Find some way to switch "include support files..." - SourceFileCompleter completer(interpreter, false, request); + SourceFileCompleter completer(interpreter, request); if (searcher == nullptr) { lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); @@ -295,7 +512,7 @@ void CommandCompletions::SettingsNames(CommandInterpreter &interpreter, if (properties_sp) { StreamString strm; properties_sp->DumpValue(nullptr, strm, OptionValue::eDumpOptionName); - const std::string &str = strm.GetString(); + const std::string &str = std::string(strm.GetString()); g_property_names.SplitIntoLines(str.c_str(), str.size()); } } @@ -323,185 +540,57 @@ void CommandCompletions::VariablePath(CommandInterpreter &interpreter, Variable::AutoComplete(interpreter.GetExecutionContext(), request); } -CommandCompletions::Completer::Completer(CommandInterpreter &interpreter, - CompletionRequest &request) - : m_interpreter(interpreter), m_request(request) {} - -CommandCompletions::Completer::~Completer() = default; - -// SourceFileCompleter - -CommandCompletions::SourceFileCompleter::SourceFileCompleter( - CommandInterpreter &interpreter, bool include_support_files, - CompletionRequest &request) - : CommandCompletions::Completer(interpreter, request), - m_include_support_files(include_support_files), m_matching_files() { - FileSpec partial_spec(m_request.GetCursorArgumentPrefix()); - m_file_name = partial_spec.GetFilename().GetCString(); - m_dir_name = partial_spec.GetDirectory().GetCString(); -} - -lldb::SearchDepth CommandCompletions::SourceFileCompleter::GetDepth() { - return lldb::eSearchDepthCompUnit; -} - -Searcher::CallbackReturn -CommandCompletions::SourceFileCompleter::SearchCallback(SearchFilter &filter, - SymbolContext &context, - Address *addr) { - if (context.comp_unit != nullptr) { - if (m_include_support_files) { - FileSpecList supporting_files = context.comp_unit->GetSupportFiles(); - for (size_t sfiles = 0; sfiles < supporting_files.GetSize(); sfiles++) { - const FileSpec &sfile_spec = - supporting_files.GetFileSpecAtIndex(sfiles); - const char *sfile_file_name = sfile_spec.GetFilename().GetCString(); - const char *sfile_dir_name = sfile_spec.GetFilename().GetCString(); - bool match = false; - if (m_file_name && sfile_file_name && - strstr(sfile_file_name, m_file_name) == sfile_file_name) - match = true; - if (match && m_dir_name && sfile_dir_name && - strstr(sfile_dir_name, m_dir_name) != sfile_dir_name) - match = false; - - if (match) { - m_matching_files.AppendIfUnique(sfile_spec); - } - } - } else { - const char *cur_file_name = - context.comp_unit->GetPrimaryFile().GetFilename().GetCString(); - const char *cur_dir_name = - context.comp_unit->GetPrimaryFile().GetDirectory().GetCString(); - - bool match = false; - if (m_file_name && cur_file_name && - strstr(cur_file_name, m_file_name) == cur_file_name) - match = true; - - if (match && m_dir_name && cur_dir_name && - strstr(cur_dir_name, m_dir_name) != cur_dir_name) - match = false; - - if (match) { - m_matching_files.AppendIfUnique(context.comp_unit->GetPrimaryFile()); - } - } - } - return Searcher::eCallbackReturnContinue; -} - -void CommandCompletions::SourceFileCompleter::DoCompletion( - SearchFilter *filter) { - filter->Search(*this); - // Now convert the filelist to completions: - for (size_t i = 0; i < m_matching_files.GetSize(); i++) { - m_request.AddCompletion( - m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString()); +void CommandCompletions::Registers(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + std::string reg_prefix = ""; + if (request.GetCursorArgumentPrefix().startswith("$")) + reg_prefix = "$"; + + RegisterContext *reg_ctx = + interpreter.GetExecutionContext().GetRegisterContext(); + const size_t reg_num = reg_ctx->GetRegisterCount(); + for (size_t reg_idx = 0; reg_idx < reg_num; ++reg_idx) { + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_idx); + request.TryCompleteCurrentArg(reg_prefix + reg_info->name, + reg_info->alt_name); } } -// SymbolCompleter - -static bool regex_chars(const char comp) { - return llvm::StringRef("[](){}+.*|^$\\?").contains(comp); -} +void CommandCompletions::Breakpoints(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + lldb::TargetSP target = interpreter.GetDebugger().GetSelectedTarget(); + if (!target) + return; -CommandCompletions::SymbolCompleter::SymbolCompleter( - CommandInterpreter &interpreter, CompletionRequest &request) - : CommandCompletions::Completer(interpreter, request) { - std::string regex_str; - if (!m_request.GetCursorArgumentPrefix().empty()) { - regex_str.append("^"); - regex_str.append(m_request.GetCursorArgumentPrefix()); - } else { - // Match anything since the completion string is empty - regex_str.append("."); - } - std::string::iterator pos = - find_if(regex_str.begin() + 1, regex_str.end(), regex_chars); - while (pos < regex_str.end()) { - pos = regex_str.insert(pos, '\\'); - pos = find_if(pos + 2, regex_str.end(), regex_chars); - } - m_regex = RegularExpression(regex_str); -} + const BreakpointList &breakpoints = target->GetBreakpointList(); -lldb::SearchDepth CommandCompletions::SymbolCompleter::GetDepth() { - return lldb::eSearchDepthModule; -} + std::unique_lock lock; + target->GetBreakpointList().GetListMutex(lock); -Searcher::CallbackReturn CommandCompletions::SymbolCompleter::SearchCallback( - SearchFilter &filter, SymbolContext &context, Address *addr) { - if (context.module_sp) { - SymbolContextList sc_list; - const bool include_symbols = true; - const bool include_inlines = true; - context.module_sp->FindFunctions(m_regex, include_symbols, include_inlines, - sc_list); - - SymbolContext sc; - // Now add the functions & symbols to the list - only add if unique: - for (uint32_t i = 0; i < sc_list.GetSize(); i++) { - if (sc_list.GetContextAtIndex(i, sc)) { - ConstString func_name = sc.GetFunctionName(Mangled::ePreferDemangled); - // Ensure that the function name matches the regex. This is more than a - // sanity check. It is possible that the demangled function name does - // not start with the prefix, for example when it's in an anonymous - // namespace. - if (!func_name.IsEmpty() && m_regex.Execute(func_name.GetStringRef())) - m_match_set.insert(func_name); - } - } - } - return Searcher::eCallbackReturnContinue; -} + size_t num_breakpoints = breakpoints.GetSize(); + if (num_breakpoints == 0) + return; -void CommandCompletions::SymbolCompleter::DoCompletion(SearchFilter *filter) { - filter->Search(*this); - collection::iterator pos = m_match_set.begin(), end = m_match_set.end(); - for (pos = m_match_set.begin(); pos != end; pos++) - m_request.AddCompletion((*pos).GetCString()); -} + for (size_t i = 0; i < num_breakpoints; ++i) { + lldb::BreakpointSP bp = breakpoints.GetBreakpointAtIndex(i); -// ModuleCompleter -CommandCompletions::ModuleCompleter::ModuleCompleter( - CommandInterpreter &interpreter, CompletionRequest &request) - : CommandCompletions::Completer(interpreter, request) { - FileSpec partial_spec(m_request.GetCursorArgumentPrefix()); - m_file_name = partial_spec.GetFilename().GetCString(); - m_dir_name = partial_spec.GetDirectory().GetCString(); -} + StreamString s; + bp->GetDescription(&s, lldb::eDescriptionLevelBrief); + llvm::StringRef bp_info = s.GetString(); -lldb::SearchDepth CommandCompletions::ModuleCompleter::GetDepth() { - return lldb::eSearchDepthModule; -} + const size_t colon_pos = bp_info.find_first_of(':'); + if (colon_pos != llvm::StringRef::npos) + bp_info = bp_info.drop_front(colon_pos + 2); -Searcher::CallbackReturn CommandCompletions::ModuleCompleter::SearchCallback( - SearchFilter &filter, SymbolContext &context, Address *addr) { - if (context.module_sp) { - const char *cur_file_name = - context.module_sp->GetFileSpec().GetFilename().GetCString(); - const char *cur_dir_name = - context.module_sp->GetFileSpec().GetDirectory().GetCString(); - - bool match = false; - if (m_file_name && cur_file_name && - strstr(cur_file_name, m_file_name) == cur_file_name) - match = true; - - if (match && m_dir_name && cur_dir_name && - strstr(cur_dir_name, m_dir_name) != cur_dir_name) - match = false; - - if (match) { - m_request.AddCompletion(cur_file_name); - } + request.TryCompleteCurrentArg(std::to_string(bp->GetID()), bp_info); } - return Searcher::eCallbackReturnContinue; } -void CommandCompletions::ModuleCompleter::DoCompletion(SearchFilter *filter) { - filter->Search(*this); -} +void CommandCompletions::ProcessPluginNames(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + PluginManager::AutoCompleteProcessName(request.GetCursorArgumentPrefix(), + request); +} \ No newline at end of file diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectApropos.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectApropos.cpp index 15a20737273..6e1e1f06173 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectApropos.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectApropos.cpp @@ -1,5 +1,4 @@ -//===-- CommandObjectApropos.cpp ---------------------------------*- C++ -//-*-===// +//===-- CommandObjectApropos.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectApropos.h b/gnu/llvm/lldb/source/Commands/CommandObjectApropos.h index 37d86b17d1a..042753f2403 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectApropos.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectApropos.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectApropos_h_ -#define liblldb_CommandObjectApropos_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTAPROPOS_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTAPROPOS_H #include "lldb/Interpreter/CommandObject.h" @@ -28,4 +28,4 @@ protected: } // namespace lldb_private -#endif // liblldb_CommandObjectApropos_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTAPROPOS_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectBreakpoint.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectBreakpoint.cpp index 7c4c50ecf3f..be7ef8a1b60 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===// +//===-- CommandObjectBreakpoint.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -70,7 +70,7 @@ public: m_bp_opts.m_set_flags.Set(BreakpointOptions::eCondition); break; case 'C': - m_commands.push_back(option_arg); + m_commands.push_back(std::string(option_arg)); break; case 'd': m_bp_opts.SetEnabled(false); @@ -270,11 +270,11 @@ public: break; case 'b': - m_func_names.push_back(option_arg); + m_func_names.push_back(std::string(option_arg)); m_func_name_type_mask |= eFunctionNameTypeBase; break; - case 'C': + case 'u': if (option_arg.getAsInteger(0, m_column)) error.SetErrorStringWithFormat("invalid column number: %s", option_arg.str().c_str()); @@ -320,7 +320,7 @@ public: break; case 'F': - m_func_names.push_back(option_arg); + m_func_names.push_back(std::string(option_arg)); m_func_name_type_mask |= eFunctionNameTypeFull; break; @@ -383,18 +383,18 @@ public: } case 'M': - m_func_names.push_back(option_arg); + m_func_names.push_back(std::string(option_arg)); m_func_name_type_mask |= eFunctionNameTypeMethod; break; case 'n': - m_func_names.push_back(option_arg); + m_func_names.push_back(std::string(option_arg)); m_func_name_type_mask |= eFunctionNameTypeAuto; break; case 'N': { if (BreakpointID::StringIsBreakpointName(option_arg, error)) - m_breakpoint_names.push_back(option_arg); + m_breakpoint_names.push_back(std::string(option_arg)); else error.SetErrorStringWithFormat("Invalid breakpoint name: %s", option_arg.str().c_str()); @@ -415,11 +415,11 @@ public: break; case 'p': - m_source_text_regexp.assign(option_arg); + m_source_text_regexp.assign(std::string(option_arg)); break; case 'r': - m_func_regexp.assign(option_arg); + m_func_regexp.assign(std::string(option_arg)); break; case 's': @@ -427,7 +427,7 @@ public: break; case 'S': - m_func_names.push_back(option_arg); + m_func_names.push_back(std::string(option_arg)); m_func_name_type_mask |= eFunctionNameTypeSelector; break; @@ -441,7 +441,7 @@ public: } break; case 'X': - m_source_regex_func_names.insert(option_arg); + m_source_regex_func_names.insert(std::string(option_arg)); break; default: @@ -620,8 +620,16 @@ protected: RegularExpression regexp(m_options.m_func_regexp); if (llvm::Error err = regexp.GetError()) { result.AppendErrorWithFormat( - "Function name regular expression could not be compiled: \"%s\"", + "Function name regular expression could not be compiled: %s", llvm::toString(std::move(err)).c_str()); + // Check if the incorrect regex looks like a globbing expression and + // warn the user about it. + if (!m_options.m_func_regexp.empty()) { + if (m_options.m_func_regexp[0] == '*' || + m_options.m_func_regexp[0] == '?') + result.AppendWarning( + "Function name regex does not accept glob patterns."); + } result.SetStatus(eReturnStatusFailed); return false; } @@ -811,6 +819,14 @@ public: ~CommandObjectBreakpointModify() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, + request, nullptr); + } + Options *GetOptions() override { return &m_options; } protected: @@ -877,6 +893,14 @@ public: ~CommandObjectBreakpointEnable() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, + request, nullptr); + } + protected: bool DoExecute(Args &command, CommandReturnObject &result) override { Target &target = GetSelectedOrDummyTarget(); @@ -985,6 +1009,14 @@ the second re-enables the first location."); ~CommandObjectBreakpointDisable() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, + request, nullptr); + } + protected: bool DoExecute(Args &command, CommandReturnObject &result) override { Target &target = GetSelectedOrDummyTarget(); @@ -1231,7 +1263,7 @@ public: switch (short_option) { case 'f': - m_filename.assign(option_arg); + m_filename.assign(std::string(option_arg)); break; case 'l': @@ -1363,6 +1395,14 @@ public: ~CommandObjectBreakpointDelete() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, + request, nullptr); + } + Options *GetOptions() override { return &m_options; } class CommandOptions : public Options { @@ -1730,6 +1770,14 @@ public: ~CommandObjectBreakpointNameAdd() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, + request, nullptr); + } + Options *GetOptions() override { return &m_option_group; } protected: @@ -1809,6 +1857,14 @@ public: ~CommandObjectBreakpointNameDelete() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, + request, nullptr); + } + Options *GetOptions() override { return &m_option_group; } protected: @@ -1978,14 +2034,7 @@ public: "Read and set the breakpoints previously saved to " "a file with \"breakpoint write\". ", nullptr), - m_options() { - CommandArgumentEntry arg; - CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, - eArgTypeBreakpointIDRange); - // Add the entry for the first argument for this command to the object's - // arguments vector. - m_arguments.push_back(arg); - } + m_options() {} ~CommandObjectBreakpointRead() override = default; @@ -2004,7 +2053,7 @@ public: switch (short_option) { case 'f': - m_filename.assign(option_arg); + m_filename.assign(std::string(option_arg)); break; case 'N': { Status name_error; @@ -2013,7 +2062,7 @@ public: error.SetErrorStringWithFormat("Invalid breakpoint name: %s", name_error.AsCString()); } - m_names.push_back(option_arg); + m_names.push_back(std::string(option_arg)); break; } default: @@ -2107,6 +2156,14 @@ public: ~CommandObjectBreakpointWrite() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, + request, nullptr); + } + Options *GetOptions() override { return &m_options; } class CommandOptions : public Options { @@ -2122,7 +2179,7 @@ public: switch (short_option) { case 'f': - m_filename.assign(option_arg); + m_filename.assign(std::string(option_arg)); break; case 'a': m_append = true; diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectBreakpoint.h b/gnu/llvm/lldb/source/Commands/CommandObjectBreakpoint.h index b29bbc0a74f..6625652b260 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectBreakpoint.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectBreakpoint.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectBreakpoint_h_ -#define liblldb_CommandObjectBreakpoint_h_ - +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTBREAKPOINT_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTBREAKPOINT_H #include "lldb/Breakpoint/BreakpointName.h" #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -46,4 +45,4 @@ private: } // namespace lldb_private -#endif // liblldb_CommandObjectBreakpoint_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTBREAKPOINT_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectBreakpointCommand.cpp index bbd2ca57012..45df8658901 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectBreakpointCommand.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectBreakpointCommand.cpp ----------------------*- C++ -*-===// +//===-- CommandObjectBreakpointCommand.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -292,7 +292,7 @@ are no syntax errors may indicate that a function was declared but never called. switch (short_option) { case 'o': m_use_one_liner = true; - m_one_liner = option_arg; + m_one_liner = std::string(option_arg); break; case 's': diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectBreakpointCommand.h b/gnu/llvm/lldb/source/Commands/CommandObjectBreakpointCommand.h index fb246d47abf..cb516d76ea3 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectBreakpointCommand.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectBreakpointCommand.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectBreakpointCommand_h_ -#define liblldb_CommandObjectBreakpointCommand_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTBREAKPOINTCOMMAND_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTBREAKPOINTCOMMAND_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -24,4 +24,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectBreakpointCommand_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTBREAKPOINTCOMMAND_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectCommands.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectCommands.cpp index 388db6fad63..d77e69c6f6a 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectCommands.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectCommands.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectCommands.cpp -------------------------------*- C++ -*-===// +//===-- CommandObjectCommands.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -527,14 +527,13 @@ protected: m_option_group.NotifyOptionParsingStarting(&exe_ctx); OptionsWithRaw args_with_suffix(raw_command_line); - const char *remainder = args_with_suffix.GetRawPart().c_str(); if (args_with_suffix.HasArgs()) if (!ParseOptionsAndNotify(args_with_suffix.GetArgs(), result, m_option_group, exe_ctx)) return false; - llvm::StringRef raw_command_string(remainder); + llvm::StringRef raw_command_string = args_with_suffix.GetRawPart(); Args args(raw_command_string); if (args.GetArgumentCount() < 2) { @@ -652,8 +651,8 @@ protected: } // Save these in std::strings since we're going to shift them off. - const std::string alias_command(args[0].ref()); - const std::string actual_command(args[1].ref()); + const std::string alias_command(std::string(args[0].ref())); + const std::string actual_command(std::string(args[1].ref())); args.Shift(); // Shift the alias command word off the argument vector. args.Shift(); // Shift the old command word off the argument vector. @@ -1007,7 +1006,7 @@ protected: *this, nullptr)); if (io_handler_sp) { - debugger.PushIOHandler(io_handler_sp); + debugger.RunIOHandlerAsync(io_handler_sp); result.SetStatus(eReturnStatusSuccessFinishNoResult); } } else { @@ -1114,12 +1113,12 @@ protected: } if (!check_only) { - std::string regex(regex_sed.substr(first_separator_char_pos + 1, - second_separator_char_pos - - first_separator_char_pos - 1)); - std::string subst(regex_sed.substr(second_separator_char_pos + 1, - third_separator_char_pos - - second_separator_char_pos - 1)); + std::string regex(std::string(regex_sed.substr( + first_separator_char_pos + 1, + second_separator_char_pos - first_separator_char_pos - 1))); + std::string subst(std::string(regex_sed.substr( + second_separator_char_pos + 1, + third_separator_char_pos - second_separator_char_pos - 1))); m_regex_cmd_up->AddRegexCommand(regex.c_str(), subst.c_str()); } return error; @@ -1150,10 +1149,10 @@ private: switch (short_option) { case 'h': - m_help.assign(option_arg); + m_help.assign(std::string(option_arg)); break; case 's': - m_syntax.assign(option_arg); + m_syntax.assign(std::string(option_arg)); break; default: llvm_unreachable("Unimplemented option"); @@ -1171,14 +1170,9 @@ private: return llvm::makeArrayRef(g_regex_options); } - // TODO: Convert these functions to return StringRefs. - const char *GetHelp() { - return (m_help.empty() ? nullptr : m_help.c_str()); - } + llvm::StringRef GetHelp() { return m_help; } - const char *GetSyntax() { - return (m_syntax.empty() ? nullptr : m_syntax.c_str()); - } + llvm::StringRef GetSyntax() { return m_syntax; } protected: // Instance variables to hold the values for command options. @@ -1526,15 +1520,15 @@ protected: switch (short_option) { case 'f': if (!option_arg.empty()) - m_funct_name = option_arg; + m_funct_name = std::string(option_arg); break; case 'c': if (!option_arg.empty()) - m_class_name = option_arg; + m_class_name = std::string(option_arg); break; case 'h': if (!option_arg.empty()) - m_short_help = option_arg; + m_short_help = std::string(option_arg); break; case 's': m_synchronicity = @@ -1627,7 +1621,6 @@ protected: io_handler.SetIsDone(true); } -protected: bool DoExecute(Args &command, CommandReturnObject &result) override { if (GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) { result.AppendError("only scripting language supported for scripted " @@ -1643,7 +1636,7 @@ protected: } // Store the options in case we get multi-line input - m_cmd_name = command[0].ref(); + m_cmd_name = std::string(command[0].ref()); m_short_help.assign(m_options.m_short_help); m_synchronicity = m_options.m_synchronicity; @@ -1773,6 +1766,16 @@ public: ~CommandObjectCommandsScriptDelete() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (!m_interpreter.HasCommands() || request.GetCursorIndex() != 0) + return; + + for (const auto &c : m_interpreter.GetUserCommands()) + request.TryCompleteCurrentArg(c.first, c.second->GetHelp()); + } + protected: bool DoExecute(Args &command, CommandReturnObject &result) override { diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectCommands.h b/gnu/llvm/lldb/source/Commands/CommandObjectCommands.h index dcf02f3a7da..f418e5ba779 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectCommands.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectCommands.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectCommands_h_ -#define liblldb_CommandObjectCommands_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTCOMMANDS_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTCOMMANDS_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -25,4 +25,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectCommands_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTCOMMANDS_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectDisassemble.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectDisassemble.cpp index 63679e996e7..cf4d8ed04f8 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectDisassemble.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectDisassemble.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectDisassemble.cpp ----------------------------*- C++ -*-===// +//===-- CommandObjectDisassemble.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -21,8 +21,9 @@ #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" -#define DEFAULT_DISASM_BYTE_SIZE 32 -#define DEFAULT_DISASM_NUM_INS 4 +static constexpr unsigned default_disasm_byte_size = 32; +static constexpr unsigned default_disasm_num_ins = 4; +static constexpr unsigned large_function_threshold = 8000; using namespace lldb; using namespace lldb_private; @@ -83,7 +84,7 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue( } break; case 'n': - func_name.assign(option_arg); + func_name.assign(std::string(option_arg)); some_location_specified = true; break; @@ -101,7 +102,7 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue( break; case 'P': - plugin_name.assign(option_arg); + plugin_name.assign(std::string(option_arg)); break; case 'F': { @@ -111,7 +112,7 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue( llvm::Triple::x86 || target_sp->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86_64)) { - flavor_string.assign(option_arg); + flavor_string.assign(std::string(option_arg)); } else error.SetErrorStringWithFormat("Disassembler flavors are currently only " "supported for x86 and x86_64 targets."); @@ -143,6 +144,10 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue( } } break; + case '\x01': + force = true; + break; + default: llvm_unreachable("Unimplemented option"); } @@ -186,6 +191,7 @@ void CommandObjectDisassemble::CommandOptions::OptionParsingStarting( arch.Clear(); some_location_specified = false; + force = false; } Status CommandObjectDisassemble::CommandOptions::OptionParsingFinished( @@ -214,6 +220,194 @@ CommandObjectDisassemble::CommandObjectDisassemble( CommandObjectDisassemble::~CommandObjectDisassemble() = default; +llvm::Error CommandObjectDisassemble::CheckRangeSize(const AddressRange &range, + llvm::StringRef what) { + if (m_options.num_instructions > 0 || m_options.force || + range.GetByteSize() < large_function_threshold) + return llvm::Error::success(); + StreamString msg; + msg << "Not disassembling " << what << " because it is very large "; + range.Dump(&msg, &GetSelectedTarget(), Address::DumpStyleLoadAddress, + Address::DumpStyleFileAddress); + msg << ". To disassemble specify an instruction count limit, start/stop " + "addresses or use the --force option."; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + msg.GetString()); +} + +llvm::Expected> +CommandObjectDisassemble::GetContainingAddressRanges() { + std::vector ranges; + const auto &get_range = [&](Address addr) { + ModuleSP module_sp(addr.GetModule()); + SymbolContext sc; + bool resolve_tail_call_address = true; + addr.GetModule()->ResolveSymbolContextForAddress( + addr, eSymbolContextEverything, sc, resolve_tail_call_address); + if (sc.function || sc.symbol) { + AddressRange range; + sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0, + false, range); + ranges.push_back(range); + } + }; + + Target &target = GetSelectedTarget(); + if (!target.GetSectionLoadList().IsEmpty()) { + Address symbol_containing_address; + if (target.GetSectionLoadList().ResolveLoadAddress( + m_options.symbol_containing_addr, symbol_containing_address)) { + get_range(symbol_containing_address); + } + } else { + for (lldb::ModuleSP module_sp : target.GetImages().Modules()) { + Address file_address; + if (module_sp->ResolveFileAddress(m_options.symbol_containing_addr, + file_address)) { + get_range(file_address); + } + } + } + + if (ranges.empty()) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Could not find function bounds for address 0x%" PRIx64, + m_options.symbol_containing_addr); + } + + if (llvm::Error err = CheckRangeSize(ranges[0], "the function")) + return std::move(err); + return ranges; +} + +llvm::Expected> +CommandObjectDisassemble::GetCurrentFunctionRanges() { + StackFrame *frame = m_exe_ctx.GetFramePtr(); + if (!frame) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Cannot disassemble around the current " + "function without a selected frame.\n"); + } + SymbolContext sc( + frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol)); + AddressRange range; + if (sc.function) + range = sc.function->GetAddressRange(); + else if (sc.symbol && sc.symbol->ValueIsAddress()) { + range = {sc.symbol->GetAddress(), sc.symbol->GetByteSize()}; + } else + range = {frame->GetFrameCodeAddress(), default_disasm_byte_size}; + + if (llvm::Error err = CheckRangeSize(range, "the current function")) + return std::move(err); + return std::vector{range}; +} + +llvm::Expected> +CommandObjectDisassemble::GetCurrentLineRanges() { + StackFrame *frame = m_exe_ctx.GetFramePtr(); + if (!frame) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Cannot disassemble around the current " + "line without a selected frame.\n"); + } + + LineEntry pc_line_entry( + frame->GetSymbolContext(eSymbolContextLineEntry).line_entry); + if (pc_line_entry.IsValid()) + return std::vector{pc_line_entry.range}; + + // No line entry, so just disassemble around the current pc + m_options.show_mixed = false; + return GetPCRanges(); +} + +llvm::Expected> +CommandObjectDisassemble::GetNameRanges(CommandReturnObject &result) { + ConstString name(m_options.func_name.c_str()); + const bool include_symbols = true; + const bool include_inlines = true; + + // Find functions matching the given name. + SymbolContextList sc_list; + GetSelectedTarget().GetImages().FindFunctions( + name, eFunctionNameTypeAuto, include_symbols, include_inlines, sc_list); + + std::vector ranges; + llvm::Error range_errs = llvm::Error::success(); + AddressRange range; + const uint32_t scope = + eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol; + const bool use_inline_block_range = true; + for (SymbolContext sc : sc_list.SymbolContexts()) { + for (uint32_t range_idx = 0; + sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); + ++range_idx) { + if (llvm::Error err = CheckRangeSize(range, "a range")) + range_errs = joinErrors(std::move(range_errs), std::move(err)); + else + ranges.push_back(range); + } + } + if (ranges.empty()) { + if (range_errs) + return std::move(range_errs); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Unable to find symbol with name '%s'.\n", + name.GetCString()); + } + if (range_errs) + result.AppendWarning(toString(std::move(range_errs))); + return ranges; +} + +llvm::Expected> +CommandObjectDisassemble::GetPCRanges() { + StackFrame *frame = m_exe_ctx.GetFramePtr(); + if (!frame) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Cannot disassemble around the current " + "PC without a selected frame.\n"); + } + + if (m_options.num_instructions == 0) { + // Disassembling at the PC always disassembles some number of + // instructions (not the whole function). + m_options.num_instructions = default_disasm_num_ins; + } + return std::vector{{frame->GetFrameCodeAddress(), 0}}; +} + +llvm::Expected> +CommandObjectDisassemble::GetStartEndAddressRanges() { + addr_t size = 0; + if (m_options.end_addr != LLDB_INVALID_ADDRESS) { + if (m_options.end_addr <= m_options.start_addr) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "End address before start address."); + } + size = m_options.end_addr - m_options.start_addr; + } + return std::vector{{Address(m_options.start_addr), size}}; +} + +llvm::Expected> +CommandObjectDisassemble::GetRangesForSelectedMode( + CommandReturnObject &result) { + if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS) + return CommandObjectDisassemble::GetContainingAddressRanges(); + if (m_options.current_function) + return CommandObjectDisassemble::GetCurrentFunctionRanges(); + if (m_options.frame_line) + return CommandObjectDisassemble::GetCurrentLineRanges(); + if (!m_options.func_name.empty()) + return CommandObjectDisassemble::GetNameRanges(result); + if (m_options.start_addr != LLDB_INVALID_ADDRESS) + return CommandObjectDisassemble::GetStartEndAddressRanges(); + return CommandObjectDisassemble::GetPCRanges(); +} + bool CommandObjectDisassemble::DoExecute(Args &command, CommandReturnObject &result) { Target *target = &GetSelectedTarget(); @@ -281,238 +475,44 @@ bool CommandObjectDisassemble::DoExecute(Args &command, if (m_options.raw) options |= Disassembler::eOptionRawOuput; - if (!m_options.func_name.empty()) { - ConstString name(m_options.func_name.c_str()); + llvm::Expected> ranges = + GetRangesForSelectedMode(result); + if (!ranges) { + result.AppendError(toString(ranges.takeError())); + result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); + } + bool print_sc_header = ranges->size() > 1; + for (AddressRange cur_range : *ranges) { + Disassembler::Limit limit; + if (m_options.num_instructions == 0) { + limit = {Disassembler::Limit::Bytes, cur_range.GetByteSize()}; + if (limit.value == 0) + limit.value = default_disasm_byte_size; + } else { + limit = {Disassembler::Limit::Instructions, m_options.num_instructions}; + } if (Disassembler::Disassemble( GetDebugger(), m_options.arch, plugin_name, flavor_string, - m_exe_ctx, name, - nullptr, // Module * - m_options.num_instructions, m_options.show_mixed, + m_exe_ctx, cur_range.GetBaseAddress(), limit, m_options.show_mixed, m_options.show_mixed ? m_options.num_lines_context : 0, options, result.GetOutputStream())) { result.SetStatus(eReturnStatusSuccessFinishResult); } else { - result.AppendErrorWithFormat("Unable to find symbol with name '%s'.\n", - name.GetCString()); - result.SetStatus(eReturnStatusFailed); - } - } else { - std::vector ranges; - AddressRange range; - StackFrame *frame = m_exe_ctx.GetFramePtr(); - if (m_options.frame_line) { - if (frame == nullptr) { - result.AppendError("Cannot disassemble around the current line without " - "a selected frame.\n"); - result.SetStatus(eReturnStatusFailed); - return false; - } - LineEntry pc_line_entry( - frame->GetSymbolContext(eSymbolContextLineEntry).line_entry); - if (pc_line_entry.IsValid()) { - range = pc_line_entry.range; - } else { - m_options.at_pc = - true; // No line entry, so just disassemble around the current pc - m_options.show_mixed = false; - } - } else if (m_options.current_function) { - if (frame == nullptr) { - result.AppendError("Cannot disassemble around the current function " - "without a selected frame.\n"); - result.SetStatus(eReturnStatusFailed); - return false; - } - Symbol *symbol = frame->GetSymbolContext(eSymbolContextSymbol).symbol; - if (symbol) { - range.GetBaseAddress() = symbol->GetAddress(); - range.SetByteSize(symbol->GetByteSize()); - } - } - - // Did the "m_options.frame_line" find a valid range already? If so skip - // the rest... - if (range.GetByteSize() == 0) { - if (m_options.at_pc) { - if (frame == nullptr) { - result.AppendError("Cannot disassemble around the current PC without " - "a selected frame.\n"); - result.SetStatus(eReturnStatusFailed); - return false; - } - range.GetBaseAddress() = frame->GetFrameCodeAddress(); - if (m_options.num_instructions == 0) { - // Disassembling at the PC always disassembles some number of - // instructions (not the whole function). - m_options.num_instructions = DEFAULT_DISASM_NUM_INS; - } - ranges.push_back(range); + if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS) { + result.AppendErrorWithFormat( + "Failed to disassemble memory in function at 0x%8.8" PRIx64 ".\n", + m_options.symbol_containing_addr); } else { - range.GetBaseAddress().SetOffset(m_options.start_addr); - if (range.GetBaseAddress().IsValid()) { - if (m_options.end_addr != LLDB_INVALID_ADDRESS) { - if (m_options.end_addr <= m_options.start_addr) { - result.AppendErrorWithFormat( - "End address before start address.\n"); - result.SetStatus(eReturnStatusFailed); - return false; - } - range.SetByteSize(m_options.end_addr - m_options.start_addr); - } - ranges.push_back(range); - } else { - if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS && - target) { - if (!target->GetSectionLoadList().IsEmpty()) { - bool failed = false; - Address symbol_containing_address; - if (target->GetSectionLoadList().ResolveLoadAddress( - m_options.symbol_containing_addr, - symbol_containing_address)) { - ModuleSP module_sp(symbol_containing_address.GetModule()); - SymbolContext sc; - bool resolve_tail_call_address = true; // PC can be one past the - // address range of the - // function. - module_sp->ResolveSymbolContextForAddress( - symbol_containing_address, eSymbolContextEverything, sc, - resolve_tail_call_address); - if (sc.function || sc.symbol) { - sc.GetAddressRange(eSymbolContextFunction | - eSymbolContextSymbol, - 0, false, range); - } else { - failed = true; - } - } else { - failed = true; - } - if (failed) { - result.AppendErrorWithFormat( - "Could not find function bounds for address 0x%" PRIx64 - "\n", - m_options.symbol_containing_addr); - result.SetStatus(eReturnStatusFailed); - return false; - } - ranges.push_back(range); - } else { - for (lldb::ModuleSP module_sp : target->GetImages().Modules()) { - lldb::addr_t file_addr = m_options.symbol_containing_addr; - Address file_address; - if (module_sp->ResolveFileAddress(file_addr, file_address)) { - SymbolContext sc; - bool resolve_tail_call_address = true; // PC can be one past - // the address range of - // the function. - module_sp->ResolveSymbolContextForAddress( - file_address, eSymbolContextEverything, sc, - resolve_tail_call_address); - if (sc.function || sc.symbol) { - sc.GetAddressRange(eSymbolContextFunction | - eSymbolContextSymbol, - 0, false, range); - ranges.push_back(range); - } - } - } - } - } - } - } - } else - ranges.push_back(range); - - if (m_options.num_instructions != 0) { - if (ranges.empty()) { - // The default action is to disassemble the current frame function. - if (frame) { - SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | - eSymbolContextSymbol)); - if (sc.function) - range.GetBaseAddress() = - sc.function->GetAddressRange().GetBaseAddress(); - else if (sc.symbol && sc.symbol->ValueIsAddress()) - range.GetBaseAddress() = sc.symbol->GetAddress(); - else - range.GetBaseAddress() = frame->GetFrameCodeAddress(); - } - - if (!range.GetBaseAddress().IsValid()) { - result.AppendError("invalid frame"); - result.SetStatus(eReturnStatusFailed); - return false; - } - } - - bool print_sc_header = ranges.size() > 1; - for (AddressRange cur_range : ranges) { - if (Disassembler::Disassemble( - GetDebugger(), m_options.arch, plugin_name, flavor_string, - m_exe_ctx, cur_range.GetBaseAddress(), - m_options.num_instructions, m_options.show_mixed, - m_options.show_mixed ? m_options.num_lines_context : 0, options, - result.GetOutputStream())) { - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - if (m_options.start_addr != LLDB_INVALID_ADDRESS) - result.AppendErrorWithFormat( - "Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", - m_options.start_addr); - else if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS) - result.AppendErrorWithFormat( - "Failed to disassemble memory in function at 0x%8.8" PRIx64 - ".\n", - m_options.symbol_containing_addr); - result.SetStatus(eReturnStatusFailed); - } - } - if (print_sc_header) - result.AppendMessage("\n"); - } else { - if (ranges.empty()) { - // The default action is to disassemble the current frame function. - if (frame) { - SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | - eSymbolContextSymbol)); - if (sc.function) - range = sc.function->GetAddressRange(); - else if (sc.symbol && sc.symbol->ValueIsAddress()) { - range.GetBaseAddress() = sc.symbol->GetAddress(); - range.SetByteSize(sc.symbol->GetByteSize()); - } else - range.GetBaseAddress() = frame->GetFrameCodeAddress(); - } else { - result.AppendError("invalid frame"); - result.SetStatus(eReturnStatusFailed); - return false; - } - ranges.push_back(range); - } - - bool print_sc_header = ranges.size() > 1; - for (AddressRange cur_range : ranges) { - if (cur_range.GetByteSize() == 0) - cur_range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE); - - if (Disassembler::Disassemble( - GetDebugger(), m_options.arch, plugin_name, flavor_string, - m_exe_ctx, cur_range, m_options.num_instructions, - m_options.show_mixed, - m_options.show_mixed ? m_options.num_lines_context : 0, options, - result.GetOutputStream())) { - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - result.AppendErrorWithFormat( - "Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", - cur_range.GetBaseAddress().GetLoadAddress(target)); - result.SetStatus(eReturnStatusFailed); - } - if (print_sc_header) - result.AppendMessage("\n"); + result.AppendErrorWithFormat( + "Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", + cur_range.GetBaseAddress().GetLoadAddress(target)); } + result.SetStatus(eReturnStatusFailed); } + if (print_sc_header) + result.GetOutputStream() << "\n"; } return result.Succeeded(); diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectDisassemble.h b/gnu/llvm/lldb/source/Commands/CommandObjectDisassemble.h index 70193e914c7..340bf648de1 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectDisassemble.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectDisassemble.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectDisassemble_h_ -#define liblldb_CommandObjectDisassemble_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTDISASSEMBLE_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTDISASSEMBLE_H #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/Options.h" @@ -62,6 +62,7 @@ public: // "at_pc". This should be set // in SetOptionValue if anything the selects a location is set. lldb::addr_t symbol_containing_addr; + bool force = false; }; CommandObjectDisassemble(CommandInterpreter &interpreter); @@ -73,9 +74,22 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override; + llvm::Expected> + GetRangesForSelectedMode(CommandReturnObject &result); + + llvm::Expected> GetContainingAddressRanges(); + llvm::Expected> GetCurrentFunctionRanges(); + llvm::Expected> GetCurrentLineRanges(); + llvm::Expected> + GetNameRanges(CommandReturnObject &result); + llvm::Expected> GetPCRanges(); + llvm::Expected> GetStartEndAddressRanges(); + + llvm::Error CheckRangeSize(const AddressRange &range, llvm::StringRef what); + CommandOptions m_options; }; } // namespace lldb_private -#endif // liblldb_CommandObjectDisassemble_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTDISASSEMBLE_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectExpression.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectExpression.cpp index db90dde98ef..b23adb087b4 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectExpression.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectExpression.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectExpression.cpp -----------------------------*- C++ -*-===// +//===-- CommandObjectExpression.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -311,7 +311,12 @@ void CommandObjectExpression::HandleCompletion(CompletionRequest &request) { target = &GetDummyTarget(); unsigned cursor_pos = request.GetRawCursorPos(); - llvm::StringRef code = request.GetRawLine(); + // Get the full user input including the suffix. The suffix is necessary + // as OptionsWithRaw will use it to detect if the cursor is cursor is in the + // argument part of in the raw input part of the arguments. If we cut of + // of the suffix then "expr -arg[cursor] --" would interpret the "-arg" as + // the raw input (as the "--" is hidden in the suffix). + llvm::StringRef code = request.GetRawLineWithUnusedSuffix(); const std::size_t original_code_size = code.size(); @@ -357,29 +362,13 @@ CanBeUsedForElementCountPrinting(ValueObject &valobj) { return Status(); } -bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, - Stream *output_stream, - Stream *error_stream, - CommandReturnObject *result) { - // Don't use m_exe_ctx as this might be called asynchronously after the - // command object DoExecute has finished when doing multi-line expression - // that use an input reader... - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - - Target *target = exe_ctx.GetTargetPtr(); - - if (!target) - target = &GetDummyTarget(); - - lldb::ValueObjectSP result_valobj_sp; - bool keep_in_memory = true; - StackFrame *frame = exe_ctx.GetFramePtr(); - +EvaluateExpressionOptions +CommandObjectExpression::GetEvalOptions(const Target &target) { EvaluateExpressionOptions options; options.SetCoerceToId(m_varobj_options.use_objc); options.SetUnwindOnError(m_command_options.unwind_on_error); options.SetIgnoreBreakpoints(m_command_options.ignore_breakpoints); - options.SetKeepInMemory(keep_in_memory); + options.SetKeepInMemory(true); options.SetUseDynamic(m_varobj_options.use_dynamic); options.SetTryAllThreads(m_command_options.try_all_threads); options.SetDebug(m_command_options.debug); @@ -391,11 +380,12 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, bool auto_apply_fixits; if (m_command_options.auto_apply_fixits == eLazyBoolCalculate) - auto_apply_fixits = target->GetEnableAutoApplyFixIts(); + auto_apply_fixits = target.GetEnableAutoApplyFixIts(); else auto_apply_fixits = m_command_options.auto_apply_fixits == eLazyBoolYes; options.SetAutoApplyFixIts(auto_apply_fixits); + options.SetRetriesWithFixIts(target.GetNumberOfRetriesWithFixits()); if (m_command_options.top_level) options.SetExecutionPolicy(eExecutionPolicyTopLevel); @@ -410,17 +400,36 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, options.SetTimeout(std::chrono::microseconds(m_command_options.timeout)); else options.SetTimeout(llvm::None); + return options; +} +bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, + Stream &output_stream, + Stream &error_stream, + CommandReturnObject &result) { + // Don't use m_exe_ctx as this might be called asynchronously after the + // command object DoExecute has finished when doing multi-line expression + // that use an input reader... + ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); + + Target *target = exe_ctx.GetTargetPtr(); + + if (!target) + target = &GetDummyTarget(); + + lldb::ValueObjectSP result_valobj_sp; + StackFrame *frame = exe_ctx.GetFramePtr(); + + const EvaluateExpressionOptions options = GetEvalOptions(*target); ExpressionResults success = target->EvaluateExpression( expr, frame, result_valobj_sp, options, &m_fixed_expression); // We only tell you about the FixIt if we applied it. The compiler errors // will suggest the FixIt if it parsed. - if (error_stream && !m_fixed_expression.empty() && - target->GetEnableNotifyAboutFixIts()) { + if (!m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts()) { if (success == eExpressionCompleted) - error_stream->Printf(" Fix-it applied, fixed expression was: \n %s\n", - m_fixed_expression.c_str()); + error_stream.Printf(" Fix-it applied, fixed expression was: \n %s\n", + m_fixed_expression.c_str()); } if (result_valobj_sp) { @@ -434,10 +443,10 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, if (m_varobj_options.elem_count > 0) { Status error(CanBeUsedForElementCountPrinting(*result_valobj_sp)); if (error.Fail()) { - result->AppendErrorWithFormat( + result.AppendErrorWithFormat( "expression cannot be used with --element-count %s\n", error.AsCString("")); - result->SetStatus(eReturnStatusFailed); + result.SetStatus(eReturnStatusFailed); return false; } } @@ -447,41 +456,39 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, options.SetVariableFormatDisplayLanguage( result_valobj_sp->GetPreferredDisplayLanguage()); - result_valobj_sp->Dump(*output_stream, options); + result_valobj_sp->Dump(output_stream, options); - if (result) - result->SetStatus(eReturnStatusSuccessFinishResult); + result.SetStatus(eReturnStatusSuccessFinishResult); } } else { if (result_valobj_sp->GetError().GetError() == UserExpression::kNoResult) { if (format != eFormatVoid && GetDebugger().GetNotifyVoid()) { - error_stream->PutCString("(void)\n"); + error_stream.PutCString("(void)\n"); } - if (result) - result->SetStatus(eReturnStatusSuccessFinishResult); + result.SetStatus(eReturnStatusSuccessFinishResult); } else { const char *error_cstr = result_valobj_sp->GetError().AsCString(); if (error_cstr && error_cstr[0]) { const size_t error_cstr_len = strlen(error_cstr); const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n'; if (strstr(error_cstr, "error:") != error_cstr) - error_stream->PutCString("error: "); - error_stream->Write(error_cstr, error_cstr_len); + error_stream.PutCString("error: "); + error_stream.Write(error_cstr, error_cstr_len); if (!ends_with_newline) - error_stream->EOL(); + error_stream.EOL(); } else { - error_stream->PutCString("error: unknown error\n"); + error_stream.PutCString("error: unknown error\n"); } - if (result) - result->SetStatus(eReturnStatusFailed); + result.SetStatus(eReturnStatusFailed); } } } - return true; + return (success != eExpressionSetupError && + success != eExpressionParseError); } void CommandObjectExpression::IOHandlerInputComplete(IOHandler &io_handler, @@ -493,7 +500,9 @@ void CommandObjectExpression::IOHandlerInputComplete(IOHandler &io_handler, StreamFileSP output_sp = io_handler.GetOutputStreamFileSP(); StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); - EvaluateExpression(line.c_str(), output_sp.get(), error_sp.get()); + CommandReturnObject return_obj( + GetCommandInterpreter().GetDebugger().GetUseColor()); + EvaluateExpression(line.c_str(), *output_sp, *error_sp, return_obj); if (output_sp) output_sp->Flush(); if (error_sp) @@ -535,7 +544,7 @@ void CommandObjectExpression::GetMultilineExpression() { "Enter expressions, then terminate with an empty line to evaluate:\n"); output_sp->Flush(); } - debugger.PushIOHandler(io_handler_sp); + debugger.RunIOHandlerAsync(io_handler_sp); } static EvaluateExpressionOptions @@ -622,10 +631,8 @@ bool CommandObjectExpression::DoExecute(llvm::StringRef command, } IOHandlerSP io_handler_sp(repl_sp->GetIOHandler()); - io_handler_sp->SetIsDone(false); - - debugger.PushIOHandler(io_handler_sp); + debugger.RunIOHandlerAsync(io_handler_sp); } else { repl_error.SetErrorStringWithFormat( "Couldn't create a REPL for %s", @@ -643,8 +650,8 @@ bool CommandObjectExpression::DoExecute(llvm::StringRef command, } Target &target = GetSelectedOrDummyTarget(); - if (EvaluateExpression(expr, &(result.GetOutputStream()), - &(result.GetErrorStream()), &result)) { + if (EvaluateExpression(expr, result.GetOutputStream(), + result.GetErrorStream(), result)) { if (!m_fixed_expression.empty() && target.GetEnableNotifyAboutFixIts()) { CommandHistory &history = m_interpreter.GetCommandHistory(); @@ -654,7 +661,7 @@ bool CommandObjectExpression::DoExecute(llvm::StringRef command, std::string fixed_command("expression "); if (args.HasArgs()) { // Add in any options that might have been in the original command: - fixed_command.append(args.GetArgStringWithDelimiter()); + fixed_command.append(std::string(args.GetArgStringWithDelimiter())); fixed_command.append(m_fixed_expression); } else fixed_command.append(m_fixed_expression); diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectExpression.h b/gnu/llvm/lldb/source/Commands/CommandObjectExpression.h index de159863b43..1e59cbc1452 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectExpression.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectExpression.h @@ -6,15 +6,17 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectExpression_h_ -#define liblldb_CommandObjectExpression_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTEXPRESSION_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTEXPRESSION_H #include "lldb/Core/IOHandler.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/OptionGroupBoolean.h" #include "lldb/Interpreter/OptionGroupFormat.h" #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" +#include "lldb/Target/Target.h" #include "lldb/lldb-private-enumerations.h" + namespace lldb_private { class CommandObjectExpression : public CommandObjectRaw, @@ -65,9 +67,22 @@ protected: bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override; - bool EvaluateExpression(llvm::StringRef expr, Stream *output_stream, - Stream *error_stream, - CommandReturnObject *result = nullptr); + /// Return the appropriate expression options used for evaluating the + /// expression in the given target. + EvaluateExpressionOptions GetEvalOptions(const Target &target); + + /// Evaluates the given expression. + /// \param output_stream The stream to which the evaluation result will be + /// printed. + /// \param error_stream Contains error messages that should be displayed to + /// the user in case the evaluation fails. + /// \param result A CommandReturnObject which status will be set to the + /// appropriate value depending on evaluation success and + /// whether the expression produced any result. + /// \return Returns true iff the expression was successfully evaluated, + /// executed and the result could be printed to the output stream. + bool EvaluateExpression(llvm::StringRef expr, Stream &output_stream, + Stream &error_stream, CommandReturnObject &result); void GetMultilineExpression(); @@ -83,4 +98,4 @@ protected: } // namespace lldb_private -#endif // liblldb_CommandObjectExpression_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTEXPRESSION_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectFrame.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectFrame.cpp index 50d5c751de5..6ebad9b5c48 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectFrame.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectFrame.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectFrame.cpp ----------------------------------*- C++ -*-===// +//===-- CommandObjectFrame.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -12,7 +12,6 @@ #include "lldb/DataFormatters/ValueObjectPrinter.h" #include "lldb/Host/Config.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" @@ -172,8 +171,7 @@ protected: Stream &stream) -> bool { const ValueObject::GetExpressionPathFormat format = ValueObject:: GetExpressionPathFormat::eGetExpressionPathFormatHonorPointers; - const bool qualify_cxx_base_classes = false; - valobj_sp->GetExpressionPath(stream, qualify_cxx_base_classes, format); + valobj_sp->GetExpressionPath(stream, format); stream.PutCString(" ="); return true; }; @@ -187,7 +185,6 @@ protected: return true; } -protected: CommandOptions m_options; }; @@ -291,6 +288,22 @@ public: ~CommandObjectFrameSelect() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (!m_exe_ctx.HasProcessScope() || request.GetCursorIndex() != 0) + return; + + lldb::ThreadSP thread_sp = m_exe_ctx.GetThreadSP(); + const uint32_t frame_num = thread_sp->GetStackFrameCount(); + for (uint32_t i = 0; i < frame_num; ++i) { + lldb::StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(i); + StreamString strm; + frame_sp->Dump(&strm, false, true); + request.TryCompleteCurrentArg(std::to_string(i), strm.GetString()); + } + } + Options *GetOptions() override { return &m_options; } protected: @@ -380,7 +393,6 @@ protected: return result.Succeeded(); } -protected: CommandOptions m_options; }; @@ -715,7 +727,6 @@ protected: return res; } -protected: OptionGroupOptions m_option_group; OptionGroupVariable m_option_variable; OptionGroupFormat m_option_format; @@ -747,7 +758,7 @@ private: m_module = std::string(option_arg); break; case 'n': - m_function = std::string(option_arg); + m_symbols.push_back(std::string(option_arg)); break; case 'x': m_regex = true; @@ -761,7 +772,7 @@ private: void OptionParsingStarting(ExecutionContext *execution_context) override { m_module = ""; - m_function = ""; + m_symbols.clear(); m_class_name = ""; m_regex = false; } @@ -773,7 +784,7 @@ private: // Instance variables to hold the values for command options. std::string m_class_name; std::string m_module; - std::string m_function; + std::vector m_symbols; bool m_regex; }; @@ -855,9 +866,18 @@ bool CommandObjectFrameRecognizerAdd::DoExecute(Args &command, return false; } - if (m_options.m_function.empty()) { - result.AppendErrorWithFormat("%s needs a function name (-n argument).\n", - m_cmd_name.c_str()); + if (m_options.m_symbols.empty()) { + result.AppendErrorWithFormat( + "%s needs at least one symbol name (-n argument).\n", + m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + if (m_options.m_regex && m_options.m_symbols.size() > 1) { + result.AppendErrorWithFormat( + "%s needs only one symbol regular expression (-n argument).\n", + m_cmd_name.c_str()); result.SetStatus(eReturnStatusFailed); return false; } @@ -877,12 +897,13 @@ bool CommandObjectFrameRecognizerAdd::DoExecute(Args &command, auto module = RegularExpressionSP(new RegularExpression(m_options.m_module)); auto func = - RegularExpressionSP(new RegularExpression(m_options.m_function)); + RegularExpressionSP(new RegularExpression(m_options.m_symbols.front())); 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); + std::vector symbols(m_options.m_symbols.begin(), + m_options.m_symbols.end()); + StackFrameRecognizerManager::AddRecognizer(recognizer_sp, module, symbols); } #endif @@ -914,6 +935,33 @@ public: ~CommandObjectFrameRecognizerDelete() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (request.GetCursorIndex() != 0) + return; + + StackFrameRecognizerManager::ForEach( + [&request](uint32_t rid, std::string rname, std::string module, + llvm::ArrayRef symbols, + bool regexp) { + StreamString strm; + if (rname.empty()) + rname = "(internal)"; + + strm << rname; + if (!module.empty()) + strm << ", module " << module; + if (!symbols.empty()) + for (auto &symbol : symbols) + strm << ", symbol " << symbol; + if (regexp) + strm << " (regexp)"; + + request.TryCompleteCurrentArg(std::to_string(rid), strm.GetString()); + }); + } + protected: bool DoExecute(Args &command, CommandReturnObject &result) override { if (command.GetArgumentCount() == 0) { @@ -937,8 +985,13 @@ protected: return false; } - uint32_t recognizer_id = - StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0); + uint32_t recognizer_id; + if (!llvm::to_integer(command.GetArgumentAtIndex(0), recognizer_id)) { + result.AppendErrorWithFormat("'%s' is not a valid recognizer id.\n", + command.GetArgumentAtIndex(0)); + result.SetStatus(eReturnStatusFailed); + return false; + } StackFrameRecognizerManager::RemoveRecognizerWithID(recognizer_id); result.SetStatus(eReturnStatusSuccessFinishResult); @@ -959,14 +1012,26 @@ 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 == "") + [&result, &any_printed]( + uint32_t recognizer_id, std::string name, std::string module, + llvm::ArrayRef symbols, bool regexp) { + Stream &stream = result.GetOutputStream(); + + if (name.empty()) 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)" : ""); + + stream << std::to_string(recognizer_id) << ": " << name; + if (!module.empty()) + stream << ", module " << module; + if (!symbols.empty()) + for (auto &symbol : symbols) + stream << ", symbol " << symbol; + if (regexp) + stream << " (regexp)"; + + stream.EOL(); + stream.Flush(); + any_printed = true; }); @@ -1006,6 +1071,15 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { + const char *frame_index_str = command.GetArgumentAtIndex(0); + uint32_t frame_index; + if (!llvm::to_integer(frame_index_str, frame_index)) { + result.AppendErrorWithFormat("'%s' is not a valid frame index.", + frame_index_str); + result.SetStatus(eReturnStatusFailed); + return false; + } + Process *process = m_exe_ctx.GetProcessPtr(); if (process == nullptr) { result.AppendError("no process"); @@ -1025,8 +1099,6 @@ protected: 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); diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectFrame.h b/gnu/llvm/lldb/source/Commands/CommandObjectFrame.h index b2378f14290..71cb94aa8f5 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectFrame.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectFrame.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectFrame_h_ -#define liblldb_CommandObjectFrame_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTFRAME_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTFRAME_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -24,4 +24,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectFrame_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTFRAME_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectGUI.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectGUI.cpp index 67ddc68a169..3f45a26de22 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectGUI.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectGUI.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectGUI.cpp ------------------------------------*- C++ -*-===// +//===-- CommandObjectGUI.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -35,7 +35,7 @@ bool CommandObjectGUI::DoExecute(Args &args, CommandReturnObject &result) { input.GetIsInteractive()) { IOHandlerSP io_handler_sp(new IOHandlerCursesGUI(debugger)); if (io_handler_sp) - debugger.PushIOHandler(io_handler_sp); + debugger.RunIOHandlerAsync(io_handler_sp); result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendError("the gui command requires an interactive terminal."); @@ -47,7 +47,7 @@ bool CommandObjectGUI::DoExecute(Args &args, CommandReturnObject &result) { } return true; #else - result.AppendError("lldb was not build with gui support"); + result.AppendError("lldb was not built with gui support"); return false; #endif } diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectGUI.h b/gnu/llvm/lldb/source/Commands/CommandObjectGUI.h index a19aad18ec3..49bad49a957 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectGUI.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectGUI.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectGUI_h_ -#define liblldb_CommandObjectGUI_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTGUI_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTGUI_H #include "lldb/Interpreter/CommandObject.h" @@ -27,4 +27,4 @@ protected: } // namespace lldb_private -#endif // liblldb_CommandObjectGUI_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTGUI_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectHelp.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectHelp.cpp index 6e908dc496a..6dc1868a2af 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectHelp.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectHelp.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectHelp.cpp -----------------------------------*- C++ -*-===// +//===-- CommandObjectHelp.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -107,7 +107,7 @@ bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) { // object that corresponds to the help command entered. std::string sub_command; for (auto &entry : command.entries().drop_front()) { - sub_command = entry.ref(); + sub_command = std::string(entry.ref()); matches.Clear(); if (sub_cmd_obj->IsAlias()) sub_cmd_obj = diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectHelp.h b/gnu/llvm/lldb/source/Commands/CommandObjectHelp.h index 52a00ac79ff..8f45db55666 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectHelp.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectHelp.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectHelp_h_ -#define liblldb_CommandObjectHelp_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTHELP_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTHELP_H #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandObject.h" @@ -84,4 +84,4 @@ private: } // namespace lldb_private -#endif // liblldb_CommandObjectHelp_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTHELP_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectLanguage.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectLanguage.cpp index 35ce6e3193e..e6d22ec4ae4 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectLanguage.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectLanguage.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectLanguage.cpp -------------------------------*- C++ -*-===// +//===-- CommandObjectLanguage.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectLanguage.h b/gnu/llvm/lldb/source/Commands/CommandObjectLanguage.h index 47079e219d0..7a280902a07 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectLanguage.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectLanguage.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectLanguage_h_ -#define liblldb_CommandObjectLanguage_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTLANGUAGE_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTLANGUAGE_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -23,4 +23,4 @@ protected: }; } // namespace lldb_private -#endif // liblldb_CommandObjectLanguage_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTLANGUAGE_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectLog.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectLog.cpp index 9bf0b30bc15..4016b07c91e 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectLog.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectLog.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectLog.cpp ------------------------------------*- C++ -*-===// +//===-- CommandObjectLog.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -156,7 +156,7 @@ protected: } // Store into a std::string since we're about to shift the channel off. - const std::string channel = args[0].ref(); + const std::string channel = std::string(args[0].ref()); args.Shift(); // Shift off the channel char log_file[PATH_MAX]; if (m_options.log_file) @@ -229,7 +229,7 @@ protected: return false; } - const std::string channel = args[0].ref(); + const std::string channel = std::string(args[0].ref()); args.Shift(); // Shift off the channel if (channel == "all") { Log::DisableAllLogChannels(); @@ -298,61 +298,170 @@ protected: } }; -class CommandObjectLogTimer : public CommandObjectParsed { +class CommandObjectLogTimerEnable : public CommandObjectParsed { public: // Constructors and Destructors - CommandObjectLogTimer(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "log timers", - "Enable, disable, dump, and reset LLDB internal " - "performance timers.", - "log timers < enable | disable | dump | " - "increment | reset >") {} + CommandObjectLogTimerEnable(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "log timers enable", + "enable LLDB internal performance timers", + "log timers enable ") { + CommandArgumentEntry arg; + CommandArgumentData depth_arg; - ~CommandObjectLogTimer() override = default; + // Define the first (and only) variant of this arg. + depth_arg.arg_type = eArgTypeCount; + depth_arg.arg_repetition = eArgRepeatOptional; + + // There is only one variant this argument could be; put it into the + // argument entry. + arg.push_back(depth_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back(arg); + } + + ~CommandObjectLogTimerEnable() override = default; + +protected: + bool DoExecute(Args &args, CommandReturnObject &result) override { + result.SetStatus(eReturnStatusFailed); + + if (args.GetArgumentCount() == 0) { + Timer::SetDisplayDepth(UINT32_MAX); + result.SetStatus(eReturnStatusSuccessFinishNoResult); + } else if (args.GetArgumentCount() == 1) { + uint32_t depth; + if (args[0].ref().consumeInteger(0, depth)) { + result.AppendError( + "Could not convert enable depth to an unsigned integer."); + } else { + Timer::SetDisplayDepth(depth); + result.SetStatus(eReturnStatusSuccessFinishNoResult); + } + } + + if (!result.Succeeded()) { + result.AppendError("Missing subcommand"); + result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); + } + return result.Succeeded(); + } +}; + +class CommandObjectLogTimerDisable : public CommandObjectParsed { +public: + // Constructors and Destructors + CommandObjectLogTimerDisable(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "log timers disable", + "disable LLDB internal performance timers", + nullptr) {} + + ~CommandObjectLogTimerDisable() override = default; + +protected: + bool DoExecute(Args &args, CommandReturnObject &result) override { + Timer::DumpCategoryTimes(&result.GetOutputStream()); + Timer::SetDisplayDepth(0); + result.SetStatus(eReturnStatusSuccessFinishResult); + + if (!result.Succeeded()) { + result.AppendError("Missing subcommand"); + result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); + } + return result.Succeeded(); + } +}; + +class CommandObjectLogTimerDump : public CommandObjectParsed { +public: + // Constructors and Destructors + CommandObjectLogTimerDump(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "log timers dump", + "dump LLDB internal performance timers", nullptr) {} + + ~CommandObjectLogTimerDump() override = default; + +protected: + bool DoExecute(Args &args, CommandReturnObject &result) override { + Timer::DumpCategoryTimes(&result.GetOutputStream()); + result.SetStatus(eReturnStatusSuccessFinishResult); + + if (!result.Succeeded()) { + result.AppendError("Missing subcommand"); + result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); + } + return result.Succeeded(); + } +}; + +class CommandObjectLogTimerReset : public CommandObjectParsed { +public: + // Constructors and Destructors + CommandObjectLogTimerReset(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "log timers reset", + "reset LLDB internal performance timers", nullptr) { + } + + ~CommandObjectLogTimerReset() override = default; + +protected: + bool DoExecute(Args &args, CommandReturnObject &result) override { + Timer::ResetCategoryTimes(); + result.SetStatus(eReturnStatusSuccessFinishResult); + + if (!result.Succeeded()) { + result.AppendError("Missing subcommand"); + result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); + } + return result.Succeeded(); + } +}; + +class CommandObjectLogTimerIncrement : public CommandObjectParsed { +public: + // Constructors and Destructors + CommandObjectLogTimerIncrement(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "log timers increment", + "increment LLDB internal performance timers", + "log timers increment ") { + CommandArgumentEntry arg; + CommandArgumentData bool_arg; + + // Define the first (and only) variant of this arg. + bool_arg.arg_type = eArgTypeBoolean; + bool_arg.arg_repetition = eArgRepeatPlain; + + // There is only one variant this argument could be; put it into the + // argument entry. + arg.push_back(bool_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back(arg); + } + + ~CommandObjectLogTimerIncrement() override = default; + + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + request.TryCompleteCurrentArg("true"); + request.TryCompleteCurrentArg("false"); + } protected: bool DoExecute(Args &args, CommandReturnObject &result) override { result.SetStatus(eReturnStatusFailed); if (args.GetArgumentCount() == 1) { - auto sub_command = args[0].ref(); + bool success; + bool increment = + OptionArgParser::ToBoolean(args[0].ref(), false, &success); - if (sub_command.equals_lower("enable")) { - Timer::SetDisplayDepth(UINT32_MAX); + if (success) { + Timer::SetQuiet(!increment); result.SetStatus(eReturnStatusSuccessFinishNoResult); - } else if (sub_command.equals_lower("disable")) { - Timer::DumpCategoryTimes(&result.GetOutputStream()); - Timer::SetDisplayDepth(0); - result.SetStatus(eReturnStatusSuccessFinishResult); - } else if (sub_command.equals_lower("dump")) { - Timer::DumpCategoryTimes(&result.GetOutputStream()); - result.SetStatus(eReturnStatusSuccessFinishResult); - } else if (sub_command.equals_lower("reset")) { - Timer::ResetCategoryTimes(); - result.SetStatus(eReturnStatusSuccessFinishResult); - } - } else if (args.GetArgumentCount() == 2) { - auto sub_command = args[0].ref(); - auto param = args[1].ref(); - - if (sub_command.equals_lower("enable")) { - uint32_t depth; - if (param.consumeInteger(0, depth)) { - result.AppendError( - "Could not convert enable depth to an unsigned integer."); - } else { - Timer::SetDisplayDepth(depth); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } - } else if (sub_command.equals_lower("increment")) { - bool success; - bool increment = OptionArgParser::ToBoolean(param, false, &success); - if (success) { - Timer::SetQuiet(!increment); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } else - result.AppendError("Could not convert increment value to boolean."); - } + } else + result.AppendError("Could not convert increment value to boolean."); } if (!result.Succeeded()) { @@ -363,6 +472,30 @@ protected: } }; +class CommandObjectLogTimer : public CommandObjectMultiword { +public: + CommandObjectLogTimer(CommandInterpreter &interpreter) + : CommandObjectMultiword(interpreter, "log timers", + "Enable, disable, dump, and reset LLDB internal " + "performance timers.", + "log timers < enable | disable | dump | " + "increment | reset >") { + LoadSubCommand("enable", CommandObjectSP( + new CommandObjectLogTimerEnable(interpreter))); + LoadSubCommand("disable", CommandObjectSP(new CommandObjectLogTimerDisable( + interpreter))); + LoadSubCommand("dump", + CommandObjectSP(new CommandObjectLogTimerDump(interpreter))); + LoadSubCommand( + "reset", CommandObjectSP(new CommandObjectLogTimerReset(interpreter))); + LoadSubCommand( + "increment", + CommandObjectSP(new CommandObjectLogTimerIncrement(interpreter))); + } + + ~CommandObjectLogTimer() override = default; +}; + CommandObjectLog::CommandObjectLog(CommandInterpreter &interpreter) : CommandObjectMultiword(interpreter, "log", "Commands controlling LLDB internal logging.", diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectLog.h b/gnu/llvm/lldb/source/Commands/CommandObjectLog.h index eae41bf6b8d..8dc3f1b7b9e 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectLog.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectLog.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectLog_h_ -#define liblldb_CommandObjectLog_h_ - +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTLOG_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTLOG_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -25,9 +24,10 @@ public: private: // For CommandObjectLog only - DISALLOW_COPY_AND_ASSIGN(CommandObjectLog); + CommandObjectLog(const CommandObjectLog &) = delete; + const CommandObjectLog &operator=(const CommandObjectLog &) = delete; }; } // namespace lldb_private -#endif // liblldb_CommandObjectLog_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTLOG_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectMemory.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectMemory.cpp index e497b5246b8..474c3771014 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectMemory.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectMemory.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectMemory.cpp ---------------------------------*- C++ -*-===// +//===-- CommandObjectMemory.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectMemory.h b/gnu/llvm/lldb/source/Commands/CommandObjectMemory.h index f94cdf3287a..5f7f6bb30b8 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectMemory.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectMemory.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectMemory_h_ -#define liblldb_CommandObjectMemory_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTMEMORY_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTMEMORY_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -22,4 +22,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectMemory_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTMEMORY_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectMultiword.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectMultiword.cpp index 67225d3d6b8..9033cfebf46 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectMultiword.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectMultiword.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectMultiword.cpp ------------------------------*- C++ -*-===// +//===-- CommandObjectMultiword.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -32,7 +32,7 @@ CommandObjectSP CommandObjectMultiword::GetSubcommandSP(llvm::StringRef sub_cmd, CommandObject::CommandMap::iterator pos; if (!m_subcommand_dict.empty()) { - pos = m_subcommand_dict.find(sub_cmd); + pos = m_subcommand_dict.find(std::string(sub_cmd)); if (pos != m_subcommand_dict.end()) { // An exact match; append the sub_cmd to the 'matches' string list. if (matches) @@ -50,7 +50,7 @@ CommandObjectSP CommandObjectMultiword::GetSubcommandSP(llvm::StringRef sub_cmd, // function, since I now know I have an exact match... sub_cmd = matches->GetStringAtIndex(0); - pos = m_subcommand_dict.find(sub_cmd); + pos = m_subcommand_dict.find(std::string(sub_cmd)); if (pos != m_subcommand_dict.end()) return_cmd_sp = pos->second; } @@ -74,9 +74,9 @@ bool CommandObjectMultiword::LoadSubCommand(llvm::StringRef name, CommandMap::iterator pos; bool success = true; - pos = m_subcommand_dict.find(name); + pos = m_subcommand_dict.find(std::string(name)); if (pos == m_subcommand_dict.end()) { - m_subcommand_dict[name] = cmd_obj; + m_subcommand_dict[std::string(name)] = cmd_obj; } else success = false; @@ -130,9 +130,9 @@ bool CommandObjectMultiword::Execute(const char *args_string, error_msg.assign("invalid command "); error_msg.append("'"); - error_msg.append(GetCommandName()); + error_msg.append(std::string(GetCommandName())); error_msg.append(" "); - error_msg.append(sub_command); + error_msg.append(std::string(sub_command)); error_msg.append("'."); if (num_subcmd_matches > 0) { @@ -165,15 +165,14 @@ void CommandObjectMultiword::GenerateHelpText(Stream &output_stream) { std::string indented_command(" "); indented_command.append(pos->first); if (pos->second->WantsRawCommandString()) { - std::string help_text(pos->second->GetHelp()); + std::string help_text(std::string(pos->second->GetHelp())); help_text.append(" Expects 'raw' input (see 'help raw-input'.)"); - m_interpreter.OutputFormattedHelpText(output_stream, - indented_command.c_str(), "--", - help_text.c_str(), max_len); + m_interpreter.OutputFormattedHelpText(output_stream, indented_command, + "--", help_text, max_len); } else - m_interpreter.OutputFormattedHelpText(output_stream, - indented_command.c_str(), "--", - pos->second->GetHelp(), max_len); + m_interpreter.OutputFormattedHelpText(output_stream, indented_command, + "--", pos->second->GetHelp(), + max_len); } output_stream.PutCString("\nFor more help on any particular subcommand, type " diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectPlatform.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectPlatform.cpp index 10e6a4aa179..fcc8af6f915 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectPlatform.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectPlatform.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectPlatform.cpp -------------------------------*- C++ -*-===// +//===-- CommandObjectPlatform.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -11,7 +11,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandOptionValidators.h" #include "lldb/Interpreter/CommandReturnObject.h" @@ -133,7 +132,8 @@ public: uint32_t m_permissions; private: - DISALLOW_COPY_AND_ASSIGN(OptionPermissions); + OptionPermissions(const OptionPermissions &) = delete; + const OptionPermissions &operator=(const OptionPermissions &) = delete; }; // "platform select " @@ -421,7 +421,6 @@ protected: return &m_options; } -protected: OptionGroupOptions m_options; OptionGroupFile m_option_working_dir; }; @@ -546,8 +545,13 @@ public: if (platform_sp) { std::string cmd_line; args.GetCommandString(cmd_line); - const lldb::user_id_t fd = - StringConvert::ToUInt64(cmd_line.c_str(), UINT64_MAX); + lldb::user_id_t fd; + if (!llvm::to_integer(cmd_line, fd)) { + result.AppendErrorWithFormatv("'{0}' is not a valid file descriptor.\n", + cmd_line); + result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); + } Status error; bool success = platform_sp->CloseFile(fd, error); if (success) { @@ -586,8 +590,13 @@ public: if (platform_sp) { std::string cmd_line; args.GetCommandString(cmd_line); - const lldb::user_id_t fd = - StringConvert::ToUInt64(cmd_line.c_str(), UINT64_MAX); + lldb::user_id_t fd; + if (!llvm::to_integer(cmd_line, fd)) { + result.AppendErrorWithFormatv("'{0}' is not a valid file descriptor.\n", + cmd_line); + result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); + } std::string buffer(m_options.m_count, 0); Status error; uint32_t retcode = platform_sp->ReadFile( @@ -674,8 +683,13 @@ public: std::string cmd_line; args.GetCommandString(cmd_line); Status error; - const lldb::user_id_t fd = - StringConvert::ToUInt64(cmd_line.c_str(), UINT64_MAX); + lldb::user_id_t fd; + if (!llvm::to_integer(cmd_line, fd)) { + result.AppendErrorWithFormatv("'{0}' is not a valid file descriptor.", + cmd_line); + result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); + } uint32_t retcode = platform_sp->WriteFile(fd, m_options.m_offset, &m_options.m_data[0], m_options.m_data.size(), error); @@ -709,7 +723,7 @@ protected: option_arg.str().c_str()); break; case 'd': - m_data.assign(option_arg); + m_data.assign(std::string(option_arg)); break; default: llvm_unreachable("Unimplemented option"); @@ -758,7 +772,9 @@ public: private: // For CommandObjectPlatform only - DISALLOW_COPY_AND_ASSIGN(CommandObjectPlatformFile); + CommandObjectPlatformFile(const CommandObjectPlatformFile &) = delete; + const CommandObjectPlatformFile & + operator=(const CommandObjectPlatformFile &) = delete; }; // "platform get-file remote-file-path host-file-path" @@ -1020,7 +1036,6 @@ protected: return result.Succeeded(); } -protected: ProcessLaunchCommandOptions m_options; }; @@ -1128,7 +1143,7 @@ protected: ProcessInstanceInfo::DumpTableHeader(ostrm, m_options.show_args, m_options.verbose); for (uint32_t i = 0; i < matches; ++i) { - proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow( + proc_infos[i].DumpAsTableRow( ostrm, platform_sp->GetUserIDResolver(), m_options.show_args, m_options.verbose); } @@ -1462,12 +1477,12 @@ public: match_info.SetNameMatchType(NameMatch::StartsWith); } platform_sp->FindProcesses(match_info, process_infos); - const uint32_t num_matches = process_infos.GetSize(); + const uint32_t num_matches = process_infos.size(); if (num_matches == 0) return; for (uint32_t i = 0; i < num_matches; ++i) { - request.AddCompletion(process_infos.GetProcessNameAtIndex(i)); + request.AddCompletion(process_infos[i].GetNameAsStringRef()); } return; } @@ -1541,7 +1556,9 @@ public: private: // For CommandObjectPlatform only - DISALLOW_COPY_AND_ASSIGN(CommandObjectPlatformProcess); + CommandObjectPlatformProcess(const CommandObjectPlatformProcess &) = delete; + const CommandObjectPlatformProcess & + operator=(const CommandObjectPlatformProcess &) = delete; }; // "platform shell" @@ -1567,6 +1584,9 @@ public: const char short_option = (char)GetDefinitions()[option_idx].short_option; switch (short_option) { + case 'h': + m_use_host_platform = true; + break; case 't': uint32_t timeout_sec; if (option_arg.getAsInteger(10, timeout_sec)) @@ -1574,7 +1594,7 @@ public: "could not convert \"%s\" to a numeric value.", option_arg.str().c_str()); else - timeout = std::chrono::seconds(timeout_sec); + m_timeout = std::chrono::seconds(timeout_sec); break; default: llvm_unreachable("Unimplemented option"); @@ -1583,9 +1603,13 @@ public: return error; } - void OptionParsingStarting(ExecutionContext *execution_context) override {} + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_timeout.reset(); + m_use_host_platform = false; + } - Timeout timeout = std::chrono::seconds(10); + Timeout m_timeout = std::chrono::seconds(10); + bool m_use_host_platform; }; CommandObjectPlatformShell(CommandInterpreter &interpreter) @@ -1609,6 +1633,7 @@ public: return true; } + const bool is_alias = !raw_command_line.contains("platform"); OptionsWithRaw args(raw_command_line); const char *expr = args.GetRawPart().c_str(); @@ -1616,8 +1641,16 @@ public: if (!ParseOptions(args.GetArgs(), result)) return false; + if (args.GetRawPart().empty()) { + result.GetOutputStream().Printf("%s \n", + is_alias ? "shell" : "platform shell"); + return false; + } + PlatformSP platform_sp( - GetDebugger().GetPlatformList().GetSelectedPlatform()); + m_options.m_use_host_platform + ? Platform::GetHostPlatform() + : GetDebugger().GetPlatformList().GetSelectedPlatform()); Status error; if (platform_sp) { FileSpec working_dir{}; @@ -1625,7 +1658,7 @@ public: int status = -1; int signo = -1; error = (platform_sp->RunShellCommand(expr, working_dir, &status, &signo, - &output, m_options.timeout)); + &output, m_options.m_timeout)); if (!output.empty()) result.GetOutputStream().PutCString(output); if (status > 0) { diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectPlatform.h b/gnu/llvm/lldb/source/Commands/CommandObjectPlatform.h index 45e4a41c5b2..86f55c7d9b0 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectPlatform.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectPlatform.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectPlatform_h_ -#define liblldb_CommandObjectPlatform_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTPLATFORM_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTPLATFORM_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -22,9 +22,11 @@ public: ~CommandObjectPlatform() override; private: - DISALLOW_COPY_AND_ASSIGN(CommandObjectPlatform); + CommandObjectPlatform(const CommandObjectPlatform &) = delete; + const CommandObjectPlatform & + operator=(const CommandObjectPlatform &) = delete; }; } // namespace lldb_private -#endif // liblldb_CommandObjectPlatform_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTPLATFORM_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectPlugin.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectPlugin.cpp index 6fcb64f207b..98a212eef0f 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectPlugin.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectPlugin.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectPlugin.cpp ---------------------------------*- C++ -*-===// +//===-- CommandObjectPlugin.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectPlugin.h b/gnu/llvm/lldb/source/Commands/CommandObjectPlugin.h index 94cea7db411..6db9f0a40a4 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectPlugin.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectPlugin.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectPlugin_h_ -#define liblldb_CommandObjectPlugin_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTPLUGIN_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTPLUGIN_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -22,4 +22,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectPlugin_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTPLUGIN_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectProcess.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectProcess.cpp index d825647728f..f86779d85b5 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectProcess.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectProcess.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectProcess.cpp --------------------------------*- C++ -*-===// +//===-- CommandObjectProcess.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,7 +13,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" @@ -249,7 +248,6 @@ protected: return result.Succeeded(); } -protected: ProcessLaunchCommandOptions m_options; }; @@ -325,34 +323,38 @@ public: int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; - // We are only completing the name option for now... - - // Are we in the name? - if (GetDefinitions()[opt_defs_index].short_option != 'n') - return; - - // Look to see if there is a -P argument provided, and if so use that - // plugin, otherwise use the default plugin. - - const char *partial_name = nullptr; - partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos); + switch (GetDefinitions()[opt_defs_index].short_option) { + case 'n': { + // Look to see if there is a -P argument provided, and if so use that + // plugin, otherwise use the default plugin. + + const char *partial_name = nullptr; + partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos); + + PlatformSP platform_sp(interpreter.GetPlatform(true)); + if (!platform_sp) + return; + ProcessInstanceInfoList process_infos; + ProcessInstanceInfoMatch match_info; + if (partial_name) { + match_info.GetProcessInfo().GetExecutableFile().SetFile( + partial_name, FileSpec::Style::native); + match_info.SetNameMatchType(NameMatch::StartsWith); + } + platform_sp->FindProcesses(match_info, process_infos); + const size_t num_matches = process_infos.size(); + if (num_matches == 0) + return; + for (size_t i = 0; i < num_matches; ++i) { + request.AddCompletion(process_infos[i].GetNameAsStringRef()); + } + } break; - PlatformSP platform_sp(interpreter.GetPlatform(true)); - if (!platform_sp) - return; - ProcessInstanceInfoList process_infos; - ProcessInstanceInfoMatch match_info; - if (partial_name) { - match_info.GetProcessInfo().GetExecutableFile().SetFile( - partial_name, FileSpec::Style::native); - match_info.SetNameMatchType(NameMatch::StartsWith); - } - platform_sp->FindProcesses(match_info, process_infos); - const size_t num_matches = process_infos.GetSize(); - if (num_matches == 0) - return; - for (size_t i = 0; i < num_matches; ++i) { - request.AddCompletion(process_infos.GetProcessNameAtIndex(i)); + case 'P': + CommandCompletions::InvokeCommonCompletionCallbacks( + interpreter, CommandCompletions::eProcessPluginCompletion, request, + nullptr); + break; } } @@ -759,7 +761,7 @@ public: switch (short_option) { case 'p': - plugin_name.assign(option_arg); + plugin_name.assign(std::string(option_arg)); break; default: @@ -818,9 +820,15 @@ protected: Status error; Debugger &debugger = GetDebugger(); PlatformSP platform_sp = m_interpreter.GetPlatform(true); - ProcessSP process_sp = platform_sp->ConnectProcess( - command.GetArgumentAtIndex(0), plugin_name, debugger, - debugger.GetSelectedTarget().get(), error); + ProcessSP process_sp = + debugger.GetAsyncExecution() + ? platform_sp->ConnectProcess( + command.GetArgumentAtIndex(0), plugin_name, debugger, + debugger.GetSelectedTarget().get(), error) + : platform_sp->ConnectProcessSynchronous( + command.GetArgumentAtIndex(0), plugin_name, debugger, + result.GetOutputStream(), debugger.GetSelectedTarget().get(), + error); if (error.Fail() || process_sp == nullptr) { result.AppendError(error.AsCString("Error connecting to the process")); result.SetStatus(eReturnStatusFailed); @@ -1034,6 +1042,20 @@ public: ~CommandObjectProcessSignal() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (!m_exe_ctx.HasProcessScope() || request.GetCursorIndex() != 0) + return; + + UnixSignalsSP signals = m_exe_ctx.GetProcessPtr()->GetUnixSignals(); + int signo = signals->GetFirstSignalNumber(); + while (signo != LLDB_INVALID_SIGNAL_NUMBER) { + request.AddCompletion(signals->GetSignalAsCString(signo), ""); + signo = signals->GetNextSignalNumber(signo); + } + } + protected: bool DoExecute(Args &command, CommandReturnObject &result) override { Process *process = m_exe_ctx.GetProcessPtr(); @@ -1042,10 +1064,10 @@ protected: int signo = LLDB_INVALID_SIGNAL_NUMBER; const char *signal_name = command.GetArgumentAtIndex(0); - if (::isxdigit(signal_name[0])) - signo = - StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); - else + if (::isxdigit(signal_name[0])) { + if (!llvm::to_integer(signal_name, signo)) + signo = LLDB_INVALID_SIGNAL_NUMBER; + } else signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name); if (signo == LLDB_INVALID_SIGNAL_NUMBER) { @@ -1201,6 +1223,8 @@ protected: // CommandObjectProcessStatus #pragma mark CommandObjectProcessStatus +#define LLDB_OPTIONS_process_status +#include "CommandOptions.inc" class CommandObjectProcessStatus : public CommandObjectParsed { public: @@ -1209,13 +1233,57 @@ public: interpreter, "process status", "Show status and stop location for the current target process.", "process status", - eCommandRequiresProcess | eCommandTryTargetAPILock) {} + eCommandRequiresProcess | eCommandTryTargetAPILock), + m_options() {} ~CommandObjectProcessStatus() override = default; + Options *GetOptions() override { return &m_options; } + + class CommandOptions : public Options { + public: + CommandOptions() : Options(), m_verbose(false) {} + + ~CommandOptions() override = default; + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) override { + const int short_option = m_getopt_table[option_idx].val; + + switch (short_option) { + case 'v': + m_verbose = true; + break; + default: + llvm_unreachable("Unimplemented option"); + } + + return {}; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_verbose = false; + } + + llvm::ArrayRef GetDefinitions() override { + return llvm::makeArrayRef(g_process_status_options); + } + + // Instance variables to hold the values for command options. + bool m_verbose; + }; + +protected: bool DoExecute(Args &command, CommandReturnObject &result) override { Stream &strm = result.GetOutputStream(); result.SetStatus(eReturnStatusSuccessFinishNoResult); + + if (command.GetArgumentCount()) { + result.AppendError("'process status' takes no arguments"); + result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); + } + // No need to check "process" for validity as eCommandRequiresProcess // ensures it is valid Process *process = m_exe_ctx.GetProcessPtr(); @@ -1227,8 +1295,37 @@ public: process->GetStatus(strm); process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame, num_frames, num_frames_with_source, stop_format); + + if (m_options.m_verbose) { + PlatformSP platform_sp = process->GetTarget().GetPlatform(); + if (!platform_sp) { + result.AppendError("Couldn'retrieve the target's platform"); + result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); + } + + auto expected_crash_info = + platform_sp->FetchExtendedCrashInformation(*process); + + if (!expected_crash_info) { + result.AppendError(llvm::toString(expected_crash_info.takeError())); + result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); + } + + StructuredData::DictionarySP crash_info_sp = *expected_crash_info; + + if (crash_info_sp) { + strm.PutCString("Extended Crash Information:\n"); + crash_info_sp->Dump(strm); + } + } + return result.Succeeded(); } + +private: + CommandOptions m_options; }; // CommandObjectProcessHandle @@ -1252,13 +1349,13 @@ public: switch (short_option) { case 's': - stop = option_arg; + stop = std::string(option_arg); break; case 'n': - notify = option_arg; + notify = std::string(option_arg); break; case 'p': - pass = option_arg; + pass = std::string(option_arg); break; default: llvm_unreachable("Unimplemented option"); @@ -1318,7 +1415,8 @@ public: real_value = 0; else { // If the value isn't 'true' or 'false', it had better be 0 or 1. - real_value = StringConvert::ToUInt32(option.c_str(), 3); + if (!llvm::to_integer(option, real_value)) + real_value = 3; if (real_value != 0 && real_value != 1) okay = false; } diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectProcess.h b/gnu/llvm/lldb/source/Commands/CommandObjectProcess.h index 3b1ff26dbb0..55d445142e7 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectProcess.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectProcess.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectProcess_h_ -#define liblldb_CommandObjectProcess_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTPROCESS_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTPROCESS_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -24,4 +24,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectProcess_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTPROCESS_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectQuit.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectQuit.cpp index 70ee336f8a1..d0c7bbd3abf 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectQuit.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectQuit.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectQuit.cpp -----------------------------------*- C++ -*-===// +//===-- CommandObjectQuit.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectQuit.h b/gnu/llvm/lldb/source/Commands/CommandObjectQuit.h index 458ef2456fc..ccbd863cd6f 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectQuit.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectQuit.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectQuit_h_ -#define liblldb_CommandObjectQuit_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTQUIT_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTQUIT_H #include "lldb/Interpreter/CommandObject.h" @@ -29,4 +29,4 @@ protected: } // namespace lldb_private -#endif // liblldb_CommandObjectQuit_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTQUIT_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectRegister.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectRegister.cpp index 523b32a996b..56e8c3fb4b8 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectRegister.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectRegister.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectRegister.cpp -------------------------------*- C++ -*-===// +//===-- CommandObjectRegister.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -70,6 +70,17 @@ public: ~CommandObjectRegisterRead() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (!m_exe_ctx.HasProcessScope()) + return; + + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eRegisterCompletion, + request, nullptr); + } + Options *GetOptions() override { return &m_option_group; } bool DumpRegister(const ExecutionContext &exe_ctx, Stream &strm, @@ -323,6 +334,17 @@ public: ~CommandObjectRegisterWrite() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (!m_exe_ctx.HasProcessScope() || request.GetCursorIndex() != 0) + return; + + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eRegisterCompletion, + request, nullptr); + } + protected: bool DoExecute(Args &command, CommandReturnObject &result) override { DataExtractor reg_data; diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectRegister.h b/gnu/llvm/lldb/source/Commands/CommandObjectRegister.h index 6fc47cf386a..671ffc57014 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectRegister.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectRegister.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectRegister_h_ -#define liblldb_CommandObjectRegister_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTREGISTER_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTREGISTER_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -24,9 +24,11 @@ public: private: // For CommandObjectRegister only - DISALLOW_COPY_AND_ASSIGN(CommandObjectRegister); + CommandObjectRegister(const CommandObjectRegister &) = delete; + const CommandObjectRegister & + operator=(const CommandObjectRegister &) = delete; }; } // namespace lldb_private -#endif // liblldb_CommandObjectRegister_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTREGISTER_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectReproducer.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectReproducer.cpp index d15f622314d..104130b70b2 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectReproducer.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectReproducer.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectReproducer.cpp -----------------------------*- C++ -*-===// +//===-- CommandObjectReproducer.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,13 +8,14 @@ #include "CommandObjectReproducer.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Utility/GDBRemote.h" -#include "lldb/Utility/Reproducer.h" - #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Utility/GDBRemote.h" +#include "lldb/Utility/ProcessInfo.h" +#include "lldb/Utility/Reproducer.h" #include @@ -27,6 +28,7 @@ enum ReproducerProvider { eReproducerProviderCommands, eReproducerProviderFiles, eReproducerProviderGDB, + eReproducerProviderProcessInfo, eReproducerProviderVersion, eReproducerProviderWorkingDirectory, eReproducerProviderNone @@ -48,6 +50,11 @@ static constexpr OptionEnumValueElement g_reproducer_provider_type[] = { "gdb", "GDB Remote Packets", }, + { + eReproducerProviderProcessInfo, + "processes", + "Process Info", + }, { eReproducerProviderVersion, "version", @@ -97,6 +104,24 @@ static constexpr OptionEnumValues ReproducerSignalType() { #define LLDB_OPTIONS_reproducer_xcrash #include "CommandOptions.inc" +template +llvm::Expected static ReadFromYAML(StringRef filename) { + auto error_or_file = MemoryBuffer::getFile(filename); + if (auto err = error_or_file.getError()) { + return errorCodeToError(err); + } + + T t; + yaml::Input yin((*error_or_file)->getBuffer()); + yin >> t; + + if (auto err = yin.error()) { + return errorCodeToError(err); + } + + return t; +} + class CommandObjectReproducerGenerate : public CommandObjectParsed { public: CommandObjectReproducerGenerate(CommandInterpreter &interpreter) @@ -258,6 +283,18 @@ protected: result.GetOutputStream() << "Reproducer is off.\n"; } + if (r.IsCapturing() || r.IsReplaying()) { + result.GetOutputStream() + << "Path: " << r.GetReproducerPath().GetPath() << '\n'; + } + + // Auto generate is hidden unless enabled because this is mostly for + // development and testing. + if (Generator *g = r.GetGenerator()) { + if (g->IsAutoGenerate()) + result.GetOutputStream() << "Auto generate: on\n"; + } + result.SetStatus(eReturnStatusSuccessFinishResult); return result.Succeeded(); } @@ -410,8 +447,8 @@ protected: repro::MultiLoader::Create(loader); if (!multi_loader) { SetError(result, - make_error(llvm::inconvertibleErrorCode(), - "Unable to create command loader.")); + make_error("Unable to create command loader.", + llvm::inconvertibleErrorCode())); return false; } @@ -436,26 +473,52 @@ protected: std::unique_ptr> multi_loader = repro::MultiLoader::Create(loader); + + if (!multi_loader) { + SetError(result, + make_error("Unable to create GDB loader.", + llvm::inconvertibleErrorCode())); + return false; + } + llvm::Optional gdb_file; while ((gdb_file = multi_loader->GetNextFile())) { - auto error_or_file = MemoryBuffer::getFile(*gdb_file); - if (auto err = error_or_file.getError()) { - SetError(result, errorCodeToError(err)); + if (llvm::Expected> packets = + ReadFromYAML>(*gdb_file)) { + for (GDBRemotePacket &packet : *packets) { + packet.Dump(result.GetOutputStream()); + } + } else { + SetError(result, packets.takeError()); return false; } + } + + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } + case eReproducerProviderProcessInfo: { + std::unique_ptr> + multi_loader = + repro::MultiLoader::Create(loader); - std::vector packets; - yaml::Input yin((*error_or_file)->getBuffer()); - yin >> packets; + if (!multi_loader) { + SetError(result, make_error( + llvm::inconvertibleErrorCode(), + "Unable to create process info loader.")); + return false; + } - if (auto err = yin.error()) { - SetError(result, errorCodeToError(err)); + llvm::Optional process_file; + while ((process_file = multi_loader->GetNextFile())) { + if (llvm::Expected infos = + ReadFromYAML(*process_file)) { + for (ProcessInstanceInfo info : *infos) + info.Dump(result.GetOutputStream(), HostInfo::GetUserIDResolver()); + } else { + SetError(result, infos.takeError()); return false; } - - for (GDBRemotePacket &packet : packets) { - packet.Dump(result.GetOutputStream()); - } } result.SetStatus(eReturnStatusSuccessFinishResult); diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectReproducer.h b/gnu/llvm/lldb/source/Commands/CommandObjectReproducer.h index 8a85c21d651..bdee8053549 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectReproducer.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectReproducer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectReproducer_h_ -#define liblldb_CommandObjectReproducer_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTREPRODUCER_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTREPRODUCER_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -24,4 +24,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectReproducer_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTREPRODUCER_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectSettings.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectSettings.cpp index 95f79f45e22..87e0352636e 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectSettings.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectSettings.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectSettings.cpp -------------------------------*- C++ -*-===// +//===-- CommandObjectSettings.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -343,7 +343,7 @@ public: switch (short_option) { case 'f': - m_filename.assign(option_arg); + m_filename.assign(std::string(option_arg)); break; case 'a': m_append = true; @@ -444,7 +444,7 @@ public: switch (short_option) { case 'f': - m_filename.assign(option_arg); + m_filename.assign(std::string(option_arg)); break; default: llvm_unreachable("Unimplemented option"); @@ -531,10 +531,8 @@ protected: if (argc > 0) { const bool dump_qualified_name = true; - // TODO: Convert to StringRef based enumeration. Requires converting - // GetPropertyAtPath first. - for (size_t i = 0; i < argc; ++i) { - const char *property_path = args.GetArgumentAtIndex(i); + for (const Args::ArgEntry &arg : args) { + const char *property_path = arg.c_str(); const Property *property = GetDebugger().GetValueProperties()->GetPropertyAtPath( @@ -1043,13 +1041,16 @@ protected: }; // CommandObjectSettingsClear +#define LLDB_OPTIONS_settings_clear +#include "CommandOptions.inc" class CommandObjectSettingsClear : public CommandObjectParsed { public: CommandObjectSettingsClear(CommandInterpreter &interpreter) : CommandObjectParsed( interpreter, "settings clear", - "Clear a debugger setting array, dictionary, or string.", nullptr) { + "Clear a debugger setting array, dictionary, or string. " + "If '-a' option is specified, it clears all settings.", nullptr) { CommandArgumentEntry arg; CommandArgumentData var_name_arg; @@ -1077,11 +1078,53 @@ public: request, nullptr); } + Options *GetOptions() override { return &m_options; } + + class CommandOptions : public Options { + public: + CommandOptions() = default; + + ~CommandOptions() override = default; + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) override { + const int short_option = m_getopt_table[option_idx].val; + switch (short_option) { + case 'a': + m_clear_all = true; + break; + default: + llvm_unreachable("Unimplemented option"); + } + return Status(); + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_clear_all = false; + } + + llvm::ArrayRef GetDefinitions() override { + return llvm::makeArrayRef(g_settings_clear_options); + } + + bool m_clear_all = false; + }; + protected: bool DoExecute(Args &command, CommandReturnObject &result) override { result.SetStatus(eReturnStatusSuccessFinishNoResult); const size_t argc = command.GetArgumentCount(); + if (m_options.m_clear_all) { + if (argc != 0) { + result.AppendError("'settings clear --all' doesn't take any arguments"); + result.SetStatus(eReturnStatusFailed); + return false; + } + GetDebugger().GetValueProperties()->Clear(); + return result.Succeeded(); + } + if (argc != 1) { result.AppendError("'settings clear' takes exactly one argument"); result.SetStatus(eReturnStatusFailed); @@ -1106,6 +1149,9 @@ protected: return result.Succeeded(); } + + private: + CommandOptions m_options; }; // CommandObjectMultiwordSettings diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectSettings.h b/gnu/llvm/lldb/source/Commands/CommandObjectSettings.h index 4db0ca1f83f..31ec1d3bef1 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectSettings.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectSettings.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectSettings_h_ -#define liblldb_CommandObjectSettings_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTSETTINGS_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTSETTINGS_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -24,4 +24,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectSettings_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTSETTINGS_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectSource.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectSource.cpp index 19a554fb290..1ccfd3a5166 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectSource.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectSource.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectSource.cpp ---------------------------------*- C++ -*-===// +//===-- CommandObjectSource.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -63,11 +63,11 @@ class CommandObjectSourceInfo : public CommandObjectParsed { break; case 'f': - file_name = option_arg; + file_name = std::string(option_arg); break; case 'n': - symbol_name = option_arg; + symbol_name = std::string(option_arg); break; case 'a': { @@ -646,11 +646,11 @@ class CommandObjectSourceList : public CommandObjectParsed { break; case 'f': - file_name = option_arg; + file_name = std::string(option_arg); break; case 'n': - symbol_name = option_arg; + symbol_name = std::string(option_arg); break; case 'a': { diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectSource.h b/gnu/llvm/lldb/source/Commands/CommandObjectSource.h index a4b8823a4fa..f2117bd6ca3 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectSource.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectSource.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectSource_h_ -#define liblldb_CommandObjectSource_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTSOURCE_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTSOURCE_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -25,4 +25,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectSource_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTSOURCE_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectStats.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectStats.cpp index eeec4a8d3e7..6b06581f5a8 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectStats.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectStats.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectStats.cpp ----------------------------------*- C++ -*-===// +//===-- CommandObjectStats.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectStats.h b/gnu/llvm/lldb/source/Commands/CommandObjectStats.h index 593c4521e17..c4cd6340f67 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectStats.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectStats.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectStats_h_ -#define liblldb_CommandObjectStats_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTSTATS_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTSTATS_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -20,4 +20,4 @@ public: }; } // namespace lldb_private -#endif // liblldb_CommandObjectLanguage_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTSTATS_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectTarget.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectTarget.cpp index 8738e850c9f..7bb71f4d518 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectTarget.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectTarget.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===// +//===-- CommandObjectTarget.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -16,7 +16,6 @@ #include "lldb/Core/ValueObjectVariable.h" #include "lldb/DataFormatters/ValueObjectPrinter.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" @@ -200,7 +199,9 @@ public: LoadDependentFiles m_load_dependent_files; private: - DISALLOW_COPY_AND_ASSIGN(OptionGroupDependents); + OptionGroupDependents(const OptionGroupDependents &) = delete; + const OptionGroupDependents & + operator=(const OptionGroupDependents &) = delete; }; #pragma mark CommandObjectTargetCreate @@ -271,15 +272,13 @@ protected: FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue()); if (core_file) { - 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 (!FileSystem::Instance().Readable(core_file)) { - result.AppendErrorWithFormat("core file '%s' is not readable", - core_file.GetPath().c_str()); + auto file = FileSystem::Instance().Open( + core_file, lldb_private::File::eOpenOptionRead); + + if (!file) { + result.AppendErrorWithFormatv("Cannot open '{0}': {1}.", + core_file.GetPath(), + llvm::toString(file.takeError())); result.SetStatus(eReturnStatusFailed); return false; } @@ -288,18 +287,13 @@ protected: if (argc == 1 || core_file || remote_file) { FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue()); if (symfile) { - 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); - return false; - } - } else { - char symfile_path[PATH_MAX]; - symfile.GetPath(symfile_path, sizeof(symfile_path)); - result.AppendErrorWithFormat("invalid symbol file path '%s'", - symfile_path); + auto file = FileSystem::Instance().Open( + symfile, lldb_private::File::eOpenOptionRead); + + if (!file) { + result.AppendErrorWithFormatv("Cannot open '{0}': {1}.", + symfile.GetPath(), + llvm::toString(file.takeError())); result.SetStatus(eReturnStatusFailed); return false; } @@ -401,48 +395,34 @@ protected: if (module_sp) module_sp->SetPlatformFileSpec(remote_file); } + if (core_file) { - char core_path[PATH_MAX]; - core_file.GetPath(core_path, sizeof(core_path)); - 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); - return false; - } - FileSpec core_file_dir; - core_file_dir.GetDirectory() = core_file.GetDirectory(); - target_sp->AppendExecutableSearchPaths(core_file_dir); + FileSpec core_file_dir; + core_file_dir.GetDirectory() = core_file.GetDirectory(); + target_sp->AppendExecutableSearchPaths(core_file_dir); - ProcessSP process_sp(target_sp->CreateProcess( - GetDebugger().GetListener(), llvm::StringRef(), &core_file)); + ProcessSP process_sp(target_sp->CreateProcess( + GetDebugger().GetListener(), llvm::StringRef(), &core_file)); - if (process_sp) { - // Seems weird that we Launch a core file, but that is what we - // do! - error = process_sp->LoadCore(); + if (process_sp) { + // Seems weird that we Launch a core file, but that is what we + // do! + error = process_sp->LoadCore(); - if (error.Fail()) { - result.AppendError( - error.AsCString("can't find plug-in for core file")); - result.SetStatus(eReturnStatusFailed); - return false; - } else { - result.AppendMessageWithFormat( - "Core file '%s' (%s) was loaded.\n", core_path, - target_sp->GetArchitecture().GetArchitectureName()); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } - } else { - result.AppendErrorWithFormat( - "Unable to find process plug-in for core file '%s'\n", - core_path); + if (error.Fail()) { + result.AppendError( + error.AsCString("can't find plug-in for core file")); result.SetStatus(eReturnStatusFailed); + return false; + } else { + result.AppendMessageWithFormatv("Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(), + target_sp->GetArchitecture().GetArchitectureName()); + result.SetStatus(eReturnStatusSuccessFinishNoResult); } } else { - result.AppendErrorWithFormat("Core file '%s' does not exist\n", - core_path); + result.AppendErrorWithFormatv( + "Unable to find process plug-in for core file '{0}'\n", + core_file.GetPath()); result.SetStatus(eReturnStatusFailed); } } else { @@ -525,11 +505,9 @@ public: protected: bool DoExecute(Args &args, CommandReturnObject &result) override { if (args.GetArgumentCount() == 1) { - bool success = false; const char *target_idx_arg = args.GetArgumentAtIndex(0); - uint32_t target_idx = - StringConvert::ToUInt32(target_idx_arg, UINT32_MAX, 0, &success); - if (success) { + uint32_t target_idx; + if (llvm::to_integer(target_idx_arg, target_idx)) { TargetList &target_list = GetDebugger().GetTargetList(); const uint32_t num_targets = target_list.GetNumTargets(); if (target_idx < num_targets) { @@ -571,7 +549,7 @@ protected: } }; -#pragma mark CommandObjectTargetSelect +#pragma mark CommandObjectTargetDelete // "target delete" @@ -682,6 +660,41 @@ protected: OptionGroupBoolean m_cleanup_option; }; +class CommandObjectTargetShowLaunchEnvironment : public CommandObjectParsed { +public: + CommandObjectTargetShowLaunchEnvironment(CommandInterpreter &interpreter) + : CommandObjectParsed( + interpreter, "target show-launch-environment", + "Shows the environment being passed to the process when launched, " + "taking info account 3 settings: target.env-vars, " + "target.inherit-env and target.unset-env-vars.", + nullptr, eCommandRequiresTarget) {} + + ~CommandObjectTargetShowLaunchEnvironment() override = default; + +protected: + bool DoExecute(Args &args, CommandReturnObject &result) override { + Target *target = m_exe_ctx.GetTargetPtr(); + Environment env = target->GetEnvironment(); + + std::vector env_vector; + env_vector.reserve(env.size()); + for (auto &KV : env) + env_vector.push_back(&KV); + std::sort(env_vector.begin(), env_vector.end(), + [](Environment::value_type *a, Environment::value_type *b) { + return a->first() < b->first(); + }); + + auto &strm = result.GetOutputStream(); + for (auto &KV : env_vector) + strm.Format("{0}={1}\n", KV->first(), KV->second); + + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } +}; + #pragma mark CommandObjectTargetVariable // "target variable" @@ -841,21 +854,18 @@ protected: Stream &s = result.GetOutputStream(); if (argc > 0) { - - // TODO: Convert to entry-based iteration. Requires converting - // DumpValueObject. - for (size_t idx = 0; idx < argc; ++idx) { + for (const Args::ArgEntry &arg : args) { VariableList variable_list; ValueObjectList valobj_list; - const char *arg = args.GetArgumentAtIndex(idx); size_t matches = 0; bool use_var_name = false; if (m_option_variable.use_regex) { - RegularExpression regex(llvm::StringRef::withNullAsEmpty(arg)); + RegularExpression regex( + llvm::StringRef::withNullAsEmpty(arg.c_str())); if (!regex.IsValid()) { result.GetErrorStream().Printf( - "error: invalid regular expression: '%s'\n", arg); + "error: invalid regular expression: '%s'\n", arg.c_str()); result.SetStatus(eReturnStatusFailed); return false; } @@ -865,14 +875,14 @@ protected: matches = variable_list.GetSize(); } else { Status error(Variable::GetValuesForVariableExpressionPath( - arg, m_exe_ctx.GetBestExecutionContextScope(), + arg.c_str(), m_exe_ctx.GetBestExecutionContextScope(), GetVariableCallback, target, variable_list, valobj_list)); matches = variable_list.GetSize(); } if (matches == 0) { result.GetErrorStream().Printf( - "error: can't find global variable '%s'\n", arg); + "error: can't find global variable '%s'\n", arg.c_str()); result.SetStatus(eReturnStatusFailed); return false; } else { @@ -888,7 +898,7 @@ protected: if (valobj_sp) DumpValueObject(s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() - : arg); + : arg.c_str()); } } } @@ -1163,12 +1173,9 @@ protected: size_t argc = command.GetArgumentCount(); // check for at least 3 arguments and an odd number of parameters if (argc >= 3 && argc & 1) { - bool success = false; - - uint32_t insert_idx = StringConvert::ToUInt32( - command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success); + uint32_t insert_idx; - if (!success) { + if (!llvm::to_integer(command.GetArgumentAtIndex(0), insert_idx)) { result.AppendErrorWithFormat( " parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0)); @@ -1292,7 +1299,7 @@ static void DumpModuleArchitecture(Stream &strm, Module *module, module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream()); else arch_strm.PutCString(module->GetArchitecture().GetArchitectureName()); - std::string arch_str = arch_strm.GetString(); + std::string arch_str = std::string(arch_strm.GetString()); if (width) strm.Printf("%-*s", width, arch_str.c_str()); @@ -1431,11 +1438,9 @@ static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm, strm.Printf("Sections for '%s' (%s):\n", module->GetSpecificationDescription().c_str(), module->GetArchitecture().GetArchitectureName()); - strm.IndentMore(); - section_list->Dump(&strm, + section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2, interpreter.GetExecutionContext().GetTargetPtr(), true, UINT32_MAX); - strm.IndentLess(); } } } @@ -1599,8 +1604,9 @@ static size_t LookupFunctionInModule(CommandInterpreter &interpreter, include_inlines, sc_list); } else { ConstString function_name(name); - module->FindFunctions(function_name, nullptr, eFunctionNameTypeAuto, - include_symbols, include_inlines, sc_list); + module->FindFunctions(function_name, CompilerDeclContext(), + eFunctionNameTypeAuto, include_symbols, + include_inlines, sc_list); } num_matches = sc_list.GetSize(); if (num_matches) { @@ -2162,7 +2168,7 @@ protected: } }; -#pragma mark CommandObjectTargetModulesDumpSections +#pragma mark CommandObjectTargetModulesDumpClangAST // Clang AST dumping command @@ -2736,10 +2742,8 @@ protected: const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1); if (sect_name && load_addr_cstr) { ConstString const_sect_name(sect_name); - bool success = false; - addr_t load_addr = StringConvert::ToUInt64( - load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success); - if (success) { + addr_t load_addr; + if (llvm::to_integer(load_addr_cstr, load_addr)) { SectionSP section_sp( section_list->FindSectionByName(const_sect_name)); if (section_sp) { @@ -3022,17 +3026,14 @@ protected: module_list_ptr = &target->GetImages(); } } else { - // TODO: Convert to entry based iteration. Requires converting - // FindModulesByName. - for (size_t i = 0; i < argc; ++i) { + for (const Args::ArgEntry &arg : command) { // Dump specified images (by basename or fullpath) - const char *arg_cstr = command.GetArgumentAtIndex(i); const size_t num_matches = FindModulesByName( - target, arg_cstr, module_list, use_global_module_list); + target, arg.c_str(), module_list, use_global_module_list); if (num_matches == 0) { if (argc == 1) { result.AppendErrorWithFormat("no modules found that match '%s'", - arg_cstr); + arg.c_str()); result.SetStatus(eReturnStatusFailed); return false; } @@ -3268,7 +3269,7 @@ public: switch (short_option) { case 'a': { - m_str = option_arg; + m_str = std::string(option_arg); m_type = eLookupTypeAddress; m_addr = OptionArgParser::ToAddress(execution_context, option_arg, LLDB_INVALID_ADDRESS, &error); @@ -3279,7 +3280,7 @@ public: } case 'n': - m_str = option_arg; + m_str = std::string(option_arg); m_type = eLookupTypeFunctionOrSymbol; break; @@ -3603,7 +3604,7 @@ public: break; case 's': - m_str = option_arg; + m_str = std::string(option_arg); m_type = eLookupTypeSymbol; break; @@ -3626,17 +3627,17 @@ public: break; case 'F': - m_str = option_arg; + m_str = std::string(option_arg); m_type = eLookupTypeFunction; break; case 'n': - m_str = option_arg; + m_str = std::string(option_arg); m_type = eLookupTypeFunctionOrSymbol; break; case 't': - m_str = option_arg; + m_str = std::string(option_arg); m_type = eLookupTypeType; break; @@ -3990,7 +3991,9 @@ public: private: // For CommandObjectTargetModules only - DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetModules); + CommandObjectTargetModules(const CommandObjectTargetModules &) = delete; + const CommandObjectTargetModules & + operator=(const CommandObjectTargetModules &) = delete; }; class CommandObjectTargetSymbolsAdd : public CommandObjectParsed { @@ -3999,19 +4002,20 @@ public: : CommandObjectParsed( interpreter, "target symbols add", "Add a debug symbol file to one of the target's current modules by " - "specifying a path to a debug symbols file, or using the options " - "to specify a module to download symbols for.", + "specifying a path to a debug symbols file or by using the options " + "to specify a module.", "target symbols add []", eCommandRequiresTarget), m_option_group(), m_file_option( LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, - "Fullpath or basename for module to find debug symbols for."), + "Locate the debug symbols for the shared library specified by " + "name."), m_current_frame_option( LLDB_OPT_SET_2, false, "frame", 'F', - "Locate the debug symbols the currently selected frame.", false, - true) + "Locate the debug symbols for the currently selected frame.", + false, true) { m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL, @@ -4053,12 +4057,10 @@ protected: module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename(); } - // We now have a module that represents a symbol file that can be used - // for a module that might exist in the current target, so we need to - // find that module in the target - ModuleList matching_module_list; + // Now module_spec represents a symbol file for a module that might exist + // in the current target. Let's find possible matches. + ModuleList matching_modules; - size_t num_matches = 0; // First extract all module specs from the symbol file lldb_private::ModuleSpecList symfile_module_specs; if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(), @@ -4069,34 +4071,30 @@ protected: target_arch_module_spec.GetArchitecture() = target->GetArchitecture(); if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec, symfile_module_spec)) { - // See if it has a UUID? if (symfile_module_spec.GetUUID().IsValid()) { // It has a UUID, look for this UUID in the target modules ModuleSpec symfile_uuid_module_spec; symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); target->GetImages().FindModules(symfile_uuid_module_spec, - matching_module_list); - num_matches = matching_module_list.GetSize(); + matching_modules); } } - if (num_matches == 0) { - // No matches yet, iterate through the module specs to find a UUID - // value that we can match up to an image in our target - const size_t num_symfile_module_specs = - symfile_module_specs.GetSize(); - for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0; - ++i) { + if (matching_modules.IsEmpty()) { + // No matches yet. Iterate through the module specs to find a UUID + // value that we can match up to an image in our target. + const size_t num_symfile_module_specs = symfile_module_specs.GetSize(); + for (size_t i = 0; + i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) { if (symfile_module_specs.GetModuleSpecAtIndex( i, symfile_module_spec)) { if (symfile_module_spec.GetUUID().IsValid()) { - // It has a UUID, look for this UUID in the target modules + // It has a UUID. Look for this UUID in the target modules. ModuleSpec symfile_uuid_module_spec; symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); target->GetImages().FindModules(symfile_uuid_module_spec, - matching_module_list); - num_matches = matching_module_list.GetSize(); + matching_modules); } } } @@ -4104,13 +4102,11 @@ protected: } // Just try to match up the file by basename if we have no matches at - // this point - if (num_matches == 0) { - target->GetImages().FindModules(module_spec, matching_module_list); - num_matches = matching_module_list.GetSize(); - } + // this point. For example, module foo might have symbols in foo.debug. + if (matching_modules.IsEmpty()) + target->GetImages().FindModules(module_spec, matching_modules); - while (num_matches == 0) { + while (matching_modules.IsEmpty()) { ConstString filename_no_extension( module_spec.GetFileSpec().GetFileNameStrippingExtension()); // Empty string returned, let's bail @@ -4123,17 +4119,20 @@ protected: // Replace basename with one fewer extension module_spec.GetFileSpec().GetFilename() = filename_no_extension; - target->GetImages().FindModules(module_spec, matching_module_list); - num_matches = matching_module_list.GetSize(); + target->GetImages().FindModules(module_spec, matching_modules); } - if (num_matches > 1) { + if (matching_modules.GetSize() > 1) { result.AppendErrorWithFormat("multiple modules match symbol file '%s', " "use the --uuid option to resolve the " "ambiguity.\n", symfile_path); - } else if (num_matches == 1) { - ModuleSP module_sp(matching_module_list.GetModuleAtIndex(0)); + result.SetStatus(eReturnStatusFailed); + return false; + } + + if (matching_modules.GetSize() == 1) { + ModuleSP module_sp(matching_modules.GetModuleAtIndex(0)); // The module has not yet created its symbol vendor, we can just give // the existing target module the symfile path to use for when it @@ -4144,7 +4143,6 @@ protected: module_sp->GetSymbolFile(true, &result.GetErrorStream()); if (symbol_file) { ObjectFile *object_file = symbol_file->GetObjectFile(); - if (object_file && object_file->GetFileSpec() == symbol_fspec) { // Provide feedback that the symfile has been successfully added. const FileSpec &module_fs = module_sp->GetFileSpec(); @@ -4163,7 +4161,7 @@ protected: Status error; StreamString feedback_stream; module_sp->LoadScriptingResourceInTarget(target, error, - &feedback_stream); + &feedback_stream); if (error.Fail() && error.AsCString()) result.AppendWarningWithFormat( "unable to load scripting data for module %s - error " @@ -4173,7 +4171,7 @@ protected: .GetCString(), error.AsCString()); else if (feedback_stream.GetSize()) - result.AppendWarningWithFormat("%s", feedback_stream.GetData()); + result.AppendWarning(feedback_stream.GetData()); flush = true; result.SetStatus(eReturnStatusSuccessFinishResult); @@ -4184,7 +4182,6 @@ protected: module_sp->SetSymbolFileFileSpec(FileSpec()); } - namespace fs = llvm::sys::fs; StreamString ss_symfile_uuid; if (module_spec.GetUUID().IsValid()) { ss_symfile_uuid << " ("; @@ -4194,7 +4191,7 @@ protected: result.AppendErrorWithFormat( "symbol file '%s'%s does not match any existing module%s\n", symfile_path, ss_symfile_uuid.GetData(), - !fs::is_regular_file(symbol_fspec.GetPath()) + !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath()) ? "\n please specify the full path to the symbol file" : ""); result.SetStatus(eReturnStatusFailed); @@ -4394,7 +4391,9 @@ public: private: // For CommandObjectTargetModules only - DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetSymbols); + CommandObjectTargetSymbols(const CommandObjectTargetSymbols &) = delete; + const CommandObjectTargetSymbols & + operator=(const CommandObjectTargetSymbols &) = delete; }; #pragma mark CommandObjectTargetStopHookAdd @@ -4427,7 +4426,7 @@ public: switch (short_option) { case 'c': - m_class_name = option_arg; + m_class_name = std::string(option_arg); m_sym_ctx_specified = true; break; @@ -4464,18 +4463,18 @@ public: break; case 'n': - m_function_name = option_arg; + m_function_name = std::string(option_arg); m_func_name_type_mask |= eFunctionNameTypeAuto; m_sym_ctx_specified = true; break; case 'f': - m_file_name = option_arg; + m_file_name = std::string(option_arg); m_sym_ctx_specified = true; break; case 's': - m_module_name = option_arg; + m_module_name = std::string(option_arg); m_sym_ctx_specified = true; break; @@ -4487,12 +4486,12 @@ public: break; case 'T': - m_thread_name = option_arg; + m_thread_name = std::string(option_arg); m_thread_specified = true; break; case 'q': - m_queue_name = option_arg; + m_queue_name = std::string(option_arg); m_thread_specified = true; break; @@ -4505,7 +4504,7 @@ public: case 'o': m_use_one_liner = true; - m_one_liner.push_back(option_arg); + m_one_liner.push_back(std::string(option_arg)); break; default: @@ -4615,8 +4614,8 @@ protected: // First step, make the specifier. std::unique_ptr specifier_up; if (m_options.m_sym_ctx_specified) { - specifier_up.reset( - new SymbolContextSpecifier(GetDebugger().GetSelectedTarget())); + specifier_up = std::make_unique( + GetDebugger().GetSelectedTarget()); if (!m_options.m_module_name.empty()) { specifier_up->AddSpecification( @@ -4725,18 +4724,15 @@ protected: target.RemoveAllStopHooks(); } } else { - bool success; for (size_t i = 0; i < num_args; i++) { - lldb::user_id_t user_id = StringConvert::ToUInt32( - command.GetArgumentAtIndex(i), 0, 0, &success); - if (!success) { + lldb::user_id_t user_id; + if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) { result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); result.SetStatus(eReturnStatusFailed); return false; } - success = target.RemoveStopHookByID(user_id); - if (!success) { + if (!target.RemoveStopHookByID(user_id)) { result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); result.SetStatus(eReturnStatusFailed); @@ -4774,9 +4770,8 @@ protected: target.SetAllStopHooksActiveState(m_enable); } else { for (size_t i = 0; i < num_args; i++) { - lldb::user_id_t user_id = StringConvert::ToUInt32( - command.GetArgumentAtIndex(i), 0, 0, &success); - if (!success) { + lldb::user_id_t user_id; + if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) { result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); result.SetStatus(eReturnStatusFailed); @@ -4881,6 +4876,9 @@ CommandObjectMultiwordTarget::CommandObjectMultiwordTarget( CommandObjectSP(new CommandObjectTargetList(interpreter))); LoadSubCommand("select", CommandObjectSP(new CommandObjectTargetSelect(interpreter))); + LoadSubCommand("show-launch-environment", + CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment( + interpreter))); LoadSubCommand( "stop-hook", CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter))); diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectTarget.h b/gnu/llvm/lldb/source/Commands/CommandObjectTarget.h index bf1dae6bfdc..94afc00064c 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectTarget.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectTarget.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectTarget_h_ -#define liblldb_CommandObjectTarget_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTTARGET_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTTARGET_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -24,4 +24,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectTarget_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTTARGET_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectThread.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectThread.cpp index 83c7cb50d14..f0ad1798fec 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectThread.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectThread.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectThread.cpp ---------------------------------*- C++ -*-===// +//===-- CommandObjectThread.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,7 +10,6 @@ #include "lldb/Core/ValueObject.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" @@ -109,11 +108,8 @@ public: process->GetThreadList().GetMutex()); for (size_t i = 0; i < num_args; i++) { - bool success; - - uint32_t thread_idx = StringConvert::ToUInt32( - command.GetArgumentAtIndex(i), 0, 0, &success); - if (!success) { + uint32_t thread_idx; + if (!llvm::to_integer(command.GetArgumentAtIndex(i), thread_idx)) { result.AppendErrorWithFormat("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i)); result.SetStatus(eReturnStatusFailed); @@ -464,12 +460,12 @@ public: case 'r': m_avoid_regexp.clear(); - m_avoid_regexp.assign(option_arg); + m_avoid_regexp.assign(std::string(option_arg)); break; case 't': m_step_in_target.clear(); - m_step_in_target.assign(option_arg); + m_step_in_target.assign(std::string(option_arg)); break; default: @@ -565,9 +561,9 @@ protected: } } else { const char *thread_idx_cstr = command.GetArgumentAtIndex(0); - uint32_t step_thread_idx = - StringConvert::ToUInt32(thread_idx_cstr, LLDB_INVALID_INDEX32); - if (step_thread_idx == LLDB_INVALID_INDEX32) { + uint32_t step_thread_idx; + + if (!llvm::to_integer(thread_idx_cstr, step_thread_idx)) { result.AppendErrorWithFormat("invalid thread index '%s'.\n", thread_idx_cstr); result.SetStatus(eReturnStatusFailed); @@ -775,7 +771,6 @@ protected: return result.Succeeded(); } -protected: StepType m_step_type; StepScope m_step_scope; ThreadStepScopeOptionGroup m_options; @@ -1096,9 +1091,7 @@ protected: size_t num_args = command.GetArgumentCount(); for (size_t i = 0; i < num_args; i++) { uint32_t line_number; - line_number = StringConvert::ToUInt32(command.GetArgumentAtIndex(i), - UINT32_MAX); - if (line_number == UINT32_MAX) { + if (!llvm::to_integer(command.GetArgumentAtIndex(i), line_number)) { result.AppendErrorWithFormat("invalid line number: '%s'.\n", command.GetArgumentAtIndex(i)); result.SetStatus(eReturnStatusFailed); @@ -1322,8 +1315,13 @@ protected: return false; } - uint32_t index_id = - StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0); + uint32_t index_id; + if (!llvm::to_integer(command.GetArgumentAtIndex(0), index_id)) { + result.AppendErrorWithFormat("Invalid thread index '%s'", + command.GetArgumentAtIndex(0)); + result.SetStatus(eReturnStatusFailed); + return false; + } Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get(); @@ -1833,25 +1831,36 @@ public: 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 'i': m_internal = true; break; + case 't': + lldb::tid_t tid; + if (option_arg.getAsInteger(0, tid)) + return Status("invalid tid: '%s'.", option_arg.str().c_str()); + m_tids.push_back(tid); + break; + case 'u': + m_unreported = false; + break; case 'v': m_verbose = true; break; default: llvm_unreachable("Unimplemented option"); } - return error; + return {}; } void OptionParsingStarting(ExecutionContext *execution_context) override { m_verbose = false; m_internal = false; + m_unreported = true; // The variable is "skip unreported" and we want to + // skip unreported by default. + m_tids.clear(); } llvm::ArrayRef GetDefinitions() override { @@ -1861,6 +1870,8 @@ public: // Instance variables to hold the values for command options. bool m_verbose; bool m_internal; + bool m_unreported; + std::vector m_tids; }; CommandObjectThreadPlanList(CommandInterpreter &interpreter) @@ -1879,25 +1890,59 @@ public: Options *GetOptions() override { return &m_options; } + bool DoExecute(Args &command, CommandReturnObject &result) override { + // If we are reporting all threads, dispatch to the Process to do that: + if (command.GetArgumentCount() == 0 && m_options.m_tids.empty()) { + Stream &strm = result.GetOutputStream(); + DescriptionLevel desc_level = m_options.m_verbose + ? eDescriptionLevelVerbose + : eDescriptionLevelFull; + m_exe_ctx.GetProcessPtr()->DumpThreadPlans( + strm, desc_level, m_options.m_internal, true, m_options.m_unreported); + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } else { + // Do any TID's that the user may have specified as TID, then do any + // Thread Indexes... + if (!m_options.m_tids.empty()) { + Process *process = m_exe_ctx.GetProcessPtr(); + StreamString tmp_strm; + for (lldb::tid_t tid : m_options.m_tids) { + bool success = process->DumpThreadPlansForTID( + tmp_strm, tid, eDescriptionLevelFull, m_options.m_internal, + true /* condense_trivial */, m_options.m_unreported); + // If we didn't find a TID, stop here and return an error. + if (!success) { + result.SetError("Error dumping plans:"); + result.AppendError(tmp_strm.GetString()); + result.SetStatus(eReturnStatusFailed); + return false; + } + // Otherwise, add our data to the output: + result.GetOutputStream() << tmp_strm.GetString(); + } + } + return CommandObjectIterateOverThreads::DoExecute(command, result); + } + } + protected: 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; - } + // If we have already handled this from a -t option, skip it here. + if (std::find(m_options.m_tids.begin(), m_options.m_tids.end(), tid) != + m_options.m_tids.end()) + return true; - Thread *thread = thread_sp.get(); + Process *process = m_exe_ctx.GetProcessPtr(); Stream &strm = result.GetOutputStream(); DescriptionLevel desc_level = eDescriptionLevelFull; if (m_options.m_verbose) desc_level = eDescriptionLevelVerbose; - thread->DumpThreadPlans(&strm, desc_level, m_options.m_internal, true); + process->DumpThreadPlansForTID(strm, tid, desc_level, m_options.m_internal, + true /* condense_trivial */, + m_options.m_unreported); return true; } @@ -1943,10 +1988,8 @@ public: return false; } - bool success; - uint32_t thread_plan_idx = - StringConvert::ToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success); - if (!success) { + uint32_t thread_plan_idx; + if (!llvm::to_integer(args.GetArgumentAtIndex(0), thread_plan_idx)) { result.AppendErrorWithFormat( "Invalid thread index: \"%s\" - should be unsigned int.", args.GetArgumentAtIndex(0)); @@ -1974,6 +2017,71 @@ public: } }; +class CommandObjectThreadPlanPrune : public CommandObjectParsed { +public: + CommandObjectThreadPlanPrune(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "thread plan prune", + "Removes any thread plans associated with " + "currently unreported threads. " + "Specify one or more TID's to remove, or if no " + "TID's are provides, remove threads for all " + "unreported threads", + nullptr, + eCommandRequiresProcess | + eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched | + eCommandProcessMustBePaused) { + CommandArgumentEntry arg; + CommandArgumentData tid_arg; + + // Define the first (and only) variant of this arg. + tid_arg.arg_type = eArgTypeThreadID; + tid_arg.arg_repetition = eArgRepeatStar; + + // There is only one variant this argument could be; put it into the + // argument entry. + arg.push_back(tid_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back(arg); + } + + ~CommandObjectThreadPlanPrune() override = default; + + bool DoExecute(Args &args, CommandReturnObject &result) override { + Process *process = m_exe_ctx.GetProcessPtr(); + + if (args.GetArgumentCount() == 0) { + process->PruneThreadPlans(); + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return true; + } + + const size_t num_args = args.GetArgumentCount(); + + std::lock_guard guard( + process->GetThreadList().GetMutex()); + + for (size_t i = 0; i < num_args; i++) { + lldb::tid_t tid; + if (!llvm::to_integer(args.GetArgumentAtIndex(i), tid)) { + result.AppendErrorWithFormat("invalid thread specification: \"%s\"\n", + args.GetArgumentAtIndex(i)); + result.SetStatus(eReturnStatusFailed); + return false; + } + if (!process->PruneThreadPlansForTID(tid)) { + result.AppendErrorWithFormat("Could not find unreported tid: \"%s\"\n", + args.GetArgumentAtIndex(i)); + result.SetStatus(eReturnStatusFailed); + return false; + } + } + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return true; + } +}; + // CommandObjectMultiwordThreadPlan class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword { @@ -1988,6 +2096,9 @@ public: LoadSubCommand( "discard", CommandObjectSP(new CommandObjectThreadPlanDiscard(interpreter))); + LoadSubCommand( + "prune", + CommandObjectSP(new CommandObjectThreadPlanPrune(interpreter))); } ~CommandObjectMultiwordThreadPlan() override = default; diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectThread.h b/gnu/llvm/lldb/source/Commands/CommandObjectThread.h index 77729ceecd6..3ca6a215950 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectThread.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectThread.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectThread_h_ -#define liblldb_CommandObjectThread_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTTHREAD_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTTHREAD_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -22,4 +22,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectThread_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTTHREAD_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectType.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectType.cpp index 87c107cfb94..b2020f26621 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectType.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectType.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectType.cpp -----------------------------------*- C++ -*-===// +//===-- CommandObjectType.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -531,7 +531,7 @@ private: m_skip_pointers = true; break; case 'w': - m_category.assign(option_value); + m_category.assign(std::string(option_value)); break; case 'r': m_skip_references = true; @@ -540,7 +540,7 @@ private: m_regex = true; break; case 't': - m_custom_type_name.assign(option_value); + m_custom_type_name.assign(std::string(option_value)); break; default: llvm_unreachable("Unimplemented option"); @@ -1031,8 +1031,8 @@ protected: std::unique_ptr formatter_regex; if (m_options.m_category_regex.OptionWasSet()) { - category_regex.reset(new RegularExpression( - m_options.m_category_regex.GetCurrentValueAsRef())); + category_regex = std::make_unique( + m_options.m_category_regex.GetCurrentValueAsRef()); if (!category_regex->IsValid()) { result.AppendErrorWithFormat( "syntax error in category regular expression '%s'", @@ -1044,8 +1044,8 @@ protected: if (argc == 1) { const char *arg = command.GetArgumentAtIndex(0); - formatter_regex.reset( - new RegularExpression(llvm::StringRef::withNullAsEmpty(arg))); + formatter_regex = std::make_unique( + llvm::StringRef::withNullAsEmpty(arg)); if (!formatter_regex->IsValid()) { result.AppendErrorWithFormat("syntax error in regular expression '%s'", arg); @@ -1206,11 +1206,11 @@ Status CommandObjectTypeSummaryAdd::CommandOptions::SetOptionValue( m_name.SetString(option_arg); break; case 'o': - m_python_script = option_arg; + m_python_script = std::string(option_arg); m_is_add_script = true; break; case 'F': - m_python_function = option_arg; + m_python_function = std::string(option_arg); m_is_add_script = true; break; case 'P': @@ -1326,7 +1326,7 @@ bool CommandObjectTypeSummaryAdd::Execute_ScriptSummary( return false; } - options->m_target_types << entry.ref(); + options->m_target_types << std::string(entry.ref()); } m_interpreter.GetPythonCommandsFromIOHandler( @@ -2092,7 +2092,8 @@ protected: if (argc == 1) { const char *arg = command.GetArgumentAtIndex(0); - regex.reset(new RegularExpression(llvm::StringRef::withNullAsEmpty(arg))); + regex = std::make_unique( + llvm::StringRef::withNullAsEmpty(arg)); if (!regex->IsValid()) { result.AppendErrorWithFormat( "syntax error in category regular expression '%s'", arg); @@ -2225,7 +2226,7 @@ bool CommandObjectTypeSynthAdd::Execute_HandwritePython( return false; } - options->m_target_types << entry.ref(); + options->m_target_types << std::string(entry.ref()); } m_interpreter.GetPythonCommandsFromIOHandler( @@ -2390,7 +2391,7 @@ private: option_arg.str().c_str()); break; case 'c': - m_expr_paths.push_back(option_arg); + m_expr_paths.push_back(std::string(option_arg)); has_child_list = true; break; case 'p': @@ -2705,7 +2706,7 @@ public: return true; }); - m_cmd_help_long = stream.GetString(); + m_cmd_help_long = std::string(stream.GetString()); return m_cmd_help_long; } diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectType.h b/gnu/llvm/lldb/source/Commands/CommandObjectType.h index 938e481a6b8..1c081abe2be 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectType.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectType.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectType_h_ -#define liblldb_CommandObjectType_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTTYPE_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTTYPE_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -22,4 +22,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectType_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTTYPE_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectVersion.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectVersion.cpp index 227d5d132d9..065cbe4660d 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectVersion.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectVersion.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectVersion.cpp --------------------------------*- C++ -*-===// +//===-- CommandObjectVersion.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectVersion.h b/gnu/llvm/lldb/source/Commands/CommandObjectVersion.h index 30f44aeb165..dce1a8d67b8 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectVersion.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectVersion.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectVersion_h_ -#define liblldb_CommandObjectVersion_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTVERSION_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTVERSION_H #include "lldb/Interpreter/CommandObject.h" @@ -27,4 +27,4 @@ protected: } // namespace lldb_private -#endif // liblldb_CommandObjectVersion_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTVERSION_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectWatchpoint.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectWatchpoint.cpp index c965d354f73..ce4662930a7 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectWatchpoint.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectWatchpoint.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectWatchpoint.cpp -----------------------------*- C++ -*-===// +//===-- CommandObjectWatchpoint.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -41,7 +41,7 @@ static bool CheckTargetForWatchpointOperations(Target *target, bool process_is_valid = target->GetProcessSP() && target->GetProcessSP()->IsAlive(); if (!process_is_valid) { - result.AppendError("Thre's no process or it is not alive."); + result.AppendError("There's no process or it is not alive."); result.SetStatus(eReturnStatusFailed); return false; } @@ -692,7 +692,7 @@ public: switch (short_option) { case 'c': - m_condition = option_arg; + m_condition = std::string(option_arg); m_condition_passed = true; break; default: @@ -934,7 +934,7 @@ protected: StreamString ss; // True to show fullpath for declaration file. var_sp->GetDeclaration().DumpStopContext(&ss, true); - wp->SetDeclInfo(ss.GetString()); + wp->SetDeclInfo(std::string(ss.GetString())); } output_stream.Printf("Watchpoint created: "); wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull); @@ -1038,7 +1038,7 @@ protected: // set a watchpoint. if (raw_command.trim().empty()) { result.GetErrorStream().Printf("error: required argument missing; " - "specify an expression to evaulate into " + "specify an expression to evaluate into " "the address to watch for\n"); result.SetStatus(eReturnStatusFailed); return false; @@ -1070,6 +1070,8 @@ protected: result.GetErrorStream().Printf( "error: expression evaluation of address to watch failed\n"); result.GetErrorStream() << "expression evaluated: \n" << expr << "\n"; + if (valobj_sp && !valobj_sp->GetError().Success()) + result.GetErrorStream() << valobj_sp->GetError().AsCString() << "\n"; result.SetStatus(eReturnStatusFailed); return false; } diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectWatchpoint.h b/gnu/llvm/lldb/source/Commands/CommandObjectWatchpoint.h index 4f4f80bbd62..87f9f4383bd 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectWatchpoint.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectWatchpoint.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectWatchpoint_h_ -#define liblldb_CommandObjectWatchpoint_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTWATCHPOINT_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTWATCHPOINT_H #include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/Interpreter/OptionGroupWatchpoint.h" @@ -28,4 +28,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectWatchpoint_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTWATCHPOINT_H diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectWatchpointCommand.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectWatchpointCommand.cpp index 1b83e885d27..fe3052a775a 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectWatchpointCommand.cpp +++ b/gnu/llvm/lldb/source/Commands/CommandObjectWatchpointCommand.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectWatchpointCommand.cpp ----------------------*- C++ -*-===// +//===-- CommandObjectWatchpointCommand.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -39,7 +39,7 @@ static constexpr OptionEnumValueElement g_script_option_enumeration[] = { { eScriptLanguageLua, "lua", - "Commands are in the Python language.", + "Commands are in the Lua language.", }, { eSortOrderByName, @@ -282,12 +282,12 @@ are no syntax errors may indicate that a function was declared but never called. ExecutionContext exe_ctx(context->exe_ctx_ref); Target *target = exe_ctx.GetTargetPtr(); if (target) { - CommandReturnObject result; Debugger &debugger = target->GetDebugger(); + CommandReturnObject result(debugger.GetUseColor()); + // Rig up the results secondary output stream to the debugger's, so the // output will come out synchronously if the debugger is set up that // way. - StreamSP output_stream(debugger.GetAsyncOutputStream()); StreamSP error_stream(debugger.GetAsyncErrorStream()); result.SetImmediateOutputStream(output_stream); @@ -327,7 +327,7 @@ are no syntax errors may indicate that a function was declared but never called. switch (short_option) { case 'o': m_use_one_liner = true; - m_one_liner = option_arg; + m_one_liner = std::string(option_arg); break; case 's': @@ -359,7 +359,7 @@ are no syntax errors may indicate that a function was declared but never called. case 'F': m_use_one_liner = false; - m_function_name.assign(option_arg); + m_function_name.assign(std::string(option_arg)); break; default: diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectWatchpointCommand.h b/gnu/llvm/lldb/source/Commands/CommandObjectWatchpointCommand.h index 6fbc9c74161..b3cb70d0898 100644 --- a/gnu/llvm/lldb/source/Commands/CommandObjectWatchpointCommand.h +++ b/gnu/llvm/lldb/source/Commands/CommandObjectWatchpointCommand.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectWatchpointCommand_h_ -#define liblldb_CommandObjectWatchpointCommand_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTWATCHPOINTCOMMAND_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTWATCHPOINTCOMMAND_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -24,4 +24,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectWatchpointCommand_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTWATCHPOINTCOMMAND_H diff --git a/gnu/llvm/lldb/source/Commands/Options.td b/gnu/llvm/lldb/source/Commands/Options.td index 850df133a42..d6f1e0a3c96 100644 --- a/gnu/llvm/lldb/source/Commands/Options.td +++ b/gnu/llvm/lldb/source/Commands/Options.td @@ -39,6 +39,11 @@ let Command = "settings read" in { Desc<"The file from which to read the settings.">; } +let Command = "settings clear" in { + def setclear_all : Option<"all", "a">, + Desc<"Clear all settings.">; +} + let Command = "breakpoint list" in { // 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. @@ -115,6 +120,8 @@ let Command = "breakpoint set" in { def breakpoint_set_line : Option<"line", "l">, Group<1>, Arg<"LineNum">, Required, Desc<"Specifies the line number on which to set this breakpoint.">; + def breakpoint_set_column : Option<"column", "u">, Group<1>, Arg<"ColumnNum">, + Desc<"Specifies the column number on which to set this breakpoint.">; def breakpoint_set_address : Option<"address", "a">, Group<2>, Arg<"AddressOrExpression">, Required, Desc<"Set the breakpoint at the specified address. If the address maps " @@ -150,7 +157,7 @@ let Command = "breakpoint set" in { "multiple times tomake one breakpoint for multiple methods.">; def breakpoint_set_func_regex : Option<"func-regex", "r">, Group<7>, Arg<"RegularExpression">, Required, Desc<"Set the breakpoint by function " - "name, evaluating a regular-expression to findthe function name(s).">; + "name, evaluating a regular-expression to find the function name(s).">; def breakpoint_set_basename : Option<"basename", "b">, Group<8>, Arg<"FunctionName">, Required, Completion<"Symbol">, Desc<"Set the breakpoint by function basename (C++ namespaces and arguments" @@ -304,7 +311,7 @@ let Command = "disassemble" in { Desc<"Address at which to start disassembling.">; def disassemble_options_end_address : Option<"end-address", "e">, Group<1>, Arg<"AddressOrExpression">, Desc<"Address at which to end disassembling.">; - def disassemble_options_count : Option<"count", "c">, Groups<[2,3,4,5]>, + def disassemble_options_count : Option<"count", "c">, Groups<[2,3,4,5,7]>, Arg<"NumLines">, Desc<"Number of instructions to display.">; def disassemble_options_name : Option<"name", "n">, Group<3>, Arg<"FunctionName">, Completion<"Symbol">, @@ -319,6 +326,8 @@ let Command = "disassemble" in { def disassemble_options_address : Option<"address", "a">, Group<7>, Arg<"AddressOrExpression">, Desc<"Disassemble function containing this address.">; + def disassemble_options_force : Option<"force", "\\x01">, Groups<[2,3,4,5,7]>, + Desc<"Force dissasembly of large functions.">; } let Command = "expression" in { @@ -382,7 +391,8 @@ let Command = "frame recognizer add" in { "to.">; def frame_recognizer_function : Option<"function", "n">, Arg<"Name">, Completion<"Symbol">, - Desc<"Name of the function that this recognizer applies to.">; + Desc<"Name of the function that this recognizer applies to. " + "Can be specified more than once except if -x|--regex is provided.">; def frame_recognizer_python_class : Option<"python-class", "l">, Group<2>, Arg<"PythonClass">, Desc<"Give the name of a Python class to use for this frame recognizer.">; @@ -614,6 +624,8 @@ let Command = "platform process attach" in { } let Command = "platform shell" in { + def platform_shell_host : Option<"host", "h">, + Desc<"Run the commands on the host shell when enabled.">; def platform_shell_timeout : Option<"timeout", "t">, Arg<"Value">, Desc<"Seconds to wait for the remote host to finish running the command.">; } @@ -668,6 +680,11 @@ let Command = "process handle" in { Desc<"Whether or not the signal should be passed to the process.">; } +let Command = "process status" in { + def process_status_verbose : Option<"verbose", "v">, Group<1>, + Desc<"Show verbose process status including extended crash information.">; +} + let Command = "script import" in { def script_import_allow_reload : Option<"allow-reload", "r">, Group<1>, Desc<"Allow the script to be loaded even if it was already loaded before. " @@ -688,6 +705,7 @@ let Command = "script add" in { Desc<"Set the synchronicity of this command's executions with regard to " "LLDB event system.">; } + let Command = "source info" in { def source_info_count : Option<"count", "c">, Arg<"Count">, Desc<"The number of line entries to display.">; @@ -956,6 +974,11 @@ let Command = "thread plan list" in { Desc<"Display more information about the thread plans">; def thread_plan_list_internal : Option<"internal", "i">, Group<1>, Desc<"Display internal as well as user thread plans">; + def thread_plan_list_thread_id : Option<"thread-id", "t">, Group<1>, + Arg<"ThreadID">, Desc<"List the thread plans for this TID, can be " + "specified more than once.">; + def thread_plan_list_unreported : Option<"unreported", "u">, Group<1>, + Desc<"Display thread plans for unreported threads">; } let Command = "type summary add" in { diff --git a/gnu/llvm/lldb/source/Core/Address.cpp b/gnu/llvm/lldb/source/Core/Address.cpp index b9a7b4a3894..9d52f1db891 100644 --- a/gnu/llvm/lldb/source/Core/Address.cpp +++ b/gnu/llvm/lldb/source/Core/Address.cpp @@ -1,4 +1,4 @@ -//===-- Address.cpp ---------------------------------------------*- C++ -*-===// +//===-- Address.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -415,7 +415,7 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, case DumpStyleSectionNameOffset: if (section_sp) { - section_sp->DumpName(s); + section_sp->DumpName(s->AsRawOstream()); s->Printf(" + %" PRIu64, m_offset); } else { DumpAddress(s->AsRawOstream(), m_offset, addr_size); diff --git a/gnu/llvm/lldb/source/Core/AddressRange.cpp b/gnu/llvm/lldb/source/Core/AddressRange.cpp index 83a1e54157d..0868ac5e088 100644 --- a/gnu/llvm/lldb/source/Core/AddressRange.cpp +++ b/gnu/llvm/lldb/source/Core/AddressRange.cpp @@ -1,4 +1,4 @@ -//===-- AddressRange.cpp ----------------------------------------*- C++ -*-===// +//===-- AddressRange.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Core/AddressResolver.cpp b/gnu/llvm/lldb/source/Core/AddressResolver.cpp index 974d99b6206..16b849b721d 100644 --- a/gnu/llvm/lldb/source/Core/AddressResolver.cpp +++ b/gnu/llvm/lldb/source/Core/AddressResolver.cpp @@ -1,4 +1,4 @@ -//===-- AddressResolver.cpp -------------------------------------*- C++ -*-===// +//===-- AddressResolver.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Core/AddressResolverFileLine.cpp b/gnu/llvm/lldb/source/Core/AddressResolverFileLine.cpp index 4122b5d3b74..b0d8dcdde2d 100644 --- a/gnu/llvm/lldb/source/Core/AddressResolverFileLine.cpp +++ b/gnu/llvm/lldb/source/Core/AddressResolverFileLine.cpp @@ -1,4 +1,4 @@ -//===-- AddressResolverFileLine.cpp -----------------------------*- C++ -*-===// +//===-- AddressResolverFileLine.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Core/AddressResolverName.cpp b/gnu/llvm/lldb/source/Core/AddressResolverName.cpp index 6b9b7b2de72..51ab6435e8f 100644 --- a/gnu/llvm/lldb/source/Core/AddressResolverName.cpp +++ b/gnu/llvm/lldb/source/Core/AddressResolverName.cpp @@ -1,4 +1,4 @@ -//===-- AddressResolverName.cpp ---------------------------------*- C++ -*-===// +//===-- AddressResolverName.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -91,7 +91,7 @@ AddressResolverName::SearchCallback(SearchFilter &filter, if (context.module_sp) { context.module_sp->FindSymbolsWithNameAndType(m_func_name, eSymbolTypeCode, sym_list); - context.module_sp->FindFunctions(m_func_name, nullptr, + context.module_sp->FindFunctions(m_func_name, CompilerDeclContext(), eFunctionNameTypeAuto, include_symbols, include_inlines, func_list); } diff --git a/gnu/llvm/lldb/source/Core/CMakeLists.txt b/gnu/llvm/lldb/source/Core/CMakeLists.txt index a03fe6f4800..a4057d11077 100644 --- a/gnu/llvm/lldb/source/Core/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Core/CMakeLists.txt @@ -96,7 +96,7 @@ add_dependencies(lldbCore # Needed to properly resolve references in a debug build. # TODO: Remove once we have better layering -set_target_properties(lldbCore PROPERTIES LINK_INTERFACE_MULTIPLICITY 4) +set_target_properties(lldbCore PROPERTIES LINK_INTERFACE_MULTIPLICITY 5) if (LLDB_ENABLE_LIBEDIT) target_include_directories(lldbCore PRIVATE ${LibEdit_INCLUDE_DIRS}) diff --git a/gnu/llvm/lldb/source/Core/Communication.cpp b/gnu/llvm/lldb/source/Core/Communication.cpp index 0afd897a209..b358e70b1a9 100644 --- a/gnu/llvm/lldb/source/Core/Communication.cpp +++ b/gnu/llvm/lldb/source/Core/Communication.cpp @@ -1,4 +1,4 @@ -//===-- Communication.cpp ---------------------------------------*- C++ -*-===// +//===-- Communication.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -71,8 +71,8 @@ Communication::~Communication() { void Communication::Clear() { SetReadThreadBytesReceivedCallback(nullptr, nullptr); - Disconnect(nullptr); StopReadThread(nullptr); + Disconnect(nullptr); } ConnectionStatus Communication::Connect(const char *url, Status *error_ptr) { @@ -93,6 +93,8 @@ ConnectionStatus Communication::Disconnect(Status *error_ptr) { LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION), "{0} Communication::Disconnect ()", this); + assert((!m_read_thread_enabled || m_read_thread_did_exit) && + "Disconnecting while the read thread is running is racy!"); lldb::ConnectionSP connection_sp(m_connection_sp); if (connection_sp) { ConnectionStatus status = connection_sp->Disconnect(error_ptr); @@ -315,16 +317,12 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) { Status error; ConnectionStatus status = eConnectionStatusSuccess; bool done = false; + bool disconnect = false; while (!done && comm->m_read_thread_enabled) { size_t bytes_read = comm->ReadFromConnection( buf, sizeof(buf), std::chrono::seconds(5), status, &error); - if (bytes_read > 0) + if (bytes_read > 0 || status == eConnectionStatusEndOfFile) comm->AppendBytesToCache(buf, bytes_read, true, status); - else if ((bytes_read == 0) && status == eConnectionStatusEndOfFile) { - if (comm->GetCloseOnEOF()) - comm->Disconnect(); - comm->AppendBytesToCache(buf, bytes_read, true, status); - } switch (status) { case eConnectionStatusSuccess: @@ -332,11 +330,12 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) { case eConnectionStatusEndOfFile: done = true; + disconnect = comm->GetCloseOnEOF(); break; case eConnectionStatusError: // Check GetError() for details if (error.GetType() == eErrorTypePOSIX && error.GetError() == EIO) { // EIO on a pipe is usually caused by remote shutdown - comm->Disconnect(); + disconnect = comm->GetCloseOnEOF(); done = true; } if (error.Fail()) @@ -365,9 +364,22 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) { if (log) LLDB_LOGF(log, "%p Communication::ReadThread () thread exiting...", p); - comm->m_read_thread_did_exit = true; + // Handle threads wishing to synchronize with us. + { + // Prevent new ones from showing up. + comm->m_read_thread_did_exit = true; + + // Unblock any existing thread waiting for the synchronization signal. + comm->BroadcastEvent(eBroadcastBitNoMorePendingInput); + + // Wait for the thread to finish... + std::lock_guard guard(comm->m_synchronize_mutex); + // ... and disconnect. + if (disconnect) + comm->Disconnect(); + } + // Let clients know that this thread is exiting - comm->BroadcastEvent(eBroadcastBitNoMorePendingInput); comm->BroadcastEvent(eBroadcastBitReadThreadDidExit); return {}; } @@ -399,10 +411,10 @@ void Communication::SynchronizeWithReadThread() { listener_sp->GetEvent(event_sp, llvm::None); } -void Communication::SetConnection(Connection *connection) { +void Communication::SetConnection(std::unique_ptr connection) { Disconnect(nullptr); StopReadThread(nullptr); - m_connection_sp.reset(connection); + m_connection_sp = std::move(connection); } const char * diff --git a/gnu/llvm/lldb/source/Core/CoreProperties.td b/gnu/llvm/lldb/source/Core/CoreProperties.td index 014927c65c6..b04738175f3 100644 --- a/gnu/llvm/lldb/source/Core/CoreProperties.td +++ b/gnu/llvm/lldb/source/Core/CoreProperties.td @@ -9,6 +9,10 @@ let Definition = "modulelist" in { Global, DefaultStringValue<"">, Desc<"The path to the clang modules cache directory (-fmodules-cache-path).">; + def SymLinkPaths: Property<"debug-info-symlink-paths", "FileSpecList">, + Global, + DefaultStringValue<"">, + Desc<"Debug info path which should be resolved while parsing, relative to the host filesystem.">; } let Definition = "debugger" in { @@ -18,7 +22,7 @@ let Definition = "debugger" in { Desc<"If true all confirmation prompts will receive their default reply.">; def DisassemblyFormat: Property<"disassembly-format", "FormatEntity">, Global, - DefaultStringValue<"{${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\\\\n}{${function.changed}\\\\n{${module.file.basename}`}{${function.name-without-args}}:\\\\n}{${current-pc-arrow} }${addr-file-or-load}{ <${function.concrete-only-addr-offset-no-padding}>}: ">, + DefaultStringValue<"{${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\\\\n}{${function.changed}\\\\n{${module.file.basename}`}{${function.name-without-args}}:\\\\n}{${ansi.fg.yellow}${current-pc-arrow}${ansi.normal} }${addr-file-or-load}{ <${function.concrete-only-addr-offset-no-padding}>}: ">, Desc<"The default disassembly format string to use when disassembling instruction sequences.">; def FrameFormat: Property<"frame-format", "FormatEntity">, Global, @@ -71,6 +75,14 @@ let Definition = "debugger" in { Global, DefaultStringValue<"${ansi.normal}">, Desc<"When displaying the column marker in a color-enabled (i.e. ANSI) terminal, use the ANSI terminal code specified in this format immediately after the column to be marked.">; + def StopShowLineMarkerAnsiPrefix: Property<"stop-show-line-ansi-prefix", "String">, + Global, + DefaultStringValue<"${ansi.fg.yellow}">, + Desc<"When displaying the line marker in a color-enabled (i.e. ANSI) terminal, use the ANSI terminal code specified in this format at the immediately before the line to be marked.">; + def StopShowLineMarkerAnsiSuffix: Property<"stop-show-line-ansi-suffix", "String">, + Global, + DefaultStringValue<"${ansi.normal}">, + Desc<"When displaying the line marker in a color-enabled (i.e. ANSI) terminal, use the ANSI terminal code specified in this format immediately after the line to be marked.">; def TerminalWidth: Property<"term-width", "SInt64">, Global, DefaultUnsignedValue<80>, @@ -91,6 +103,10 @@ let Definition = "debugger" in { Global, DefaultTrue, Desc<"Whether to use Ansi color codes or not.">; + def UseSourceCache: Property<"use-source-cache", "Boolean">, + Global, + DefaultTrue, + Desc<"Whether to cache source files in memory or not.">; def AutoOneLineSummaries: Property<"auto-one-line-summaries", "Boolean">, Global, DefaultTrue, diff --git a/gnu/llvm/lldb/source/Core/Debugger.cpp b/gnu/llvm/lldb/source/Core/Debugger.cpp index 33f72a0896c..5f4f1e266d8 100644 --- a/gnu/llvm/lldb/source/Core/Debugger.cpp +++ b/gnu/llvm/lldb/source/Core/Debugger.cpp @@ -1,4 +1,4 @@ -//===-- Debugger.cpp --------------------------------------------*- C++ -*-===// +//===-- Debugger.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -135,84 +135,6 @@ static constexpr OptionEnumValueElement g_language_enumerators[] = { }, }; -#define MODULE_WITH_FUNC \ - "{ " \ - "${module.file.basename}{`${function.name-with-args}" \ - "{${frame.no-debug}${function.pc-offset}}}}" - -#define MODULE_WITH_FUNC_NO_ARGS \ - "{ " \ - "${module.file.basename}{`${function.name-without-args}" \ - "{${frame.no-debug}${function.pc-offset}}}}" - -#define FILE_AND_LINE \ - "{ at ${ansi.fg.cyan}${line.file.basename}${ansi.normal}" \ - ":${ansi.fg.yellow}${line.number}${ansi.normal}" \ - "{:${ansi.fg.yellow}${line.column}${ansi.normal}}}" - -#define IS_OPTIMIZED "{${function.is-optimized} [opt]}" - -#define IS_ARTIFICIAL "{${frame.is-artificial} [artificial]}" - -#define DEFAULT_THREAD_FORMAT \ - "thread #${thread.index}: tid = ${thread.id%tid}" \ - "{, ${frame.pc}}" MODULE_WITH_FUNC FILE_AND_LINE \ - "{, name = ${ansi.fg.green}'${thread.name}'${ansi.normal}}" \ - "{, queue = ${ansi.fg.green}'${thread.queue}'${ansi.normal}}" \ - "{, activity = " \ - "${ansi.fg.green}'${thread.info.activity.name}'${ansi.normal}}" \ - "{, ${thread.info.trace_messages} messages}" \ - "{, stop reason = ${ansi.fg.red}${thread.stop-reason}${ansi.normal}}" \ - "{\\nReturn value: ${thread.return-value}}" \ - "{\\nCompleted expression: ${thread.completed-expression}}" \ - "\\n" - -#define DEFAULT_THREAD_STOP_FORMAT \ - "thread #${thread.index}{, name = '${thread.name}'}" \ - "{, queue = ${ansi.fg.green}'${thread.queue}'${ansi.normal}}" \ - "{, activity = " \ - "${ansi.fg.green}'${thread.info.activity.name}'${ansi.normal}}" \ - "{, ${thread.info.trace_messages} messages}" \ - "{, stop reason = ${ansi.fg.red}${thread.stop-reason}${ansi.normal}}" \ - "{\\nReturn value: ${thread.return-value}}" \ - "{\\nCompleted expression: ${thread.completed-expression}}" \ - "\\n" - -#define DEFAULT_FRAME_FORMAT \ - "frame #${frame.index}: " \ - "${ansi.fg.yellow}${frame.pc}${ansi.normal}" MODULE_WITH_FUNC FILE_AND_LINE \ - IS_OPTIMIZED IS_ARTIFICIAL "\\n" - -#define DEFAULT_FRAME_FORMAT_NO_ARGS \ - "frame #${frame.index}: " \ - "${ansi.fg.yellow}${frame.pc}${ansi.normal}" MODULE_WITH_FUNC_NO_ARGS \ - FILE_AND_LINE IS_OPTIMIZED IS_ARTIFICIAL "\\n" - -// Three parts to this disassembly format specification: -// 1. If this is a new function/symbol (no previous symbol/function), print -// dylib`funcname:\n -// 2. If this is a symbol context change (different from previous -// symbol/function), print -// dylib`funcname:\n -// 3. print -// address <+offset>: -#define DEFAULT_DISASSEMBLY_FORMAT \ - "{${function.initial-function}{${module.file.basename}`}{${function.name-" \ - "without-args}}:\\n}{${function.changed}\\n{${module.file.basename}`}{${" \ - "function.name-without-args}}:\\n}{${current-pc-arrow} " \ - "}${addr-file-or-load}{ " \ - "<${function.concrete-only-addr-offset-no-padding}>}: " - -// gdb's disassembly format can be emulated with ${current-pc-arrow}${addr- -// file-or-load}{ <${function.name-without-args}${function.concrete-only-addr- -// offset-no-padding}>}: - -// lldb's original format for disassembly would look like this format string - -// {${function.initial-function}{${module.file.basename}`}{${function.name- -// without- -// args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name- -// without-args}}:\n}{${current-pc-arrow} }{${addr-file-or-load}}: - static constexpr OptionEnumValueElement s_stop_show_column_values[] = { { eStopShowColumnAnsiOrCaret, @@ -290,6 +212,11 @@ Status Debugger::SetPropertyValue(const ExecutionContext *exe_ctx, // use-color changed. Ping the prompt so it can reset the ansi terminal // codes. SetPrompt(GetPrompt()); + } else if (property_path == g_debugger_properties[ePropertyUseSourceCache].name) { + // use-source-cache changed. Wipe out the cache contents if it was disabled. + if (!GetUseSourceCache()) { + m_source_file_cache.Clear(); + } } else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn) { if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == @@ -388,6 +315,9 @@ uint32_t Debugger::GetTerminalWidth() const { } bool Debugger::SetTerminalWidth(uint32_t term_width) { + if (auto handler_sp = m_io_handler_stack.Top()) + handler_sp->TerminalSizeChanged(); + const uint32_t idx = ePropertyTerminalWidth; return m_collection_sp->SetPropertyAtIndexAsSInt64(nullptr, idx, term_width); } @@ -416,6 +346,20 @@ bool Debugger::SetUseColor(bool b) { return ret; } +bool Debugger::GetUseSourceCache() const { + const uint32_t idx = ePropertyUseSourceCache; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_debugger_properties[idx].default_uint_value != 0); +} + +bool Debugger::SetUseSourceCache(bool b) { + const uint32_t idx = ePropertyUseSourceCache; + bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); + if (!ret) { + m_source_file_cache.Clear(); + } + return ret; +} bool Debugger::GetHighlightSource() const { const uint32_t idx = ePropertyHighlightSource; return m_collection_sp->GetPropertyAtIndexAsBoolean( @@ -438,6 +382,16 @@ llvm::StringRef Debugger::GetStopShowColumnAnsiSuffix() const { return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); } +llvm::StringRef Debugger::GetStopShowLineMarkerAnsiPrefix() const { + const uint32_t idx = ePropertyStopShowLineMarkerAnsiPrefix; + return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); +} + +llvm::StringRef Debugger::GetStopShowLineMarkerAnsiSuffix() const { + const uint32_t idx = ePropertyStopShowLineMarkerAnsiSuffix; + return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); +} + uint32_t Debugger::GetStopSourceLineCount(bool before) const { const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter; @@ -708,7 +662,7 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) m_source_manager_up(), m_source_file_cache(), m_command_interpreter_up( std::make_unique(*this, false)), - m_input_reader_stack(), m_instance_name(), m_loaded_plugins(), + m_io_handler_stack(), m_instance_name(), m_loaded_plugins(), m_event_handler_thread(), m_io_handler_thread(), m_sync_broadcaster(nullptr, "lldb.debugger.sync"), m_forward_listener_sp(), m_clear_once() { @@ -870,15 +824,15 @@ ExecutionContext Debugger::GetSelectedExecutionContext() { } void Debugger::DispatchInputInterrupt() { - std::lock_guard guard(m_input_reader_stack.GetMutex()); - IOHandlerSP reader_sp(m_input_reader_stack.Top()); + std::lock_guard guard(m_io_handler_stack.GetMutex()); + IOHandlerSP reader_sp(m_io_handler_stack.Top()); if (reader_sp) reader_sp->Interrupt(); } void Debugger::DispatchInputEndOfFile() { - std::lock_guard guard(m_input_reader_stack.GetMutex()); - IOHandlerSP reader_sp(m_input_reader_stack.Top()); + std::lock_guard guard(m_io_handler_stack.GetMutex()); + IOHandlerSP reader_sp(m_io_handler_stack.Top()); if (reader_sp) reader_sp->GotEOF(); } @@ -886,81 +840,107 @@ void Debugger::DispatchInputEndOfFile() { void Debugger::ClearIOHandlers() { // The bottom input reader should be the main debugger input reader. We do // not want to close that one here. - std::lock_guard guard(m_input_reader_stack.GetMutex()); - while (m_input_reader_stack.GetSize() > 1) { - IOHandlerSP reader_sp(m_input_reader_stack.Top()); + std::lock_guard guard(m_io_handler_stack.GetMutex()); + while (m_io_handler_stack.GetSize() > 1) { + IOHandlerSP reader_sp(m_io_handler_stack.Top()); if (reader_sp) PopIOHandler(reader_sp); } } -void Debugger::ExecuteIOHandlers() { +void Debugger::RunIOHandlers() { + IOHandlerSP reader_sp = m_io_handler_stack.Top(); while (true) { - IOHandlerSP reader_sp(m_input_reader_stack.Top()); if (!reader_sp) break; reader_sp->Run(); + { + std::lock_guard guard( + m_io_handler_synchronous_mutex); + + // Remove all input readers that are done from the top of the stack + while (true) { + IOHandlerSP top_reader_sp = m_io_handler_stack.Top(); + if (top_reader_sp && top_reader_sp->GetIsDone()) + PopIOHandler(top_reader_sp); + else + break; + } + reader_sp = m_io_handler_stack.Top(); + } + } + ClearIOHandlers(); +} + +void Debugger::RunIOHandlerSync(const IOHandlerSP &reader_sp) { + std::lock_guard guard(m_io_handler_synchronous_mutex); + + PushIOHandler(reader_sp); + IOHandlerSP top_reader_sp = reader_sp; + + while (top_reader_sp) { + if (!top_reader_sp) + break; - // Remove all input readers that are done from the top of the stack + top_reader_sp->Run(); + + // Don't unwind past the starting point. + if (top_reader_sp.get() == reader_sp.get()) { + if (PopIOHandler(reader_sp)) + break; + } + + // If we pushed new IO handlers, pop them if they're done or restart the + // loop to run them if they're not. while (true) { - IOHandlerSP top_reader_sp = m_input_reader_stack.Top(); - if (top_reader_sp && top_reader_sp->GetIsDone()) + top_reader_sp = m_io_handler_stack.Top(); + if (top_reader_sp && top_reader_sp->GetIsDone()) { PopIOHandler(top_reader_sp); - else + // Don't unwind past the starting point. + if (top_reader_sp.get() == reader_sp.get()) + return; + } else { break; + } } } - ClearIOHandlers(); } bool Debugger::IsTopIOHandler(const lldb::IOHandlerSP &reader_sp) { - return m_input_reader_stack.IsTop(reader_sp); + return m_io_handler_stack.IsTop(reader_sp); } bool Debugger::CheckTopIOHandlerTypes(IOHandler::Type top_type, IOHandler::Type second_top_type) { - return m_input_reader_stack.CheckTopIOHandlerTypes(top_type, second_top_type); + return m_io_handler_stack.CheckTopIOHandlerTypes(top_type, second_top_type); } void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) { lldb_private::StreamFile &stream = is_stdout ? GetOutputStream() : GetErrorStream(); - m_input_reader_stack.PrintAsync(&stream, s, len); + m_io_handler_stack.PrintAsync(&stream, s, len); } ConstString Debugger::GetTopIOHandlerControlSequence(char ch) { - return m_input_reader_stack.GetTopIOHandlerControlSequence(ch); + return m_io_handler_stack.GetTopIOHandlerControlSequence(ch); } const char *Debugger::GetIOHandlerCommandPrefix() { - return m_input_reader_stack.GetTopIOHandlerCommandPrefix(); + return m_io_handler_stack.GetTopIOHandlerCommandPrefix(); } const char *Debugger::GetIOHandlerHelpPrologue() { - return m_input_reader_stack.GetTopIOHandlerHelpPrologue(); + return m_io_handler_stack.GetTopIOHandlerHelpPrologue(); } -void Debugger::RunIOHandler(const IOHandlerSP &reader_sp) { - PushIOHandler(reader_sp); - - IOHandlerSP top_reader_sp = reader_sp; - while (top_reader_sp) { - top_reader_sp->Run(); - - if (top_reader_sp.get() == reader_sp.get()) { - if (PopIOHandler(reader_sp)) - break; - } +bool Debugger::RemoveIOHandler(const IOHandlerSP &reader_sp) { + return PopIOHandler(reader_sp); +} - while (true) { - top_reader_sp = m_input_reader_stack.Top(); - if (top_reader_sp && top_reader_sp->GetIsDone()) - PopIOHandler(top_reader_sp); - else - break; - } - } +void Debugger::RunIOHandlerAsync(const IOHandlerSP &reader_sp, + bool cancel_top_handler) { + PushIOHandler(reader_sp, cancel_top_handler); } void Debugger::AdoptTopIOHandlerFilesIfInvalid(FileSP &in, StreamFileSP &out, @@ -970,8 +950,8 @@ void Debugger::AdoptTopIOHandlerFilesIfInvalid(FileSP &in, StreamFileSP &out, // input reader's in/out/err streams, or fall back to the debugger file // handles, or we fall back onto stdin/stdout/stderr as a last resort. - std::lock_guard guard(m_input_reader_stack.GetMutex()); - IOHandlerSP top_reader_sp(m_input_reader_stack.Top()); + std::lock_guard guard(m_io_handler_stack.GetMutex()); + IOHandlerSP top_reader_sp(m_io_handler_stack.Top()); // If no STDIN has been set, then set it appropriately if (!in || !in->IsValid()) { if (top_reader_sp) @@ -1009,17 +989,17 @@ void Debugger::PushIOHandler(const IOHandlerSP &reader_sp, if (!reader_sp) return; - std::lock_guard guard(m_input_reader_stack.GetMutex()); + std::lock_guard guard(m_io_handler_stack.GetMutex()); // Get the current top input reader... - IOHandlerSP top_reader_sp(m_input_reader_stack.Top()); + IOHandlerSP top_reader_sp(m_io_handler_stack.Top()); // Don't push the same IO handler twice... if (reader_sp == top_reader_sp) return; // Push our new input reader - m_input_reader_stack.Push(reader_sp); + m_io_handler_stack.Push(reader_sp); reader_sp->Activate(); // Interrupt the top input reader to it will exit its Run() function and let @@ -1035,23 +1015,23 @@ bool Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) { if (!pop_reader_sp) return false; - std::lock_guard guard(m_input_reader_stack.GetMutex()); + std::lock_guard guard(m_io_handler_stack.GetMutex()); // The reader on the stop of the stack is done, so let the next read on the // stack refresh its prompt and if there is one... - if (m_input_reader_stack.IsEmpty()) + if (m_io_handler_stack.IsEmpty()) return false; - IOHandlerSP reader_sp(m_input_reader_stack.Top()); + IOHandlerSP reader_sp(m_io_handler_stack.Top()); if (pop_reader_sp != reader_sp) return false; reader_sp->Deactivate(); reader_sp->Cancel(); - m_input_reader_stack.Pop(); + m_io_handler_stack.Pop(); - reader_sp = m_input_reader_stack.Top(); + reader_sp = m_io_handler_stack.Top(); if (reader_sp) reader_sp->Activate(); @@ -1174,17 +1154,22 @@ bool Debugger::EnableLog(llvm::StringRef channel, if (pos != m_log_streams.end()) log_stream_sp = pos->second.lock(); if (!log_stream_sp) { - llvm::sys::fs::OpenFlags flags = llvm::sys::fs::OF_Text; + File::OpenOptions flags = + File::eOpenOptionWrite | File::eOpenOptionCanCreate; if (log_options & LLDB_LOG_OPTION_APPEND) - flags |= llvm::sys::fs::OF_Append; - int FD; - if (std::error_code ec = llvm::sys::fs::openFileForWrite( - log_file, FD, llvm::sys::fs::CD_CreateAlways, flags)) { - error_stream << "Unable to open log file: " << ec.message(); + flags |= File::eOpenOptionAppend; + else + flags |= File::eOpenOptionTruncate; + auto file = FileSystem::Instance().Open( + FileSpec(log_file), flags, lldb::eFilePermissionsFileDefault, false); + if (!file) { + // FIXME: This gets garbled when called from the log command. + error_stream << "Unable to open log file: " << log_file; return false; } - log_stream_sp = - std::make_shared(FD, should_close, unbuffered); + + log_stream_sp = std::make_shared( + (*file)->GetDescriptor(), should_close, unbuffered); m_log_streams[log_file] = log_stream_sp; } } @@ -1503,9 +1488,9 @@ bool Debugger::StartEventHandlerThread() { listener_sp->StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening); - auto thread_name = + llvm::StringRef thread_name = full_name.GetLength() < llvm::get_max_thread_name_length() - ? full_name.AsCString() + ? full_name.GetStringRef() : "dbg.evt-handler"; // Use larger 8MB stack for this thread @@ -1542,7 +1527,7 @@ void Debugger::StopEventHandlerThread() { lldb::thread_result_t Debugger::IOHandlerThread(lldb::thread_arg_t arg) { Debugger *debugger = (Debugger *)arg; - debugger->ExecuteIOHandlers(); + debugger->RunIOHandlers(); debugger->StopEventHandlerThread(); return {}; } diff --git a/gnu/llvm/lldb/source/Core/Disassembler.cpp b/gnu/llvm/lldb/source/Core/Disassembler.cpp index 33172cc8868..4da823c7a24 100644 --- a/gnu/llvm/lldb/source/Core/Disassembler.cpp +++ b/gnu/llvm/lldb/source/Core/Disassembler.cpp @@ -1,4 +1,4 @@ -//===-- Disassembler.cpp ----------------------------------------*- C++ -*-===// +//===-- Disassembler.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -89,124 +89,57 @@ DisassemblerSP Disassembler::FindPlugin(const ArchSpec &arch, return DisassemblerSP(); } -DisassemblerSP Disassembler::FindPluginForTarget(const TargetSP target_sp, +DisassemblerSP Disassembler::FindPluginForTarget(const Target &target, const ArchSpec &arch, const char *flavor, const char *plugin_name) { - if (target_sp && flavor == nullptr) { + if (flavor == nullptr) { // FIXME - we don't have the mechanism in place to do per-architecture // settings. But since we know that for now we only support flavors on x86 // & x86_64, if (arch.GetTriple().getArch() == llvm::Triple::x86 || arch.GetTriple().getArch() == llvm::Triple::x86_64) - flavor = target_sp->GetDisassemblyFlavor(); + flavor = target.GetDisassemblyFlavor(); } return FindPlugin(arch, flavor, plugin_name); } -static void ResolveAddress(const ExecutionContext &exe_ctx, const Address &addr, - Address &resolved_addr) { +static Address ResolveAddress(Target &target, const Address &addr) { if (!addr.IsSectionOffset()) { + Address resolved_addr; // If we weren't passed in a section offset address range, try and resolve // it to something - Target *target = exe_ctx.GetTargetPtr(); - if (target) { - bool is_resolved = - target->GetSectionLoadList().IsEmpty() ? - target->GetImages().ResolveFileAddress(addr.GetOffset(), - resolved_addr) : - target->GetSectionLoadList().ResolveLoadAddress(addr.GetOffset(), - resolved_addr); - - // We weren't able to resolve the address, just treat it as a raw address - if (is_resolved && resolved_addr.IsValid()) - return; - } - } - resolved_addr = addr; -} - -size_t Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, - const char *plugin_name, const char *flavor, - const ExecutionContext &exe_ctx, - SymbolContextList &sc_list, - uint32_t num_instructions, - bool mixed_source_and_assembly, - uint32_t num_mixed_context_lines, - uint32_t options, Stream &strm) { - size_t success_count = 0; - const size_t count = sc_list.GetSize(); - SymbolContext sc; - AddressRange range; - const uint32_t scope = - eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol; - const bool use_inline_block_range = true; - for (size_t i = 0; i < count; ++i) { - if (!sc_list.GetContextAtIndex(i, sc)) - break; - for (uint32_t range_idx = 0; - sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); - ++range_idx) { - if (Disassemble(debugger, arch, plugin_name, flavor, exe_ctx, range, - num_instructions, mixed_source_and_assembly, - num_mixed_context_lines, options, strm)) { - ++success_count; - strm.EOL(); - } - } - } - return success_count; -} - -bool Disassembler::Disassemble( - Debugger &debugger, const ArchSpec &arch, const char *plugin_name, - const char *flavor, const ExecutionContext &exe_ctx, ConstString name, - Module *module, uint32_t num_instructions, bool mixed_source_and_assembly, - uint32_t num_mixed_context_lines, uint32_t options, Stream &strm) { - // If no name is given there's nothing to disassemble. - if (!name) - return false; - - const bool include_symbols = true; - const bool include_inlines = true; - - // Find functions matching the given name. - SymbolContextList sc_list; - if (module) { - module->FindFunctions(name, nullptr, eFunctionNameTypeAuto, include_symbols, - include_inlines, sc_list); - } else if (exe_ctx.GetTargetPtr()) { - exe_ctx.GetTargetPtr()->GetImages().FindFunctions( - name, eFunctionNameTypeAuto, include_symbols, include_inlines, sc_list); + bool is_resolved = target.GetSectionLoadList().IsEmpty() + ? target.GetImages().ResolveFileAddress( + addr.GetOffset(), resolved_addr) + : target.GetSectionLoadList().ResolveLoadAddress( + addr.GetOffset(), resolved_addr); + + // We weren't able to resolve the address, just treat it as a raw address + if (is_resolved && resolved_addr.IsValid()) + return resolved_addr; } - - // If no functions were found there's nothing to disassemble. - if (sc_list.IsEmpty()) - return false; - - return Disassemble(debugger, arch, plugin_name, flavor, exe_ctx, sc_list, - num_instructions, mixed_source_and_assembly, - num_mixed_context_lines, options, strm); + return addr; } lldb::DisassemblerSP Disassembler::DisassembleRange( const ArchSpec &arch, const char *plugin_name, const char *flavor, - const ExecutionContext &exe_ctx, const AddressRange &range, - bool prefer_file_cache) { + Target &target, const AddressRange &range, bool prefer_file_cache) { if (range.GetByteSize() <= 0) return {}; if (!range.GetBaseAddress().IsValid()) return {}; - lldb::DisassemblerSP disasm_sp = Disassembler::FindPluginForTarget( - exe_ctx.GetTargetSP(), arch, flavor, plugin_name); + lldb::DisassemblerSP disasm_sp = + Disassembler::FindPluginForTarget(target, arch, flavor, plugin_name); if (!disasm_sp) return {}; - const size_t bytes_disassembled = - disasm_sp->ParseInstructions(&exe_ctx, range, nullptr, prefer_file_cache); + const size_t bytes_disassembled = disasm_sp->ParseInstructions( + target, range.GetBaseAddress(), {Limit::Bytes, range.GetByteSize()}, + nullptr, prefer_file_cache); if (bytes_disassembled == 0) return {}; @@ -238,63 +171,28 @@ Disassembler::DisassembleBytes(const ArchSpec &arch, const char *plugin_name, bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name, const char *flavor, const ExecutionContext &exe_ctx, - const AddressRange &disasm_range, - uint32_t num_instructions, + const Address &address, Limit limit, bool mixed_source_and_assembly, uint32_t num_mixed_context_lines, uint32_t options, Stream &strm) { - if (!disasm_range.GetByteSize()) + if (!exe_ctx.GetTargetPtr()) return false; lldb::DisassemblerSP disasm_sp(Disassembler::FindPluginForTarget( - exe_ctx.GetTargetSP(), arch, flavor, plugin_name)); - + exe_ctx.GetTargetRef(), arch, flavor, plugin_name)); if (!disasm_sp) return false; - AddressRange range; - ResolveAddress(exe_ctx, disasm_range.GetBaseAddress(), - range.GetBaseAddress()); - range.SetByteSize(disasm_range.GetByteSize()); - const bool prefer_file_cache = false; - size_t bytes_disassembled = - disasm_sp->ParseInstructions(&exe_ctx, range, &strm, prefer_file_cache); - if (bytes_disassembled == 0) - return false; - - return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx, - num_instructions, mixed_source_and_assembly, - num_mixed_context_lines, options, strm); -} - -bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, - const char *plugin_name, const char *flavor, - const ExecutionContext &exe_ctx, - const Address &start_address, - uint32_t num_instructions, - bool mixed_source_and_assembly, - uint32_t num_mixed_context_lines, - uint32_t options, Stream &strm) { - if (num_instructions == 0) - return false; - - lldb::DisassemblerSP disasm_sp(Disassembler::FindPluginForTarget( - exe_ctx.GetTargetSP(), arch, flavor, plugin_name)); - if (!disasm_sp) - return false; - - Address addr; - ResolveAddress(exe_ctx, start_address, addr); - const bool prefer_file_cache = false; size_t bytes_disassembled = disasm_sp->ParseInstructions( - &exe_ctx, addr, num_instructions, prefer_file_cache); + exe_ctx.GetTargetRef(), address, limit, &strm, prefer_file_cache); if (bytes_disassembled == 0) return false; - return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx, - num_instructions, mixed_source_and_assembly, - num_mixed_context_lines, options, strm); + disasm_sp->PrintInstructions(debugger, arch, exe_ctx, + mixed_source_and_assembly, + num_mixed_context_lines, options, strm); + return true; } Disassembler::SourceLine @@ -380,21 +278,16 @@ bool Disassembler::ElideMixedSourceAndDisassemblyLine( return false; } -bool Disassembler::PrintInstructions(Disassembler *disasm_ptr, - Debugger &debugger, const ArchSpec &arch, +void Disassembler::PrintInstructions(Debugger &debugger, const ArchSpec &arch, const ExecutionContext &exe_ctx, - uint32_t num_instructions, bool mixed_source_and_assembly, uint32_t num_mixed_context_lines, uint32_t options, Stream &strm) { // We got some things disassembled... - size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize(); - - if (num_instructions > 0 && num_instructions < num_instructions_found) - num_instructions_found = num_instructions; + size_t num_instructions_found = GetInstructionList().GetSize(); const uint32_t max_opcode_byte_size = - disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize(); + GetInstructionList().GetMaxOpcocdeByteSize(); SymbolContext sc; SymbolContext prev_sc; AddressRange current_source_line_range; @@ -435,8 +328,7 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr, size_t address_text_size = 0; for (size_t i = 0; i < num_instructions_found; ++i) { - Instruction *inst = - disasm_ptr->GetInstructionList().GetInstructionAtIndex(i).get(); + Instruction *inst = GetInstructionList().GetInstructionAtIndex(i).get(); if (inst) { const Address &addr = inst->GetAddress(); ModuleSP module_sp(addr.GetModule()); @@ -485,8 +377,7 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr, previous_symbol = nullptr; SourceLine previous_line; for (size_t i = 0; i < num_instructions_found; ++i) { - Instruction *inst = - disasm_ptr->GetInstructionList().GetInstructionAtIndex(i).get(); + Instruction *inst = GetInstructionList().GetInstructionAtIndex(i).get(); if (inst) { const Address &addr = inst->GetAddress(); @@ -646,8 +537,6 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr, break; } } - - return true; } bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, @@ -675,9 +564,10 @@ bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE); } - return Disassemble(debugger, arch, plugin_name, flavor, exe_ctx, range, - num_instructions, mixed_source_and_assembly, - num_mixed_context_lines, options, strm); + return Disassemble( + debugger, arch, plugin_name, flavor, exe_ctx, range.GetBaseAddress(), + {Limit::Instructions, num_instructions}, mixed_source_and_assembly, + num_mixed_context_lines, options, strm); } Instruction::Instruction(const Address &address, AddressClass addr_class) @@ -1182,82 +1072,44 @@ InstructionList::GetIndexOfInstructionAtLoadAddress(lldb::addr_t load_addr, return GetIndexOfInstructionAtAddress(address); } -size_t Disassembler::ParseInstructions(const ExecutionContext *exe_ctx, - const AddressRange &range, - Stream *error_strm_ptr, - bool prefer_file_cache) { - if (exe_ctx) { - Target *target = exe_ctx->GetTargetPtr(); - const addr_t byte_size = range.GetByteSize(); - if (target == nullptr || byte_size == 0 || - !range.GetBaseAddress().IsValid()) - return 0; - - auto data_sp = std::make_shared(byte_size, '\0'); - - Status error; - lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; - const size_t bytes_read = target->ReadMemory( - range.GetBaseAddress(), prefer_file_cache, data_sp->GetBytes(), - data_sp->GetByteSize(), error, &load_addr); - - if (bytes_read > 0) { - if (bytes_read != data_sp->GetByteSize()) - data_sp->SetByteSize(bytes_read); - DataExtractor data(data_sp, m_arch.GetByteOrder(), - m_arch.GetAddressByteSize()); - const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; - return DecodeInstructions(range.GetBaseAddress(), data, 0, UINT32_MAX, - false, data_from_file); - } else if (error_strm_ptr) { - const char *error_cstr = error.AsCString(); - if (error_cstr) { - error_strm_ptr->Printf("error: %s\n", error_cstr); - } - } - } else if (error_strm_ptr) { - error_strm_ptr->PutCString("error: invalid execution context\n"); - } - return 0; -} - -size_t Disassembler::ParseInstructions(const ExecutionContext *exe_ctx, - const Address &start, - uint32_t num_instructions, +size_t Disassembler::ParseInstructions(Target &target, Address start, + Limit limit, Stream *error_strm_ptr, bool prefer_file_cache) { m_instruction_list.Clear(); - if (exe_ctx == nullptr || num_instructions == 0 || !start.IsValid()) + if (!start.IsValid()) return 0; - Target *target = exe_ctx->GetTargetPtr(); - // Calculate the max buffer size we will need in order to disassemble - const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize(); - - if (target == nullptr || byte_size == 0) - return 0; + start = ResolveAddress(target, start); - DataBufferHeap *heap_buffer = new DataBufferHeap(byte_size, '\0'); - DataBufferSP data_sp(heap_buffer); + addr_t byte_size = limit.value; + if (limit.kind == Limit::Instructions) + byte_size *= m_arch.GetMaximumOpcodeByteSize(); + auto data_sp = std::make_shared(byte_size, '\0'); Status error; lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; const size_t bytes_read = - target->ReadMemory(start, prefer_file_cache, heap_buffer->GetBytes(), - byte_size, error, &load_addr); - + target.ReadMemory(start, prefer_file_cache, data_sp->GetBytes(), + data_sp->GetByteSize(), error, &load_addr); const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; - if (bytes_read == 0) + if (bytes_read == 0) { + if (error_strm_ptr) { + if (const char *error_cstr = error.AsCString()) + error_strm_ptr->Printf("error: %s\n", error_cstr); + } return 0; + } + + if (bytes_read != data_sp->GetByteSize()) + data_sp->SetByteSize(bytes_read); DataExtractor data(data_sp, m_arch.GetByteOrder(), m_arch.GetAddressByteSize()); - - const bool append_instructions = true; - DecodeInstructions(start, data, 0, num_instructions, append_instructions, - data_from_file); - - return m_instruction_list.GetSize(); + return DecodeInstructions(start, data, 0, + limit.kind == Limit::Instructions ? limit.value + : UINT32_MAX, + false, data_from_file); } // Disassembler copy constructor @@ -1346,7 +1198,7 @@ void PseudoInstruction::SetOpcode(size_t opcode_size, void *opcode_data) { } void PseudoInstruction::SetDescription(llvm::StringRef description) { - m_description = description; + m_description = std::string(description); } Instruction::Operand Instruction::Operand::BuildRegister(ConstString &r) { diff --git a/gnu/llvm/lldb/source/Core/DumpDataExtractor.cpp b/gnu/llvm/lldb/source/Core/DumpDataExtractor.cpp index b5e1071b72a..dbfedfae27a 100644 --- a/gnu/llvm/lldb/source/Core/DumpDataExtractor.cpp +++ b/gnu/llvm/lldb/source/Core/DumpDataExtractor.cpp @@ -1,4 +1,4 @@ -//===-- DumpDataExtractor.cpp -----------------------------------*- C++ -*-===// +//===-- DumpDataExtractor.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -128,6 +128,104 @@ static lldb::offset_t DumpAPInt(Stream *s, const DataExtractor &data, return offset; } +/// Dumps decoded instructions to a stream. +static lldb::offset_t DumpInstructions(const DataExtractor &DE, Stream *s, + ExecutionContextScope *exe_scope, + offset_t start_offset, + uint64_t base_addr, + size_t number_of_instructions) { + offset_t offset = start_offset; + + TargetSP target_sp; + if (exe_scope) + target_sp = exe_scope->CalculateTarget(); + if (target_sp) { + DisassemblerSP disassembler_sp( + Disassembler::FindPlugin(target_sp->GetArchitecture(), + target_sp->GetDisassemblyFlavor(), nullptr)); + if (disassembler_sp) { + lldb::addr_t addr = base_addr + start_offset; + lldb_private::Address so_addr; + bool data_from_file = true; + if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) { + data_from_file = false; + } else { + if (target_sp->GetSectionLoadList().IsEmpty() || + !target_sp->GetImages().ResolveFileAddress(addr, so_addr)) + so_addr.SetRawAddress(addr); + } + + size_t bytes_consumed = disassembler_sp->DecodeInstructions( + so_addr, DE, start_offset, number_of_instructions, false, + data_from_file); + + if (bytes_consumed) { + offset += bytes_consumed; + const bool show_address = base_addr != LLDB_INVALID_ADDRESS; + const bool show_bytes = true; + ExecutionContext exe_ctx; + exe_scope->CalculateExecutionContext(exe_ctx); + disassembler_sp->GetInstructionList().Dump(s, show_address, show_bytes, + &exe_ctx); + } + } + } else + s->Printf("invalid target"); + + return offset; +} + +/// Prints the specific escape sequence of the given character to the stream. +/// If the character doesn't have a known specific escape sequence (e.g., '\a', +/// '\n' but not generic escape sequences such as'\x12'), this function will +/// not modify the stream and return false. +static bool TryDumpSpecialEscapedChar(Stream &s, const char c) { + switch (c) { + case '\033': + // Common non-standard escape code for 'escape'. + s.Printf("\\e"); + return true; + case '\a': + s.Printf("\\a"); + return true; + case '\b': + s.Printf("\\b"); + return true; + case '\f': + s.Printf("\\f"); + return true; + case '\n': + s.Printf("\\n"); + return true; + case '\r': + s.Printf("\\r"); + return true; + case '\t': + s.Printf("\\t"); + return true; + case '\v': + s.Printf("\\v"); + return true; + case '\0': + s.Printf("\\0"); + return true; + default: + return false; + } +} + +/// Dump the character to a stream. A character that is not printable will be +/// represented by its escape sequence. +static void DumpCharacter(Stream &s, const char c) { + if (TryDumpSpecialEscapedChar(s, c)) + return; + if (llvm::isPrint(c)) { + s.PutChar(c); + return; + } + s.Printf("\\x%2.2x", c); +} + lldb::offset_t lldb_private::DumpDataExtractor( const DataExtractor &DE, Stream *s, offset_t start_offset, lldb::Format item_format, size_t item_byte_size, size_t item_count, @@ -147,44 +245,9 @@ lldb::offset_t lldb_private::DumpDataExtractor( offset_t offset = start_offset; - if (item_format == eFormatInstruction) { - TargetSP target_sp; - if (exe_scope) - target_sp = exe_scope->CalculateTarget(); - if (target_sp) { - DisassemblerSP disassembler_sp(Disassembler::FindPlugin( - target_sp->GetArchitecture(), - target_sp->GetDisassemblyFlavor(), nullptr)); - if (disassembler_sp) { - lldb::addr_t addr = base_addr + start_offset; - lldb_private::Address so_addr; - bool data_from_file = true; - if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) { - data_from_file = false; - } else { - if (target_sp->GetSectionLoadList().IsEmpty() || - !target_sp->GetImages().ResolveFileAddress(addr, so_addr)) - so_addr.SetRawAddress(addr); - } - - size_t bytes_consumed = disassembler_sp->DecodeInstructions( - so_addr, DE, start_offset, item_count, false, data_from_file); - - if (bytes_consumed) { - offset += bytes_consumed; - const bool show_address = base_addr != LLDB_INVALID_ADDRESS; - const bool show_bytes = true; - ExecutionContext exe_ctx; - exe_scope->CalculateExecutionContext(exe_ctx); - disassembler_sp->GetInstructionList().Dump(s, show_address, - show_bytes, &exe_ctx); - } - } - } else - s->Printf("invalid target"); - - return offset; - } + if (item_format == eFormatInstruction) + return DumpInstructions(DE, s, exe_scope, start_offset, base_addr, + item_count); if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) && item_byte_size > 8) @@ -284,43 +347,14 @@ lldb::offset_t lldb_private::DumpDataExtractor( const uint64_t ch = DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset); - if (isprint(ch)) + if (llvm::isPrint(ch)) s->Printf("%c", (char)ch); else if (item_format != eFormatCharPrintable) { - switch (ch) { - case '\033': - s->Printf("\\e"); - break; - case '\a': - s->Printf("\\a"); - break; - case '\b': - s->Printf("\\b"); - break; - case '\f': - s->Printf("\\f"); - break; - case '\n': - s->Printf("\\n"); - break; - case '\r': - s->Printf("\\r"); - break; - case '\t': - s->Printf("\\t"); - break; - case '\v': - s->Printf("\\v"); - break; - case '\0': - s->Printf("\\0"); - break; - default: + if (!TryDumpSpecialEscapedChar(*s, ch)) { if (item_byte_size == 1) s->Printf("\\x%2.2x", (uint8_t)ch); else s->Printf("%" PRIu64, ch); - break; } } else { s->PutChar(NON_PRINTABLE_CHAR); @@ -375,42 +409,7 @@ lldb::offset_t lldb_private::DumpDataExtractor( s->PutChar('\''); for (uint32_t i = 0; i < item_byte_size; ++i) { uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8)); - if (isprint(ch)) - s->Printf("%c", ch); - else { - switch (ch) { - case '\033': - s->Printf("\\e"); - break; - case '\a': - s->Printf("\\a"); - break; - case '\b': - s->Printf("\\b"); - break; - case '\f': - s->Printf("\\f"); - break; - case '\n': - s->Printf("\\n"); - break; - case '\r': - s->Printf("\\r"); - break; - case '\t': - s->Printf("\\t"); - break; - case '\v': - s->Printf("\\v"); - break; - case '\0': - s->Printf("\\0"); - break; - default: - s->Printf("\\x%2.2x", ch); - break; - } - } + DumpCharacter(*s, ch); } s->PutChar('\''); } break; @@ -425,40 +424,7 @@ lldb::offset_t lldb_private::DumpDataExtractor( s->PutChar('\"'); while (const char c = *cstr) { - if (isprint(c)) { - s->PutChar(c); - } else { - switch (c) { - case '\033': - s->Printf("\\e"); - break; - case '\a': - s->Printf("\\a"); - break; - case '\b': - s->Printf("\\b"); - break; - case '\f': - s->Printf("\\f"); - break; - case '\n': - s->Printf("\\n"); - break; - case '\r': - s->Printf("\\r"); - break; - case '\t': - s->Printf("\\t"); - break; - case '\v': - s->Printf("\\v"); - break; - default: - s->Printf("\\x%2.2x", c); - break; - } - } - + DumpCharacter(*s, c); ++cstr; } diff --git a/gnu/llvm/lldb/source/Core/DumpRegisterValue.cpp b/gnu/llvm/lldb/source/Core/DumpRegisterValue.cpp index 74b02413f10..2018d618f1d 100644 --- a/gnu/llvm/lldb/source/Core/DumpRegisterValue.cpp +++ b/gnu/llvm/lldb/source/Core/DumpRegisterValue.cpp @@ -1,4 +1,4 @@ -//===-- DumpRegisterValue.cpp -----------------------------------*- C++ -*-===// +//===-- DumpRegisterValue.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -33,7 +33,7 @@ bool lldb_private::DumpRegisterValue(const RegisterValue ®_val, Stream *s, format_string.Printf("%%%us", reg_name_right_align_at); else format_string.Printf("%%s"); - std::string fmt = format_string.GetString(); + std::string fmt = std::string(format_string.GetString()); if (prefix_with_name) { if (reg_info->name) { s->Printf(fmt.c_str(), reg_info->name); diff --git a/gnu/llvm/lldb/source/Core/DynamicLoader.cpp b/gnu/llvm/lldb/source/Core/DynamicLoader.cpp index 57130d6fa57..ceccbe437e1 100644 --- a/gnu/llvm/lldb/source/Core/DynamicLoader.cpp +++ b/gnu/llvm/lldb/source/Core/DynamicLoader.cpp @@ -1,4 +1,4 @@ -//===-- DynamicLoader.cpp ---------------------------------------*- C++ -*-===// +//===-- DynamicLoader.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -193,7 +193,7 @@ ModuleSP DynamicLoader::LoadModuleAtAddress(const FileSpec &file, if (error.Success() && memory_info.GetMapped() && memory_info.GetRange().GetRangeBase() == base_addr && !(memory_info.GetName().IsEmpty())) { - ModuleSpec new_module_spec(FileSpec(memory_info.GetName().AsCString()), + ModuleSpec new_module_spec(FileSpec(memory_info.GetName().GetStringRef()), target.GetArchitecture()); if ((module_sp = modules.FindFirstModule(new_module_spec))) { diff --git a/gnu/llvm/lldb/source/Core/EmulateInstruction.cpp b/gnu/llvm/lldb/source/Core/EmulateInstruction.cpp index 62942fb715b..f7f56e9fc54 100644 --- a/gnu/llvm/lldb/source/Core/EmulateInstruction.cpp +++ b/gnu/llvm/lldb/source/Core/EmulateInstruction.cpp @@ -1,4 +1,4 @@ -//===-- EmulateInstruction.cpp ----------------------------------*- C++ -*-===// +//===-- EmulateInstruction.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Core/FileLineResolver.cpp b/gnu/llvm/lldb/source/Core/FileLineResolver.cpp index 7d91d1a3e47..37435f9e904 100644 --- a/gnu/llvm/lldb/source/Core/FileLineResolver.cpp +++ b/gnu/llvm/lldb/source/Core/FileLineResolver.cpp @@ -1,4 +1,4 @@ -//===-- FileLineResolver.cpp ------------------------------------*- C++ -*-===// +//===-- FileLineResolver.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Core/FileSpecList.cpp b/gnu/llvm/lldb/source/Core/FileSpecList.cpp index 6651324fa36..3ada7b495fd 100644 --- a/gnu/llvm/lldb/source/Core/FileSpecList.cpp +++ b/gnu/llvm/lldb/source/Core/FileSpecList.cpp @@ -1,4 +1,4 @@ -//===-- FileSpecList.cpp ----------------------------------------*- C++ -*-===// +//===-- FileSpecList.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Core/FormatEntity.cpp b/gnu/llvm/lldb/source/Core/FormatEntity.cpp index 3d2e1d98b8c..d491ac14bec 100644 --- a/gnu/llvm/lldb/source/Core/FormatEntity.cpp +++ b/gnu/llvm/lldb/source/Core/FormatEntity.cpp @@ -1,4 +1,4 @@ -//===-- FormatEntity.cpp ----------------------------------------*- C++ -*-===// +//===-- FormatEntity.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -46,7 +46,6 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" #include "lldb/Utility/RegisterValue.h" -#include "lldb/Utility/SharingPtr.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StringList.h" @@ -166,6 +165,7 @@ static FormatEntity::Entry::Definition g_thread_child_entries[] = { ENTRY("queue", ThreadQueue), ENTRY("name", ThreadName), ENTRY("stop-reason", ThreadStopReason), + ENTRY("stop-reason-raw", ThreadStopReasonRaw), ENTRY("return-value", ThreadReturnValue), ENTRY("completed-expression", ThreadCompletedExpression), }; @@ -328,6 +328,7 @@ const char *FormatEntity::Entry::TypeToCString(Type t) { ENUM_TO_CSTR(ThreadName); ENUM_TO_CSTR(ThreadQueue); ENUM_TO_CSTR(ThreadStopReason); + ENUM_TO_CSTR(ThreadStopReasonRaw); ENUM_TO_CSTR(ThreadReturnValue); ENUM_TO_CSTR(ThreadCompletedExpression); ENUM_TO_CSTR(ScriptThread); @@ -1206,8 +1207,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, : llvm::Triple::UnknownOS; if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux) || - (ostype == llvm::Triple::NetBSD) || - (ostype == llvm::Triple::OpenBSD)) { + (ostype == llvm::Triple::NetBSD)) { format = "%" PRIu64; } } else { @@ -1274,15 +1274,23 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, case Entry::Type::ThreadStopReason: if (exe_ctx) { - Thread *thread = exe_ctx->GetThreadPtr(); - if (thread) { - StopInfoSP stop_info_sp = thread->GetStopInfo(); - if (stop_info_sp && stop_info_sp->IsValid()) { - const char *cstr = stop_info_sp->GetDescription(); - if (cstr && cstr[0]) { - s.PutCString(cstr); - return true; - } + if (Thread *thread = exe_ctx->GetThreadPtr()) { + std::string stop_description = thread->GetStopDescription(); + if (!stop_description.empty()) { + s.PutCString(stop_description); + return true; + } + } + } + return false; + + case Entry::Type::ThreadStopReasonRaw: + if (exe_ctx) { + if (Thread *thread = exe_ctx->GetThreadPtr()) { + std::string stop_description = thread->GetStopDescriptionRaw(); + if (!stop_description.empty()) { + s.PutCString(stop_description); + return true; } } } @@ -1545,7 +1553,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, sc->block->GetInlinedFunctionInfo(); if (inline_info) { s.PutCString(" [inlined] "); - inline_info->GetName(sc->function->GetLanguage()).Dump(&s); + inline_info->GetName().Dump(&s); } } } @@ -1629,8 +1637,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, if (inline_info) { s.PutCString(cstr); s.PutCString(" [inlined] "); - cstr = - inline_info->GetName(sc->function->GetLanguage()).GetCString(); + cstr = inline_info->GetName().GetCString(); } VariableList args; @@ -1751,12 +1758,11 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, case Entry::Type::FunctionMangledName: { const char *name = nullptr; if (sc->symbol) - name = sc->symbol->GetMangled() - .GetName(sc->symbol->GetLanguage(), Mangled::ePreferMangled) - .AsCString(); + name = + sc->symbol->GetMangled().GetName(Mangled::ePreferMangled).AsCString(); else if (sc->function) name = sc->function->GetMangled() - .GetName(sc->symbol->GetLanguage(), Mangled::ePreferMangled) + .GetName(Mangled::ePreferMangled) .AsCString(); if (!name) @@ -1767,7 +1773,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, if (const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo()) { s.PutCString(" [inlined] "); - inline_info->GetName(sc->function->GetLanguage()).Dump(&s); + inline_info->GetName().Dump(&s); } } return true; @@ -2341,10 +2347,10 @@ bool FormatEntity::FormatFileSpec(const FileSpec &file_spec, Stream &s, file_spec.Dump(s.AsRawOstream()); return true; } else if (variable_name.equals(".basename")) { - s.PutCString(file_spec.GetFilename().AsCString("")); + s.PutCString(file_spec.GetFilename().GetStringRef()); return true; } else if (variable_name.equals(".dirname")) { - s.PutCString(file_spec.GetFilename().AsCString("")); + s.PutCString(file_spec.GetFilename().GetStringRef()); return true; } return false; @@ -2403,7 +2409,7 @@ void FormatEntity::AutoComplete(CompletionRequest &request) { llvm::StringRef partial_variable(str.substr(dollar_pos + 2)); if (partial_variable.empty()) { - // Suggest all top level entites as we are just past "${" + // Suggest all top level entities as we are just past "${" StringList new_matches; AddMatches(&g_root, str, llvm::StringRef(), new_matches); request.AddCompletions(new_matches); diff --git a/gnu/llvm/lldb/source/Core/Highlighter.cpp b/gnu/llvm/lldb/source/Core/Highlighter.cpp index c3c614aac21..04d993b8305 100644 --- a/gnu/llvm/lldb/source/Core/Highlighter.cpp +++ b/gnu/llvm/lldb/source/Core/Highlighter.cpp @@ -1,4 +1,4 @@ -//===-- Highlighter.cpp -----------------------------------------*- C++ -*-===// +//===-- Highlighter.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Core/IOHandler.cpp b/gnu/llvm/lldb/source/Core/IOHandler.cpp index 4021a6d7f32..6cf09aaa7f9 100644 --- a/gnu/llvm/lldb/source/Core/IOHandler.cpp +++ b/gnu/llvm/lldb/source/Core/IOHandler.cpp @@ -1,4 +1,4 @@ -//===-- IOHandler.cpp -------------------------------------------*- C++ -*-===// +//===-- IOHandler.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -125,6 +125,8 @@ void IOHandlerStack::PrintAsync(Stream *stream, const char *s, size_t len) { std::lock_guard guard(m_mutex); if (m_top) m_top->PrintAsync(stream, s, len); + else + stream->Write(s, len); } } @@ -251,9 +253,9 @@ IOHandlerEditline::IOHandlerEditline( m_input_sp && m_input_sp->GetIsRealTerminal(); if (use_editline) { - m_editline_up.reset(new Editline(editline_name, GetInputFILE(), - GetOutputFILE(), GetErrorFILE(), - m_color_prompts)); + m_editline_up = std::make_unique(editline_name, GetInputFILE(), + GetOutputFILE(), GetErrorFILE(), + m_color_prompts); m_editline_up->SetIsInputCompleteCallback(IsInputCompleteCallback, this); m_editline_up->SetAutoCompleteCallback(AutoCompleteCallback, this); // See if the delegate supports fixing indentation @@ -287,12 +289,20 @@ void IOHandlerEditline::Deactivate() { m_delegate.IOHandlerDeactivated(*this); } +void IOHandlerEditline::TerminalSizeChanged() { +#if LLDB_ENABLE_LIBEDIT + if (m_editline_up) + m_editline_up->TerminalSizeChanged(); +#endif +} + // Split out a line from the buffer, if there is a full one to get. static Optional SplitLine(std::string &line_buffer) { size_t pos = line_buffer.find('\n'); if (pos == std::string::npos) return None; - std::string line = StringRef(line_buffer.c_str(), pos).rtrim("\n\r"); + std::string line = + std::string(StringRef(line_buffer.c_str(), pos).rtrim("\n\r")); line_buffer = line_buffer.substr(pos + 1); return line; } @@ -300,7 +310,7 @@ static Optional SplitLine(std::string &line_buffer) { // If the final line of the file ends without a end-of-line, return // it as a line anyway. static Optional SplitLineEOF(std::string &line_buffer) { - if (llvm::all_of(line_buffer, isspace)) + if (llvm::all_of(line_buffer, llvm::isSpace)) return None; std::string line = std::move(line_buffer); line_buffer.clear(); @@ -443,7 +453,7 @@ const char *IOHandlerEditline::GetPrompt() { } bool IOHandlerEditline::SetPrompt(llvm::StringRef prompt) { - m_prompt = prompt; + m_prompt = std::string(prompt); #if LLDB_ENABLE_LIBEDIT if (m_editline_up) @@ -458,7 +468,7 @@ const char *IOHandlerEditline::GetContinuationPrompt() { } void IOHandlerEditline::SetContinuationPrompt(llvm::StringRef prompt) { - m_continuation_prompt = prompt; + m_continuation_prompt = std::string(prompt); #if LLDB_ENABLE_LIBEDIT if (m_editline_up) diff --git a/gnu/llvm/lldb/source/Core/IOHandlerCursesGUI.cpp b/gnu/llvm/lldb/source/Core/IOHandlerCursesGUI.cpp index 1661b465efa..f8fc9177219 100644 --- a/gnu/llvm/lldb/source/Core/IOHandlerCursesGUI.cpp +++ b/gnu/llvm/lldb/source/Core/IOHandlerCursesGUI.cpp @@ -1,4 +1,4 @@ -//===-- IOHandlerCursesGUI.cpp ----------------------------------*- C++ -*-===// +//===-- IOHandlerCursesGUI.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -744,7 +744,8 @@ protected: bool m_is_subwin; private: - DISALLOW_COPY_AND_ASSIGN(Window); + Window(const Window &) = delete; + const Window &operator=(const Window &) = delete; }; class MenuDelegate { @@ -918,7 +919,7 @@ void Menu::DrawMenuTitle(Window &window, bool highlight) { const attr_t hilgight_attr = A_REVERSE; if (highlight) window.AttributeOn(hilgight_attr); - if (isprint(shortcut_key)) { + if (llvm::isPrint(shortcut_key)) { size_t lower_pos = m_name.find(tolower(shortcut_key)); size_t upper_pos = m_name.find(toupper(shortcut_key)); const char *name = m_name.c_str(); @@ -947,7 +948,7 @@ void Menu::DrawMenuTitle(Window &window, bool highlight) { window.AttributeOff(hilgight_attr); if (m_key_name.empty()) { - if (!underlined_shortcut && isprint(m_key_value)) { + if (!underlined_shortcut && llvm::isPrint(m_key_value)) { window.AttributeOn(COLOR_PAIR(3)); window.Printf(" (%c)", m_key_value); window.AttributeOff(COLOR_PAIR(3)); @@ -2714,7 +2715,7 @@ static const char *CursesKeyToCString(int ch) { case KEY_ESCAPE: return "escape"; default: - if (isprint(ch)) + if (llvm::isPrint(ch)) snprintf(g_desc, sizeof(g_desc), "%c", ch); else snprintf(g_desc, sizeof(g_desc), "\\x%2.2x", ch); @@ -3909,7 +3910,7 @@ IOHandlerCursesGUI::IOHandlerCursesGUI(Debugger &debugger) void IOHandlerCursesGUI::Activate() { IOHandler::Activate(); if (!m_app_ap) { - m_app_ap.reset(new Application(GetInputFILE(), GetOutputFILE())); + m_app_ap = std::make_unique(GetInputFILE(), GetOutputFILE()); // This is both a window and a menu delegate std::shared_ptr app_delegate_sp( diff --git a/gnu/llvm/lldb/source/Core/Mangled.cpp b/gnu/llvm/lldb/source/Core/Mangled.cpp index 15baffd212a..143ec8770bf 100644 --- a/gnu/llvm/lldb/source/Core/Mangled.cpp +++ b/gnu/llvm/lldb/source/Core/Mangled.cpp @@ -1,4 +1,4 @@ -//===-- Mangled.cpp ---------------------------------------------*- C++ -*-===// +//===-- Mangled.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -142,9 +142,8 @@ void Mangled::Clear() { // Compare the string values. int Mangled::Compare(const Mangled &a, const Mangled &b) { - return ConstString::Compare( - a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled), - b.GetName(lldb::eLanguageTypeUnknown, ePreferMangled)); + return ConstString::Compare(a.GetName(ePreferMangled), + b.GetName(ePreferMangled)); } // Set the string value in this objects. If "mangled" is true, then the mangled @@ -182,7 +181,7 @@ void Mangled::SetValue(ConstString name) { // Local helpers for different demangling implementations. static char *GetMSVCDemangledStr(const char *M) { char *demangled_cstr = llvm::microsoftDemangle( - M, nullptr, nullptr, nullptr, + M, nullptr, nullptr, nullptr, nullptr, llvm::MSDemangleFlags(llvm::MSDF_NoAccessSpecifier | llvm::MSDF_NoCallingConvention | llvm::MSDF_NoMemberType)); @@ -295,8 +294,7 @@ bool Mangled::DemangleWithRichManglingInfo( // class will need to use this accessor if it wishes to decode the demangled // name. The result is cached and will be kept until a new string value is // supplied to this object, or until the end of the object's lifetime. -ConstString -Mangled::GetDemangledName(lldb::LanguageType language) const { +ConstString Mangled::GetDemangledName() const { // Check to make sure we have a valid mangled name and that we haven't // already decoded our mangled name. if (m_mangled && m_demangled.IsNull()) { @@ -341,26 +339,24 @@ Mangled::GetDemangledName(lldb::LanguageType language) const { } ConstString -Mangled::GetDisplayDemangledName(lldb::LanguageType language) const { - return GetDemangledName(language); +Mangled::GetDisplayDemangledName() const { + return GetDemangledName(); } -bool Mangled::NameMatches(const RegularExpression ®ex, - lldb::LanguageType language) const { - if (m_mangled && regex.Execute(m_mangled.AsCString())) +bool Mangled::NameMatches(const RegularExpression ®ex) const { + if (m_mangled && regex.Execute(m_mangled.GetStringRef())) return true; - ConstString demangled = GetDemangledName(language); - return demangled && regex.Execute(demangled.AsCString()); + ConstString demangled = GetDemangledName(); + return demangled && regex.Execute(demangled.GetStringRef()); } // Get the demangled name if there is one, else return the mangled name. -ConstString Mangled::GetName(lldb::LanguageType language, - Mangled::NamePreference preference) const { +ConstString Mangled::GetName(Mangled::NamePreference preference) const { if (preference == ePreferMangled && m_mangled) return m_mangled; - ConstString demangled = GetDemangledName(language); + ConstString demangled = GetDemangledName(); if (preference == ePreferDemangledWithoutArguments) { return get_demangled_name_without_arguments(m_mangled, demangled); @@ -417,12 +413,10 @@ lldb::LanguageType Mangled::GuessLanguage() const { const char *mangled_name = mangled.GetCString(); if (CPlusPlusLanguage::IsCPPMangledName(mangled_name)) return lldb::eLanguageTypeC_plus_plus; - else if (ObjCLanguage::IsPossibleObjCMethodName(mangled_name)) - return lldb::eLanguageTypeObjC; } else { // ObjC names aren't really mangled, so they won't necessarily be in the // mangled name slot. - ConstString demangled_name = GetDemangledName(lldb::eLanguageTypeUnknown); + ConstString demangled_name = GetDemangledName(); if (demangled_name && ObjCLanguage::IsPossibleObjCMethodName(demangled_name.GetCString())) return lldb::eLanguageTypeObjC; @@ -436,8 +430,7 @@ Stream &operator<<(Stream &s, const Mangled &obj) { if (obj.GetMangledName()) s << "mangled = '" << obj.GetMangledName() << "'"; - ConstString demangled = - obj.GetDemangledName(lldb::eLanguageTypeUnknown); + ConstString demangled = obj.GetDemangledName(); if (demangled) s << ", demangled = '" << demangled << '\''; else diff --git a/gnu/llvm/lldb/source/Core/Module.cpp b/gnu/llvm/lldb/source/Core/Module.cpp index 031892abdd2..b76659ee3e0 100644 --- a/gnu/llvm/lldb/source/Core/Module.cpp +++ b/gnu/llvm/lldb/source/Core/Module.cpp @@ -1,4 +1,4 @@ -//===-- Module.cpp ----------------------------------------------*- C++ -*-===// +//===-- Module.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,6 +18,7 @@ #include "lldb/Core/Section.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Symbol/CompileUnit.h" @@ -33,7 +34,6 @@ #include "lldb/Symbol/TypeMap.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/Language.h" -#include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" @@ -147,11 +147,16 @@ Module::Module(const ModuleSpec &module_spec) : module_spec.GetObjectName().AsCString(""), module_spec.GetObjectName().IsEmpty() ? "" : ")"); + auto data_sp = module_spec.GetData(); + lldb::offset_t file_size = 0; + if (data_sp) + file_size = data_sp->GetByteSize(); + // First extract all module specifications from the file using the local file // path. If there are no specifications, then don't fill anything in ModuleSpecList modules_specs; - if (ObjectFile::GetModuleSpecifications(module_spec.GetFileSpec(), 0, 0, - modules_specs) == 0) + if (ObjectFile::GetModuleSpecifications( + module_spec.GetFileSpec(), 0, file_size, modules_specs, data_sp) == 0) return; // Now make sure that one of the module specifications matches what we just @@ -170,11 +175,20 @@ Module::Module(const ModuleSpec &module_spec) return; } - if (module_spec.GetFileSpec()) - m_mod_time = FileSystem::Instance().GetModificationTime(module_spec.GetFileSpec()); - else if (matching_module_spec.GetFileSpec()) - m_mod_time = - FileSystem::Instance().GetModificationTime(matching_module_spec.GetFileSpec()); + // Set m_data_sp if it was initially provided in the ModuleSpec. Note that + // we cannot use the data_sp variable here, because it will have been + // modified by GetModuleSpecifications(). + if (auto module_spec_data_sp = module_spec.GetData()) { + m_data_sp = module_spec_data_sp; + m_mod_time = {}; + } else { + if (module_spec.GetFileSpec()) + m_mod_time = + FileSystem::Instance().GetModificationTime(module_spec.GetFileSpec()); + else if (matching_module_spec.GetFileSpec()) + m_mod_time = FileSystem::Instance().GetModificationTime( + matching_module_spec.GetFileSpec()); + } // Copy the architecture from the actual spec if we got one back, else use // the one that was specified @@ -297,7 +311,9 @@ ObjectFile *Module::GetMemoryObjectFile(const lldb::ProcessSP &process_sp, const size_t bytes_read = process_sp->ReadMemory(header_addr, data_up->GetBytes(), data_up->GetByteSize(), readmem_error); - if (bytes_read == size_to_read) { + if (bytes_read < size_to_read) + data_up->SetByteSize(bytes_read); + if (data_up->GetByteSize() > 0) { DataBufferSP data_sp(data_up.release()); m_objfile_sp = ObjectFile::FindPlugin(shared_from_this(), process_sp, header_addr, data_sp); @@ -364,11 +380,11 @@ void Module::ParseAllDebugSymbols() { if (num_comp_units == 0) return; - SymbolContext sc; - sc.module_sp = shared_from_this(); SymbolFile *symbols = GetSymbolFile(); for (size_t cu_idx = 0; cu_idx < num_comp_units; cu_idx++) { + SymbolContext sc; + sc.module_sp = shared_from_this(); sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get(); if (!sc.comp_unit) continue; @@ -595,7 +611,7 @@ uint32_t Module::ResolveSymbolContextsForFileSpec( } void Module::FindGlobalVariables(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, size_t max_matches, VariableList &variables) { if (SymbolFile *symbols = GetSymbolFile()) symbols->FindGlobalVariables(name, parent_decl_ctx, max_matches, variables); @@ -783,7 +799,7 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list, } void Module::FindFunctions(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, FunctionNameType name_type_mask, bool include_symbols, bool include_inlines, SymbolContextList &sc_list) { @@ -920,7 +936,7 @@ void Module::FindAddressesForLine(const lldb::TargetSP target_sp, } void Module::FindTypes_Impl( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, size_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) { @@ -932,7 +948,7 @@ void Module::FindTypes_Impl( } void Module::FindTypesInNamespace(ConstString type_name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, size_t max_matches, TypeList &type_list) { TypeMap types_map; llvm::DenseSet searched_symbol_files; @@ -974,10 +990,11 @@ void Module::FindTypes( exact_match = type_scope.consume_front("::"); ConstString type_basename_const_str(type_basename); - FindTypes_Impl(type_basename_const_str, nullptr, max_matches, + FindTypes_Impl(type_basename_const_str, CompilerDeclContext(), max_matches, searched_symbol_files, typesmap); if (typesmap.GetSize()) - typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class, + typesmap.RemoveMismatchedTypes(std::string(type_scope), + std::string(type_basename), type_class, exact_match); } else { // The type is not in a namespace/class scope, just search for it by @@ -985,16 +1002,18 @@ void Module::FindTypes( if (type_class != eTypeClassAny && !type_basename.empty()) { // The "type_name_cstr" will have been modified if we have a valid type // class prefix (like "struct", "class", "union", "typedef" etc). - FindTypes_Impl(ConstString(type_basename), nullptr, UINT_MAX, - searched_symbol_files, typesmap); - typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class, + FindTypes_Impl(ConstString(type_basename), CompilerDeclContext(), + UINT_MAX, searched_symbol_files, typesmap); + typesmap.RemoveMismatchedTypes(std::string(type_scope), + std::string(type_basename), type_class, exact_match); } else { - FindTypes_Impl(name, nullptr, UINT_MAX, searched_symbol_files, typesmap); + FindTypes_Impl(name, CompilerDeclContext(), UINT_MAX, + searched_symbol_files, typesmap); if (exact_match) { std::string name_str(name.AsCString("")); - typesmap.RemoveMismatchedTypes(type_scope, name_str, type_class, - exact_match); + typesmap.RemoveMismatchedTypes(std::string(type_scope), name_str, + type_class, exact_match); } } } @@ -1105,6 +1124,10 @@ void Module::ReportError(const char *format, ...) { } bool Module::FileHasChanged() const { + // We have provided the DataBuffer for this module to avoid accessing the + // filesystem. We never want to reload those files. + if (m_data_sp) + return false; if (!m_file_has_changed) m_file_has_changed = (FileSystem::Instance().GetModificationTime(m_file) != m_mod_time); @@ -1224,12 +1247,19 @@ ObjectFile *Module::GetObjectFile() { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString("")); - DataBufferSP data_sp; lldb::offset_t data_offset = 0; - const lldb::offset_t file_size = - FileSystem::Instance().GetByteSize(m_file); + lldb::offset_t file_size = 0; + + if (m_data_sp) + file_size = m_data_sp->GetByteSize(); + else if (m_file) + file_size = FileSystem::Instance().GetByteSize(m_file); + if (file_size > m_object_offset) { m_did_load_objfile = true; + // FindPlugin will modify its data_sp argument. Do not let it + // modify our m_data_sp member. + auto data_sp = m_data_sp; m_objfile_sp = ObjectFile::FindPlugin( shared_from_this(), &m_file, m_object_offset, file_size - m_object_offset, data_sp, data_offset); @@ -1409,7 +1439,7 @@ void Module::SetSymbolFileFileSpec(const FileSpec &file) { if (FileSystem::Instance().IsDirectory(file)) { std::string new_path(file.GetPath()); std::string old_path(obj_file->GetFileSpec().GetPath()); - if (old_path.find(new_path) == 0) { + if (llvm::StringRef(old_path).startswith(new_path)) { // We specified the same bundle as the symbol file that we already // have return; @@ -1591,6 +1621,19 @@ bool Module::RemapSourceFile(llvm::StringRef path, return m_source_mappings.RemapPath(path, new_path); } +void Module::RegisterXcodeSDK(llvm::StringRef sdk_name, llvm::StringRef sysroot) { + XcodeSDK sdk(sdk_name.str()); + ConstString sdk_path(HostInfo::GetXcodeSDKPath(sdk)); + if (!sdk_path) + return; + // If the SDK changed for a previously registered source path, update it. + // This could happend with -fdebug-prefix-map, otherwise it's unlikely. + ConstString sysroot_cs(sysroot); + if (!m_source_mappings.Replace(sysroot_cs, sdk_path, true)) + // In the general case, however, append it to the list. + m_source_mappings.Append(sysroot_cs, sdk_path, false); +} + bool Module::MergeArchitecture(const ArchSpec &arch_spec) { if (!arch_spec.IsValid()) return false; diff --git a/gnu/llvm/lldb/source/Core/ModuleChild.cpp b/gnu/llvm/lldb/source/Core/ModuleChild.cpp index 2fcb2ffca13..6e04bb4589e 100644 --- a/gnu/llvm/lldb/source/Core/ModuleChild.cpp +++ b/gnu/llvm/lldb/source/Core/ModuleChild.cpp @@ -1,4 +1,4 @@ -//===-- ModuleChild.cpp -----------------------------------------*- C++ -*-===// +//===-- ModuleChild.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Core/ModuleList.cpp b/gnu/llvm/lldb/source/Core/ModuleList.cpp index 07100bb81dc..1701cb56338 100644 --- a/gnu/llvm/lldb/source/Core/ModuleList.cpp +++ b/gnu/llvm/lldb/source/Core/ModuleList.cpp @@ -1,4 +1,4 @@ -//===-- ModuleList.cpp ------------------------------------------*- C++ -*-===// +//===-- ModuleList.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -12,6 +12,7 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/FileSystem.h" #include "lldb/Interpreter/OptionValueFileSpec.h" +#include "lldb/Interpreter/OptionValueFileSpecList.h" #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Interpreter/Property.h" #include "lldb/Symbol/LocateSymbolFile.h" @@ -77,6 +78,8 @@ ModuleListProperties::ModuleListProperties() { m_collection_sp = std::make_shared(ConstString("symbols")); m_collection_sp->Initialize(g_modulelist_properties); + m_collection_sp->SetValueChangedCallback(ePropertySymLinkPaths, + [this] { UpdateSymlinkMappings(); }); llvm::SmallString<128> path; clang::driver::Driver::getDefaultModuleCachePath(path); @@ -106,6 +109,28 @@ bool ModuleListProperties::SetClangModulesCachePath(llvm::StringRef path) { nullptr, ePropertyClangModulesCachePath, path); } +void ModuleListProperties::UpdateSymlinkMappings() { + FileSpecList list = m_collection_sp + ->GetPropertyAtIndexAsOptionValueFileSpecList( + nullptr, false, ePropertySymLinkPaths) + ->GetCurrentValue(); + llvm::sys::ScopedWriter lock(m_symlink_paths_mutex); + const bool notify = false; + m_symlink_paths.Clear(notify); + for (FileSpec symlink : list) { + FileSpec resolved; + Status status = FileSystem::Instance().Readlink(symlink, resolved); + if (status.Success()) + m_symlink_paths.Append(ConstString(symlink.GetPath()), + ConstString(resolved.GetPath()), notify); + } +} + +PathMappingList ModuleListProperties::GetSymlinkMappings() const { + llvm::sys::ScopedReader lock(m_symlink_paths_mutex); + return m_symlink_paths; +} + ModuleList::ModuleList() : m_modules(), m_modules_mutex(), m_notifier(nullptr) {} @@ -146,7 +171,9 @@ void ModuleList::Append(const ModuleSP &module_sp, bool notify) { AppendImpl(module_sp, notify); } -void ModuleList::ReplaceEquivalent(const ModuleSP &module_sp) { +void ModuleList::ReplaceEquivalent( + const ModuleSP &module_sp, + llvm::SmallVectorImpl *old_modules) { if (module_sp) { std::lock_guard guard(m_modules_mutex); @@ -159,11 +186,14 @@ void ModuleList::ReplaceEquivalent(const ModuleSP &module_sp) { size_t idx = 0; while (idx < m_modules.size()) { - ModuleSP module_sp(m_modules[idx]); - if (module_sp->MatchesModuleSpec(equivalent_module_spec)) + ModuleSP test_module_sp(m_modules[idx]); + if (test_module_sp->MatchesModuleSpec(equivalent_module_spec)) { + if (old_modules) + old_modules->push_back(test_module_sp); RemoveImpl(m_modules.begin() + idx); - else + } else { ++idx; + } } // Now add the new module to the list Append(module_sp); @@ -338,7 +368,7 @@ void ModuleList::FindFunctions(ConstString name, std::lock_guard guard(m_modules_mutex); collection::const_iterator pos, end = m_modules.end(); for (pos = m_modules.begin(); pos != end; ++pos) { - (*pos)->FindFunctions(lookup_info.GetLookupName(), nullptr, + (*pos)->FindFunctions(lookup_info.GetLookupName(), CompilerDeclContext(), lookup_info.GetNameTypeMask(), include_symbols, include_inlines, sc_list); } @@ -351,8 +381,8 @@ void ModuleList::FindFunctions(ConstString name, std::lock_guard guard(m_modules_mutex); collection::const_iterator pos, end = m_modules.end(); for (pos = m_modules.begin(); pos != end; ++pos) { - (*pos)->FindFunctions(name, nullptr, name_type_mask, include_symbols, - include_inlines, sc_list); + (*pos)->FindFunctions(name, CompilerDeclContext(), name_type_mask, + include_symbols, include_inlines, sc_list); } } } @@ -409,7 +439,8 @@ void ModuleList::FindGlobalVariables(ConstString name, size_t max_matches, std::lock_guard guard(m_modules_mutex); collection::const_iterator pos, end = m_modules.end(); for (pos = m_modules.begin(); pos != end; ++pos) { - (*pos)->FindGlobalVariables(name, nullptr, max_matches, variable_list); + (*pos)->FindGlobalVariables(name, CompilerDeclContext(), max_matches, + variable_list); } } @@ -565,10 +596,6 @@ size_t ModuleList::GetSize() const { } void ModuleList::Dump(Stream *s) const { - // s.Printf("%.*p: ", (int)sizeof(void*) * 2, this); - // s.Indent(); - // s << "ModuleList\n"; - std::lock_guard guard(m_modules_mutex); collection::const_iterator pos, end = m_modules.end(); for (pos = m_modules.begin(); pos != end; ++pos) { @@ -709,11 +736,11 @@ size_t ModuleList::RemoveOrphanSharedModules(bool mandatory) { return GetSharedModuleList().RemoveOrphans(mandatory); } -Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, - ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, - ModuleSP *old_module_sp_ptr, - bool *did_create_ptr, bool always_create) { +Status +ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, + bool *did_create_ptr, bool always_create) { ModuleList &shared_module_list = GetSharedModuleList(); std::lock_guard guard( shared_module_list.m_modules_mutex); @@ -725,8 +752,6 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, if (did_create_ptr) *did_create_ptr = false; - if (old_module_sp_ptr) - old_module_sp_ptr->reset(); const UUID *uuid_ptr = module_spec.GetUUIDPtr(); const FileSpec &module_file_spec = module_spec.GetFileSpec(); @@ -747,8 +772,8 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, // Make sure the file for the module hasn't been modified if (module_sp->FileHasChanged()) { - if (old_module_sp_ptr && !*old_module_sp_ptr) - *old_module_sp_ptr = module_sp; + if (old_modules) + old_modules->push_back(module_sp); Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES)); if (log != nullptr) @@ -790,7 +815,7 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, *did_create_ptr = true; } - shared_module_list.ReplaceEquivalent(module_sp); + shared_module_list.ReplaceEquivalent(module_sp, old_modules); return error; } } @@ -807,7 +832,7 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, if (!FileSystem::Instance().IsDirectory(search_path_spec)) continue; search_path_spec.AppendPathComponent( - module_spec.GetFileSpec().GetFilename().AsCString()); + module_spec.GetFileSpec().GetFilename().GetStringRef()); if (!FileSystem::Instance().Exists(search_path_spec)) continue; @@ -827,7 +852,7 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, if (did_create_ptr) *did_create_ptr = true; - shared_module_list.ReplaceEquivalent(module_sp); + shared_module_list.ReplaceEquivalent(module_sp, old_modules); return Status(); } } @@ -902,8 +927,8 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, located_binary_modulespec.GetFileSpec()); if (file_spec_mod_time != llvm::sys::TimePoint<>()) { if (file_spec_mod_time != module_sp->GetModificationTime()) { - if (old_module_sp_ptr) - *old_module_sp_ptr = module_sp; + if (old_modules) + old_modules->push_back(module_sp); shared_module_list.Remove(module_sp); module_sp.reset(); } @@ -925,7 +950,7 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, if (did_create_ptr) *did_create_ptr = true; - shared_module_list.ReplaceEquivalent(module_sp); + shared_module_list.ReplaceEquivalent(module_sp, old_modules); } } else { located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path)); diff --git a/gnu/llvm/lldb/source/Core/Opcode.cpp b/gnu/llvm/lldb/source/Core/Opcode.cpp index 6ca46de40de..b544064b061 100644 --- a/gnu/llvm/lldb/source/Core/Opcode.cpp +++ b/gnu/llvm/lldb/source/Core/Opcode.cpp @@ -1,4 +1,4 @@ -//===-- Opcode.cpp ----------------------------------------------*- C++ -*-===// +//===-- Opcode.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Core/PluginManager.cpp b/gnu/llvm/lldb/source/Core/PluginManager.cpp index e8bfef72437..3545ef66cc3 100644 --- a/gnu/llvm/lldb/source/Core/PluginManager.cpp +++ b/gnu/llvm/lldb/source/Core/PluginManager.cpp @@ -1,4 +1,4 @@ -//===-- PluginManager.cpp ---------------------------------------*- C++ -*-===// +//===-- PluginManager.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -16,38 +16,24 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StringList.h" - -#if defined(_WIN32) -#include "lldb/Host/windows/PosixApi.h" -#endif - #include "llvm/ADT/StringRef.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/raw_ostream.h" - +#include #include #include #include #include #include #include - -#include - -namespace lldb_private { -class CommandInterpreter; -} +#if defined(_WIN32) +#include "lldb/Host/windows/PosixApi.h" +#endif using namespace lldb; using namespace lldb_private; -enum PluginAction { - ePluginRegisterInstance, - ePluginUnregisterInstance, - ePluginGetInstanceAtIndex -}; - typedef bool (*PluginInitCallback)(); typedef void (*PluginTermCallback)(); @@ -92,7 +78,6 @@ template static FPtrTy CastToFPtr(void *VPtr) { static FileSystem::EnumerateDirectoryResult LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path) { - // PluginManager *plugin_manager = (PluginManager *)baton; Status error; namespace fs = llvm::sys::fs; @@ -156,7 +141,6 @@ LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, } void PluginManager::Initialize() { -#if 1 const bool find_directories = true; const bool find_files = true; const bool find_other = true; @@ -178,7 +162,6 @@ void PluginManager::Initialize() { LoadPluginCallback, nullptr); } } -#endif } void PluginManager::Terminate() { @@ -197,99 +180,127 @@ void PluginManager::Terminate() { plugin_map.clear(); } -#pragma mark ABI +template struct PluginInstance { + typedef Callback CallbackType; -struct ABIInstance { - ABIInstance() : name(), description(), create_callback(nullptr) {} + PluginInstance() = default; + PluginInstance(ConstString name, std::string description, + Callback create_callback = nullptr, + DebuggerInitializeCallback debugger_init_callback = nullptr) + : name(name), description(std::move(description)), + create_callback(create_callback), + debugger_init_callback(debugger_init_callback) {} ConstString name; std::string description; - ABICreateInstance create_callback; + Callback create_callback; + DebuggerInitializeCallback debugger_init_callback; }; -typedef std::vector ABIInstances; +template class PluginInstances { +public: + template + bool RegisterPlugin(ConstString name, const char *description, + typename Instance::CallbackType callback, + Args &&... args) { + if (!callback) + return false; + assert((bool)name); + Instance instance = + Instance(name, description, callback, std::forward(args)...); + m_instances.push_back(instance); + return false; + } + + bool UnregisterPlugin(typename Instance::CallbackType callback) { + if (!callback) + return false; + auto pos = m_instances.begin(); + auto end = m_instances.end(); + for (; pos != end; ++pos) { + if (pos->create_callback == callback) { + m_instances.erase(pos); + return true; + } + } + return false; + } -static std::recursive_mutex &GetABIInstancesMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} + typename Instance::CallbackType GetCallbackAtIndex(uint32_t idx) { + if (Instance *instance = GetInstanceAtIndex(idx)) + return instance->create_callback; + return nullptr; + } + + const char *GetDescriptionAtIndex(uint32_t idx) { + if (Instance *instance = GetInstanceAtIndex(idx)) + return instance->description.c_str(); + return nullptr; + } + + const char *GetNameAtIndex(uint32_t idx) { + if (Instance *instance = GetInstanceAtIndex(idx)) + return instance->name.GetCString(); + return nullptr; + } + + typename Instance::CallbackType GetCallbackForName(ConstString name) { + if (!name) + return nullptr; + for (auto &instance : m_instances) { + if (name == instance.name) + return instance.create_callback; + } + return nullptr; + } + + void PerformDebuggerCallback(Debugger &debugger) { + for (auto &instance : m_instances) { + if (instance.debugger_init_callback) + instance.debugger_init_callback(debugger); + } + } + + const std::vector &GetInstances() const { return m_instances; } + std::vector &GetInstances() { return m_instances; } + +private: + Instance *GetInstanceAtIndex(uint32_t idx) { + if (idx < m_instances.size()) + return &m_instances[idx]; + return nullptr; + } + std::vector m_instances; +}; + +#pragma mark ABI + +typedef PluginInstance ABIInstance; +typedef PluginInstances ABIInstances; static ABIInstances &GetABIInstances() { static ABIInstances g_instances; return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, - const char *description, +bool PluginManager::RegisterPlugin(ConstString name, const char *description, ABICreateInstance create_callback) { - if (create_callback) { - ABIInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - std::lock_guard guard(GetABIInstancesMutex()); - GetABIInstances().push_back(instance); - return true; - } - return false; + return GetABIInstances().RegisterPlugin(name, description, create_callback); } bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetABIInstancesMutex()); - ABIInstances &instances = GetABIInstances(); - - ABIInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetABIInstances().UnregisterPlugin(create_callback); } ABICreateInstance PluginManager::GetABICreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetABIInstancesMutex()); - ABIInstances &instances = GetABIInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -ABICreateInstance -PluginManager::GetABICreateCallbackForPluginName(ConstString name) { - if (name) { - std::lock_guard guard(GetABIInstancesMutex()); - ABIInstances &instances = GetABIInstances(); - - ABIInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetABIInstances().GetCallbackAtIndex(idx); } #pragma mark Architecture -struct ArchitectureInstance { - ConstString name; - std::string description; - PluginManager::ArchitectureCreateInstance create_callback; -}; - +typedef PluginInstance ArchitectureInstance; typedef std::vector ArchitectureInstances; -static std::mutex &GetArchitectureMutex() { - static std::mutex g_architecture_mutex; - return g_architecture_mutex; -} - static ArchitectureInstances &GetArchitectureInstances() { static ArchitectureInstances g_instances; return g_instances; @@ -298,13 +309,12 @@ static ArchitectureInstances &GetArchitectureInstances() { void PluginManager::RegisterPlugin(ConstString name, llvm::StringRef description, ArchitectureCreateInstance create_callback) { - std::lock_guard guard(GetArchitectureMutex()); - GetArchitectureInstances().push_back({name, description, create_callback}); + GetArchitectureInstances().push_back( + {name, std::string(description), create_callback}); } void PluginManager::UnregisterPlugin( ArchitectureCreateInstance create_callback) { - std::lock_guard guard(GetArchitectureMutex()); auto &instances = GetArchitectureInstances(); for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) { @@ -318,7 +328,6 @@ void PluginManager::UnregisterPlugin( std::unique_ptr PluginManager::CreateArchitectureInstance(const ArchSpec &arch) { - std::lock_guard guard(GetArchitectureMutex()); for (const auto &instances : GetArchitectureInstances()) { if (auto plugin_up = instances.create_callback(arch)) return plugin_up; @@ -328,104 +337,39 @@ PluginManager::CreateArchitectureInstance(const ArchSpec &arch) { #pragma mark Disassembler -struct DisassemblerInstance { - DisassemblerInstance() : name(), description(), create_callback(nullptr) {} - - ConstString name; - std::string description; - DisassemblerCreateInstance create_callback; -}; - -typedef std::vector DisassemblerInstances; - -static std::recursive_mutex &GetDisassemblerMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance DisassemblerInstance; +typedef PluginInstances DisassemblerInstances; static DisassemblerInstances &GetDisassemblerInstances() { static DisassemblerInstances g_instances; return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, - const char *description, +bool PluginManager::RegisterPlugin(ConstString name, const char *description, DisassemblerCreateInstance create_callback) { - if (create_callback) { - DisassemblerInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - std::lock_guard guard(GetDisassemblerMutex()); - GetDisassemblerInstances().push_back(instance); - return true; - } - return false; + return GetDisassemblerInstances().RegisterPlugin(name, description, + create_callback); } bool PluginManager::UnregisterPlugin( DisassemblerCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetDisassemblerMutex()); - DisassemblerInstances &instances = GetDisassemblerInstances(); - - DisassemblerInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetDisassemblerInstances().UnregisterPlugin(create_callback); } DisassemblerCreateInstance PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetDisassemblerMutex()); - DisassemblerInstances &instances = GetDisassemblerInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; + return GetDisassemblerInstances().GetCallbackAtIndex(idx); } DisassemblerCreateInstance -PluginManager::GetDisassemblerCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard guard(GetDisassemblerMutex()); - DisassemblerInstances &instances = GetDisassemblerInstances(); - - DisassemblerInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; +PluginManager::GetDisassemblerCreateCallbackForPluginName(ConstString name) { + return GetDisassemblerInstances().GetCallbackForName(name); } #pragma mark DynamicLoader -struct DynamicLoaderInstance { - DynamicLoaderInstance() - : name(), description(), create_callback(nullptr), - debugger_init_callback(nullptr) {} - - ConstString name; - std::string description; - DynamicLoaderCreateInstance create_callback; - DebuggerInitializeCallback debugger_init_callback; -}; - -typedef std::vector DynamicLoaderInstances; - -static std::recursive_mutex &GetDynamicLoaderMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance DynamicLoaderInstance; +typedef PluginInstances DynamicLoaderInstances; static DynamicLoaderInstances &GetDynamicLoaderInstances() { static DynamicLoaderInstances g_instances; @@ -436,81 +380,29 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, DynamicLoaderCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { - if (create_callback) { - DynamicLoaderInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.debugger_init_callback = debugger_init_callback; - std::lock_guard guard(GetDynamicLoaderMutex()); - GetDynamicLoaderInstances().push_back(instance); - } - return false; + return GetDynamicLoaderInstances().RegisterPlugin( + name, description, create_callback, debugger_init_callback); } bool PluginManager::UnregisterPlugin( DynamicLoaderCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetDynamicLoaderMutex()); - DynamicLoaderInstances &instances = GetDynamicLoaderInstances(); - - DynamicLoaderInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetDynamicLoaderInstances().UnregisterPlugin(create_callback); } DynamicLoaderCreateInstance PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetDynamicLoaderMutex()); - DynamicLoaderInstances &instances = GetDynamicLoaderInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; + return GetDynamicLoaderInstances().GetCallbackAtIndex(idx); } DynamicLoaderCreateInstance -PluginManager::GetDynamicLoaderCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard guard(GetDynamicLoaderMutex()); - DynamicLoaderInstances &instances = GetDynamicLoaderInstances(); - - DynamicLoaderInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; +PluginManager::GetDynamicLoaderCreateCallbackForPluginName(ConstString name) { + return GetDynamicLoaderInstances().GetCallbackForName(name); } #pragma mark JITLoader -struct JITLoaderInstance { - JITLoaderInstance() - : name(), description(), create_callback(nullptr), - debugger_init_callback(nullptr) {} - - ConstString name; - std::string description; - JITLoaderCreateInstance create_callback; - DebuggerInitializeCallback debugger_init_callback; -}; - -typedef std::vector JITLoaderInstances; - -static std::recursive_mutex &GetJITLoaderMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance JITLoaderInstance; +typedef PluginInstances JITLoaderInstances; static JITLoaderInstances &GetJITLoaderInstances() { static JITLoaderInstances g_instances; @@ -521,77 +413,24 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, JITLoaderCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { - if (create_callback) { - JITLoaderInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.debugger_init_callback = debugger_init_callback; - std::lock_guard guard(GetJITLoaderMutex()); - GetJITLoaderInstances().push_back(instance); - } - return false; + return GetJITLoaderInstances().RegisterPlugin( + name, description, create_callback, debugger_init_callback); } bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetJITLoaderMutex()); - JITLoaderInstances &instances = GetJITLoaderInstances(); - - JITLoaderInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetJITLoaderInstances().UnregisterPlugin(create_callback); } JITLoaderCreateInstance PluginManager::GetJITLoaderCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetJITLoaderMutex()); - JITLoaderInstances &instances = GetJITLoaderInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -JITLoaderCreateInstance PluginManager::GetJITLoaderCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard guard(GetJITLoaderMutex()); - JITLoaderInstances &instances = GetJITLoaderInstances(); - - JITLoaderInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetJITLoaderInstances().GetCallbackAtIndex(idx); } #pragma mark EmulateInstruction -struct EmulateInstructionInstance { - EmulateInstructionInstance() - : name(), description(), create_callback(nullptr) {} - - ConstString name; - std::string description; - EmulateInstructionCreateInstance create_callback; -}; - -typedef std::vector EmulateInstructionInstances; - -static std::recursive_mutex &GetEmulateInstructionMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance + EmulateInstructionInstance; +typedef PluginInstances EmulateInstructionInstances; static EmulateInstructionInstances &GetEmulateInstructionInstances() { static EmulateInstructionInstances g_instances; @@ -601,80 +440,30 @@ static EmulateInstructionInstances &GetEmulateInstructionInstances() { bool PluginManager::RegisterPlugin( ConstString name, const char *description, EmulateInstructionCreateInstance create_callback) { - if (create_callback) { - EmulateInstructionInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - std::lock_guard guard(GetEmulateInstructionMutex()); - GetEmulateInstructionInstances().push_back(instance); - } - return false; + return GetEmulateInstructionInstances().RegisterPlugin(name, description, + create_callback); } bool PluginManager::UnregisterPlugin( EmulateInstructionCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetEmulateInstructionMutex()); - EmulateInstructionInstances &instances = GetEmulateInstructionInstances(); - - EmulateInstructionInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetEmulateInstructionInstances().UnregisterPlugin(create_callback); } EmulateInstructionCreateInstance PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetEmulateInstructionMutex()); - EmulateInstructionInstances &instances = GetEmulateInstructionInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; + return GetEmulateInstructionInstances().GetCallbackAtIndex(idx); } EmulateInstructionCreateInstance PluginManager::GetEmulateInstructionCreateCallbackForPluginName( ConstString name) { - if (name) { - std::lock_guard guard(GetEmulateInstructionMutex()); - EmulateInstructionInstances &instances = GetEmulateInstructionInstances(); - - EmulateInstructionInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetEmulateInstructionInstances().GetCallbackForName(name); } #pragma mark OperatingSystem -struct OperatingSystemInstance { - OperatingSystemInstance() - : name(), description(), create_callback(nullptr), - debugger_init_callback(nullptr) {} - - ConstString name; - std::string description; - OperatingSystemCreateInstance create_callback; - DebuggerInitializeCallback debugger_init_callback; -}; - -typedef std::vector OperatingSystemInstances; - -static std::recursive_mutex &GetOperatingSystemMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance OperatingSystemInstance; +typedef PluginInstances OperatingSystemInstances; static OperatingSystemInstances &GetOperatingSystemInstances() { static OperatingSystemInstances g_instances; @@ -685,158 +474,70 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, OperatingSystemCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { - if (create_callback) { - OperatingSystemInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.debugger_init_callback = debugger_init_callback; - std::lock_guard guard(GetOperatingSystemMutex()); - GetOperatingSystemInstances().push_back(instance); - } - return false; + return GetOperatingSystemInstances().RegisterPlugin( + name, description, create_callback, debugger_init_callback); } bool PluginManager::UnregisterPlugin( OperatingSystemCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetOperatingSystemMutex()); - OperatingSystemInstances &instances = GetOperatingSystemInstances(); - - OperatingSystemInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetOperatingSystemInstances().UnregisterPlugin(create_callback); } OperatingSystemCreateInstance PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetOperatingSystemMutex()); - OperatingSystemInstances &instances = GetOperatingSystemInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; + return GetOperatingSystemInstances().GetCallbackAtIndex(idx); } OperatingSystemCreateInstance -PluginManager::GetOperatingSystemCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard guard(GetOperatingSystemMutex()); - OperatingSystemInstances &instances = GetOperatingSystemInstances(); - - OperatingSystemInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; +PluginManager::GetOperatingSystemCreateCallbackForPluginName(ConstString name) { + return GetOperatingSystemInstances().GetCallbackForName(name); } #pragma mark Language -struct LanguageInstance { - LanguageInstance() : name(), description(), create_callback(nullptr) {} - - ConstString name; - std::string description; - LanguageCreateInstance create_callback; -}; - -typedef std::vector LanguageInstances; - -static std::recursive_mutex &GetLanguageMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance LanguageInstance; +typedef PluginInstances LanguageInstances; static LanguageInstances &GetLanguageInstances() { static LanguageInstances g_instances; return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, - const char *description, +bool PluginManager::RegisterPlugin(ConstString name, const char *description, LanguageCreateInstance create_callback) { - if (create_callback) { - LanguageInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - std::lock_guard guard(GetLanguageMutex()); - GetLanguageInstances().push_back(instance); - } - return false; + return GetLanguageInstances().RegisterPlugin(name, description, + create_callback); } bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetLanguageMutex()); - LanguageInstances &instances = GetLanguageInstances(); - - LanguageInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetLanguageInstances().UnregisterPlugin(create_callback); } LanguageCreateInstance PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetLanguageMutex()); - LanguageInstances &instances = GetLanguageInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -LanguageCreateInstance -PluginManager::GetLanguageCreateCallbackForPluginName(ConstString name) { - if (name) { - std::lock_guard guard(GetLanguageMutex()); - LanguageInstances &instances = GetLanguageInstances(); - - LanguageInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetLanguageInstances().GetCallbackAtIndex(idx); } #pragma mark LanguageRuntime -struct LanguageRuntimeInstance { - LanguageRuntimeInstance() : name(), description(), create_callback(nullptr) {} +struct LanguageRuntimeInstance + : public PluginInstance { + LanguageRuntimeInstance( + ConstString name, std::string description, CallbackType create_callback, + DebuggerInitializeCallback debugger_init_callback, + LanguageRuntimeGetCommandObject command_callback, + LanguageRuntimeGetExceptionPrecondition precondition_callback) + : PluginInstance( + name, std::move(description), create_callback, + debugger_init_callback), + command_callback(command_callback), + precondition_callback(precondition_callback) {} - ConstString name; - std::string description; - LanguageRuntimeCreateInstance create_callback; LanguageRuntimeGetCommandObject command_callback; LanguageRuntimeGetExceptionPrecondition precondition_callback; }; -typedef std::vector LanguageRuntimeInstances; - -static std::recursive_mutex &GetLanguageRuntimeMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstances LanguageRuntimeInstances; static LanguageRuntimeInstances &GetLanguageRuntimeInstances() { static LanguageRuntimeInstances g_instances; @@ -848,51 +549,24 @@ bool PluginManager::RegisterPlugin( LanguageRuntimeCreateInstance create_callback, LanguageRuntimeGetCommandObject command_callback, LanguageRuntimeGetExceptionPrecondition precondition_callback) { - if (create_callback) { - LanguageRuntimeInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.command_callback = command_callback; - instance.precondition_callback = precondition_callback; - std::lock_guard guard(GetLanguageRuntimeMutex()); - GetLanguageRuntimeInstances().push_back(instance); - } - return false; + return GetLanguageRuntimeInstances().RegisterPlugin( + name, description, create_callback, nullptr, command_callback, + precondition_callback); } bool PluginManager::UnregisterPlugin( LanguageRuntimeCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetLanguageRuntimeMutex()); - LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); - - LanguageRuntimeInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetLanguageRuntimeInstances().UnregisterPlugin(create_callback); } LanguageRuntimeCreateInstance PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetLanguageRuntimeMutex()); - LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; + return GetLanguageRuntimeInstances().GetCallbackAtIndex(idx); } LanguageRuntimeGetCommandObject PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) { - std::lock_guard guard(GetLanguageRuntimeMutex()); - LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); + const auto &instances = GetLanguageRuntimeInstances().GetInstances(); if (idx < instances.size()) return instances[idx].command_callback; return nullptr; @@ -900,45 +574,16 @@ PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) { LanguageRuntimeGetExceptionPrecondition PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx) { - std::lock_guard guard(GetLanguageRuntimeMutex()); - LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); + const auto &instances = GetLanguageRuntimeInstances().GetInstances(); if (idx < instances.size()) return instances[idx].precondition_callback; return nullptr; } -LanguageRuntimeCreateInstance -PluginManager::GetLanguageRuntimeCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard guard(GetLanguageRuntimeMutex()); - LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); - - LanguageRuntimeInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; -} - #pragma mark SystemRuntime -struct SystemRuntimeInstance { - SystemRuntimeInstance() : name(), description(), create_callback(nullptr) {} - - ConstString name; - std::string description; - SystemRuntimeCreateInstance create_callback; -}; - -typedef std::vector SystemRuntimeInstances; - -static std::recursive_mutex &GetSystemRuntimeMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance SystemRuntimeInstance; +typedef PluginInstances SystemRuntimeInstances; static SystemRuntimeInstances &GetSystemRuntimeInstances() { static SystemRuntimeInstances g_instances; @@ -948,83 +593,39 @@ static SystemRuntimeInstances &GetSystemRuntimeInstances() { bool PluginManager::RegisterPlugin( ConstString name, const char *description, SystemRuntimeCreateInstance create_callback) { - if (create_callback) { - SystemRuntimeInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - std::lock_guard guard(GetSystemRuntimeMutex()); - GetSystemRuntimeInstances().push_back(instance); - } - return false; + return GetSystemRuntimeInstances().RegisterPlugin(name, description, + create_callback); } bool PluginManager::UnregisterPlugin( SystemRuntimeCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetSystemRuntimeMutex()); - SystemRuntimeInstances &instances = GetSystemRuntimeInstances(); - - SystemRuntimeInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetSystemRuntimeInstances().UnregisterPlugin(create_callback); } SystemRuntimeCreateInstance PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetSystemRuntimeMutex()); - SystemRuntimeInstances &instances = GetSystemRuntimeInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -SystemRuntimeCreateInstance -PluginManager::GetSystemRuntimeCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard guard(GetSystemRuntimeMutex()); - SystemRuntimeInstances &instances = GetSystemRuntimeInstances(); - - SystemRuntimeInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetSystemRuntimeInstances().GetCallbackAtIndex(idx); } #pragma mark ObjectFile -struct ObjectFileInstance { - ObjectFileInstance() - : name(), description(), create_callback(nullptr), - create_memory_callback(nullptr), get_module_specifications(nullptr), - save_core(nullptr) {} +struct ObjectFileInstance : public PluginInstance { + ObjectFileInstance( + ConstString name, std::string description, CallbackType create_callback, + ObjectFileCreateMemoryInstance create_memory_callback, + ObjectFileGetModuleSpecifications get_module_specifications, + ObjectFileSaveCore save_core) + : PluginInstance(name, std::move(description), + create_callback), + create_memory_callback(create_memory_callback), + get_module_specifications(get_module_specifications), + save_core(save_core) {} - ConstString name; - std::string description; - ObjectFileCreateInstance create_callback; ObjectFileCreateMemoryInstance create_memory_callback; ObjectFileGetModuleSpecifications get_module_specifications; ObjectFileSaveCore save_core; }; - -typedef std::vector ObjectFileInstances; - -static std::recursive_mutex &GetObjectFileMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstances ObjectFileInstances; static ObjectFileInstances &GetObjectFileInstances() { static ObjectFileInstances g_instances; @@ -1037,51 +638,23 @@ bool PluginManager::RegisterPlugin( ObjectFileCreateMemoryInstance create_memory_callback, ObjectFileGetModuleSpecifications get_module_specifications, ObjectFileSaveCore save_core) { - if (create_callback) { - ObjectFileInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.create_memory_callback = create_memory_callback; - instance.save_core = save_core; - instance.get_module_specifications = get_module_specifications; - std::lock_guard guard(GetObjectFileMutex()); - GetObjectFileInstances().push_back(instance); - } - return false; + return GetObjectFileInstances().RegisterPlugin( + name, description, create_callback, create_memory_callback, + get_module_specifications, save_core); } bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetObjectFileMutex()); - ObjectFileInstances &instances = GetObjectFileInstances(); - - ObjectFileInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetObjectFileInstances().UnregisterPlugin(create_callback); } ObjectFileCreateInstance PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetObjectFileMutex()); - ObjectFileInstances &instances = GetObjectFileInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; + return GetObjectFileInstances().GetCallbackAtIndex(idx); } ObjectFileCreateMemoryInstance PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetObjectFileMutex()); - ObjectFileInstances &instances = GetObjectFileInstances(); + const auto &instances = GetObjectFileInstances().GetInstances(); if (idx < instances.size()) return instances[idx].create_memory_callback; return nullptr; @@ -1090,41 +663,21 @@ PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) { ObjectFileGetModuleSpecifications PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex( uint32_t idx) { - std::lock_guard guard(GetObjectFileMutex()); - ObjectFileInstances &instances = GetObjectFileInstances(); + const auto &instances = GetObjectFileInstances().GetInstances(); if (idx < instances.size()) return instances[idx].get_module_specifications; return nullptr; } -ObjectFileCreateInstance -PluginManager::GetObjectFileCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard guard(GetObjectFileMutex()); - ObjectFileInstances &instances = GetObjectFileInstances(); - - ObjectFileInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; -} - ObjectFileCreateMemoryInstance PluginManager::GetObjectFileCreateMemoryCallbackForPluginName( ConstString name) { - if (name) { - std::lock_guard guard(GetObjectFileMutex()); - ObjectFileInstances &instances = GetObjectFileInstances(); - - ObjectFileInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_memory_callback; - } + if (!name) + return nullptr; + const auto &instances = GetObjectFileInstances().GetInstances(); + for (auto &instance : instances) { + if (instance.name == name) + return instance.create_memory_callback; } return nullptr; } @@ -1132,12 +685,9 @@ PluginManager::GetObjectFileCreateMemoryCallbackForPluginName( Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp, const FileSpec &outfile) { Status error; - std::lock_guard guard(GetObjectFileMutex()); - ObjectFileInstances &instances = GetObjectFileInstances(); - - ObjectFileInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->save_core && pos->save_core(process_sp, outfile, error)) + auto &instances = GetObjectFileInstances().GetInstances(); + for (auto &instance : instances) { + if (instance.save_core && instance.save_core(process_sp, outfile, error)) return error; } error.SetErrorString( @@ -1147,23 +697,18 @@ Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp, #pragma mark ObjectContainer -struct ObjectContainerInstance { - ObjectContainerInstance() - : name(), description(), create_callback(nullptr), - get_module_specifications(nullptr) {} +struct ObjectContainerInstance + : public PluginInstance { + ObjectContainerInstance( + ConstString name, std::string description, CallbackType create_callback, + ObjectFileGetModuleSpecifications get_module_specifications) + : PluginInstance( + name, std::move(description), create_callback), + get_module_specifications(get_module_specifications) {} - ConstString name; - std::string description; - ObjectContainerCreateInstance create_callback; ObjectFileGetModuleSpecifications get_module_specifications; }; - -typedef std::vector ObjectContainerInstances; - -static std::recursive_mutex &GetObjectContainerMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstances ObjectContainerInstances; static ObjectContainerInstances &GetObjectContainerInstances() { static ObjectContainerInstances g_instances; @@ -1174,67 +719,24 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, ObjectContainerCreateInstance create_callback, ObjectFileGetModuleSpecifications get_module_specifications) { - if (create_callback) { - ObjectContainerInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.get_module_specifications = get_module_specifications; - std::lock_guard guard(GetObjectContainerMutex()); - GetObjectContainerInstances().push_back(instance); - } - return false; + return GetObjectContainerInstances().RegisterPlugin( + name, description, create_callback, get_module_specifications); } bool PluginManager::UnregisterPlugin( ObjectContainerCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetObjectContainerMutex()); - ObjectContainerInstances &instances = GetObjectContainerInstances(); - - ObjectContainerInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetObjectContainerInstances().UnregisterPlugin(create_callback); } ObjectContainerCreateInstance PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetObjectContainerMutex()); - ObjectContainerInstances &instances = GetObjectContainerInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -ObjectContainerCreateInstance -PluginManager::GetObjectContainerCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard guard(GetObjectContainerMutex()); - ObjectContainerInstances &instances = GetObjectContainerInstances(); - - ObjectContainerInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetObjectContainerInstances().GetCallbackAtIndex(idx); } ObjectFileGetModuleSpecifications PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex( uint32_t idx) { - std::lock_guard guard(GetObjectContainerMutex()); - ObjectContainerInstances &instances = GetObjectContainerInstances(); + const auto &instances = GetObjectContainerInstances().GetInstances(); if (idx < instances.size()) return instances[idx].get_module_specifications; return nullptr; @@ -1242,23 +744,8 @@ PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex( #pragma mark Platform -struct PlatformInstance { - PlatformInstance() - : name(), description(), create_callback(nullptr), - debugger_init_callback(nullptr) {} - - ConstString name; - std::string description; - PlatformCreateInstance create_callback; - DebuggerInitializeCallback debugger_init_callback; -}; - -typedef std::vector PlatformInstances; - -static std::recursive_mutex &GetPlatformInstancesMutex() { - static std::recursive_mutex g_platform_instances_mutex; - return g_platform_instances_mutex; -} +typedef PluginInstance PlatformInstance; +typedef PluginInstances PlatformInstances; static PlatformInstances &GetPlatformInstances() { static PlatformInstances g_platform_instances; @@ -1269,114 +756,44 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, PlatformCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { - if (create_callback) { - std::lock_guard guard(GetPlatformInstancesMutex()); + return GetPlatformInstances().RegisterPlugin( + name, description, create_callback, debugger_init_callback); +} - PlatformInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.debugger_init_callback = debugger_init_callback; - GetPlatformInstances().push_back(instance); - return true; - } - return false; +bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) { + return GetPlatformInstances().UnregisterPlugin(create_callback); } const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) { - std::lock_guard guard(GetPlatformInstancesMutex()); - PlatformInstances &instances = GetPlatformInstances(); - if (idx < instances.size()) - return instances[idx].name.GetCString(); - return nullptr; + return GetPlatformInstances().GetNameAtIndex(idx); } const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) { - std::lock_guard guard(GetPlatformInstancesMutex()); - PlatformInstances &instances = GetPlatformInstances(); - if (idx < instances.size()) - return instances[idx].description.c_str(); - return nullptr; -} - -bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetPlatformInstancesMutex()); - PlatformInstances &instances = GetPlatformInstances(); - - PlatformInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetPlatformInstances().GetDescriptionAtIndex(idx); } PlatformCreateInstance PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetPlatformInstancesMutex()); - PlatformInstances &instances = GetPlatformInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; + return GetPlatformInstances().GetCallbackAtIndex(idx); } PlatformCreateInstance PluginManager::GetPlatformCreateCallbackForPluginName(ConstString name) { - if (name) { - std::lock_guard guard(GetPlatformInstancesMutex()); - PlatformInstances &instances = GetPlatformInstances(); - - PlatformInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetPlatformInstances().GetCallbackForName(name); } void PluginManager::AutoCompletePlatformName(llvm::StringRef name, - CompletionRequest &request) { - if (name.empty()) - return; - - std::lock_guard guard(GetPlatformInstancesMutex()); - PlatformInstances &instances = GetPlatformInstances(); - llvm::StringRef name_sref(name); - - PlatformInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - llvm::StringRef plugin_name(pos->name.GetCString()); - if (plugin_name.startswith(name_sref)) - request.AddCompletion(plugin_name.data()); - } -} - -#pragma mark Process - -struct ProcessInstance { - ProcessInstance() - : name(), description(), create_callback(nullptr), - debugger_init_callback(nullptr) {} - - ConstString name; - std::string description; - ProcessCreateInstance create_callback; - DebuggerInitializeCallback debugger_init_callback; -}; + CompletionRequest &request) { + for (const auto &instance : GetPlatformInstances().GetInstances()) { + if (instance.name.GetStringRef().startswith(name)) + request.AddCompletion(instance.name.GetCString()); + } +} -typedef std::vector ProcessInstances; +#pragma mark Process -static std::recursive_mutex &GetProcessMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance ProcessInstance; +typedef PluginInstances ProcessInstances; static ProcessInstances &GetProcessInstances() { static ProcessInstances g_instances; @@ -1387,95 +804,55 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, ProcessCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { - if (create_callback) { - ProcessInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.debugger_init_callback = debugger_init_callback; - std::lock_guard guard(GetProcessMutex()); - GetProcessInstances().push_back(instance); - } - return false; + return GetProcessInstances().RegisterPlugin( + name, description, create_callback, debugger_init_callback); } -const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) { - std::lock_guard guard(GetProcessMutex()); - ProcessInstances &instances = GetProcessInstances(); - if (idx < instances.size()) - return instances[idx].name.GetCString(); - return nullptr; +bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) { + return GetProcessInstances().UnregisterPlugin(create_callback); } -const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) { - std::lock_guard guard(GetProcessMutex()); - ProcessInstances &instances = GetProcessInstances(); - if (idx < instances.size()) - return instances[idx].description.c_str(); - return nullptr; +const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) { + return GetProcessInstances().GetNameAtIndex(idx); } -bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetProcessMutex()); - ProcessInstances &instances = GetProcessInstances(); - - ProcessInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; +const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) { + return GetProcessInstances().GetDescriptionAtIndex(idx); } ProcessCreateInstance PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetProcessMutex()); - ProcessInstances &instances = GetProcessInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; + return GetProcessInstances().GetCallbackAtIndex(idx); } ProcessCreateInstance PluginManager::GetProcessCreateCallbackForPluginName(ConstString name) { - if (name) { - std::lock_guard guard(GetProcessMutex()); - ProcessInstances &instances = GetProcessInstances(); - - ProcessInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } + return GetProcessInstances().GetCallbackForName(name); +} + +void PluginManager::AutoCompleteProcessName(llvm::StringRef name, + CompletionRequest &request) { + for (const auto &instance : GetProcessInstances().GetInstances()) { + if (instance.name.GetStringRef().startswith(name)) + request.AddCompletion(instance.name.GetCString(), instance.description); } - return nullptr; } #pragma mark ScriptInterpreter -struct ScriptInterpreterInstance { - ScriptInterpreterInstance() - : name(), language(lldb::eScriptLanguageNone), description(), - create_callback(nullptr) {} +struct ScriptInterpreterInstance + : public PluginInstance { + ScriptInterpreterInstance(ConstString name, std::string description, + CallbackType create_callback, + lldb::ScriptLanguage language) + : PluginInstance( + name, std::move(description), create_callback), + language(language) {} - ConstString name; - lldb::ScriptLanguage language; - std::string description; - ScriptInterpreterCreateInstance create_callback; + lldb::ScriptLanguage language = lldb::eScriptLanguageNone; }; -typedef std::vector ScriptInterpreterInstances; - -static std::recursive_mutex &GetScriptInterpreterMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstances ScriptInterpreterInstances; static ScriptInterpreterInstances &GetScriptInterpreterInstances() { static ScriptInterpreterInstances g_instances; @@ -1486,61 +863,31 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, lldb::ScriptLanguage script_language, ScriptInterpreterCreateInstance create_callback) { - if (!create_callback) - return false; - ScriptInterpreterInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.language = script_language; - std::lock_guard guard(GetScriptInterpreterMutex()); - GetScriptInterpreterInstances().push_back(instance); - return false; + return GetScriptInterpreterInstances().RegisterPlugin( + name, description, create_callback, script_language); } bool PluginManager::UnregisterPlugin( ScriptInterpreterCreateInstance create_callback) { - if (!create_callback) - return false; - std::lock_guard guard(GetScriptInterpreterMutex()); - ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); - - ScriptInterpreterInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback != create_callback) - continue; - - instances.erase(pos); - return true; - } - return false; + return GetScriptInterpreterInstances().UnregisterPlugin(create_callback); } ScriptInterpreterCreateInstance PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetScriptInterpreterMutex()); - ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; + return GetScriptInterpreterInstances().GetCallbackAtIndex(idx); } lldb::ScriptInterpreterSP PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, Debugger &debugger) { - std::lock_guard guard(GetScriptInterpreterMutex()); - ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); - - ScriptInterpreterInstances::iterator pos, end = instances.end(); + const auto &instances = GetScriptInterpreterInstances().GetInstances(); ScriptInterpreterCreateInstance none_instance = nullptr; - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->language == lldb::eScriptLanguageNone) - none_instance = pos->create_callback; + for (const auto &instance : instances) { + if (instance.language == lldb::eScriptLanguageNone) + none_instance = instance.create_callback; - if (script_lang == pos->language) - return pos->create_callback(debugger); + if (script_lang == instance.language) + return instance.create_callback(debugger); } // If we didn't find one, return the ScriptInterpreter for the null language. @@ -1548,29 +895,24 @@ PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, return none_instance(debugger); } -#pragma mark - #pragma mark StructuredDataPlugin -// StructuredDataPlugin - -struct StructuredDataPluginInstance { - StructuredDataPluginInstance() - : name(), description(), create_callback(nullptr), - debugger_init_callback(nullptr), filter_callback(nullptr) {} - - ConstString name; - std::string description; - StructuredDataPluginCreateInstance create_callback; - DebuggerInitializeCallback debugger_init_callback; - StructuredDataFilterLaunchInfo filter_callback; +struct StructuredDataPluginInstance + : public PluginInstance { + StructuredDataPluginInstance( + ConstString name, std::string description, CallbackType create_callback, + DebuggerInitializeCallback debugger_init_callback, + StructuredDataFilterLaunchInfo filter_callback) + : PluginInstance( + name, std::move(description), create_callback, + debugger_init_callback), + filter_callback(filter_callback) {} + + StructuredDataFilterLaunchInfo filter_callback = nullptr; }; -typedef std::vector StructuredDataPluginInstances; - -static std::recursive_mutex &GetStructuredDataPluginMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstances + StructuredDataPluginInstances; static StructuredDataPluginInstances &GetStructuredDataPluginInstances() { static StructuredDataPluginInstances g_instances; @@ -1582,70 +924,25 @@ bool PluginManager::RegisterPlugin( StructuredDataPluginCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback, StructuredDataFilterLaunchInfo filter_callback) { - if (create_callback) { - StructuredDataPluginInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.debugger_init_callback = debugger_init_callback; - instance.filter_callback = filter_callback; - std::lock_guard guard(GetStructuredDataPluginMutex()); - GetStructuredDataPluginInstances().push_back(instance); - } - return false; + return GetStructuredDataPluginInstances().RegisterPlugin( + name, description, create_callback, debugger_init_callback, + filter_callback); } bool PluginManager::UnregisterPlugin( StructuredDataPluginCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetStructuredDataPluginMutex()); - StructuredDataPluginInstances &instances = - GetStructuredDataPluginInstances(); - - StructuredDataPluginInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetStructuredDataPluginInstances().UnregisterPlugin(create_callback); } StructuredDataPluginCreateInstance PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetStructuredDataPluginMutex()); - StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -StructuredDataPluginCreateInstance -PluginManager::GetStructuredDataPluginCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard guard(GetStructuredDataPluginMutex()); - StructuredDataPluginInstances &instances = - GetStructuredDataPluginInstances(); - - StructuredDataPluginInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetStructuredDataPluginInstances().GetCallbackAtIndex(idx); } StructuredDataFilterLaunchInfo PluginManager::GetStructuredDataFilterCallbackAtIndex( uint32_t idx, bool &iteration_complete) { - std::lock_guard guard(GetStructuredDataPluginMutex()); - StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances(); + const auto &instances = GetStructuredDataPluginInstances().GetInstances(); if (idx < instances.size()) { iteration_complete = false; return instances[idx].filter_callback; @@ -1657,23 +954,8 @@ PluginManager::GetStructuredDataFilterCallbackAtIndex( #pragma mark SymbolFile -struct SymbolFileInstance { - SymbolFileInstance() - : name(), description(), create_callback(nullptr), - debugger_init_callback(nullptr) {} - - ConstString name; - std::string description; - SymbolFileCreateInstance create_callback; - DebuggerInitializeCallback debugger_init_callback; -}; - -typedef std::vector SymbolFileInstances; - -static std::recursive_mutex &GetSymbolFileMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance SymbolFileInstance; +typedef PluginInstances SymbolFileInstances; static SymbolFileInstances &GetSymbolFileInstances() { static SymbolFileInstances g_instances; @@ -1684,157 +966,49 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, SymbolFileCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { - if (create_callback) { - SymbolFileInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.debugger_init_callback = debugger_init_callback; - std::lock_guard guard(GetSymbolFileMutex()); - GetSymbolFileInstances().push_back(instance); - } - return false; + return GetSymbolFileInstances().RegisterPlugin( + name, description, create_callback, debugger_init_callback); } bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetSymbolFileMutex()); - SymbolFileInstances &instances = GetSymbolFileInstances(); - - SymbolFileInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetSymbolFileInstances().UnregisterPlugin(create_callback); } SymbolFileCreateInstance PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetSymbolFileMutex()); - SymbolFileInstances &instances = GetSymbolFileInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -SymbolFileCreateInstance -PluginManager::GetSymbolFileCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard guard(GetSymbolFileMutex()); - SymbolFileInstances &instances = GetSymbolFileInstances(); - - SymbolFileInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetSymbolFileInstances().GetCallbackAtIndex(idx); } #pragma mark SymbolVendor -struct SymbolVendorInstance { - SymbolVendorInstance() : name(), description(), create_callback(nullptr) {} - - ConstString name; - std::string description; - SymbolVendorCreateInstance create_callback; -}; - -typedef std::vector SymbolVendorInstances; - -static std::recursive_mutex &GetSymbolVendorMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance SymbolVendorInstance; +typedef PluginInstances SymbolVendorInstances; static SymbolVendorInstances &GetSymbolVendorInstances() { static SymbolVendorInstances g_instances; return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, - const char *description, +bool PluginManager::RegisterPlugin(ConstString name, const char *description, SymbolVendorCreateInstance create_callback) { - if (create_callback) { - SymbolVendorInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - std::lock_guard guard(GetSymbolVendorMutex()); - GetSymbolVendorInstances().push_back(instance); - } - return false; + return GetSymbolVendorInstances().RegisterPlugin(name, description, + create_callback); } bool PluginManager::UnregisterPlugin( SymbolVendorCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetSymbolVendorMutex()); - SymbolVendorInstances &instances = GetSymbolVendorInstances(); - - SymbolVendorInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetSymbolVendorInstances().UnregisterPlugin(create_callback); } SymbolVendorCreateInstance PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetSymbolVendorMutex()); - SymbolVendorInstances &instances = GetSymbolVendorInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -SymbolVendorCreateInstance -PluginManager::GetSymbolVendorCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard guard(GetSymbolVendorMutex()); - SymbolVendorInstances &instances = GetSymbolVendorInstances(); - - SymbolVendorInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetSymbolVendorInstances().GetCallbackAtIndex(idx); } #pragma mark UnwindAssembly -struct UnwindAssemblyInstance { - UnwindAssemblyInstance() : name(), description(), create_callback(nullptr) {} - - ConstString name; - std::string description; - UnwindAssemblyCreateInstance create_callback; -}; - -typedef std::vector UnwindAssemblyInstances; - -static std::recursive_mutex &GetUnwindAssemblyMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance UnwindAssemblyInstance; +typedef PluginInstances UnwindAssemblyInstances; static UnwindAssemblyInstances &GetUnwindAssemblyInstances() { static UnwindAssemblyInstances g_instances; @@ -1844,77 +1018,24 @@ static UnwindAssemblyInstances &GetUnwindAssemblyInstances() { bool PluginManager::RegisterPlugin( ConstString name, const char *description, UnwindAssemblyCreateInstance create_callback) { - if (create_callback) { - UnwindAssemblyInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - std::lock_guard guard(GetUnwindAssemblyMutex()); - GetUnwindAssemblyInstances().push_back(instance); - } - return false; + return GetUnwindAssemblyInstances().RegisterPlugin(name, description, + create_callback); } bool PluginManager::UnregisterPlugin( UnwindAssemblyCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetUnwindAssemblyMutex()); - UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances(); - - UnwindAssemblyInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetUnwindAssemblyInstances().UnregisterPlugin(create_callback); } UnwindAssemblyCreateInstance PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetUnwindAssemblyMutex()); - UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -UnwindAssemblyCreateInstance -PluginManager::GetUnwindAssemblyCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard guard(GetUnwindAssemblyMutex()); - UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances(); - - UnwindAssemblyInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetUnwindAssemblyInstances().GetCallbackAtIndex(idx); } #pragma mark MemoryHistory -struct MemoryHistoryInstance { - MemoryHistoryInstance() : name(), description(), create_callback(nullptr) {} - - ConstString name; - std::string description; - MemoryHistoryCreateInstance create_callback; -}; - -typedef std::vector MemoryHistoryInstances; - -static std::recursive_mutex &GetMemoryHistoryMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance MemoryHistoryInstance; +typedef PluginInstances MemoryHistoryInstances; static MemoryHistoryInstances &GetMemoryHistoryInstances() { static MemoryHistoryInstances g_instances; @@ -1924,81 +1045,37 @@ static MemoryHistoryInstances &GetMemoryHistoryInstances() { bool PluginManager::RegisterPlugin( ConstString name, const char *description, MemoryHistoryCreateInstance create_callback) { - if (create_callback) { - MemoryHistoryInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - std::lock_guard guard(GetMemoryHistoryMutex()); - GetMemoryHistoryInstances().push_back(instance); - } - return false; + return GetMemoryHistoryInstances().RegisterPlugin(name, description, + create_callback); } bool PluginManager::UnregisterPlugin( MemoryHistoryCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetMemoryHistoryMutex()); - MemoryHistoryInstances &instances = GetMemoryHistoryInstances(); - - MemoryHistoryInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetMemoryHistoryInstances().UnregisterPlugin(create_callback); } MemoryHistoryCreateInstance PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetMemoryHistoryMutex()); - MemoryHistoryInstances &instances = GetMemoryHistoryInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -MemoryHistoryCreateInstance -PluginManager::GetMemoryHistoryCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard guard(GetMemoryHistoryMutex()); - MemoryHistoryInstances &instances = GetMemoryHistoryInstances(); - - MemoryHistoryInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetMemoryHistoryInstances().GetCallbackAtIndex(idx); } #pragma mark InstrumentationRuntime -struct InstrumentationRuntimeInstance { - InstrumentationRuntimeInstance() - : name(), description(), create_callback(nullptr) {} +struct InstrumentationRuntimeInstance + : public PluginInstance { + InstrumentationRuntimeInstance( + ConstString name, std::string description, CallbackType create_callback, + InstrumentationRuntimeGetType get_type_callback) + : PluginInstance( + name, std::move(description), create_callback), + get_type_callback(get_type_callback) {} - ConstString name; - std::string description; - InstrumentationRuntimeCreateInstance create_callback; - InstrumentationRuntimeGetType get_type_callback; + InstrumentationRuntimeGetType get_type_callback = nullptr; }; -typedef std::vector +typedef PluginInstances InstrumentationRuntimeInstances; -static std::recursive_mutex &GetInstrumentationRuntimeMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} - static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() { static InstrumentationRuntimeInstances g_instances; return g_instances; @@ -2008,45 +1085,18 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, InstrumentationRuntimeCreateInstance create_callback, InstrumentationRuntimeGetType get_type_callback) { - if (create_callback) { - InstrumentationRuntimeInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.get_type_callback = get_type_callback; - std::lock_guard guard( - GetInstrumentationRuntimeMutex()); - GetInstrumentationRuntimeInstances().push_back(instance); - } - return false; + return GetInstrumentationRuntimeInstances().RegisterPlugin( + name, description, create_callback, get_type_callback); } bool PluginManager::UnregisterPlugin( InstrumentationRuntimeCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard( - GetInstrumentationRuntimeMutex()); - InstrumentationRuntimeInstances &instances = - GetInstrumentationRuntimeInstances(); - - InstrumentationRuntimeInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetInstrumentationRuntimeInstances().UnregisterPlugin(create_callback); } InstrumentationRuntimeGetType PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetInstrumentationRuntimeMutex()); - InstrumentationRuntimeInstances &instances = - GetInstrumentationRuntimeInstances(); + const auto &instances = GetInstrumentationRuntimeInstances().GetInstances(); if (idx < instances.size()) return instances[idx].get_type_callback; return nullptr; @@ -2054,48 +1104,27 @@ PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) { InstrumentationRuntimeCreateInstance PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetInstrumentationRuntimeMutex()); - InstrumentationRuntimeInstances &instances = - GetInstrumentationRuntimeInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -InstrumentationRuntimeCreateInstance -PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard guard( - GetInstrumentationRuntimeMutex()); - InstrumentationRuntimeInstances &instances = - GetInstrumentationRuntimeInstances(); - - InstrumentationRuntimeInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetInstrumentationRuntimeInstances().GetCallbackAtIndex(idx); } #pragma mark TypeSystem -struct TypeSystemInstance { - ConstString name; - std::string description; - TypeSystemCreateInstance create_callback; +struct TypeSystemInstance : public PluginInstance { + TypeSystemInstance(ConstString name, std::string description, + CallbackType create_callback, + LanguageSet supported_languages_for_types, + LanguageSet supported_languages_for_expressions) + : PluginInstance(name, std::move(description), + create_callback), + supported_languages_for_types(supported_languages_for_types), + supported_languages_for_expressions( + supported_languages_for_expressions) {} + LanguageSet supported_languages_for_types; LanguageSet supported_languages_for_expressions; }; -typedef std::vector TypeSystemInstances; - -static std::recursive_mutex &GetTypeSystemMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstances TypeSystemInstances; static TypeSystemInstances &GetTypeSystemInstances() { static TypeSystemInstances g_instances; @@ -2107,75 +1136,31 @@ bool PluginManager::RegisterPlugin( TypeSystemCreateInstance create_callback, LanguageSet supported_languages_for_types, LanguageSet supported_languages_for_expressions) { - if (create_callback) { - TypeSystemInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.supported_languages_for_types = supported_languages_for_types; - instance.supported_languages_for_expressions = supported_languages_for_expressions; - std::lock_guard guard(GetTypeSystemMutex()); - GetTypeSystemInstances().push_back(instance); - } - return false; + return GetTypeSystemInstances().RegisterPlugin( + name, description, create_callback, supported_languages_for_types, + supported_languages_for_expressions); } bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetTypeSystemMutex()); - TypeSystemInstances &instances = GetTypeSystemInstances(); - - TypeSystemInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetTypeSystemInstances().UnregisterPlugin(create_callback); } TypeSystemCreateInstance PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetTypeSystemMutex()); - TypeSystemInstances &instances = GetTypeSystemInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -TypeSystemCreateInstance -PluginManager::GetTypeSystemCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard guard(GetTypeSystemMutex()); - TypeSystemInstances &instances = GetTypeSystemInstances(); - - TypeSystemInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetTypeSystemInstances().GetCallbackAtIndex(idx); } LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() { - std::lock_guard guard(GetTypeSystemMutex()); + const auto &instances = GetTypeSystemInstances().GetInstances(); LanguageSet all; - TypeSystemInstances &instances = GetTypeSystemInstances(); for (unsigned i = 0; i < instances.size(); ++i) all.bitvector |= instances[i].supported_languages_for_types.bitvector; return all; } LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() { - std::lock_guard guard(GetTypeSystemMutex()); + const auto &instances = GetTypeSystemInstances().GetInstances(); LanguageSet all; - TypeSystemInstances &instances = GetTypeSystemInstances(); for (unsigned i = 0; i < instances.size(); ++i) all.bitvector |= instances[i].supported_languages_for_expressions.bitvector; return all; @@ -2183,21 +1168,17 @@ LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() { #pragma mark REPL -struct REPLInstance { - REPLInstance() : name(), description(), create_callback(nullptr) {} +struct REPLInstance : public PluginInstance { + REPLInstance(ConstString name, std::string description, + CallbackType create_callback, LanguageSet supported_languages) + : PluginInstance(name, std::move(description), + create_callback), + supported_languages(supported_languages) {} - ConstString name; - std::string description; - REPLCreateInstance create_callback; LanguageSet supported_languages; }; -typedef std::vector REPLInstances; - -static std::recursive_mutex &GetREPLMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstances REPLInstances; static REPLInstances &GetREPLInstances() { static REPLInstances g_instances; @@ -2207,63 +1188,21 @@ static REPLInstances &GetREPLInstances() { bool PluginManager::RegisterPlugin(ConstString name, const char *description, REPLCreateInstance create_callback, LanguageSet supported_languages) { - if (create_callback) { - REPLInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.supported_languages = supported_languages; - std::lock_guard guard(GetREPLMutex()); - GetREPLInstances().push_back(instance); - } - return false; + return GetREPLInstances().RegisterPlugin(name, description, create_callback, + supported_languages); } bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) { - if (create_callback) { - std::lock_guard guard(GetREPLMutex()); - REPLInstances &instances = GetREPLInstances(); - - REPLInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetREPLInstances().UnregisterPlugin(create_callback); } REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard guard(GetREPLMutex()); - REPLInstances &instances = GetREPLInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -REPLCreateInstance -PluginManager::GetREPLCreateCallbackForPluginName(ConstString name) { - if (name) { - std::lock_guard guard(GetREPLMutex()); - REPLInstances &instances = GetREPLInstances(); - - REPLInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetREPLInstances().GetCallbackAtIndex(idx); } LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() { - std::lock_guard guard(GetREPLMutex()); + const auto &instances = GetREPLInstances().GetInstances(); LanguageSet all; - REPLInstances &instances = GetREPLInstances(); for (unsigned i = 0; i < instances.size(); ++i) all.bitvector |= instances[i].supported_languages.bitvector; return all; @@ -2272,88 +1211,21 @@ LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() { #pragma mark PluginManager void PluginManager::DebuggerInitialize(Debugger &debugger) { - // Initialize the DynamicLoader plugins - { - std::lock_guard guard(GetDynamicLoaderMutex()); - DynamicLoaderInstances &instances = GetDynamicLoaderInstances(); - - DynamicLoaderInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->debugger_init_callback) - pos->debugger_init_callback(debugger); - } - } - - // Initialize the JITLoader plugins - { - std::lock_guard guard(GetJITLoaderMutex()); - JITLoaderInstances &instances = GetJITLoaderInstances(); - - JITLoaderInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->debugger_init_callback) - pos->debugger_init_callback(debugger); - } - } - - // Initialize the Platform plugins - { - std::lock_guard guard(GetPlatformInstancesMutex()); - PlatformInstances &instances = GetPlatformInstances(); - - PlatformInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->debugger_init_callback) - pos->debugger_init_callback(debugger); - } - } - - // Initialize the Process plugins - { - std::lock_guard guard(GetProcessMutex()); - ProcessInstances &instances = GetProcessInstances(); - - ProcessInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->debugger_init_callback) - pos->debugger_init_callback(debugger); - } - } - - // Initialize the SymbolFile plugins - { - std::lock_guard guard(GetSymbolFileMutex()); - for (auto &sym_file : GetSymbolFileInstances()) { - if (sym_file.debugger_init_callback) - sym_file.debugger_init_callback(debugger); - } - } - - // Initialize the OperatingSystem plugins - { - std::lock_guard guard(GetOperatingSystemMutex()); - for (auto &os : GetOperatingSystemInstances()) { - if (os.debugger_init_callback) - os.debugger_init_callback(debugger); - } - } - - // Initialize the StructuredDataPlugin plugins - { - std::lock_guard guard(GetStructuredDataPluginMutex()); - for (auto &plugin : GetStructuredDataPluginInstances()) { - if (plugin.debugger_init_callback) - plugin.debugger_init_callback(debugger); - } - } + GetDynamicLoaderInstances().PerformDebuggerCallback(debugger); + GetJITLoaderInstances().PerformDebuggerCallback(debugger); + GetPlatformInstances().PerformDebuggerCallback(debugger); + GetProcessInstances().PerformDebuggerCallback(debugger); + GetSymbolFileInstances().PerformDebuggerCallback(debugger); + GetOperatingSystemInstances().PerformDebuggerCallback(debugger); + GetStructuredDataPluginInstances().PerformDebuggerCallback(debugger); } // This is the preferred new way to register plugin specific settings. e.g. // This will put a plugin's settings under e.g. // "plugin...SETTINGNAME". -static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPlugins( - Debugger &debugger, ConstString plugin_type_name, - ConstString plugin_type_desc, bool can_create) { +static lldb::OptionValuePropertiesSP +GetDebuggerPropertyForPlugins(Debugger &debugger, ConstString plugin_type_name, + ConstString plugin_type_desc, bool can_create) { lldb::OptionValuePropertiesSP parent_properties_sp( debugger.GetValueProperties()); if (parent_properties_sp) { @@ -2422,8 +1294,8 @@ static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle( namespace { typedef lldb::OptionValuePropertiesSP -GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString , - ConstString , bool can_create); +GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString, ConstString, + bool can_create); lldb::OptionValuePropertiesSP GetSettingForPlugin(Debugger &debugger, ConstString setting_name, @@ -2444,8 +1316,8 @@ GetSettingForPlugin(Debugger &debugger, ConstString setting_name, bool CreateSettingForPlugin( Debugger &debugger, ConstString plugin_type_name, ConstString plugin_type_desc, - const lldb::OptionValuePropertiesSP &properties_sp, - ConstString description, bool is_global_property, + const lldb::OptionValuePropertiesSP &properties_sp, ConstString description, + bool is_global_property, GetDebuggerPropertyForPluginsPtr get_debugger_property = GetDebuggerPropertyForPlugins) { if (properties_sp) { @@ -2471,8 +1343,9 @@ const char *kStructuredDataPluginName("structured-data"); } // anonymous namespace -lldb::OptionValuePropertiesSP PluginManager::GetSettingForDynamicLoaderPlugin( - Debugger &debugger, ConstString setting_name) { +lldb::OptionValuePropertiesSP +PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger, + ConstString setting_name) { return GetSettingForPlugin(debugger, setting_name, ConstString(kDynamicLoaderPluginName)); } @@ -2551,8 +1424,9 @@ bool PluginManager::CreateSettingForJITLoaderPlugin( static const char *kOperatingSystemPluginName("os"); -lldb::OptionValuePropertiesSP PluginManager::GetSettingForOperatingSystemPlugin( - Debugger &debugger, ConstString setting_name) { +lldb::OptionValuePropertiesSP +PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger, + ConstString setting_name) { lldb::OptionValuePropertiesSP properties_sp; lldb::OptionValuePropertiesSP plugin_type_properties_sp( GetDebuggerPropertyForPlugins( @@ -2583,8 +1457,9 @@ bool PluginManager::CreateSettingForOperatingSystemPlugin( return false; } -lldb::OptionValuePropertiesSP PluginManager::GetSettingForStructuredDataPlugin( - Debugger &debugger, ConstString setting_name) { +lldb::OptionValuePropertiesSP +PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger, + ConstString setting_name) { return GetSettingForPlugin(debugger, setting_name, ConstString(kStructuredDataPluginName)); } diff --git a/gnu/llvm/lldb/source/Core/RichManglingContext.cpp b/gnu/llvm/lldb/source/Core/RichManglingContext.cpp index 3d1941ebdd2..2094d96acd7 100644 --- a/gnu/llvm/lldb/source/Core/RichManglingContext.cpp +++ b/gnu/llvm/lldb/source/Core/RichManglingContext.cpp @@ -1,4 +1,4 @@ -//===-- RichManglingContext.cpp ---------------------------------*- C++ -*-===// +//===-- RichManglingContext.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Core/SearchFilter.cpp b/gnu/llvm/lldb/source/Core/SearchFilter.cpp index 9902166be52..ea51fb37918 100644 --- a/gnu/llvm/lldb/source/Core/SearchFilter.cpp +++ b/gnu/llvm/lldb/source/Core/SearchFilter.cpp @@ -1,4 +1,4 @@ -//===-- SearchFilter.cpp ----------------------------------------*- C++ -*-===// +//===-- SearchFilter.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -75,7 +75,8 @@ SearchFilter::SearchFilter(const TargetSP &target_sp, unsigned char filterType) SearchFilter::~SearchFilter() = default; SearchFilterSP SearchFilter::CreateFromStructuredData( - Target &target, const StructuredData::Dictionary &filter_dict, + const lldb::TargetSP& target_sp, + const StructuredData::Dictionary &filter_dict, Status &error) { SearchFilterSP result_sp; if (!filter_dict.IsValid()) { @@ -109,19 +110,19 @@ SearchFilterSP SearchFilter::CreateFromStructuredData( switch (filter_type) { case Unconstrained: result_sp = SearchFilterForUnconstrainedSearches::CreateFromStructuredData( - target, *subclass_options, error); + target_sp, *subclass_options, error); break; case ByModule: result_sp = SearchFilterByModule::CreateFromStructuredData( - target, *subclass_options, error); + target_sp, *subclass_options, error); break; case ByModules: result_sp = SearchFilterByModuleList::CreateFromStructuredData( - target, *subclass_options, error); + target_sp, *subclass_options, error); break; case ByModulesAndCU: result_sp = SearchFilterByModuleListAndCU::CreateFromStructuredData( - target, *subclass_options, error); + target_sp, *subclass_options, error); break; case Exception: error.SetErrorString("Can't serialize exception breakpoints yet."); @@ -160,9 +161,8 @@ void SearchFilter::GetDescription(Stream *s) {} void SearchFilter::Dump(Stream *s) const {} -lldb::SearchFilterSP SearchFilter::CopyForBreakpoint(Breakpoint &breakpoint) { - SearchFilterSP ret_sp = DoCopyForBreakpoint(breakpoint); - TargetSP target_sp = breakpoint.GetTargetSP(); +lldb::SearchFilterSP SearchFilter::CreateCopy(lldb::TargetSP& target_sp) { + SearchFilterSP ret_sp = DoCreateCopy(); ret_sp->SetTarget(target_sp); return ret_sp; } @@ -212,7 +212,7 @@ void SearchFilter::Search(Searcher &searcher) { searcher.SearchCallback(*this, empty_sc, nullptr); return; } - + DoModuleIteration(empty_sc, searcher); } @@ -362,11 +362,11 @@ Searcher::CallbackReturn SearchFilter::DoFunctionIteration( // Selects a shared library matching a given file spec, consulting the targets // "black list". SearchFilterSP SearchFilterForUnconstrainedSearches::CreateFromStructuredData( - Target &target, const StructuredData::Dictionary &data_dict, + const lldb::TargetSP& target_sp, + const StructuredData::Dictionary &data_dict, Status &error) { // No options for an unconstrained search. - return std::make_shared( - target.shared_from_this()); + return std::make_shared(target_sp); } StructuredData::ObjectSP @@ -390,8 +390,7 @@ bool SearchFilterForUnconstrainedSearches::ModulePasses( return true; } -lldb::SearchFilterSP SearchFilterForUnconstrainedSearches::DoCopyForBreakpoint( - Breakpoint &breakpoint) { +SearchFilterSP SearchFilterForUnconstrainedSearches::DoCreateCopy() { return std::make_shared(*this); } @@ -418,12 +417,6 @@ bool SearchFilterByModule::AddressPasses(Address &address) { return true; } -bool SearchFilterByModule::CompUnitPasses(FileSpec &fileSpec) { return true; } - -bool SearchFilterByModule::CompUnitPasses(CompileUnit &compUnit) { - return true; -} - void SearchFilterByModule::Search(Searcher &searcher) { if (!m_target_sp) return; @@ -466,13 +459,13 @@ uint32_t SearchFilterByModule::GetFilterRequiredItems() { void SearchFilterByModule::Dump(Stream *s) const {} -lldb::SearchFilterSP -SearchFilterByModule::DoCopyForBreakpoint(Breakpoint &breakpoint) { +SearchFilterSP SearchFilterByModule::DoCreateCopy() { return std::make_shared(*this); } SearchFilterSP SearchFilterByModule::CreateFromStructuredData( - Target &target, const StructuredData::Dictionary &data_dict, + const lldb::TargetSP& target_sp, + const StructuredData::Dictionary &data_dict, Status &error) { StructuredData::Array *modules_array; bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList), @@ -497,8 +490,7 @@ SearchFilterSP SearchFilterByModule::CreateFromStructuredData( } FileSpec module_spec(module); - return std::make_shared(target.shared_from_this(), - module_spec); + return std::make_shared(target_sp, module_spec); } StructuredData::ObjectSP SearchFilterByModule::SerializeToStructuredData() { @@ -545,14 +537,6 @@ bool SearchFilterByModuleList::AddressPasses(Address &address) { return true; } -bool SearchFilterByModuleList::CompUnitPasses(FileSpec &fileSpec) { - return true; -} - -bool SearchFilterByModuleList::CompUnitPasses(CompileUnit &compUnit) { - return true; -} - void SearchFilterByModuleList::Search(Searcher &searcher) { if (!m_target_sp) return; @@ -611,20 +595,20 @@ uint32_t SearchFilterByModuleList::GetFilterRequiredItems() { void SearchFilterByModuleList::Dump(Stream *s) const {} -lldb::SearchFilterSP -SearchFilterByModuleList::DoCopyForBreakpoint(Breakpoint &breakpoint) { +lldb::SearchFilterSP SearchFilterByModuleList::DoCreateCopy() { return std::make_shared(*this); } SearchFilterSP SearchFilterByModuleList::CreateFromStructuredData( - Target &target, const StructuredData::Dictionary &data_dict, + const lldb::TargetSP& target_sp, + const StructuredData::Dictionary &data_dict, Status &error) { StructuredData::Array *modules_array; bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList), modules_array); if (!success) - return std::make_shared(target.shared_from_this(), + return std::make_shared(target_sp, FileSpecList{}); FileSpecList modules; size_t num_modules = modules_array->GetSize(); @@ -638,8 +622,7 @@ SearchFilterSP SearchFilterByModuleList::CreateFromStructuredData( } modules.EmplaceBack(module); } - return std::make_shared(target.shared_from_this(), - modules); + return std::make_shared(target_sp, modules); } void SearchFilterByModuleList::SerializeUnwrapped( @@ -667,7 +650,8 @@ SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU( SearchFilterByModuleListAndCU::~SearchFilterByModuleListAndCU() = default; lldb::SearchFilterSP SearchFilterByModuleListAndCU::CreateFromStructuredData( - Target &target, const StructuredData::Dictionary &data_dict, + const lldb::TargetSP& target_sp, + const StructuredData::Dictionary &data_dict, Status &error) { StructuredData::Array *modules_array = nullptr; SearchFilterSP result_sp; @@ -710,7 +694,7 @@ lldb::SearchFilterSP SearchFilterByModuleListAndCU::CreateFromStructuredData( } return std::make_shared( - target.shared_from_this(), modules, cus); + target_sp, modules, cus); } StructuredData::ObjectSP @@ -832,7 +816,6 @@ uint32_t SearchFilterByModuleListAndCU::GetFilterRequiredItems() { void SearchFilterByModuleListAndCU::Dump(Stream *s) const {} -lldb::SearchFilterSP -SearchFilterByModuleListAndCU::DoCopyForBreakpoint(Breakpoint &breakpoint) { +SearchFilterSP SearchFilterByModuleListAndCU::DoCreateCopy() { return std::make_shared(*this); } diff --git a/gnu/llvm/lldb/source/Core/Section.cpp b/gnu/llvm/lldb/source/Core/Section.cpp index 1697f1f7a5d..9bf1c62c5ab 100644 --- a/gnu/llvm/lldb/source/Core/Section.cpp +++ b/gnu/llvm/lldb/source/Core/Section.cpp @@ -1,4 +1,4 @@ -//===-- Section.cpp ---------------------------------------------*- C++ -*-===// +//===-- Section.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,7 +13,6 @@ #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/Stream.h" #include "lldb/Utility/VMRange.h" #include @@ -68,6 +67,8 @@ const char *Section::GetTypeAsCString() const { return "dwarf-aranges"; case eSectionTypeDWARFDebugCuIndex: return "dwarf-cu-index"; + case eSectionTypeDWARFDebugTuIndex: + return "dwarf-tu-index"; case eSectionTypeDWARFDebugFrame: return "dwarf-frame"; case eSectionTypeDWARFDebugInfo: @@ -265,11 +266,8 @@ bool Section::ResolveContainedAddress(addr_t offset, Address &so_addr, so_addr.SetOffset(offset); so_addr.SetSection(const_cast
(this)->shared_from_this()); -#ifdef LLDB_CONFIGURATION_DEBUG - // For debug builds, ensure that there are no orphaned (i.e., moduleless) - // sections. + // Ensure that there are no orphaned (i.e., moduleless) sections. assert(GetModule().get()); -#endif return true; } @@ -284,15 +282,15 @@ bool Section::ContainsFileAddress(addr_t vm_addr) const { return false; } -void Section::Dump(Stream *s, Target *target, uint32_t depth) const { - // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); - s->Indent(); - s->Printf("0x%8.8" PRIx64 " %-16s ", GetID(), GetTypeAsCString()); +void Section::Dump(llvm::raw_ostream &s, unsigned indent, Target *target, + uint32_t depth) const { + s.indent(indent); + s << llvm::format("0x%8.8" PRIx64 " %-16s ", GetID(), GetTypeAsCString()); bool resolved = true; addr_t addr = LLDB_INVALID_ADDRESS; if (GetByteSize() == 0) - s->Printf("%39s", ""); + s.indent(39); else { if (target) addr = GetLoadBaseAddress(target); @@ -304,27 +302,27 @@ void Section::Dump(Stream *s, Target *target, uint32_t depth) const { } VMRange range(addr, addr + m_byte_size); - range.Dump(s->AsRawOstream(), 0); + range.Dump(s, 0); } - s->Printf("%c %c%c%c 0x%8.8" PRIx64 " 0x%8.8" PRIx64 " 0x%8.8x ", - resolved ? ' ' : '*', m_readable ? 'r' : '-', - m_writable ? 'w' : '-', m_executable ? 'x' : '-', m_file_offset, - m_file_size, Get()); + s << llvm::format("%c %c%c%c 0x%8.8" PRIx64 " 0x%8.8" PRIx64 " 0x%8.8x ", + resolved ? ' ' : '*', m_readable ? 'r' : '-', + m_writable ? 'w' : '-', m_executable ? 'x' : '-', + m_file_offset, m_file_size, Get()); DumpName(s); - s->EOL(); + s << "\n"; if (depth > 0) - m_children.Dump(s, target, false, depth - 1); + m_children.Dump(s, indent, target, false, depth - 1); } -void Section::DumpName(Stream *s) const { +void Section::DumpName(llvm::raw_ostream &s) const { SectionSP parent_sp(GetParent()); if (parent_sp) { parent_sp->DumpName(s); - s->PutChar('.'); + s << '.'; } else { // The top most section prints the module basename const char *name = nullptr; @@ -337,9 +335,9 @@ void Section::DumpName(Stream *s) const { if ((!name || !name[0]) && module_sp) name = module_sp->GetFileSpec().GetFilename().AsCString(); if (name && name[0]) - s->Printf("%s.", name); + s << name << '.'; } - m_name.Dump(s); + s << m_name; } bool Section::IsDescendant(const Section *section) { @@ -569,31 +567,27 @@ bool SectionList::ContainsSection(user_id_t sect_id) const { return FindSectionByID(sect_id).get() != nullptr; } -void SectionList::Dump(Stream *s, Target *target, bool show_header, - uint32_t depth) const { +void SectionList::Dump(llvm::raw_ostream &s, unsigned indent, Target *target, + bool show_header, uint32_t depth) const { bool target_has_loaded_sections = target && !target->GetSectionLoadList().IsEmpty(); if (show_header && !m_sections.empty()) { - s->Indent(); - s->Printf("SectID Type %s Address " - " Perm File Off. File Size Flags " - " Section Name\n", - target_has_loaded_sections ? "Load" : "File"); - s->Indent(); - s->PutCString("---------- ---------------- " - "--------------------------------------- ---- ---------- " - "---------- " - "---------- ----------------------------\n"); + s.indent(indent); + s << llvm::formatv( + "SectID Type {0} Address " + " Perm File Off. File Size Flags " + " Section Name\n", + target_has_loaded_sections ? "Load" : "File"); + s.indent(indent); + s << "---------- ---------------- " + "--------------------------------------- ---- ---------- " + "---------- " + "---------- ----------------------------\n"; } - const_iterator sect_iter; - const_iterator end = m_sections.end(); - for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter) { - (*sect_iter)->Dump(s, target_has_loaded_sections ? target : nullptr, depth); - } - - if (show_header && !m_sections.empty()) - s->IndentLess(); + for (const auto §ion_sp : m_sections) + section_sp->Dump(s, indent, target_has_loaded_sections ? target : nullptr, + depth); } size_t SectionList::Slide(addr_t slide_amount, bool slide_children) { diff --git a/gnu/llvm/lldb/source/Core/SourceManager.cpp b/gnu/llvm/lldb/source/Core/SourceManager.cpp index 8e0cc57f80c..7414dd281d4 100644 --- a/gnu/llvm/lldb/source/Core/SourceManager.cpp +++ b/gnu/llvm/lldb/source/Core/SourceManager.cpp @@ -1,4 +1,4 @@ -//===-- SourceManager.cpp ---------------------------------------*- C++ -*-===// +//===-- SourceManager.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -22,6 +22,7 @@ #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/PathMappingList.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/AnsiTerminal.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataBufferLLVM.h" @@ -51,27 +52,24 @@ static inline bool is_newline_char(char ch) { return ch == '\n' || ch == '\r'; } // SourceManager constructor SourceManager::SourceManager(const TargetSP &target_sp) - : m_last_file_sp(), m_last_line(0), m_last_count(0), m_default_set(false), + : m_last_line(0), m_last_count(0), m_default_set(false), m_target_wp(target_sp), m_debugger_wp(target_sp->GetDebugger().shared_from_this()) {} SourceManager::SourceManager(const DebuggerSP &debugger_sp) - : m_last_file_sp(), m_last_line(0), m_last_count(0), m_default_set(false), - m_target_wp(), m_debugger_wp(debugger_sp) {} + : m_last_line(0), m_last_count(0), m_default_set(false), m_target_wp(), + m_debugger_wp(debugger_sp) {} // Destructor SourceManager::~SourceManager() {} SourceManager::FileSP SourceManager::GetFile(const FileSpec &file_spec) { - bool same_as_previous = - m_last_file_sp && - FileSpec::Match(file_spec, m_last_file_sp->GetFileSpec()); + if (!file_spec) + return nullptr; DebuggerSP debugger_sp(m_debugger_wp.lock()); FileSP file_sp; - if (same_as_previous) - file_sp = m_last_file_sp; - else if (debugger_sp) + if (debugger_sp && debugger_sp->GetUseSourceCache()) file_sp = debugger_sp->GetSourceFileCache().FindSourceFile(file_spec); TargetSP target_sp(m_target_wp.lock()); @@ -94,7 +92,7 @@ SourceManager::FileSP SourceManager::GetFile(const FileSpec &file_spec) { else file_sp = std::make_shared(file_spec, debugger_sp); - if (debugger_sp) + if (debugger_sp && debugger_sp->GetUseSourceCache()) debugger_sp->GetSourceFileCache().AddSourceFile(file_sp); } return file_sp; @@ -148,6 +146,10 @@ static bool should_show_stop_column_with_caret(DebuggerSP debugger_sp) { return value == eStopShowColumnCaret; } +static bool should_show_stop_line_with_ansi(DebuggerSP debugger_sp) { + return debugger_sp && debugger_sp->GetUseColor(); +} + size_t SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile( uint32_t start_line, uint32_t count, uint32_t curr_line, uint32_t column, const char *current_line_cstr, Stream *s, @@ -173,10 +175,10 @@ size_t SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile( m_last_line = start_line; m_last_count = count; - if (m_last_file_sp.get()) { + if (FileSP last_file_sp = GetLastFile()) { const uint32_t end_line = start_line + count - 1; for (uint32_t line = start_line; line <= end_line; ++line) { - if (!m_last_file_sp->LineIsValid(line)) { + if (!last_file_sp->LineIsValid(line)) { m_last_line = UINT32_MAX; break; } @@ -191,8 +193,20 @@ size_t SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile( ::snprintf(prefix, sizeof(prefix), " "); } - s->Printf("%s%2.2s %-4u\t", prefix, - line == curr_line ? current_line_cstr : "", line); + char buffer[3]; + sprintf(buffer, "%2.2s", (line == curr_line) ? current_line_cstr : ""); + std::string current_line_highlight(buffer); + + auto debugger_sp = m_debugger_wp.lock(); + if (should_show_stop_line_with_ansi(debugger_sp)) { + current_line_highlight = ansi::FormatAnsiTerminalCodes( + (debugger_sp->GetStopShowLineMarkerAnsiPrefix() + + current_line_highlight + + debugger_sp->GetStopShowLineMarkerAnsiSuffix()) + .str()); + } + + s->Printf("%s%s %-4u\t", prefix, current_line_highlight.c_str(), line); // So far we treated column 0 as a special 'no column value', but // DisplaySourceLines starts counting columns from 0 (and no column is @@ -202,12 +216,12 @@ size_t SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile( columnToHighlight = column - 1; size_t this_line_size = - m_last_file_sp->DisplaySourceLines(line, columnToHighlight, 0, 0, s); + last_file_sp->DisplaySourceLines(line, columnToHighlight, 0, 0, s); if (column != 0 && line == curr_line && - should_show_stop_column_with_caret(m_debugger_wp.lock())) { + should_show_stop_column_with_caret(debugger_sp)) { // Display caret cursor. std::string src_line; - m_last_file_sp->GetLine(line, src_line); + last_file_sp->GetLine(line, src_line); s->Printf(" \t"); // Insert a space for every non-tab character in the source line. for (size_t i = 0; i + 1 < column && i < src_line.length(); ++i) @@ -238,10 +252,11 @@ size_t SourceManager::DisplaySourceLinesWithLineNumbers( else start_line = 1; - if (m_last_file_sp.get() != file_sp.get()) { + FileSP last_file_sp(GetLastFile()); + if (last_file_sp.get() != file_sp.get()) { if (line == 0) m_last_line = 0; - m_last_file_sp = file_sp; + m_last_file_spec = file_spec; } return DisplaySourceLinesWithLineNumbersUsingLastFile( start_line, count, line, column, current_line_cstr, s, bp_locs); @@ -251,14 +266,15 @@ size_t SourceManager::DisplayMoreWithLineNumbers( Stream *s, uint32_t count, bool reverse, const SymbolContextList *bp_locs) { // If we get called before anybody has set a default file and line, then try // to figure it out here. - const bool have_default_file_line = m_last_file_sp && m_last_line > 0; + FileSP last_file_sp(GetLastFile()); + const bool have_default_file_line = last_file_sp && m_last_line > 0; if (!m_default_set) { FileSpec tmp_spec; uint32_t tmp_line; GetDefaultFileAndLine(tmp_spec, tmp_line); } - if (m_last_file_sp) { + if (last_file_sp) { if (m_last_line == UINT32_MAX) return 0; @@ -293,22 +309,21 @@ size_t SourceManager::DisplayMoreWithLineNumbers( bool SourceManager::SetDefaultFileAndLine(const FileSpec &file_spec, uint32_t line) { - FileSP old_file_sp = m_last_file_sp; - m_last_file_sp = GetFile(file_spec); - m_default_set = true; - if (m_last_file_sp) { + FileSP file_sp(GetFile(file_spec)); + + if (file_sp) { m_last_line = line; + m_last_file_spec = file_spec; return true; } else { - m_last_file_sp = old_file_sp; return false; } } bool SourceManager::GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line) { - if (m_last_file_sp) { - file_spec = m_last_file_sp->GetFileSpec(); + if (FileSP last_file_sp = GetLastFile()) { + file_spec = m_last_file_spec; line = m_last_line; return true; } else if (!m_default_set) { @@ -325,7 +340,7 @@ bool SourceManager::GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line) { ConstString main_name("main"); bool symbols_okay = false; // Force it to be a debug symbol. bool inlines_okay = true; - executable_ptr->FindFunctions(main_name, nullptr, + executable_ptr->FindFunctions(main_name, CompilerDeclContext(), lldb::eFunctionNameTypeBase, inlines_okay, symbols_okay, sc_list); size_t num_matches = sc_list.GetSize(); @@ -338,7 +353,7 @@ bool SourceManager::GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line) { .GetBaseAddress() .CalculateSymbolContextLineEntry(line_entry)) { SetDefaultFileAndLine(line_entry.file, line_entry.line); - file_spec = m_last_file_sp->GetFileSpec(); + file_spec = m_last_file_spec; line = m_last_line; return true; } @@ -679,7 +694,7 @@ bool SourceManager::File::GetLine(uint32_t line_no, std::string &buffer) { } void SourceManager::SourceFileCache::AddSourceFile(const FileSP &file_sp) { - FileSpec file_spec; + FileSpec file_spec = file_sp->GetFileSpec(); FileCache::iterator pos = m_file_cache.find(file_spec); if (pos == m_file_cache.end()) m_file_cache[file_spec] = file_sp; diff --git a/gnu/llvm/lldb/source/Core/StreamAsynchronousIO.cpp b/gnu/llvm/lldb/source/Core/StreamAsynchronousIO.cpp index d283749144e..04195a6d13e 100644 --- a/gnu/llvm/lldb/source/Core/StreamAsynchronousIO.cpp +++ b/gnu/llvm/lldb/source/Core/StreamAsynchronousIO.cpp @@ -1,4 +1,4 @@ -//===-- StreamAsynchronousIO.cpp --------------------------------*- C++ -*-===// +//===-- StreamAsynchronousIO.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Core/StreamFile.cpp b/gnu/llvm/lldb/source/Core/StreamFile.cpp index 475c27ec411..43a9df802f7 100644 --- a/gnu/llvm/lldb/source/Core/StreamFile.cpp +++ b/gnu/llvm/lldb/source/Core/StreamFile.cpp @@ -1,4 +1,4 @@ -//===-- StreamFile.cpp ------------------------------------------*- C++ -*-===// +//===-- StreamFile.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Core/UserSettingsController.cpp b/gnu/llvm/lldb/source/Core/UserSettingsController.cpp index 3a656766dce..b9f7d5eaa68 100644 --- a/gnu/llvm/lldb/source/Core/UserSettingsController.cpp +++ b/gnu/llvm/lldb/source/Core/UserSettingsController.cpp @@ -1,4 +1,4 @@ -//====-- UserSettingsController.cpp ------------------------------*- C++-*-===// +//===-- UserSettingsController.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Core/Value.cpp b/gnu/llvm/lldb/source/Core/Value.cpp index c70ab98dcdf..63467644cde 100644 --- a/gnu/llvm/lldb/source/Core/Value.cpp +++ b/gnu/llvm/lldb/source/Core/Value.cpp @@ -1,4 +1,4 @@ -//===-- Value.cpp -----------------------------------------------*- C++ -*-===// +//===-- Value.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Core/ValueObject.cpp b/gnu/llvm/lldb/source/Core/ValueObject.cpp index 1dd9a6cf62c..3a775b07e5e 100644 --- a/gnu/llvm/lldb/source/Core/ValueObject.cpp +++ b/gnu/llvm/lldb/source/Core/ValueObject.cpp @@ -1,4 +1,4 @@ -//===-- ValueObject.cpp -----------------------------------------*- C++ -*-===// +//===-- ValueObject.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,7 +25,6 @@ #include "lldb/DataFormatters/ValueObjectPrinter.h" #include "lldb/Expression/ExpressionVariable.h" #include "lldb/Host/Config.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/Declaration.h" @@ -46,7 +45,6 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" #include "lldb/Utility/Scalar.h" -#include "lldb/Utility/SharingPtr.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" #include "lldb/lldb-private-types.h" @@ -106,12 +104,13 @@ ValueObject::ValueObject(ValueObject &parent) // ValueObject constructor ValueObject::ValueObject(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, AddressType child_ptr_or_ref_addr_type) : UserID(++g_value_obj_uid), // Unique identifier for every value object m_parent(nullptr), m_root(nullptr), m_update_point(exe_scope), m_name(), m_data(), m_value(), m_error(), m_value_str(), m_old_value_str(), m_location_str(), m_summary_str(), m_object_desc_str(), - m_manager(), m_children(), m_synthetic_children(), + m_manager(&manager), m_children(), m_synthetic_children(), m_dynamic_value(nullptr), m_synthetic_value(nullptr), m_deref_valobj(nullptr), m_format(eFormatDefault), m_last_format(eFormatDefault), m_last_format_mgr_revision(0), @@ -135,65 +134,12 @@ ValueObject::ValueObject(ExecutionContextScope *exe_scope, m_data.SetAddressByteSize(arch.GetAddressByteSize()); } } - m_manager = new ValueObjectManager(); m_manager->ManageObject(this); } // Destructor ValueObject::~ValueObject() {} -void ValueObject::UpdateChildrenAddressType() { - Value::ValueType value_type = m_value.GetValueType(); - ExecutionContext exe_ctx(GetExecutionContextRef()); - Process *process = exe_ctx.GetProcessPtr(); - const bool process_is_alive = process && process->IsAlive(); - const uint32_t type_info = GetCompilerType().GetTypeInfo(); - const bool is_pointer_or_ref = - (type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0; - - switch (value_type) { - case Value::eValueTypeFileAddress: - // If this type is a pointer, then its children will be considered load - // addresses if the pointer or reference is dereferenced, but only if - // the process is alive. - // - // There could be global variables like in the following code: - // struct LinkedListNode { Foo* foo; LinkedListNode* next; }; - // Foo g_foo1; - // Foo g_foo2; - // LinkedListNode g_second_node = { &g_foo2, NULL }; - // LinkedListNode g_first_node = { &g_foo1, &g_second_node }; - // - // When we aren't running, we should be able to look at these variables - // using the "target variable" command. Children of the "g_first_node" - // always will be of the same address type as the parent. But children - // of the "next" member of LinkedListNode will become load addresses if - // we have a live process, or remain a file address if it was a file - // address. - if (process_is_alive && is_pointer_or_ref) - SetAddressTypeOfChildren(eAddressTypeLoad); - else - SetAddressTypeOfChildren(eAddressTypeFile); - break; - case Value::eValueTypeHostAddress: - // Same as above for load addresses, except children of pointer or refs - // are always load addresses. Host addresses are used to store freeze - // dried variables. If this type is a struct, the entire struct - // contents will be copied into the heap of the - // LLDB process, but we do not currently follow any pointers. - if (is_pointer_or_ref) - SetAddressTypeOfChildren(eAddressTypeLoad); - else - SetAddressTypeOfChildren(eAddressTypeHost); - break; - case Value::eValueTypeLoadAddress: - case Value::eValueTypeScalar: - case Value::eValueTypeVector: - SetAddressTypeOfChildren(eAddressTypeLoad); - break; - } -} - bool ValueObject::UpdateValueIfNeeded(bool update_format) { bool did_change_formats = false; @@ -416,7 +362,7 @@ const char *ValueObject::GetLocationAsCStringImpl(const Value &value, uint32_t addr_nibble_size = data.GetAddressByteSize() * 2; sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS)); - m_location_str = sstr.GetString(); + m_location_str = std::string(sstr.GetString()); } break; } } @@ -576,15 +522,13 @@ size_t ValueObject::GetIndexOfChildWithName(ConstString name) { ValueObjectSP ValueObject::GetChildMemberWithName(ConstString name, bool can_create) { - // when getting a child by name, it could be buried inside some base classes - // (which really aren't part of the expression path), so we need a vector of - // indexes that can get us down to the correct child - ValueObjectSP child_sp; - - // We may need to update our value if we are dynamic + // We may need to update our value if we are dynamic. if (IsPossibleDynamicType()) UpdateValueIfNeeded(false); + // When getting a child by name, it could be buried inside some base classes + // (which really aren't part of the expression path), so we need a vector of + // indexes that can get us down to the correct child. std::vector child_indexes; bool omit_empty_base_classes = true; @@ -594,20 +538,13 @@ ValueObjectSP ValueObject::GetChildMemberWithName(ConstString name, const size_t num_child_indexes = GetCompilerType().GetIndexOfChildMemberWithName( name.GetCString(), omit_empty_base_classes, child_indexes); - if (num_child_indexes > 0) { - std::vector::const_iterator pos = child_indexes.begin(); - std::vector::const_iterator end = child_indexes.end(); - - child_sp = GetChildAtIndex(*pos, can_create); - for (++pos; pos != end; ++pos) { - if (child_sp) { - ValueObjectSP new_child_sp(child_sp->GetChildAtIndex(*pos, can_create)); - child_sp = new_child_sp; - } else { - child_sp.reset(); - } - } - } + if (num_child_indexes == 0) + return nullptr; + + ValueObjectSP child_sp = GetSP(); + for (uint32_t idx : child_indexes) + if (child_sp) + child_sp = child_sp->GetChildAtIndex(idx, can_create); return child_sp; } @@ -689,6 +626,16 @@ ValueObject *ValueObject::CreateChildAtIndex(size_t idx, language_flags); } + // In case of an incomplete type, try to use the ValueObject's + // synthetic value to create the child ValueObject. + if (!valobj && synthetic_array_member) { + if (ValueObjectSP synth_valobj_sp = GetSyntheticValue()) { + valobj = synth_valobj_sp + ->GetChildAtIndex(synthetic_index, synthetic_array_member) + .get(); + } + } + return valobj; } @@ -766,7 +713,7 @@ bool ValueObject::IsCStringContainer(bool check_pointer) { return true; addr_t cstr_address = LLDB_INVALID_ADDRESS; AddressType cstr_address_type = eAddressTypeInvalid; - cstr_address = GetAddressOf(true, &cstr_address_type); + cstr_address = GetPointerValue(&cstr_address_type); return (cstr_address != LLDB_INVALID_ADDRESS); } @@ -1120,7 +1067,7 @@ const char *ValueObject::GetObjectDescription() { if (LanguageRuntime *runtime = process->GetLanguageRuntime(language)) { StreamString s; if (runtime->GetObjectDescription(s, *this)) { - m_object_desc_str.append(s.GetString()); + m_object_desc_str.append(std::string(s.GetString())); return m_object_desc_str.c_str(); } } @@ -1200,6 +1147,7 @@ uint64_t ValueObject::GetValueAsUnsigned(uint64_t fail_value, bool *success) { if (ResolveValue(scalar)) { if (success) *success = true; + scalar.MakeUnsigned(); return scalar.ULongLong(fail_value); } // fallthrough, otherwise... @@ -1217,6 +1165,7 @@ int64_t ValueObject::GetValueAsSigned(int64_t fail_value, bool *success) { if (ResolveValue(scalar)) { if (success) *success = true; + scalar.MakeSigned(); return scalar.SLongLong(fail_value); } // fallthrough, otherwise... @@ -1447,7 +1396,7 @@ bool ValueObject::DumpPrintableRepresentation( break; case eValueObjectRepresentationStyleExpressionPath: - GetExpressionPath(strm, false); + GetExpressionPath(strm); str = strm.GetString(); break; } @@ -1553,7 +1502,7 @@ addr_t ValueObject::GetPointerValue(AddressType *address_type) { case Value::eValueTypeLoadAddress: case Value::eValueTypeFileAddress: { lldb::offset_t data_offset = 0; - address = m_data.GetPointer(&data_offset); + address = m_data.GetAddress(&data_offset); } break; } @@ -1652,13 +1601,13 @@ bool ValueObject::GetDeclaration(Declaration &decl) { } ConstString ValueObject::GetTypeName() { - return GetCompilerType().GetConstTypeName(); + return GetCompilerType().GetTypeName(); } ConstString ValueObject::GetDisplayTypeName() { return GetTypeName(); } ConstString ValueObject::GetQualifiedTypeName() { - return GetCompilerType().GetConstQualifiedTypeName(); + return GetCompilerType().GetTypeName(); } LanguageType ValueObject::GetObjectRuntimeLanguage() { @@ -1720,7 +1669,7 @@ bool ValueObject::IsRuntimeSupportValue() { return false; if (auto *runtime = process->GetLanguageRuntime(GetVariable()->GetLanguage())) - if (runtime->IsWhitelistedRuntimeValue(GetName())) + if (runtime->IsAllowedRuntimeValue(GetName())) return false; return true; @@ -1935,10 +1884,7 @@ ValueObject::GetSyntheticExpressionPathChild(const char *expression, return synthetic_child_sp; } -void ValueObject::CalculateSyntheticValue(bool use_synthetic) { - if (!use_synthetic) - return; - +void ValueObject::CalculateSyntheticValue() { TargetSP target_sp(GetTargetSP()); if (target_sp && !target_sp->GetEnableSyntheticValue()) { m_synthetic_value = nullptr; @@ -1990,11 +1936,8 @@ ValueObjectSP ValueObject::GetStaticValue() { return GetSP(); } lldb::ValueObjectSP ValueObject::GetNonSyntheticValue() { return GetSP(); } -ValueObjectSP ValueObject::GetSyntheticValue(bool use_synthetic) { - if (!use_synthetic) - return ValueObjectSP(); - - CalculateSyntheticValue(use_synthetic); +ValueObjectSP ValueObject::GetSyntheticValue() { + CalculateSyntheticValue(); if (m_synthetic_value) return m_synthetic_value->GetSP(); @@ -2008,28 +1951,11 @@ bool ValueObject::HasSyntheticValue() { if (m_synthetic_children_sp.get() == nullptr) return false; - CalculateSyntheticValue(true); + CalculateSyntheticValue(); return m_synthetic_value != nullptr; } -bool ValueObject::GetBaseClassPath(Stream &s) { - if (IsBaseClass()) { - bool parent_had_base_class = - GetParent() && GetParent()->GetBaseClassPath(s); - CompilerType compiler_type = GetCompilerType(); - llvm::Optional cxx_class_name = - ClangASTContext::GetCXXClassName(compiler_type); - if (cxx_class_name) { - if (parent_had_base_class) - s.PutCString("::"); - s.PutCString(cxx_class_name.getValue()); - } - return parent_had_base_class || cxx_class_name; - } - return false; -} - ValueObject *ValueObject::GetNonBaseClassParent() { if (GetParent()) { if (GetParent()->IsBaseClass()) @@ -2055,7 +1981,7 @@ bool ValueObject::IsBaseClass(uint32_t &depth) { return true; } -void ValueObject::GetExpressionPath(Stream &s, bool qualify_cxx_base_classes, +void ValueObject::GetExpressionPath(Stream &s, GetExpressionPathFormat epformat) { // synthetic children do not actually "exist" as part of the hierarchy, and // sometimes they are consed up in ways that don't make sense from an @@ -2104,14 +2030,14 @@ void ValueObject::GetExpressionPath(Stream &s, bool qualify_cxx_base_classes, ValueObject *parent = GetParent(); if (parent) - parent->GetExpressionPath(s, qualify_cxx_base_classes, epformat); + parent->GetExpressionPath(s, epformat); // if we are a deref_of_parent just because we are synthetic array members // made up to allow ptr[%d] syntax to work in variable printing, then add our // name ([%d]) to the expression path if (m_is_array_item_for_pointer && epformat == eGetExpressionPathFormatHonorPointers) - s.PutCString(m_name.AsCString()); + s.PutCString(m_name.GetStringRef()); if (!IsBaseClass()) { if (!is_deref_of_parent) { @@ -2139,13 +2065,8 @@ void ValueObject::GetExpressionPath(Stream &s, bool qualify_cxx_base_classes, } const char *name = GetName().GetCString(); - if (name) { - if (qualify_cxx_base_classes) { - if (GetBaseClassPath(s)) - s.PutCString("::"); - } + if (name) s.PutCString(name); - } } } @@ -2834,7 +2755,7 @@ ValueObjectSP ValueObject::Dereference(Status &error) { const bool transparent_pointers = false; CompilerType compiler_type = GetCompilerType(); CompilerType child_compiler_type; - uint64_t language_flags; + uint64_t language_flags = 0; ExecutionContext exe_ctx(GetExecutionContextRef()); @@ -2854,11 +2775,35 @@ ValueObjectSP ValueObject::Dereference(Status &error) { child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid, language_flags); } + + // In case of incomplete child compiler type, use the pointee type and try + // to recreate a new ValueObjectChild using it. + if (!m_deref_valobj) { + if (HasSyntheticValue()) { + child_compiler_type = compiler_type.GetPointeeType(); + + if (child_compiler_type) { + ConstString child_name; + if (!child_name_str.empty()) + child_name.SetCString(child_name_str.c_str()); + + m_deref_valobj = new ValueObjectChild( + *this, child_compiler_type, child_name, child_byte_size, + child_byte_offset, child_bitfield_bit_size, + child_bitfield_bit_offset, child_is_base_class, + child_is_deref_of_parent, eAddressTypeInvalid, language_flags); + } + } + } + } else if (HasSyntheticValue()) { m_deref_valobj = GetSyntheticValue() ->GetChildMemberWithName(ConstString("$$dereference$$"), true) .get(); + } else if (IsSynthetic()) { + m_deref_valobj = + GetChildMemberWithName(ConstString("$$dereference$$"), true).get(); } if (m_deref_valobj) { @@ -2866,7 +2811,7 @@ ValueObjectSP ValueObject::Dereference(Status &error) { return m_deref_valobj->GetSP(); } else { StreamString strm; - GetExpressionPath(strm, true); + GetExpressionPath(strm); if (is_pointer_or_reference_type) error.SetErrorStringWithFormat("dereference failed: (%s) %s", @@ -2892,7 +2837,7 @@ ValueObjectSP ValueObject::AddressOf(Status &error) { switch (address_type) { case eAddressTypeInvalid: { StreamString expr_path_strm; - GetExpressionPath(expr_path_strm, true); + GetExpressionPath(expr_path_strm); error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetData()); } break; @@ -2915,7 +2860,7 @@ ValueObjectSP ValueObject::AddressOf(Status &error) { } } else { StreamString expr_path_strm; - GetExpressionPath(expr_path_strm, true); + GetExpressionPath(expr_path_strm); error.SetErrorStringWithFormat("'%s' doesn't have a valid address", expr_path_strm.GetData()); } @@ -3291,19 +3236,17 @@ ValueObjectSP ValueObject::Persist() { if (!persistent_state) return nullptr; - auto prefix = persistent_state->GetPersistentVariablePrefix(); - ConstString name = - persistent_state->GetNextPersistentVariableName(*target_sp, prefix); + ConstString name = persistent_state->GetNextPersistentVariableName(); ValueObjectSP const_result_sp = ValueObjectConstResult::Create(target_sp.get(), GetValue(), name); - ExpressionVariableSP clang_var_sp = + ExpressionVariableSP persistent_var_sp = persistent_state->CreatePersistentVariable(const_result_sp); - clang_var_sp->m_live_sp = clang_var_sp->m_frozen_sp; - clang_var_sp->m_flags |= ExpressionVariable::EVIsProgramReference; + persistent_var_sp->m_live_sp = persistent_var_sp->m_frozen_sp; + persistent_var_sp->m_flags |= ExpressionVariable::EVIsProgramReference; - return clang_var_sp->GetValueObject(); + return persistent_var_sp->GetValueObject(); } bool ValueObject::IsSyntheticChildrenGenerated() { @@ -3364,7 +3307,7 @@ lldb::ValueObjectSP ValueObjectManager::GetSP() { } if (m_use_synthetic) { - lldb::ValueObjectSP synthetic_sp = m_user_valobj_sp->GetSyntheticValue(m_use_synthetic); + lldb::ValueObjectSP synthetic_sp = m_user_valobj_sp->GetSyntheticValue(); if (synthetic_sp) m_user_valobj_sp = synthetic_sp; } diff --git a/gnu/llvm/lldb/source/Core/ValueObjectCast.cpp b/gnu/llvm/lldb/source/Core/ValueObjectCast.cpp index 3a74b6a7fe1..22e856be539 100644 --- a/gnu/llvm/lldb/source/Core/ValueObjectCast.cpp +++ b/gnu/llvm/lldb/source/Core/ValueObjectCast.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectCast.cpp -------------------------------------*- C++ -*-===// +//===-- ValueObjectCast.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -33,8 +33,6 @@ ValueObjectCast::ValueObjectCast(ValueObject &parent, ConstString name, const CompilerType &cast_type) : ValueObject(parent), m_cast_type(cast_type) { SetName(name); - // m_value.SetContext (Value::eContextTypeClangType, - // cast_type.GetOpaqueQualType()); m_value.SetCompilerType(cast_type); } @@ -68,7 +66,6 @@ bool ValueObjectCast::UpdateValue() { m_update_point.SetUpdated(); m_value = m_parent->GetValue(); CompilerType compiler_type(GetCompilerType()); - // m_value.SetContext (Value::eContextTypeClangType, compiler_type); m_value.SetCompilerType(compiler_type); SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren()); if (!CanProvideValue()) { diff --git a/gnu/llvm/lldb/source/Core/ValueObjectChild.cpp b/gnu/llvm/lldb/source/Core/ValueObjectChild.cpp index 6b4ada154d6..6205ed32c61 100644 --- a/gnu/llvm/lldb/source/Core/ValueObjectChild.cpp +++ b/gnu/llvm/lldb/source/Core/ValueObjectChild.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectChild.cpp ------------------------------------*- C++ -*-===// +//===-- ValueObjectChild.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -70,14 +70,14 @@ static void AdjustForBitfieldness(ConstString &name, ConstString ValueObjectChild::GetTypeName() { if (m_type_name.IsEmpty()) { - m_type_name = GetCompilerType().GetConstTypeName(); + m_type_name = GetCompilerType().GetTypeName(); AdjustForBitfieldness(m_type_name, m_bitfield_bit_size); } return m_type_name; } ConstString ValueObjectChild::GetQualifiedTypeName() { - ConstString qualified_name = GetCompilerType().GetConstTypeName(); + ConstString qualified_name = GetCompilerType().GetTypeName(); AdjustForBitfieldness(qualified_name, m_bitfield_bit_size); return qualified_name; } diff --git a/gnu/llvm/lldb/source/Core/ValueObjectConstResult.cpp b/gnu/llvm/lldb/source/Core/ValueObjectConstResult.cpp index 71620698da2..8d84f8e62cc 100644 --- a/gnu/llvm/lldb/source/Core/ValueObjectConstResult.cpp +++ b/gnu/llvm/lldb/source/Core/ValueObjectConstResult.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectConstResult.cpp ------------------------------*- C++ -*-===// +//===-- ValueObjectConstResult.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -29,16 +29,18 @@ ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope, ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address) { - return (new ValueObjectConstResult(exe_scope, byte_order, addr_byte_size, - address)) + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectConstResult(exe_scope, *manager_sp, byte_order, + addr_byte_size, address)) ->GetSP(); } ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address) - : ValueObject(exe_scope), m_type_name(), m_byte_size(0), + : ValueObject(exe_scope, manager), m_type_name(), m_byte_size(0), m_impl(this, address) { SetIsConstant(); SetValueIsValid(true); @@ -52,15 +54,17 @@ ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope, ConstString name, const DataExtractor &data, lldb::addr_t address) { - return (new ValueObjectConstResult(exe_scope, compiler_type, name, data, - address)) + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectConstResult(exe_scope, *manager_sp, compiler_type, + name, data, address)) ->GetSP(); } ValueObjectConstResult::ValueObjectConstResult( - ExecutionContextScope *exe_scope, const CompilerType &compiler_type, - ConstString name, const DataExtractor &data, lldb::addr_t address) - : ValueObject(exe_scope), m_type_name(), m_byte_size(0), + ExecutionContextScope *exe_scope, ValueObjectManager &manager, + const CompilerType &compiler_type, ConstString name, + const DataExtractor &data, lldb::addr_t address) + : ValueObject(exe_scope, manager), m_type_name(), m_byte_size(0), m_impl(this, address) { m_data = data; @@ -86,8 +90,10 @@ ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope, lldb::ByteOrder data_byte_order, uint32_t data_addr_size, lldb::addr_t address) { - return (new ValueObjectConstResult(exe_scope, compiler_type, name, data_sp, - data_byte_order, data_addr_size, address)) + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectConstResult(exe_scope, *manager_sp, compiler_type, + name, data_sp, data_byte_order, + data_addr_size, address)) ->GetSP(); } @@ -95,22 +101,24 @@ ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope, Value &value, ConstString name, Module *module) { - return (new ValueObjectConstResult(exe_scope, value, name, module))->GetSP(); + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectConstResult(exe_scope, *manager_sp, value, name, + module)) + ->GetSP(); } ValueObjectConstResult::ValueObjectConstResult( - ExecutionContextScope *exe_scope, const CompilerType &compiler_type, - ConstString name, const lldb::DataBufferSP &data_sp, - lldb::ByteOrder data_byte_order, uint32_t data_addr_size, - lldb::addr_t address) - : ValueObject(exe_scope), m_type_name(), m_byte_size(0), + ExecutionContextScope *exe_scope, ValueObjectManager &manager, + const CompilerType &compiler_type, ConstString name, + const lldb::DataBufferSP &data_sp, lldb::ByteOrder data_byte_order, + uint32_t data_addr_size, lldb::addr_t address) + : ValueObject(exe_scope, manager), m_type_name(), m_byte_size(0), m_impl(this, address) { m_data.SetByteOrder(data_byte_order); m_data.SetAddressByteSize(data_addr_size); m_data.SetData(data_sp); m_value.GetScalar() = (uintptr_t)data_sp->GetBytes(); m_value.SetValueType(Value::eValueTypeHostAddress); - // m_value.SetContext(Value::eContextTypeClangType, compiler_type); m_value.SetCompilerType(compiler_type); m_name = name; SetIsConstant(); @@ -124,16 +132,18 @@ ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope, lldb::addr_t address, AddressType address_type, uint32_t addr_byte_size) { - return (new ValueObjectConstResult(exe_scope, compiler_type, name, address, - address_type, addr_byte_size)) + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectConstResult(exe_scope, *manager_sp, compiler_type, + name, address, address_type, + addr_byte_size)) ->GetSP(); } ValueObjectConstResult::ValueObjectConstResult( - ExecutionContextScope *exe_scope, const CompilerType &compiler_type, - ConstString name, lldb::addr_t address, AddressType address_type, - uint32_t addr_byte_size) - : ValueObject(exe_scope), m_type_name(), m_byte_size(0), + ExecutionContextScope *exe_scope, ValueObjectManager &manager, + const CompilerType &compiler_type, ConstString name, lldb::addr_t address, + AddressType address_type, uint32_t addr_byte_size) + : ValueObject(exe_scope, manager), m_type_name(), m_byte_size(0), m_impl(this, address) { m_value.GetScalar() = address; m_data.SetAddressByteSize(addr_byte_size); @@ -153,7 +163,6 @@ ValueObjectConstResult::ValueObjectConstResult( m_value.SetValueType(Value::eValueTypeHostAddress); break; } - // m_value.SetContext(Value::eContextTypeClangType, compiler_type); m_value.SetCompilerType(compiler_type); m_name = name; SetIsConstant(); @@ -163,21 +172,25 @@ ValueObjectConstResult::ValueObjectConstResult( ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope, const Status &error) { - return (new ValueObjectConstResult(exe_scope, error))->GetSP(); + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectConstResult(exe_scope, *manager_sp, error))->GetSP(); } ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, const Status &error) - : ValueObject(exe_scope), m_type_name(), m_byte_size(0), m_impl(this) { + : ValueObject(exe_scope, manager), m_type_name(), m_byte_size(0), + m_impl(this) { m_error = error; SetIsConstant(); } ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, const Value &value, - ConstString name, - Module *module) - : ValueObject(exe_scope), m_type_name(), m_byte_size(0), m_impl(this) { + ConstString name, Module *module) + : ValueObject(exe_scope, manager), m_type_name(), m_byte_size(0), + m_impl(this) { m_value = value; m_name = name; ExecutionContext exe_ctx; @@ -215,7 +228,7 @@ size_t ValueObjectConstResult::CalculateNumChildren(uint32_t max) { ConstString ValueObjectConstResult::GetTypeName() { if (m_type_name.IsEmpty()) - m_type_name = GetCompilerType().GetConstTypeName(); + m_type_name = GetCompilerType().GetTypeName(); return m_type_name; } diff --git a/gnu/llvm/lldb/source/Core/ValueObjectConstResultCast.cpp b/gnu/llvm/lldb/source/Core/ValueObjectConstResultCast.cpp index b47e699e30f..53ec9db4554 100644 --- a/gnu/llvm/lldb/source/Core/ValueObjectConstResultCast.cpp +++ b/gnu/llvm/lldb/source/Core/ValueObjectConstResultCast.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectConstResultCast.cpp --------------------------*- C++ -*-===// +//===-- ValueObjectConstResultCast.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Core/ValueObjectConstResultChild.cpp b/gnu/llvm/lldb/source/Core/ValueObjectConstResultChild.cpp index 4e0b303b69d..13c8393d808 100644 --- a/gnu/llvm/lldb/source/Core/ValueObjectConstResultChild.cpp +++ b/gnu/llvm/lldb/source/Core/ValueObjectConstResultChild.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectConstResultChild.cpp --------------------------*- C++-*-===// +//===-- ValueObjectConstResultChild.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Core/ValueObjectConstResultImpl.cpp b/gnu/llvm/lldb/source/Core/ValueObjectConstResultImpl.cpp index de51735736b..e4cbbec849e 100644 --- a/gnu/llvm/lldb/source/Core/ValueObjectConstResultImpl.cpp +++ b/gnu/llvm/lldb/source/Core/ValueObjectConstResultImpl.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectConstResultImpl.cpp ---------------------------*- C++-*-===// +//===-- ValueObjectConstResultImpl.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,7 +18,6 @@ #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Scalar.h" -#include "lldb/Utility/SharingPtr.h" #include diff --git a/gnu/llvm/lldb/source/Core/ValueObjectDynamicValue.cpp b/gnu/llvm/lldb/source/Core/ValueObjectDynamicValue.cpp index 59037e2b6b2..ca66740cb55 100644 --- a/gnu/llvm/lldb/source/Core/ValueObjectDynamicValue.cpp +++ b/gnu/llvm/lldb/source/Core/ValueObjectDynamicValue.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectDynamicValue.cpp ------------------------------*- C++-*-===// +//===-- ValueObjectDynamicValue.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -237,7 +237,6 @@ bool ValueObjectDynamicValue::UpdateValue() { m_dynamic_type_info = runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent); - // m_value.SetContext (Value::eContextTypeClangType, corrected_type); m_value.SetCompilerType(m_dynamic_type_info.GetCompilerType()); m_value.SetValueType(value_type); @@ -328,7 +327,7 @@ bool ValueObjectDynamicValue::SetData(DataExtractor &data, Status &error) { // but NULL'ing out a value should always be allowed lldb::offset_t offset = 0; - if (data.GetPointer(&offset) != 0) { + if (data.GetAddress(&offset) != 0) { error.SetErrorString( "unable to modify dynamic value, use 'expression' command"); return false; diff --git a/gnu/llvm/lldb/source/Core/ValueObjectList.cpp b/gnu/llvm/lldb/source/Core/ValueObjectList.cpp index 358a1b14517..28907261f0a 100644 --- a/gnu/llvm/lldb/source/Core/ValueObjectList.cpp +++ b/gnu/llvm/lldb/source/Core/ValueObjectList.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectList.cpp -------------------------------------*- C++ -*-===// +//===-- ValueObjectList.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,7 +10,6 @@ #include "lldb/Core/ValueObject.h" #include "lldb/Utility/ConstString.h" -#include "lldb/Utility/SharingPtr.h" #include diff --git a/gnu/llvm/lldb/source/Core/ValueObjectMemory.cpp b/gnu/llvm/lldb/source/Core/ValueObjectMemory.cpp index 1a316bf3e7b..91b2c608492 100644 --- a/gnu/llvm/lldb/source/Core/ValueObjectMemory.cpp +++ b/gnu/llvm/lldb/source/Core/ValueObjectMemory.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectMemory.cpp ---------------------------------*- C++ -*-===// +//===-- ValueObjectMemory.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -32,21 +32,27 @@ ValueObjectSP ValueObjectMemory::Create(ExecutionContextScope *exe_scope, llvm::StringRef name, const Address &address, lldb::TypeSP &type_sp) { - return (new ValueObjectMemory(exe_scope, name, address, type_sp))->GetSP(); + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectMemory(exe_scope, *manager_sp, name, address, type_sp)) + ->GetSP(); } ValueObjectSP ValueObjectMemory::Create(ExecutionContextScope *exe_scope, llvm::StringRef name, const Address &address, const CompilerType &ast_type) { - return (new ValueObjectMemory(exe_scope, name, address, ast_type))->GetSP(); + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectMemory(exe_scope, *manager_sp, name, address, + ast_type)) + ->GetSP(); } ValueObjectMemory::ValueObjectMemory(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, llvm::StringRef name, const Address &address, lldb::TypeSP &type_sp) - : ValueObject(exe_scope), m_address(address), m_type_sp(type_sp), + : ValueObject(exe_scope, manager), m_address(address), m_type_sp(type_sp), m_compiler_type() { // Do not attempt to construct one of these objects with no variable! assert(m_type_sp.get() != nullptr); @@ -70,10 +76,11 @@ ValueObjectMemory::ValueObjectMemory(ExecutionContextScope *exe_scope, } ValueObjectMemory::ValueObjectMemory(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, llvm::StringRef name, const Address &address, const CompilerType &ast_type) - : ValueObject(exe_scope), m_address(address), m_type_sp(), + : ValueObject(exe_scope, manager), m_address(address), m_type_sp(), m_compiler_type(ast_type) { // Do not attempt to construct one of these objects with no variable! assert(m_compiler_type.GetTypeSystem()); @@ -82,8 +89,6 @@ ValueObjectMemory::ValueObjectMemory(ExecutionContextScope *exe_scope, TargetSP target_sp(GetTargetSP()); SetName(ConstString(name)); - // m_value.SetContext(Value::eContextTypeClangType, - // m_compiler_type.GetOpaqueQualType()); m_value.SetCompilerType(m_compiler_type); lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get()); if (load_address != LLDB_INVALID_ADDRESS) { @@ -112,7 +117,7 @@ CompilerType ValueObjectMemory::GetCompilerTypeImpl() { ConstString ValueObjectMemory::GetTypeName() { if (m_type_sp) return m_type_sp->GetName(); - return m_compiler_type.GetConstTypeName(); + return m_compiler_type.GetTypeName(); } ConstString ValueObjectMemory::GetDisplayTypeName() { @@ -204,8 +209,6 @@ bool ValueObjectMemory::UpdateValue() { if (m_type_sp) value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get()); else { - // value.SetContext(Value::eContextTypeClangType, - // m_compiler_type.GetOpaqueQualType()); value.SetCompilerType(m_compiler_type); } diff --git a/gnu/llvm/lldb/source/Core/ValueObjectRegister.cpp b/gnu/llvm/lldb/source/Core/ValueObjectRegister.cpp index 7e97df6d2a3..ec87c38fb36 100644 --- a/gnu/llvm/lldb/source/Core/ValueObjectRegister.cpp +++ b/gnu/llvm/lldb/source/Core/ValueObjectRegister.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectRegister.cpp ---------------------------------*- C++ -*-===// +//===-- ValueObjectRegister.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -35,86 +35,24 @@ class ExecutionContextScope; using namespace lldb; using namespace lldb_private; -#pragma mark ValueObjectRegisterContext - -ValueObjectRegisterContext::ValueObjectRegisterContext( - ValueObject &parent, RegisterContextSP ®_ctx) - : ValueObject(parent), m_reg_ctx_sp(reg_ctx) { - assert(reg_ctx); - m_name.SetCString("Registers"); - SetValueIsValid(true); -} - -ValueObjectRegisterContext::~ValueObjectRegisterContext() {} - -CompilerType ValueObjectRegisterContext::GetCompilerTypeImpl() { - return CompilerType(); -} - -ConstString ValueObjectRegisterContext::GetTypeName() { return ConstString(); } - -ConstString ValueObjectRegisterContext::GetDisplayTypeName() { - return ConstString(); -} - -ConstString ValueObjectRegisterContext::GetQualifiedTypeName() { - return ConstString(); -} - -size_t ValueObjectRegisterContext::CalculateNumChildren(uint32_t max) { - auto reg_set_count = m_reg_ctx_sp->GetRegisterSetCount(); - return reg_set_count <= max ? reg_set_count : max; -} - -uint64_t ValueObjectRegisterContext::GetByteSize() { return 0; } - -bool ValueObjectRegisterContext::UpdateValue() { - m_error.Clear(); - ExecutionContext exe_ctx(GetExecutionContextRef()); - StackFrame *frame = exe_ctx.GetFramePtr(); - if (frame) - m_reg_ctx_sp = frame->GetRegisterContext(); - else - m_reg_ctx_sp.reset(); - - if (m_reg_ctx_sp.get() == nullptr) { - SetValueIsValid(false); - m_error.SetErrorToGenericError(); - } else - SetValueIsValid(true); - - return m_error.Success(); -} - -ValueObject *ValueObjectRegisterContext::CreateChildAtIndex( - size_t idx, bool synthetic_array_member, int32_t synthetic_index) { - ValueObject *new_valobj = nullptr; - - const size_t num_children = GetNumChildren(); - if (idx < num_children) { - ExecutionContext exe_ctx(GetExecutionContextRef()); - new_valobj = new ValueObjectRegisterSet( - exe_ctx.GetBestExecutionContextScope(), m_reg_ctx_sp, idx); - } - - return new_valobj; -} - -#pragma mark - #pragma mark ValueObjectRegisterSet ValueObjectSP ValueObjectRegisterSet::Create(ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx_sp, uint32_t set_idx) { - return (new ValueObjectRegisterSet(exe_scope, reg_ctx_sp, set_idx))->GetSP(); + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectRegisterSet(exe_scope, *manager_sp, reg_ctx_sp, + set_idx)) + ->GetSP(); } ValueObjectRegisterSet::ValueObjectRegisterSet(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, lldb::RegisterContextSP ®_ctx, uint32_t reg_set_idx) - : ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_set(nullptr), - m_reg_set_idx(reg_set_idx) { + : ValueObject(exe_scope, manager), m_reg_ctx_sp(reg_ctx), + m_reg_set(nullptr), m_reg_set_idx(reg_set_idx) { assert(reg_ctx); m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx); if (m_reg_set) { @@ -192,7 +130,7 @@ ValueObjectRegisterSet::GetChildMemberWithName(ConstString name, ValueObject *valobj = nullptr; if (m_reg_ctx_sp && m_reg_set) { const RegisterInfo *reg_info = - m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString()); + m_reg_ctx_sp->GetRegisterInfoByName(name.GetStringRef()); if (reg_info != nullptr) valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info->kinds[eRegisterKindLLDB]); @@ -207,7 +145,7 @@ size_t ValueObjectRegisterSet::GetIndexOfChildWithName(ConstString name) { if (m_reg_ctx_sp && m_reg_set) { const RegisterInfo *reg_info = - m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString()); + m_reg_ctx_sp->GetRegisterInfoByName(name.GetStringRef()); if (reg_info != nullptr) return reg_info->kinds[eRegisterKindLLDB]; } @@ -240,13 +178,16 @@ ValueObjectRegister::ValueObjectRegister(ValueObject &parent, ValueObjectSP ValueObjectRegister::Create(ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx_sp, uint32_t reg_num) { - return (new ValueObjectRegister(exe_scope, reg_ctx_sp, reg_num))->GetSP(); + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectRegister(exe_scope, *manager_sp, reg_ctx_sp, reg_num)) + ->GetSP(); } ValueObjectRegister::ValueObjectRegister(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, lldb::RegisterContextSP ®_ctx, uint32_t reg_num) - : ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_info(), + : ValueObject(exe_scope, manager), m_reg_ctx_sp(reg_ctx), m_reg_info(), m_reg_value(), m_type_name(), m_compiler_type() { assert(reg_ctx); ConstructObject(reg_num); @@ -278,7 +219,7 @@ CompilerType ValueObjectRegister::GetCompilerTypeImpl() { ConstString ValueObjectRegister::GetTypeName() { if (m_type_name.IsEmpty()) - m_type_name = GetCompilerType().GetConstTypeName(); + m_type_name = GetCompilerType().GetTypeName(); return m_type_name; } @@ -357,7 +298,6 @@ bool ValueObjectRegister::ResolveValue(Scalar &scalar) { } void ValueObjectRegister::GetExpressionPath(Stream &s, - bool qualify_cxx_base_classes, GetExpressionPathFormat epformat) { s.Printf("$%s", m_reg_info.name); } diff --git a/gnu/llvm/lldb/source/Core/ValueObjectSyntheticFilter.cpp b/gnu/llvm/lldb/source/Core/ValueObjectSyntheticFilter.cpp index a30be1b0833..32d1e6ab836 100644 --- a/gnu/llvm/lldb/source/Core/ValueObjectSyntheticFilter.cpp +++ b/gnu/llvm/lldb/source/Core/ValueObjectSyntheticFilter.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectSyntheticFilter.cpp --------------------------*- C++ -*-===// +//===-- ValueObjectSyntheticFilter.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -14,7 +14,6 @@ #include "lldb/Target/ExecutionContext.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" -#include "lldb/Utility/SharingPtr.h" #include "lldb/Utility/Status.h" #include "llvm/ADT/STLExtras.h" @@ -54,7 +53,9 @@ ValueObjectSynthetic::ValueObjectSynthetic(ValueObject &parent, m_might_have_children(eLazyBoolCalculate), m_provides_value(eLazyBoolCalculate) { SetName(parent.GetName()); - CopyValueData(m_parent); + // Copying the data of an incomplete type won't work as it has no byte size. + if (m_parent->GetCompilerType().IsCompleteType()) + CopyValueData(m_parent); CreateSynthFilter(); } @@ -220,7 +221,9 @@ bool ValueObjectSynthetic::UpdateValue() { GetName().AsCString()); m_provides_value = eLazyBoolNo; - CopyValueData(m_parent); + // Copying the data of an incomplete type won't work as it has no byte size. + if (m_parent->GetCompilerType().IsCompleteType()) + CopyValueData(m_parent); } SetValueIsValid(true); diff --git a/gnu/llvm/lldb/source/Core/ValueObjectVariable.cpp b/gnu/llvm/lldb/source/Core/ValueObjectVariable.cpp index 240ebe1fdff..0d1e7b047a0 100644 --- a/gnu/llvm/lldb/source/Core/ValueObjectVariable.cpp +++ b/gnu/llvm/lldb/source/Core/ValueObjectVariable.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectVariable.cpp ---------------------------------*- C++ -*-===// +//===-- ValueObjectVariable.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -50,12 +50,14 @@ using namespace lldb_private; lldb::ValueObjectSP ValueObjectVariable::Create(ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp) { - return (new ValueObjectVariable(exe_scope, var_sp))->GetSP(); + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectVariable(exe_scope, *manager_sp, var_sp))->GetSP(); } ValueObjectVariable::ValueObjectVariable(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, const lldb::VariableSP &var_sp) - : ValueObject(exe_scope), m_variable_sp(var_sp) { + : ValueObject(exe_scope, manager), m_variable_sp(var_sp) { // Do not attempt to construct one of these objects with no variable! assert(m_variable_sp.get() != nullptr); m_name = var_sp->GetName(); @@ -166,6 +168,27 @@ bool ValueObjectVariable::UpdateValue() { Value::ValueType value_type = m_value.GetValueType(); + // The size of the buffer within m_value can be less than the size + // prescribed by its type. E.g. this can happen when an expression only + // partially describes an object (say, because it contains DW_OP_piece). + // + // In this case, grow m_value to the expected size. An alternative way to + // handle this is to teach Value::GetValueAsData() and ValueObjectChild + // not to read past the end of a host buffer, but this gets impractically + // complicated as a Value's host buffer may be shared with a distant + // ancestor or sibling in the ValueObject hierarchy. + // + // FIXME: When we grow m_value, we should represent the added bits as + // undefined somehow instead of as 0's. + if (value_type == Value::eValueTypeHostAddress && + compiler_type.IsValid()) { + if (size_t value_buf_size = m_value.GetBuffer().GetByteSize()) { + size_t value_size = m_value.GetValueByteSize(&m_error, &exe_ctx); + if (m_error.Success() && value_buf_size < value_size) + m_value.ResizeData(value_size); + } + } + Process *process = exe_ctx.GetProcessPtr(); const bool process_is_alive = process && process->IsAlive(); @@ -219,9 +242,64 @@ bool ValueObjectVariable::UpdateValue() { m_resolved_value.SetContext(Value::eContextTypeInvalid, nullptr); } } + return m_error.Success(); } +void ValueObjectVariable::DoUpdateChildrenAddressType(ValueObject &valobj) { + Value::ValueType value_type = valobj.GetValue().GetValueType(); + ExecutionContext exe_ctx(GetExecutionContextRef()); + Process *process = exe_ctx.GetProcessPtr(); + const bool process_is_alive = process && process->IsAlive(); + const uint32_t type_info = valobj.GetCompilerType().GetTypeInfo(); + const bool is_pointer_or_ref = + (type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0; + + switch (value_type) { + case Value::eValueTypeFileAddress: + // If this type is a pointer, then its children will be considered load + // addresses if the pointer or reference is dereferenced, but only if + // the process is alive. + // + // There could be global variables like in the following code: + // struct LinkedListNode { Foo* foo; LinkedListNode* next; }; + // Foo g_foo1; + // Foo g_foo2; + // LinkedListNode g_second_node = { &g_foo2, NULL }; + // LinkedListNode g_first_node = { &g_foo1, &g_second_node }; + // + // When we aren't running, we should be able to look at these variables + // using the "target variable" command. Children of the "g_first_node" + // always will be of the same address type as the parent. But children + // of the "next" member of LinkedListNode will become load addresses if + // we have a live process, or remain a file address if it was a file + // address. + if (process_is_alive && is_pointer_or_ref) + valobj.SetAddressTypeOfChildren(eAddressTypeLoad); + else + valobj.SetAddressTypeOfChildren(eAddressTypeFile); + break; + case Value::eValueTypeHostAddress: + // Same as above for load addresses, except children of pointer or refs + // are always load addresses. Host addresses are used to store freeze + // dried variables. If this type is a struct, the entire struct + // contents will be copied into the heap of the + // LLDB process, but we do not currently follow any pointers. + if (is_pointer_or_ref) + valobj.SetAddressTypeOfChildren(eAddressTypeLoad); + else + valobj.SetAddressTypeOfChildren(eAddressTypeHost); + break; + case Value::eValueTypeLoadAddress: + case Value::eValueTypeScalar: + case Value::eValueTypeVector: + valobj.SetAddressTypeOfChildren(eAddressTypeLoad); + break; + } +} + + + bool ValueObjectVariable::IsInScope() { const ExecutionContextRef &exe_ctx_ref = GetExecutionContextRef(); if (exe_ctx_ref.HasFrameRef()) { diff --git a/gnu/llvm/lldb/source/DataFormatters/CXXFunctionPointer.cpp b/gnu/llvm/lldb/source/DataFormatters/CXXFunctionPointer.cpp index 0ca000eb052..3b7b0bc27cf 100644 --- a/gnu/llvm/lldb/source/DataFormatters/CXXFunctionPointer.cpp +++ b/gnu/llvm/lldb/source/DataFormatters/CXXFunctionPointer.cpp @@ -1,4 +1,4 @@ -//===-- CXXFunctionPointer.cpp-----------------------------------*- C++ -*-===// +//===-- CXXFunctionPointer.cpp---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/DataFormatters/DataVisualization.cpp b/gnu/llvm/lldb/source/DataFormatters/DataVisualization.cpp index 99c303c9f0b..450a5cbc3ef 100644 --- a/gnu/llvm/lldb/source/DataFormatters/DataVisualization.cpp +++ b/gnu/llvm/lldb/source/DataFormatters/DataVisualization.cpp @@ -1,5 +1,4 @@ -//===-- DataVisualization.cpp ---------------------------------------*- C++ -//-*-===// +//===-- DataVisualization.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/DataFormatters/DumpValueObjectOptions.cpp b/gnu/llvm/lldb/source/DataFormatters/DumpValueObjectOptions.cpp index 84f21696e05..46a2a489586 100644 --- a/gnu/llvm/lldb/source/DataFormatters/DumpValueObjectOptions.cpp +++ b/gnu/llvm/lldb/source/DataFormatters/DumpValueObjectOptions.cpp @@ -1,5 +1,4 @@ -//===-- DumpValueObjectOptions.cpp -----------------------------------*- C++ -//-*-===// +//===-- DumpValueObjectOptions.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/DataFormatters/FormatCache.cpp b/gnu/llvm/lldb/source/DataFormatters/FormatCache.cpp index 99f14070544..5e0965fcdae 100644 --- a/gnu/llvm/lldb/source/DataFormatters/FormatCache.cpp +++ b/gnu/llvm/lldb/source/DataFormatters/FormatCache.cpp @@ -1,5 +1,4 @@ -//===-- FormatCache.cpp ------------------------------------------*- C++ -//-*-===// +//===-- FormatCache.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -52,15 +51,6 @@ void FormatCache::Entry::Set(lldb::SyntheticChildrenSP synthetic_sp) { m_synthetic_sp = synthetic_sp; } -FormatCache::FormatCache() - : m_map(), m_mutex() -#ifdef LLDB_CONFIGURATION_DEBUG - , - m_cache_hits(0), m_cache_misses(0) -#endif -{ -} - FormatCache::Entry &FormatCache::GetEntry(ConstString type) { auto i = m_map.find(type), e = m_map.end(); if (i != e) @@ -88,15 +78,11 @@ bool FormatCache::Get(ConstString type, ImplSP &format_impl_sp) { std::lock_guard guard(m_mutex); auto entry = GetEntry(type); if (entry.IsCached()) { -#ifdef LLDB_CONFIGURATION_DEBUG m_cache_hits++; -#endif entry.Get(format_impl_sp); return true; } -#ifdef LLDB_CONFIGURATION_DEBUG m_cache_misses++; -#endif format_impl_sp.reset(); return false; } diff --git a/gnu/llvm/lldb/source/DataFormatters/FormatClasses.cpp b/gnu/llvm/lldb/source/DataFormatters/FormatClasses.cpp index 6a9279f54d6..44fa96033bc 100644 --- a/gnu/llvm/lldb/source/DataFormatters/FormatClasses.cpp +++ b/gnu/llvm/lldb/source/DataFormatters/FormatClasses.cpp @@ -1,5 +1,4 @@ -//===-- FormatClasses.cpp ----------------------------------------*- C++ -//-*-===// +//===-- FormatClasses.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/DataFormatters/FormatManager.cpp b/gnu/llvm/lldb/source/DataFormatters/FormatManager.cpp index d5db3ee75bf..ad02d37360b 100644 --- a/gnu/llvm/lldb/source/DataFormatters/FormatManager.cpp +++ b/gnu/llvm/lldb/source/DataFormatters/FormatManager.cpp @@ -1,4 +1,4 @@ -//===-- FormatManager.cpp ----------------------------------------*- C++-*-===// +//===-- FormatManager.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -174,28 +174,27 @@ void FormatManager::DisableAllCategories() { } void FormatManager::GetPossibleMatches( - ValueObject &valobj, CompilerType compiler_type, uint32_t reason, + ValueObject &valobj, CompilerType compiler_type, lldb::DynamicValueType use_dynamic, FormattersMatchVector &entries, bool did_strip_ptr, bool did_strip_ref, bool did_strip_typedef, bool root_level) { compiler_type = compiler_type.GetTypeForFormatters(); - ConstString type_name(compiler_type.GetConstTypeName()); + ConstString type_name(compiler_type.GetTypeName()); if (valobj.GetBitfieldBitSize() > 0) { StreamString sstring; sstring.Printf("%s:%d", type_name.AsCString(), valobj.GetBitfieldBitSize()); ConstString bitfieldname(sstring.GetString()); entries.push_back( - {bitfieldname, 0, did_strip_ptr, did_strip_ref, did_strip_typedef}); - reason |= lldb_private::eFormatterChoiceCriterionStrippedBitField; + {bitfieldname, did_strip_ptr, did_strip_ref, did_strip_typedef}); } if (!compiler_type.IsMeaninglessWithoutDynamicResolution()) { entries.push_back( - {type_name, reason, did_strip_ptr, did_strip_ref, did_strip_typedef}); + {type_name, did_strip_ptr, did_strip_ref, did_strip_typedef}); - ConstString display_type_name(compiler_type.GetDisplayTypeName()); + ConstString display_type_name(compiler_type.GetTypeName()); if (display_type_name != type_name) - entries.push_back({display_type_name, reason, did_strip_ptr, + entries.push_back({display_type_name, did_strip_ptr, did_strip_ref, did_strip_typedef}); } @@ -204,8 +203,6 @@ void FormatManager::GetPossibleMatches( CompilerType non_ref_type = compiler_type.GetNonReferenceType(); GetPossibleMatches( valobj, non_ref_type, - reason | - lldb_private::eFormatterChoiceCriterionStrippedPointerReference, use_dynamic, entries, did_strip_ptr, true, did_strip_typedef); if (non_ref_type.IsTypedefType()) { CompilerType deffed_referenced_type = non_ref_type.GetTypedefedType(); @@ -214,7 +211,6 @@ void FormatManager::GetPossibleMatches( : deffed_referenced_type.GetLValueReferenceType(); GetPossibleMatches( valobj, deffed_referenced_type, - reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs, use_dynamic, entries, did_strip_ptr, did_strip_ref, true); // this is not exactly the usual meaning of stripping typedefs } @@ -224,8 +220,6 @@ void FormatManager::GetPossibleMatches( CompilerType non_ptr_type = compiler_type.GetPointeeType(); GetPossibleMatches( valobj, non_ptr_type, - reason | - lldb_private::eFormatterChoiceCriterionStrippedPointerReference, use_dynamic, entries, true, did_strip_ref, did_strip_typedef); if (non_ptr_type.IsTypedefType()) { CompilerType deffed_pointed_type = @@ -233,7 +227,6 @@ void FormatManager::GetPossibleMatches( const bool stripped_typedef = true; GetPossibleMatches( valobj, deffed_pointed_type, - reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs, use_dynamic, entries, did_strip_ptr, did_strip_ref, stripped_typedef); // this is not exactly the usual meaning of // stripping typedefs @@ -253,7 +246,6 @@ void FormatManager::GetPossibleMatches( const bool stripped_typedef = true; GetPossibleMatches( valobj, deffed_array_type, - reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs, use_dynamic, entries, did_strip_ptr, did_strip_ref, stripped_typedef); // this is not exactly the usual meaning of // stripping typedefs @@ -267,7 +259,6 @@ void FormatManager::GetPossibleMatches( language->GetPossibleFormattersMatches(valobj, use_dynamic)) { entries.push_back( {candidate, - reason | lldb_private::eFormatterChoiceCriterionLanguagePlugin, did_strip_ptr, did_strip_ref, did_strip_typedef}); } } @@ -278,7 +269,6 @@ void FormatManager::GetPossibleMatches( CompilerType deffed_type = compiler_type.GetTypedefedType(); GetPossibleMatches( valobj, deffed_type, - reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs, use_dynamic, entries, did_strip_ptr, did_strip_ref, true); } @@ -293,7 +283,7 @@ void FormatManager::GetPossibleMatches( break; if (unqual_compiler_ast_type.GetOpaqueQualType() != compiler_type.GetOpaqueQualType()) - GetPossibleMatches(valobj, unqual_compiler_ast_type, reason, + GetPossibleMatches(valobj, unqual_compiler_ast_type, use_dynamic, entries, did_strip_ptr, did_strip_ref, did_strip_typedef); } while (false); @@ -304,7 +294,6 @@ void FormatManager::GetPossibleMatches( if (static_value_sp) GetPossibleMatches( *static_value_sp.get(), static_value_sp->GetCompilerType(), - reason | lldb_private::eFormatterChoiceCriterionWentToStaticValue, use_dynamic, entries, did_strip_ptr, did_strip_ref, did_strip_typedef, true); } diff --git a/gnu/llvm/lldb/source/DataFormatters/FormattersHelpers.cpp b/gnu/llvm/lldb/source/DataFormatters/FormattersHelpers.cpp index b2a5a17595c..7944ff06eee 100644 --- a/gnu/llvm/lldb/source/DataFormatters/FormattersHelpers.cpp +++ b/gnu/llvm/lldb/source/DataFormatters/FormattersHelpers.cpp @@ -1,5 +1,4 @@ -//===-- FormattersHelpers.cpp -------------------------------------*- C++ -//-*-===// +//===-- FormattersHelpers.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -143,3 +142,14 @@ lldb_private::formatters::GetArrayAddressOrPointerValue(ValueObject &valobj) { return data_addr; } + +lldb::ValueObjectSP +lldb_private::formatters::GetValueOfLibCXXCompressedPair(ValueObject &pair) { + ValueObjectSP value = + pair.GetChildMemberWithName(ConstString("__value_"), true); + if (!value) { + // pre-r300140 member name + value = pair.GetChildMemberWithName(ConstString("__first_"), true); + } + return value; +} diff --git a/gnu/llvm/lldb/source/DataFormatters/LanguageCategory.cpp b/gnu/llvm/lldb/source/DataFormatters/LanguageCategory.cpp index daf8c7af7d1..4794186ce9a 100644 --- a/gnu/llvm/lldb/source/DataFormatters/LanguageCategory.cpp +++ b/gnu/llvm/lldb/source/DataFormatters/LanguageCategory.cpp @@ -1,5 +1,4 @@ -//===-- LanguageCategory.cpp ---------------------------------------*- C++ -//-*-===// +//===-- LanguageCategory.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/DataFormatters/StringPrinter.cpp b/gnu/llvm/lldb/source/DataFormatters/StringPrinter.cpp index 27d649bfc37..139f1ec0554 100644 --- a/gnu/llvm/lldb/source/DataFormatters/StringPrinter.cpp +++ b/gnu/llvm/lldb/source/DataFormatters/StringPrinter.cpp @@ -1,5 +1,4 @@ -//===-- StringPrinter.cpp ----------------------------------------*- C++ -//-*-===// +//===-- StringPrinter.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -16,6 +15,7 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/Status.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/ConvertUTF.h" #include @@ -25,15 +25,48 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; +using GetPrintableElementType = StringPrinter::GetPrintableElementType; +using StringElementType = StringPrinter::StringElementType; + +/// DecodedCharBuffer stores the decoded contents of a single character. It +/// avoids managing memory on the heap by copying decoded bytes into an in-line +/// buffer. +class DecodedCharBuffer { +public: + DecodedCharBuffer(std::nullptr_t) {} + + DecodedCharBuffer(const uint8_t *bytes, size_t size) : m_size(size) { + if (size > MaxLength) + llvm_unreachable("unsupported length"); + memcpy(m_data, bytes, size); + } + + DecodedCharBuffer(const char *bytes, size_t size) + : DecodedCharBuffer(reinterpret_cast(bytes), size) {} + + const uint8_t *GetBytes() const { return m_data; } + + size_t GetSize() const { return m_size; } + +private: + static constexpr unsigned MaxLength = 16; + + size_t m_size = 0; + uint8_t m_data[MaxLength] = {0}; +}; + +using EscapingHelper = + std::function; // we define this for all values of type but only implement it for those we // care about that's good because we get linker errors for any unsupported type -template -static StringPrinter::StringPrinterBufferPointer<> -GetPrintableImpl(uint8_t *buffer, uint8_t *buffer_end, uint8_t *&next); +template +static DecodedCharBuffer +GetPrintableImpl(uint8_t *buffer, uint8_t *buffer_end, uint8_t *&next, + StringPrinter::EscapeStyle escape_style); -// mimic isprint() for Unicode codepoints -static bool isprint(char32_t codepoint) { +// Mimic isprint() for Unicode codepoints. +static bool isprint32(char32_t codepoint) { if (codepoint <= 0x1F || codepoint == 0x7F) // C0 { return false; @@ -60,216 +93,174 @@ static bool isprint(char32_t codepoint) { return true; } -template <> -StringPrinter::StringPrinterBufferPointer<> -GetPrintableImpl(uint8_t *buffer, - uint8_t *buffer_end, - uint8_t *&next) { - StringPrinter::StringPrinterBufferPointer<> retval = {nullptr}; - - switch (*buffer) { +DecodedCharBuffer attemptASCIIEscape(llvm::UTF32 c, + StringPrinter::EscapeStyle escape_style) { + const bool is_swift_escape_style = + escape_style == StringPrinter::EscapeStyle::Swift; + switch (c) { case 0: - retval = {"\\0", 2}; - break; + return {"\\0", 2}; case '\a': - retval = {"\\a", 2}; - break; + return {"\\a", 2}; case '\b': - retval = {"\\b", 2}; - break; + if (is_swift_escape_style) + return nullptr; + return {"\\b", 2}; case '\f': - retval = {"\\f", 2}; - break; + if (is_swift_escape_style) + return nullptr; + return {"\\f", 2}; case '\n': - retval = {"\\n", 2}; - break; + return {"\\n", 2}; case '\r': - retval = {"\\r", 2}; - break; + return {"\\r", 2}; case '\t': - retval = {"\\t", 2}; - break; + return {"\\t", 2}; case '\v': - retval = {"\\v", 2}; - break; + if (is_swift_escape_style) + return nullptr; + return {"\\v", 2}; case '\"': - retval = {"\\\"", 2}; - break; + return {"\\\"", 2}; + case '\'': + if (is_swift_escape_style) + return {"\\'", 2}; + return nullptr; case '\\': - retval = {"\\\\", 2}; - break; - default: - if (isprint(*buffer)) - retval = {buffer, 1}; - else { - uint8_t *data = new uint8_t[5]; - sprintf((char *)data, "\\x%02x", *buffer); - retval = {data, 4, [](const uint8_t *c) { delete[] c; }}; - break; - } + return {"\\\\", 2}; } - - next = buffer + 1; - return retval; -} - -static char32_t ConvertUTF8ToCodePoint(unsigned char c0, unsigned char c1) { - return (c0 - 192) * 64 + (c1 - 128); -} -static char32_t ConvertUTF8ToCodePoint(unsigned char c0, unsigned char c1, - unsigned char c2) { - return (c0 - 224) * 4096 + (c1 - 128) * 64 + (c2 - 128); -} -static char32_t ConvertUTF8ToCodePoint(unsigned char c0, unsigned char c1, - unsigned char c2, unsigned char c3) { - return (c0 - 240) * 262144 + (c2 - 128) * 4096 + (c2 - 128) * 64 + (c3 - 128); + return nullptr; } template <> -StringPrinter::StringPrinterBufferPointer<> -GetPrintableImpl(uint8_t *buffer, - uint8_t *buffer_end, - uint8_t *&next) { - StringPrinter::StringPrinterBufferPointer<> retval{nullptr}; - - unsigned utf8_encoded_len = llvm::getNumBytesForUTF8(*buffer); - - if (1u + std::distance(buffer, buffer_end) < utf8_encoded_len) { - // I don't have enough bytes - print whatever I have left - retval = {buffer, static_cast(1 + buffer_end - buffer)}; - next = buffer_end + 1; +DecodedCharBuffer GetPrintableImpl( + uint8_t *buffer, uint8_t *buffer_end, uint8_t *&next, + StringPrinter::EscapeStyle escape_style) { + // The ASCII helper always advances 1 byte at a time. + next = buffer + 1; + + DecodedCharBuffer retval = attemptASCIIEscape(*buffer, escape_style); + if (retval.GetSize()) return retval; - } - char32_t codepoint = 0; - switch (utf8_encoded_len) { - case 1: - // this is just an ASCII byte - ask ASCII - return GetPrintableImpl( - buffer, buffer_end, next); - case 2: - codepoint = ConvertUTF8ToCodePoint((unsigned char)*buffer, - (unsigned char)*(buffer + 1)); - break; - case 3: - codepoint = ConvertUTF8ToCodePoint((unsigned char)*buffer, - (unsigned char)*(buffer + 1), - (unsigned char)*(buffer + 2)); + // Use llvm's locale-independent isPrint(char), instead of the libc + // implementation which may give different results on different platforms. + if (llvm::isPrint(*buffer)) + return {buffer, 1}; + + unsigned escaped_len; + constexpr unsigned max_buffer_size = 7; + uint8_t data[max_buffer_size]; + switch (escape_style) { + case StringPrinter::EscapeStyle::CXX: + // Prints 4 characters, then a \0 terminator. + escaped_len = sprintf((char *)data, "\\x%02x", *buffer); break; - case 4: - codepoint = ConvertUTF8ToCodePoint( - (unsigned char)*buffer, (unsigned char)*(buffer + 1), - (unsigned char)*(buffer + 2), (unsigned char)*(buffer + 3)); + case StringPrinter::EscapeStyle::Swift: + // Prints up to 6 characters, then a \0 terminator. + escaped_len = sprintf((char *)data, "\\u{%x}", *buffer); break; - default: - // this is probably some bogus non-character thing just print it as-is and - // hope to sync up again soon - retval = {buffer, 1}; - next = buffer + 1; - return retval; } + lldbassert(escaped_len > 0 && "unknown string escape style"); + return {data, escaped_len}; +} - if (codepoint) { - switch (codepoint) { - case 0: - retval = {"\\0", 2}; - break; - case '\a': - retval = {"\\a", 2}; - break; - case '\b': - retval = {"\\b", 2}; - break; - case '\f': - retval = {"\\f", 2}; - break; - case '\n': - retval = {"\\n", 2}; - break; - case '\r': - retval = {"\\r", 2}; - break; - case '\t': - retval = {"\\t", 2}; - break; - case '\v': - retval = {"\\v", 2}; - break; - case '\"': - retval = {"\\\"", 2}; - break; - case '\\': - retval = {"\\\\", 2}; - break; - default: - if (isprint(codepoint)) - retval = {buffer, utf8_encoded_len}; - else { - uint8_t *data = new uint8_t[11]; - sprintf((char *)data, "\\U%08x", (unsigned)codepoint); - retval = {data, 10, [](const uint8_t *c) { delete[] c; }}; - break; - } - } - - next = buffer + utf8_encoded_len; +template <> +DecodedCharBuffer GetPrintableImpl( + uint8_t *buffer, uint8_t *buffer_end, uint8_t *&next, + StringPrinter::EscapeStyle escape_style) { + // If the utf8 encoded length is invalid (i.e., not in the closed interval + // [1;4]), or if there aren't enough bytes to print, or if the subsequence + // isn't valid utf8, fall back to printing an ASCII-escaped subsequence. + if (!llvm::isLegalUTF8Sequence(buffer, buffer_end)) + return GetPrintableImpl(buffer, buffer_end, next, + escape_style); + + // Convert the valid utf8 sequence to a utf32 codepoint. This cannot fail. + llvm::UTF32 codepoint = 0; + const llvm::UTF8 *buffer_for_conversion = buffer; + llvm::ConversionResult result = llvm::convertUTF8Sequence( + &buffer_for_conversion, buffer_end, &codepoint, llvm::strictConversion); + assert(result == llvm::conversionOK && + "Failed to convert legal utf8 sequence"); + (void)result; + + // The UTF8 helper always advances by the utf8 encoded length. + const unsigned utf8_encoded_len = buffer_for_conversion - buffer; + next = buffer + utf8_encoded_len; + + DecodedCharBuffer retval = attemptASCIIEscape(codepoint, escape_style); + if (retval.GetSize()) return retval; + if (isprint32(codepoint)) + return {buffer, utf8_encoded_len}; + + unsigned escaped_len; + constexpr unsigned max_buffer_size = 13; + uint8_t data[max_buffer_size]; + switch (escape_style) { + case StringPrinter::EscapeStyle::CXX: + // Prints 10 characters, then a \0 terminator. + escaped_len = sprintf((char *)data, "\\U%08x", codepoint); + break; + case StringPrinter::EscapeStyle::Swift: + // Prints up to 12 characters, then a \0 terminator. + escaped_len = sprintf((char *)data, "\\u{%x}", codepoint); + break; } - - // this should not happen - but just in case.. try to resync at some point - retval = {buffer, 1}; - next = buffer + 1; - return retval; + lldbassert(escaped_len > 0 && "unknown string escape style"); + return {data, escaped_len}; } // Given a sequence of bytes, this function returns: a sequence of bytes to // actually print out + a length the following unscanned position of the buffer // is in next -static StringPrinter::StringPrinterBufferPointer<> -GetPrintable(StringPrinter::StringElementType type, uint8_t *buffer, - uint8_t *buffer_end, uint8_t *&next) { - if (!buffer) +static DecodedCharBuffer GetPrintable(StringElementType type, uint8_t *buffer, + uint8_t *buffer_end, uint8_t *&next, + StringPrinter::EscapeStyle escape_style) { + if (!buffer || buffer >= buffer_end) return {nullptr}; switch (type) { - case StringPrinter::StringElementType::ASCII: - return GetPrintableImpl( - buffer, buffer_end, next); - case StringPrinter::StringElementType::UTF8: - return GetPrintableImpl( - buffer, buffer_end, next); + case StringElementType::ASCII: + return GetPrintableImpl(buffer, buffer_end, next, + escape_style); + case StringElementType::UTF8: + return GetPrintableImpl(buffer, buffer_end, next, + escape_style); default: return {nullptr}; } } -StringPrinter::EscapingHelper -StringPrinter::GetDefaultEscapingHelper(GetPrintableElementType elem_type) { +static EscapingHelper +GetDefaultEscapingHelper(GetPrintableElementType elem_type, + StringPrinter::EscapeStyle escape_style) { switch (elem_type) { case GetPrintableElementType::UTF8: - return [](uint8_t *buffer, uint8_t *buffer_end, - uint8_t *&next) -> StringPrinter::StringPrinterBufferPointer<> { - return GetPrintable(StringPrinter::StringElementType::UTF8, buffer, - buffer_end, next); - }; case GetPrintableElementType::ASCII: - return [](uint8_t *buffer, uint8_t *buffer_end, - uint8_t *&next) -> StringPrinter::StringPrinterBufferPointer<> { - return GetPrintable(StringPrinter::StringElementType::ASCII, buffer, - buffer_end, next); + return [escape_style, elem_type](uint8_t *buffer, uint8_t *buffer_end, + uint8_t *&next) -> DecodedCharBuffer { + return GetPrintable(elem_type == GetPrintableElementType::UTF8 + ? StringElementType::UTF8 + : StringElementType::ASCII, + buffer, buffer_end, next, escape_style); }; } llvm_unreachable("bad element type"); } -// use this call if you already have an LLDB-side buffer for the data +/// Read a string encoded in accordance with \tparam SourceDataType from a +/// host-side LLDB buffer, then pretty-print it to a stream using \p style. template -static bool DumpUTFBufferToStream( +static bool DumpEncodedBufferToStream( + GetPrintableElementType style, llvm::ConversionResult (*ConvertFunction)(const SourceDataType **, const SourceDataType *, llvm::UTF8 **, llvm::UTF8 *, llvm::ConversionFlags), const StringPrinter::ReadBufferAndDumpToStreamOptions &dump_options) { + assert(dump_options.GetStream() && "need a Stream to print the string to"); Stream &stream(*dump_options.GetStream()); if (dump_options.GetPrefixToken() != nullptr) stream.Printf("%s", dump_options.GetPrefixToken()); @@ -329,18 +320,10 @@ static bool DumpUTFBufferToStream( } const bool escape_non_printables = dump_options.GetEscapeNonPrintables(); - lldb_private::formatters::StringPrinter::EscapingHelper escaping_callback; - if (escape_non_printables) { - if (Language *language = Language::FindPlugin(dump_options.GetLanguage())) - escaping_callback = language->GetStringPrinterEscapingHelper( - lldb_private::formatters::StringPrinter::GetPrintableElementType:: - UTF8); - else - escaping_callback = - lldb_private::formatters::StringPrinter::GetDefaultEscapingHelper( - lldb_private::formatters::StringPrinter:: - GetPrintableElementType::UTF8); - } + EscapingHelper escaping_callback; + if (escape_non_printables) + escaping_callback = + GetDefaultEscapingHelper(style, dump_options.GetEscapeStyle()); // since we tend to accept partial data (and even partially malformed data) // we might end up with no NULL terminator before the end_ptr hence we need @@ -355,13 +338,11 @@ static bool DumpUTFBufferToStream( escaping_callback(utf8_data_ptr, utf8_data_end_ptr, next_data); auto printable_bytes = printable.GetBytes(); auto printable_size = printable.GetSize(); - if (!printable_bytes || !next_data) { - // GetPrintable() failed on us - print one byte in a desperate resync - // attempt - printable_bytes = utf8_data_ptr; - printable_size = 1; - next_data = utf8_data_ptr + 1; - } + + // We failed to figure out how to print this string. + if (!printable_bytes || !next_data) + return false; + for (unsigned c = 0; c < printable_size; c++) stream.Printf("%c", *(printable_bytes + c)); utf8_data_ptr = (uint8_t *)next_data; @@ -404,173 +385,91 @@ lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStreamOptions:: SetQuote(options.GetQuote()); SetEscapeNonPrintables(options.GetEscapeNonPrintables()); SetBinaryZeroIsTerminator(options.GetBinaryZeroIsTerminator()); - SetLanguage(options.GetLanguage()); + SetEscapeStyle(options.GetEscapeStyle()); } namespace lldb_private { namespace formatters { -template <> -bool StringPrinter::ReadStringAndDumpToStream< - StringPrinter::StringElementType::ASCII>( - const ReadStringAndDumpToStreamOptions &options) { - assert(options.GetStream() && "need a Stream to print the string to"); - Status my_error; - - ProcessSP process_sp(options.GetProcessSP()); - - if (process_sp.get() == nullptr || options.GetLocation() == 0) - return false; - - size_t size; - const auto max_size = process_sp->GetTarget().GetMaximumSizeOfStringSummary(); - bool is_truncated = false; - - if (options.GetSourceSize() == 0) - size = max_size; - else if (!options.GetIgnoreMaxLength()) { - size = options.GetSourceSize(); - if (size > max_size) { - size = max_size; - is_truncated = true; - } - } else - size = options.GetSourceSize(); - - lldb::DataBufferSP buffer_sp(new DataBufferHeap(size, 0)); - - process_sp->ReadCStringFromMemory( - options.GetLocation(), (char *)buffer_sp->GetBytes(), size, my_error); - - if (my_error.Fail()) - return false; - - const char *prefix_token = options.GetPrefixToken(); - char quote = options.GetQuote(); - - if (prefix_token != nullptr) - options.GetStream()->Printf("%s%c", prefix_token, quote); - else if (quote != 0) - options.GetStream()->Printf("%c", quote); - - uint8_t *data_end = buffer_sp->GetBytes() + buffer_sp->GetByteSize(); - - const bool escape_non_printables = options.GetEscapeNonPrintables(); - lldb_private::formatters::StringPrinter::EscapingHelper escaping_callback; - if (escape_non_printables) { - if (Language *language = Language::FindPlugin(options.GetLanguage())) - escaping_callback = language->GetStringPrinterEscapingHelper( - lldb_private::formatters::StringPrinter::GetPrintableElementType:: - ASCII); - else - escaping_callback = - lldb_private::formatters::StringPrinter::GetDefaultEscapingHelper( - lldb_private::formatters::StringPrinter::GetPrintableElementType:: - ASCII); - } - - // since we tend to accept partial data (and even partially malformed data) - // we might end up with no NULL terminator before the end_ptr hence we need - // to take a slower route and ensure we stay within boundaries - for (uint8_t *data = buffer_sp->GetBytes(); *data && (data < data_end);) { - if (escape_non_printables) { - uint8_t *next_data = nullptr; - auto printable = escaping_callback(data, data_end, next_data); - auto printable_bytes = printable.GetBytes(); - auto printable_size = printable.GetSize(); - if (!printable_bytes || !next_data) { - // GetPrintable() failed on us - print one byte in a desperate resync - // attempt - printable_bytes = data; - printable_size = 1; - next_data = data + 1; - } - for (unsigned c = 0; c < printable_size; c++) - options.GetStream()->Printf("%c", *(printable_bytes + c)); - data = (uint8_t *)next_data; - } else { - options.GetStream()->Printf("%c", *data); - data++; - } - } - - const char *suffix_token = options.GetSuffixToken(); - - if (suffix_token != nullptr) - options.GetStream()->Printf("%c%s", quote, suffix_token); - else if (quote != 0) - options.GetStream()->Printf("%c", quote); - - if (is_truncated) - options.GetStream()->Printf("..."); - - return true; -} - template -static bool ReadUTFBufferAndDumpToStream( +static bool ReadEncodedBufferAndDumpToStream( + StringElementType elem_type, const StringPrinter::ReadStringAndDumpToStreamOptions &options, llvm::ConversionResult (*ConvertFunction)(const SourceDataType **, const SourceDataType *, llvm::UTF8 **, llvm::UTF8 *, llvm::ConversionFlags)) { assert(options.GetStream() && "need a Stream to print the string to"); + if (!options.GetStream()) + return false; if (options.GetLocation() == 0 || options.GetLocation() == LLDB_INVALID_ADDRESS) return false; lldb::ProcessSP process_sp(options.GetProcessSP()); - if (!process_sp) return false; - const int type_width = sizeof(SourceDataType); - const int origin_encoding = 8 * type_width; + constexpr int type_width = sizeof(SourceDataType); + constexpr int origin_encoding = 8 * type_width; if (origin_encoding != 8 && origin_encoding != 16 && origin_encoding != 32) return false; - // if not UTF8, I need a conversion function to return proper UTF8 + // If not UTF8 or ASCII, conversion to UTF8 is necessary. if (origin_encoding != 8 && !ConvertFunction) return false; - if (!options.GetStream()) - return false; - - uint32_t sourceSize = options.GetSourceSize(); bool needs_zero_terminator = options.GetNeedsZeroTermination(); bool is_truncated = false; const auto max_size = process_sp->GetTarget().GetMaximumSizeOfStringSummary(); - if (!sourceSize) { + uint32_t sourceSize; + if (elem_type == StringElementType::ASCII && !options.GetSourceSize()) { + // FIXME: The NSString formatter sets HasSourceSize(true) when the size is + // actually unknown, as well as SetBinaryZeroIsTerminator(false). IIUC the + // C++ formatter also sets SetBinaryZeroIsTerminator(false) when it doesn't + // mean to. I don't see how this makes sense: we should fix the formatters. + // + // Until then, the behavior that's expected for ASCII strings with unknown + // lengths is to read up to the max size and then null-terminate. Do that. sourceSize = max_size; needs_zero_terminator = true; - } else if (!options.GetIgnoreMaxLength()) { - if (sourceSize > max_size) { - sourceSize = max_size; - is_truncated = true; + } else if (options.HasSourceSize()) { + sourceSize = options.GetSourceSize(); + if (!options.GetIgnoreMaxLength()) { + if (sourceSize > max_size) { + sourceSize = max_size; + is_truncated = true; + } } + } else { + sourceSize = max_size; + needs_zero_terminator = true; } const int bufferSPSize = sourceSize * type_width; - lldb::DataBufferSP buffer_sp(new DataBufferHeap(bufferSPSize, 0)); - if (!buffer_sp->GetBytes()) + // Check if we got bytes. We never get any bytes if we have an empty + // string, but we still continue so that we end up actually printing + // an empty string (""). + if (sourceSize != 0 && !buffer_sp->GetBytes()) return false; Status error; char *buffer = reinterpret_cast(buffer_sp->GetBytes()); - if (needs_zero_terminator) + if (elem_type == StringElementType::ASCII) + process_sp->ReadCStringFromMemory(options.GetLocation(), buffer, + bufferSPSize, error); + else if (needs_zero_terminator) process_sp->ReadStringFromMemory(options.GetLocation(), buffer, bufferSPSize, error, type_width); else - process_sp->ReadMemoryFromInferior(options.GetLocation(), - (char *)buffer_sp->GetBytes(), + process_sp->ReadMemoryFromInferior(options.GetLocation(), buffer, bufferSPSize, error); - if (error.Fail()) { options.GetStream()->Printf("unable to read data"); return true; @@ -583,67 +482,79 @@ static bool ReadUTFBufferAndDumpToStream( dump_options.SetData(data); dump_options.SetSourceSize(sourceSize); dump_options.SetIsTruncated(is_truncated); + dump_options.SetNeedsZeroTermination(needs_zero_terminator); + if (needs_zero_terminator) + dump_options.SetBinaryZeroIsTerminator(true); - return DumpUTFBufferToStream(ConvertFunction, dump_options); + GetPrintableElementType print_style = (elem_type == StringElementType::ASCII) + ? GetPrintableElementType::ASCII + : GetPrintableElementType::UTF8; + return DumpEncodedBufferToStream(print_style, ConvertFunction, dump_options); } template <> -bool StringPrinter::ReadStringAndDumpToStream< - StringPrinter::StringElementType::UTF8>( +bool StringPrinter::ReadStringAndDumpToStream( const ReadStringAndDumpToStreamOptions &options) { - return ReadUTFBufferAndDumpToStream(options, nullptr); + return ReadEncodedBufferAndDumpToStream(StringElementType::UTF8, + options, nullptr); } template <> -bool StringPrinter::ReadStringAndDumpToStream< - StringPrinter::StringElementType::UTF16>( +bool StringPrinter::ReadStringAndDumpToStream( const ReadStringAndDumpToStreamOptions &options) { - return ReadUTFBufferAndDumpToStream(options, - llvm::ConvertUTF16toUTF8); + return ReadEncodedBufferAndDumpToStream( + StringElementType::UTF16, options, llvm::ConvertUTF16toUTF8); } template <> -bool StringPrinter::ReadStringAndDumpToStream< - StringPrinter::StringElementType::UTF32>( +bool StringPrinter::ReadStringAndDumpToStream( const ReadStringAndDumpToStreamOptions &options) { - return ReadUTFBufferAndDumpToStream(options, - llvm::ConvertUTF32toUTF8); + return ReadEncodedBufferAndDumpToStream( + StringElementType::UTF32, options, llvm::ConvertUTF32toUTF8); } template <> -bool StringPrinter::ReadBufferAndDumpToStream< - StringPrinter::StringElementType::UTF8>( - const ReadBufferAndDumpToStreamOptions &options) { - assert(options.GetStream() && "need a Stream to print the string to"); - - return DumpUTFBufferToStream(nullptr, options); +bool StringPrinter::ReadStringAndDumpToStream( + const ReadStringAndDumpToStreamOptions &options) { + return ReadEncodedBufferAndDumpToStream(StringElementType::ASCII, + options, nullptr); } template <> -bool StringPrinter::ReadBufferAndDumpToStream< - StringPrinter::StringElementType::ASCII>( +bool StringPrinter::ReadBufferAndDumpToStream( const ReadBufferAndDumpToStreamOptions &options) { - // treat ASCII the same as UTF8 - // FIXME: can we optimize ASCII some more? - return ReadBufferAndDumpToStream(options); + return DumpEncodedBufferToStream(GetPrintableElementType::UTF8, + nullptr, options); } template <> -bool StringPrinter::ReadBufferAndDumpToStream< - StringPrinter::StringElementType::UTF16>( +bool StringPrinter::ReadBufferAndDumpToStream( const ReadBufferAndDumpToStreamOptions &options) { - assert(options.GetStream() && "need a Stream to print the string to"); - - return DumpUTFBufferToStream(llvm::ConvertUTF16toUTF8, options); + return DumpEncodedBufferToStream(GetPrintableElementType::UTF8, + llvm::ConvertUTF16toUTF8, options); } template <> -bool StringPrinter::ReadBufferAndDumpToStream< - StringPrinter::StringElementType::UTF32>( +bool StringPrinter::ReadBufferAndDumpToStream( const ReadBufferAndDumpToStreamOptions &options) { - assert(options.GetStream() && "need a Stream to print the string to"); + return DumpEncodedBufferToStream(GetPrintableElementType::UTF8, + llvm::ConvertUTF32toUTF8, options); +} - return DumpUTFBufferToStream(llvm::ConvertUTF32toUTF8, options); +template <> +bool StringPrinter::ReadBufferAndDumpToStream( + const ReadBufferAndDumpToStreamOptions &options) { + // Treat ASCII the same as UTF8. + // + // FIXME: This is probably not the right thing to do (well, it's debatable). + // If an ASCII-encoded string happens to contain a sequence of invalid bytes + // that forms a valid UTF8 character, we'll print out that character. This is + // good if you're playing fast and loose with encodings (probably good for + // std::string users), but maybe not so good if you care about your string + // formatter respecting the semantics of your selected string encoding. In + // the latter case you'd want to see the character byte sequence ('\x..'), not + // the UTF8 character itself. + return ReadBufferAndDumpToStream(options); } } // namespace formatters diff --git a/gnu/llvm/lldb/source/DataFormatters/TypeCategory.cpp b/gnu/llvm/lldb/source/DataFormatters/TypeCategory.cpp index 85699691f52..8368c91a57f 100644 --- a/gnu/llvm/lldb/source/DataFormatters/TypeCategory.cpp +++ b/gnu/llvm/lldb/source/DataFormatters/TypeCategory.cpp @@ -1,4 +1,4 @@ -//===-- TypeCategory.cpp -----------------------------------------*- C++-*-===// +//===-- TypeCategory.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -86,51 +86,41 @@ void TypeCategoryImpl::AddLanguage(lldb::LanguageType lang) { bool TypeCategoryImpl::Get(lldb::LanguageType lang, const FormattersMatchVector &candidates, - lldb::TypeFormatImplSP &entry, uint32_t *reason) { + lldb::TypeFormatImplSP &entry) { if (!IsEnabled() || !IsApplicable(lang)) return false; - if (GetTypeFormatsContainer()->Get(candidates, entry, reason)) + if (GetTypeFormatsContainer()->Get(candidates, entry)) return true; - bool regex = GetRegexTypeFormatsContainer()->Get(candidates, entry, reason); - if (regex && reason) - *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary; + bool regex = GetRegexTypeFormatsContainer()->Get(candidates, entry); return regex; } bool TypeCategoryImpl::Get(lldb::LanguageType lang, const FormattersMatchVector &candidates, - lldb::TypeSummaryImplSP &entry, uint32_t *reason) { + lldb::TypeSummaryImplSP &entry) { if (!IsEnabled() || !IsApplicable(lang)) return false; - if (GetTypeSummariesContainer()->Get(candidates, entry, reason)) + if (GetTypeSummariesContainer()->Get(candidates, entry)) return true; - bool regex = GetRegexTypeSummariesContainer()->Get(candidates, entry, reason); - if (regex && reason) - *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary; + bool regex = GetRegexTypeSummariesContainer()->Get(candidates, entry); return regex; } bool TypeCategoryImpl::Get(lldb::LanguageType lang, const FormattersMatchVector &candidates, - lldb::SyntheticChildrenSP &entry, uint32_t *reason) { + lldb::SyntheticChildrenSP &entry) { if (!IsEnabled() || !IsApplicable(lang)) return false; TypeFilterImpl::SharedPointer filter_sp; - uint32_t reason_filter = 0; - bool regex_filter = false; // first find both Filter and Synth, and then check which is most recent - if (!GetTypeFiltersContainer()->Get(candidates, filter_sp, &reason_filter)) - regex_filter = GetRegexTypeFiltersContainer()->Get(candidates, filter_sp, - &reason_filter); + if (!GetTypeFiltersContainer()->Get(candidates, filter_sp)) + GetRegexTypeFiltersContainer()->Get(candidates, filter_sp); - bool regex_synth = false; - uint32_t reason_synth = 0; bool pick_synth = false; ScriptedSyntheticChildren::SharedPointer synth; - if (!GetTypeSyntheticsContainer()->Get(candidates, synth, &reason_synth)) - regex_synth = GetRegexTypeSyntheticsContainer()->Get(candidates, synth, - &reason_synth); + if (!GetTypeSyntheticsContainer()->Get(candidates, synth)) + GetRegexTypeSyntheticsContainer()->Get(candidates, synth); if (!filter_sp.get() && !synth.get()) return false; else if (!filter_sp.get() && synth.get()) @@ -144,13 +134,9 @@ bool TypeCategoryImpl::Get(lldb::LanguageType lang, pick_synth = filter_sp->GetRevision() <= synth->GetRevision(); } if (pick_synth) { - if (regex_synth && reason) - *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter; entry = synth; return true; } else { - if (regex_filter && reason) - *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter; entry = filter_sp; return true; } @@ -492,5 +478,5 @@ std::string TypeCategoryImpl::GetDescription() { if (print_lang) stream.PutCString(lang_stream.GetString()); stream.PutChar(')'); - return stream.GetString(); + return std::string(stream.GetString()); } diff --git a/gnu/llvm/lldb/source/DataFormatters/TypeCategoryMap.cpp b/gnu/llvm/lldb/source/DataFormatters/TypeCategoryMap.cpp index ac515154299..a011c5414ee 100644 --- a/gnu/llvm/lldb/source/DataFormatters/TypeCategoryMap.cpp +++ b/gnu/llvm/lldb/source/DataFormatters/TypeCategoryMap.cpp @@ -1,5 +1,4 @@ -//===-- TypeCategoryMap.cpp ----------------------------------------*- C++ -//-*-===// +//===-- TypeCategoryMap.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -173,7 +172,6 @@ template void TypeCategoryMap::Get(FormattersMatchData &match_data, ImplSP &retval) { std::lock_guard guard(m_map_mutex); - uint32_t reason_why; ActiveCategoriesIterator begin, end = m_active_categories.end(); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS)); @@ -182,13 +180,12 @@ void TypeCategoryMap::Get(FormattersMatchData &match_data, ImplSP &retval) { for (auto match : match_data.GetMatchesVector()) { LLDB_LOGF( log, - "[%s] candidate match = %s %s %s %s reason = %" PRIu32, + "[%s] candidate match = %s %s %s %s", __FUNCTION__, match.GetTypeName().GetCString(), match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers", match.DidStripReference() ? "strip-reference" : "no-strip-reference", - match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef", - match.GetReason()); + match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef"); } } @@ -199,7 +196,7 @@ void TypeCategoryMap::Get(FormattersMatchData &match_data, ImplSP &retval) { category_sp->GetName()); if (!category_sp->Get( match_data.GetValueObject().GetObjectRuntimeLanguage(), - match_data.GetMatchesVector(), current_format, &reason_why)) + match_data.GetMatchesVector(), current_format)) continue; retval = std::move(current_format); diff --git a/gnu/llvm/lldb/source/DataFormatters/TypeFormat.cpp b/gnu/llvm/lldb/source/DataFormatters/TypeFormat.cpp index b272c2e8dc3..b9a9447c5f3 100644 --- a/gnu/llvm/lldb/source/DataFormatters/TypeFormat.cpp +++ b/gnu/llvm/lldb/source/DataFormatters/TypeFormat.cpp @@ -1,4 +1,4 @@ -//===-- TypeFormat.cpp ----------------------------------------*- C++ -*-===// +//===-- TypeFormat.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -60,7 +60,7 @@ bool TypeFormatImpl_Format::FormatObject(ValueObject *valobj, DumpDataExtractor(data, ®_sstr, 0, GetFormat(), reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0, exe_ctx.GetBestExecutionContextScope()); - dest = reg_sstr.GetString(); + dest = std::string(reg_sstr.GetString()); } } else { CompilerType compiler_type = value.GetCompilerType(); @@ -114,7 +114,7 @@ bool TypeFormatImpl_Format::FormatObject(ValueObject *valobj, // here, but that's about as severe as we get // CompilerType::DumpTypeValue() should always return something, even // if that something is an error message - dest = sstr.GetString(); + dest = std::string(sstr.GetString()); } } return !dest.empty(); @@ -128,7 +128,7 @@ std::string TypeFormatImpl_Format::GetDescription() { Cascades() ? "" : " (not cascading)", SkipsPointers() ? " (skip pointers)" : "", SkipsReferences() ? " (skip references)" : ""); - return sstr.GetString(); + return std::string(sstr.GetString()); } TypeFormatImpl_EnumType::TypeFormatImpl_EnumType( @@ -191,7 +191,7 @@ bool TypeFormatImpl_EnumType::FormatObject(ValueObject *valobj, data.GetByteSize(), 0, 0, exe_ctx.GetBestExecutionContextScope()); if (!sstr.GetString().empty()) - dest = sstr.GetString(); + dest = std::string(sstr.GetString()); return !dest.empty(); } @@ -201,5 +201,5 @@ std::string TypeFormatImpl_EnumType::GetDescription() { Cascades() ? "" : " (not cascading)", SkipsPointers() ? " (skip pointers)" : "", SkipsReferences() ? " (skip references)" : ""); - return sstr.GetString(); + return std::string(sstr.GetString()); } diff --git a/gnu/llvm/lldb/source/DataFormatters/TypeSummary.cpp b/gnu/llvm/lldb/source/DataFormatters/TypeSummary.cpp index 7f6930fdf41..5d4fe2e467f 100644 --- a/gnu/llvm/lldb/source/DataFormatters/TypeSummary.cpp +++ b/gnu/llvm/lldb/source/DataFormatters/TypeSummary.cpp @@ -1,4 +1,4 @@ -//===-- TypeSummary.cpp ----------------------------------------*- C++ -*-===// +//===-- TypeSummary.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -83,13 +83,13 @@ bool StringSummaryFormat::FormatObject(ValueObject *valobj, std::string &retval, if (IsOneLiner()) { ValueObjectPrinter printer(valobj, &s, DumpValueObjectOptions()); printer.PrintChildrenOneLiner(HideNames(valobj)); - retval = s.GetString(); + retval = std::string(s.GetString()); return true; } else { if (FormatEntity::Format(m_format, s, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), valobj, false, false)) { - retval.assign(s.GetString()); + retval.assign(std::string(s.GetString())); return true; } else { retval.assign("error: summary string parsing error"); @@ -111,7 +111,7 @@ std::string StringSummaryFormat::GetDescription() { SkipsPointers() ? " (skip pointers)" : "", SkipsReferences() ? " (skip references)" : "", HideNames(nullptr) ? " (hide member names)" : ""); - return sstr.GetString(); + return std::string(sstr.GetString()); } CXXFunctionSummaryFormat::CXXFunctionSummaryFormat( @@ -126,7 +126,7 @@ bool CXXFunctionSummaryFormat::FormatObject(ValueObject *valobj, StreamString stream; if (!m_impl || !m_impl(*valobj, stream, options)) return false; - dest = stream.GetString(); + dest = std::string(stream.GetString()); return true; } @@ -140,7 +140,7 @@ std::string CXXFunctionSummaryFormat::GetDescription() { SkipsReferences() ? " (skip references)" : "", HideNames(nullptr) ? " (hide member names)" : "", m_description.c_str()); - return sstr.GetString(); + return std::string(sstr.GetString()); } ScriptSummaryFormat::ScriptSummaryFormat(const TypeSummaryImpl::Flags &flags, @@ -197,5 +197,5 @@ std::string ScriptSummaryFormat::GetDescription() { } else { sstr.PutCString(m_python_script); } - return sstr.GetString(); + return std::string(sstr.GetString()); } diff --git a/gnu/llvm/lldb/source/DataFormatters/TypeSynthetic.cpp b/gnu/llvm/lldb/source/DataFormatters/TypeSynthetic.cpp index 23c80fc58d0..75388a93cc6 100644 --- a/gnu/llvm/lldb/source/DataFormatters/TypeSynthetic.cpp +++ b/gnu/llvm/lldb/source/DataFormatters/TypeSynthetic.cpp @@ -1,5 +1,4 @@ -//===-- TypeSynthetic.cpp ----------------------------------------*- C++ -//-*-===// +//===-- TypeSynthetic.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -82,7 +81,7 @@ std::string TypeFilterImpl::GetDescription() { } sstr.Printf("}"); - return sstr.GetString(); + return std::string(sstr.GetString()); } std::string CXXSyntheticChildren::GetDescription() { @@ -92,7 +91,7 @@ std::string CXXSyntheticChildren::GetDescription() { SkipsReferences() ? " (skip references)" : "", m_description.c_str()); - return sstr.GetString(); + return std::string(sstr.GetString()); } lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateValueObjectFromExpression( @@ -213,5 +212,5 @@ std::string ScriptedSyntheticChildren::GetDescription() { SkipsReferences() ? " (skip references)" : "", m_python_class.c_str()); - return sstr.GetString(); + return std::string(sstr.GetString()); } diff --git a/gnu/llvm/lldb/source/DataFormatters/ValueObjectPrinter.cpp b/gnu/llvm/lldb/source/DataFormatters/ValueObjectPrinter.cpp index 466cf398ec2..c8a306334cf 100644 --- a/gnu/llvm/lldb/source/DataFormatters/ValueObjectPrinter.cpp +++ b/gnu/llvm/lldb/source/DataFormatters/ValueObjectPrinter.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectPrinter.cpp -----------------------------------*- C++-*-===// +//===-- ValueObjectPrinter.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -151,11 +151,11 @@ const char *ValueObjectPrinter::GetDescriptionForDisplay() { return str; } -const char *ValueObjectPrinter::GetRootNameForDisplay(const char *if_fail) { +const char *ValueObjectPrinter::GetRootNameForDisplay() { const char *root_valobj_name = m_options.m_root_valobj_name.empty() ? m_valobj->GetName().AsCString() : m_options.m_root_valobj_name.c_str(); - return root_valobj_name ? root_valobj_name : if_fail; + return root_valobj_name ? root_valobj_name : ""; } bool ValueObjectPrinter::ShouldPrintValueObject() { @@ -239,17 +239,14 @@ void ValueObjectPrinter::PrintDecl() { // type if there is one to print ConstString type_name; if (m_compiler_type.IsValid()) { - if (m_options.m_use_type_display_name) - type_name = m_valobj->GetDisplayTypeName(); - else - type_name = m_valobj->GetQualifiedTypeName(); + type_name = m_options.m_use_type_display_name + ? m_valobj->GetDisplayTypeName() + : m_valobj->GetQualifiedTypeName(); } else { // only show an invalid type name if the user explicitly triggered // show_type if (m_options.m_show_types) type_name = ConstString(""); - else - type_name.Clear(); } if (type_name) { @@ -260,21 +257,17 @@ void ValueObjectPrinter::PrintDecl() { type_name_str.erase(iter, 2); } } - typeName.Printf("%s", type_name_str.c_str()); + typeName << type_name_str.c_str(); } } StreamString varName; - if (m_options.m_flat_output) { - // If we are showing types, also qualify the C++ base classes - const bool qualify_cxx_base_classes = show_type; - if (!m_options.m_hide_name) { - m_valobj->GetExpressionPath(varName, qualify_cxx_base_classes); - } - } else if (!m_options.m_hide_name) { - const char *name_cstr = GetRootNameForDisplay(""); - varName.Printf("%s", name_cstr); + if (!m_options.m_hide_name) { + if (m_options.m_flat_output) + m_valobj->GetExpressionPath(varName); + else + varName << GetRootNameForDisplay(); } bool decl_printed = false; @@ -450,9 +443,9 @@ bool ValueObjectPrinter::PrintObjectDescriptionIfNeeded(bool value_printed, // If the description already ends with a \n don't add another one. size_t object_end = strlen(object_desc) - 1; if (object_desc[object_end] == '\n') - m_stream->Printf("%s", object_desc); + m_stream->Printf("%s", object_desc); else - m_stream->Printf("%s\n", object_desc); + m_stream->Printf("%s\n", object_desc); return true; } else if (!value_printed && !summary_printed) return true; diff --git a/gnu/llvm/lldb/source/DataFormatters/VectorType.cpp b/gnu/llvm/lldb/source/DataFormatters/VectorType.cpp index 26fc03a4cdc..fd1c0bc96cd 100644 --- a/gnu/llvm/lldb/source/DataFormatters/VectorType.cpp +++ b/gnu/llvm/lldb/source/DataFormatters/VectorType.cpp @@ -1,4 +1,4 @@ -//===-- VectorType.cpp ------------------------------------------*- C++ -*-===// +//===-- VectorType.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Expression/DWARFExpression.cpp b/gnu/llvm/lldb/source/Expression/DWARFExpression.cpp index 08cc70c201f..6050c192256 100644 --- a/gnu/llvm/lldb/source/Expression/DWARFExpression.cpp +++ b/gnu/llvm/lldb/source/Expression/DWARFExpression.cpp @@ -1,4 +1,4 @@ -//===-- DWARFExpression.cpp -------------------------------------*- C++ -*-===// +//===-- DWARFExpression.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -88,8 +88,7 @@ void DWARFExpression::UpdateValue(uint64_t const_value, void DWARFExpression::DumpLocation(Stream *s, const DataExtractor &data, lldb::DescriptionLevel level, ABI *abi) const { - llvm::DWARFExpression(data.GetAsLLVM(), llvm::dwarf::DWARF_VERSION, - data.GetAddressByteSize()) + llvm::DWARFExpression(data.GetAsLLVM(), data.GetAddressByteSize()) .print(s->AsRawOstream(), abi ? &abi->GetMCRegisterInfo() : nullptr, nullptr); } @@ -138,12 +137,15 @@ void DWARFExpression::GetDescription(Stream *s, lldb::DescriptionLevel level, m_dwarf_cu->GetLocationTable(m_data); llvm::MCRegisterInfo *MRI = abi ? &abi->GetMCRegisterInfo() : nullptr; - + llvm::DIDumpOptions DumpOpts; + DumpOpts.RecoverableErrorHandler = [&](llvm::Error E) { + s->AsRawOstream() << "error: " << toString(std::move(E)); + }; loctable_up->dumpLocationList( &offset, s->AsRawOstream(), llvm::object::SectionedAddress{m_loclist_addresses->cu_file_addr}, MRI, DummyDWARFObject(m_data.GetByteOrder() == eByteOrderLittle), nullptr, - llvm::DIDumpOptions(), s->GetIndentLevel() + 2); + DumpOpts, s->GetIndentLevel() + 2); } else { // We have a normal location that contains DW_OP location opcodes DumpLocation(s, m_data, level, abi); @@ -394,6 +396,7 @@ static offset_t GetOpcodeDataSize(const DataExtractor &data, return offset - data_offset; } + case DW_OP_GNU_entry_value: case DW_OP_entry_value: // 0xa3 ULEB128 size + variable-length block { uint64_t subexpr_len = data.GetULEB128(&offset); @@ -933,7 +936,7 @@ bool DWARFExpression::Evaluate( Value tmp; uint32_t reg_num; - /// Insertion point for evaluating multi-piece expression. + /// Insertion point for evaluating multi-piece expression. uint64_t op_piece_offset = 0; Value pieces; // Used for DW_OP_piece @@ -1183,7 +1186,7 @@ bool DWARFExpression::Evaluate( break; default: stack.back().GetScalar() = - addr_data.GetPointer(&addr_data_offset); + addr_data.GetAddress(&addr_data_offset); } stack.back().ClearContext(); } else { @@ -2319,6 +2322,12 @@ bool DWARFExpression::Evaluate( // rather is a constant value. The value from the top of the stack is the // value to be used. This is the actual object value and not the location. case DW_OP_stack_value: + if (stack.empty()) { + if (error_ptr) + error_ptr->SetErrorString( + "Expression stack needs at least 1 item for DW_OP_stack_value."); + return false; + } stack.back().SetValueType(Value::eValueTypeScalar); break; @@ -2337,8 +2346,8 @@ bool DWARFExpression::Evaluate( return false; } const uint64_t die_offset = opcodes.GetULEB128(&offset); - Scalar::Type type = Scalar::e_void; uint64_t bit_size; + bool sign; if (die_offset == 0) { // The generic type has the size of an address on the target // machine and an unspecified signedness. Scalar has no @@ -2348,13 +2357,13 @@ bool DWARFExpression::Evaluate( error_ptr->SetErrorString("No module"); return false; } + sign = false; bit_size = module_sp->GetArchitecture().GetAddressByteSize() * 8; if (!bit_size) { if (error_ptr) error_ptr->SetErrorString("unspecified architecture"); return false; } - type = Scalar::GetBestTypeForBitSize(bit_size, false); } else { // Retrieve the type DIE that the value is being converted to. // FIXME: the constness has annoying ripple effects. @@ -2377,11 +2386,11 @@ bool DWARFExpression::Evaluate( switch (encoding) { case DW_ATE_signed: case DW_ATE_signed_char: - type = Scalar::GetBestTypeForBitSize(bit_size, true); + sign = true; break; case DW_ATE_unsigned: case DW_ATE_unsigned_char: - type = Scalar::GetBestTypeForBitSize(bit_size, false); + sign = false; break; default: if (error_ptr) @@ -2389,13 +2398,8 @@ bool DWARFExpression::Evaluate( return false; } } - if (type == Scalar::e_void) { - if (error_ptr) - error_ptr->SetErrorString("Unsupported pointer size"); - return false; - } Scalar &top = stack.back().ResolveValue(exe_ctx); - top.TruncOrExtendTo(type, bit_size); + top.TruncOrExtendTo(bit_size, sign); break; } @@ -2514,6 +2518,7 @@ bool DWARFExpression::Evaluate( stack.push_back(Scalar(value)); } break; + case DW_OP_GNU_entry_value: case DW_OP_entry_value: { if (!Evaluate_DW_OP_entry_value(stack, exe_ctx, reg_ctx, opcodes, offset, error_ptr, log)) { @@ -2525,9 +2530,10 @@ bool DWARFExpression::Evaluate( } default: - LLDB_LOGF(log, "Unhandled opcode %s in DWARFExpression.", - DW_OP_value_to_name(op)); - break; + if (error_ptr) + error_ptr->SetErrorStringWithFormatv( + "Unhandled opcode {0} in DWARFExpression", LocationAtom(op)); + return false; } } @@ -2558,235 +2564,6 @@ bool DWARFExpression::Evaluate( return true; // Return true on success } -static bool print_dwarf_exp_op(Stream &s, const DataExtractor &data, - lldb::offset_t *offset_ptr, int address_size, - int dwarf_ref_size) { - uint8_t opcode = data.GetU8(offset_ptr); - DRC_class opcode_class; - uint64_t uint; - int64_t sint; - - int size; - - opcode_class = DW_OP_value_to_class(opcode) & (~DRC_DWARFv3); - - s.Printf("%s ", DW_OP_value_to_name(opcode)); - - /* Does this take zero parameters? If so we can shortcut this function. */ - if (opcode_class == DRC_ZEROOPERANDS) - return true; - - if (opcode_class == DRC_TWOOPERANDS && opcode == DW_OP_bregx) { - uint = data.GetULEB128(offset_ptr); - sint = data.GetSLEB128(offset_ptr); - s.Printf("%" PRIu64 " %" PRIi64, uint, sint); - return true; - } - if (opcode_class == DRC_TWOOPERANDS && opcode == DW_OP_entry_value) { - uint = data.GetULEB128(offset_ptr); - s.Printf("%" PRIu64 " ", uint); - return true; - } - if (opcode_class != DRC_ONEOPERAND) { - s.Printf("UNKNOWN OP %u", opcode); - return false; - } - - switch (opcode) { - case DW_OP_addr: - size = address_size; - break; - case DW_OP_const1u: - size = 1; - break; - case DW_OP_const1s: - size = -1; - break; - case DW_OP_const2u: - size = 2; - break; - case DW_OP_const2s: - size = -2; - break; - case DW_OP_const4u: - size = 4; - break; - case DW_OP_const4s: - size = -4; - break; - case DW_OP_const8u: - size = 8; - break; - case DW_OP_const8s: - size = -8; - break; - case DW_OP_constu: - size = 128; - break; - case DW_OP_consts: - size = -128; - break; - case DW_OP_fbreg: - size = -128; - break; - case DW_OP_breg0: - case DW_OP_breg1: - case DW_OP_breg2: - case DW_OP_breg3: - case DW_OP_breg4: - case DW_OP_breg5: - case DW_OP_breg6: - case DW_OP_breg7: - case DW_OP_breg8: - case DW_OP_breg9: - case DW_OP_breg10: - case DW_OP_breg11: - case DW_OP_breg12: - case DW_OP_breg13: - case DW_OP_breg14: - case DW_OP_breg15: - case DW_OP_breg16: - case DW_OP_breg17: - case DW_OP_breg18: - case DW_OP_breg19: - case DW_OP_breg20: - case DW_OP_breg21: - case DW_OP_breg22: - case DW_OP_breg23: - case DW_OP_breg24: - case DW_OP_breg25: - case DW_OP_breg26: - case DW_OP_breg27: - case DW_OP_breg28: - case DW_OP_breg29: - case DW_OP_breg30: - case DW_OP_breg31: - size = -128; - break; - case DW_OP_pick: - case DW_OP_deref_size: - case DW_OP_xderef_size: - size = 1; - break; - case DW_OP_skip: - case DW_OP_bra: - size = -2; - break; - case DW_OP_call2: - size = 2; - break; - case DW_OP_call4: - size = 4; - break; - case DW_OP_call_ref: - size = dwarf_ref_size; - break; - case DW_OP_addrx: - case DW_OP_piece: - case DW_OP_plus_uconst: - case DW_OP_regx: - case DW_OP_GNU_addr_index: - case DW_OP_GNU_const_index: - case DW_OP_entry_value: - size = 128; - break; - default: - s.Printf("UNKNOWN ONE-OPERAND OPCODE, #%u", opcode); - return false; - } - - switch (size) { - case -1: - sint = (int8_t)data.GetU8(offset_ptr); - s.Printf("%+" PRIi64, sint); - break; - case -2: - sint = (int16_t)data.GetU16(offset_ptr); - s.Printf("%+" PRIi64, sint); - break; - case -4: - sint = (int32_t)data.GetU32(offset_ptr); - s.Printf("%+" PRIi64, sint); - break; - case -8: - sint = (int64_t)data.GetU64(offset_ptr); - s.Printf("%+" PRIi64, sint); - break; - case -128: - sint = data.GetSLEB128(offset_ptr); - s.Printf("%+" PRIi64, sint); - break; - case 1: - uint = data.GetU8(offset_ptr); - s.Printf("0x%2.2" PRIx64, uint); - break; - case 2: - uint = data.GetU16(offset_ptr); - s.Printf("0x%4.4" PRIx64, uint); - break; - case 4: - uint = data.GetU32(offset_ptr); - s.Printf("0x%8.8" PRIx64, uint); - break; - case 8: - uint = data.GetU64(offset_ptr); - s.Printf("0x%16.16" PRIx64, uint); - break; - case 128: - uint = data.GetULEB128(offset_ptr); - s.Printf("0x%" PRIx64, uint); - break; - } - - return true; -} - -bool DWARFExpression::PrintDWARFExpression(Stream &s, const DataExtractor &data, - int address_size, int dwarf_ref_size, - bool location_expression) { - int op_count = 0; - lldb::offset_t offset = 0; - while (data.ValidOffset(offset)) { - if (location_expression && op_count > 0) - return false; - if (op_count > 0) - s.PutCString(", "); - if (!print_dwarf_exp_op(s, data, &offset, address_size, dwarf_ref_size)) - return false; - op_count++; - } - - return true; -} - -void DWARFExpression::PrintDWARFLocationList( - Stream &s, const DWARFUnit *cu, const DataExtractor &debug_loc_data, - lldb::offset_t offset) { - uint64_t start_addr, end_addr; - uint32_t addr_size = DWARFUnit::GetAddressByteSize(cu); - s.SetAddressByteSize(DWARFUnit::GetAddressByteSize(cu)); - dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0; - while (debug_loc_data.ValidOffset(offset)) { - start_addr = debug_loc_data.GetMaxU64(&offset, addr_size); - end_addr = debug_loc_data.GetMaxU64(&offset, addr_size); - - if (start_addr == 0 && end_addr == 0) - break; - - s.PutCString("\n "); - s.Indent(); - if (cu) - DumpAddressRange(s.AsRawOstream(), start_addr + base_addr, - end_addr + base_addr, cu->GetAddressByteSize(), nullptr, - ": "); - uint32_t loc_length = debug_loc_data.GetU16(&offset); - - DataExtractor locationData(debug_loc_data, offset, loc_length); - PrintDWARFExpression(s, locationData, addr_size, 4, false); - offset += loc_length; - } -} - static DataExtractor ToDataExtractor(const llvm::DWARFLocationExpression &loc, ByteOrder byte_order, uint32_t addr_size) { auto buffer_sp = diff --git a/gnu/llvm/lldb/source/Expression/DiagnosticManager.cpp b/gnu/llvm/lldb/source/Expression/DiagnosticManager.cpp index 48eba3586d3..08977066e33 100644 --- a/gnu/llvm/lldb/source/Expression/DiagnosticManager.cpp +++ b/gnu/llvm/lldb/source/Expression/DiagnosticManager.cpp @@ -1,4 +1,4 @@ -//===-- DiagnosticManager.cpp -----------------------------------*- C++ -*-===// +//===-- DiagnosticManager.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -49,7 +49,7 @@ std::string DiagnosticManager::GetString(char separator) { for (const auto &diagnostic : Diagnostics()) { ret.append(StringForSeverity(diagnostic->GetSeverity())); - ret.append(diagnostic->GetMessage()); + ret.append(std::string(diagnostic->GetMessage())); ret.push_back(separator); } diff --git a/gnu/llvm/lldb/source/Expression/Expression.cpp b/gnu/llvm/lldb/source/Expression/Expression.cpp index 71369d0b9ee..93f585edfce 100644 --- a/gnu/llvm/lldb/source/Expression/Expression.cpp +++ b/gnu/llvm/lldb/source/Expression/Expression.cpp @@ -1,4 +1,4 @@ -//===-- Expression.cpp ------------------------------------------*- C++ -*-===// +//===-- Expression.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Expression/ExpressionVariable.cpp b/gnu/llvm/lldb/source/Expression/ExpressionVariable.cpp index ed8da0ad867..d95f0745cf4 100644 --- a/gnu/llvm/lldb/source/Expression/ExpressionVariable.cpp +++ b/gnu/llvm/lldb/source/Expression/ExpressionVariable.cpp @@ -1,4 +1,4 @@ -//===-- ExpressionVariable.cpp ----------------------------------*- C++ -*-===// +//===-- ExpressionVariable.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -69,20 +69,10 @@ void PersistentExpressionState::RegisterExecutionUnit( // of the demangled name will find the mangled one (needed for looking up // metadata pointers.) Mangled mangler(global_var.m_name); - mangler.GetDemangledName(lldb::eLanguageTypeUnknown); + mangler.GetDemangledName(); m_symbol_map[global_var.m_name.GetCString()] = global_var.m_remote_addr; LLDB_LOGF(log, " Symbol: %s at 0x%" PRIx64 ".", global_var.m_name.GetCString(), global_var.m_remote_addr); } } } - -ConstString PersistentExpressionState::GetNextPersistentVariableName( - Target &target, llvm::StringRef Prefix) { - llvm::SmallString<64> name; - { - llvm::raw_svector_ostream os(name); - os << Prefix << target.GetNextPersistentVariableIndex(); - } - return ConstString(name); -} diff --git a/gnu/llvm/lldb/source/Expression/FunctionCaller.cpp b/gnu/llvm/lldb/source/Expression/FunctionCaller.cpp index dc80c8169d7..26ab4bfaff5 100644 --- a/gnu/llvm/lldb/source/Expression/FunctionCaller.cpp +++ b/gnu/llvm/lldb/source/Expression/FunctionCaller.cpp @@ -1,4 +1,4 @@ -//===-- FunctionCaller.cpp ---------------------------------------*- C++-*-===// +//===-- FunctionCaller.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -364,8 +364,9 @@ lldb::ExpressionResults FunctionCaller::ExecuteFunction( if (return_value != lldb::eExpressionCompleted) { LLDB_LOGF(log, "== [FunctionCaller::ExecuteFunction] Execution of \"%s\" " - "completed abnormally ==", - m_name.c_str()); + "completed abnormally: %s ==", + m_name.c_str(), + Process::ExecutionResultAsCString(return_value)); } else { LLDB_LOGF(log, "== [FunctionCaller::ExecuteFunction] Execution of \"%s\" " diff --git a/gnu/llvm/lldb/source/Expression/IRExecutionUnit.cpp b/gnu/llvm/lldb/source/Expression/IRExecutionUnit.cpp index e033b90cfd8..e3c9c1d7fdf 100644 --- a/gnu/llvm/lldb/source/Expression/IRExecutionUnit.cpp +++ b/gnu/llvm/lldb/source/Expression/IRExecutionUnit.cpp @@ -1,4 +1,4 @@ -//===-- IRExecutionUnit.cpp -------------------------------------*- C++ -*-===// +//===-- IRExecutionUnit.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -265,11 +265,9 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr, builder.setEngineKind(llvm::EngineKind::JIT) .setErrorStr(&error_string) - .setRelocationModel(triple.isOSBinFormatMachO() - ? llvm::Reloc::PIC_ - : llvm::Reloc::Static) - .setMCJITMemoryManager( - std::unique_ptr(new MemoryManager(*this))) + .setRelocationModel(triple.isOSBinFormatMachO() ? llvm::Reloc::PIC_ + : llvm::Reloc::Static) + .setMCJITMemoryManager(std::make_unique(*this)) .setOptLevel(llvm::CodeGenOpt::Less); llvm::StringRef mArch; @@ -404,9 +402,7 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr, ss.PutCString("\n"); emitNewLine = true; ss.PutCString(" "); - ss.PutCString(Mangled(failed_lookup) - .GetDemangledName(lldb::eLanguageTypeObjC_plus_plus) - .AsCString()); + ss.PutCString(Mangled(failed_lookup).GetDemangledName().GetStringRef()); } m_failed_lookups.clear(); @@ -645,10 +641,8 @@ uint8_t *IRExecutionUnit::MemoryManager::allocateDataSection( return return_value; } -static ConstString -FindBestAlternateMangledName(ConstString demangled, - const lldb::LanguageType &lang_type, - const SymbolContext &sym_ctx) { +static ConstString FindBestAlternateMangledName(ConstString demangled, + const SymbolContext &sym_ctx) { CPlusPlusLanguage::MethodName cpp_name(demangled); std::string scope_qualified_name = cpp_name.GetScopeQualifiedName(); @@ -670,7 +664,7 @@ FindBestAlternateMangledName(ConstString demangled, for (size_t i = 0; i < alternates.size(); i++) { ConstString alternate_mangled_name = alternates[i]; Mangled mangled(alternate_mangled_name); - ConstString demangled = mangled.GetDemangledName(lang_type); + ConstString demangled = mangled.GetDemangledName(); CPlusPlusLanguage::MethodName alternate_cpp_name(demangled); if (!cpp_name.IsValid()) @@ -718,12 +712,11 @@ void IRExecutionUnit::CollectCandidateCPlusPlusNames( if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString())) { Mangled mangled(name); - ConstString demangled = - mangled.GetDemangledName(lldb::eLanguageTypeC_plus_plus); + ConstString demangled = mangled.GetDemangledName(); if (demangled) { - ConstString best_alternate_mangled_name = FindBestAlternateMangledName( - demangled, lldb::eLanguageTypeC_plus_plus, sc); + ConstString best_alternate_mangled_name = + FindBestAlternateMangledName(demangled, sc); if (best_alternate_mangled_name) { CPP_specs.push_back(best_alternate_mangled_name); @@ -746,20 +739,22 @@ void IRExecutionUnit::CollectFallbackNames( for (const SearchSpec &C_spec : C_specs) { ConstString name = C_spec.name; - if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString())) { - Mangled mangled_name(name); - ConstString demangled_name = - mangled_name.GetDemangledName(lldb::eLanguageTypeC_plus_plus); - if (!demangled_name.IsEmpty()) { - const char *demangled_cstr = demangled_name.AsCString(); - const char *lparen_loc = strchr(demangled_cstr, '('); - if (lparen_loc) { - llvm::StringRef base_name(demangled_cstr, - lparen_loc - demangled_cstr); - fallback_specs.push_back(ConstString(base_name)); - } - } - } + if (!CPlusPlusLanguage::IsCPPMangledName(name.GetCString())) + continue; + + Mangled mangled_name(name); + ConstString demangled_name = mangled_name.GetDemangledName(); + if (demangled_name.IsEmpty()) + continue; + + const char *demangled_cstr = demangled_name.AsCString(); + const char *lparen_loc = strchr(demangled_cstr, '('); + if (!lparen_loc) + continue; + + llvm::StringRef base_name(demangled_cstr, + lparen_loc - demangled_cstr); + fallback_specs.push_back(ConstString(base_name)); } } @@ -849,7 +844,7 @@ lldb::addr_t IRExecutionUnit::FindInSymbols( }; if (sc.module_sp) { - sc.module_sp->FindFunctions(spec.name, nullptr, spec.mask, + sc.module_sp->FindFunctions(spec.name, CompilerDeclContext(), spec.mask, true, // include_symbols false, // include_inlines sc_list); diff --git a/gnu/llvm/lldb/source/Expression/IRInterpreter.cpp b/gnu/llvm/lldb/source/Expression/IRInterpreter.cpp index b2e4be5e40f..4c7a6562659 100644 --- a/gnu/llvm/lldb/source/Expression/IRInterpreter.cpp +++ b/gnu/llvm/lldb/source/Expression/IRInterpreter.cpp @@ -1,4 +1,4 @@ -//===-- IRInterpreter.cpp ---------------------------------------*- C++ -*-===// +//===-- IRInterpreter.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -144,10 +144,10 @@ public: ss.Printf(" 0x%llx", (unsigned long long)addr); } - return ss.GetString(); + return std::string(ss.GetString()); } - bool AssignToMatchType(lldb_private::Scalar &scalar, uint64_t u64value, + bool AssignToMatchType(lldb_private::Scalar &scalar, llvm::APInt value, Type *type) { size_t type_size = m_target_data.getTypeStoreSize(type); @@ -157,7 +157,7 @@ public: if (type_size != 1) type_size = PowerOf2Ceil(type_size); - scalar = llvm::APInt(type_size*8, u64value); + scalar = value.zextOrTrunc(type_size * 8); return true; } @@ -171,32 +171,32 @@ public: if (!ResolveConstantValue(value_apint, constant)) return false; - return AssignToMatchType(scalar, value_apint.getLimitedValue(), - value->getType()); - } else { - lldb::addr_t process_address = ResolveValue(value, module); - size_t value_size = m_target_data.getTypeStoreSize(value->getType()); + return AssignToMatchType(scalar, value_apint, value->getType()); + } - lldb_private::DataExtractor value_extractor; - lldb_private::Status extract_error; + lldb::addr_t process_address = ResolveValue(value, module); + size_t value_size = m_target_data.getTypeStoreSize(value->getType()); - m_execution_unit.GetMemoryData(value_extractor, process_address, - value_size, extract_error); + lldb_private::DataExtractor value_extractor; + lldb_private::Status extract_error; - if (!extract_error.Success()) - return false; + m_execution_unit.GetMemoryData(value_extractor, process_address, + value_size, extract_error); - lldb::offset_t offset = 0; - if (value_size <= 8) { - uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size); - return AssignToMatchType(scalar, u64value, value->getType()); - } + if (!extract_error.Success()) + return false; + + lldb::offset_t offset = 0; + if (value_size <= 8) { + uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size); + return AssignToMatchType(scalar, llvm::APInt(64, u64value), + value->getType()); } return false; } - bool AssignValue(const Value *value, lldb_private::Scalar &scalar, + bool AssignValue(const Value *value, lldb_private::Scalar scalar, Module &module) { lldb::addr_t process_address = ResolveValue(value, module); @@ -205,7 +205,9 @@ public: lldb_private::Scalar cast_scalar; - if (!AssignToMatchType(cast_scalar, scalar.ULongLong(), value->getType())) + scalar.MakeUnsigned(); + if (!AssignToMatchType(cast_scalar, scalar.UInt128(llvm::APInt()), + value->getType())) return false; size_t value_byte_size = m_target_data.getTypeStoreSize(value->getType()); @@ -403,7 +405,7 @@ public: ss.Printf("%02hhx ", buf.GetBytes()[i]); } - return ss.GetString(); + return std::string(ss.GetString()); } lldb::addr_t ResolveValue(const Value *value, Module &module) { @@ -433,8 +435,6 @@ static const char *unsupported_opcode_error = "Interpreter doesn't handle one of the expression's opcodes"; static const char *unsupported_operand_error = "Interpreter doesn't handle one of the expression's operands"; -// static const char *interpreter_initialization_error = "Interpreter couldn't -// be initialized"; static const char *interpreter_internal_error = "Interpreter encountered an internal error"; static const char *bad_value_error = @@ -444,8 +444,6 @@ static const char *memory_allocation_error = static const char *memory_write_error = "Interpreter couldn't write to memory"; static const char *memory_read_error = "Interpreter couldn't read from memory"; static const char *infinite_loop_error = "Interpreter ran for too many cycles"; -// static const char *bad_result_error = "Result of expression -// is in bad memory"; static const char *too_many_functions_error = "Interpreter doesn't handle modules with multiple function bodies."; @@ -597,7 +595,8 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, switch (operand_type->getTypeID()) { default: break; - case Type::VectorTyID: { + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: { LLDB_LOGF(log, "Unsupported operand type: %s", PrintType(operand_type).c_str()); error.SetErrorString(unsupported_operand_error); @@ -1370,7 +1369,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, // Find the address of the callee function lldb_private::Scalar I; - const llvm::Value *val = call_inst->getCalledValue(); + const llvm::Value *val = call_inst->getCalledOperand(); if (!frame.EvaluateValue(I, val, module)) { error.SetErrorToGenericError(); @@ -1510,7 +1509,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, lldb_private::ValueObject *vobj = retVal.get(); // Check if the return value is valid - if (vobj == nullptr || retVal.empty()) { + if (vobj == nullptr || !retVal) { error.SetErrorToGenericError(); error.SetErrorStringWithFormat("unable to get the return value"); return false; diff --git a/gnu/llvm/lldb/source/Expression/IRMemoryMap.cpp b/gnu/llvm/lldb/source/Expression/IRMemoryMap.cpp index 02a875ec833..6b1e4c313a3 100644 --- a/gnu/llvm/lldb/source/Expression/IRMemoryMap.cpp +++ b/gnu/llvm/lldb/source/Expression/IRMemoryMap.cpp @@ -1,4 +1,4 @@ -//===-- IRMemoryMap.cpp -----------------------------------------*- C++ -*-===// +//===-- IRMemoryMap.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Expression/LLVMUserExpression.cpp b/gnu/llvm/lldb/source/Expression/LLVMUserExpression.cpp index 1fc878bbd61..187b427e66a 100644 --- a/gnu/llvm/lldb/source/Expression/LLVMUserExpression.cpp +++ b/gnu/llvm/lldb/source/Expression/LLVMUserExpression.cpp @@ -1,4 +1,4 @@ -//===-- LLVMUserExpression.cpp ----------------------------------*- C++ -*-===// +//===-- LLVMUserExpression.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -134,6 +134,10 @@ LLVMUserExpression::DoExecute(DiagnosticManager &diagnostic_manager, return lldb::eExpressionSetupError; } + // Store away the thread ID for error reporting, in case it exits + // during execution: + lldb::tid_t expr_thread_id = exe_ctx.GetThreadRef().GetID(); + Address wrapper_address(m_jit_start_addr); std::vector args; @@ -223,6 +227,14 @@ LLVMUserExpression::DoExecute(DiagnosticManager &diagnostic_manager, "Use \"thread return -x\" to return to the state before expression " "evaluation."); return execution_result; + } else if (execution_result == lldb::eExpressionThreadVanished) { + diagnostic_manager.Printf( + eDiagnosticSeverityError, + "Couldn't complete execution; the thread " + "on which the expression was being run: 0x%" PRIx64 + " exited during its execution.", + expr_thread_id); + return execution_result; } else if (execution_result != lldb::eExpressionCompleted) { diagnostic_manager.Printf( eDiagnosticSeverityError, "Couldn't execute function; result was %s", @@ -357,8 +369,3 @@ bool LLVMUserExpression::PrepareToExecuteJITExpression( return true; } -lldb::ModuleSP LLVMUserExpression::GetJITModule() { - if (m_execution_unit_sp) - return m_execution_unit_sp->GetJITModule(); - return lldb::ModuleSP(); -} diff --git a/gnu/llvm/lldb/source/Expression/Materializer.cpp b/gnu/llvm/lldb/source/Expression/Materializer.cpp index cd332484deb..f33462053f2 100644 --- a/gnu/llvm/lldb/source/Expression/Materializer.cpp +++ b/gnu/llvm/lldb/source/Expression/Materializer.cpp @@ -1,4 +1,4 @@ -//===-- Materializer.cpp ----------------------------------------*- C++ -*-===// +//===-- Materializer.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -399,7 +399,8 @@ uint32_t Materializer::AddPersistentVariable( lldb::ExpressionVariableSP &persistent_variable_sp, PersistentVariableDelegate *delegate, Status &err) { EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP()); - iter->reset(new EntityPersistentVariable(persistent_variable_sp, delegate)); + *iter = std::make_unique(persistent_variable_sp, + delegate); uint32_t ret = AddStructMember(**iter); (*iter)->SetOffset(ret); return ret; @@ -698,7 +699,7 @@ public: lldb::offset_t offset; - ptr = extractor.GetPointer(&offset); + ptr = extractor.GetAddress(&offset); dump_stream.PutChar('\n'); } @@ -752,7 +753,7 @@ private: uint32_t Materializer::AddVariable(lldb::VariableSP &variable_sp, Status &err) { EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP()); - iter->reset(new EntityVariable(variable_sp)); + *iter = std::make_unique(variable_sp); uint32_t ret = AddStructMember(**iter); (*iter)->SetOffset(ret); return ret; @@ -784,7 +785,9 @@ public: const lldb::addr_t load_addr = process_address + m_offset; - ExecutionContextScope *exe_scope = map.GetBestExecutionContextScope(); + ExecutionContextScope *exe_scope = frame_sp.get(); + if (!exe_scope) + exe_scope = map.GetBestExecutionContextScope(); llvm::Optional byte_size = m_type.GetByteSize(exe_scope); if (!byte_size) { @@ -834,7 +837,9 @@ public: lldb::addr_t frame_bottom, Status &err) override { err.Clear(); - ExecutionContextScope *exe_scope = map.GetBestExecutionContextScope(); + ExecutionContextScope *exe_scope = frame_sp.get(); + if (!exe_scope) + exe_scope = map.GetBestExecutionContextScope(); if (!exe_scope) { err.SetErrorString("Couldn't dematerialize a result variable: invalid " @@ -881,11 +886,9 @@ public: return; } - ConstString name = - m_delegate - ? m_delegate->GetName() - : persistent_state->GetNextPersistentVariableName( - *target_sp, persistent_state->GetPersistentVariablePrefix()); + ConstString name = m_delegate + ? m_delegate->GetName() + : persistent_state->GetNextPersistentVariableName(); lldb::ExpressionVariableSP ret = persistent_state->CreatePersistentVariable( exe_scope, name, m_type, map.GetByteOrder(), map.GetAddressByteSize()); @@ -972,7 +975,7 @@ public: lldb::offset_t offset; - ptr = extractor.GetPointer(&offset); + ptr = extractor.GetAddress(&offset); dump_stream.PutChar('\n'); } @@ -1032,8 +1035,8 @@ uint32_t Materializer::AddResultVariable(const CompilerType &type, PersistentVariableDelegate *delegate, Status &err) { EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP()); - iter->reset(new EntityResultVariable(type, is_program_reference, - keep_in_memory, delegate)); + *iter = std::make_unique(type, is_program_reference, + keep_in_memory, delegate); uint32_t ret = AddStructMember(**iter); (*iter)->SetOffset(ret); return ret; @@ -1062,7 +1065,9 @@ public: const Address sym_address = m_symbol.GetAddress(); - ExecutionContextScope *exe_scope = map.GetBestExecutionContextScope(); + ExecutionContextScope *exe_scope = frame_sp.get(); + if (!exe_scope) + exe_scope = map.GetBestExecutionContextScope(); lldb::TargetSP target_sp; @@ -1149,7 +1154,7 @@ private: uint32_t Materializer::AddSymbol(const Symbol &symbol_sp, Status &err) { EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP()); - iter->reset(new EntitySymbol(symbol_sp)); + *iter = std::make_unique(symbol_sp); uint32_t ret = AddStructMember(**iter); (*iter)->SetOffset(ret); return ret; @@ -1326,15 +1331,12 @@ private: uint32_t Materializer::AddRegister(const RegisterInfo ®ister_info, Status &err) { EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP()); - iter->reset(new EntityRegister(register_info)); + *iter = std::make_unique(register_info); uint32_t ret = AddStructMember(**iter); (*iter)->SetOffset(ret); return ret; } -Materializer::Materializer() - : m_dematerializer_wp(), m_current_offset(0), m_struct_alignment(8) {} - Materializer::~Materializer() { DematerializerSP dematerializer_sp = m_dematerializer_wp.lock(); @@ -1346,7 +1348,6 @@ Materializer::DematerializerSP Materializer::Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Status &error) { ExecutionContextScope *exe_scope = frame_sp.get(); - if (!exe_scope) exe_scope = map.GetBestExecutionContextScope(); @@ -1397,7 +1398,9 @@ void Materializer::Dematerializer::Dematerialize(Status &error, if (thread_sp) frame_sp = thread_sp->GetFrameWithStackID(m_stack_id); - ExecutionContextScope *exe_scope = m_map->GetBestExecutionContextScope(); + ExecutionContextScope *exe_scope = frame_sp.get(); + if (!exe_scope) + exe_scope = m_map->GetBestExecutionContextScope(); if (!IsValid()) { error.SetErrorToGenericError(); diff --git a/gnu/llvm/lldb/source/Expression/REPL.cpp b/gnu/llvm/lldb/source/Expression/REPL.cpp index fcd08368473..fd7c3968692 100644 --- a/gnu/llvm/lldb/source/Expression/REPL.cpp +++ b/gnu/llvm/lldb/source/Expression/REPL.cpp @@ -1,4 +1,4 @@ -//===-- REPL.cpp ------------------------------------------------*- C++ -*-===// +//===-- REPL.cpp ----------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -53,11 +53,11 @@ std::string REPL::GetSourcePath() { ConstString file_basename = GetSourceFileBasename(); FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir(); if (tmpdir_file_spec) { - tmpdir_file_spec.GetFilename().SetCString(file_basename.AsCString()); + tmpdir_file_spec.GetFilename() = file_basename; m_repl_source_path = tmpdir_file_spec.GetPath(); } else { tmpdir_file_spec = FileSpec("/tmp"); - tmpdir_file_spec.AppendPathComponent(file_basename.AsCString()); + tmpdir_file_spec.AppendPathComponent(file_basename.GetStringRef()); } return tmpdir_file_spec.GetPath(); @@ -216,7 +216,7 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { ci.SetPromptOnQuit(false); // Execute the command - CommandReturnObject result; + CommandReturnObject result(debugger.GetUseColor()); result.SetImmediateOutputStream(output_sp); result.SetImmediateErrorStream(error_sp); ci.HandleCommand(code.c_str(), eLazyBoolNo, result); @@ -252,7 +252,7 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { lldb::IOHandlerSP io_handler_sp(ci.GetIOHandler()); if (io_handler_sp) { io_handler_sp->SetIsDone(false); - debugger.PushIOHandler(ci.GetIOHandler()); + debugger.RunIOHandlerAsync(ci.GetIOHandler()); } } } @@ -291,12 +291,10 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { const char *expr_prefix = nullptr; lldb::ValueObjectSP result_valobj_sp; Status error; - lldb::ModuleSP jit_module_sp; lldb::ExpressionResults execution_results = UserExpression::Evaluate(exe_ctx, expr_options, code.c_str(), expr_prefix, result_valobj_sp, error, - nullptr, // Fixed Expression - &jit_module_sp); + nullptr); // fixed expression // CommandInterpreter &ci = debugger.GetCommandInterpreter(); @@ -370,7 +368,7 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { lldb::IOHandlerSP io_handler_sp(ci.GetIOHandler()); if (io_handler_sp) { io_handler_sp->SetIsDone(false); - debugger.PushIOHandler(ci.GetIOHandler()); + debugger.RunIOHandlerAsync(ci.GetIOHandler()); } } break; @@ -390,6 +388,11 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { error_sp->Printf("error: stopped for debug -- %s\n", error.AsCString()); break; + case lldb::eExpressionThreadVanished: + // Shoulnd't happen??? + error_sp->Printf("error: expression thread vanished -- %s\n", + error.AsCString()); + break; } } @@ -454,6 +457,10 @@ void REPL::IOHandlerComplete(IOHandler &io_handler, debugger.GetCommandInterpreter().HandleCompletion(sub_request); StringList matches, descriptions; sub_result.GetMatches(matches); + // Prepend command prefix that was excluded in the completion request. + if (request.GetCursorIndex() == 0) + for (auto &match : matches) + match.insert(0, 1, ':'); sub_result.GetDescriptions(descriptions); request.AddCompletions(matches, descriptions); return; @@ -488,14 +495,7 @@ void REPL::IOHandlerComplete(IOHandler &io_handler, current_code.append("\n"); current_code += request.GetRawLine(); - StringList matches; - int result = CompleteCode(current_code, matches); - if (result == -2) { - assert(matches.GetSize() == 1); - request.AddCompletion(matches.GetStringAtIndex(0), "", - CompletionMode::RewriteLine); - } else - request.AddCompletions(matches); + CompleteCode(current_code, request); } bool QuitCommandOverrideCallback(void *baton, const char **argv) { @@ -530,7 +530,7 @@ Status REPL::RunLoop() { save_default_line); } - debugger.PushIOHandler(io_handler_sp); + debugger.RunIOHandlerAsync(io_handler_sp); // Check if we are in dedicated REPL mode where LLDB was start with the "-- // repl" option from the command line. Currently we know this by checking if diff --git a/gnu/llvm/lldb/source/Expression/UserExpression.cpp b/gnu/llvm/lldb/source/Expression/UserExpression.cpp index 3b507da8e4a..47d13f052bf 100644 --- a/gnu/llvm/lldb/source/Expression/UserExpression.cpp +++ b/gnu/llvm/lldb/source/Expression/UserExpression.cpp @@ -1,4 +1,4 @@ -//===-- UserExpression.cpp ---------------------------------*- C++ -*-===// +//===-- UserExpression.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -53,8 +53,9 @@ UserExpression::UserExpression(ExecutionContextScope &exe_scope, lldb::LanguageType language, ResultType desired_type, const EvaluateExpressionOptions &options) - : Expression(exe_scope), m_expr_text(expr), m_expr_prefix(prefix), - m_language(language), m_desired_type(desired_type), m_options(options) {} + : Expression(exe_scope), m_expr_text(std::string(expr)), + m_expr_prefix(std::string(prefix)), m_language(language), + m_desired_type(desired_type), m_options(options) {} UserExpression::~UserExpression() {} @@ -116,7 +117,7 @@ lldb::addr_t UserExpression::GetObjectPointer(lldb::StackFrameSP frame_sp, lldb::ValueObjectSP valobj_sp; valobj_sp = frame_sp->GetValueForVariableExpressionPath( - object_name.AsCString(), lldb::eNoDynamicValues, + object_name.GetStringRef(), lldb::eNoDynamicValues, StackFrame::eExpressionPathOptionCheckPtrVsMember | StackFrame::eExpressionPathOptionsNoFragileObjcIvar | StackFrame::eExpressionPathOptionsNoSyntheticChildren | @@ -138,12 +139,12 @@ lldb::addr_t UserExpression::GetObjectPointer(lldb::StackFrameSP frame_sp, return ret; } -lldb::ExpressionResults UserExpression::Evaluate( - ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options, - llvm::StringRef expr, llvm::StringRef prefix, - lldb::ValueObjectSP &result_valobj_sp, Status &error, - std::string *fixed_expression, lldb::ModuleSP *jit_module_sp_ptr, - ValueObject *ctx_obj) { +lldb::ExpressionResults +UserExpression::Evaluate(ExecutionContext &exe_ctx, + const EvaluateExpressionOptions &options, + llvm::StringRef expr, llvm::StringRef prefix, + lldb::ValueObjectSP &result_valobj_sp, Status &error, + std::string *fixed_expression, ValueObject *ctx_obj) { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP)); @@ -167,8 +168,8 @@ lldb::ExpressionResults UserExpression::Evaluate( Target *target = exe_ctx.GetTargetPtr(); if (!target) { - LLDB_LOGF(log, "== [UserExpression::Evaluate] Passed a NULL target, can't " - "run expressions."); + LLDB_LOG(log, "== [UserExpression::Evaluate] Passed a NULL target, can't " + "run expressions."); error.SetErrorString("expression passed a null target"); return lldb::eExpressionSetupError; } @@ -177,9 +178,8 @@ lldb::ExpressionResults UserExpression::Evaluate( if (process == nullptr || process->GetState() != lldb::eStateStopped) { if (execution_policy == eExecutionPolicyAlways) { - LLDB_LOGF(log, - "== [UserExpression::Evaluate] Expression may not run, but " - "is not constant =="); + LLDB_LOG(log, "== [UserExpression::Evaluate] Expression may not run, but " + "is not constant =="); error.SetErrorString("expression needed to run but couldn't"); @@ -201,8 +201,8 @@ lldb::ExpressionResults UserExpression::Evaluate( llvm::StringRef option_prefix(options.GetPrefix()); std::string full_prefix_storage; if (!prefix.empty() && !option_prefix.empty()) { - full_prefix_storage = prefix; - full_prefix_storage.append(option_prefix); + full_prefix_storage = std::string(prefix); + full_prefix_storage.append(std::string(option_prefix)); full_prefix = full_prefix_storage; } else if (!prefix.empty()) full_prefix = prefix; @@ -224,15 +224,13 @@ lldb::ExpressionResults UserExpression::Evaluate( desired_type, options, ctx_obj, error)); if (error.Fail()) { - if (log) - LLDB_LOGF(log, "== [UserExpression::Evaluate] Getting expression: %s ==", - error.AsCString()); + LLDB_LOG(log, "== [UserExpression::Evaluate] Getting expression: {0} ==", + error.AsCString()); return lldb::eExpressionSetupError; } - if (log) - LLDB_LOGF(log, "== [UserExpression::Evaluate] Parsing expression %s ==", - expr.str().c_str()); + LLDB_LOG(log, "== [UserExpression::Evaluate] Parsing expression {0} ==", + expr.str()); const bool keep_expression_in_memory = true; const bool generate_debug_info = options.GetGenerateDebugInfo(); @@ -261,25 +259,40 @@ lldb::ExpressionResults UserExpression::Evaluate( // If there is a fixed expression, try to parse it: if (!parse_success) { + // Delete the expression that failed to parse before attempting to parse + // the next expression. + user_expression_sp.reset(); + execution_results = lldb::eExpressionParseError; if (fixed_expression && !fixed_expression->empty() && options.GetAutoApplyFixIts()) { - lldb::UserExpressionSP fixed_expression_sp( - target->GetUserExpressionForLanguage(fixed_expression->c_str(), - full_prefix, language, - desired_type, options, ctx_obj, - error)); - DiagnosticManager fixed_diagnostic_manager; - parse_success = fixed_expression_sp->Parse( - fixed_diagnostic_manager, exe_ctx, execution_policy, - keep_expression_in_memory, generate_debug_info); - if (parse_success) { - diagnostic_manager.Clear(); - user_expression_sp = fixed_expression_sp; - } else { - // If the fixed expression failed to parse, don't tell the user about, - // that won't help. - fixed_expression->clear(); + const uint64_t max_fix_retries = options.GetRetriesWithFixIts(); + for (uint64_t i = 0; i < max_fix_retries; ++i) { + // Try parsing the fixed expression. + lldb::UserExpressionSP fixed_expression_sp( + target->GetUserExpressionForLanguage( + fixed_expression->c_str(), full_prefix, language, desired_type, + options, ctx_obj, error)); + DiagnosticManager fixed_diagnostic_manager; + parse_success = fixed_expression_sp->Parse( + fixed_diagnostic_manager, exe_ctx, execution_policy, + keep_expression_in_memory, generate_debug_info); + if (parse_success) { + diagnostic_manager.Clear(); + user_expression_sp = fixed_expression_sp; + break; + } else { + // The fixed expression also didn't parse. Let's check for any new + // Fix-Its we could try. + if (fixed_expression_sp->GetFixedText()) { + *fixed_expression = fixed_expression_sp->GetFixedText(); + } else { + // Fixed expression didn't compile without a fixit, don't retry and + // don't tell the user about it. + fixed_expression->clear(); + break; + } + } } } @@ -301,19 +314,12 @@ lldb::ExpressionResults UserExpression::Evaluate( } if (parse_success) { - // If a pointer to a lldb::ModuleSP was passed in, return the JIT'ed module - // if one was created - if (jit_module_sp_ptr) - *jit_module_sp_ptr = user_expression_sp->GetJITModule(); - lldb::ExpressionVariableSP expr_result; if (execution_policy == eExecutionPolicyNever && !user_expression_sp->CanInterpret()) { - if (log) - LLDB_LOGF(log, - "== [UserExpression::Evaluate] Expression may not run, but " - "is not constant =="); + LLDB_LOG(log, "== [UserExpression::Evaluate] Expression may not run, but " + "is not constant =="); if (!diagnostic_manager.Diagnostics().size()) error.SetExpressionError(lldb::eExpressionSetupError, @@ -333,17 +339,15 @@ lldb::ExpressionResults UserExpression::Evaluate( diagnostic_manager.Clear(); - if (log) - LLDB_LOGF(log, "== [UserExpression::Evaluate] Executing expression =="); + LLDB_LOG(log, "== [UserExpression::Evaluate] Executing expression =="); execution_results = user_expression_sp->Execute(diagnostic_manager, exe_ctx, options, user_expression_sp, expr_result); if (execution_results != lldb::eExpressionCompleted) { - if (log) - LLDB_LOGF(log, "== [UserExpression::Evaluate] Execution completed " - "abnormally =="); + LLDB_LOG(log, "== [UserExpression::Evaluate] Execution completed " + "abnormally =="); if (!diagnostic_manager.Diagnostics().size()) error.SetExpressionError( @@ -355,15 +359,13 @@ lldb::ExpressionResults UserExpression::Evaluate( if (expr_result) { result_valobj_sp = expr_result->GetValueObject(); - if (log) - LLDB_LOGF(log, - "== [UserExpression::Evaluate] Execution completed " - "normally with result %s ==", - result_valobj_sp->GetValueAsCString()); + LLDB_LOG(log, + "== [UserExpression::Evaluate] Execution completed " + "normally with result %s ==", + result_valobj_sp->GetValueAsCString()); } else { - if (log) - LLDB_LOGF(log, "== [UserExpression::Evaluate] Execution completed " - "normally with no result =="); + LLDB_LOG(log, "== [UserExpression::Evaluate] Execution completed " + "normally with no result =="); error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric); } diff --git a/gnu/llvm/lldb/source/Expression/UtilityFunction.cpp b/gnu/llvm/lldb/source/Expression/UtilityFunction.cpp index 2dbc0e9d73e..3de2ee2acbb 100644 --- a/gnu/llvm/lldb/source/Expression/UtilityFunction.cpp +++ b/gnu/llvm/lldb/source/Expression/UtilityFunction.cpp @@ -1,4 +1,4 @@ -//===-- UtilityFunction.cpp -------------------------------------*- C++ -*-===// +//===-- UtilityFunction.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/CMakeLists.txt b/gnu/llvm/lldb/source/Host/CMakeLists.txt index 2e9bb402227..add503a5f36 100644 --- a/gnu/llvm/lldb/source/Host/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Host/CMakeLists.txt @@ -1,22 +1,16 @@ +if (APPLE AND LLVM_ENABLE_LOCAL_SUBMODULE_VISIBILITY) + # The arpa/inet.h header used in the files here is providing a miscompiled + # htonl function on macOS <= 10.15 when local submodule visibility is active. + # Disabling modules in this directory until this is is fixed. + # See rdar://problem/62886385 + remove_module_flags() +endif() + macro(add_host_subdirectory group) list(APPEND HOST_SOURCES ${ARGN}) source_group(${group} FILES ${ARGN}) endmacro() -# Removes all module flags from the current CMAKE_CXX_FLAGS. Used for -# the Objective-C++ code in lldb which we don't want to build with modules. -# Reasons for this are that modules with Objective-C++ would require that -# all LLVM/Clang modules are Objective-C++ compatible (which they are likely -# not) and we would have rebuild a second set of modules just for the few -# Objective-C++ files in lldb (which slows down the build process). -macro(remove_module_flags) - string(REGEX REPLACE "-fmodules-cache-path=[^ ]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - string(REGEX REPLACE "-fmodules-local-submodule-visibility" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - string(REGEX REPLACE "-fmodules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - string(REGEX REPLACE "-gmodules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - string(REGEX REPLACE "-fcxx-modules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") -endmacro() - add_host_subdirectory(common common/FileAction.cpp common/FileCache.cpp @@ -44,7 +38,6 @@ add_host_subdirectory(common common/SocketAddress.cpp common/Socket.cpp common/StringConvert.cpp - common/TaskPool.cpp common/TCPSocket.cpp common/Terminal.cpp common/ThreadLauncher.cpp @@ -90,7 +83,6 @@ else() ) if (CMAKE_SYSTEM_NAME MATCHES "Darwin") - include_directories(SYSTEM ${LIBXML2_INCLUDE_DIR}) add_subdirectory(macosx/objcxx) set(LLDBObjCLibs lldbHostMacOSXObjCXX) add_host_subdirectory(macosx @@ -129,7 +121,7 @@ else() elseif (CMAKE_SYSTEM_NAME MATCHES "NetBSD") add_host_subdirectory(netbsd - netbsd/Host.cpp + netbsd/HostNetBSD.cpp netbsd/HostInfoNetBSD.cpp ) @@ -144,14 +136,10 @@ endif() set(EXTRA_LIBS) if (CMAKE_SYSTEM_NAME MATCHES "NetBSD") list(APPEND EXTRA_LIBS kvm) -endif () -if (APPLE) - list(APPEND EXTRA_LIBS xml2) -else () - if (LIBXML2_FOUND) - list(APPEND EXTRA_LIBS ${LIBXML2_LIBRARIES}) - endif() -endif () +endif() +if (LLDB_ENABLE_LIBXML2) + list(APPEND EXTRA_LIBS ${LIBXML2_LIBRARIES}) +endif() if (HAVE_LIBDL) list(APPEND EXTRA_LIBS ${CMAKE_DL_LIBS}) endif() @@ -161,6 +149,9 @@ endif() if (LLDB_ENABLE_LZMA) list(APPEND EXTRA_LIBS ${LIBLZMA_LIBRARIES}) endif() +if (WIN32) + list(APPEND LLDB_SYSTEM_LIBS psapi) +endif() if (LLDB_ENABLE_LIBEDIT) list(APPEND LLDB_LIBEDIT_LIBS ${LibEdit_LIBRARIES}) diff --git a/gnu/llvm/lldb/source/Host/android/HostInfoAndroid.cpp b/gnu/llvm/lldb/source/Host/android/HostInfoAndroid.cpp index 9619ec1a837..68440e016af 100644 --- a/gnu/llvm/lldb/source/Host/android/HostInfoAndroid.cpp +++ b/gnu/llvm/lldb/source/Host/android/HostInfoAndroid.cpp @@ -1,4 +1,4 @@ -//===-- HostInfoAndroid.cpp -------------------------------------*- C++ -*-===// +//===-- HostInfoAndroid.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/android/LibcGlue.cpp b/gnu/llvm/lldb/source/Host/android/LibcGlue.cpp index 6eac87be10e..f7e0bf3a99d 100644 --- a/gnu/llvm/lldb/source/Host/android/LibcGlue.cpp +++ b/gnu/llvm/lldb/source/Host/android/LibcGlue.cpp @@ -1,4 +1,4 @@ -//===-- LibcGlue.cpp --------------------------------------------*- C++ -*-===// +//===-- LibcGlue.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/Editline.cpp b/gnu/llvm/lldb/source/Host/common/Editline.cpp index 5fd5a0cfc7f..226e638aba2 100644 --- a/gnu/llvm/lldb/source/Host/common/Editline.cpp +++ b/gnu/llvm/lldb/source/Host/common/Editline.cpp @@ -1,4 +1,4 @@ -//===-- Editline.cpp --------------------------------------------*- C++ -*-===// +//===-- Editline.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include -#include #include #include "lldb/Host/ConnectionFileDescriptor.h" @@ -35,7 +34,7 @@ using namespace lldb_private::line_editor; // with until TERM is set to VT100 where it stumbles over an implementation // assumption that may not exist on other platforms. The setupterm() function // would normally require headers that don't work gracefully in this context, -// so the function declaraction has been hoisted here. +// so the function declaration has been hoisted here. #if defined(__APPLE__) extern "C" { int setupterm(char *term, int fildes, int *errret); @@ -99,18 +98,24 @@ bool IsOnlySpaces(const EditLineStringType &content) { static int GetOperation(HistoryOperation op) { // The naming used by editline for the history operations is counter - // intuitive to how it's used here. + // intuitive to how it's used in LLDB's editline implementation. + // + // - The H_LAST returns the oldest entry in the history. // // - The H_PREV operation returns the previous element in the history, which // is newer than the current one. // + // - The H_CURR returns the current entry in the history. + // // - The H_NEXT operation returns the next element in the history, which is // older than the current one. // + // - The H_FIRST returns the most recent entry in the history. + // // The naming of the enum entries match the semantic meaning. switch(op) { case HistoryOperation::Oldest: - return H_FIRST; + return H_LAST; case HistoryOperation::Older: return H_NEXT; case HistoryOperation::Current: @@ -118,7 +123,7 @@ static int GetOperation(HistoryOperation op) { case HistoryOperation::Newer: return H_PREV; case HistoryOperation::Newest: - return H_LAST; + return H_FIRST; } llvm_unreachable("Fully covered switch!"); } @@ -138,10 +143,10 @@ std::vector SplitLines(const EditLineStringType &input) { while (start < input.length()) { size_t end = input.find('\n', start); if (end == std::string::npos) { - result.insert(result.end(), input.substr(start)); + result.push_back(input.substr(start)); break; } - result.insert(result.end(), input.substr(start, end - start)); + result.push_back(input.substr(start, end - start)); start = end + 1; } return result; @@ -214,7 +219,7 @@ private: std::string filename = m_prefix + "-history"; #endif llvm::sys::path::append(lldb_history_file, filename); - m_path = lldb_history_file.str(); + m_path = std::string(lldb_history_file.str()); } } @@ -296,19 +301,16 @@ protected: // Editline private methods void Editline::SetBaseLineNumber(int line_number) { - std::stringstream line_number_stream; - line_number_stream << line_number; m_base_line_number = line_number; m_line_number_digits = - std::max(3, (int)line_number_stream.str().length() + 1); + std::max(3, std::to_string(line_number).length() + 1); } std::string Editline::PromptForIndex(int line_index) { bool use_line_numbers = m_multiline_enabled && m_base_line_number > 0; std::string prompt = m_set_prompt; - if (use_line_numbers && prompt.length() == 0) { + if (use_line_numbers && prompt.length() == 0) prompt = ": "; - } std::string continuation_prompt = prompt; if (m_set_continuation_prompt.length() > 0) { continuation_prompt = m_set_continuation_prompt; @@ -327,7 +329,7 @@ std::string Editline::PromptForIndex(int line_index) { prompt_stream.Printf( "%*d%s", m_line_number_digits, m_base_line_number + line_index, (line_index == 0) ? prompt.c_str() : continuation_prompt.c_str()); - return std::move(prompt_stream.GetString()); + return std::string(std::move(prompt_stream.GetString())); } return (line_index == 0) ? prompt : continuation_prompt; } @@ -423,7 +425,7 @@ void Editline::DisplayInput(int firstIndex) { } int Editline::CountRowsForLine(const EditLineStringType &content) { - auto prompt = + std::string prompt = PromptForIndex(0); // Prompt width is constant during an edit session int line_length = (int)(content.length() + prompt.length()); return (line_length / m_terminal_width) + 1; @@ -557,6 +559,9 @@ int Editline::GetCharacter(EditLineGetCharType *c) { lldb::ConnectionStatus status = lldb::eConnectionStatusSuccess; char ch = 0; + if (m_terminal_size_has_changed) + ApplyTerminalSizeChange(); + // This mutex is locked by our caller (GetLine). Unlock it while we read a // character (blocking operation), so we do not hold the mutex // indefinitely. This gives a chance for someone to interrupt us. After @@ -1049,7 +1054,7 @@ void Editline::ConfigureEditor(bool multiline) { m_editline = el_init(m_editor_name.c_str(), m_input_file, m_output_file, m_error_file); - TerminalSizeChanged(); + ApplyTerminalSizeChange(); if (m_history_sp && m_history_sp->IsValid()) { if (!m_history_sp->Load()) { @@ -1302,28 +1307,32 @@ void Editline::SetContinuationPrompt(const char *continuation_prompt) { continuation_prompt == nullptr ? "" : continuation_prompt; } -void Editline::TerminalSizeChanged() { - if (m_editline != nullptr) { - el_resize(m_editline); - int columns; - // This function is documenting as taking (const char *, void *) for the - // vararg part, but in reality in was consuming arguments until the first - // null pointer. This was fixed in libedit in April 2019 - // , - // but we're keeping the workaround until a version with that fix is more - // widely available. - if (el_get(m_editline, EL_GETTC, "co", &columns, nullptr) == 0) { - m_terminal_width = columns; - if (m_current_line_rows != -1) { - const LineInfoW *info = el_wline(m_editline); - int lineLength = - (int)((info->lastchar - info->buffer) + GetPromptWidth()); - m_current_line_rows = (lineLength / columns) + 1; - } - } else { - m_terminal_width = INT_MAX; - m_current_line_rows = 1; +void Editline::TerminalSizeChanged() { m_terminal_size_has_changed = 1; } + +void Editline::ApplyTerminalSizeChange() { + if (!m_editline) + return; + + m_terminal_size_has_changed = 0; + el_resize(m_editline); + int columns; + // This function is documenting as taking (const char *, void *) for the + // vararg part, but in reality in was consuming arguments until the first + // null pointer. This was fixed in libedit in April 2019 + // , + // but we're keeping the workaround until a version with that fix is more + // widely available. + if (el_get(m_editline, EL_GETTC, "co", &columns, nullptr) == 0) { + m_terminal_width = columns; + if (m_current_line_rows != -1) { + const LineInfoW *info = el_wline(m_editline); + int lineLength = + (int)((info->lastchar - info->buffer) + GetPromptWidth()); + m_current_line_rows = (lineLength / columns) + 1; } + } else { + m_terminal_width = INT_MAX; + m_current_line_rows = 1; } } diff --git a/gnu/llvm/lldb/source/Host/common/File.cpp b/gnu/llvm/lldb/source/Host/common/File.cpp index 7850222376f..a5b970907e6 100644 --- a/gnu/llvm/lldb/source/Host/common/File.cpp +++ b/gnu/llvm/lldb/source/Host/common/File.cpp @@ -1,4 +1,4 @@ -//===-- File.cpp ------------------------------------------------*- C++ -*-===// +//===-- File.cpp ----------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/FileAction.cpp b/gnu/llvm/lldb/source/Host/common/FileAction.cpp index 3268d952bcc..8b4e7f4c220 100644 --- a/gnu/llvm/lldb/source/Host/common/FileAction.cpp +++ b/gnu/llvm/lldb/source/Host/common/FileAction.cpp @@ -1,4 +1,4 @@ -//===-- FileAction.cpp ------------------------------------------*- C++ -*-===// +//===-- FileAction.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/FileCache.cpp b/gnu/llvm/lldb/source/Host/common/FileCache.cpp index d9dcad992c3..da9a748e2f1 100644 --- a/gnu/llvm/lldb/source/Host/common/FileCache.cpp +++ b/gnu/llvm/lldb/source/Host/common/FileCache.cpp @@ -1,4 +1,4 @@ -//===-- FileCache.cpp -------------------------------------------*- C++ -*-===// +//===-- FileCache.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/FileSystem.cpp b/gnu/llvm/lldb/source/Host/common/FileSystem.cpp index 2db5bff3207..0fa27d131e1 100644 --- a/gnu/llvm/lldb/source/Host/common/FileSystem.cpp +++ b/gnu/llvm/lldb/source/Host/common/FileSystem.cpp @@ -1,4 +1,4 @@ -//===-- FileSystem.cpp ------------------------------------------*- C++ -*-===// +//===-- FileSystem.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -87,6 +87,11 @@ Optional &FileSystem::InstanceImpl() { vfs::directory_iterator FileSystem::DirBegin(const FileSpec &file_spec, std::error_code &ec) { + if (!file_spec) { + ec = std::error_code(static_cast(errc::no_such_file_or_directory), + std::system_category()); + return {}; + } return DirBegin(file_spec.GetPath(), ec); } @@ -97,6 +102,9 @@ vfs::directory_iterator FileSystem::DirBegin(const Twine &dir, llvm::ErrorOr FileSystem::GetStatus(const FileSpec &file_spec) const { + if (!file_spec) + return std::error_code(static_cast(errc::no_such_file_or_directory), + std::system_category()); return GetStatus(file_spec.GetPath()); } @@ -106,6 +114,8 @@ llvm::ErrorOr FileSystem::GetStatus(const Twine &path) const { sys::TimePoint<> FileSystem::GetModificationTime(const FileSpec &file_spec) const { + if (!file_spec) + return sys::TimePoint<>(); return GetModificationTime(file_spec.GetPath()); } @@ -117,6 +127,8 @@ sys::TimePoint<> FileSystem::GetModificationTime(const Twine &path) const { } uint64_t FileSystem::GetByteSize(const FileSpec &file_spec) const { + if (!file_spec) + return 0; return GetByteSize(file_spec.GetPath()); } @@ -133,6 +145,8 @@ uint32_t FileSystem::GetPermissions(const FileSpec &file_spec) const { uint32_t FileSystem::GetPermissions(const FileSpec &file_spec, std::error_code &ec) const { + if (!file_spec) + return sys::fs::perms::perms_not_known; return GetPermissions(file_spec.GetPath(), ec); } @@ -154,7 +168,7 @@ uint32_t FileSystem::GetPermissions(const Twine &path, 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()); + return file_spec && Exists(file_spec.GetPath()); } bool FileSystem::Readable(const Twine &path) const { @@ -162,7 +176,7 @@ bool FileSystem::Readable(const Twine &path) const { } bool FileSystem::Readable(const FileSpec &file_spec) const { - return Readable(file_spec.GetPath()); + return file_spec && Readable(file_spec.GetPath()); } bool FileSystem::IsDirectory(const Twine &path) const { @@ -173,7 +187,7 @@ bool FileSystem::IsDirectory(const Twine &path) const { } bool FileSystem::IsDirectory(const FileSpec &file_spec) const { - return IsDirectory(file_spec.GetPath()); + return file_spec && IsDirectory(file_spec.GetPath()); } bool FileSystem::IsLocal(const Twine &path) const { @@ -183,7 +197,7 @@ bool FileSystem::IsLocal(const Twine &path) const { } bool FileSystem::IsLocal(const FileSpec &file_spec) const { - return IsLocal(file_spec.GetPath()); + return file_spec && IsLocal(file_spec.GetPath()); } void FileSystem::EnumerateDirectory(Twine path, bool find_directories, @@ -261,6 +275,9 @@ void FileSystem::Resolve(SmallVectorImpl &path) { } void FileSystem::Resolve(FileSpec &file_spec) { + if (!file_spec) + return; + // Extract path from the FileSpec. SmallString<128> path; file_spec.GetPath(path); @@ -279,8 +296,7 @@ void FileSystem::Resolve(FileSpec &file_spec) { std::shared_ptr FileSystem::CreateDataBuffer(const llvm::Twine &path, uint64_t size, uint64_t offset) { - if (m_collector) - m_collector->addFile(path); + Collect(path); const bool is_volatile = !IsLocal(path); const ErrorOr external_path = GetExternalPath(path); @@ -418,8 +434,7 @@ static mode_t GetOpenMode(uint32_t permissions) { Expected FileSystem::Open(const FileSpec &file_spec, File::OpenOptions options, uint32_t permissions, bool should_close_fd) { - if (m_collector) - m_collector->addFile(file_spec.GetPath()); + Collect(file_spec.GetPath()); const int open_flags = GetOpenFlags(options); const mode_t open_mode = @@ -466,3 +481,17 @@ ErrorOr FileSystem::GetExternalPath(const llvm::Twine &path) { ErrorOr FileSystem::GetExternalPath(const FileSpec &file_spec) { return GetExternalPath(file_spec.GetPath()); } + +void FileSystem::Collect(const FileSpec &file_spec) { + Collect(file_spec.GetPath()); +} + +void FileSystem::Collect(const llvm::Twine &file) { + if (!m_collector) + return; + + if (llvm::sys::fs::is_directory(file)) + m_collector->addDirectory(file); + else + m_collector->addFile(file); +} diff --git a/gnu/llvm/lldb/source/Host/common/GetOptInc.cpp b/gnu/llvm/lldb/source/Host/common/GetOptInc.cpp index 95a68c5d3c7..62ce7428e8c 100644 --- a/gnu/llvm/lldb/source/Host/common/GetOptInc.cpp +++ b/gnu/llvm/lldb/source/Host/common/GetOptInc.cpp @@ -1,4 +1,4 @@ -//===-- GetOptInc.cpp -------------------------------------------*- C++ -*-===// +//===-- GetOptInc.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/Host.cpp b/gnu/llvm/lldb/source/Host/common/Host.cpp index 5fbb655fc79..4128fa19c14 100644 --- a/gnu/llvm/lldb/source/Host/common/Host.cpp +++ b/gnu/llvm/lldb/source/Host/common/Host.cpp @@ -1,4 +1,4 @@ -//===-- Host.cpp ------------------------------------------------*- C++ -*-===// +//===-- Host.cpp ----------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -28,7 +28,7 @@ #if defined(__linux__) || defined(__FreeBSD__) || \ defined(__FreeBSD_kernel__) || defined(__APPLE__) || \ - defined(__NetBSD__) || defined(__OpenBSD__) + defined(__NetBSD__) || defined(__OpenBSD__) || defined(__EMSCRIPTEN__) #if !defined(__ANDROID__) #include #endif @@ -501,6 +501,8 @@ Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir, launch_info.SetArguments(args, first_arg_is_executable); } + launch_info.GetEnvironment() = Host::GetEnvironment(); + if (working_dir) launch_info.SetWorkingDirectory(working_dir); llvm::SmallString<64> output_file_path; @@ -519,7 +521,7 @@ Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir, } } - FileSpec output_file_spec(output_file_path.c_str()); + FileSpec output_file_spec(output_file_path.str()); // Set up file descriptors. launch_info.AppendSuppressFileAction(STDIN_FILENO, true, false); if (output_file_spec) @@ -678,3 +680,23 @@ void llvm::format_provider::format(const WaitStatus &WS, } OS << desc << " " << int(WS.status); } + +uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, + ProcessInstanceInfoList &process_infos) { + + if (llvm::Optional infos = + repro::GetReplayProcessInstanceInfoList()) { + process_infos = *infos; + return process_infos.size(); + } + + uint32_t result = FindProcessesImpl(match_info, process_infos); + + if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) { + g->GetOrCreate() + .GetNewProcessInfoRecorder() + ->Record(process_infos); + } + + return result; +} diff --git a/gnu/llvm/lldb/source/Host/common/HostInfoBase.cpp b/gnu/llvm/lldb/source/Host/common/HostInfoBase.cpp index 8f263e90d90..333137a7fd2 100644 --- a/gnu/llvm/lldb/source/Host/common/HostInfoBase.cpp +++ b/gnu/llvm/lldb/source/Host/common/HostInfoBase.cpp @@ -1,4 +1,4 @@ -//===-- HostInfoBase.cpp ----------------------------------------*- C++ -*-===// +//===-- HostInfoBase.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/HostNativeThreadBase.cpp b/gnu/llvm/lldb/source/Host/common/HostNativeThreadBase.cpp index fe7d85acaf1..a79431f61d8 100644 --- a/gnu/llvm/lldb/source/Host/common/HostNativeThreadBase.cpp +++ b/gnu/llvm/lldb/source/Host/common/HostNativeThreadBase.cpp @@ -1,4 +1,4 @@ -//===-- HostNativeThreadBase.cpp --------------------------------*- C++ -*-===// +//===-- HostNativeThreadBase.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/HostProcess.cpp b/gnu/llvm/lldb/source/Host/common/HostProcess.cpp index e180687551f..256a73bb671 100644 --- a/gnu/llvm/lldb/source/Host/common/HostProcess.cpp +++ b/gnu/llvm/lldb/source/Host/common/HostProcess.cpp @@ -1,4 +1,4 @@ -//===-- HostProcess.cpp -----------------------------------------*- C++ -*-===// +//===-- HostProcess.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/HostThread.cpp b/gnu/llvm/lldb/source/Host/common/HostThread.cpp index 89cadce5b20..eec029be1c0 100644 --- a/gnu/llvm/lldb/source/Host/common/HostThread.cpp +++ b/gnu/llvm/lldb/source/Host/common/HostThread.cpp @@ -1,4 +1,4 @@ -//===-- HostThread.cpp ------------------------------------------*- C++ -*-===// +//===-- HostThread.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/LZMA.cpp b/gnu/llvm/lldb/source/Host/common/LZMA.cpp index 02be8a09df6..5b457f07afc 100644 --- a/gnu/llvm/lldb/source/Host/common/LZMA.cpp +++ b/gnu/llvm/lldb/source/Host/common/LZMA.cpp @@ -1,4 +1,4 @@ -//===-- LZMA.cpp ------------------------------------------------*- C++ -*-===// +//===-- LZMA.cpp ----------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/LockFileBase.cpp b/gnu/llvm/lldb/source/Host/common/LockFileBase.cpp index 744b1eaabb4..d4cd8f7ffed 100644 --- a/gnu/llvm/lldb/source/Host/common/LockFileBase.cpp +++ b/gnu/llvm/lldb/source/Host/common/LockFileBase.cpp @@ -1,4 +1,4 @@ -//===-- LockFileBase.cpp ----------------------------------------*- C++ -*-===// +//===-- LockFileBase.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/MainLoop.cpp b/gnu/llvm/lldb/source/Host/common/MainLoop.cpp index 240320f8324..02cabbc9355 100644 --- a/gnu/llvm/lldb/source/Host/common/MainLoop.cpp +++ b/gnu/llvm/lldb/source/Host/common/MainLoop.cpp @@ -1,4 +1,4 @@ -//===-- MainLoop.cpp --------------------------------------------*- C++ -*-===// +//===-- MainLoop.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/MonitoringProcessLauncher.cpp b/gnu/llvm/lldb/source/Host/common/MonitoringProcessLauncher.cpp index 55e9f69a089..1ef345cd508 100644 --- a/gnu/llvm/lldb/source/Host/common/MonitoringProcessLauncher.cpp +++ b/gnu/llvm/lldb/source/Host/common/MonitoringProcessLauncher.cpp @@ -1,4 +1,4 @@ -//===-- MonitoringProcessLauncher.cpp ---------------------------*- C++ -*-===// +//===-- MonitoringProcessLauncher.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/NativeProcessProtocol.cpp b/gnu/llvm/lldb/source/Host/common/NativeProcessProtocol.cpp index 712c448dc2c..a4d0b4181d5 100644 --- a/gnu/llvm/lldb/source/Host/common/NativeProcessProtocol.cpp +++ b/gnu/llvm/lldb/source/Host/common/NativeProcessProtocol.cpp @@ -1,4 +1,4 @@ -//===-- NativeProcessProtocol.cpp -------------------------------*- C++ -*-===// +//===-- NativeProcessProtocol.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -650,7 +650,7 @@ Status NativeProcessProtocol::ReadMemoryWithoutTrap(lldb::addr_t addr, 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 + continue; // Breakpoint not in range, ignore if (bp_addr < addr) { saved_opcodes = saved_opcodes.drop_front(addr - bp_addr); diff --git a/gnu/llvm/lldb/source/Host/common/NativeRegisterContext.cpp b/gnu/llvm/lldb/source/Host/common/NativeRegisterContext.cpp index fe40073eb59..47548f90491 100644 --- a/gnu/llvm/lldb/source/Host/common/NativeRegisterContext.cpp +++ b/gnu/llvm/lldb/source/Host/common/NativeRegisterContext.cpp @@ -1,4 +1,4 @@ -//===-- NativeRegisterContext.cpp -------------------------*- C++ -*-===// +//===-- NativeRegisterContext.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/NativeThreadProtocol.cpp b/gnu/llvm/lldb/source/Host/common/NativeThreadProtocol.cpp index e62b1425c89..16901bc9cf7 100644 --- a/gnu/llvm/lldb/source/Host/common/NativeThreadProtocol.cpp +++ b/gnu/llvm/lldb/source/Host/common/NativeThreadProtocol.cpp @@ -1,4 +1,4 @@ -//===-- NativeThreadProtocol.cpp --------------------------------*- C++ -*-===// +//===-- NativeThreadProtocol.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/NativeWatchpointList.cpp b/gnu/llvm/lldb/source/Host/common/NativeWatchpointList.cpp index c3db95fb252..6d856202d14 100644 --- a/gnu/llvm/lldb/source/Host/common/NativeWatchpointList.cpp +++ b/gnu/llvm/lldb/source/Host/common/NativeWatchpointList.cpp @@ -1,4 +1,4 @@ -//===-- NativeWatchpointList.cpp --------------------------------*- C++ -*-===// +//===-- NativeWatchpointList.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/OptionParser.cpp b/gnu/llvm/lldb/source/Host/common/OptionParser.cpp index 1e76f9b8f9f..b5c7ea66732 100644 --- a/gnu/llvm/lldb/source/Host/common/OptionParser.cpp +++ b/gnu/llvm/lldb/source/Host/common/OptionParser.cpp @@ -1,4 +1,4 @@ -//===-- source/Host/common/OptionParser.cpp ---------------------*- C++ -*-===// +//===-- source/Host/common/OptionParser.cpp -------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -41,7 +41,7 @@ int OptionParser::Parse(llvm::MutableArrayRef argv, ++longopts; } opts.push_back(option()); - std::string opt_cstr = optstring; + std::string opt_cstr = std::string(optstring); return getopt_long_only(argv.size() - 1, argv.data(), opt_cstr.c_str(), &opts[0], longindex); } diff --git a/gnu/llvm/lldb/source/Host/common/PipeBase.cpp b/gnu/llvm/lldb/source/Host/common/PipeBase.cpp index 2cbadf0c85f..b3e0ab34a58 100644 --- a/gnu/llvm/lldb/source/Host/common/PipeBase.cpp +++ b/gnu/llvm/lldb/source/Host/common/PipeBase.cpp @@ -1,4 +1,4 @@ -//===-- source/Host/common/PipeBase.cpp -------------------------*- C++ -*-===// +//===-- source/Host/common/PipeBase.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/ProcessLaunchInfo.cpp b/gnu/llvm/lldb/source/Host/common/ProcessLaunchInfo.cpp index 266b4676399..4bc8cda7a00 100644 --- a/gnu/llvm/lldb/source/Host/common/ProcessLaunchInfo.cpp +++ b/gnu/llvm/lldb/source/Host/common/ProcessLaunchInfo.cpp @@ -1,4 +1,4 @@ -//===-- ProcessLaunchInfo.cpp -----------------------------------*- C++ -*-===// +//===-- ProcessLaunchInfo.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -133,7 +133,7 @@ const char *ProcessLaunchInfo::GetProcessPluginName() const { } void ProcessLaunchInfo::SetProcessPluginName(llvm::StringRef plugin) { - m_plugin_name = plugin; + m_plugin_name = std::string(plugin); } const FileSpec &ProcessLaunchInfo::GetShell() const { return m_shell; } @@ -218,26 +218,26 @@ llvm::Error ProcessLaunchInfo::SetUpPtyRedirection() { // do for now. open_flags |= O_CLOEXEC; #endif - if (!m_pty->OpenFirstAvailableMaster(open_flags, nullptr, 0)) { + if (!m_pty->OpenFirstAvailablePrimary(open_flags, nullptr, 0)) { return llvm::createStringError(llvm::inconvertibleErrorCode(), - "PTY::OpenFirstAvailableMaster failed"); + "PTY::OpenFirstAvailablePrimary failed"); } - const FileSpec slave_file_spec(m_pty->GetSlaveName(nullptr, 0)); + const FileSpec secondary_file_spec(m_pty->GetSecondaryName(nullptr, 0)); - // Only use the slave tty if we don't have anything specified for + // Only use the secondary 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); + AppendOpenFileAction(STDIN_FILENO, secondary_file_spec, true, false); - // Only use the slave tty if we don't have anything specified for + // Only use the secondary 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); + AppendOpenFileAction(STDOUT_FILENO, secondary_file_spec, false, true); - // Only use the slave tty if we don't have anything specified for + // Only use the secondary 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); + AppendOpenFileAction(STDERR_FILENO, secondary_file_spec, false, true); return llvm::Error::success(); } diff --git a/gnu/llvm/lldb/source/Host/common/ProcessRunLock.cpp b/gnu/llvm/lldb/source/Host/common/ProcessRunLock.cpp index a931da71876..3b6f033d33a 100644 --- a/gnu/llvm/lldb/source/Host/common/ProcessRunLock.cpp +++ b/gnu/llvm/lldb/source/Host/common/ProcessRunLock.cpp @@ -1,4 +1,4 @@ -//===-- ProcessRunLock.cpp --------------------------------------*- C++ -*-===// +//===-- ProcessRunLock.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/PseudoTerminal.cpp b/gnu/llvm/lldb/source/Host/common/PseudoTerminal.cpp index 85828283e21..72549f1c88a 100644 --- a/gnu/llvm/lldb/source/Host/common/PseudoTerminal.cpp +++ b/gnu/llvm/lldb/source/Host/common/PseudoTerminal.cpp @@ -1,4 +1,4 @@ -//===-- PseudoTerminal.cpp --------------------------------------*- C++ -*-===// +//===-- PseudoTerminal.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -34,73 +34,73 @@ static void ErrnoToStr(char *error_str, size_t error_len) { // PseudoTerminal constructor PseudoTerminal::PseudoTerminal() - : m_master_fd(invalid_fd), m_slave_fd(invalid_fd) {} + : m_primary_fd(invalid_fd), m_secondary_fd(invalid_fd) {} // Destructor // -// The destructor will close the master and slave file descriptors if they are -// valid and ownership has not been released using the -// ReleaseMasterFileDescriptor() or the ReleaseSaveFileDescriptor() member +// The destructor will close the primary and secondary file descriptors if they +// are valid and ownership has not been released using the +// ReleasePrimaryFileDescriptor() or the ReleaseSaveFileDescriptor() member // functions. PseudoTerminal::~PseudoTerminal() { - CloseMasterFileDescriptor(); - CloseSlaveFileDescriptor(); + ClosePrimaryFileDescriptor(); + CloseSecondaryFileDescriptor(); } -// Close the master file descriptor if it is valid. -void PseudoTerminal::CloseMasterFileDescriptor() { - if (m_master_fd >= 0) { - ::close(m_master_fd); - m_master_fd = invalid_fd; +// Close the primary file descriptor if it is valid. +void PseudoTerminal::ClosePrimaryFileDescriptor() { + if (m_primary_fd >= 0) { + ::close(m_primary_fd); + m_primary_fd = invalid_fd; } } -// Close the slave file descriptor if it is valid. -void PseudoTerminal::CloseSlaveFileDescriptor() { - if (m_slave_fd >= 0) { - ::close(m_slave_fd); - m_slave_fd = invalid_fd; +// Close the secondary file descriptor if it is valid. +void PseudoTerminal::CloseSecondaryFileDescriptor() { + if (m_secondary_fd >= 0) { + ::close(m_secondary_fd); + m_secondary_fd = invalid_fd; } } // Open the first available pseudo terminal with OFLAG as the permissions. The // file descriptor is stored in this object and can be accessed with the -// MasterFileDescriptor() accessor. The ownership of the master file descriptor -// can be released using the ReleaseMasterFileDescriptor() accessor. If this -// object has a valid master files descriptor when its destructor is called, it -// will close the master file descriptor, therefore clients must call -// ReleaseMasterFileDescriptor() if they wish to use the master file descriptor -// after this object is out of scope or destroyed. +// PrimaryFileDescriptor() accessor. The ownership of the primary file +// descriptor can be released using the ReleasePrimaryFileDescriptor() accessor. +// If this object has a valid primary files descriptor when its destructor is +// called, it will close the primary file descriptor, therefore clients must +// call ReleasePrimaryFileDescriptor() if they wish to use the primary file +// descriptor after this object is out of scope or destroyed. // // RETURNS: // True when successful, false indicating an error occurred. -bool PseudoTerminal::OpenFirstAvailableMaster(int oflag, char *error_str, - size_t error_len) { +bool PseudoTerminal::OpenFirstAvailablePrimary(int oflag, char *error_str, + size_t error_len) { if (error_str) error_str[0] = '\0'; #if LLDB_ENABLE_POSIX - // Open the master side of a pseudo terminal - m_master_fd = ::posix_openpt(oflag); - if (m_master_fd < 0) { + // Open the primary side of a pseudo terminal + m_primary_fd = ::posix_openpt(oflag); + if (m_primary_fd < 0) { if (error_str) ErrnoToStr(error_str, error_len); return false; } - // Grant access to the slave pseudo terminal - if (::grantpt(m_master_fd) < 0) { + // Grant access to the secondary pseudo terminal + if (::grantpt(m_primary_fd) < 0) { if (error_str) ErrnoToStr(error_str, error_len); - CloseMasterFileDescriptor(); + ClosePrimaryFileDescriptor(); return false; } - // Clear the lock flag on the slave pseudo terminal - if (::unlockpt(m_master_fd) < 0) { + // Clear the lock flag on the secondary pseudo terminal + if (::unlockpt(m_primary_fd) < 0) { if (error_str) ErrnoToStr(error_str, error_len); - CloseMasterFileDescriptor(); + ClosePrimaryFileDescriptor(); return false; } @@ -112,30 +112,32 @@ bool PseudoTerminal::OpenFirstAvailableMaster(int oflag, char *error_str, #endif } -// Open the slave pseudo terminal for the current master pseudo terminal. A -// master pseudo terminal should already be valid prior to calling this -// function (see OpenFirstAvailableMaster()). The file descriptor is stored +// Open the secondary pseudo terminal for the current primary pseudo terminal. A +// primary pseudo terminal should already be valid prior to calling this +// function (see OpenFirstAvailablePrimary()). The file descriptor is stored // this object's member variables and can be accessed via the -// GetSlaveFileDescriptor(), or released using the ReleaseSlaveFileDescriptor() -// member function. +// GetSecondaryFileDescriptor(), or released using the +// ReleaseSecondaryFileDescriptor() member function. // // RETURNS: // True when successful, false indicating an error occurred. -bool PseudoTerminal::OpenSlave(int oflag, char *error_str, size_t error_len) { +bool PseudoTerminal::OpenSecondary(int oflag, char *error_str, + size_t error_len) { if (error_str) error_str[0] = '\0'; - CloseSlaveFileDescriptor(); + CloseSecondaryFileDescriptor(); - // Open the master side of a pseudo terminal - const char *slave_name = GetSlaveName(error_str, error_len); + // Open the primary side of a pseudo terminal + const char *secondary_name = GetSecondaryName(error_str, error_len); - if (slave_name == nullptr) + if (secondary_name == nullptr) return false; - m_slave_fd = llvm::sys::RetryAfterSignal(-1, ::open, slave_name, oflag); + m_secondary_fd = + llvm::sys::RetryAfterSignal(-1, ::open, secondary_name, oflag); - if (m_slave_fd < 0) { + if (m_secondary_fd < 0) { if (error_str) ErrnoToStr(error_str, error_len); return false; @@ -144,46 +146,46 @@ bool PseudoTerminal::OpenSlave(int oflag, char *error_str, size_t error_len) { return true; } -// Get the name of the slave pseudo terminal. A master pseudo terminal should -// already be valid prior to calling this function (see -// OpenFirstAvailableMaster()). +// Get the name of the secondary pseudo terminal. A primary pseudo terminal +// should already be valid prior to calling this function (see +// OpenFirstAvailablePrimary()). // // RETURNS: -// NULL if no valid master pseudo terminal or if ptsname() fails. -// The name of the slave pseudo terminal as a NULL terminated C string +// NULL if no valid primary pseudo terminal or if ptsname() fails. +// The name of the secondary pseudo terminal as a NULL terminated C string // that comes from static memory, so a copy of the string should be // made as subsequent calls can change this value. -const char *PseudoTerminal::GetSlaveName(char *error_str, - size_t error_len) const { +const char *PseudoTerminal::GetSecondaryName(char *error_str, + size_t error_len) const { if (error_str) error_str[0] = '\0'; - if (m_master_fd < 0) { + if (m_primary_fd < 0) { if (error_str) ::snprintf(error_str, error_len, "%s", - "master file descriptor is invalid"); + "primary file descriptor is invalid"); return nullptr; } - const char *slave_name = ::ptsname(m_master_fd); + const char *secondary_name = ::ptsname(m_primary_fd); - if (error_str && slave_name == nullptr) + if (error_str && secondary_name == nullptr) ErrnoToStr(error_str, error_len); - return slave_name; + return secondary_name; } // Fork a child process and have its stdio routed to a pseudo terminal. // -// In the parent process when a valid pid is returned, the master file +// In the parent process when a valid pid is returned, the primary file // descriptor can be used as a read/write access to stdio of the child process. // // In the child process the stdin/stdout/stderr will already be routed to the -// slave pseudo terminal and the master file descriptor will be closed as it is -// no longer needed by the child process. +// secondary pseudo terminal and the primary file descriptor will be closed as +// it is no longer needed by the child process. // -// This class will close the file descriptors for the master/slave when the -// destructor is called, so be sure to call ReleaseMasterFileDescriptor() or -// ReleaseSlaveFileDescriptor() if any file descriptors are going to be used +// This class will close the file descriptors for the primary/secondary when the +// destructor is called, so be sure to call ReleasePrimaryFileDescriptor() or +// ReleaseSecondaryFileDescriptor() if any file descriptors are going to be used // past the lifespan of this object. // // RETURNS: @@ -196,8 +198,8 @@ lldb::pid_t PseudoTerminal::Fork(char *error_str, size_t error_len) { #if LLDB_ENABLE_POSIX int flags = O_RDWR; flags |= O_CLOEXEC; - if (OpenFirstAvailableMaster(flags, error_str, error_len)) { - // Successfully opened our master pseudo terminal + if (OpenFirstAvailablePrimary(flags, error_str, error_len)) { + // Successfully opened our primary pseudo terminal pid = ::fork(); if (pid < 0) { @@ -208,32 +210,32 @@ lldb::pid_t PseudoTerminal::Fork(char *error_str, size_t error_len) { // Child Process ::setsid(); - if (OpenSlave(O_RDWR, error_str, error_len)) { - // Successfully opened slave + if (OpenSecondary(O_RDWR, error_str, error_len)) { + // Successfully opened secondary - // Master FD should have O_CLOEXEC set, but let's close it just in + // Primary FD should have O_CLOEXEC set, but let's close it just in // case... - CloseMasterFileDescriptor(); + ClosePrimaryFileDescriptor(); #if defined(TIOCSCTTY) // Acquire the controlling terminal - if (::ioctl(m_slave_fd, TIOCSCTTY, (char *)0) < 0) { + if (::ioctl(m_secondary_fd, TIOCSCTTY, (char *)0) < 0) { if (error_str) 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) { + // Duplicate all stdio file descriptors to the secondary pseudo terminal + if (::dup2(m_secondary_fd, STDIN_FILENO) != STDIN_FILENO) { if (error_str && !error_str[0]) ErrnoToStr(error_str, error_len); } - if (::dup2(m_slave_fd, STDOUT_FILENO) != STDOUT_FILENO) { + if (::dup2(m_secondary_fd, STDOUT_FILENO) != STDOUT_FILENO) { if (error_str && !error_str[0]) ErrnoToStr(error_str, error_len); } - if (::dup2(m_slave_fd, STDERR_FILENO) != STDERR_FILENO) { + if (::dup2(m_secondary_fd, STDERR_FILENO) != STDERR_FILENO) { if (error_str && !error_str[0]) ErrnoToStr(error_str, error_len); } @@ -247,41 +249,43 @@ lldb::pid_t PseudoTerminal::Fork(char *error_str, size_t error_len) { return pid; } -// The master file descriptor accessor. This object retains ownership of the -// master file descriptor when this accessor is used. Use -// ReleaseMasterFileDescriptor() if you wish this object to release ownership -// of the master file descriptor. +// The primary file descriptor accessor. This object retains ownership of the +// primary file descriptor when this accessor is used. Use +// ReleasePrimaryFileDescriptor() if you wish this object to release ownership +// of the primary file descriptor. // -// Returns the master file descriptor, or -1 if the master file descriptor is +// Returns the primary file descriptor, or -1 if the primary file descriptor is // not currently valid. -int PseudoTerminal::GetMasterFileDescriptor() const { return m_master_fd; } +int PseudoTerminal::GetPrimaryFileDescriptor() const { return m_primary_fd; } -// The slave file descriptor accessor. +// The secondary file descriptor accessor. // -// Returns the slave file descriptor, or -1 if the slave file descriptor is not -// currently valid. -int PseudoTerminal::GetSlaveFileDescriptor() const { return m_slave_fd; } +// Returns the secondary file descriptor, or -1 if the secondary file descriptor +// is not currently valid. +int PseudoTerminal::GetSecondaryFileDescriptor() const { + return m_secondary_fd; +} -// Release ownership of the master pseudo terminal file descriptor without -// closing it. The destructor for this class will close the master file -// descriptor if the ownership isn't released using this call and the master +// Release ownership of the primary pseudo terminal file descriptor without +// closing it. The destructor for this class will close the primary file +// descriptor if the ownership isn't released using this call and the primary // file descriptor has been opened. -int PseudoTerminal::ReleaseMasterFileDescriptor() { - // Release ownership of the master pseudo terminal file descriptor without +int PseudoTerminal::ReleasePrimaryFileDescriptor() { + // Release ownership of the primary pseudo terminal file descriptor without // closing it. (the destructor for this class will close it otherwise!) - int fd = m_master_fd; - m_master_fd = invalid_fd; + int fd = m_primary_fd; + m_primary_fd = invalid_fd; return fd; } -// Release ownership of the slave pseudo terminal file descriptor without -// closing it. The destructor for this class will close the slave file -// descriptor if the ownership isn't released using this call and the slave +// Release ownership of the secondary pseudo terminal file descriptor without +// closing it. The destructor for this class will close the secondary file +// descriptor if the ownership isn't released using this call and the secondary // file descriptor has been opened. -int PseudoTerminal::ReleaseSlaveFileDescriptor() { - // Release ownership of the slave pseudo terminal file descriptor without +int PseudoTerminal::ReleaseSecondaryFileDescriptor() { + // Release ownership of the secondary pseudo terminal file descriptor without // closing it (the destructor for this class will close it otherwise!) - int fd = m_slave_fd; - m_slave_fd = invalid_fd; + int fd = m_secondary_fd; + m_secondary_fd = invalid_fd; return fd; } diff --git a/gnu/llvm/lldb/source/Host/common/Socket.cpp b/gnu/llvm/lldb/source/Host/common/Socket.cpp index 7fba1daff75..4bcf34a6b45 100644 --- a/gnu/llvm/lldb/source/Host/common/Socket.cpp +++ b/gnu/llvm/lldb/source/Host/common/Socket.cpp @@ -1,4 +1,4 @@ -//===-- Socket.cpp ----------------------------------------------*- C++ -*-===// +//===-- Socket.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -147,71 +147,65 @@ std::unique_ptr Socket::Create(const SocketProtocol protocol, return socket_up; } -Status Socket::TcpConnect(llvm::StringRef host_and_port, - bool child_processes_inherit, Socket *&socket) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION)); - LLDB_LOGF(log, "Socket::%s (host/port = %s)", __FUNCTION__, - host_and_port.str().c_str()); +llvm::Expected> +Socket::TcpConnect(llvm::StringRef host_and_port, + bool child_processes_inherit) { + Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); + LLDB_LOG(log, "host_and_port = {0}", host_and_port); Status error; std::unique_ptr connect_socket( Create(ProtocolTcp, child_processes_inherit, error)); if (error.Fail()) - return error; + return error.ToError(); error = connect_socket->Connect(host_and_port); if (error.Success()) - socket = connect_socket.release(); + return std::move(connect_socket); - return error; + return error.ToError(); } -Status Socket::TcpListen(llvm::StringRef host_and_port, - bool child_processes_inherit, Socket *&socket, - Predicate *predicate, int backlog) { +llvm::Expected> +Socket::TcpListen(llvm::StringRef host_and_port, bool child_processes_inherit, + Predicate *predicate, int backlog) { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); - LLDB_LOGF(log, "Socket::%s (%s)", __FUNCTION__, host_and_port.str().c_str()); + LLDB_LOG(log, "host_and_port = {0}", host_and_port); Status error; std::string host_str; std::string port_str; int32_t port = INT32_MIN; if (!DecodeHostAndPort(host_and_port, host_str, port_str, port, &error)) - return error; + return error.ToError(); std::unique_ptr listen_socket( new TCPSocket(true, child_processes_inherit)); - if (error.Fail()) - return error; error = listen_socket->Listen(host_and_port, backlog); - if (error.Success()) { - // We were asked to listen on port zero which means we must now read the - // actual port that was given to us as port zero is a special code for - // "find an open port for me". - if (port == 0) - port = listen_socket->GetLocalPortNumber(); - - // Set the port predicate since when doing a listen://: it - // often needs to accept the incoming connection which is a blocking system - // call. Allowing access to the bound port using a predicate allows us to - // wait for the port predicate to be set to a non-zero value from another - // thread in an efficient manor. - if (predicate) - predicate->SetValue(port, eBroadcastAlways); - socket = listen_socket.release(); - } - - return error; + if (error.Fail()) + return error.ToError(); + + // We were asked to listen on port zero which means we must now read the + // actual port that was given to us as port zero is a special code for + // "find an open port for me". + if (port == 0) + port = listen_socket->GetLocalPortNumber(); + + // Set the port predicate since when doing a listen://: it + // often needs to accept the incoming connection which is a blocking system + // call. Allowing access to the bound port using a predicate allows us to + // wait for the port predicate to be set to a non-zero value from another + // thread in an efficient manor. + if (predicate) + predicate->SetValue(port, eBroadcastAlways); + return std::move(listen_socket); } -Status Socket::UdpConnect(llvm::StringRef host_and_port, - bool child_processes_inherit, Socket *&socket) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); - LLDB_LOGF(log, "Socket::%s (host/port = %s)", __FUNCTION__, - host_and_port.str().c_str()); - - return UDPSocket::Connect(host_and_port, child_processes_inherit, socket); +llvm::Expected> +Socket::UdpConnect(llvm::StringRef host_and_port, + bool child_processes_inherit) { + return UDPSocket::Connect(host_and_port, child_processes_inherit); } Status Socket::UnixDomainConnect(llvm::StringRef name, @@ -309,7 +303,7 @@ bool Socket::DecodeHostAndPort(llvm::StringRef host_and_port, host_str.clear(); port_str.clear(); if (to_integer(host_and_port, port, 10) && port < UINT16_MAX) { - port_str = host_and_port; + port_str = std::string(host_and_port); if (error_ptr) error_ptr->Clear(); return true; diff --git a/gnu/llvm/lldb/source/Host/common/SocketAddress.cpp b/gnu/llvm/lldb/source/Host/common/SocketAddress.cpp index 7431e3a155e..e98944d6cdc 100644 --- a/gnu/llvm/lldb/source/Host/common/SocketAddress.cpp +++ b/gnu/llvm/lldb/source/Host/common/SocketAddress.cpp @@ -1,4 +1,4 @@ -//===-- SocketAddress.cpp ---------------------------------------*- C++ -*-===// +//===-- SocketAddress.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -113,7 +113,7 @@ static socklen_t GetFamilyLength(sa_family_t family) { } socklen_t SocketAddress::GetLength() const { -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) return m_socket_addr.sa.sa_len; #else return GetFamilyLength(GetFamily()); @@ -128,7 +128,7 @@ sa_family_t SocketAddress::GetFamily() const { void SocketAddress::SetFamily(sa_family_t family) { m_socket_addr.sa.sa_family = family; -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) m_socket_addr.sa.sa_len = GetFamilyLength(family); #endif } diff --git a/gnu/llvm/lldb/source/Host/common/StringConvert.cpp b/gnu/llvm/lldb/source/Host/common/StringConvert.cpp index 8bf04f0a9ca..e5f05e628c7 100644 --- a/gnu/llvm/lldb/source/Host/common/StringConvert.cpp +++ b/gnu/llvm/lldb/source/Host/common/StringConvert.cpp @@ -1,4 +1,4 @@ -//===-- StringConvert.cpp ---------------------------------------*- C++ -*-===// +//===-- StringConvert.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/TCPSocket.cpp b/gnu/llvm/lldb/source/Host/common/TCPSocket.cpp index b716935db6e..047cb0e4c2b 100644 --- a/gnu/llvm/lldb/source/Host/common/TCPSocket.cpp +++ b/gnu/llvm/lldb/source/Host/common/TCPSocket.cpp @@ -1,4 +1,4 @@ -//===-- TCPSocket.cpp -------------------------------------------*- C++ -*-===// +//===-- TCPSocket.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,6 +18,7 @@ #include "llvm/Config/llvm-config.h" #include "llvm/Support/Errno.h" +#include "llvm/Support/WindowsError.h" #include "llvm/Support/raw_ostream.h" #if LLDB_ENABLE_POSIX @@ -42,6 +43,16 @@ typedef const void *set_socket_option_arg_type; using namespace lldb; using namespace lldb_private; +static Status GetLastSocketError() { + std::error_code EC; +#ifdef _WIN32 + EC = llvm::mapWindowsError(WSAGetLastError()); +#else + EC = std::error_code(errno, std::generic_category()); +#endif + return EC; +} + namespace { const int kType = SOCK_STREAM; } @@ -120,8 +131,8 @@ std::string TCPSocket::GetRemoteIPAddress() const { std::string TCPSocket::GetRemoteConnectionURI() const { if (m_socket != kInvalidSocketValue) { - return llvm::formatv("connect://[{0}]:{1}", GetRemoteIPAddress(), - GetRemotePortNumber()); + return std::string(llvm::formatv( + "connect://[{0}]:{1}", GetRemoteIPAddress(), GetRemotePortNumber())); } return ""; } @@ -192,10 +203,8 @@ Status TCPSocket::Listen(llvm::StringRef name, int backlog) { for (SocketAddress &address : addresses) { int fd = Socket::CreateSocket(address.GetFamily(), kType, IPPROTO_TCP, m_child_processes_inherit, error); - if (error.Fail()) { - error.Clear(); + if (error.Fail()) continue; - } // enable local address reuse int option_value = 1; @@ -216,6 +225,7 @@ Status TCPSocket::Listen(llvm::StringRef name, int backlog) { err = ::listen(fd, backlog); if (-1 == err) { + error = GetLastSocketError(); CLOSE_SOCKET(fd); continue; } @@ -228,9 +238,11 @@ Status TCPSocket::Listen(llvm::StringRef name, int backlog) { m_listen_sockets[fd] = address; } - if (m_listen_sockets.size() == 0) - error.SetErrorString("Failed to connect port"); - return error; + if (m_listen_sockets.empty()) { + assert(error.Fail()); + return error; + } + return Status(); } void TCPSocket::CloseListenSockets() { diff --git a/gnu/llvm/lldb/source/Host/common/Terminal.cpp b/gnu/llvm/lldb/source/Host/common/Terminal.cpp index e1aea26eeb9..9990dbf7435 100644 --- a/gnu/llvm/lldb/source/Host/common/Terminal.cpp +++ b/gnu/llvm/lldb/source/Host/common/Terminal.cpp @@ -1,4 +1,4 @@ -//===-- Terminal.cpp --------------------------------------------*- C++ -*-===// +//===-- Terminal.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/ThreadLauncher.cpp b/gnu/llvm/lldb/source/Host/common/ThreadLauncher.cpp index 6e3c8b6a13a..bd104b3e4ae 100644 --- a/gnu/llvm/lldb/source/Host/common/ThreadLauncher.cpp +++ b/gnu/llvm/lldb/source/Host/common/ThreadLauncher.cpp @@ -1,4 +1,4 @@ -//===-- ThreadLauncher.cpp --------------------------------------*- C++ -*-===// +//===-- ThreadLauncher.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/common/UDPSocket.cpp b/gnu/llvm/lldb/source/Host/common/UDPSocket.cpp index 0a991c33645..0b537b3a9b1 100644 --- a/gnu/llvm/lldb/source/Host/common/UDPSocket.cpp +++ b/gnu/llvm/lldb/source/Host/common/UDPSocket.cpp @@ -1,4 +1,4 @@ -//===-- UDPSocket.cpp -------------------------------------------*- C++ -*-===// +//===-- UDPSocket.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -53,19 +53,19 @@ Status UDPSocket::Accept(Socket *&socket) { return Status("%s", g_not_supported_error); } -Status UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit, - Socket *&socket) { - std::unique_ptr final_socket; +llvm::Expected> +UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit) { + std::unique_ptr socket; Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); - LLDB_LOGF(log, "UDPSocket::%s (host/port = %s)", __FUNCTION__, name.data()); + LLDB_LOG(log, "host/port = {0}", name); Status error; std::string host_str; std::string port_str; int32_t port = INT32_MIN; if (!DecodeHostAndPort(name, host_str, port_str, port, &error)) - return error; + return error.ToError(); // At this point we have setup the receive port, now we need to setup the UDP // send socket @@ -86,7 +86,7 @@ Status UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit, "getaddrinfo(%s, %s, &hints, &info) returned error %i (%s)", #endif host_str.c_str(), port_str.c_str(), err, gai_strerror(err)); - return error; + return error.ToError(); } for (struct addrinfo *service_info_ptr = service_info_list; @@ -96,8 +96,8 @@ Status UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit, service_info_ptr->ai_family, service_info_ptr->ai_socktype, service_info_ptr->ai_protocol, child_processes_inherit, error); if (error.Success()) { - final_socket.reset(new UDPSocket(send_fd)); - final_socket->m_sockaddr = service_info_ptr; + socket.reset(new UDPSocket(send_fd)); + socket->m_sockaddr = service_info_ptr; break; } else continue; @@ -105,8 +105,8 @@ Status UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit, ::freeaddrinfo(service_info_list); - if (!final_socket) - return error; + if (!socket) + return error.ToError(); SocketAddress bind_addr; @@ -118,26 +118,25 @@ Status UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit, if (!bind_addr_success) { error.SetErrorString("Failed to get hostspec to bind for"); - return error; + return error.ToError(); } bind_addr.SetPort(0); // Let the source port # be determined dynamically - err = ::bind(final_socket->GetNativeSocket(), bind_addr, bind_addr.GetLength()); + err = ::bind(socket->GetNativeSocket(), bind_addr, bind_addr.GetLength()); struct sockaddr_in source_info; socklen_t address_len = sizeof (struct sockaddr_in); - err = ::getsockname(final_socket->GetNativeSocket(), (struct sockaddr *) &source_info, &address_len); + err = ::getsockname(socket->GetNativeSocket(), + (struct sockaddr *)&source_info, &address_len); - socket = final_socket.release(); - error.Clear(); - return error; + return std::move(socket); } std::string UDPSocket::GetRemoteConnectionURI() const { if (m_socket != kInvalidSocketValue) { - return llvm::formatv("udp://[{0}]:{1}", m_sockaddr.GetIPAddress(), - m_sockaddr.GetPort()); + return std::string(llvm::formatv( + "udp://[{0}]:{1}", m_sockaddr.GetIPAddress(), m_sockaddr.GetPort())); } return ""; } diff --git a/gnu/llvm/lldb/source/Host/common/XML.cpp b/gnu/llvm/lldb/source/Host/common/XML.cpp index 28d1f5a8eaf..456c879b014 100644 --- a/gnu/llvm/lldb/source/Host/common/XML.cpp +++ b/gnu/llvm/lldb/source/Host/common/XML.cpp @@ -1,4 +1,4 @@ -//===-- XML.cpp -------------------------------------------------*- C++ -*-===// +//===-- XML.cpp -----------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/freebsd/Host.cpp b/gnu/llvm/lldb/source/Host/freebsd/Host.cpp index 99d728d63bc..09547e48afa 100644 --- a/gnu/llvm/lldb/source/Host/freebsd/Host.cpp +++ b/gnu/llvm/lldb/source/Host/freebsd/Host.cpp @@ -1,5 +1,4 @@ -//===-- source/Host/freebsd/Host.cpp ------------------------------*- C++ -//-*-===// +//===-- source/Host/freebsd/Host.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -150,8 +149,8 @@ error: return false; } -uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, - ProcessInstanceInfoList &process_infos) { +uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info, + ProcessInstanceInfoList &process_infos) { const ::pid_t our_pid = ::getpid(); const ::uid_t our_uid = ::getuid(); std::vector kinfos; @@ -196,10 +195,10 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, bool already_registered = false; for (uint32_t pi = 0; !already_registered && (const int)kinfo.ki_numthreads > 1 && - pi < (const uint32_t)process_infos.GetSize(); + pi < (const uint32_t)process_infos.size(); pi++) already_registered = - (process_infos.GetProcessIDAtIndex(pi) == (uint32_t)kinfo.ki_pid); + (process_infos[pi].GetProcessID() == (uint32_t)kinfo.ki_pid); if (already_registered) continue; @@ -217,11 +216,11 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, GetFreeBSDProcessArgs(&match_info, process_info)) { GetFreeBSDProcessCPUType(process_info); if (match_info.Matches(process_info)) - process_infos.Append(process_info); + process_infos.push_back(process_info); } } - return process_infos.GetSize(); + return process_infos.size(); } bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) { diff --git a/gnu/llvm/lldb/source/Host/freebsd/HostInfoFreeBSD.cpp b/gnu/llvm/lldb/source/Host/freebsd/HostInfoFreeBSD.cpp index 7fc6f43d467..2db97dbcd74 100644 --- a/gnu/llvm/lldb/source/Host/freebsd/HostInfoFreeBSD.cpp +++ b/gnu/llvm/lldb/source/Host/freebsd/HostInfoFreeBSD.cpp @@ -1,4 +1,4 @@ -//===-- HostInfoFreeBSD.cpp -------------------------------------*- C++ -*-===// +//===-- HostInfoFreeBSD.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/linux/AbstractSocket.cpp b/gnu/llvm/lldb/source/Host/linux/AbstractSocket.cpp index 5a47787a5f4..833234028c8 100644 --- a/gnu/llvm/lldb/source/Host/linux/AbstractSocket.cpp +++ b/gnu/llvm/lldb/source/Host/linux/AbstractSocket.cpp @@ -1,4 +1,4 @@ -//===-- AbstractSocket.cpp --------------------------------------*- C++ -*-===// +//===-- AbstractSocket.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/linux/Host.cpp b/gnu/llvm/lldb/source/Host/linux/Host.cpp index fe60d1fd8a7..45973f5d214 100644 --- a/gnu/llvm/lldb/source/Host/linux/Host.cpp +++ b/gnu/llvm/lldb/source/Host/linux/Host.cpp @@ -1,4 +1,4 @@ -//===-- source/Host/linux/Host.cpp ------------------------------*- C++ -*-===// +//===-- source/Host/linux/Host.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -221,8 +221,8 @@ static bool GetProcessAndStatInfo(::pid_t pid, return true; } -uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, - ProcessInstanceInfoList &process_infos) { +uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info, + ProcessInstanceInfoList &process_infos) { static const char procdir[] = "/proc/"; DIR *dirproc = opendir(procdir); @@ -262,14 +262,14 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, continue; if (match_info.Matches(process_info)) { - process_infos.Append(process_info); + process_infos.push_back(process_info); } } closedir(dirproc); } - return process_infos.GetSize(); + return process_infos.size(); } bool Host::FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach) { diff --git a/gnu/llvm/lldb/source/Host/linux/HostInfoLinux.cpp b/gnu/llvm/lldb/source/Host/linux/HostInfoLinux.cpp index a008a74ec95..a35e5ef9e97 100644 --- a/gnu/llvm/lldb/source/Host/linux/HostInfoLinux.cpp +++ b/gnu/llvm/lldb/source/Host/linux/HostInfoLinux.cpp @@ -1,4 +1,4 @@ -//===-- HostInfoLinux.cpp ---------------------------------------*- C++ -*-===// +//===-- HostInfoLinux.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/linux/LibcGlue.cpp b/gnu/llvm/lldb/source/Host/linux/LibcGlue.cpp index 0acc2064c82..fe61ac79cea 100644 --- a/gnu/llvm/lldb/source/Host/linux/LibcGlue.cpp +++ b/gnu/llvm/lldb/source/Host/linux/LibcGlue.cpp @@ -1,4 +1,4 @@ -//===-- LibcGlue.cpp --------------------------------------------*- C++ -*-===// +//===-- LibcGlue.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/linux/Support.cpp b/gnu/llvm/lldb/source/Host/linux/Support.cpp index b9deb21b55e..c71824c5c5e 100644 --- a/gnu/llvm/lldb/source/Host/linux/Support.cpp +++ b/gnu/llvm/lldb/source/Host/linux/Support.cpp @@ -1,4 +1,4 @@ -//===-- Support.cpp ---------------------------------------------*- C++ -*-===// +//===-- Support.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCBundle.cpp b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCBundle.cpp index 0ca2c00798f..1c268fa112d 100644 --- a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCBundle.cpp +++ b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCBundle.cpp @@ -1,4 +1,4 @@ -//===-- CFCBundle.cpp -------------------------------------------*- C++ -*-===// +//===-- CFCBundle.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCBundle.h b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCBundle.h index 014552ab18f..8c56a5f37fc 100644 --- a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCBundle.h +++ b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCBundle.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef CoreFoundationCPP_CFBundle_h_ -#define CoreFoundationCPP_CFBundle_h_ +#ifndef LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCBUNDLE_H +#define LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCBUNDLE_H #include "CFCReleaser.h" @@ -36,4 +36,4 @@ private: const CFCBundle &operator=(const CFCBundle &) = delete; }; -#endif // #ifndef CoreFoundationCPP_CFBundle_h_ +#endif // LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCBUNDLE_H diff --git a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCData.cpp b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCData.cpp index 191f4734c64..bfa213b860e 100644 --- a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCData.cpp +++ b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCData.cpp @@ -1,4 +1,4 @@ -//===-- CFCData.cpp ---------------------------------------------*- C++ -*-===// +//===-- CFCData.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCData.h b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCData.h index 33fcf53ed0b..ce8bfa2862f 100644 --- a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCData.h +++ b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCData.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef CoreFoundationCPP_CFData_h_ -#define CoreFoundationCPP_CFData_h_ +#ifndef LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCDATA_H +#define LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCDATA_H #include "CFCReleaser.h" @@ -27,4 +27,4 @@ protected: // Classes that inherit from CFCData can see and modify these }; -#endif // #ifndef CoreFoundationCPP_CFData_h_ +#endif // LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCDATA_H diff --git a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableArray.cpp b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableArray.cpp index a2172c296f6..64e90bdcce6 100644 --- a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableArray.cpp +++ b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableArray.cpp @@ -1,4 +1,4 @@ -//===-- CFCMutableArray.cpp -------------------------------------*- C++ -*-===// +//===-- CFCMutableArray.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableArray.h b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableArray.h index 46c5b912627..a951a3d43f7 100644 --- a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableArray.h +++ b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableArray.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef CoreFoundationCPP_CFMutableArray_h_ -#define CoreFoundationCPP_CFMutableArray_h_ +#ifndef LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCMUTABLEARRAY_H +#define LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCMUTABLEARRAY_H #include "CFCReleaser.h" @@ -40,4 +40,4 @@ public: bool can_create = true); }; -#endif // #ifndef CoreFoundationCPP_CFMutableArray_h_ +#endif // LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCMUTABLEARRAY_H diff --git a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp index 66d572d2cfc..37391ccb970 100644 --- a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp +++ b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp @@ -1,4 +1,4 @@ -//===-- CFCMutableDictionary.cpp --------------------------------*- C++ -*-===// +//===-- CFCMutableDictionary.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableDictionary.h b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableDictionary.h index e9b494a5854..4a422d765d4 100644 --- a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableDictionary.h +++ b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableDictionary.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef CoreFoundationCPP_CFMutableDictionary_h_ -#define CoreFoundationCPP_CFMutableDictionary_h_ +#ifndef LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCMUTABLEDICTIONARY_H +#define LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCMUTABLEDICTIONARY_H #include "CFCReleaser.h" @@ -63,4 +63,4 @@ private: // For CFCMutableDictionary only }; -#endif // CoreFoundationCPP_CFMutableDictionary_h_ +#endif // LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCMUTABLEDICTIONARY_H diff --git a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableSet.cpp b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableSet.cpp index a6517fafb00..0852c8cfdff 100644 --- a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableSet.cpp +++ b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableSet.cpp @@ -1,4 +1,4 @@ -//===-- CFCMutableSet.cpp ---------------------------------------*- C++ -*-===// +//===-- CFCMutableSet.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableSet.h b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableSet.h index a55d646be6e..49acfd4b115 100644 --- a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableSet.h +++ b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCMutableSet.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef CoreFoundationCPP_CFMutableSet_h_ -#define CoreFoundationCPP_CFMutableSet_h_ +#ifndef LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCMUTABLESET_H +#define LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCMUTABLESET_H #include "CFCReleaser.h" @@ -35,4 +35,4 @@ private: // For CFCMutableSet only }; -#endif // CoreFoundationCPP_CFMutableSet_h_ +#endif // LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCMUTABLESET_H diff --git a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCReleaser.h b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCReleaser.h index 8a29f398021..23e6073cb80 100644 --- a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCReleaser.h +++ b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCReleaser.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef CoreFoundationCPP_CFReleaser_h_ -#define CoreFoundationCPP_CFReleaser_h_ +#ifndef LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCRELEASER_H +#define LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCRELEASER_H #include @@ -106,4 +106,4 @@ private: }; #endif // #ifdef __cplusplus -#endif // #ifndef CoreFoundationCPP_CFReleaser_h_ +#endif // LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCRELEASER_H diff --git a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCString.cpp b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCString.cpp index fbd33fc7224..ae018cf5ae3 100644 --- a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCString.cpp +++ b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCString.cpp @@ -1,4 +1,4 @@ -//===-- CFCString.cpp -------------------------------------------*- C++ -*-===// +//===-- CFCString.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCString.h b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCString.h index 300b1c4a413..b5ed79ed3bd 100644 --- a/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCString.h +++ b/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCString.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef CoreFoundationCPP_CFString_h_ -#define CoreFoundationCPP_CFString_h_ +#ifndef LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCSTRING_H +#define LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCSTRING_H #include @@ -35,4 +35,4 @@ public: std::string &expanded_path); }; -#endif // #ifndef CoreFoundationCPP_CFString_h_ +#endif // LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCSTRING_H diff --git a/gnu/llvm/lldb/source/Host/macosx/objcxx/Host.mm b/gnu/llvm/lldb/source/Host/macosx/objcxx/Host.mm index 9febb8fb8b2..1635132a154 100644 --- a/gnu/llvm/lldb/source/Host/macosx/objcxx/Host.mm +++ b/gnu/llvm/lldb/source/Host/macosx/objcxx/Host.mm @@ -9,13 +9,9 @@ #include "lldb/Host/Host.h" #include +#include -// On device doesn't have supporty for XPC. -#if defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__)) -#define NO_XPC_SERVICES 1 -#endif - -#if !defined(NO_XPC_SERVICES) +#if TARGET_OS_OSX #define __XPC_PRIVATE_H__ #include @@ -135,6 +131,8 @@ bool Host::ResolveExecutableInBundle(FileSpec &file) { return false; } +#if TARGET_OS_OSX + static void *AcceptPIDFromInferior(void *arg) { const char *connect_url = (const char *)arg; ConnectionFileDescriptor file_conn; @@ -153,35 +151,6 @@ static void *AcceptPIDFromInferior(void *arg) { return NULL; } -static bool WaitForProcessToSIGSTOP(const lldb::pid_t pid, - const int timeout_in_seconds) { - const int time_delta_usecs = 100000; - const int num_retries = timeout_in_seconds / time_delta_usecs; - for (int i = 0; i < num_retries; i++) { - struct proc_bsdinfo bsd_info; - int error = ::proc_pidinfo(pid, PROC_PIDTBSDINFO, (uint64_t)0, &bsd_info, - PROC_PIDTBSDINFO_SIZE); - - switch (error) { - case EINVAL: - case ENOTSUP: - case ESRCH: - case EPERM: - return false; - - default: - break; - - case 0: - if (bsd_info.pbi_status == SSTOP) - return true; - } - ::usleep(time_delta_usecs); - } - return false; -} -#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) - const char *applscript_in_new_tty = "tell application \"Terminal\"\n" " activate\n" " do script \"/bin/bash -c '%s';exit\"\n" @@ -325,11 +294,6 @@ LaunchInNewTerminalWithAppleScript(const char *exe_path, lldb_error = accept_thread->Join(&accept_thread_result); if (lldb_error.Success() && accept_thread_result) { pid = (intptr_t)accept_thread_result; - - // Wait for process to be stopped at the entry point by watching - // for the process status to be set to SSTOP which indicates it it - // SIGSTOP'ed at the entry point - WaitForProcessToSIGSTOP(pid, 5); } llvm::sys::fs::remove(unix_socket_name); @@ -339,13 +303,13 @@ LaunchInNewTerminalWithAppleScript(const char *exe_path, return error; } -#endif // #if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) +#endif // TARGET_OS_OSX bool Host::OpenFileInExternalEditor(const FileSpec &file_spec, uint32_t line_no) { -#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) +#if !TARGET_OS_OSX return false; -#else +#else // !TARGET_OS_OSX // We attach this to an 'odoc' event to specify a particular selection typedef struct { int16_t reserved0; // must be zero @@ -436,7 +400,7 @@ bool Host::OpenFileInExternalEditor(const FileSpec &file_spec, } return true; -#endif // #if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) +#endif // TARGET_OS_OSX } Environment Host::GetEnvironment() { return Environment(*_NSGetEnviron()); } @@ -623,8 +587,8 @@ static bool GetMacOSXProcessUserAndGroup(ProcessInstanceInfo &process_info) { return false; } -uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, - ProcessInstanceInfoList &process_infos) { +uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info, + ProcessInstanceInfoList &process_infos) { std::vector kinfos; int mib[3] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL}; @@ -667,8 +631,7 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, kinfo.kp_proc.p_pid == 0 || // Skip kernel (kernel pid is zero) kinfo.kp_proc.p_stat == SZOMB || // Zombies are bad, they like brains... kinfo.kp_proc.p_flag & P_TRACED || // Being debugged? - kinfo.kp_proc.p_flag & P_WEXIT || // Working on exiting? - kinfo.kp_proc.p_flag & P_TRANSLATED) // Skip translated ppc (Rosetta) + kinfo.kp_proc.p_flag & P_WEXIT) continue; ProcessInstanceInfo process_info; @@ -692,11 +655,11 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, if (GetMacOSXProcessCPUType(process_info)) { if (GetMacOSXProcessArgs(&match_info, process_info)) { if (match_info.Matches(process_info)) - process_infos.Append(process_info); + process_infos.push_back(process_info); } } } - return process_infos.GetSize(); + return process_infos.size(); } bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) { @@ -721,7 +684,7 @@ bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) { return false; } -#if !NO_XPC_SERVICES +#if TARGET_OS_OSX static void PackageXPCArguments(xpc_object_t message, const char *prefix, const Args &args) { size_t count = args.GetArgumentCount(); @@ -873,7 +836,7 @@ static short GetPosixspawnFlags(const ProcessLaunchInfo &launch_info) { static Status LaunchProcessXPC(const char *exe_path, ProcessLaunchInfo &launch_info, lldb::pid_t &pid) { -#if !NO_XPC_SERVICES +#if TARGET_OS_OSX Status error = getXPCAuthorization(launch_info); if (error.Fail()) return error; @@ -1120,43 +1083,6 @@ static Status LaunchProcessPosixSpawn(const char *exe_path, return error; } -// posix_spawnattr_setbinpref_np appears to be an Apple extension per: -// http://www.unix.com/man-page/OSX/3/posix_spawnattr_setbinpref_np/ -#if !defined(__arm__) - - // Don't set the binpref if a shell was provided. After all, that's only - // going to affect what version of the shell - // is launched, not what fork of the binary is launched. We insert "arch - // --arch as part of the shell invocation - // to do that job on OSX. - - if (launch_info.GetShell() == FileSpec()) { - // We don't need to do this for ARM, and we really shouldn't now that we - // have multiple CPU subtypes and no posix_spawnattr call that allows us - // to set which CPU subtype to launch... - const ArchSpec &arch_spec = launch_info.GetArchitecture(); - cpu_type_t cpu = arch_spec.GetMachOCPUType(); - cpu_type_t sub = arch_spec.GetMachOCPUSubType(); - if (cpu != 0 && cpu != static_cast(UINT32_MAX) && - cpu != static_cast(LLDB_INVALID_CPUTYPE) && - !(cpu == 0x01000007 && sub == 8)) // If haswell is specified, don't try - // to set the CPU type or we will fail - { - size_t ocount = 0; - error.SetError(::posix_spawnattr_setbinpref_np(&attr, 1, &cpu, &ocount), - eErrorTypePOSIX); - if (error.Fail()) - LLDB_LOG(log, - "error: {0}, ::posix_spawnattr_setbinpref_np ( &attr, 1, " - "cpu_type = {1:x}, count => {2} )", - error, cpu, ocount); - - if (error.Fail() || ocount != 1) - return error; - } - } -#endif // !defined(__arm__) - const char *tmp_argv[2]; char *const *argv = const_cast( launch_info.GetArguments().GetConstArgumentVector()); @@ -1263,7 +1189,7 @@ static Status LaunchProcessPosixSpawn(const char *exe_path, static bool ShouldLaunchUsingXPC(ProcessLaunchInfo &launch_info) { bool result = false; -#if !NO_XPC_SERVICES +#if TARGET_OS_OSX bool launchingAsRoot = launch_info.GetUserID() == 0; bool currentUserIsRoot = HostInfo::GetEffectiveUserID() == 0; @@ -1295,7 +1221,7 @@ Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) { } if (launch_info.GetFlags().Test(eLaunchFlagLaunchInTTY)) { -#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) +#if TARGET_OS_OSX return LaunchInNewTerminalWithAppleScript(exe_spec.GetPath().c_str(), launch_info); #else diff --git a/gnu/llvm/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/gnu/llvm/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm index e73d2ffe9b9..60eacb1e49b 100644 --- a/gnu/llvm/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm +++ b/gnu/llvm/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm @@ -8,6 +8,7 @@ #include "lldb/Host/macosx/HostInfoMacOSX.h" #include "lldb/Host/FileSystem.h" +#include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/Log.h" @@ -135,7 +136,7 @@ bool HostInfoMacOSX::ComputeSupportExeDirectory(FileSpec &file_spec) { size_t framework_pos = raw_path.find("LLDB.framework"); if (framework_pos != std::string::npos) { framework_pos += strlen("LLDB.framework"); -#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) +#if TARGET_OS_EMBEDDED // Shallow bundle raw_path.resize(framework_pos); #else @@ -275,6 +276,9 @@ void HostInfoMacOSX::ComputeHostArchitectureSupport(ArchSpec &arch_32, #elif defined(TARGET_OS_WATCHOS) && TARGET_OS_WATCHOS == 1 arch_32.GetTriple().setOS(llvm::Triple::WatchOS); arch_64.GetTriple().setOS(llvm::Triple::WatchOS); +#elif defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1 + arch_32.GetTriple().setOS(llvm::Triple::MacOSX); + arch_64.GetTriple().setOS(llvm::Triple::MacOSX); #else arch_32.GetTriple().setOS(llvm::Triple::IOS); arch_64.GetTriple().setOS(llvm::Triple::IOS); @@ -295,3 +299,161 @@ void HostInfoMacOSX::ComputeHostArchitectureSupport(ArchSpec &arch_32, } } } + +/// Return and cache $DEVELOPER_DIR if it is set and exists. +static std::string GetEnvDeveloperDir() { + static std::string g_env_developer_dir; + static std::once_flag g_once_flag; + std::call_once(g_once_flag, [&]() { + if (const char *developer_dir_env_var = getenv("DEVELOPER_DIR")) { + FileSpec fspec(developer_dir_env_var); + if (FileSystem::Instance().Exists(fspec)) + g_env_developer_dir = fspec.GetPath(); + }}); + return g_env_developer_dir; +} + +FileSpec HostInfoMacOSX::GetXcodeContentsDirectory() { + static FileSpec g_xcode_contents_path; + static std::once_flag g_once_flag; + std::call_once(g_once_flag, [&]() { + // Try the shlib dir first. + if (FileSpec fspec = HostInfo::GetShlibDir()) { + if (FileSystem::Instance().Exists(fspec)) { + std::string xcode_contents_dir = + XcodeSDK::FindXcodeContentsDirectoryInPath(fspec.GetPath()); + if (!xcode_contents_dir.empty()) { + g_xcode_contents_path = FileSpec(xcode_contents_dir); + return; + } + } + } + + llvm::SmallString<128> env_developer_dir(GetEnvDeveloperDir()); + if (!env_developer_dir.empty()) { + llvm::sys::path::append(env_developer_dir, "Contents"); + std::string xcode_contents_dir = + XcodeSDK::FindXcodeContentsDirectoryInPath(env_developer_dir); + if (!xcode_contents_dir.empty()) { + g_xcode_contents_path = FileSpec(xcode_contents_dir); + return; + } + } + + FileSpec fspec(HostInfo::GetXcodeSDKPath(XcodeSDK::GetAnyMacOS())); + if (fspec) { + if (FileSystem::Instance().Exists(fspec)) { + std::string xcode_contents_dir = + XcodeSDK::FindXcodeContentsDirectoryInPath(fspec.GetPath()); + if (!xcode_contents_dir.empty()) { + g_xcode_contents_path = FileSpec(xcode_contents_dir); + return; + } + } + } + }); + return g_xcode_contents_path; +} + +lldb_private::FileSpec HostInfoMacOSX::GetXcodeDeveloperDirectory() { + static lldb_private::FileSpec g_developer_directory; + static llvm::once_flag g_once_flag; + llvm::call_once(g_once_flag, []() { + if (FileSpec fspec = GetXcodeContentsDirectory()) { + fspec.AppendPathComponent("Developer"); + if (FileSystem::Instance().Exists(fspec)) + g_developer_directory = fspec; + } + }); + return g_developer_directory; +} + +static std::string GetXcodeSDK(XcodeSDK sdk) { + XcodeSDK::Info info = sdk.Parse(); + std::string sdk_name = XcodeSDK::GetCanonicalName(info); + auto find_sdk = [](std::string sdk_name) -> std::string { + std::string xcrun_cmd; + std::string developer_dir = GetEnvDeveloperDir(); + if (developer_dir.empty()) + if (FileSpec fspec = HostInfo::GetShlibDir()) + if (FileSystem::Instance().Exists(fspec)) { + FileSpec path( + XcodeSDK::FindXcodeContentsDirectoryInPath(fspec.GetPath())); + if (path.RemoveLastPathComponent()) + developer_dir = path.GetPath(); + } + if (!developer_dir.empty()) + xcrun_cmd = "/usr/bin/env DEVELOPER_DIR=\"" + developer_dir + "\" "; + xcrun_cmd += "xcrun --show-sdk-path --sdk " + sdk_name; + + int status = 0; + int signo = 0; + std::string output_str; + lldb_private::Status error = + Host::RunShellCommand(xcrun_cmd.c_str(), FileSpec(), &status, &signo, + &output_str, std::chrono::seconds(15)); + + // Check that xcrun return something useful. + if (status != 0 || output_str.empty()) + return {}; + + // Convert to a StringRef so we can manipulate the string without modifying + // the underlying data. + llvm::StringRef output(output_str); + + // Remove any trailing newline characters. + output = output.rtrim(); + + // Strip any leading newline characters and everything before them. + const size_t last_newline = output.rfind('\n'); + if (last_newline != llvm::StringRef::npos) + output = output.substr(last_newline + 1); + + return output.str(); + }; + + std::string path = find_sdk(sdk_name); + while (path.empty()) { + // Try an alternate spelling of the name ("macosx10.9internal"). + if (info.type == XcodeSDK::Type::MacOSX && !info.version.empty() && + info.internal) { + llvm::StringRef fixed(sdk_name); + if (fixed.consume_back(".internal")) + sdk_name = fixed.str() + "internal"; + path = find_sdk(sdk_name); + if (!path.empty()) + break; + } + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + LLDB_LOGF(log, "Couldn't find SDK %s on host", sdk_name.c_str()); + + // Try without the version. + if (!info.version.empty()) { + info.version = {}; + sdk_name = XcodeSDK::GetCanonicalName(info); + path = find_sdk(sdk_name); + if (!path.empty()) + break; + } + + LLDB_LOGF(log, "Couldn't find any matching SDK on host"); + return {}; + } + + // Whatever is left in output should be a valid path. + if (!FileSystem::Instance().Exists(path)) + return {}; + return path; +} + +llvm::StringRef HostInfoMacOSX::GetXcodeSDKPath(XcodeSDK sdk) { + static llvm::StringMap g_sdk_path; + static std::mutex g_sdk_path_mutex; + + std::lock_guard guard(g_sdk_path_mutex); + auto it = g_sdk_path.find(sdk.GetString()); + if (it != g_sdk_path.end()) + return it->second; + auto it_new = g_sdk_path.insert({sdk.GetString(), GetXcodeSDK(sdk)}); + return it_new.first->second; +} diff --git a/gnu/llvm/lldb/source/Host/macosx/objcxx/HostThreadMacOSX.mm b/gnu/llvm/lldb/source/Host/macosx/objcxx/HostThreadMacOSX.mm index d9f32ca498f..5c60caa33e6 100644 --- a/gnu/llvm/lldb/source/Host/macosx/objcxx/HostThreadMacOSX.mm +++ b/gnu/llvm/lldb/source/Host/macosx/objcxx/HostThreadMacOSX.mm @@ -44,7 +44,8 @@ protected: NSAutoreleasePool *m_pool; private: - DISALLOW_COPY_AND_ASSIGN(MacOSXDarwinThread); + MacOSXDarwinThread(const MacOSXDarwinThread &) = delete; + const MacOSXDarwinThread &operator=(const MacOSXDarwinThread &) = delete; }; void InitThreadCreated() { diff --git a/gnu/llvm/lldb/source/Host/netbsd/HostInfoNetBSD.cpp b/gnu/llvm/lldb/source/Host/netbsd/HostInfoNetBSD.cpp index 99d41392232..cc01ec35a5b 100644 --- a/gnu/llvm/lldb/source/Host/netbsd/HostInfoNetBSD.cpp +++ b/gnu/llvm/lldb/source/Host/netbsd/HostInfoNetBSD.cpp @@ -1,4 +1,4 @@ -//===-- HostInfoNetBSD.cpp -------------------------------------*- C++ -*-===// +//===-- HostInfoNetBSD.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/netbsd/HostNetBSD.cpp b/gnu/llvm/lldb/source/Host/netbsd/HostNetBSD.cpp new file mode 100644 index 00000000000..4708fb45dee --- /dev/null +++ b/gnu/llvm/lldb/source/Host/netbsd/HostNetBSD.cpp @@ -0,0 +1,268 @@ +//===-- source/Host/netbsd/HostNetBSD.cpp ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/NameMatches.h" +#include "lldb/Utility/ProcessInfo.h" +#include "lldb/Utility/Status.h" +#include "lldb/Utility/StreamString.h" + +#include "llvm/Object/ELF.h" +#include "llvm/Support/Host.h" + +extern "C" { +extern char **environ; +} + +using namespace lldb; +using namespace lldb_private; + +namespace lldb_private { +class ProcessLaunchInfo; +} + +Environment Host::GetEnvironment() { return Environment(environ); } + +static bool GetNetBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr, + ProcessInstanceInfo &process_info) { + if (!process_info.ProcessIDIsValid()) + return false; + + int pid = process_info.GetProcessID(); + + int mib[4] = {CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_ARGV}; + + char arg_data[8192]; + size_t arg_data_size = sizeof(arg_data); + if (::sysctl(mib, 4, arg_data, &arg_data_size, NULL, 0) != 0) + return false; + + DataExtractor data(arg_data, arg_data_size, endian::InlHostByteOrder(), + sizeof(void *)); + lldb::offset_t offset = 0; + const char *cstr; + + cstr = data.GetCStr(&offset); + if (!cstr) + return false; + + process_info.GetExecutableFile().SetFile(cstr, + FileSpec::Style::native); + + if (!(match_info_ptr == NULL || + NameMatches(process_info.GetExecutableFile().GetFilename().GetCString(), + match_info_ptr->GetNameMatchType(), + match_info_ptr->GetProcessInfo().GetName()))) + return false; + + process_info.SetArg0(cstr); + Args &proc_args = process_info.GetArguments(); + while (1) { + const uint8_t *p = data.PeekData(offset, 1); + while ((p != NULL) && (*p == '\0') && offset < arg_data_size) { + ++offset; + p = data.PeekData(offset, 1); + } + if (p == NULL || offset >= arg_data_size) + break; + + cstr = data.GetCStr(&offset); + if (!cstr) + break; + + proc_args.AppendArgument(llvm::StringRef(cstr)); + } + + return true; +} + +static bool GetNetBSDProcessCPUType(ProcessInstanceInfo &process_info) { + Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + + if (process_info.ProcessIDIsValid()) { + auto buffer_sp = FileSystem::Instance().CreateDataBuffer( + process_info.GetExecutableFile(), 0x20, 0); + if (buffer_sp) { + uint8_t exe_class = + llvm::object::getElfArchType( + {buffer_sp->GetChars(), size_t(buffer_sp->GetByteSize())}) + .first; + + switch (exe_class) { + case llvm::ELF::ELFCLASS32: + process_info.GetArchitecture() = + HostInfo::GetArchitecture(HostInfo::eArchKind32); + return true; + case llvm::ELF::ELFCLASS64: + process_info.GetArchitecture() = + HostInfo::GetArchitecture(HostInfo::eArchKind64); + return true; + default: + LLDB_LOG(log, "Unknown elf class ({0}) in file {1}", exe_class, + process_info.GetExecutableFile()); + } + } + } + process_info.GetArchitecture().Clear(); + return false; +} + +static bool GetNetBSDProcessUserAndGroup(ProcessInstanceInfo &process_info) { + ::kvm_t *kdp; + char errbuf[_POSIX2_LINE_MAX]; /* XXX: error string unused */ + + struct ::kinfo_proc2 *proc_kinfo; + const int pid = process_info.GetProcessID(); + int nproc; + + if (!process_info.ProcessIDIsValid()) + goto error; + + if ((kdp = ::kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf)) == NULL) + goto error; + + if ((proc_kinfo = ::kvm_getproc2(kdp, KERN_PROC_PID, pid, + sizeof(struct ::kinfo_proc2), &nproc)) == + NULL) { + ::kvm_close(kdp); + goto error; + } + + if (nproc < 1) { + ::kvm_close(kdp); /* XXX: we don't check for error here */ + goto error; + } + + process_info.SetParentProcessID(proc_kinfo->p_ppid); + process_info.SetUserID(proc_kinfo->p_ruid); + process_info.SetGroupID(proc_kinfo->p_rgid); + process_info.SetEffectiveUserID(proc_kinfo->p_uid); + process_info.SetEffectiveGroupID(proc_kinfo->p_gid); + + ::kvm_close(kdp); /* XXX: we don't check for error here */ + + return true; + +error: + process_info.SetParentProcessID(LLDB_INVALID_PROCESS_ID); + process_info.SetUserID(UINT32_MAX); + process_info.SetGroupID(UINT32_MAX); + process_info.SetEffectiveUserID(UINT32_MAX); + process_info.SetEffectiveGroupID(UINT32_MAX); + return false; +} + +uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info, + ProcessInstanceInfoList &process_infos) { + const ::pid_t our_pid = ::getpid(); + const ::uid_t our_uid = ::getuid(); + + const bool all_users = + match_info.GetMatchAllUsers() || + // Special case, if lldb is being run as root we can attach to anything + (our_uid == 0); + + kvm_t *kdp; + char errbuf[_POSIX2_LINE_MAX]; /* XXX: error string unused */ + if ((kdp = ::kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf)) == NULL) + return 0; + + struct ::kinfo_proc2 *proc_kinfo; + int nproc; + if ((proc_kinfo = ::kvm_getproc2(kdp, KERN_PROC_ALL, 0, + sizeof(struct ::kinfo_proc2), &nproc)) == + NULL) { + ::kvm_close(kdp); + return 0; + } + + for (int i = 0; i < nproc; i++) { + if (proc_kinfo[i].p_pid < 1) + continue; /* not valid */ + /* Make sure the user is acceptable */ + if (!all_users && proc_kinfo[i].p_ruid != our_uid) + continue; + + if (proc_kinfo[i].p_pid == our_pid || // Skip this process + proc_kinfo[i].p_pid == 0 || // Skip kernel (kernel pid is 0) + proc_kinfo[i].p_stat == LSZOMB || // Zombies are bad + proc_kinfo[i].p_flag & P_TRACED || // Being debugged? + proc_kinfo[i].p_flag & P_WEXIT) // Working on exiting + continue; + + // Every thread is a process in NetBSD, but all the threads of a single + // process have the same pid. Do not store the process info in the result + // list if a process with given identifier is already registered there. + if (proc_kinfo[i].p_nlwps > 1) { + bool already_registered = false; + for (size_t pi = 0; pi < process_infos.size(); pi++) { + if (process_infos[pi].GetProcessID() == proc_kinfo[i].p_pid) { + already_registered = true; + break; + } + } + + if (already_registered) + continue; + } + ProcessInstanceInfo process_info; + process_info.SetProcessID(proc_kinfo[i].p_pid); + process_info.SetParentProcessID(proc_kinfo[i].p_ppid); + process_info.SetUserID(proc_kinfo[i].p_ruid); + process_info.SetGroupID(proc_kinfo[i].p_rgid); + process_info.SetEffectiveUserID(proc_kinfo[i].p_uid); + process_info.SetEffectiveGroupID(proc_kinfo[i].p_gid); + // Make sure our info matches before we go fetch the name and cpu type + if (match_info.Matches(process_info) && + GetNetBSDProcessArgs(&match_info, process_info)) { + GetNetBSDProcessCPUType(process_info); + if (match_info.Matches(process_info)) + process_infos.push_back(process_info); + } + } + + kvm_close(kdp); /* XXX: we don't check for error here */ + + return process_infos.size(); +} + +bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) { + process_info.SetProcessID(pid); + + if (GetNetBSDProcessArgs(NULL, process_info)) { + GetNetBSDProcessCPUType(process_info); + GetNetBSDProcessUserAndGroup(process_info); + return true; + } + + process_info.Clear(); + return false; +} + +Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) { + return Status("unimplemented"); +} diff --git a/gnu/llvm/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp b/gnu/llvm/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp index aeddb724ede..58836333b63 100644 --- a/gnu/llvm/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp +++ b/gnu/llvm/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp @@ -1,4 +1,4 @@ -//===-- HostInfoOpenBSD.cpp -------------------------------------*- C++ -*-===// +//===-- HostInfoOpenBSD.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,11 +7,9 @@ //===----------------------------------------------------------------------===// #include "lldb/Host/openbsd/HostInfoOpenBSD.h" -#include "lldb/Host/FileSystem.h" #include #include -#include #include #include #include @@ -21,18 +19,13 @@ using namespace lldb_private; llvm::VersionTuple HostInfoOpenBSD::GetOSVersion() { struct utsname un; - ::memset(&un, 0, sizeof(un)); - if (::uname(&un) < 0) + ::memset(&un, 0, sizeof(utsname)); + if (uname(&un) < 0) return llvm::VersionTuple(); - uint32_t major, minor; - int status = ::sscanf(un.release, "%" PRIu32 ".%" PRIu32, &major, &minor); - switch (status) { - case 1: - return llvm::VersionTuple(major); - case 2: + unsigned major, minor; + if (2 == sscanf(un.release, "%u.%u", &major, &minor)) return llvm::VersionTuple(major, minor); - } return llvm::VersionTuple(); } @@ -70,12 +63,3 @@ FileSpec HostInfoOpenBSD::GetProgramFileSpec() { static FileSpec g_program_filespec; return g_program_filespec; } - -bool HostInfoOpenBSD::ComputeSupportExeDirectory(FileSpec &file_spec) { - if (HostInfoPosix::ComputeSupportExeDirectory(file_spec) && - file_spec.IsAbsolute() && FileSystem::Instance().Exists(file_spec)) - return true; - - file_spec.GetDirectory().SetCString("/usr/bin"); - return true; -} diff --git a/gnu/llvm/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/gnu/llvm/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp index 2223e1625b1..3a547ce128d 100644 --- a/gnu/llvm/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp +++ b/gnu/llvm/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp @@ -1,4 +1,4 @@ -//===-- ConnectionFileDescriptorPosix.cpp -----------------------*- C++ -*-===// +//===-- ConnectionFileDescriptorPosix.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -42,6 +42,7 @@ #include "lldb/Host/Host.h" #include "lldb/Host/Socket.h" #include "lldb/Host/common/TCPSocket.h" +#include "lldb/Host/common/UDPSocket.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" @@ -208,7 +209,7 @@ ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path, // this. For now, we assume we must assume we don't own it. std::unique_ptr tcp_socket; - tcp_socket.reset(new TCPSocket(fd, false, false)); + tcp_socket = std::make_unique(fd, false, false); // Try and get a socket option from this file descriptor to see if // this is a socket and set m_is_socket accordingly. int resuse; @@ -223,7 +224,7 @@ ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path, m_write_sp = std::make_shared(fd, File::eOpenOptionWrite, false); } - m_uri = *addr; + m_uri = std::string(*addr); return eConnectionStatusSuccess; } } @@ -652,7 +653,7 @@ ConnectionFileDescriptor::NamedSocketAccept(llvm::StringRef socket_name, if (error.Fail()) { return eConnectionStatusError; } - m_uri.assign(socket_name); + m_uri.assign(std::string(socket_name)); return eConnectionStatusSuccess; } @@ -669,7 +670,7 @@ ConnectionFileDescriptor::NamedSocketConnect(llvm::StringRef socket_name, if (error.Fail()) { return eConnectionStatusError; } - m_uri.assign(socket_name); + m_uri.assign(std::string(socket_name)); return eConnectionStatusSuccess; } @@ -686,66 +687,79 @@ ConnectionFileDescriptor::UnixAbstractSocketConnect(llvm::StringRef socket_name, if (error.Fail()) { return eConnectionStatusError; } - m_uri.assign(socket_name); + m_uri.assign(std::string(socket_name)); return eConnectionStatusSuccess; } ConnectionStatus ConnectionFileDescriptor::SocketListenAndAccept(llvm::StringRef s, Status *error_ptr) { + if (error_ptr) + *error_ptr = Status(); m_port_predicate.SetValue(0, eBroadcastNever); - Socket *socket = nullptr; m_waiting_for_accept = true; - Status error = Socket::TcpListen(s, m_child_processes_inherit, socket, - &m_port_predicate); - if (error_ptr) - *error_ptr = error; - if (error.Fail()) + llvm::Expected> listening_socket = + Socket::TcpListen(s, m_child_processes_inherit, &m_port_predicate); + if (!listening_socket) { + if (error_ptr) + *error_ptr = listening_socket.takeError(); + else + LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION), + listening_socket.takeError(), "tcp listen failed: {0}"); return eConnectionStatusError; + } - std::unique_ptr listening_socket_up; - listening_socket_up.reset(socket); - socket = nullptr; - error = listening_socket_up->Accept(socket); - listening_socket_up.reset(); + Socket *accepted_socket; + Status error = listening_socket.get()->Accept(accepted_socket); if (error_ptr) *error_ptr = error; if (error.Fail()) return eConnectionStatusError; - InitializeSocket(socket); + InitializeSocket(accepted_socket); return eConnectionStatusSuccess; } ConnectionStatus ConnectionFileDescriptor::ConnectTCP(llvm::StringRef s, Status *error_ptr) { - Socket *socket = nullptr; - Status error = Socket::TcpConnect(s, m_child_processes_inherit, socket); if (error_ptr) - *error_ptr = error; - m_write_sp.reset(socket); - m_read_sp = m_write_sp; - if (error.Fail()) { + *error_ptr = Status(); + + llvm::Expected> socket = + Socket::TcpConnect(s, m_child_processes_inherit); + if (!socket) { + if (error_ptr) + *error_ptr = socket.takeError(); + else + LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION), + socket.takeError(), "tcp connect failed: {0}"); return eConnectionStatusError; } - m_uri.assign(s); + m_write_sp = std::move(*socket); + m_read_sp = m_write_sp; + m_uri.assign(std::string(s)); return eConnectionStatusSuccess; } ConnectionStatus ConnectionFileDescriptor::ConnectUDP(llvm::StringRef s, Status *error_ptr) { - Socket *socket = nullptr; - Status error = Socket::UdpConnect(s, m_child_processes_inherit, socket); if (error_ptr) - *error_ptr = error; - m_write_sp.reset(socket); - m_read_sp = m_write_sp; - if (error.Fail()) { + *error_ptr = Status(); + llvm::Expected> socket = + Socket::UdpConnect(s, m_child_processes_inherit); + if (!socket) { + if (error_ptr) + *error_ptr = socket.takeError(); + else + LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION), + socket.takeError(), "tcp connect failed: {0}"); return eConnectionStatusError; } - m_uri.assign(s); + m_write_sp = std::move(*socket); + m_read_sp = m_write_sp; + m_uri.assign(std::string(s)); return eConnectionStatusSuccess; } diff --git a/gnu/llvm/lldb/source/Host/posix/DomainSocket.cpp b/gnu/llvm/lldb/source/Host/posix/DomainSocket.cpp index 7b7d8f085e5..5a396906fdf 100644 --- a/gnu/llvm/lldb/source/Host/posix/DomainSocket.cpp +++ b/gnu/llvm/lldb/source/Host/posix/DomainSocket.cpp @@ -1,4 +1,4 @@ -//===-- DomainSocket.cpp ----------------------------------------*- C++ -*-===// +//===-- DomainSocket.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -50,7 +50,7 @@ bool SetSockAddr(llvm::StringRef name, const size_t name_offset, saddr_un_len = offsetof(struct sockaddr_un, sun_path) + name_offset + name.size(); -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) saddr_un->sun_len = saddr_un_len; #endif @@ -146,10 +146,10 @@ std::string DomainSocket::GetSocketName() const { std::string DomainSocket::GetRemoteConnectionURI() const { if (m_socket != kInvalidSocketValue) { - return llvm::formatv("{0}://{1}", - GetNameOffset() == 0 ? "unix-connect" - : "unix-abstract-connect", - GetSocketName()); + return std::string(llvm::formatv( + "{0}://{1}", + GetNameOffset() == 0 ? "unix-connect" : "unix-abstract-connect", + GetSocketName())); } return ""; } diff --git a/gnu/llvm/lldb/source/Host/posix/FileSystemPosix.cpp b/gnu/llvm/lldb/source/Host/posix/FileSystemPosix.cpp index 32fae68abb4..0aa34bc5943 100644 --- a/gnu/llvm/lldb/source/Host/posix/FileSystemPosix.cpp +++ b/gnu/llvm/lldb/source/Host/posix/FileSystemPosix.cpp @@ -1,4 +1,4 @@ -//===-- FileSystem.cpp ------------------------------------------*- C++ -*-===// +//===-- FileSystemPosix.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -43,7 +43,7 @@ Status FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) { Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) { Status error; char buf[PATH_MAX]; - ssize_t count = ::readlink(src.GetCString(), buf, sizeof(buf) - 1); + ssize_t count = ::readlink(src.GetPath().c_str(), buf, sizeof(buf) - 1); if (count < 0) error.SetErrorToErrno(); else { @@ -72,9 +72,11 @@ Status FileSystem::ResolveSymbolicLink(const FileSpec &src, FileSpec &dst) { } FILE *FileSystem::Fopen(const char *path, const char *mode) { + Collect(path); return llvm::sys::RetryAfterSignal(nullptr, ::fopen, path, mode); } int FileSystem::Open(const char *path, int flags, int mode) { + Collect(path); return llvm::sys::RetryAfterSignal(-1, ::open, path, flags, mode); } diff --git a/gnu/llvm/lldb/source/Host/posix/HostInfoPosix.cpp b/gnu/llvm/lldb/source/Host/posix/HostInfoPosix.cpp index 63cc5dc65e0..7e110f07d7c 100644 --- a/gnu/llvm/lldb/source/Host/posix/HostInfoPosix.cpp +++ b/gnu/llvm/lldb/source/Host/posix/HostInfoPosix.cpp @@ -1,4 +1,4 @@ -//===-- HostInfoPosix.cpp ---------------------------------------*- C++ -*-===// +//===-- HostInfoPosix.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/posix/HostProcessPosix.cpp b/gnu/llvm/lldb/source/Host/posix/HostProcessPosix.cpp index cc187d44246..69a049bcf7a 100644 --- a/gnu/llvm/lldb/source/Host/posix/HostProcessPosix.cpp +++ b/gnu/llvm/lldb/source/Host/posix/HostProcessPosix.cpp @@ -1,4 +1,4 @@ -//===-- HostProcessPosix.cpp ------------------------------------*- C++ -*-===// +//===-- HostProcessPosix.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/posix/HostThreadPosix.cpp b/gnu/llvm/lldb/source/Host/posix/HostThreadPosix.cpp index d78bba517f6..31c7c7f8e2f 100644 --- a/gnu/llvm/lldb/source/Host/posix/HostThreadPosix.cpp +++ b/gnu/llvm/lldb/source/Host/posix/HostThreadPosix.cpp @@ -1,4 +1,4 @@ -//===-- HostThreadPosix.cpp -------------------------------------*- C++ -*-===// +//===-- HostThreadPosix.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/posix/LockFilePosix.cpp b/gnu/llvm/lldb/source/Host/posix/LockFilePosix.cpp index a6eae95c333..d197974a72a 100644 --- a/gnu/llvm/lldb/source/Host/posix/LockFilePosix.cpp +++ b/gnu/llvm/lldb/source/Host/posix/LockFilePosix.cpp @@ -1,4 +1,4 @@ -//===-- LockFilePosix.cpp ---------------------------------------*- C++ -*-===// +//===-- LockFilePosix.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/posix/PipePosix.cpp b/gnu/llvm/lldb/source/Host/posix/PipePosix.cpp index 3558ebcdc96..780222dffbf 100644 --- a/gnu/llvm/lldb/source/Host/posix/PipePosix.cpp +++ b/gnu/llvm/lldb/source/Host/posix/PipePosix.cpp @@ -1,4 +1,4 @@ -//===-- PipePosix.cpp -------------------------------------------*- C++ -*-===// +//===-- PipePosix.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -39,7 +39,7 @@ enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE // pipe2 is supported by a limited set of platforms // TODO: Add more platforms that support pipe2. #if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD__ >= 10) || \ - defined(__NetBSD__) || defined(__OpenBSD__) + defined(__NetBSD__) #define PIPE2_SUPPORTED 1 #else #define PIPE2_SUPPORTED 0 diff --git a/gnu/llvm/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp b/gnu/llvm/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp index 185c7f0fe24..35482341d3e 100644 --- a/gnu/llvm/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp +++ b/gnu/llvm/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp @@ -1,4 +1,4 @@ -//===-- ProcessLauncherPosixFork.cpp ----------------------------*- C++ -*-===// +//===-- ProcessLauncherPosixFork.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/windows/ConnectionGenericFileWindows.cpp b/gnu/llvm/lldb/source/Host/windows/ConnectionGenericFileWindows.cpp index 174ed73e981..817663d6212 100644 --- a/gnu/llvm/lldb/source/Host/windows/ConnectionGenericFileWindows.cpp +++ b/gnu/llvm/lldb/source/Host/windows/ConnectionGenericFileWindows.cpp @@ -1,4 +1,4 @@ -//===-- ConnectionGenericFileWindows.cpp ------------------------*- C++ -*-===// +//===-- ConnectionGenericFileWindows.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -127,7 +127,7 @@ lldb::ConnectionStatus ConnectionGenericFile::Connect(llvm::StringRef path, } m_owns_file = true; - m_uri.assign(path); + m_uri = path.str(); return eConnectionStatusSuccess; } diff --git a/gnu/llvm/lldb/source/Host/windows/EditLineWin.cpp b/gnu/llvm/lldb/source/Host/windows/EditLineWin.cpp index 67a7d541726..3567b5e2418 100644 --- a/gnu/llvm/lldb/source/Host/windows/EditLineWin.cpp +++ b/gnu/llvm/lldb/source/Host/windows/EditLineWin.cpp @@ -1,4 +1,4 @@ -//===-- EditLineWin.cpp -----------------------------------------*- C++ -*-===// +//===-- EditLineWin.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/windows/FileSystem.cpp b/gnu/llvm/lldb/source/Host/windows/FileSystem.cpp index 310bf8f074f..94872c99b15 100644 --- a/gnu/llvm/lldb/source/Host/windows/FileSystem.cpp +++ b/gnu/llvm/lldb/source/Host/windows/FileSystem.cpp @@ -1,4 +1,4 @@ -//===-- FileSystem.cpp ------------------------------------------*- C++ -*-===// +//===-- FileSystem.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -86,6 +86,7 @@ Status FileSystem::ResolveSymbolicLink(const FileSpec &src, FileSpec &dst) { } FILE *FileSystem::Fopen(const char *path, const char *mode) { + Collect(path); std::wstring wpath, wmode; if (!llvm::ConvertUTF8toWide(path, wpath)) return nullptr; @@ -98,6 +99,7 @@ FILE *FileSystem::Fopen(const char *path, const char *mode) { } int FileSystem::Open(const char *path, int flags, int mode) { + Collect(path); std::wstring wpath; if (!llvm::ConvertUTF8toWide(path, wpath)) return -1; diff --git a/gnu/llvm/lldb/source/Host/windows/Host.cpp b/gnu/llvm/lldb/source/Host/windows/Host.cpp index 1282bbe8e5c..50617a8c4bb 100644 --- a/gnu/llvm/lldb/source/Host/windows/Host.cpp +++ b/gnu/llvm/lldb/source/Host/windows/Host.cpp @@ -1,4 +1,4 @@ -//===-- source/Host/windows/Host.cpp ----------------------------*- C++ -*-===// +//===-- source/Host/windows/Host.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -131,9 +131,9 @@ FileSpec Host::GetModuleFileSpecForHostAddress(const void *host_addr) { return module_filespec; } -uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, - ProcessInstanceInfoList &process_infos) { - process_infos.Clear(); +uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info, + ProcessInstanceInfoList &process_infos) { + process_infos.clear(); AutoHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)); if (!snapshot.IsValid()) @@ -156,10 +156,10 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, GetProcessExecutableAndTriple(handle, process); if (match_info.MatchAllProcesses() || match_info.Matches(process)) - process_infos.Append(process); + process_infos.push_back(process); } while (Process32NextW(snapshot.get(), &pe)); } - return process_infos.GetSize(); + return process_infos.size(); } bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) { @@ -225,7 +225,7 @@ Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) { int status; std::string output; - std::string command = expand_command.GetString(); + std::string command = expand_command.GetString().str(); Status e = RunShellCommand(command.c_str(), launch_info.GetWorkingDirectory(), &status, nullptr, &output, std::chrono::seconds(10)); diff --git a/gnu/llvm/lldb/source/Host/windows/HostInfoWindows.cpp b/gnu/llvm/lldb/source/Host/windows/HostInfoWindows.cpp index 459703ff0ed..ba170b68bbc 100644 --- a/gnu/llvm/lldb/source/Host/windows/HostInfoWindows.cpp +++ b/gnu/llvm/lldb/source/Host/windows/HostInfoWindows.cpp @@ -1,4 +1,4 @@ -//===-- HostInfoWindows.cpp -------------------------------------*- C++ -*-===// +//===-- HostInfoWindows.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/windows/HostProcessWindows.cpp b/gnu/llvm/lldb/source/Host/windows/HostProcessWindows.cpp index 90517249db7..0dc23e1a656 100644 --- a/gnu/llvm/lldb/source/Host/windows/HostProcessWindows.cpp +++ b/gnu/llvm/lldb/source/Host/windows/HostProcessWindows.cpp @@ -1,4 +1,4 @@ -//===-- HostProcessWindows.cpp ----------------------------------*- C++ -*-===// +//===-- HostProcessWindows.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/windows/HostThreadWindows.cpp b/gnu/llvm/lldb/source/Host/windows/HostThreadWindows.cpp index 3eaaee28089..b1b8ac38d7e 100644 --- a/gnu/llvm/lldb/source/Host/windows/HostThreadWindows.cpp +++ b/gnu/llvm/lldb/source/Host/windows/HostThreadWindows.cpp @@ -1,4 +1,4 @@ -//===-- HostThreadWindows.cpp -----------------------------------*- C++ -*-===// +//===-- HostThreadWindows.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/windows/LockFileWindows.cpp b/gnu/llvm/lldb/source/Host/windows/LockFileWindows.cpp index 6b82796872e..4e0675e50ae 100644 --- a/gnu/llvm/lldb/source/Host/windows/LockFileWindows.cpp +++ b/gnu/llvm/lldb/source/Host/windows/LockFileWindows.cpp @@ -1,4 +1,4 @@ -//===-- LockFileWindows.cpp -------------------------------------*- C++ -*-===// +//===-- LockFileWindows.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/windows/PipeWindows.cpp b/gnu/llvm/lldb/source/Host/windows/PipeWindows.cpp index 920e5a1029f..b63e58e53e7 100644 --- a/gnu/llvm/lldb/source/Host/windows/PipeWindows.cpp +++ b/gnu/llvm/lldb/source/Host/windows/PipeWindows.cpp @@ -1,4 +1,4 @@ -//===-- PipeWindows.cpp -----------------------------------------*- C++ -*-===// +//===-- PipeWindows.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -104,8 +104,8 @@ Status PipeWindows::CreateNew(llvm::StringRef name, if (CanRead() || CanWrite()) return Status(ERROR_ALREADY_EXISTS, eErrorTypeWin32); - std::string pipe_path = g_pipe_name_prefix; - pipe_path.append(name); + std::string pipe_path = g_pipe_name_prefix.str(); + pipe_path.append(name.str()); // Always open for overlapped i/o. We implement blocking manually in Read // and Write. @@ -182,8 +182,8 @@ Status PipeWindows::OpenNamedPipe(llvm::StringRef name, SECURITY_ATTRIBUTES attributes = {}; attributes.bInheritHandle = child_process_inherit; - std::string pipe_path = g_pipe_name_prefix; - pipe_path.append(name); + std::string pipe_path = g_pipe_name_prefix.str(); + pipe_path.append(name.str()); if (is_read) { m_read = ::CreateFileA(pipe_path.c_str(), GENERIC_READ, 0, &attributes, diff --git a/gnu/llvm/lldb/source/Host/windows/ProcessLauncherWindows.cpp b/gnu/llvm/lldb/source/Host/windows/ProcessLauncherWindows.cpp index b74308264fe..00470f558e9 100644 --- a/gnu/llvm/lldb/source/Host/windows/ProcessLauncherWindows.cpp +++ b/gnu/llvm/lldb/source/Host/windows/ProcessLauncherWindows.cpp @@ -1,4 +1,4 @@ -//===-- ProcessLauncherWindows.cpp ------------------------------*- C++ -*-===// +//===-- ProcessLauncherWindows.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -23,10 +23,9 @@ using namespace lldb_private; namespace { void CreateEnvironmentBuffer(const Environment &env, std::vector &buffer) { - if (env.size() == 0) - return; - - // Environment buffer is a null terminated list of null terminated strings + // The buffer is a list of null-terminated UTF-16 strings, followed by an + // extra L'\0' (two bytes of 0). An empty environment must have one + // empty string, followed by an extra L'\0'. for (const auto &KV : env) { std::wstring warg; if (llvm::ConvertUTF8toWide(Environment::compose(KV), warg)) { @@ -38,6 +37,9 @@ void CreateEnvironmentBuffer(const Environment &env, // One null wchar_t (to end the block) is two null bytes buffer.push_back(0); buffer.push_back(0); + // Insert extra two bytes, just in case the environment was empty. + buffer.push_back(0); + buffer.push_back(0); } bool GetFlattenedWindowsCommandString(Args args, std::string &command) { @@ -94,8 +96,7 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info, LPVOID env_block = nullptr; ::CreateEnvironmentBuffer(launch_info.GetEnvironment(), environment); - if (!environment.empty()) - env_block = environment.data(); + env_block = environment.data(); executable = launch_info.GetExecutableFile().GetPath(); GetFlattenedWindowsCommandString(launch_info.GetArguments(), commandLine); diff --git a/gnu/llvm/lldb/source/Host/windows/ProcessRunLock.cpp b/gnu/llvm/lldb/source/Host/windows/ProcessRunLock.cpp index 85df7826f16..693641e42ed 100644 --- a/gnu/llvm/lldb/source/Host/windows/ProcessRunLock.cpp +++ b/gnu/llvm/lldb/source/Host/windows/ProcessRunLock.cpp @@ -1,4 +1,4 @@ -//===-- ProcessRunLock.cpp --------------------------------------*- C++ -*-===// +//===-- ProcessRunLock.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Host/windows/Windows.cpp b/gnu/llvm/lldb/source/Host/windows/Windows.cpp index fa664f53984..32129bb6d1e 100644 --- a/gnu/llvm/lldb/source/Host/windows/Windows.cpp +++ b/gnu/llvm/lldb/source/Host/windows/Windows.cpp @@ -1,4 +1,4 @@ -//===-- Windows.cpp ---------------------------------------------*- C++ -*-===// +//===-- Windows.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Initialization/CMakeLists.txt b/gnu/llvm/lldb/source/Initialization/CMakeLists.txt index b6282e162aa..c1a167826f7 100644 --- a/gnu/llvm/lldb/source/Initialization/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Initialization/CMakeLists.txt @@ -1,4 +1,4 @@ -if ( CMAKE_SYSTEM_NAME MATCHES "Linux|Android|FreeBSD|NetBSD|OpenBSD" ) +if ( CMAKE_SYSTEM_NAME MATCHES "Linux|Android|FreeBSD|NetBSD" ) list(APPEND EXTRA_PLUGINS lldbPluginProcessPOSIX) endif() diff --git a/gnu/llvm/lldb/source/Initialization/SystemInitializer.cpp b/gnu/llvm/lldb/source/Initialization/SystemInitializer.cpp index 1e40c269446..fc460c32650 100644 --- a/gnu/llvm/lldb/source/Initialization/SystemInitializer.cpp +++ b/gnu/llvm/lldb/source/Initialization/SystemInitializer.cpp @@ -1,4 +1,4 @@ -//===-- SystemInitializer.cpp -----------------------------------*- C++ -*-===// +//===-- SystemInitializer.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Initialization/SystemInitializerCommon.cpp b/gnu/llvm/lldb/source/Initialization/SystemInitializerCommon.cpp index c26aed708f5..0cef2a48dcb 100644 --- a/gnu/llvm/lldb/source/Initialization/SystemInitializerCommon.cpp +++ b/gnu/llvm/lldb/source/Initialization/SystemInitializerCommon.cpp @@ -1,4 +1,4 @@ -//===-- SystemInitializerCommon.cpp -----------------------------*- C++ -*-===// +//===-- SystemInitializerCommon.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,7 +18,7 @@ #include "lldb/Utility/Timer.h" #include "lldb/lldb-private.h" -#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" #endif @@ -110,7 +110,7 @@ llvm::Error SystemInitializerCommon::Initialize() { process_gdb_remote::ProcessGDBRemoteLog::Initialize(); -#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) ProcessPOSIXLog::Initialize(); #endif #if defined(_WIN32) diff --git a/gnu/llvm/lldb/source/Initialization/SystemLifetimeManager.cpp b/gnu/llvm/lldb/source/Initialization/SystemLifetimeManager.cpp index 97f60489f04..00ab3198c36 100644 --- a/gnu/llvm/lldb/source/Initialization/SystemLifetimeManager.cpp +++ b/gnu/llvm/lldb/source/Initialization/SystemLifetimeManager.cpp @@ -1,4 +1,4 @@ -//===-- SystemLifetimeManager.cpp ------------------------------*- C++ -*-===// +//===-- SystemLifetimeManager.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/CommandAlias.cpp b/gnu/llvm/lldb/source/Interpreter/CommandAlias.cpp index 5209a7bcbc4..a5e03393721 100644 --- a/gnu/llvm/lldb/source/Interpreter/CommandAlias.cpp +++ b/gnu/llvm/lldb/source/Interpreter/CommandAlias.cpp @@ -1,4 +1,4 @@ -//===-- CommandAlias.cpp -----------------------------------------*- C++-*-===// +//===-- CommandAlias.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -32,7 +32,7 @@ static bool ProcessAliasOptionsArgs(lldb::CommandObjectSP &cmd_obj_sp, std::string options_string(options_args); // TODO: Find a way to propagate errors in this CommandReturnObject up the // stack. - CommandReturnObject result; + CommandReturnObject result(false); // Check to see if the command being aliased can take any command options. Options *options = cmd_obj_sp->GetOptions(); if (options) { @@ -80,7 +80,7 @@ CommandAlias::CommandAlias(CommandInterpreter &interpreter, llvm::StringRef help, llvm::StringRef syntax, uint32_t flags) : CommandObject(interpreter, name, help, syntax, flags), - m_underlying_command_sp(), m_option_string(options_args), + m_underlying_command_sp(), m_option_string(std::string(options_args)), m_option_args_sp(new OptionArgVector), m_is_dashdash_alias(eLazyBoolCalculate), m_did_set_help(false), m_did_set_help_long(false) { diff --git a/gnu/llvm/lldb/source/Interpreter/CommandHistory.cpp b/gnu/llvm/lldb/source/Interpreter/CommandHistory.cpp index 0be61f836e0..9c7919ecc41 100644 --- a/gnu/llvm/lldb/source/Interpreter/CommandHistory.cpp +++ b/gnu/llvm/lldb/source/Interpreter/CommandHistory.cpp @@ -1,4 +1,4 @@ -//===-- CommandHistory.cpp --------------------------------------*- C++ -*-===// +//===-- CommandHistory.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -87,7 +87,7 @@ void CommandHistory::AppendString(llvm::StringRef str, bool reject_if_dupe) { return; } } - m_history.push_back(str); + m_history.push_back(std::string(str)); } void CommandHistory::Clear() { diff --git a/gnu/llvm/lldb/source/Interpreter/CommandInterpreter.cpp b/gnu/llvm/lldb/source/Interpreter/CommandInterpreter.cpp index 1ee80503f56..e55b2550017 100644 --- a/gnu/llvm/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/gnu/llvm/lldb/source/Interpreter/CommandInterpreter.cpp @@ -1,4 +1,4 @@ -//===-- CommandInterpreter.cpp ----------------------------------*- C++ -*-===// +//===-- CommandInterpreter.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -116,8 +116,7 @@ CommandInterpreter::CommandInterpreter(Debugger &debugger, m_skip_lldbinit_files(false), m_skip_app_init_files(false), m_command_io_handler_sp(), m_comment_char('#'), m_batch_command_mode(false), m_truncation_warning(eNoTruncation), - m_command_source_depth(0), m_num_errors(0), m_quit_requested(false), - m_stopped_for_crash(false) { + m_command_source_depth(0), m_result() { SetEventName(eBroadcastBitThreadShouldExit, "thread-should-exit"); SetEventName(eBroadcastBitResetPrompt, "reset-prompt"); SetEventName(eBroadcastBitQuitCommandReceived, "quit"); @@ -210,7 +209,7 @@ void CommandInterpreter::Initialize() { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION); - CommandReturnObject result; + CommandReturnObject result(m_debugger.GetUseColor()); LoadCommandDictionary(); @@ -357,7 +356,7 @@ void CommandInterpreter::Initialize() { AddAlias("p", cmd_obj_sp, "--")->SetHelpLong(""); AddAlias("print", cmd_obj_sp, "--")->SetHelpLong(""); AddAlias("call", cmd_obj_sp, "--")->SetHelpLong(""); - if (auto po = AddAlias("po", cmd_obj_sp, "-O --")) { + if (auto *po = AddAlias("po", cmd_obj_sp, "-O --")) { po->SetHelp("Evaluate an expression on the current thread. Displays any " "returned value with formatting " "controlled by the type's author."); @@ -382,6 +381,16 @@ void CommandInterpreter::Initialize() { } } + cmd_obj_sp = GetCommandSPExact("platform shell", false); + if (cmd_obj_sp) { + CommandAlias *shell_alias = AddAlias("shell", cmd_obj_sp, " --host --"); + if (shell_alias) { + shell_alias->SetHelp("Run a shell command on the host."); + shell_alias->SetHelpLong(""); + shell_alias->SetSyntax("shell "); + } + } + cmd_obj_sp = GetCommandSPExact("process kill", false); if (cmd_obj_sp) { AddAlias("kill", cmd_obj_sp); @@ -500,7 +509,10 @@ void CommandInterpreter::LoadCommandDictionary() { m_command_dict["language"] = CommandObjectSP(new CommandObjectLanguage(*this)); + // clang-format off const char *break_regexes[][2] = { + {"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", + "breakpoint set --file '%1' --line %2 --column %3"}, {"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2"}, {"^/([^/]+)/$", "breakpoint set --source-pattern-regexp '%1'"}, @@ -515,6 +527,7 @@ void CommandInterpreter::LoadCommandDictionary() { "breakpoint set --name '%1' --skip-prologue=0"}, {"^[\"']?(.*[^[:space:]\"'])[\"']?[[:space:]]*$", "breakpoint set --name '%1'"}}; + // clang-format on size_t num_regexes = llvm::array_lengthof(break_regexes); @@ -523,6 +536,9 @@ void CommandInterpreter::LoadCommandDictionary() { *this, "_regexp-break", "Set a breakpoint using one of several shorthand formats.", "\n" + "_regexp-break ::\n" + " main.c:12:21 // Break at line 12 and column " + "21 of main.c\n\n" "_regexp-break :\n" " main.c:12 // Break at line 12 of " "main.c\n\n" @@ -546,7 +562,7 @@ void CommandInterpreter::LoadCommandDictionary() { "current file\n" " // containing text 'break " "here'.\n", - 2, + 3, CommandCompletions::eSymbolCompletion | CommandCompletions::eSourceFileCompletion, false)); @@ -564,7 +580,8 @@ void CommandInterpreter::LoadCommandDictionary() { if (success) { CommandObjectSP break_regex_cmd_sp(break_regex_cmd_up.release()); - m_command_dict[break_regex_cmd_sp->GetCommandName()] = break_regex_cmd_sp; + m_command_dict[std::string(break_regex_cmd_sp->GetCommandName())] = + break_regex_cmd_sp; } } @@ -573,6 +590,9 @@ void CommandInterpreter::LoadCommandDictionary() { *this, "_regexp-tbreak", "Set a one-shot breakpoint using one of several shorthand formats.", "\n" + "_regexp-break ::\n" + " main.c:12:21 // Break at line 12 and column " + "21 of main.c\n\n" "_regexp-break :\n" " main.c:12 // Break at line 12 of " "main.c\n\n" @@ -621,7 +641,7 @@ void CommandInterpreter::LoadCommandDictionary() { if (success) { CommandObjectSP tbreak_regex_cmd_sp(tbreak_regex_cmd_up.release()); - m_command_dict[tbreak_regex_cmd_sp->GetCommandName()] = + m_command_dict[std::string(tbreak_regex_cmd_sp->GetCommandName())] = tbreak_regex_cmd_sp; } } @@ -641,7 +661,7 @@ void CommandInterpreter::LoadCommandDictionary() { "process attach --name '%1'") && attach_regex_cmd_up->AddRegexCommand("^$", "process attach")) { CommandObjectSP attach_regex_cmd_sp(attach_regex_cmd_up.release()); - m_command_dict[attach_regex_cmd_sp->GetCommandName()] = + m_command_dict[std::string(attach_regex_cmd_sp->GetCommandName())] = attach_regex_cmd_sp; } } @@ -657,7 +677,8 @@ void CommandInterpreter::LoadCommandDictionary() { down_regex_cmd_up->AddRegexCommand("^([0-9]+)$", "frame select -r -%1")) { CommandObjectSP down_regex_cmd_sp(down_regex_cmd_up.release()); - m_command_dict[down_regex_cmd_sp->GetCommandName()] = down_regex_cmd_sp; + m_command_dict[std::string(down_regex_cmd_sp->GetCommandName())] = + down_regex_cmd_sp; } } @@ -671,7 +692,8 @@ void CommandInterpreter::LoadCommandDictionary() { if (up_regex_cmd_up->AddRegexCommand("^$", "frame select -r 1") && up_regex_cmd_up->AddRegexCommand("^([0-9]+)$", "frame select -r %1")) { CommandObjectSP up_regex_cmd_sp(up_regex_cmd_up.release()); - m_command_dict[up_regex_cmd_sp->GetCommandName()] = up_regex_cmd_sp; + m_command_dict[std::string(up_regex_cmd_sp->GetCommandName())] = + up_regex_cmd_sp; } } @@ -684,7 +706,7 @@ void CommandInterpreter::LoadCommandDictionary() { if (display_regex_cmd_up->AddRegexCommand( "^(.+)$", "target stop-hook add -o \"expr -- %1\"")) { CommandObjectSP display_regex_cmd_sp(display_regex_cmd_up.release()); - m_command_dict[display_regex_cmd_sp->GetCommandName()] = + m_command_dict[std::string(display_regex_cmd_sp->GetCommandName())] = display_regex_cmd_sp; } } @@ -699,7 +721,7 @@ void CommandInterpreter::LoadCommandDictionary() { if (undisplay_regex_cmd_up->AddRegexCommand("^([0-9]+)$", "target stop-hook delete %1")) { CommandObjectSP undisplay_regex_cmd_sp(undisplay_regex_cmd_up.release()); - m_command_dict[undisplay_regex_cmd_sp->GetCommandName()] = + m_command_dict[std::string(undisplay_regex_cmd_sp->GetCommandName())] = undisplay_regex_cmd_sp; } } @@ -718,7 +740,7 @@ void CommandInterpreter::LoadCommandDictionary() { "^([[:digit:]]+)$", "process connect --plugin gdb-remote connect://localhost:%1")) { CommandObjectSP command_sp(connect_gdb_remote_cmd_up.release()); - m_command_dict[command_sp->GetCommandName()] = command_sp; + m_command_dict[std::string(command_sp->GetCommandName())] = command_sp; } } @@ -736,7 +758,7 @@ void CommandInterpreter::LoadCommandDictionary() { connect_kdp_remote_cmd_up->AddRegexCommand( "^(.+)$", "process connect --plugin kdp-remote udp://%1:41139")) { CommandObjectSP command_sp(connect_kdp_remote_cmd_up.release()); - m_command_dict[command_sp->GetCommandName()] = command_sp; + m_command_dict[std::string(command_sp->GetCommandName())] = command_sp; } } @@ -761,7 +783,7 @@ void CommandInterpreter::LoadCommandDictionary() { bt_regex_cmd_up->AddRegexCommand("^all[[:space:]]*$", "thread backtrace all") && bt_regex_cmd_up->AddRegexCommand("^[[:space:]]*$", "thread backtrace")) { CommandObjectSP command_sp(bt_regex_cmd_up.release()); - m_command_dict[command_sp->GetCommandName()] = command_sp; + m_command_dict[std::string(command_sp->GetCommandName())] = command_sp; } } @@ -797,7 +819,8 @@ void CommandInterpreter::LoadCommandDictionary() { "source list --name \"%1\"") && list_regex_cmd_up->AddRegexCommand("^$", "source list")) { CommandObjectSP list_regex_cmd_sp(list_regex_cmd_up.release()); - m_command_dict[list_regex_cmd_sp->GetCommandName()] = list_regex_cmd_sp; + m_command_dict[std::string(list_regex_cmd_sp->GetCommandName())] = + list_regex_cmd_sp; } } @@ -815,7 +838,8 @@ void CommandInterpreter::LoadCommandDictionary() { env_regex_cmd_up->AddRegexCommand("^([A-Za-z_][A-Za-z_0-9]*=.*)$", "settings set target.env-vars %1")) { CommandObjectSP env_regex_cmd_sp(env_regex_cmd_up.release()); - m_command_dict[env_regex_cmd_sp->GetCommandName()] = env_regex_cmd_sp; + m_command_dict[std::string(env_regex_cmd_sp->GetCommandName())] = + env_regex_cmd_sp; } } @@ -838,7 +862,8 @@ void CommandInterpreter::LoadCommandDictionary() { jump_regex_cmd_up->AddRegexCommand("^([+\\-][0-9]+)$", "thread jump --by %1")) { CommandObjectSP jump_regex_cmd_sp(jump_regex_cmd_up.release()); - m_command_dict[jump_regex_cmd_sp->GetCommandName()] = jump_regex_cmd_sp; + m_command_dict[std::string(jump_regex_cmd_sp->GetCommandName())] = + jump_regex_cmd_sp; } } } @@ -863,7 +888,7 @@ CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, bool include_aliases, StringList *descriptions) const { CommandObjectSP command_sp; - std::string cmd = cmd_str; + std::string cmd = std::string(cmd_str); if (HasCommands()) { auto pos = m_command_dict.find(cmd); @@ -992,18 +1017,18 @@ bool CommandInterpreter::AddUserCommand(llvm::StringRef name, if (CommandExists(name)) { if (!can_replace) return false; - if (!m_command_dict[name]->IsRemovable()) + if (!m_command_dict[std::string(name)]->IsRemovable()) return false; } if (UserCommandExists(name)) { if (!can_replace) return false; - if (!m_user_dict[name]->IsRemovable()) + if (!m_user_dict[std::string(name)]->IsRemovable()) return false; } - m_user_dict[name] = cmd_sp; + m_user_dict[std::string(name)] = cmd_sp; return true; } return false; @@ -1089,14 +1114,15 @@ CommandInterpreter::GetCommandObject(llvm::StringRef cmd_str, } bool CommandInterpreter::CommandExists(llvm::StringRef cmd) const { - return m_command_dict.find(cmd) != m_command_dict.end(); + return m_command_dict.find(std::string(cmd)) != m_command_dict.end(); } bool CommandInterpreter::GetAliasFullName(llvm::StringRef cmd, std::string &full_name) const { - bool exact_match = (m_alias_dict.find(cmd) != m_alias_dict.end()); + bool exact_match = + (m_alias_dict.find(std::string(cmd)) != m_alias_dict.end()); if (exact_match) { - full_name.assign(cmd); + full_name.assign(std::string(cmd)); return exact_match; } else { StringList matches; @@ -1122,11 +1148,11 @@ bool CommandInterpreter::GetAliasFullName(llvm::StringRef cmd, } bool CommandInterpreter::AliasExists(llvm::StringRef cmd) const { - return m_alias_dict.find(cmd) != m_alias_dict.end(); + return m_alias_dict.find(std::string(cmd)) != m_alias_dict.end(); } bool CommandInterpreter::UserCommandExists(llvm::StringRef cmd) const { - return m_user_dict.find(cmd) != m_user_dict.end(); + return m_user_dict.find(std::string(cmd)) != m_user_dict.end(); } CommandAlias * @@ -1141,7 +1167,8 @@ CommandInterpreter::AddAlias(llvm::StringRef alias_name, new CommandAlias(*this, command_obj_sp, args_string, alias_name)); if (command_alias_up && command_alias_up->IsValid()) { - m_alias_dict[alias_name] = CommandObjectSP(command_alias_up.get()); + m_alias_dict[std::string(alias_name)] = + CommandObjectSP(command_alias_up.get()); return command_alias_up.release(); } @@ -1149,7 +1176,7 @@ CommandInterpreter::AddAlias(llvm::StringRef alias_name, } bool CommandInterpreter::RemoveAlias(llvm::StringRef alias_name) { - auto pos = m_alias_dict.find(alias_name); + auto pos = m_alias_dict.find(std::string(alias_name)); if (pos != m_alias_dict.end()) { m_alias_dict.erase(pos); return true; @@ -1158,7 +1185,7 @@ bool CommandInterpreter::RemoveAlias(llvm::StringRef alias_name) { } bool CommandInterpreter::RemoveCommand(llvm::StringRef cmd) { - auto pos = m_command_dict.find(cmd); + auto pos = m_command_dict.find(std::string(cmd)); if (pos != m_command_dict.end()) { if (pos->second->IsRemovable()) { // Only regular expression objects or python commands are removable @@ -1169,7 +1196,8 @@ bool CommandInterpreter::RemoveCommand(llvm::StringRef cmd) { return false; } bool CommandInterpreter::RemoveUser(llvm::StringRef alias_name) { - CommandObject::CommandMap::iterator pos = m_user_dict.find(alias_name); + CommandObject::CommandMap::iterator pos = + m_user_dict.find(std::string(alias_name)); if (pos != m_user_dict.end()) { m_user_dict.erase(pos); return true; @@ -1253,7 +1281,8 @@ CommandObject *CommandInterpreter::GetCommandObjectForCommand( end = command_string.find_first_of(k_white_space, start); if (end == std::string::npos) end = command_string.size(); - std::string cmd_word = command_string.substr(start, end - start); + std::string cmd_word = + std::string(command_string.substr(start, end - start)); if (cmd_obj == nullptr) // Since cmd_obj is NULL we are on our first time through this loop. @@ -1311,10 +1340,10 @@ static size_t FindArgumentTerminator(const std::string &s) { if (pos == std::string::npos) break; if (pos > 0) { - if (isspace(s[pos - 1])) { + if (llvm::isSpace(s[pos - 1])) { // Check if the string ends "\s--" (where \s is a space character) or // if we have "\s--\s". - if ((pos + 2 >= s_len) || isspace(s[pos + 2])) { + if ((pos + 2 >= s_len) || llvm::isSpace(s[pos + 2])) { return pos; } } @@ -1394,7 +1423,7 @@ CommandObject *CommandInterpreter::BuildAliasResult( ((CommandAlias *)alias_cmd_obj)->Desugar(); OptionArgVectorSP option_arg_vector_sp = desugared.second; alias_cmd_obj = desugared.first.get(); - std::string alias_name_str = alias_name; + std::string alias_name_str = std::string(alias_name); if ((cmd_args.GetArgumentCount() == 0) || (alias_name_str != cmd_args.GetArgumentAtIndex(0))) cmd_args.Unshift(alias_name_str); @@ -1402,7 +1431,7 @@ CommandObject *CommandInterpreter::BuildAliasResult( result_str.Printf("%s", alias_cmd_obj->GetCommandName().str().c_str()); if (!option_arg_vector_sp.get()) { - alias_result = result_str.GetString(); + alias_result = std::string(result_str.GetString()); return alias_cmd_obj; } OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); @@ -1443,7 +1472,7 @@ CommandObject *CommandInterpreter::BuildAliasResult( } } - alias_result = result_str.GetString(); + alias_result = std::string(result_str.GetString()); return alias_cmd_obj; } @@ -1527,7 +1556,7 @@ Status CommandInterpreter::PreprocessCommand(std::string &command) { 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()); + command.insert(start_backtick, std::string(value_strm.GetString())); pos = start_backtick + value_string_size; continue; } else { @@ -1591,6 +1620,11 @@ Status CommandInterpreter::PreprocessCommand(std::string &command) { "expression '%s'", expr_str.c_str()); break; + case eExpressionThreadVanished: + error.SetErrorStringWithFormat( + "expression thread vanished for the expression '%s'", + expr_str.c_str()); + break; } } } @@ -1652,8 +1686,8 @@ bool CommandInterpreter::HandleCommand(const char *command_line, search_str = search_str.drop_front(non_space); if (auto hist_str = m_command_history.FindString(search_str)) { add_to_history = false; - command_string = *hist_str; - original_command_string = *hist_str; + command_string = std::string(*hist_str); + original_command_string = std::string(*hist_str); } else { result.AppendErrorWithFormat("Could not find entry: %s in history", command_string.c_str()); @@ -1817,6 +1851,8 @@ void CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) { void CommandInterpreter::HandleCompletion(CompletionRequest &request) { + UpdateExecutionContext(nullptr); + // Don't complete comments, and if the line we are completing is just the // history repeat character, substitute the appropriate history line. llvm::StringRef first_arg = request.GetParsedLine().GetArgumentAtIndex(0); @@ -1854,7 +1890,7 @@ bool CommandInterpreter::Confirm(llvm::StringRef message, bool default_answer) { IOHandlerConfirm *confirm = new IOHandlerConfirm(m_debugger, message, default_answer); IOHandlerSP io_handler_sp(confirm); - m_debugger.RunIOHandler(io_handler_sp); + m_debugger.RunIOHandlerSync(io_handler_sp); return confirm->GetResponse(); } @@ -1862,7 +1898,7 @@ const CommandAlias * CommandInterpreter::GetAlias(llvm::StringRef alias_name) const { OptionArgVectorSP ret_val; - auto pos = m_alias_dict.find(alias_name); + auto pos = m_alias_dict.find(std::string(alias_name)); if (pos != m_alias_dict.end()) return (CommandAlias *)pos->second.get(); @@ -2228,7 +2264,7 @@ void CommandInterpreter::HandleCommands(const StringList &commands, m_debugger.GetPrompt().str().c_str(), cmd); } - CommandReturnObject tmp_result; + CommandReturnObject tmp_result(m_debugger.GetUseColor()); // If override_context is not NULL, pass no_context_switching = true for // HandleCommand() since we updated our context already. @@ -2477,7 +2513,7 @@ void CommandInterpreter::HandleCommandsFromFile( m_command_source_depth++; - debugger.RunIOHandler(io_handler_sp); + debugger.RunIOHandlerSync(io_handler_sp); if (!m_command_source_flags.empty()) m_command_source_flags.pop_back(); m_command_source_depth--; @@ -2756,7 +2792,7 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler, StartHandlingCommand(); - lldb_private::CommandReturnObject result; + lldb_private::CommandReturnObject result(m_debugger.GetUseColor()); HandleCommand(line.c_str(), eLazyBoolCalculate, result); // Now emit the command output text from the command we just executed @@ -2794,23 +2830,26 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler, break; case eReturnStatusFailed: - m_num_errors++; - if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnError)) + m_result.IncrementNumberOfErrors(); + if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnError)) { + m_result.SetResult(lldb::eCommandInterpreterResultCommandError); io_handler.SetIsDone(true); + } break; case eReturnStatusQuit: - m_quit_requested = true; + m_result.SetResult(lldb::eCommandInterpreterResultQuitRequested); io_handler.SetIsDone(true); break; } // Finally, if we're going to stop on crash, check that here: - if (!m_quit_requested && result.GetDidChangeProcessState() && + if (m_result.IsResult(lldb::eCommandInterpreterResultSuccess) && + result.GetDidChangeProcessState() && io_handler.GetFlags().Test(eHandleCommandFlagStopOnCrash) && DidProcessStopAbnormally()) { io_handler.SetIsDone(true); - m_stopped_for_crash = true; + m_result.SetResult(lldb::eCommandInterpreterResultInferiorCrash); } } @@ -2854,7 +2893,7 @@ void CommandInterpreter::GetLLDBCommandsFromIOHandler( if (io_handler_sp) { io_handler_sp->SetUserData(baton); - debugger.PushIOHandler(io_handler_sp); + debugger.RunIOHandlerAsync(io_handler_sp); } } @@ -2874,7 +2913,7 @@ void CommandInterpreter::GetPythonCommandsFromIOHandler( if (io_handler_sp) { io_handler_sp->SetUserData(baton); - debugger.PushIOHandler(io_handler_sp); + debugger.RunIOHandlerAsync(io_handler_sp); } } @@ -2928,26 +2967,27 @@ CommandInterpreter::GetIOHandler(bool force_create, return m_command_io_handler_sp; } -void CommandInterpreter::RunCommandInterpreter( - bool auto_handle_events, bool spawn_thread, +CommandInterpreterRunResult CommandInterpreter::RunCommandInterpreter( CommandInterpreterRunOptions &options) { // Always re-create the command interpreter when we run it in case any file // handles have changed. bool force_create = true; - m_debugger.PushIOHandler(GetIOHandler(force_create, &options)); - m_stopped_for_crash = false; + m_debugger.RunIOHandlerAsync(GetIOHandler(force_create, &options)); + m_result = CommandInterpreterRunResult(); - if (auto_handle_events) + if (options.GetAutoHandleEvents()) m_debugger.StartEventHandlerThread(); - if (spawn_thread) { + if (options.GetSpawnThread()) { m_debugger.StartIOHandlerThread(); } else { - m_debugger.ExecuteIOHandlers(); + m_debugger.RunIOHandlers(); - if (auto_handle_events) + if (options.GetAutoHandleEvents()) m_debugger.StopEventHandlerThread(); } + + return m_result; } CommandObject * @@ -3073,7 +3113,7 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, std::string gdb_format_option("--gdb-format="); gdb_format_option += (suffix.c_str() + 1); - std::string cmd = revised_command_line.GetString(); + std::string cmd = std::string(revised_command_line.GetString()); size_t arg_terminator_idx = FindArgumentTerminator(cmd); if (arg_terminator_idx != std::string::npos) { // Insert the gdb format option before the "--" that terminates @@ -3114,7 +3154,7 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, revised_command_line.Printf(" %s", scratch_command.c_str()); if (cmd_obj != nullptr) - command_line = revised_command_line.GetString(); + command_line = std::string(revised_command_line.GetString()); return cmd_obj; } diff --git a/gnu/llvm/lldb/source/Interpreter/CommandObject.cpp b/gnu/llvm/lldb/source/Interpreter/CommandObject.cpp index d666852ee68..538f7a1ba69 100644 --- a/gnu/llvm/lldb/source/Interpreter/CommandObject.cpp +++ b/gnu/llvm/lldb/source/Interpreter/CommandObject.cpp @@ -1,4 +1,4 @@ -//===-- CommandObject.cpp ---------------------------------------*- C++ -*-===// +//===-- CommandObject.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,6 +18,7 @@ #include "lldb/Core/Address.h" #include "lldb/Interpreter/Options.h" #include "lldb/Utility/ArchSpec.h" +#include "llvm/ADT/ScopeExit.h" // These are for the Sourcename completers. // FIXME: Make a separate file for the completers. @@ -37,14 +38,15 @@ using namespace lldb_private; // CommandObject -CommandObject::CommandObject(CommandInterpreter &interpreter, llvm::StringRef name, - llvm::StringRef help, llvm::StringRef syntax, uint32_t flags) - : m_interpreter(interpreter), m_cmd_name(name), +CommandObject::CommandObject(CommandInterpreter &interpreter, + llvm::StringRef name, llvm::StringRef help, + llvm::StringRef syntax, uint32_t flags) + : m_interpreter(interpreter), m_cmd_name(std::string(name)), m_cmd_help_short(), m_cmd_help_long(), m_cmd_syntax(), m_flags(flags), m_arguments(), m_deprecated_command_override_callback(nullptr), m_command_override_callback(nullptr), m_command_override_baton(nullptr) { - m_cmd_help_short = help; - m_cmd_syntax = syntax; + m_cmd_help_short = std::string(help); + m_cmd_syntax = std::string(syntax); } CommandObject::~CommandObject() {} @@ -73,20 +75,28 @@ llvm::StringRef CommandObject::GetSyntax() { syntax_str.PutCString("-- "); GetFormattedCommandArguments(syntax_str); } - m_cmd_syntax = syntax_str.GetString(); + m_cmd_syntax = std::string(syntax_str.GetString()); return m_cmd_syntax; } llvm::StringRef CommandObject::GetCommandName() const { return m_cmd_name; } -void CommandObject::SetCommandName(llvm::StringRef name) { m_cmd_name = name; } +void CommandObject::SetCommandName(llvm::StringRef name) { + m_cmd_name = std::string(name); +} -void CommandObject::SetHelp(llvm::StringRef str) { m_cmd_help_short = str; } +void CommandObject::SetHelp(llvm::StringRef str) { + m_cmd_help_short = std::string(str); +} -void CommandObject::SetHelpLong(llvm::StringRef str) { m_cmd_help_long = str; } +void CommandObject::SetHelpLong(llvm::StringRef str) { + m_cmd_help_long = std::string(str); +} -void CommandObject::SetSyntax(llvm::StringRef str) { m_cmd_syntax = str; } +void CommandObject::SetSyntax(llvm::StringRef str) { + m_cmd_syntax = std::string(str); +} Options *CommandObject::GetOptions() { // By default commands don't have options unless this virtual function is @@ -258,6 +268,10 @@ void CommandObject::Cleanup() { } void CommandObject::HandleCompletion(CompletionRequest &request) { + + m_exe_ctx = m_interpreter.GetExecutionContext(); + auto reset_ctx = llvm::make_scope_exit([this]() { Cleanup(); }); + // Default implementation of WantsCompletion() is !WantsRawCommandString(). // Subclasses who want raw command string but desire, for example, argument // completion should override WantsCompletion() to return true, instead. @@ -268,7 +282,7 @@ void CommandObject::HandleCompletion(CompletionRequest &request) { } else { // Can we do anything generic with the options? Options *cur_options = GetOptions(); - CommandReturnObject result; + CommandReturnObject result(m_interpreter.GetDebugger().GetUseColor()); OptionElementVector opt_element_vector; if (cur_options != nullptr) { @@ -485,7 +499,7 @@ void CommandObject::GetFormattedCommandArguments(Stream &str, names.Printf("%s", GetArgumentName(arg_entry[j].arg_type)); } - std::string name_str = names.GetString(); + std::string name_str = std::string(names.GetString()); switch (arg_entry[0].arg_repetition) { case eArgRepeatPlain: str.Printf("<%s>", name_str.c_str()); @@ -673,7 +687,7 @@ static llvm::StringRef FormatHelpTextCallback() { sstr.Flush(); - help_text = sstr.GetString(); + help_text = std::string(sstr.GetString()); return help_text; } @@ -691,7 +705,7 @@ static llvm::StringRef LanguageTypeHelpTextCallback() { sstr.Flush(); - help_text = sstr.GetString(); + help_text = std::string(sstr.GetString()); return help_text; } @@ -809,7 +823,7 @@ static llvm::StringRef ExprPathHelpTextCallback() { void CommandObject::FormatLongHelpText(Stream &output_strm, llvm::StringRef long_help) { CommandInterpreter &interpreter = GetCommandInterpreter(); - std::stringstream lineStream(long_help); + std::stringstream lineStream{std::string(long_help)}; std::string line; while (std::getline(lineStream, line)) { if (line.empty()) { @@ -822,8 +836,8 @@ void CommandObject::FormatLongHelpText(Stream &output_strm, } std::string whitespace_prefix = line.substr(0, result); std::string remainder = line.substr(result); - interpreter.OutputFormattedHelpText(output_strm, whitespace_prefix.c_str(), - remainder.c_str()); + interpreter.OutputFormattedHelpText(output_strm, whitespace_prefix, + remainder); } } @@ -835,13 +849,11 @@ void CommandObject::GenerateHelpText(CommandReturnObject &result) { void CommandObject::GenerateHelpText(Stream &output_strm) { CommandInterpreter &interpreter = GetCommandInterpreter(); + std::string help_text(GetHelp()); if (WantsRawCommandString()) { - std::string help_text(GetHelp()); help_text.append(" Expects 'raw' input (see 'help raw-input'.)"); - interpreter.OutputFormattedHelpText(output_strm, "", "", help_text.c_str(), - 1); - } else - interpreter.OutputFormattedHelpText(output_strm, "", "", GetHelp(), 1); + } + interpreter.OutputFormattedHelpText(output_strm, "", help_text); output_strm << "\nSyntax: " << GetSyntax() << "\n"; Options *options = GetOptions(); if (options != nullptr) { @@ -1066,7 +1078,7 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = { { eArgTypePermissionsNumber, "perms-numeric", CommandCompletions::eNoCompletion, { nullptr, false }, "Permissions given as an octal number (e.g. 755)." }, { eArgTypePermissionsString, "perms=string", CommandCompletions::eNoCompletion, { nullptr, false }, "Permissions given as a string value (e.g. rw-r-xr--)." }, { eArgTypePid, "pid", CommandCompletions::eNoCompletion, { nullptr, false }, "The process ID number." }, - { eArgTypePlugin, "plugin", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, + { eArgTypePlugin, "plugin", CommandCompletions::eProcessPluginCompletion, { nullptr, false }, "Help text goes here." }, { eArgTypeProcessName, "process-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of the process." }, { eArgTypePythonClass, "python-class", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a Python class." }, { eArgTypePythonFunction, "python-function", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a Python function." }, @@ -1077,7 +1089,7 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = { { eArgTypeRunArgs, "run-args", CommandCompletions::eNoCompletion, { nullptr, false }, "Arguments to be passed to the target program when it starts executing." }, { eArgTypeRunMode, "run-mode", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, { eArgTypeScriptedCommandSynchronicity, "script-cmd-synchronicity", CommandCompletions::eNoCompletion, { nullptr, false }, "The synchronicity to use to run scripted commands with regard to LLDB event system." }, - { eArgTypeScriptLang, "script-language", CommandCompletions::eNoCompletion, { nullptr, false }, "The scripting language to be used for script-based commands. Currently only Python is valid." }, + { eArgTypeScriptLang, "script-language", CommandCompletions::eNoCompletion, { nullptr, false }, "The scripting language to be used for script-based commands. Supported languages are python and lua." }, { eArgTypeSearchWord, "search-word", CommandCompletions::eNoCompletion, { nullptr, false }, "Any word of interest for search purposes." }, { eArgTypeSelector, "selector", CommandCompletions::eNoCompletion, { nullptr, false }, "An Objective-C selector name." }, { eArgTypeSettingIndex, "setting-index", CommandCompletions::eNoCompletion, { nullptr, false }, "An index into a settings variable that is an array (try 'settings list' to see all the possible settings variables and their types)." }, @@ -1105,7 +1117,8 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = { { eArgTypeWatchpointIDRange, "watchpt-id-list", CommandCompletions::eNoCompletion, { nullptr, false }, "For example, '1-3' or '1 to 3'." }, { eArgTypeWatchType, "watch-type", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify the type for a watchpoint." }, { eArgRawInput, "raw-input", CommandCompletions::eNoCompletion, { nullptr, false }, "Free-form text passed to a command without prior interpretation, allowing spaces without requiring quotes. To pass arguments and free form text put two dashes ' -- ' between the last argument and any raw input." }, - { eArgTypeCommand, "command", CommandCompletions::eNoCompletion, { nullptr, false }, "An LLDB Command line command." } + { eArgTypeCommand, "command", CommandCompletions::eNoCompletion, { nullptr, false }, "An LLDB Command line command." }, + { eArgTypeColumnNum, "column", CommandCompletions::eNoCompletion, { nullptr, false }, "Column number in a source file." } // clang-format on }; diff --git a/gnu/llvm/lldb/source/Interpreter/CommandObjectRegexCommand.cpp b/gnu/llvm/lldb/source/Interpreter/CommandObjectRegexCommand.cpp index 693d18ce7bd..5a0265e58c5 100644 --- a/gnu/llvm/lldb/source/Interpreter/CommandObjectRegexCommand.cpp +++ b/gnu/llvm/lldb/source/Interpreter/CommandObjectRegexCommand.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectRegexCommand.cpp ---------------------------*- C++ -*-===// +//===-- CommandObjectRegexCommand.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/CommandObjectScript.cpp b/gnu/llvm/lldb/source/Interpreter/CommandObjectScript.cpp index d61d0cac976..5e98c658ebd 100644 --- a/gnu/llvm/lldb/source/Interpreter/CommandObjectScript.cpp +++ b/gnu/llvm/lldb/source/Interpreter/CommandObjectScript.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectScript.cpp ---------------------------------*- C++ -*-===// +//===-- CommandObjectScript.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/CommandObjectScript.h b/gnu/llvm/lldb/source/Interpreter/CommandObjectScript.h index 4f7a912979b..a5f659995de 100644 --- a/gnu/llvm/lldb/source/Interpreter/CommandObjectScript.h +++ b/gnu/llvm/lldb/source/Interpreter/CommandObjectScript.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectScript_h_ -#define liblldb_CommandObjectScript_h_ +#ifndef LLDB_SOURCE_INTERPRETER_COMMANDOBJECTSCRIPT_H +#define LLDB_SOURCE_INTERPRETER_COMMANDOBJECTSCRIPT_H #include "lldb/Interpreter/CommandObject.h" @@ -28,4 +28,4 @@ protected: } // namespace lldb_private -#endif // liblldb_CommandObjectScript_h_ +#endif // LLDB_SOURCE_INTERPRETER_COMMANDOBJECTSCRIPT_H diff --git a/gnu/llvm/lldb/source/Interpreter/CommandOptionValidators.cpp b/gnu/llvm/lldb/source/Interpreter/CommandOptionValidators.cpp index c41c1566aab..a4b4b57c54b 100644 --- a/gnu/llvm/lldb/source/Interpreter/CommandOptionValidators.cpp +++ b/gnu/llvm/lldb/source/Interpreter/CommandOptionValidators.cpp @@ -1,4 +1,4 @@ -//===-- CommandOptionValidators.cpp -----------------------------*- C++ -*-===// +//===-- CommandOptionValidators.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/CommandReturnObject.cpp b/gnu/llvm/lldb/source/Interpreter/CommandReturnObject.cpp index c17390be731..6f3732e3507 100644 --- a/gnu/llvm/lldb/source/Interpreter/CommandReturnObject.cpp +++ b/gnu/llvm/lldb/source/Interpreter/CommandReturnObject.cpp @@ -1,4 +1,4 @@ -//===-- CommandReturnObject.cpp ---------------------------------*- C++ -*-===// +//===-- CommandReturnObject.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -14,12 +14,21 @@ using namespace lldb; using namespace lldb_private; -static void DumpStringToStreamWithNewline(Stream &strm, const std::string &s, - bool add_newline_if_empty) { +static llvm::raw_ostream &error(Stream &strm) { + return llvm::WithColor(strm.AsRawOstream(), llvm::HighlightColor::Error, + llvm::ColorMode::Enable) + << "error: "; +} + +static llvm::raw_ostream &warning(Stream &strm) { + return llvm::WithColor(strm.AsRawOstream(), llvm::HighlightColor::Warning, + llvm::ColorMode::Enable) + << "warning: "; +} + +static void DumpStringToStreamWithNewline(Stream &strm, const std::string &s) { bool add_newline = false; - if (s.empty()) { - add_newline = add_newline_if_empty; - } else { + if (!s.empty()) { // We already checked for empty above, now make sure there is a newline in // the error, and if there isn't one, add one. strm.Write(s.c_str(), s.size()); @@ -31,9 +40,10 @@ static void DumpStringToStreamWithNewline(Stream &strm, const std::string &s, strm.EOL(); } -CommandReturnObject::CommandReturnObject() - : m_out_stream(), m_err_stream(), m_status(eReturnStatusStarted), - m_did_change_process_state(false), m_interactive(true) {} +CommandReturnObject::CommandReturnObject(bool colors) + : m_out_stream(colors), m_err_stream(colors), + m_status(eReturnStatusStarted), m_did_change_process_state(false), + m_interactive(true) {} CommandReturnObject::~CommandReturnObject() {} @@ -46,11 +56,10 @@ void CommandReturnObject::AppendErrorWithFormat(const char *format, ...) { sstrm.PrintfVarArg(format, args); va_end(args); - const std::string &s = sstrm.GetString(); + const std::string &s = std::string(sstrm.GetString()); if (!s.empty()) { - Stream &error_strm = GetErrorStream(); - error_strm.PutCString("error: "); - DumpStringToStreamWithNewline(error_strm, s, false); + error(GetErrorStream()); + DumpStringToStreamWithNewline(GetErrorStream(), s); } } @@ -75,7 +84,7 @@ void CommandReturnObject::AppendWarningWithFormat(const char *format, ...) { sstrm.PrintfVarArg(format, args); va_end(args); - GetErrorStream() << "warning: " << sstrm.GetString(); + warning(GetErrorStream()) << sstrm.GetString(); } void CommandReturnObject::AppendMessage(llvm::StringRef in_string) { @@ -87,7 +96,7 @@ void CommandReturnObject::AppendMessage(llvm::StringRef in_string) { void CommandReturnObject::AppendWarning(llvm::StringRef in_string) { if (in_string.empty()) return; - GetErrorStream() << "warning: " << in_string << "\n"; + warning(GetErrorStream()) << in_string << '\n'; } // Similar to AppendWarning, but do not prepend 'warning: ' to message, and @@ -102,7 +111,7 @@ void CommandReturnObject::AppendRawWarning(llvm::StringRef in_string) { void CommandReturnObject::AppendError(llvm::StringRef in_string) { if (in_string.empty()) return; - GetErrorStream() << "error: " << in_string << "\n"; + error(GetErrorStream()) << in_string << '\n'; } void CommandReturnObject::SetError(const Status &error, diff --git a/gnu/llvm/lldb/source/Interpreter/OptionArgParser.cpp b/gnu/llvm/lldb/source/Interpreter/OptionArgParser.cpp index 56d99a4220f..3dcb30e846d 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionArgParser.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionArgParser.cpp @@ -1,4 +1,4 @@ -//===-- OptionArgParser.cpp -------------------------------------*- C++ -*-===// +//===-- OptionArgParser.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionGroupArchitecture.cpp b/gnu/llvm/lldb/source/Interpreter/OptionGroupArchitecture.cpp index 11f786c52c0..baca1c6e806 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionGroupArchitecture.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionGroupArchitecture.cpp @@ -1,4 +1,4 @@ -//===-- OptionGroupArchitecture.cpp -----------------------------*- C++ -*-===// +//===-- OptionGroupArchitecture.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -42,7 +42,7 @@ OptionGroupArchitecture::SetOptionValue(uint32_t option_idx, switch (short_option) { case 'a': - m_arch_str.assign(option_arg); + m_arch_str.assign(std::string(option_arg)); break; default: diff --git a/gnu/llvm/lldb/source/Interpreter/OptionGroupBoolean.cpp b/gnu/llvm/lldb/source/Interpreter/OptionGroupBoolean.cpp index 8a6482c8df2..3482e784ca0 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionGroupBoolean.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionGroupBoolean.cpp @@ -1,4 +1,4 @@ -//===-- OptionGroupBoolean.cpp ----------------------------------*- C++ -*-===// +//===-- OptionGroupBoolean.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionGroupFile.cpp b/gnu/llvm/lldb/source/Interpreter/OptionGroupFile.cpp index cda75ec205e..9d9be5b6f17 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionGroupFile.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionGroupFile.cpp @@ -1,4 +1,4 @@ -//===-- OptionGroupFile.cpp -------------------------------*- C++ -*-===// +//===-- OptionGroupFile.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionGroupFormat.cpp b/gnu/llvm/lldb/source/Interpreter/OptionGroupFormat.cpp index c25e35f8451..0052f72b055 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionGroupFormat.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionGroupFormat.cpp @@ -1,4 +1,4 @@ -//===-- OptionGroupFormat.cpp -----------------------------------*- C++ -*-===// +//===-- OptionGroupFormat.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionGroupOutputFile.cpp b/gnu/llvm/lldb/source/Interpreter/OptionGroupOutputFile.cpp index 3df75cf86b8..65105c3e018 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionGroupOutputFile.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionGroupOutputFile.cpp @@ -1,4 +1,4 @@ -//===-- OptionGroupOutputFile.cpp -------------------------------*- C++ -*-===// +//===-- OptionGroupOutputFile.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionGroupPlatform.cpp b/gnu/llvm/lldb/source/Interpreter/OptionGroupPlatform.cpp index 6ddbbf0e3ab..4242e010fa6 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionGroupPlatform.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionGroupPlatform.cpp @@ -1,4 +1,4 @@ -//===-- OptionGroupPlatform.cpp ---------------------------------*- C++ -*-===// +//===-- OptionGroupPlatform.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -95,7 +95,7 @@ OptionGroupPlatform::SetOptionValue(uint32_t option_idx, switch (short_option) { case 'p': - m_platform_name.assign(option_arg); + m_platform_name.assign(std::string(option_arg)); break; case 'v': diff --git a/gnu/llvm/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp b/gnu/llvm/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp index e41f9d7b40e..217dab2ef63 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp @@ -1,4 +1,4 @@ -//===-- OptionGroupPythonClassWithDict.cpp ----------------------------------*- C++ -*-===// +//===-- OptionGroupPythonClassWithDict.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -91,13 +91,13 @@ Status OptionGroupPythonClassWithDict::SetOptionValue( switch (option_idx) { case 0: case 3: { - m_name.assign(option_arg); + m_name.assign(std::string(option_arg)); } break; case 1: { if (!m_dict_sp) m_dict_sp = std::make_shared(); if (m_current_key.empty()) - m_current_key.assign(option_arg); + m_current_key.assign(std::string(option_arg)); else error.SetErrorStringWithFormat("Key: \"%s\" missing value.", m_current_key.c_str()); diff --git a/gnu/llvm/lldb/source/Interpreter/OptionGroupString.cpp b/gnu/llvm/lldb/source/Interpreter/OptionGroupString.cpp index c01b7065fbd..c9f78eb953f 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionGroupString.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionGroupString.cpp @@ -1,4 +1,4 @@ -//===-- OptionGroupString.cpp ----------------------------------*- C++ -*-===// +//===-- OptionGroupString.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionGroupUInt64.cpp b/gnu/llvm/lldb/source/Interpreter/OptionGroupUInt64.cpp index 53e5674d029..309855d4718 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionGroupUInt64.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionGroupUInt64.cpp @@ -1,4 +1,4 @@ -//===-- OptionGroupUInt64.cpp ----------------------------------*- C++ -*-===// +//===-- OptionGroupUInt64.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionGroupUUID.cpp b/gnu/llvm/lldb/source/Interpreter/OptionGroupUUID.cpp index 8fc330a8939..46f2ff75225 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionGroupUUID.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionGroupUUID.cpp @@ -1,4 +1,4 @@ -//===-- OptionGroupUUID.cpp -------------------------------------*- C++ -*-===// +//===-- OptionGroupUUID.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/gnu/llvm/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp index da0437ac299..e0401f8987a 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp @@ -1,4 +1,4 @@ -//===-- OptionGroupValueObjectDisplay.cpp -----------------------*- C++ -*-===// +//===-- OptionGroupValueObjectDisplay.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionGroupVariable.cpp b/gnu/llvm/lldb/source/Interpreter/OptionGroupVariable.cpp index a9004bf03cd..9f57dbbd073 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionGroupVariable.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionGroupVariable.cpp @@ -1,4 +1,4 @@ -//===-- OptionGroupVariable.cpp -----------------------*- C++ -*-===// +//===-- OptionGroupVariable.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionGroupWatchpoint.cpp b/gnu/llvm/lldb/source/Interpreter/OptionGroupWatchpoint.cpp index 682f99b8c5c..07013b5b78f 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionGroupWatchpoint.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionGroupWatchpoint.cpp @@ -1,4 +1,4 @@ -//===-- OptionGroupWatchpoint.cpp -------------------------------*- C++ -*-===// +//===-- OptionGroupWatchpoint.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValue.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValue.cpp index bc929aa9dab..198be85a7b4 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValue.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValue.cpp @@ -1,4 +1,4 @@ -//===-- OptionValue.cpp -----------------------------------------*- C++ -*-===// +//===-- OptionValue.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,10 +7,11 @@ //===----------------------------------------------------------------------===// #include "lldb/Interpreter/OptionValue.h" - #include "lldb/Interpreter/OptionValues.h" #include "lldb/Utility/StringList.h" +#include + using namespace lldb; using namespace lldb_private; @@ -505,37 +506,37 @@ lldb::OptionValueSP OptionValue::CreateValueFromCStringForTypeMask( lldb::OptionValueSP value_sp; switch (type_mask) { case 1u << eTypeArch: - value_sp.reset(new OptionValueArch()); + value_sp = std::make_shared(); break; case 1u << eTypeBoolean: - value_sp.reset(new OptionValueBoolean(false)); + value_sp = std::make_shared(false); break; case 1u << eTypeChar: - value_sp.reset(new OptionValueChar('\0')); + value_sp = std::make_shared('\0'); break; case 1u << eTypeFileSpec: - value_sp.reset(new OptionValueFileSpec()); + value_sp = std::make_shared(); break; case 1u << eTypeFormat: - value_sp.reset(new OptionValueFormat(eFormatInvalid)); + value_sp = std::make_shared(eFormatInvalid); break; case 1u << eTypeFormatEntity: - value_sp.reset(new OptionValueFormatEntity(nullptr)); + value_sp = std::make_shared(nullptr); break; case 1u << eTypeLanguage: - value_sp.reset(new OptionValueLanguage(eLanguageTypeUnknown)); + value_sp = std::make_shared(eLanguageTypeUnknown); break; case 1u << eTypeSInt64: - value_sp.reset(new OptionValueSInt64()); + value_sp = std::make_shared(); break; case 1u << eTypeString: - value_sp.reset(new OptionValueString()); + value_sp = std::make_shared(); break; case 1u << eTypeUInt64: - value_sp.reset(new OptionValueUInt64()); + value_sp = std::make_shared(); break; case 1u << eTypeUUID: - value_sp.reset(new OptionValueUUID()); + value_sp = std::make_shared(); break; } diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValueArch.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValueArch.cpp index 7271c1471f9..ac78ee64a9d 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValueArch.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValueArch.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueArch.cpp ---------------------------------*- C++ -*-===// +//===-- OptionValueArch.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValueArgs.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValueArgs.cpp index d619dba5678..9e7774a231c 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValueArgs.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValueArgs.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueArgs.cpp -------------------------------------*- C++ -*-===// +//===-- OptionValueArgs.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValueArray.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValueArray.cpp index 30902c0f295..9be11e32e2d 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValueArray.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValueArray.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueArray.cpp ------------------------------------*- C++ -*-===// +//===-- OptionValueArray.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValueBoolean.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValueBoolean.cpp index 6f893a94e86..24ae3f673bf 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValueBoolean.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValueBoolean.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueBoolean.cpp ----------------------------------*- C++ -*-===// +//===-- OptionValueBoolean.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValueChar.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValueChar.cpp index 23012e6e2ec..af9a371f46d 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValueChar.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValueChar.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueChar.cpp -------------------------------------*- C++ -*-===// +//===-- OptionValueChar.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValueDictionary.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValueDictionary.cpp index a4022288fcc..caadccd0423 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValueDictionary.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValueDictionary.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueDictionary.cpp -------------------------------*- C++ -*-===// +//===-- OptionValueDictionary.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -45,7 +45,7 @@ void OptionValueDictionary::DumpValue(const ExecutionContext *exe_ctx, else strm.EOL(); - strm.Indent(pos->first.GetCString()); + strm.Indent(pos->first.GetStringRef()); const uint32_t extra_dump_options = m_raw_value_dump ? eDumpOptionRaw : 0; switch (dict_type) { diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValueEnumeration.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValueEnumeration.cpp index 26933aa7824..9a1e08d4fba 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValueEnumeration.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValueEnumeration.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueEnumeration.cpp ------------------------------*- C++ -*-===// +//===-- OptionValueEnumeration.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValueFileSpec.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValueFileSpec.cpp index 20d3d4e68e3..15acb7e5e5b 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValueFileSpec.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValueFileSpec.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueFileSpec.cpp ---------------------------------*- C++ -*-===// +//===-- OptionValueFileSpec.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValueFormat.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValueFormat.cpp index ba5a44c270d..b676bed50e6 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValueFormat.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValueFormat.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueFormat.cpp -----------------------------------*- C++ -*-===// +//===-- OptionValueFormat.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValueFormatEntity.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValueFormatEntity.cpp index 8dc52650a33..6b36bd57518 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValueFormatEntity.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValueFormatEntity.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueFormatEntity.cpp -----------------------------*- C++ -*-===// +//===-- OptionValueFormatEntity.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -95,7 +95,7 @@ Status OptionValueFormatEntity::SetValueFromString(llvm::StringRef value_str, error = FormatEntity::Parse(value_str, entry); if (error.Success()) { m_current_entry = std::move(entry); - m_current_format = value_str; + m_current_format = std::string(value_str); m_value_was_set = true; NotifyValueChanged(); } diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValueLanguage.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValueLanguage.cpp index 1d7e18868b6..5b310782a1b 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValueLanguage.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValueLanguage.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueLanguage.cpp ---------------------------------*- C++ -*-===// +//===-- OptionValueLanguage.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValuePathMappings.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValuePathMappings.cpp index 75fcf024747..3b3f43d0729 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValuePathMappings.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValuePathMappings.cpp @@ -1,4 +1,4 @@ -//===-- OptionValuePathMappings.cpp -----------------------------*- C++ -*-===// +//===-- OptionValuePathMappings.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -61,7 +61,7 @@ Status OptionValuePathMappings::SetValueFromString(llvm::StringRef value, count); } else { bool changed = false; - for (size_t i = 1; i < argc; i += 2, ++idx) { + for (size_t i = 1; i < argc; idx++, i += 2) { const char *orginal_path = args.GetArgumentAtIndex(i); const char *replace_path = args.GetArgumentAtIndex(i + 1); if (VerifyPathExists(replace_path)) { @@ -71,9 +71,11 @@ Status OptionValuePathMappings::SetValueFromString(llvm::StringRef value, m_path_mappings.Append(a, b, m_notify_changes); changed = true; } else { + std::string previousError = + error.Fail() ? std::string(error.AsCString()) + "\n" : ""; error.SetErrorStringWithFormat( - "the replacement path doesn't exist: \"%s\"", replace_path); - break; + "%sthe replacement path doesn't exist: \"%s\"", + previousError.c_str(), replace_path); } } if (changed) @@ -109,9 +111,11 @@ Status OptionValuePathMappings::SetValueFromString(llvm::StringRef value, m_value_was_set = true; changed = true; } else { + std::string previousError = + error.Fail() ? std::string(error.AsCString()) + "\n" : ""; error.SetErrorStringWithFormat( - "the replacement path doesn't exist: \"%s\"", replace_path); - break; + "%sthe replacement path doesn't exist: \"%s\"", + previousError.c_str(), replace_path); } } if (changed) @@ -135,7 +139,7 @@ Status OptionValuePathMappings::SetValueFromString(llvm::StringRef value, bool changed = false; if (op == eVarSetOperationInsertAfter) ++idx; - for (size_t i = 1; i < argc; i += 2, ++idx) { + for (size_t i = 1; i < argc; i += 2) { const char *orginal_path = args.GetArgumentAtIndex(i); const char *replace_path = args.GetArgumentAtIndex(i + 1); if (VerifyPathExists(replace_path)) { @@ -143,10 +147,13 @@ Status OptionValuePathMappings::SetValueFromString(llvm::StringRef value, ConstString b(replace_path); m_path_mappings.Insert(a, b, idx, m_notify_changes); changed = true; + idx++; } else { + std::string previousError = + error.Fail() ? std::string(error.AsCString()) + "\n" : ""; error.SetErrorStringWithFormat( - "the replacement path doesn't exist: \"%s\"", replace_path); - break; + "%sthe replacement path doesn't exist: \"%s\"", + previousError.c_str(), replace_path); } } if (changed) @@ -161,32 +168,23 @@ Status OptionValuePathMappings::SetValueFromString(llvm::StringRef value, case eVarSetOperationRemove: if (argc > 0) { std::vector remove_indexes; - bool all_indexes_valid = true; - size_t i; - for (i = 0; all_indexes_valid && i < argc; ++i) { - const int idx = + for (size_t i = 0; i < argc; ++i) { + int idx = StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); - if (idx == INT32_MAX) - all_indexes_valid = false; - else + if (idx < 0 || idx >= (int)m_path_mappings.GetSize()) { + error.SetErrorStringWithFormat( + "invalid array index '%s', aborting remove operation", + args.GetArgumentAtIndex(i)); + break; + } else remove_indexes.push_back(idx); } - if (all_indexes_valid) { - size_t num_remove_indexes = remove_indexes.size(); - if (num_remove_indexes) { - // Sort and then erase in reverse so indexes are always valid - 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); - } - } - NotifyValueChanged(); - } else { - error.SetErrorStringWithFormat( - "invalid array index '%s', aborting remove operation", - args.GetArgumentAtIndex(i)); - } + // Sort and then erase in reverse so indexes are always valid + llvm::sort(remove_indexes.begin(), remove_indexes.end()); + for (auto index : llvm::reverse(remove_indexes)) + m_path_mappings.Remove(index, m_notify_changes); + NotifyValueChanged(); } else { error.SetErrorString("remove operation takes one or more array index"); } diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValueProperties.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValueProperties.cpp index 21750cf1861..24cda056977 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValueProperties.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValueProperties.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueProperties.cpp --------------------------------*- C++-*-===// +//===-- OptionValueProperties.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValueRegex.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValueRegex.cpp index cf806fb550f..bec3942d9cb 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValueRegex.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValueRegex.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueRegex.cpp ------------------------------------*- C++ -*-===// +//===-- OptionValueRegex.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValueSInt64.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValueSInt64.cpp index d26fc08a313..ada20b2139a 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValueSInt64.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValueSInt64.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueSInt64.cpp -----------------------------------*- C++ -*-===// +//===-- OptionValueSInt64.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValueString.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValueString.cpp index a519249ab47..22f5d08bf83 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValueString.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValueString.cpp @@ -1,5 +1,4 @@ -//===-- OptionValueString.cpp ------------------------------------*- C++ -//-*-===// +//===-- OptionValueString.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -83,7 +82,7 @@ Status OptionValueString::SetValueFromString(llvm::StringRef value, Args::EncodeEscapeSequences(value_str.c_str(), str); new_value.append(str); } else - new_value.append(value); + new_value.append(std::string(value)); } if (m_validator) { error = m_validator(new_value.c_str(), m_validator_baton); @@ -128,7 +127,7 @@ Status OptionValueString::SetCurrentValue(llvm::StringRef value) { if (error.Fail()) return error; } - m_current_value.assign(value); + m_current_value.assign(std::string(value)); return Status(); } diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValueUInt64.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValueUInt64.cpp index 3be0772daa8..98ef016e5f7 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValueUInt64.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValueUInt64.cpp @@ -1,5 +1,4 @@ -//===-- OptionValueUInt64.cpp ------------------------------------*- C++ -//-*-===// +//===-- OptionValueUInt64.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/OptionValueUUID.cpp b/gnu/llvm/lldb/source/Interpreter/OptionValueUUID.cpp index 7a6bc65b25a..2bd74977355 100644 --- a/gnu/llvm/lldb/source/Interpreter/OptionValueUUID.cpp +++ b/gnu/llvm/lldb/source/Interpreter/OptionValueUUID.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueUUID.cpp ------------------------------------*- C++ -*-===// +//===-- OptionValueUUID.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -38,7 +38,7 @@ Status OptionValueUUID::SetValueFromString(llvm::StringRef value, case eVarSetOperationReplace: case eVarSetOperationAssign: { - if (m_uuid.SetFromStringRef(value) == 0) + if (!m_uuid.SetFromStringRef(value)) error.SetErrorStringWithFormat("invalid uuid string value '%s'", value.str().c_str()); else { diff --git a/gnu/llvm/lldb/source/Interpreter/Options.cpp b/gnu/llvm/lldb/source/Interpreter/Options.cpp index 80e9d3a6fc1..c14b6b6ce66 100644 --- a/gnu/llvm/lldb/source/Interpreter/Options.cpp +++ b/gnu/llvm/lldb/source/Interpreter/Options.cpp @@ -1,4 +1,4 @@ -//===-- Options.cpp ---------------------------------------------*- C++ -*-===// +//===-- Options.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -282,7 +282,7 @@ void Options::OutputFormattedUsageText(Stream &strm, if (static_cast(actual_text.length() + strm.GetIndentLevel()) < output_max_columns) { // Output it as a single line. - strm.Indent(actual_text.c_str()); + strm.Indent(actual_text); strm.EOL(); } else { // We need to break it up into multiple lines. @@ -798,7 +798,8 @@ void Options::HandleOptionArgumentCompletion( interpreter.GetDebugger().GetSelectedTarget(); // Search filters require a target... if (target_sp) - filter_up.reset(new SearchFilterByModule(target_sp, module_spec)); + filter_up = + std::make_unique(target_sp, module_spec); } break; } @@ -932,7 +933,7 @@ static size_t FindArgumentIndexForOption(const Args &args, const Option &long_option) { std::string short_opt = llvm::formatv("-{0}", char(long_option.val)).str(); std::string long_opt = - llvm::formatv("--{0}", long_option.definition->long_option); + std::string(llvm::formatv("--{0}", long_option.definition->long_option)); for (const auto &entry : llvm::enumerate(args)) { if (entry.value().ref().startswith(short_opt) || entry.value().ref().startswith(long_opt)) @@ -1075,7 +1076,7 @@ llvm::Expected Options::ParseAlias(const Args &args, if (!input_line.empty()) { auto tmp_arg = args_copy[idx].ref(); - size_t pos = input_line.find(tmp_arg); + size_t pos = input_line.find(std::string(tmp_arg)); if (pos != std::string::npos) input_line.erase(pos, tmp_arg.size()); } @@ -1087,7 +1088,7 @@ llvm::Expected Options::ParseAlias(const Args &args, (args_copy[idx].ref() == OptionParser::GetOptionArgument())) { if (input_line.size() > 0) { auto tmp_arg = args_copy[idx].ref(); - size_t pos = input_line.find(tmp_arg); + size_t pos = input_line.find(std::string(tmp_arg)); if (pos != std::string::npos) input_line.erase(pos, tmp_arg.size()); } diff --git a/gnu/llvm/lldb/source/Interpreter/Property.cpp b/gnu/llvm/lldb/source/Interpreter/Property.cpp index a81098373c2..92381124985 100644 --- a/gnu/llvm/lldb/source/Interpreter/Property.cpp +++ b/gnu/llvm/lldb/source/Interpreter/Property.cpp @@ -1,4 +1,4 @@ -//===-- Property.cpp --------------------------------------------*- C++ -*-===// +//===-- Property.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Interpreter/ScriptInterpreter.cpp b/gnu/llvm/lldb/source/Interpreter/ScriptInterpreter.cpp index 00c460612ac..86620449f2f 100644 --- a/gnu/llvm/lldb/source/Interpreter/ScriptInterpreter.cpp +++ b/gnu/llvm/lldb/source/Interpreter/ScriptInterpreter.cpp @@ -1,4 +1,4 @@ -//===-- ScriptInterpreter.cpp -----------------------------------*- C++ -*-===// +//===-- ScriptInterpreter.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,16 +7,21 @@ //===----------------------------------------------------------------------===// #include "lldb/Interpreter/ScriptInterpreter.h" - -#include -#include -#include - +#include "lldb/Core/Debugger.h" +#include "lldb/Host/ConnectionFileDescriptor.h" +#include "lldb/Host/Pipe.h" #include "lldb/Host/PseudoTerminal.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StringList.h" +#if defined(_WIN32) +#include "lldb/Host/windows/ConnectionGenericFileWindows.h" +#endif +#include +#include +#include +#include using namespace lldb; using namespace lldb_private; @@ -102,6 +107,113 @@ Status ScriptInterpreter::SetBreakpointCommandCallbackFunction( std::unique_ptr ScriptInterpreter::AcquireInterpreterLock() { - return std::unique_ptr( - new ScriptInterpreterLocker()); + return std::make_unique(); +} + +static void ReadThreadBytesReceived(void *baton, const void *src, + size_t src_len) { + if (src && src_len) { + Stream *strm = (Stream *)baton; + strm->Write(src, src_len); + strm->Flush(); + } +} + +llvm::Expected> +ScriptInterpreterIORedirect::Create(bool enable_io, Debugger &debugger, + CommandReturnObject *result) { + if (enable_io) + return std::unique_ptr( + new ScriptInterpreterIORedirect(debugger, result)); + + auto nullin = FileSystem::Instance().Open(FileSpec(FileSystem::DEV_NULL), + File::eOpenOptionRead); + if (!nullin) + return nullin.takeError(); + + auto nullout = FileSystem::Instance().Open(FileSpec(FileSystem::DEV_NULL), + File::eOpenOptionWrite); + if (!nullout) + return nullin.takeError(); + + return std::unique_ptr( + new ScriptInterpreterIORedirect(std::move(*nullin), std::move(*nullout))); +} + +ScriptInterpreterIORedirect::ScriptInterpreterIORedirect( + std::unique_ptr input, std::unique_ptr output) + : m_input_file_sp(std::move(input)), + m_output_file_sp(std::make_shared(std::move(output))), + m_error_file_sp(m_output_file_sp), + m_communication("lldb.ScriptInterpreterIORedirect.comm"), + m_disconnect(false) {} + +ScriptInterpreterIORedirect::ScriptInterpreterIORedirect( + Debugger &debugger, CommandReturnObject *result) + : m_communication("lldb.ScriptInterpreterIORedirect.comm"), + m_disconnect(false) { + + if (result) { + m_input_file_sp = debugger.GetInputFileSP(); + + Pipe pipe; + Status pipe_result = pipe.CreateNew(false); +#if defined(_WIN32) + lldb::file_t read_file = pipe.GetReadNativeHandle(); + pipe.ReleaseReadFileDescriptor(); + std::unique_ptr conn_up = + std::make_unique(read_file, true); +#else + std::unique_ptr conn_up = + std::make_unique( + pipe.ReleaseReadFileDescriptor(), true); +#endif + + if (conn_up->IsConnected()) { + m_communication.SetConnection(std::move(conn_up)); + m_communication.SetReadThreadBytesReceivedCallback( + ReadThreadBytesReceived, &result->GetOutputStream()); + m_communication.StartReadThread(); + m_disconnect = true; + + FILE *outfile_handle = fdopen(pipe.ReleaseWriteFileDescriptor(), "w"); + m_output_file_sp = std::make_shared(outfile_handle, true); + m_error_file_sp = m_output_file_sp; + if (outfile_handle) + ::setbuf(outfile_handle, nullptr); + + result->SetImmediateOutputFile(debugger.GetOutputStream().GetFileSP()); + result->SetImmediateErrorFile(debugger.GetErrorStream().GetFileSP()); + } + } + + if (!m_input_file_sp || !m_output_file_sp || !m_error_file_sp) + debugger.AdoptTopIOHandlerFilesIfInvalid(m_input_file_sp, m_output_file_sp, + m_error_file_sp); +} + +void ScriptInterpreterIORedirect::Flush() { + if (m_output_file_sp) + m_output_file_sp->Flush(); + if (m_error_file_sp) + m_error_file_sp->Flush(); +} + +ScriptInterpreterIORedirect::~ScriptInterpreterIORedirect() { + if (!m_disconnect) + return; + + assert(m_output_file_sp); + assert(m_error_file_sp); + assert(m_output_file_sp == m_error_file_sp); + + // Close the write end of the pipe since we are done with our one line + // script. This should cause the read thread that output_comm is using to + // exit. + m_output_file_sp->GetFile().Close(); + // The close above should cause this thread to exit when it gets to the end + // of file, so let it get all its data. + m_communication.JoinReadThread(); + // Now we can close the read end of the pipe. + m_communication.Disconnect(); } diff --git a/gnu/llvm/lldb/source/Interpreter/embedded_interpreter.py b/gnu/llvm/lldb/source/Interpreter/embedded_interpreter.py index 8a1195d83c6..9312dbfaca4 100644 --- a/gnu/llvm/lldb/source/Interpreter/embedded_interpreter.py +++ b/gnu/llvm/lldb/source/Interpreter/embedded_interpreter.py @@ -73,7 +73,12 @@ def get_terminal_size(fd): def readfunc_stdio(prompt): sys.stdout.write(prompt) sys.stdout.flush() - return sys.stdin.readline().rstrip() + line = sys.stdin.readline() + # Readline always includes a trailing newline character unless the file + # ends with an incomplete line. An empty line indicates EOF. + if not line: + raise EOFError + return line.rstrip() def run_python_interpreter(local_dict): diff --git a/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp b/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp new file mode 100644 index 00000000000..5cf9fb4ad37 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp @@ -0,0 +1,52 @@ +//===-- AArch66.h ---------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABIAArch64.h" +#include "ABIMacOSX_arm64.h" +#include "ABISysV_arm64.h" +#include "Utility/ARM64_DWARF_Registers.h" +#include "lldb/Core/PluginManager.h" + +LLDB_PLUGIN_DEFINE(ABIAArch64) + +void ABIAArch64::Initialize() { + ABISysV_arm64::Initialize(); + ABIMacOSX_arm64::Initialize(); +} + +void ABIAArch64::Terminate() { + ABISysV_arm64::Terminate(); + ABIMacOSX_arm64::Terminate(); +} + +std::pair +ABIAArch64::GetEHAndDWARFNums(llvm::StringRef name) { + if (name == "pc") + return {LLDB_INVALID_REGNUM, arm64_dwarf::pc}; + if (name == "cpsr") + return {LLDB_INVALID_REGNUM, arm64_dwarf::cpsr}; + return MCBasedABI::GetEHAndDWARFNums(name); +} + +uint32_t ABIAArch64::GetGenericNum(llvm::StringRef name) { + return llvm::StringSwitch(name) + .Case("pc", LLDB_REGNUM_GENERIC_PC) + .Case("lr", LLDB_REGNUM_GENERIC_RA) + .Case("sp", LLDB_REGNUM_GENERIC_SP) + .Case("fp", LLDB_REGNUM_GENERIC_FP) + .Case("cpsr", LLDB_REGNUM_GENERIC_FLAGS) + .Case("x0", LLDB_REGNUM_GENERIC_ARG1) + .Case("x1", LLDB_REGNUM_GENERIC_ARG2) + .Case("x2", LLDB_REGNUM_GENERIC_ARG3) + .Case("x3", LLDB_REGNUM_GENERIC_ARG4) + .Case("x4", LLDB_REGNUM_GENERIC_ARG5) + .Case("x5", LLDB_REGNUM_GENERIC_ARG6) + .Case("x6", LLDB_REGNUM_GENERIC_ARG7) + .Case("x7", LLDB_REGNUM_GENERIC_ARG8) + .Default(LLDB_INVALID_REGNUM); +} diff --git a/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h b/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h new file mode 100644 index 00000000000..981145e2017 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h @@ -0,0 +1,32 @@ +//===-- AArch64.h -----------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_AARCH64_ABIAARCH64_H +#define LLDB_SOURCE_PLUGINS_ABI_AARCH64_ABIAARCH64_H + +#include "lldb/Target/ABI.h" + +class ABIAArch64: public lldb_private::MCBasedABI { +public: + static void Initialize(); + static void Terminate(); + +protected: + std::pair + GetEHAndDWARFNums(llvm::StringRef name) override; + + std::string GetMCName(std::string reg) override { + MapRegisterName(reg, "v", "q"); + return reg; + } + + uint32_t GetGenericNum(llvm::StringRef name) override; + + using lldb_private::MCBasedABI::MCBasedABI; +}; +#endif diff --git a/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp b/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp new file mode 100644 index 00000000000..983da26a2a6 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp @@ -0,0 +1,831 @@ +//===-- ABIMacOSX_arm64.cpp -----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABIMacOSX_arm64.h" + +#include + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Triple.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Target.h" +#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" + +using namespace lldb; +using namespace lldb_private; + +static const char *pluginDesc = "Mac OS X ABI for arm64 targets"; + +size_t ABIMacOSX_arm64::GetRedZoneSize() const { return 128; } + +// Static Functions + +ABISP +ABIMacOSX_arm64::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) { + 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 || + arch_type == llvm::Triple::aarch64_32) { + return ABISP( + new ABIMacOSX_arm64(std::move(process_sp), MakeMCRegisterInfo(arch))); + } + } + + return ABISP(); +} + +bool ABIMacOSX_arm64::PrepareTrivialCall( + Thread &thread, lldb::addr_t sp, lldb::addr_t func_addr, + lldb::addr_t return_addr, llvm::ArrayRef args) const { + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return false; + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (log) { + StreamString s; + s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64 + ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 + ", return_addr = 0x%" PRIx64, + thread.GetID(), (uint64_t)sp, (uint64_t)func_addr, + (uint64_t)return_addr); + + for (size_t i = 0; i < args.size(); ++i) + s.Printf(", arg%d = 0x%" PRIx64, static_cast(i + 1), args[i]); + s.PutCString(")"); + log->PutString(s.GetString()); + } + + const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); + const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); + + // x0 - x7 contain first 8 simple args + if (args.size() > 8) // TODO handle more than 6 arguments + return false; + + for (size_t i = 0; i < args.size(); ++i) { + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i); + LLDB_LOGF(log, "About to write arg%d (0x%" PRIx64 ") into %s", + static_cast(i + 1), args[i], reg_info->name); + if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) + return false; + } + + // Set "lr" to the return address + if (!reg_ctx->WriteRegisterFromUnsigned( + reg_ctx->GetRegisterInfoAtIndex(ra_reg_num), return_addr)) + return false; + + // Set "sp" to the requested value + if (!reg_ctx->WriteRegisterFromUnsigned( + reg_ctx->GetRegisterInfoAtIndex(sp_reg_num), sp)) + return false; + + // Set "pc" to the address requested + if (!reg_ctx->WriteRegisterFromUnsigned( + reg_ctx->GetRegisterInfoAtIndex(pc_reg_num), func_addr)) + return false; + + return true; +} + +bool ABIMacOSX_arm64::GetArgumentValues(Thread &thread, + ValueList &values) const { + uint32_t num_values = values.GetSize(); + + ExecutionContext exe_ctx(thread.shared_from_this()); + + // Extract the register context so we can read arguments from registers + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + + if (!reg_ctx) + return false; + + addr_t sp = 0; + + for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) { + // We currently only support extracting values with Clang QualTypes. Do we + // care about others? + Value *value = values.GetValueAtIndex(value_idx); + + if (!value) + return false; + + CompilerType value_type = value->GetCompilerType(); + llvm::Optional bit_size = value_type.GetBitSize(&thread); + if (!bit_size) + return false; + + 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 (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; + } + } + + 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; + } 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; + } + + // 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; + } + } + } + } + return true; +} + +Status +ABIMacOSX_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value_sp) { + Status error; + if (!new_value_sp) { + error.SetErrorString("Empty value object for return value."); + return error; + } + + CompilerType return_value_type = new_value_sp->GetCompilerType(); + if (!return_value_type) { + error.SetErrorString("Null clang type for return value."); + return error; + } + + Thread *thread = frame_sp->GetThread().get(); + + RegisterContext *reg_ctx = thread->GetRegisterContext().get(); + + if (reg_ctx) { + DataExtractor data; + Status data_error; + const uint64_t byte_size = new_value_sp->GetData(data, data_error); + if (data_error.Fail()) { + error.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", + data_error.AsCString()); + return error; + } + + const uint32_t type_flags = return_value_type.GetTypeInfo(nullptr); + if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) { + if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) { + // Extract the register context so we can read arguments from registers + lldb::offset_t offset = 0; + if (byte_size <= 16) { + const RegisterInfo *x0_info = reg_ctx->GetRegisterInfoByName("x0", 0); + if (byte_size <= 8) { + uint64_t raw_value = data.GetMaxU64(&offset, byte_size); + + if (!reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value)) + error.SetErrorString("failed to write register x0"); + } else { + uint64_t raw_value = data.GetMaxU64(&offset, 8); + + if (reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value)) { + const RegisterInfo *x1_info = + reg_ctx->GetRegisterInfoByName("x1", 0); + raw_value = data.GetMaxU64(&offset, byte_size - offset); + + if (!reg_ctx->WriteRegisterFromUnsigned(x1_info, raw_value)) + error.SetErrorString("failed to write register x1"); + } + } + } else { + error.SetErrorString("We don't support returning longer than 128 bit " + "integer values at present."); + } + } else if (type_flags & eTypeIsFloat) { + if (type_flags & eTypeIsComplex) { + // Don't handle complex yet. + error.SetErrorString( + "returning complex float values are not supported"); + } else { + const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0); + + if (v0_info) { + if (byte_size <= 16) { + if (byte_size <= RegisterValue::GetMaxByteSize()) { + RegisterValue reg_value; + error = reg_value.SetValueFromData(v0_info, data, 0, true); + if (error.Success()) { + if (!reg_ctx->WriteRegister(v0_info, reg_value)) + error.SetErrorString("failed to write register v0"); + } + } else { + error.SetErrorStringWithFormat( + "returning float values with a byte size of %" PRIu64 + " are not supported", + byte_size); + } + } else { + error.SetErrorString("returning float values longer than 128 " + "bits are not supported"); + } + } else { + error.SetErrorString("v0 register is not available on this target"); + } + } + } + } else if (type_flags & eTypeIsVector) { + if (byte_size > 0) { + const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0); + + if (v0_info) { + if (byte_size <= v0_info->byte_size) { + RegisterValue reg_value; + error = reg_value.SetValueFromData(v0_info, data, 0, true); + if (error.Success()) { + if (!reg_ctx->WriteRegister(v0_info, reg_value)) + error.SetErrorString("failed to write register v0"); + } + } + } + } + } + } else { + error.SetErrorString("no registers are available"); + } + + return error; +} + +bool ABIMacOSX_arm64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t lr_reg_num = arm64_dwarf::lr; + uint32_t sp_reg_num = arm64_dwarf::sp; + uint32_t pc_reg_num = arm64_dwarf::pc; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + + // Our previous Call Frame Address is the stack pointer + row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0); + + // Our previous PC is in the LR + row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true); + + unwind_plan.AppendRow(row); + + // All other registers are the same. + + unwind_plan.SetSourceName("arm64 at-func-entry default"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + + return true; +} + +bool ABIMacOSX_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t fp_reg_num = arm64_dwarf::fp; + uint32_t pc_reg_num = arm64_dwarf::pc; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + const int32_t ptr_size = 8; + + row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size); + row->SetOffset(0); + + row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); + row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); + + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("arm64-apple-darwin default unwind plan"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); + return true; +} + +// AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says +// registers x19 through x28 and sp are callee preserved. v8-v15 are non- +// volatile (and specifically only the lower 8 bytes of these regs), the rest +// of the fp/SIMD registers are volatile. +// +// v. https://github.com/ARM-software/abi-aa/blob/master/aapcs64/ + +// We treat x29 as callee preserved also, else the unwinder won't try to +// retrieve fp saves. + +bool ABIMacOSX_arm64::RegisterIsVolatile(const RegisterInfo *reg_info) { + if (reg_info) { + const char *name = reg_info->name; + + // Sometimes we'll be called with the "alternate" name for these registers; + // recognize them as non-volatile. + + if (name[0] == 'p' && name[1] == 'c') // pc + return false; + if (name[0] == 'f' && name[1] == 'p') // fp + return false; + if (name[0] == 's' && name[1] == 'p') // sp + return false; + if (name[0] == 'l' && name[1] == 'r') // lr + return false; + + if (name[0] == 'x') { + // Volatile registers: x0-x18, x30 (lr) + // Return false for the non-volatile gpr regs, true for everything else + switch (name[1]) { + case '1': + switch (name[2]) { + case '9': + return false; // x19 is non-volatile + default: + return true; + } + break; + case '2': + switch (name[2]) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + return false; // x20 - 28 are non-volatile + case '9': + return false; // x29 aka fp treat as non-volatile on Darwin + default: + return true; + } + case '3': // x30 aka lr treat as non-volatile + if (name[2] == '0') + return false; + break; + default: + return true; + } + } else if (name[0] == 'v' || name[0] == 's' || name[0] == 'd') { + // Volatile registers: v0-7, v16-v31 + // Return false for non-volatile fp/SIMD regs, true for everything else + switch (name[1]) { + case '8': + case '9': + return false; // v8-v9 are non-volatile + case '1': + switch (name[2]) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + return false; // v10-v15 are non-volatile + default: + return true; + } + default: + return true; + } + } + } + return true; +} + +static bool LoadValueFromConsecutiveGPRRegisters( + ExecutionContext &exe_ctx, RegisterContext *reg_ctx, + const CompilerType &value_type, + bool is_return_value, // false => parameter, true => return value + uint32_t &NGRN, // NGRN (see ABI documentation) + uint32_t &NSRN, // NSRN (see ABI documentation) + DataExtractor &data) { + llvm::Optional byte_size = value_type.GetByteSize(nullptr); + if (!byte_size || *byte_size == 0) + return false; + + std::unique_ptr heap_data_up( + new DataBufferHeap(*byte_size, 0)); + const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder(); + Status error; + + CompilerType base_type; + const uint32_t homogeneous_count = + value_type.IsHomogeneousAggregate(&base_type); + if (homogeneous_count > 0 && homogeneous_count <= 8) { + // Make sure we have enough registers + if (NSRN < 8 && (8 - NSRN) >= homogeneous_count) { + if (!base_type) + return false; + 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) { + char v_name[8]; + ::snprintf(v_name, sizeof(v_name), "v%u", NSRN); + const RegisterInfo *reg_info = + reg_ctx->GetRegisterInfoByName(v_name, 0); + if (reg_info == nullptr) + return false; + + if (*base_byte_size > reg_info->byte_size) + return false; + + RegisterValue reg_value; + + if (!reg_ctx->ReadRegister(reg_info, reg_value)) + return false; + + // Make sure we have enough room in "heap_data_up" + if ((data_offset + *base_byte_size) <= heap_data_up->GetByteSize()) { + const size_t bytes_copied = reg_value.GetAsMemoryData( + reg_info, heap_data_up->GetBytes() + data_offset, *base_byte_size, + byte_order, error); + if (bytes_copied != *base_byte_size) + return false; + data_offset += bytes_copied; + ++NSRN; + } else + return false; + } + data.SetByteOrder(byte_order); + data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize()); + data.SetData(DataBufferSP(heap_data_up.release())); + return true; + } + } + + const size_t max_reg_byte_size = 16; + if (*byte_size <= max_reg_byte_size) { + size_t bytes_left = *byte_size; + uint32_t data_offset = 0; + while (data_offset < *byte_size) { + if (NGRN >= 8) + return false; + + uint32_t reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN); + if (reg_num == LLDB_INVALID_REGNUM) + return false; + + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num); + if (reg_info == nullptr) + return false; + + RegisterValue reg_value; + + if (!reg_ctx->ReadRegister(reg_info, reg_value)) + return false; + + const size_t curr_byte_size = std::min(8, bytes_left); + const size_t bytes_copied = reg_value.GetAsMemoryData( + reg_info, heap_data_up->GetBytes() + data_offset, curr_byte_size, + byte_order, error); + if (bytes_copied == 0) + return false; + if (bytes_copied >= bytes_left) + break; + data_offset += bytes_copied; + bytes_left -= bytes_copied; + ++NGRN; + } + } else { + const RegisterInfo *reg_info = nullptr; + if (is_return_value) { + // We are assuming we are decoding this immediately after returning from + // a function call and that the address of the structure is in x8 + reg_info = reg_ctx->GetRegisterInfoByName("x8", 0); + } else { + // We are assuming we are stopped at the first instruction in a function + // and that the ABI is being respected so all parameters appear where + // they should be (functions with no external linkage can legally violate + // the ABI). + if (NGRN >= 8) + return false; + + uint32_t reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN); + if (reg_num == LLDB_INVALID_REGNUM) + return false; + reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num); + if (reg_info == nullptr) + return false; + ++NGRN; + } + + if (reg_info == nullptr) + return false; + + const lldb::addr_t value_addr = + reg_ctx->ReadRegisterAsUnsigned(reg_info, LLDB_INVALID_ADDRESS); + + if (value_addr == LLDB_INVALID_ADDRESS) + return false; + + if (exe_ctx.GetProcessRef().ReadMemory( + value_addr, heap_data_up->GetBytes(), heap_data_up->GetByteSize(), + error) != heap_data_up->GetByteSize()) { + return false; + } + } + + data.SetByteOrder(byte_order); + data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize()); + data.SetData(DataBufferSP(heap_data_up.release())); + return true; +} + +ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + Value value; + + ExecutionContext exe_ctx(thread.shared_from_this()); + if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr) + return return_valobj_sp; + + // value.SetContext (Value::eContextTypeClangType, return_compiler_type); + value.SetCompilerType(return_compiler_type); + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return return_valobj_sp; + + 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) { + value.SetValueType(Value::eValueTypeScalar); + + 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) { + const RegisterInfo *x0_reg_info = + reg_ctx->GetRegisterInfoByName("x0", 0); + if (x0_reg_info) { + uint64_t raw_value = + thread.GetRegisterContext()->ReadRegisterAsUnsigned(x0_reg_info, + 0); + const bool is_signed = (type_flags & eTypeIsSigned) != 0; + switch (*byte_size) { + default: + break; + case 16: // uint128_t + // In register x0 and x1 + { + const RegisterInfo *x1_reg_info = + reg_ctx->GetRegisterInfoByName("x1", 0); + + if (x1_reg_info) { + if (*byte_size <= + x0_reg_info->byte_size + x1_reg_info->byte_size) { + std::unique_ptr heap_data_up( + new DataBufferHeap(*byte_size, 0)); + const ByteOrder byte_order = + exe_ctx.GetProcessRef().GetByteOrder(); + RegisterValue x0_reg_value; + RegisterValue x1_reg_value; + if (reg_ctx->ReadRegister(x0_reg_info, x0_reg_value) && + reg_ctx->ReadRegister(x1_reg_info, x1_reg_value)) { + Status error; + if (x0_reg_value.GetAsMemoryData( + x0_reg_info, heap_data_up->GetBytes() + 0, 8, + byte_order, error) && + x1_reg_value.GetAsMemoryData( + x1_reg_info, heap_data_up->GetBytes() + 8, 8, + byte_order, error)) { + DataExtractor data( + DataBufferSP(heap_data_up.release()), byte_order, + exe_ctx.GetProcessRef().GetAddressByteSize()); + + return_valobj_sp = ValueObjectConstResult::Create( + &thread, return_compiler_type, ConstString(""), data); + return return_valobj_sp; + } + } + } + } + } + break; + case sizeof(uint64_t): + if (is_signed) + value.GetScalar() = (int64_t)(raw_value); + else + value.GetScalar() = (uint64_t)(raw_value); + success = true; + break; + + case sizeof(uint32_t): + if (is_signed) + value.GetScalar() = (int32_t)(raw_value & UINT32_MAX); + else + value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX); + success = true; + break; + + case sizeof(uint16_t): + if (is_signed) + value.GetScalar() = (int16_t)(raw_value & UINT16_MAX); + else + value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX); + success = true; + break; + + case sizeof(uint8_t): + if (is_signed) + value.GetScalar() = (int8_t)(raw_value & UINT8_MAX); + else + value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX); + success = true; + break; + } + } + } + } else if (type_flags & eTypeIsFloat) { + if (type_flags & eTypeIsComplex) { + // Don't handle complex yet. + } else { + if (*byte_size <= sizeof(long double)) { + const RegisterInfo *v0_reg_info = + reg_ctx->GetRegisterInfoByName("v0", 0); + RegisterValue v0_value; + if (reg_ctx->ReadRegister(v0_reg_info, v0_value)) { + DataExtractor data; + if (v0_value.GetData(data)) { + lldb::offset_t offset = 0; + if (*byte_size == sizeof(float)) { + value.GetScalar() = data.GetFloat(&offset); + success = true; + } else if (*byte_size == sizeof(double)) { + value.GetScalar() = data.GetDouble(&offset); + success = true; + } else if (*byte_size == sizeof(long double)) { + value.GetScalar() = data.GetLongDouble(&offset); + success = true; + } + } + } + } + } + } + + if (success) + return_valobj_sp = ValueObjectConstResult::Create( + thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); + } else if (type_flags & eTypeIsVector) { + if (*byte_size > 0) { + + const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0); + + if (v0_info) { + if (*byte_size <= v0_info->byte_size) { + std::unique_ptr heap_data_up( + new DataBufferHeap(*byte_size, 0)); + const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder(); + RegisterValue reg_value; + if (reg_ctx->ReadRegister(v0_info, reg_value)) { + Status error; + if (reg_value.GetAsMemoryData(v0_info, heap_data_up->GetBytes(), + heap_data_up->GetByteSize(), + byte_order, error)) { + DataExtractor data(DataBufferSP(heap_data_up.release()), + byte_order, + exe_ctx.GetProcessRef().GetAddressByteSize()); + return_valobj_sp = ValueObjectConstResult::Create( + &thread, return_compiler_type, ConstString(""), data); + } + } + } + } + } + } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass) { + DataExtractor data; + + uint32_t NGRN = 0; // Search ABI docs for NGRN + uint32_t NSRN = 0; // Search ABI docs for NSRN + const bool is_return_value = true; + if (LoadValueFromConsecutiveGPRRegisters( + exe_ctx, reg_ctx, return_compiler_type, is_return_value, NGRN, NSRN, + data)) { + return_valobj_sp = ValueObjectConstResult::Create( + &thread, return_compiler_type, ConstString(""), data); + } + } + return return_valobj_sp; +} + +void ABIMacOSX_arm64::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), pluginDesc, + CreateInstance); +} + +void ABIMacOSX_arm64::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +// PluginInterface protocol + +ConstString ABIMacOSX_arm64::GetPluginNameStatic() { + static ConstString g_plugin_name("ABIMacOSX_arm64"); + return g_plugin_name; +} + +uint32_t ABIMacOSX_arm64::GetPluginVersion() { return 1; } diff --git a/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h b/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h new file mode 100644 index 00000000000..fc8ccee92e7 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h @@ -0,0 +1,96 @@ +//===-- ABIMacOSX_arm64.h ---------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_AARCH64_ABIMACOSX_ARM64_H +#define LLDB_SOURCE_PLUGINS_ABI_AARCH64_ABIMACOSX_ARM64_H + +#include "Plugins/ABI/AArch64/ABIAArch64.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/lldb-private.h" + +class ABIMacOSX_arm64 : public ABIAArch64 { +public: + ~ABIMacOSX_arm64() override = default; + + size_t GetRedZoneSize() const override; + + bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t functionAddress, + lldb::addr_t returnAddress, + llvm::ArrayRef args) const override; + + bool GetArgumentValues(lldb_private::Thread &thread, + lldb_private::ValueList &values) const override; + + bool + CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override; + + // The arm64 ABI requires that stack frames be 16 byte aligned. + // When there is a trap handler on the stack, e.g. _sigtramp in userland + // code, we've seen that the stack pointer is often not aligned properly + // before the handler is invoked. This means that lldb will stop the unwind + // early -- before the function which caused the trap. + // + // To work around this, we relax that alignment to be just word-size + // (8-bytes). + // Allowing the trap handlers for user space would be easy (_sigtramp) but + // in other environments there can be a large number of different functions + // involved in async traps. + bool CallFrameAddressIsValid(lldb::addr_t cfa) override { + // Make sure the stack call frame addresses are are 8 byte aligned + if (cfa & (8ull - 1ull)) + return false; // Not 8 byte aligned + if (cfa == 0) + return false; // Zero is not a valid stack address + return true; + } + + bool CodeAddressIsValid(lldb::addr_t pc) override { + if (pc & (4ull - 1ull)) + return false; // Not 4 byte aligned + + // Anything else if fair game.. + return true; + } + + // Static Functions + + static void Initialize(); + + static void Terminate(); + + static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); + + // PluginInterface protocol + + static lldb_private::ConstString GetPluginNameStatic(); + + lldb_private::ConstString GetPluginName() override { + return GetPluginNameStatic(); + } + + uint32_t GetPluginVersion() override; + + lldb_private::Status + SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value) override; + +protected: + lldb::ValueObjectSP + GetReturnValueObjectImpl(lldb_private::Thread &thread, + lldb_private::CompilerType &ast_type) const override; + +private: + using ABIAArch64::ABIAArch64; // Call CreateInstance instead. +}; + +#endif // LLDB_SOURCE_PLUGINS_ABI_AARCH64_ABIMACOSX_ARM64_H diff --git a/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp b/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp new file mode 100644 index 00000000000..831c8aa0d76 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp @@ -0,0 +1,800 @@ +//===-- ABISysV_arm64.cpp -------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABISysV_arm64.h" + +#include + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Triple.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Target.h" +#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" + +using namespace lldb; +using namespace lldb_private; + +bool ABISysV_arm64::GetPointerReturnRegister(const char *&name) { + name = "x0"; + return true; +} + +size_t ABISysV_arm64::GetRedZoneSize() const { return 128; } + +// Static Functions + +ABISP +ABISysV_arm64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { + 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 || + arch_type == llvm::Triple::aarch64_32) { + return ABISP( + new ABISysV_arm64(std::move(process_sp), MakeMCRegisterInfo(arch))); + } + } + + return ABISP(); +} + +bool ABISysV_arm64::PrepareTrivialCall(Thread &thread, addr_t sp, + addr_t func_addr, addr_t return_addr, + llvm::ArrayRef args) const { + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return false; + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (log) { + StreamString s; + s.Printf("ABISysV_arm64::PrepareTrivialCall (tid = 0x%" PRIx64 + ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 + ", return_addr = 0x%" PRIx64, + thread.GetID(), (uint64_t)sp, (uint64_t)func_addr, + (uint64_t)return_addr); + + for (size_t i = 0; i < args.size(); ++i) + s.Printf(", arg%d = 0x%" PRIx64, static_cast(i + 1), args[i]); + s.PutCString(")"); + log->PutString(s.GetString()); + } + + // x0 - x7 contain first 8 simple args + if (args.size() > 8) + return false; + + for (size_t i = 0; i < args.size(); ++i) { + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i); + LLDB_LOGF(log, "About to write arg%d (0x%" PRIx64 ") into %s", + static_cast(i + 1), args[i], reg_info->name); + if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) + return false; + } + + // Set "lr" to the return address + if (!reg_ctx->WriteRegisterFromUnsigned( + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_RA), + return_addr)) + return false; + + // Set "sp" to the requested value + if (!reg_ctx->WriteRegisterFromUnsigned( + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_SP), + sp)) + return false; + + // Set "pc" to the address requested + if (!reg_ctx->WriteRegisterFromUnsigned( + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_PC), + func_addr)) + return false; + + return true; +} + +// TODO: We dont support fp/SIMD arguments in v0-v7 +bool ABISysV_arm64::GetArgumentValues(Thread &thread, ValueList &values) const { + uint32_t num_values = values.GetSize(); + + ExecutionContext exe_ctx(thread.shared_from_this()); + + // Extract the register context so we can read arguments from registers + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + + if (!reg_ctx) + return false; + + addr_t sp = 0; + + for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) { + // We currently only support extracting values with Clang QualTypes. Do we + // care about others? + Value *value = values.GetValueAtIndex(value_idx); + + if (!value) + return false; + + CompilerType value_type = value->GetCompilerType(); + 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 = *bit_size; + } else if (value_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 < 8) { + // Arguments 1-8 are in x0-x7... + const RegisterInfo *reg_info = nullptr; + reg_info = reg_ctx->GetRegisterInfo( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx); + + 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; + } else { + // TODO: Verify for stack layout for SysV + if (sp == 0) { + // Read the stack pointer if we already haven't read it + sp = reg_ctx->GetSP(0); + if (sp == 0) + return false; + } + + // 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; + } + } + } + } + } + return true; +} + +Status ABISysV_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value_sp) { + Status error; + if (!new_value_sp) { + error.SetErrorString("Empty value object for return value."); + return error; + } + + CompilerType return_value_type = new_value_sp->GetCompilerType(); + if (!return_value_type) { + error.SetErrorString("Null clang type for return value."); + return error; + } + + Thread *thread = frame_sp->GetThread().get(); + + RegisterContext *reg_ctx = thread->GetRegisterContext().get(); + + if (reg_ctx) { + DataExtractor data; + Status data_error; + const uint64_t byte_size = new_value_sp->GetData(data, data_error); + if (data_error.Fail()) { + error.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", + data_error.AsCString()); + return error; + } + + const uint32_t type_flags = return_value_type.GetTypeInfo(nullptr); + if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) { + if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) { + // Extract the register context so we can read arguments from registers + lldb::offset_t offset = 0; + if (byte_size <= 16) { + const RegisterInfo *x0_info = reg_ctx->GetRegisterInfo( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); + if (byte_size <= 8) { + uint64_t raw_value = data.GetMaxU64(&offset, byte_size); + + if (!reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value)) + error.SetErrorString("failed to write register x0"); + } else { + uint64_t raw_value = data.GetMaxU64(&offset, 8); + + if (reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value)) { + const RegisterInfo *x1_info = reg_ctx->GetRegisterInfo( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2); + raw_value = data.GetMaxU64(&offset, byte_size - offset); + + if (!reg_ctx->WriteRegisterFromUnsigned(x1_info, raw_value)) + error.SetErrorString("failed to write register x1"); + } + } + } else { + error.SetErrorString("We don't support returning longer than 128 bit " + "integer values at present."); + } + } else if (type_flags & eTypeIsFloat) { + if (type_flags & eTypeIsComplex) { + // Don't handle complex yet. + error.SetErrorString( + "returning complex float values are not supported"); + } else { + const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0); + + if (v0_info) { + if (byte_size <= 16) { + if (byte_size <= RegisterValue::GetMaxByteSize()) { + RegisterValue reg_value; + error = reg_value.SetValueFromData(v0_info, data, 0, true); + if (error.Success()) { + if (!reg_ctx->WriteRegister(v0_info, reg_value)) + error.SetErrorString("failed to write register v0"); + } + } else { + error.SetErrorStringWithFormat( + "returning float values with a byte size of %" PRIu64 + " are not supported", + byte_size); + } + } else { + error.SetErrorString("returning float values longer than 128 " + "bits are not supported"); + } + } else { + error.SetErrorString("v0 register is not available on this target"); + } + } + } + } else if (type_flags & eTypeIsVector) { + if (byte_size > 0) { + const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0); + + if (v0_info) { + if (byte_size <= v0_info->byte_size) { + RegisterValue reg_value; + error = reg_value.SetValueFromData(v0_info, data, 0, true); + if (error.Success()) { + if (!reg_ctx->WriteRegister(v0_info, reg_value)) + error.SetErrorString("failed to write register v0"); + } + } + } + } + } + } else { + error.SetErrorString("no registers are available"); + } + + return error; +} + +bool ABISysV_arm64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t lr_reg_num = arm64_dwarf::lr; + uint32_t sp_reg_num = arm64_dwarf::sp; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + + // Our previous Call Frame Address is the stack pointer + row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0); + + unwind_plan.AppendRow(row); + unwind_plan.SetReturnAddressRegister(lr_reg_num); + + // All other registers are the same. + + unwind_plan.SetSourceName("arm64 at-func-entry default"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); + + return true; +} + +bool ABISysV_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t fp_reg_num = arm64_dwarf::fp; + uint32_t pc_reg_num = arm64_dwarf::pc; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + const int32_t ptr_size = 8; + + row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size); + row->SetOffset(0); + + row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); + row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); + + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("arm64 default unwind plan"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); + + return true; +} + +// AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says +// registers x19 through x28 and sp are callee preserved. v8-v15 are non- +// volatile (and specifically only the lower 8 bytes of these regs), the rest +// of the fp/SIMD registers are volatile. + +// We treat x29 as callee preserved also, else the unwinder won't try to +// retrieve fp saves. + +bool ABISysV_arm64::RegisterIsVolatile(const RegisterInfo *reg_info) { + if (reg_info) { + const char *name = reg_info->name; + + // Sometimes we'll be called with the "alternate" name for these registers; + // recognize them as non-volatile. + + if (name[0] == 'p' && name[1] == 'c') // pc + return false; + if (name[0] == 'f' && name[1] == 'p') // fp + return false; + if (name[0] == 's' && name[1] == 'p') // sp + return false; + if (name[0] == 'l' && name[1] == 'r') // lr + return false; + + if (name[0] == 'x' || name[0] == 'r') { + // Volatile registers: x0-x18 + // Although documentation says only x19-28 + sp are callee saved We ll + // also have to treat x30 as non-volatile. Each dwarf frame has its own + // value of lr. Return false for the non-volatile gpr regs, true for + // everything else + switch (name[1]) { + case '1': + switch (name[2]) { + case '9': + return false; // x19 is non-volatile + default: + return true; + } + break; + case '2': + switch (name[2]) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + return false; // x20 - 28 are non-volatile + case '9': + return false; // x29 aka fp treat as non-volatile + default: + return true; + } + case '3': // x30 (lr) and x31 (sp) treat as non-volatile + if (name[2] == '0' || name[2] == '1') + return false; + break; + default: + return true; // all volatile cases not handled above fall here. + } + } else if (name[0] == 'v' || name[0] == 's' || name[0] == 'd') { + // Volatile registers: v0-7, v16-v31 + // Return false for non-volatile fp/SIMD regs, true for everything else + switch (name[1]) { + case '8': + case '9': + return false; // v8-v9 are non-volatile + case '1': + switch (name[2]) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + return false; // v10-v15 are non-volatile + default: + return true; + } + default: + return true; + } + } + } + return true; +} + +static bool LoadValueFromConsecutiveGPRRegisters( + ExecutionContext &exe_ctx, RegisterContext *reg_ctx, + const CompilerType &value_type, + bool is_return_value, // false => parameter, true => return value + uint32_t &NGRN, // NGRN (see ABI documentation) + uint32_t &NSRN, // NSRN (see ABI documentation) + DataExtractor &data) { + llvm::Optional byte_size = value_type.GetByteSize(nullptr); + + if (byte_size || *byte_size == 0) + return false; + + std::unique_ptr heap_data_up( + new DataBufferHeap(*byte_size, 0)); + const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder(); + Status error; + + CompilerType base_type; + const uint32_t homogeneous_count = + value_type.IsHomogeneousAggregate(&base_type); + if (homogeneous_count > 0 && homogeneous_count <= 8) { + // Make sure we have enough registers + if (NSRN < 8 && (8 - NSRN) >= homogeneous_count) { + if (!base_type) + return false; + 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) { + char v_name[8]; + ::snprintf(v_name, sizeof(v_name), "v%u", NSRN); + const RegisterInfo *reg_info = + reg_ctx->GetRegisterInfoByName(v_name, 0); + if (reg_info == nullptr) + return false; + + if (*base_byte_size > reg_info->byte_size) + return false; + + RegisterValue reg_value; + + if (!reg_ctx->ReadRegister(reg_info, reg_value)) + return false; + + // Make sure we have enough room in "heap_data_up" + if ((data_offset + *base_byte_size) <= heap_data_up->GetByteSize()) { + const size_t bytes_copied = reg_value.GetAsMemoryData( + reg_info, heap_data_up->GetBytes() + data_offset, *base_byte_size, + byte_order, error); + if (bytes_copied != *base_byte_size) + return false; + data_offset += bytes_copied; + ++NSRN; + } else + return false; + } + data.SetByteOrder(byte_order); + data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize()); + data.SetData(DataBufferSP(heap_data_up.release())); + return true; + } + } + + const size_t max_reg_byte_size = 16; + if (*byte_size <= max_reg_byte_size) { + size_t bytes_left = *byte_size; + uint32_t data_offset = 0; + while (data_offset < *byte_size) { + if (NGRN >= 8) + return false; + + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN); + if (reg_info == nullptr) + return false; + + RegisterValue reg_value; + + if (!reg_ctx->ReadRegister(reg_info, reg_value)) + return false; + + const size_t curr_byte_size = std::min(8, bytes_left); + const size_t bytes_copied = reg_value.GetAsMemoryData( + reg_info, heap_data_up->GetBytes() + data_offset, curr_byte_size, + byte_order, error); + if (bytes_copied == 0) + return false; + if (bytes_copied >= bytes_left) + break; + data_offset += bytes_copied; + bytes_left -= bytes_copied; + ++NGRN; + } + } else { + const RegisterInfo *reg_info = nullptr; + if (is_return_value) { + // We are assuming we are decoding this immediately after returning from + // a function call and that the address of the structure is in x8 + reg_info = reg_ctx->GetRegisterInfoByName("x8", 0); + } else { + // We are assuming we are stopped at the first instruction in a function + // and that the ABI is being respected so all parameters appear where + // they should be (functions with no external linkage can legally violate + // the ABI). + if (NGRN >= 8) + return false; + + reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_ARG1 + NGRN); + if (reg_info == nullptr) + return false; + ++NGRN; + } + + if (reg_info == nullptr) + return false; + + const lldb::addr_t value_addr = + reg_ctx->ReadRegisterAsUnsigned(reg_info, LLDB_INVALID_ADDRESS); + + if (value_addr == LLDB_INVALID_ADDRESS) + return false; + + if (exe_ctx.GetProcessRef().ReadMemory( + value_addr, heap_data_up->GetBytes(), heap_data_up->GetByteSize(), + error) != heap_data_up->GetByteSize()) { + return false; + } + } + + data.SetByteOrder(byte_order); + data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize()); + data.SetData(DataBufferSP(heap_data_up.release())); + return true; +} + +ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + Value value; + + ExecutionContext exe_ctx(thread.shared_from_this()); + if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr) + return return_valobj_sp; + + // value.SetContext (Value::eContextTypeClangType, return_compiler_type); + value.SetCompilerType(return_compiler_type); + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return return_valobj_sp; + + 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) { + value.SetValueType(Value::eValueTypeScalar); + + 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) { + const RegisterInfo *x0_reg_info = nullptr; + x0_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_ARG1); + if (x0_reg_info) { + uint64_t raw_value = + thread.GetRegisterContext()->ReadRegisterAsUnsigned(x0_reg_info, + 0); + const bool is_signed = (type_flags & eTypeIsSigned) != 0; + switch (*byte_size) { + default: + break; + case 16: // uint128_t + // In register x0 and x1 + { + const RegisterInfo *x1_reg_info = nullptr; + x1_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_ARG2); + + if (x1_reg_info) { + if (*byte_size <= + x0_reg_info->byte_size + x1_reg_info->byte_size) { + std::unique_ptr heap_data_up( + new DataBufferHeap(*byte_size, 0)); + const ByteOrder byte_order = + exe_ctx.GetProcessRef().GetByteOrder(); + RegisterValue x0_reg_value; + RegisterValue x1_reg_value; + if (reg_ctx->ReadRegister(x0_reg_info, x0_reg_value) && + reg_ctx->ReadRegister(x1_reg_info, x1_reg_value)) { + Status error; + if (x0_reg_value.GetAsMemoryData( + x0_reg_info, heap_data_up->GetBytes() + 0, 8, + byte_order, error) && + x1_reg_value.GetAsMemoryData( + x1_reg_info, heap_data_up->GetBytes() + 8, 8, + byte_order, error)) { + DataExtractor data( + DataBufferSP(heap_data_up.release()), byte_order, + exe_ctx.GetProcessRef().GetAddressByteSize()); + + return_valobj_sp = ValueObjectConstResult::Create( + &thread, return_compiler_type, ConstString(""), data); + return return_valobj_sp; + } + } + } + } + } + break; + case sizeof(uint64_t): + if (is_signed) + value.GetScalar() = (int64_t)(raw_value); + else + value.GetScalar() = (uint64_t)(raw_value); + success = true; + break; + + case sizeof(uint32_t): + if (is_signed) + value.GetScalar() = (int32_t)(raw_value & UINT32_MAX); + else + value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX); + success = true; + break; + + case sizeof(uint16_t): + if (is_signed) + value.GetScalar() = (int16_t)(raw_value & UINT16_MAX); + else + value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX); + success = true; + break; + + case sizeof(uint8_t): + if (is_signed) + value.GetScalar() = (int8_t)(raw_value & UINT8_MAX); + else + value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX); + success = true; + break; + } + } + } + } else if (type_flags & eTypeIsFloat) { + if (type_flags & eTypeIsComplex) { + // Don't handle complex yet. + } else { + if (*byte_size <= sizeof(long double)) { + const RegisterInfo *v0_reg_info = + reg_ctx->GetRegisterInfoByName("v0", 0); + RegisterValue v0_value; + if (reg_ctx->ReadRegister(v0_reg_info, v0_value)) { + DataExtractor data; + if (v0_value.GetData(data)) { + lldb::offset_t offset = 0; + if (*byte_size == sizeof(float)) { + value.GetScalar() = data.GetFloat(&offset); + success = true; + } else if (*byte_size == sizeof(double)) { + value.GetScalar() = data.GetDouble(&offset); + success = true; + } else if (*byte_size == sizeof(long double)) { + value.GetScalar() = data.GetLongDouble(&offset); + success = true; + } + } + } + } + } + } + + 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) { + const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0); + + if (v0_info) { + std::unique_ptr heap_data_up( + new DataBufferHeap(*byte_size, 0)); + const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder(); + RegisterValue reg_value; + if (reg_ctx->ReadRegister(v0_info, reg_value)) { + Status error; + if (reg_value.GetAsMemoryData(v0_info, heap_data_up->GetBytes(), + heap_data_up->GetByteSize(), byte_order, + error)) { + DataExtractor data(DataBufferSP(heap_data_up.release()), byte_order, + exe_ctx.GetProcessRef().GetAddressByteSize()); + return_valobj_sp = ValueObjectConstResult::Create( + &thread, return_compiler_type, ConstString(""), data); + } + } + } + } + } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass || + (type_flags & eTypeIsVector && *byte_size > 16)) { + DataExtractor data; + + uint32_t NGRN = 0; // Search ABI docs for NGRN + uint32_t NSRN = 0; // Search ABI docs for NSRN + const bool is_return_value = true; + if (LoadValueFromConsecutiveGPRRegisters( + exe_ctx, reg_ctx, return_compiler_type, is_return_value, NGRN, NSRN, + data)) { + return_valobj_sp = ValueObjectConstResult::Create( + &thread, return_compiler_type, ConstString(""), data); + } + } + return return_valobj_sp; +} + +void ABISysV_arm64::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + "SysV ABI for AArch64 targets", CreateInstance); +} + +void ABISysV_arm64::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString ABISysV_arm64::GetPluginNameStatic() { + static ConstString g_name("SysV-arm64"); + return g_name; +} + +// PluginInterface protocol + +ConstString ABISysV_arm64::GetPluginName() { return GetPluginNameStatic(); } + +uint32_t ABISysV_arm64::GetPluginVersion() { return 1; } diff --git a/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h b/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h new file mode 100644 index 00000000000..aeb74acc38b --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h @@ -0,0 +1,95 @@ +//===-- ABISysV_arm64.h ---------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_AARCH64_ABISYSV_ARM64_H +#define LLDB_SOURCE_PLUGINS_ABI_AARCH64_ABISYSV_ARM64_H + +#include "Plugins/ABI/AArch64/ABIAArch64.h" +#include "lldb/lldb-private.h" + +class ABISysV_arm64 : public ABIAArch64 { +public: + ~ABISysV_arm64() override = default; + + size_t GetRedZoneSize() const override; + + bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t functionAddress, + lldb::addr_t returnAddress, + llvm::ArrayRef args) const override; + + bool GetArgumentValues(lldb_private::Thread &thread, + lldb_private::ValueList &values) const override; + + lldb_private::Status + SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value) override; + + bool + CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override; + + // The arm64 ABI requires that stack frames be 16 byte aligned. + // When there is a trap handler on the stack, e.g. _sigtramp in userland + // code, we've seen that the stack pointer is often not aligned properly + // before the handler is invoked. This means that lldb will stop the unwind + // early -- before the function which caused the trap. + // + // To work around this, we relax that alignment to be just word-size + // (8-bytes). + // Allowing the trap handlers for user space would be easy (_sigtramp) but + // in other environments there can be a large number of different functions + // involved in async traps. + bool CallFrameAddressIsValid(lldb::addr_t cfa) override { + // Make sure the stack call frame addresses are are 8 byte aligned + if (cfa & (8ull - 1ull)) + return false; // Not 8 byte aligned + if (cfa == 0) + return false; // Zero is not a valid stack address + return true; + } + + bool CodeAddressIsValid(lldb::addr_t pc) override { + if (pc & (4ull - 1ull)) + return false; // Not 4 byte aligned + + // Anything else if fair game.. + return true; + } + + bool GetPointerReturnRegister(const char *&name) override; + + // Static Functions + + static void Initialize(); + + static void Terminate(); + + static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); + + static lldb_private::ConstString GetPluginNameStatic(); + + // PluginInterface protocol + + lldb_private::ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + +protected: + lldb::ValueObjectSP + GetReturnValueObjectImpl(lldb_private::Thread &thread, + lldb_private::CompilerType &ast_type) const override; + +private: + using ABIAArch64::ABIAArch64; // Call CreateInstance instead. +}; + +#endif // LLDB_SOURCE_PLUGINS_ABI_AARCH64_ABISYSV_ARM64_H diff --git a/gnu/llvm/lldb/source/Plugins/ABI/AArch64/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/ABI/AArch64/CMakeLists.txt new file mode 100644 index 00000000000..40db86f092d --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/AArch64/CMakeLists.txt @@ -0,0 +1,12 @@ +add_lldb_library(lldbPluginABIAArch64 PLUGIN + ABIAArch64.cpp + ABIMacOSX_arm64.cpp + ABISysV_arm64.cpp + + LINK_LIBS + lldbCore + lldbSymbol + lldbTarget + LINK_COMPONENTS + Support + ) diff --git a/gnu/llvm/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp b/gnu/llvm/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp new file mode 100644 index 00000000000..a212eef2ab8 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp @@ -0,0 +1,616 @@ +//===-- ABISysV_arc.cpp ---------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABISysV_arc.h" + +// C Includes +// C++ Includes +#include +#include +#include + +// Other libraries and framework includes +#include "llvm/ADT/Triple.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/Support/MathExtras.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Core/ValueObjectMemory.h" +#include "lldb/Core/ValueObjectRegister.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Status.h" + +#define DEFINE_REG_NAME(reg_num) ConstString(#reg_num).GetCString() +#define DEFINE_REG_NAME_STR(reg_name) ConstString(reg_name).GetCString() + +// The ABI is not a source of such information as size, offset, encoding, etc. +// of a register. Just provides correct dwarf and eh_frame numbers. + +#define DEFINE_GENERIC_REGISTER_STUB(dwarf_num, str_name, generic_num) \ + { \ + DEFINE_REG_NAME(dwarf_num), DEFINE_REG_NAME_STR(str_name), \ + 0, 0, eEncodingInvalid, eFormatDefault, \ + { dwarf_num, dwarf_num, generic_num, LLDB_INVALID_REGNUM, dwarf_num }, \ + nullptr, nullptr, nullptr, 0 \ + } + +#define DEFINE_REGISTER_STUB(dwarf_num, str_name) \ + DEFINE_GENERIC_REGISTER_STUB(dwarf_num, str_name, LLDB_INVALID_REGNUM) + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE_ADV(ABISysV_arc, ABIARC) + +namespace { +namespace dwarf { +enum regnums { + r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, + r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, + r27, fp = r27, r28, sp = r28, r29, r30, r31, blink = r31, + r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46, + r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58, r59, r60, + /*reserved,*/ /*limm indicator,*/ r63 = 63, pc = 70, status32 = 74 +}; + +static const std::array g_register_infos = { { + DEFINE_GENERIC_REGISTER_STUB(r0, nullptr, LLDB_REGNUM_GENERIC_ARG1), + DEFINE_GENERIC_REGISTER_STUB(r1, nullptr, LLDB_REGNUM_GENERIC_ARG2), + DEFINE_GENERIC_REGISTER_STUB(r2, nullptr, LLDB_REGNUM_GENERIC_ARG3), + DEFINE_GENERIC_REGISTER_STUB(r3, nullptr, LLDB_REGNUM_GENERIC_ARG4), + DEFINE_GENERIC_REGISTER_STUB(r4, nullptr, LLDB_REGNUM_GENERIC_ARG5), + DEFINE_GENERIC_REGISTER_STUB(r5, nullptr, LLDB_REGNUM_GENERIC_ARG6), + DEFINE_GENERIC_REGISTER_STUB(r6, nullptr, LLDB_REGNUM_GENERIC_ARG7), + DEFINE_GENERIC_REGISTER_STUB(r7, nullptr, LLDB_REGNUM_GENERIC_ARG8), + DEFINE_REGISTER_STUB(r8, nullptr), + DEFINE_REGISTER_STUB(r9, nullptr), + DEFINE_REGISTER_STUB(r10, nullptr), + DEFINE_REGISTER_STUB(r11, nullptr), + DEFINE_REGISTER_STUB(r12, nullptr), + DEFINE_REGISTER_STUB(r13, nullptr), + DEFINE_REGISTER_STUB(r14, nullptr), + DEFINE_REGISTER_STUB(r15, nullptr), + DEFINE_REGISTER_STUB(r16, nullptr), + DEFINE_REGISTER_STUB(r17, nullptr), + DEFINE_REGISTER_STUB(r18, nullptr), + DEFINE_REGISTER_STUB(r19, nullptr), + DEFINE_REGISTER_STUB(r20, nullptr), + DEFINE_REGISTER_STUB(r21, nullptr), + DEFINE_REGISTER_STUB(r22, nullptr), + DEFINE_REGISTER_STUB(r23, nullptr), + DEFINE_REGISTER_STUB(r24, nullptr), + DEFINE_REGISTER_STUB(r25, nullptr), + DEFINE_REGISTER_STUB(r26, "gp"), + DEFINE_GENERIC_REGISTER_STUB(r27, "fp", LLDB_REGNUM_GENERIC_FP), + DEFINE_GENERIC_REGISTER_STUB(r28, "sp", LLDB_REGNUM_GENERIC_SP), + DEFINE_REGISTER_STUB(r29, "ilink"), + DEFINE_REGISTER_STUB(r30, nullptr), + DEFINE_GENERIC_REGISTER_STUB(r31, "blink", LLDB_REGNUM_GENERIC_RA), + DEFINE_REGISTER_STUB(r32, nullptr), + DEFINE_REGISTER_STUB(r33, nullptr), + DEFINE_REGISTER_STUB(r34, nullptr), + DEFINE_REGISTER_STUB(r35, nullptr), + DEFINE_REGISTER_STUB(r36, nullptr), + DEFINE_REGISTER_STUB(r37, nullptr), + DEFINE_REGISTER_STUB(r38, nullptr), + DEFINE_REGISTER_STUB(r39, nullptr), + DEFINE_REGISTER_STUB(r40, nullptr), + DEFINE_REGISTER_STUB(r41, nullptr), + DEFINE_REGISTER_STUB(r42, nullptr), + DEFINE_REGISTER_STUB(r43, nullptr), + DEFINE_REGISTER_STUB(r44, nullptr), + DEFINE_REGISTER_STUB(r45, nullptr), + DEFINE_REGISTER_STUB(r46, nullptr), + DEFINE_REGISTER_STUB(r47, nullptr), + DEFINE_REGISTER_STUB(r48, nullptr), + DEFINE_REGISTER_STUB(r49, nullptr), + DEFINE_REGISTER_STUB(r50, nullptr), + DEFINE_REGISTER_STUB(r51, nullptr), + DEFINE_REGISTER_STUB(r52, nullptr), + DEFINE_REGISTER_STUB(r53, nullptr), + DEFINE_REGISTER_STUB(r54, nullptr), + DEFINE_REGISTER_STUB(r55, nullptr), + DEFINE_REGISTER_STUB(r56, nullptr), + DEFINE_REGISTER_STUB(r57, nullptr), + DEFINE_REGISTER_STUB(r58, "accl"), + DEFINE_REGISTER_STUB(r59, "acch"), + DEFINE_REGISTER_STUB(r60, "lp_count"), + DEFINE_REGISTER_STUB(r63, "pcl"), + DEFINE_GENERIC_REGISTER_STUB(pc, nullptr, LLDB_REGNUM_GENERIC_PC), + DEFINE_GENERIC_REGISTER_STUB(status32, nullptr, LLDB_REGNUM_GENERIC_FLAGS)} }; +} // namespace dwarf +} // namespace + +const RegisterInfo *ABISysV_arc::GetRegisterInfoArray(uint32_t &count) { + count = dwarf::g_register_infos.size(); + return dwarf::g_register_infos.data(); +} + +size_t ABISysV_arc::GetRedZoneSize() const { return 0; } + +bool ABISysV_arc::IsRegisterFileReduced(RegisterContext ®_ctx) const { + if (!m_is_reg_file_reduced) { + const auto *const rf_build_reg = reg_ctx.GetRegisterInfoByName("rf_build"); + + const auto reg_value = reg_ctx.ReadRegisterAsUnsigned(rf_build_reg, + /*fail_value*/ 0); + // RF_BUILD "Number of Entries" bit. + const uint32_t rf_entries_bit = 1U << 9U; + m_is_reg_file_reduced = (reg_value | rf_entries_bit) != 0; + } + + return m_is_reg_file_reduced.getValueOr(false); +} + +//------------------------------------------------------------------ +// Static Functions +//------------------------------------------------------------------ + +ABISP ABISysV_arc::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) { + return llvm::Triple::arc == arch.GetTriple().getArch() ? + ABISP(new ABISysV_arc(std::move(process_sp), MakeMCRegisterInfo(arch))) : + ABISP(); +} + +namespace { +const size_t word_size = 4U; +const size_t reg_size = word_size; + +inline size_t AugmentArgSize(size_t size_in_bytes) { + return llvm::alignTo(size_in_bytes, word_size); +} + +size_t TotalArgsSizeInWords(const llvm::ArrayRef &args) { + size_t total_size = 0; + for (const auto &arg : args) + total_size += + (ABI::CallArgument::TargetValue == arg.type ? AugmentArgSize(arg.size) + : reg_size) / + word_size; + + return total_size; +} +} // namespace + +bool ABISysV_arc::PrepareTrivialCall(Thread &thread, addr_t sp, + addr_t func_addr, addr_t return_addr, + llvm::ArrayRef args) const { + // We don't use the traditional trivial call specialized for jit. + return false; +} + +bool ABISysV_arc::PrepareTrivialCall(Thread &thread, addr_t sp, addr_t pc, + addr_t ra, llvm::Type &prototype, + llvm::ArrayRef args) const { + auto reg_ctx = thread.GetRegisterContext(); + if (!reg_ctx) + return false; + + uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + if (pc_reg == LLDB_INVALID_REGNUM) + return false; + + uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); + if (ra_reg == LLDB_INVALID_REGNUM) + return false; + + uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); + if (sp_reg == LLDB_INVALID_REGNUM) + return false; + + Status error; + ProcessSP process = thread.GetProcess(); + if (!process) + return false; + + // Push host data onto target. + for (const auto &arg : args) { + // Skip over target values. + if (arg.type == ABI::CallArgument::TargetValue) + continue; + + // Create space on the stack for this data 4-byte aligned. + sp -= AugmentArgSize(arg.size); + + if (process->WriteMemory(sp, arg.data_up.get(), arg.size, error) < arg.size + || error.Fail()) + return false; + + // Update the argument with the target pointer. + *const_cast(&arg.value) = sp; + } + + // Make sure number of parameters matches prototype. + assert(!prototype.isFunctionVarArg()); + assert(prototype.getFunctionNumParams() == args.size()); + + const size_t regs_for_args_count = IsRegisterFileReduced(*reg_ctx) ? 4U : 8U; + + // Number of arguments passed on stack. + auto args_size = TotalArgsSizeInWords(args); + auto on_stack = + args_size <= regs_for_args_count ? 0 : args_size - regs_for_args_count; + auto offset = on_stack * word_size; + + uint8_t reg_value[reg_size]; + size_t reg_index = LLDB_REGNUM_GENERIC_ARG1; + + for (const auto &arg : args) { + auto value = reinterpret_cast(&arg.value); + auto size = + ABI::CallArgument::TargetValue == arg.type ? arg.size : reg_size; + + // Pass arguments via registers. + while (size > 0 && reg_index < regs_for_args_count) { + size_t byte_index = 0; + auto end = size < reg_size ? size : reg_size; + + while (byte_index < end) { + reg_value[byte_index++] = *(value++); + --size; + } + + while (byte_index < reg_size) { + reg_value[byte_index++] = 0; + } + + RegisterValue reg_val_obj(reg_value, reg_size, eByteOrderLittle); + if (!reg_ctx->WriteRegister( + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, reg_index), + reg_val_obj)) + return false; + + // NOTE: It's unsafe to iterate through LLDB_REGNUM_GENERICs. + ++reg_index; + } + + if (reg_index < regs_for_args_count || size == 0) + continue; + + // Remaining arguments are passed on the stack. + if (process->WriteMemory(sp - offset, value, size, error) < size || + !error.Success()) + return false; + + offset -= AugmentArgSize(size); + } + + // Set stack pointer immediately below arguments. + sp -= on_stack * word_size; + + // Update registers with current function call state. + reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc); + reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra); + reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp); + + return true; +} + +bool ABISysV_arc::GetArgumentValues(Thread &thread, ValueList &values) const { + return false; +} + +Status ABISysV_arc::SetReturnValueObject(StackFrameSP &frame_sp, + ValueObjectSP &new_value_sp) { + Status result; + if (!new_value_sp) { + result.SetErrorString("Empty value object for return value."); + return result; + } + + CompilerType compiler_type = new_value_sp->GetCompilerType(); + if (!compiler_type) { + result.SetErrorString("Null clang type for return value."); + return result; + } + + auto ®_ctx = *frame_sp->GetThread()->GetRegisterContext(); + + bool is_signed = false; + if (!compiler_type.IsIntegerOrEnumerationType(is_signed) && + !compiler_type.IsPointerType()) { + result.SetErrorString("We don't support returning other types at present"); + return result; + } + + DataExtractor data; + size_t num_bytes = new_value_sp->GetData(data, result); + + if (result.Fail()) { + result.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", result.AsCString()); + return result; + } + + if (num_bytes <= 2 * reg_size) { + offset_t offset = 0; + uint64_t raw_value = data.GetMaxU64(&offset, num_bytes); + + auto reg_info = + reg_ctx.GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); + if (!reg_ctx.WriteRegisterFromUnsigned(reg_info, raw_value)) { + result.SetErrorStringWithFormat("Couldn't write value to register %s", + reg_info->name); + return result; + } + + if (num_bytes <= reg_size) + return result; // Successfully written. + + raw_value >>= 32; + reg_info = + reg_ctx.GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2); + if (!reg_ctx.WriteRegisterFromUnsigned(reg_info, raw_value)) { + result.SetErrorStringWithFormat("Couldn't write value to register %s", + reg_info->name); + } + + return result; + } + + result.SetErrorString( + "We don't support returning large integer values at present."); + return result; +} + +namespace { +template +void SetInteger(Scalar &scalar, uint64_t raw_value, bool is_signed) { + raw_value &= std::numeric_limits::max(); + if (is_signed) + scalar = static_cast::type>(raw_value); + else + scalar = static_cast(raw_value); +} + +bool SetSizedInteger(Scalar &scalar, uint64_t raw_value, uint8_t size_in_bytes, + bool is_signed) { + switch (size_in_bytes) { + default: + return false; + + case sizeof(uint64_t): + SetInteger(scalar, raw_value, is_signed); + break; + + case sizeof(uint32_t): + SetInteger(scalar, raw_value, is_signed); + break; + + case sizeof(uint16_t): + SetInteger(scalar, raw_value, is_signed); + break; + + case sizeof(uint8_t): + SetInteger(scalar, raw_value, is_signed); + break; + } + + return true; +} + +bool SetSizedFloat(Scalar &scalar, uint64_t raw_value, uint8_t size_in_bytes) { + switch (size_in_bytes) { + default: + return false; + + case sizeof(uint64_t): + scalar = *reinterpret_cast(&raw_value); + break; + + case sizeof(uint32_t): + scalar = *reinterpret_cast(&raw_value); + break; + } + + return true; +} + +uint64_t ReadRawValue(const RegisterContextSP ®_ctx, uint8_t size_in_bytes) { + auto reg_info_r0 = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); + + // Extract the register context so we can read arguments from registers. + uint64_t raw_value = + reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0) & UINT32_MAX; + + if (sizeof(uint64_t) == size_in_bytes) + raw_value |= (reg_ctx->ReadRegisterAsUnsigned( + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_ARG2), 0) & + UINT64_MAX) << 32U; + + return raw_value; +} +} // namespace + +ValueObjectSP +ABISysV_arc::GetReturnValueObjectSimple(Thread &thread, + CompilerType &compiler_type) const { + if (!compiler_type) + return ValueObjectSP(); + + auto reg_ctx = thread.GetRegisterContext(); + if (!reg_ctx) + return ValueObjectSP(); + + Value value; + value.SetCompilerType(compiler_type); + + const uint32_t type_flags = compiler_type.GetTypeInfo(); + // Integer return type. + if (type_flags & eTypeIsInteger) { + const size_t byte_size = compiler_type.GetByteSize(nullptr).getValueOr(0); + auto raw_value = ReadRawValue(reg_ctx, byte_size); + + const bool is_signed = (type_flags & eTypeIsSigned) != 0; + if (!SetSizedInteger(value.GetScalar(), raw_value, byte_size, is_signed)) + return ValueObjectSP(); + + value.SetValueType(Value::eValueTypeScalar); + } + // Pointer return type. + else if (type_flags & eTypeIsPointer) { + auto reg_info_r0 = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_ARG1); + value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0); + + value.SetValueType(Value::eValueTypeScalar); + } + // Floating point return type. + else if (type_flags & eTypeIsFloat) { + uint32_t float_count = 0; + bool is_complex = false; + + if (compiler_type.IsFloatingPointType(float_count, is_complex) && + 1 == float_count && !is_complex) { + const size_t byte_size = compiler_type.GetByteSize(nullptr).getValueOr(0); + auto raw_value = ReadRawValue(reg_ctx, byte_size); + + if (!SetSizedFloat(value.GetScalar(), raw_value, byte_size)) + return ValueObjectSP(); + } + } + // Unsupported return type. + else + return ValueObjectSP(); + + return ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(), + value, ConstString("")); +} + +ValueObjectSP ABISysV_arc::GetReturnValueObjectImpl( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + + if (!return_compiler_type) + return return_valobj_sp; + + ExecutionContext exe_ctx(thread.shared_from_this()); + return GetReturnValueObjectSimple(thread, return_compiler_type); +} + +ValueObjectSP ABISysV_arc::GetReturnValueObjectImpl(Thread &thread, + llvm::Type &retType) const { + auto reg_ctx = thread.GetRegisterContext(); + if (!reg_ctx) + return ValueObjectSP(); + + Value value; + // Void return type. + if (retType.isVoidTy()) { + value.GetScalar() = 0; + } + // Integer return type. + else if (retType.isIntegerTy()) { + size_t byte_size = retType.getPrimitiveSizeInBits(); + if (1 != byte_size) // For boolean type. + byte_size /= CHAR_BIT; + + auto raw_value = ReadRawValue(reg_ctx, byte_size); + + const bool is_signed = false; // IR Type doesn't provide this info. + if (!SetSizedInteger(value.GetScalar(), raw_value, byte_size, is_signed)) + return ValueObjectSP(); + } + // Pointer return type. + else if (retType.isPointerTy()) { + auto reg_info_r0 = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_ARG1); + value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0); + value.SetValueType(Value::eValueTypeScalar); + } + // Floating point return type. + else if (retType.isFloatingPointTy()) { + const size_t byte_size = retType.getPrimitiveSizeInBits() / CHAR_BIT; + auto raw_value = ReadRawValue(reg_ctx, byte_size); + + if (!SetSizedFloat(value.GetScalar(), raw_value, byte_size)) + return ValueObjectSP(); + } + // Unsupported return type. + else + return ValueObjectSP(); + + return ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(), + value, ConstString("")); +} + +bool ABISysV_arc::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + UnwindPlan::RowSP row(new UnwindPlan::Row); + + // Our Call Frame Address is the stack pointer value. + row->GetCFAValue().SetIsRegisterPlusOffset(dwarf::sp, 0); + + // The previous PC is in the BLINK. + row->SetRegisterLocationToRegister(dwarf::pc, dwarf::blink, true); + unwind_plan.AppendRow(row); + + // All other registers are the same. + unwind_plan.SetSourceName("arc at-func-entry default"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + + return true; +} + +bool ABISysV_arc::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { + return false; +} + +bool ABISysV_arc::RegisterIsVolatile(const RegisterInfo *reg_info) { + if (nullptr == reg_info) + return false; + + // Volatile registers are: r0..r12. + uint32_t regnum = reg_info->kinds[eRegisterKindDWARF]; + if (regnum <= 12) + return true; + + static const std::string ra_reg_name = "blink"; + return ra_reg_name == reg_info->name; +} + +void ABISysV_arc::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + "System V ABI for ARC targets", CreateInstance); +} + +void ABISysV_arc::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +ConstString ABISysV_arc::GetPluginNameStatic() { + static ConstString g_name("sysv-arc"); + return g_name; +} + +//------------------------------------------------------------------ +// PluginInterface protocol +//------------------------------------------------------------------ + +ConstString ABISysV_arc::GetPluginName() { + return GetPluginNameStatic(); +} + +uint32_t ABISysV_arc::GetPluginVersion() { return 1; } diff --git a/gnu/llvm/lldb/source/Plugins/ABI/ARC/ABISysV_arc.h b/gnu/llvm/lldb/source/Plugins/ABI/ARC/ABISysV_arc.h new file mode 100644 index 00000000000..3fbe64b4b45 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/ARC/ABISysV_arc.h @@ -0,0 +1,106 @@ +//===-- ArchitectureArc.h ---------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ABISysV_arc_h_ +#define liblldb_ABISysV_arc_h_ + +// Other libraries and framework includes +#include + +// Project includes +#include "lldb/Target/ABI.h" +#include "lldb/lldb-private.h" + +class ABISysV_arc : public lldb_private::RegInfoBasedABI { +public: + ~ABISysV_arc() override = default; + + size_t GetRedZoneSize() const override; + + bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t functionAddress, + lldb::addr_t returnAddress, + llvm::ArrayRef args) const override; + + // Special thread plan for GDB style non-jit function calls. + bool + PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t functionAddress, lldb::addr_t returnAddress, + llvm::Type &prototype, + llvm::ArrayRef args) const override; + + bool GetArgumentValues(lldb_private::Thread &thread, + lldb_private::ValueList &values) const override; + + lldb_private::Status + SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value) override; + + lldb::ValueObjectSP + GetReturnValueObjectImpl(lldb_private::Thread &thread, + lldb_private::CompilerType &type) const override; + + // Specialized to work with llvm IR types. + lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, + llvm::Type &type) const override; + + bool + CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override; + + bool CallFrameAddressIsValid(lldb::addr_t cfa) override { + // Stack call frame address must be 4 byte aligned. + return (cfa & 0x3ull) == 0; + } + + bool CodeAddressIsValid(lldb::addr_t pc) override { + // Code addresse must be 2 byte aligned. + return (pc & 1ull) == 0; + } + + const lldb_private::RegisterInfo * + GetRegisterInfoArray(uint32_t &count) override; + + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + + static void Initialize(); + + static void Terminate(); + + static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, + const lldb_private::ArchSpec &arch); + + static lldb_private::ConstString GetPluginNameStatic(); + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + + lldb_private::ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + +private: + lldb::ValueObjectSP + GetReturnValueObjectSimple(lldb_private::Thread &thread, + lldb_private::CompilerType &ast_type) const; + + bool IsRegisterFileReduced(lldb_private::RegisterContext ®_ctx) const; + + using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance instead. + + using RegisterFileFlag = llvm::Optional; + mutable RegisterFileFlag m_is_reg_file_reduced; +}; + +#endif // liblldb_ABISysV_arc_h_ diff --git a/gnu/llvm/lldb/source/Plugins/ABI/ARC/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/ABI/ARC/CMakeLists.txt new file mode 100644 index 00000000000..19421427d4d --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/ARC/CMakeLists.txt @@ -0,0 +1,11 @@ +add_lldb_library(lldbPluginABIARC PLUGIN + ABISysV_arc.cpp + + LINK_LIBS + lldbCore + lldbSymbol + lldbTarget + lldbPluginProcessUtility + LINK_COMPONENTS + Support + ) diff --git a/gnu/llvm/lldb/source/Plugins/ABI/ARM/ABIARM.cpp b/gnu/llvm/lldb/source/Plugins/ABI/ARM/ABIARM.cpp new file mode 100644 index 00000000000..882c14d386e --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/ARM/ABIARM.cpp @@ -0,0 +1,24 @@ +//===-- ARM.h -------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABIARM.h" +#include "ABIMacOSX_arm.h" +#include "ABISysV_arm.h" +#include "lldb/Core/PluginManager.h" + +LLDB_PLUGIN_DEFINE(ABIARM) + +void ABIARM::Initialize() { + ABISysV_arm::Initialize(); + ABIMacOSX_arm::Initialize(); +} + +void ABIARM::Terminate() { + ABISysV_arm::Terminate(); + ABIMacOSX_arm::Terminate(); +} diff --git a/gnu/llvm/lldb/source/Plugins/ABI/ARM/ABIARM.h b/gnu/llvm/lldb/source/Plugins/ABI/ARM/ABIARM.h new file mode 100644 index 00000000000..7d04f1c9eb0 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/ARM/ABIARM.h @@ -0,0 +1,17 @@ +//===-- ARM.h -------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_ARM_ABIARM_H +#define LLDB_SOURCE_PLUGINS_ABI_ARM_ABIARM_H + +class ABIARM { +public: + static void Initialize(); + static void Terminate(); +}; +#endif diff --git a/gnu/llvm/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp b/gnu/llvm/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp new file mode 100644 index 00000000000..ef500cb198a --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp @@ -0,0 +1,2054 @@ +//===-- ABIMacOSX_arm.cpp -------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABIMacOSX_arm.h" + +#include + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Triple.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#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" +#include "Utility/ARM_DWARF_Registers.h" +#include "Utility/ARM_ehframe_Registers.h" + +using namespace lldb; +using namespace lldb_private; + +static RegisterInfo g_register_infos[] = { + // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME + // DWARF GENERIC PROCESS PLUGIN + // LLDB NATIVE + // ========== ======= == === ============= ============ + // ======================= =================== =========================== + // ======================= ====================== + {"r0", + "arg1", + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r1", + "arg2", + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r2", + "arg3", + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r3", + "arg4", + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r4", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r5", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r6", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r7", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r8", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r9", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r10", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r11", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r12", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"sp", + "r13", + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"lr", + "r14", + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"pc", + "r15", + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"cpsr", + "psr", + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s0", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s1", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s2", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s3", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s4", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s5", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s6", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s7", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s8", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s9", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s10", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s11", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s12", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s13", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s14", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s15", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s16", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s17", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s18", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s19", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s20", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s21", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s22", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s23", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s24", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s25", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s26", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s27", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s28", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s29", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s30", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s31", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"fpscr", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d0", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d1", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d2", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d3", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d4", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d5", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d6", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d7", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d8", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d9", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d10", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d11", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d12", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d13", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d14", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d15", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d16", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d17", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d18", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d19", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d20", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d21", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d22", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d23", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d24", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d25", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d26", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d27", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d28", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d29", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d30", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d31", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r8_usr", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r8_usr, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r9_usr", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r9_usr, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r10_usr", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r10_usr, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r11_usr", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r11_usr, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r12_usr", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r12_usr, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r13_usr", + "sp_usr", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r13_usr, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r14_usr", + "lr_usr", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r14_usr, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r8_fiq", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r8_fiq, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r9_fiq", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r9_fiq, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r10_fiq", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r10_fiq, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r11_fiq", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r11_fiq, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r12_fiq", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r12_fiq, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r13_fiq", + "sp_fiq", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r13_fiq, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r14_fiq", + "lr_fiq", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r14_fiq, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r13_irq", + "sp_irq", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r13_irq, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r14_irq", + "lr_irq", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r14_irq, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r13_abt", + "sp_abt", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r13_abt, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r14_abt", + "lr_abt", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r14_abt, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r13_und", + "sp_und", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r13_und, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r14_und", + "lr_und", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r14_und, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r13_svc", + "sp_svc", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r13_svc, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r14_svc", + "lr_svc", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r14_svc, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}}; + +static const uint32_t k_num_register_infos = + llvm::array_lengthof(g_register_infos); +static bool g_register_info_names_constified = false; + +const lldb_private::RegisterInfo * +ABIMacOSX_arm::GetRegisterInfoArray(uint32_t &count) { + // Make the C-string names and alt_names for the register infos into const + // C-string values by having the ConstString unique the names in the global + // constant C-string pool. + if (!g_register_info_names_constified) { + g_register_info_names_constified = true; + for (uint32_t i = 0; i < k_num_register_infos; ++i) { + if (g_register_infos[i].name) + g_register_infos[i].name = + ConstString(g_register_infos[i].name).GetCString(); + if (g_register_infos[i].alt_name) + g_register_infos[i].alt_name = + ConstString(g_register_infos[i].alt_name).GetCString(); + } + } + count = k_num_register_infos; + return g_register_infos; +} + +size_t ABIMacOSX_arm::GetRedZoneSize() const { return 0; } + +// Static Functions + +ABISP +ABIMacOSX_arm::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) { + 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)) { + return ABISP( + new ABIMacOSX_arm(std::move(process_sp), MakeMCRegisterInfo(arch))); + } + } + + return ABISP(); +} + +bool ABIMacOSX_arm::PrepareTrivialCall(Thread &thread, addr_t sp, + addr_t function_addr, addr_t return_addr, + llvm::ArrayRef args) const { + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return false; + + const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); + const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); + + RegisterValue reg_value; + + const char *reg_names[] = {"r0", "r1", "r2", "r3"}; + + llvm::ArrayRef::iterator ai = args.begin(), ae = args.end(); + + for (size_t i = 0; i < llvm::array_lengthof(reg_names); ++i) { + if (ai == ae) + break; + + reg_value.SetUInt32(*ai); + if (!reg_ctx->WriteRegister(reg_ctx->GetRegisterInfoByName(reg_names[i]), + reg_value)) + return false; + + ++ai; + } + + if (ai != ae) { + // Spill onto the stack + size_t num_stack_regs = ae - ai; + + sp -= (num_stack_regs * 4); + // Keep the stack 16 byte aligned + sp &= ~(16ull - 1ull); + + // just using arg1 to get the right size + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); + + addr_t arg_pos = sp; + + for (; ai != ae; ++ai) { + reg_value.SetUInt32(*ai); + if (reg_ctx + ->WriteRegisterValueToMemory(reg_info, arg_pos, + reg_info->byte_size, reg_value) + .Fail()) + return false; + arg_pos += reg_info->byte_size; + } + } + + TargetSP target_sp(thread.CalculateTarget()); + Address so_addr; + + // Figure out if our return address is ARM or Thumb by using the + // Address::GetCallableLoadAddress(Target*) which will figure out the ARM + // thumb-ness and set the correct address bits for us. + so_addr.SetLoadAddress(return_addr, target_sp.get()); + return_addr = so_addr.GetCallableLoadAddress(target_sp.get()); + + // Set "lr" to the return address + if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_num, return_addr)) + return false; + + // If bit zero or 1 is set, this must be a thumb function, no need to figure + // this out from the symbols. + so_addr.SetLoadAddress(function_addr, target_sp.get()); + function_addr = so_addr.GetCallableLoadAddress(target_sp.get()); + + const RegisterInfo *cpsr_reg_info = reg_ctx->GetRegisterInfoByName("cpsr"); + const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0); + + // Make a new CPSR and mask out any Thumb IT (if/then) bits + uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK; + // If bit zero or 1 is set, this must be thumb... + if (function_addr & 1ull) + new_cpsr |= MASK_CPSR_T; // Set T bit in CPSR + else + new_cpsr &= ~MASK_CPSR_T; // Clear T bit in CPSR + + if (new_cpsr != curr_cpsr) { + if (!reg_ctx->WriteRegisterFromUnsigned(cpsr_reg_info, new_cpsr)) + return false; + } + + function_addr &= + ~1ull; // clear bit zero since the CPSR will take care of the mode for us + + // Update the sp - stack pointer - to be aligned to 16-bytes + sp &= ~(0xfull); + if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp)) + return false; + + // Set "pc" to the address requested + if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, function_addr)) + return false; + + return true; +} + +bool ABIMacOSX_arm::GetArgumentValues(Thread &thread, ValueList &values) const { + uint32_t num_values = values.GetSize(); + + ExecutionContext exe_ctx(thread.shared_from_this()); + // For now, assume that the types in the AST values come from the Target's + // scratch AST. + + // Extract the register context so we can read arguments from registers + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + + if (!reg_ctx) + return false; + + addr_t sp = 0; + + for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) { + // We currently only support extracting values with Clang QualTypes. Do we + // care about others? + Value *value = values.GetValueAtIndex(value_idx); + + if (!value) + return false; + + CompilerType compiler_type = value->GetCompilerType(); + if (compiler_type) { + bool is_signed = false; + size_t bit_width = 0; + 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) { + // Arguments 1-4 are in r0-r3... + const RegisterInfo *arg_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) { + arg_reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num); + } else { + switch (value_idx) { + case 0: + arg_reg_info = reg_ctx->GetRegisterInfoByName("r0"); + break; + case 1: + arg_reg_info = reg_ctx->GetRegisterInfoByName("r1"); + break; + case 2: + arg_reg_info = reg_ctx->GetRegisterInfoByName("r2"); + break; + case 3: + arg_reg_info = reg_ctx->GetRegisterInfoByName("r3"); + break; + } + } + + if (arg_reg_info) { + RegisterValue reg_value; + + if (reg_ctx->ReadRegister(arg_reg_info, reg_value)) { + if (is_signed) + reg_value.SignExtend(bit_width); + if (!reg_value.GetScalarValue(value->GetScalar())) + return false; + continue; + } + } + return false; + } else { + if (sp == 0) { + // Read the stack pointer if it already hasn't been read + sp = reg_ctx->GetSP(0); + if (sp == 0) + return false; + } + + // 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; + } + } + } + } + return true; +} + +bool ABIMacOSX_arm::IsArmv7kProcess() const { + bool is_armv7k = false; + ProcessSP process_sp(GetProcessSP()); + if (process_sp) { + const ArchSpec &arch(process_sp->GetTarget().GetArchitecture()); + const ArchSpec::Core system_core = arch.GetCore(); + if (system_core == ArchSpec::eCore_arm_armv7k) { + is_armv7k = true; + } + } + return is_armv7k; +} + +ValueObjectSP ABIMacOSX_arm::GetReturnValueObjectImpl( + Thread &thread, lldb_private::CompilerType &compiler_type) const { + Value value; + ValueObjectSP return_valobj_sp; + + if (!compiler_type) + return return_valobj_sp; + + value.SetCompilerType(compiler_type); + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return return_valobj_sp; + + bool is_signed; + + // Get the pointer to the first stack argument so we have a place to start + // when reading data + + const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfoByName("r0", 0); + if (compiler_type.IsIntegerOrEnumerationType(is_signed)) { + llvm::Optional bit_width = compiler_type.GetBitSize(&thread); + if (!bit_width) + return return_valobj_sp; + + switch (*bit_width) { + default: + return return_valobj_sp; + case 128: + if (IsArmv7kProcess()) { + // "A composite type not larger than 16 bytes is returned in r0-r3. The + // format is as if the result had been stored in memory at a word- + // aligned address and then loaded into r0-r3 with an ldm instruction" + { + const RegisterInfo *r1_reg_info = + reg_ctx->GetRegisterInfoByName("r1", 0); + const RegisterInfo *r2_reg_info = + reg_ctx->GetRegisterInfoByName("r2", 0); + const RegisterInfo *r3_reg_info = + reg_ctx->GetRegisterInfoByName("r3", 0); + if (r1_reg_info && r2_reg_info && r3_reg_info) { + 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 && + process_sp) { + std::unique_ptr heap_data_up( + new DataBufferHeap(*byte_size, 0)); + const ByteOrder byte_order = process_sp->GetByteOrder(); + RegisterValue r0_reg_value; + RegisterValue r1_reg_value; + RegisterValue r2_reg_value; + RegisterValue r3_reg_value; + if (reg_ctx->ReadRegister(r0_reg_info, r0_reg_value) && + reg_ctx->ReadRegister(r1_reg_info, r1_reg_value) && + reg_ctx->ReadRegister(r2_reg_info, r2_reg_value) && + reg_ctx->ReadRegister(r3_reg_info, r3_reg_value)) { + Status error; + if (r0_reg_value.GetAsMemoryData(r0_reg_info, + heap_data_up->GetBytes() + 0, + 4, byte_order, error) && + r1_reg_value.GetAsMemoryData(r1_reg_info, + heap_data_up->GetBytes() + 4, + 4, byte_order, error) && + r2_reg_value.GetAsMemoryData(r2_reg_info, + heap_data_up->GetBytes() + 8, + 4, byte_order, error) && + r3_reg_value.GetAsMemoryData(r3_reg_info, + heap_data_up->GetBytes() + 12, + 4, byte_order, error)) { + DataExtractor data(DataBufferSP(heap_data_up.release()), + byte_order, + process_sp->GetAddressByteSize()); + + return_valobj_sp = ValueObjectConstResult::Create( + &thread, compiler_type, ConstString(""), data); + return return_valobj_sp; + } + } + } + } + } + } else { + return return_valobj_sp; + } + break; + case 64: { + const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfoByName("r1", 0); + uint64_t raw_value; + raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; + raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) & + UINT32_MAX)) + << 32; + if (is_signed) + value.GetScalar() = (int64_t)raw_value; + else + value.GetScalar() = (uint64_t)raw_value; + } break; + case 32: + if (is_signed) + value.GetScalar() = (int32_t)( + reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX); + else + value.GetScalar() = (uint32_t)( + reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX); + break; + case 16: + if (is_signed) + value.GetScalar() = (int16_t)( + reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX); + else + value.GetScalar() = (uint16_t)( + reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX); + break; + case 8: + if (is_signed) + value.GetScalar() = (int8_t)( + reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX); + else + value.GetScalar() = (uint8_t)( + reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX); + break; + } + } else if (compiler_type.IsPointerType()) { + uint32_t ptr = + thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) & + UINT32_MAX; + value.GetScalar() = ptr; + } else { + // not handled yet + return return_valobj_sp; + } + + // If we get here, we have a valid Value, so make our ValueObject out of it: + + return_valobj_sp = ValueObjectConstResult::Create( + thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); + return return_valobj_sp; +} + +Status ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value_sp) { + Status error; + if (!new_value_sp) { + error.SetErrorString("Empty value object for return value."); + return error; + } + + CompilerType compiler_type = new_value_sp->GetCompilerType(); + if (!compiler_type) { + error.SetErrorString("Null clang type for return value."); + return error; + } + + Thread *thread = frame_sp->GetThread().get(); + + bool is_signed; + uint32_t count; + bool is_complex; + + RegisterContext *reg_ctx = thread->GetRegisterContext().get(); + + bool set_it_simple = false; + if (compiler_type.IsIntegerOrEnumerationType(is_signed) || + compiler_type.IsPointerType()) { + DataExtractor data; + Status data_error; + size_t num_bytes = new_value_sp->GetData(data, data_error); + if (data_error.Fail()) { + error.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", + data_error.AsCString()); + return error; + } + lldb::offset_t offset = 0; + if (num_bytes <= 8) { + const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0); + if (num_bytes <= 4) { + uint32_t raw_value = data.GetMaxU32(&offset, num_bytes); + + if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value)) + set_it_simple = true; + } else { + uint32_t raw_value = data.GetMaxU32(&offset, 4); + + if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value)) { + const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName("r1", 0); + uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset); + + if (reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value)) + set_it_simple = true; + } + } + } else if (num_bytes <= 16 && IsArmv7kProcess()) { + // "A composite type not larger than 16 bytes is returned in r0-r3. The + // format is as if the result had been stored in memory at a word-aligned + // address and then loaded into r0-r3 with an ldm instruction" + + const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0); + const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName("r1", 0); + const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0); + const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0); + lldb::offset_t offset = 0; + uint32_t bytes_written = 4; + uint32_t raw_value = data.GetMaxU64(&offset, 4); + if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value) && + bytes_written <= num_bytes) { + bytes_written += 4; + raw_value = data.GetMaxU64(&offset, 4); + if (bytes_written <= num_bytes && + reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value)) { + bytes_written += 4; + raw_value = data.GetMaxU64(&offset, 4); + if (bytes_written <= num_bytes && + reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) { + bytes_written += 4; + raw_value = data.GetMaxU64(&offset, 4); + if (bytes_written <= num_bytes && + reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value)) { + set_it_simple = true; + } + } + } + } + } else { + error.SetErrorString("We don't support returning longer than 64 bit " + "integer values at present."); + } + } else if (compiler_type.IsFloatingPointType(count, is_complex)) { + if (is_complex) + error.SetErrorString( + "We don't support returning complex values at present"); + else + error.SetErrorString( + "We don't support returning float values at present"); + } + + if (!set_it_simple) + error.SetErrorString( + "We only support setting simple integer return types at present."); + + return error; +} + +bool ABIMacOSX_arm::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t lr_reg_num = dwarf_lr; + uint32_t sp_reg_num = dwarf_sp; + uint32_t pc_reg_num = dwarf_pc; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + + // Our Call Frame Address is the stack pointer value + row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0); + + // The previous PC is in the LR + row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true); + unwind_plan.AppendRow(row); + + // All other registers are the same. + + unwind_plan.SetSourceName("arm at-func-entry default"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + + return true; +} + +bool ABIMacOSX_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t fp_reg_num = + dwarf_r7; // apple uses r7 for all frames. Normal arm uses r11 + uint32_t pc_reg_num = dwarf_pc; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + const int32_t ptr_size = 4; + + row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size); + row->SetOffset(0); + + row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); + row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); + + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("arm-apple-ios default unwind plan"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); + + return true; +} + +// cf. "ARMv6 Function Calling Conventions" +// https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARMv6FunctionCallingConventions.html +// and "ARMv7 Function Calling Conventions" +// https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARMv7FunctionCallingConventions.html + +// ARMv7 on iOS general purpose reg rules: +// r0-r3 not preserved (used for argument passing) +// r4-r6 preserved +// r7 preserved (frame pointer) +// r8 preserved +// r9 not preserved (usable as volatile scratch register with iOS 3.x and +// later) +// r10-r11 preserved +// r12 not presrved +// r13 preserved (stack pointer) +// r14 not preserved (link register) +// r15 preserved (pc) +// cpsr not preserved (different rules for different bits) + +// ARMv7 on iOS floating point rules: +// d0-d7 not preserved (aka s0-s15, q0-q3) +// d8-d15 preserved (aka s16-s31, q4-q7) +// d16-d31 not preserved (aka q8-q15) + +bool ABIMacOSX_arm::RegisterIsVolatile(const RegisterInfo *reg_info) { + if (reg_info) { + // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp) + const char *name = reg_info->name; + if (name[0] == 'r') { + switch (name[1]) { + case '0': + return name[2] == '\0'; // r0 + case '1': + switch (name[2]) { + case '\0': + return true; // r1 + case '2': + case '3': + return name[3] == '\0'; // r12, r13 (sp) + default: + break; + } + break; + + case '2': + return name[2] == '\0'; // r2 + case '3': + return name[2] == '\0'; // r3 + case '9': + return name[2] == '\0'; // r9 (apple-ios only...) + + break; + } + } else if (name[0] == 'd') { + switch (name[1]) { + case '0': + return name[2] == '\0'; // d0 is volatile + + case '1': + switch (name[2]) { + case '\0': + return true; // d1 is volatile + case '6': + case '7': + case '8': + case '9': + return name[3] == '\0'; // d16 - d19 are volatile + default: + break; + } + break; + + case '2': + switch (name[2]) { + case '\0': + return true; // d2 is volatile + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return name[3] == '\0'; // d20 - d29 are volatile + default: + break; + } + break; + + case '3': + switch (name[2]) { + case '\0': + return true; // d3 is volatile + case '0': + case '1': + return name[3] == '\0'; // d30 - d31 are volatile + default: + break; + } + break; + case '4': + case '5': + case '6': + case '7': + return name[2] == '\0'; // d4 - d7 are volatile + + default: + break; + } + } else if (name[0] == 's') { + switch (name[1]) { + case '0': + return name[2] == '\0'; // s0 is volatile + + case '1': + switch (name[2]) { + case '\0': + return true; // s1 is volatile + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + return name[3] == '\0'; // s10 - s15 are volatile + default: + break; + } + break; + + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return name[2] == '\0'; // s2 - s9 are volatile + + default: + break; + } + } else if (name[0] == 'q') { + switch (name[1]) { + case '1': + switch (name[2]) { + case '\0': + return true; // q1 is volatile + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + return true; // q10-q15 are volatile + default: + break; + }; + break; + case '0': + case '2': + case '3': + return name[2] == '\0'; // q0-q3 are volatile + case '8': + case '9': + return name[2] == '\0'; // q8-q9 are volatile + default: + break; + } + } else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') + return true; + } + return false; +} + +void ABIMacOSX_arm::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + "Mac OS X ABI for arm targets", CreateInstance); +} + +void ABIMacOSX_arm::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString ABIMacOSX_arm::GetPluginNameStatic() { + static ConstString g_name("macosx-arm"); + return g_name; +} + +// PluginInterface protocol + +lldb_private::ConstString ABIMacOSX_arm::GetPluginName() { + return GetPluginNameStatic(); +} + +uint32_t ABIMacOSX_arm::GetPluginVersion() { return 1; } diff --git a/gnu/llvm/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h b/gnu/llvm/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h new file mode 100644 index 00000000000..e0fa349eea7 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h @@ -0,0 +1,91 @@ +//===-- ABIMacOSX_arm.h ----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_ARM_ABIMACOSX_ARM_H +#define LLDB_SOURCE_PLUGINS_ABI_ARM_ABIMACOSX_ARM_H + +#include "lldb/Target/ABI.h" +#include "lldb/lldb-private.h" + +class ABIMacOSX_arm : public lldb_private::RegInfoBasedABI { +public: + ~ABIMacOSX_arm() override = default; + + size_t GetRedZoneSize() const override; + + bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t func_addr, lldb::addr_t returnAddress, + llvm::ArrayRef args) const override; + + bool GetArgumentValues(lldb_private::Thread &thread, + lldb_private::ValueList &values) const override; + + lldb_private::Status + SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value) override; + + bool + CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override; + + bool CallFrameAddressIsValid(lldb::addr_t cfa) override { + // Make sure the stack call frame addresses are are 4 byte aligned + if (cfa & (4ull - 1ull)) + return false; // Not 4 byte aligned + if (cfa == 0) + return false; // Zero is not a valid stack address + return true; + } + + bool CodeAddressIsValid(lldb::addr_t pc) override { + // Just make sure the address is a valid 32 bit address. Bit zero + // might be set due to Thumb function calls, so don't enforce 2 byte + // alignment + return pc <= UINT32_MAX; + } + + lldb::addr_t FixCodeAddress(lldb::addr_t pc) override { + // ARM uses bit zero to signify a code address is thumb, so we must + // strip bit zero in any code addresses. + return pc & ~(lldb::addr_t)1; + } + + const lldb_private::RegisterInfo * + GetRegisterInfoArray(uint32_t &count) override; + + bool IsArmv7kProcess() const; + + // Static Functions + + static void Initialize(); + + static void Terminate(); + + static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); + + static lldb_private::ConstString GetPluginNameStatic(); + + // PluginInterface protocol + + lldb_private::ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + +protected: + lldb::ValueObjectSP + GetReturnValueObjectImpl(lldb_private::Thread &thread, + lldb_private::CompilerType &ast_type) const override; + +private: + using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance instead. +}; + +#endif // LLDB_SOURCE_PLUGINS_ABI_ARM_ABIMACOSX_ARM_H diff --git a/gnu/llvm/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp b/gnu/llvm/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp new file mode 100644 index 00000000000..1a93bac564f --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp @@ -0,0 +1,2160 @@ +//===-- ABISysV_arm.cpp ---------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABISysV_arm.h" + +#include + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Triple.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#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" +#include "Utility/ARM_DWARF_Registers.h" +#include "Utility/ARM_ehframe_Registers.h" + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(ABISysV_arm) + +static RegisterInfo g_register_infos[] = { + // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME + // DWARF GENERIC PROCESS PLUGIN + // LLDB NATIVE VALUE REGS INVALIDATE REGS + // ========== ======= == === ============= ============ + // ======================= =================== =========================== + // ======================= ====================== ========== + // =============== + {"r0", + "arg1", + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r1", + "arg2", + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r2", + "arg3", + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r3", + "arg4", + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r4", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r5", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r6", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r7", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r8", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r9", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r10", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r11", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r12", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"sp", + "r13", + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"lr", + "r14", + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"pc", + "r15", + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"cpsr", + "psr", + 4, + 0, + eEncodingUint, + eFormatHex, + {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s0", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s1", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s2", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s3", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s4", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s5", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s6", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s7", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s8", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s9", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s10", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s11", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s12", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s13", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s14", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s15", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s16", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s17", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s18", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s19", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s20", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s21", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s22", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s23", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s24", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s25", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s26", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s27", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s28", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s29", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s30", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"s31", + nullptr, + 4, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"fpscr", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d0", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d1", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d2", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d3", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d4", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d5", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d6", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d7", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d8", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d9", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d10", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d11", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d12", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d13", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d14", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d15", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d16", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d17", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d18", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d19", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d20", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d21", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d22", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d23", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d24", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d25", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d26", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d27", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d28", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d29", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d30", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"d31", + nullptr, + 8, + 0, + eEncodingIEEE754, + eFormatFloat, + {LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r8_usr", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r8_usr, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r9_usr", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r9_usr, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r10_usr", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r10_usr, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r11_usr", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r11_usr, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r12_usr", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r12_usr, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r13_usr", + "sp_usr", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r13_usr, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r14_usr", + "lr_usr", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r14_usr, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r8_fiq", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r8_fiq, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r9_fiq", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r9_fiq, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r10_fiq", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r10_fiq, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r11_fiq", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r11_fiq, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r12_fiq", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r12_fiq, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r13_fiq", + "sp_fiq", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r13_fiq, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r14_fiq", + "lr_fiq", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r14_fiq, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r13_irq", + "sp_irq", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r13_irq, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r14_irq", + "lr_irq", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r14_irq, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r13_abt", + "sp_abt", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r13_abt, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r14_abt", + "lr_abt", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r14_abt, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r13_und", + "sp_und", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r13_und, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r14_und", + "lr_und", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r14_und, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r13_svc", + "sp_svc", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r13_svc, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r14_svc", + "lr_svc", + 4, + 0, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, dwarf_r14_svc, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}}; + +static const uint32_t k_num_register_infos = + llvm::array_lengthof(g_register_infos); +static bool g_register_info_names_constified = false; + +const lldb_private::RegisterInfo * +ABISysV_arm::GetRegisterInfoArray(uint32_t &count) { + // Make the C-string names and alt_names for the register infos into const + // C-string values by having the ConstString unique the names in the global + // constant C-string pool. + if (!g_register_info_names_constified) { + g_register_info_names_constified = true; + for (uint32_t i = 0; i < k_num_register_infos; ++i) { + if (g_register_infos[i].name) + g_register_infos[i].name = + ConstString(g_register_infos[i].name).GetCString(); + if (g_register_infos[i].alt_name) + g_register_infos[i].alt_name = + ConstString(g_register_infos[i].alt_name).GetCString(); + } + } + count = k_num_register_infos; + return g_register_infos; +} + +size_t ABISysV_arm::GetRedZoneSize() const { return 0; } + +// Static Functions + +ABISP +ABISysV_arm::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { + 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)) { + return ABISP( + new ABISysV_arm(std::move(process_sp), MakeMCRegisterInfo(arch))); + } + } + + return ABISP(); +} + +bool ABISysV_arm::PrepareTrivialCall(Thread &thread, addr_t sp, + addr_t function_addr, addr_t return_addr, + llvm::ArrayRef args) const { + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return false; + + const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); + const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); + + RegisterValue reg_value; + + const uint8_t reg_names[] = { + LLDB_REGNUM_GENERIC_ARG1, LLDB_REGNUM_GENERIC_ARG2, + LLDB_REGNUM_GENERIC_ARG3, LLDB_REGNUM_GENERIC_ARG4}; + + llvm::ArrayRef::iterator ai = args.begin(), ae = args.end(); + + for (size_t i = 0; i < llvm::array_lengthof(reg_names); ++i) { + if (ai == ae) + break; + + reg_value.SetUInt32(*ai); + if (!reg_ctx->WriteRegister( + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, reg_names[i]), + reg_value)) + return false; + + ++ai; + } + + if (ai != ae) { + // Spill onto the stack + size_t num_stack_regs = ae - ai; + + sp -= (num_stack_regs * 4); + // Keep the stack 8 byte aligned, not that we need to + sp &= ~(8ull - 1ull); + + // just using arg1 to get the right size + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); + + addr_t arg_pos = sp; + + for (; ai != ae; ++ai) { + reg_value.SetUInt32(*ai); + if (reg_ctx + ->WriteRegisterValueToMemory(reg_info, arg_pos, + reg_info->byte_size, reg_value) + .Fail()) + return false; + arg_pos += reg_info->byte_size; + } + } + + TargetSP target_sp(thread.CalculateTarget()); + Address so_addr; + + // Figure out if our return address is ARM or Thumb by using the + // Address::GetCallableLoadAddress(Target*) which will figure out the ARM + // thumb-ness and set the correct address bits for us. + so_addr.SetLoadAddress(return_addr, target_sp.get()); + return_addr = so_addr.GetCallableLoadAddress(target_sp.get()); + + // Set "lr" to the return address + if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_num, return_addr)) + return false; + + // Set "sp" to the requested value + if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp)) + return false; + + // If bit zero or 1 is set, this must be a thumb function, no need to figure + // this out from the symbols. + so_addr.SetLoadAddress(function_addr, target_sp.get()); + function_addr = so_addr.GetCallableLoadAddress(target_sp.get()); + + const RegisterInfo *cpsr_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS); + const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0); + + // Make a new CPSR and mask out any Thumb IT (if/then) bits + uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK; + // If bit zero or 1 is set, this must be thumb... + if (function_addr & 1ull) + new_cpsr |= MASK_CPSR_T; // Set T bit in CPSR + else + new_cpsr &= ~MASK_CPSR_T; // Clear T bit in CPSR + + if (new_cpsr != curr_cpsr) { + if (!reg_ctx->WriteRegisterFromUnsigned(cpsr_reg_info, new_cpsr)) + return false; + } + + function_addr &= + ~1ull; // clear bit zero since the CPSR will take care of the mode for us + + // Set "pc" to the address requested + return reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, function_addr); +} + +bool ABISysV_arm::GetArgumentValues(Thread &thread, ValueList &values) const { + uint32_t num_values = values.GetSize(); + + ExecutionContext exe_ctx(thread.shared_from_this()); + // For now, assume that the types in the AST values come from the Target's + // scratch AST. + + // Extract the register context so we can read arguments from registers + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + + if (!reg_ctx) + return false; + + addr_t sp = 0; + + for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) { + // We currently only support extracting values with Clang QualTypes. Do we + // care about others? + Value *value = values.GetValueAtIndex(value_idx); + + if (!value) + return false; + + CompilerType compiler_type = value->GetCompilerType(); + if (compiler_type) { + bool is_signed = false; + size_t bit_width = 0; + 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; + } + + if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) { + if (value_idx < 4) { + // Arguments 1-4 are in r0-r3... + const RegisterInfo *arg_reg_info = nullptr; + arg_reg_info = reg_ctx->GetRegisterInfo( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx); + if (arg_reg_info) { + RegisterValue reg_value; + + if (reg_ctx->ReadRegister(arg_reg_info, reg_value)) { + if (is_signed) + reg_value.SignExtend(bit_width); + if (!reg_value.GetScalarValue(value->GetScalar())) + return false; + continue; + } + } + return false; + } else { + if (sp == 0) { + // Read the stack pointer if it already hasn't been read + sp = reg_ctx->GetSP(0); + if (sp == 0) + return false; + } + + // 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; + } + } + } + } + return true; +} + +static bool GetReturnValuePassedInMemory(Thread &thread, + RegisterContext *reg_ctx, + size_t byte_size, Value &value) { + Status error; + DataBufferHeap buffer(byte_size, 0); + + const RegisterInfo *r0_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); + uint32_t address = + reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; + thread.GetProcess()->ReadMemory(address, buffer.GetBytes(), + buffer.GetByteSize(), error); + + if (error.Fail()) + return false; + + value.SetBytes(buffer.GetBytes(), buffer.GetByteSize()); + return true; +} + +bool ABISysV_arm::IsArmHardFloat(Thread &thread) const { + ProcessSP process_sp(thread.GetProcess()); + if (process_sp) { + const ArchSpec &arch(process_sp->GetTarget().GetArchitecture()); + + return (arch.GetFlags() & ArchSpec::eARM_abi_hard_float) != 0; + } + + return false; +} + +ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl( + Thread &thread, lldb_private::CompilerType &compiler_type) const { + Value value; + ValueObjectSP return_valobj_sp; + + if (!compiler_type) + return return_valobj_sp; + + // value.SetContext (Value::eContextTypeClangType, + // compiler_type.GetOpaqueQualType()); + value.SetCompilerType(compiler_type); + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return return_valobj_sp; + + bool is_signed; + bool is_complex; + uint32_t float_count; + bool is_vfp_candidate = false; + uint8_t vfp_count = 0; + uint8_t vfp_byte_size = 0; + + // Get the pointer to the first stack argument so we have a place to start + // when reading data + + const RegisterInfo *r0_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); + 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) { + default: + return return_valobj_sp; + case 64: { + const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2); + uint64_t raw_value; + raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; + raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) & + UINT32_MAX)) + << 32; + if (is_signed) + value.GetScalar() = (int64_t)raw_value; + else + value.GetScalar() = (uint64_t)raw_value; + } break; + case 32: + if (is_signed) + value.GetScalar() = (int32_t)( + reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX); + else + value.GetScalar() = (uint32_t)( + reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX); + break; + case 16: + if (is_signed) + value.GetScalar() = (int16_t)( + reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX); + else + value.GetScalar() = (uint16_t)( + reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX); + break; + case 8: + if (is_signed) + value.GetScalar() = (int8_t)( + reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX); + else + value.GetScalar() = (uint8_t)( + reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX); + break; + } + } else if (compiler_type.IsPointerType()) { + uint32_t ptr = + thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) & + UINT32_MAX; + value.GetScalar() = ptr; + } else if (compiler_type.IsVectorType(nullptr, nullptr)) { + 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) { + DataBufferHeap buffer(16, 0); + uint32_t *buffer_ptr = (uint32_t *)buffer.GetBytes(); + + 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); + } else { + 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) { + default: + return return_valobj_sp; + case 64: { + static_assert(sizeof(double) == sizeof(uint64_t), ""); + + if (IsArmHardFloat(thread)) { + RegisterValue reg_value; + const RegisterInfo *d0_reg_info = + reg_ctx->GetRegisterInfoByName("d0", 0); + reg_ctx->ReadRegister(d0_reg_info, reg_value); + value.GetScalar() = reg_value.GetAsDouble(); + } else { + uint64_t raw_value; + const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2); + raw_value = + reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; + raw_value |= + ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) & + UINT32_MAX)) + << 32; + value.GetScalar() = *reinterpret_cast(&raw_value); + } + break; + } + case 16: // Half precision returned after a conversion to single precision + case 32: { + static_assert(sizeof(float) == sizeof(uint32_t), ""); + + if (IsArmHardFloat(thread)) { + RegisterValue reg_value; + const RegisterInfo *s0_reg_info = + reg_ctx->GetRegisterInfoByName("s0", 0); + reg_ctx->ReadRegister(s0_reg_info, reg_value); + value.GetScalar() = reg_value.GetAsFloat(); + } else { + uint32_t raw_value; + raw_value = + reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; + value.GetScalar() = *reinterpret_cast(&raw_value); + } + break; + } + } + } else if (is_complex && float_count == 2) { + if (IsArmHardFloat(thread)) { + is_vfp_candidate = true; + vfp_byte_size = *byte_size / 2; + vfp_count = 2; + } else if (!GetReturnValuePassedInMemory(thread, reg_ctx, *bit_width / 8, + value)) + return return_valobj_sp; + } else + // not handled yet + return return_valobj_sp; + } else if (compiler_type.IsAggregateType()) { + if (IsArmHardFloat(thread)) { + CompilerType base_type; + const uint32_t homogeneous_count = + 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)) { + if (base_byte_size && + (*base_byte_size == 8 || *base_byte_size == 16)) { + is_vfp_candidate = true; + vfp_byte_size = 8; + 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; + if (base_byte_size) + vfp_byte_size = *base_byte_size; + vfp_count = homogeneous_count; + } + } + } else if (homogeneous_count == 0) { + const uint32_t num_children = compiler_type.GetNumFields(); + + if (num_children > 0 && num_children <= 2) { + uint32_t index = 0; + for (index = 0; index < num_children; index++) { + std::string name; + base_type = compiler_type.GetFieldAtIndex(index, name, nullptr, + nullptr, nullptr); + + 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 && base_byte_size && + vfp_byte_size != *base_byte_size) + break; + else if (base_byte_size) + vfp_byte_size = *base_byte_size; + } else + break; + } else + break; + } + + if (index == num_children) { + is_vfp_candidate = true; + vfp_byte_size = (vfp_byte_size >> 1); + vfp_count = (num_children << 1); + } + } + } + } + + 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); + } else if (!is_vfp_candidate) { + if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value)) + return return_valobj_sp; + } + } else { + // not handled yet + return return_valobj_sp; + } + + if (is_vfp_candidate) { + ProcessSP process_sp(thread.GetProcess()); + ByteOrder byte_order = process_sp->GetByteOrder(); + + 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++) { + uint32_t regnum = 0; + + if (vfp_byte_size == 4) + regnum = dwarf_s0 + reg_index; + else if (vfp_byte_size == 8) + regnum = dwarf_d0 + reg_index; + else + break; + + const RegisterInfo *reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindDWARF, regnum); + if (reg_info == nullptr) + break; + + RegisterValue reg_value; + if (!reg_ctx->ReadRegister(reg_info, reg_value)) + break; + + // Make sure we have enough room in "data_sp" + if ((data_offset + vfp_byte_size) <= data_sp->GetByteSize()) { + Status error; + const size_t bytes_copied = reg_value.GetAsMemoryData( + reg_info, data_sp->GetBytes() + data_offset, vfp_byte_size, + byte_order, error); + if (bytes_copied != vfp_byte_size) + break; + + data_offset += bytes_copied; + } + } + + if (data_offset == *byte_size) { + DataExtractor data; + data.SetByteOrder(byte_order); + data.SetAddressByteSize(process_sp->GetAddressByteSize()); + data.SetData(data_sp); + + return ValueObjectConstResult::Create(&thread, compiler_type, + ConstString(""), data); + } else { // Some error occurred while getting values from registers + return return_valobj_sp; + } + } + + // If we get here, we have a valid Value, so make our ValueObject out of it: + + return_valobj_sp = ValueObjectConstResult::Create( + thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); + return return_valobj_sp; +} + +Status ABISysV_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value_sp) { + Status error; + if (!new_value_sp) { + error.SetErrorString("Empty value object for return value."); + return error; + } + + CompilerType compiler_type = new_value_sp->GetCompilerType(); + if (!compiler_type) { + error.SetErrorString("Null clang type for return value."); + return error; + } + + Thread *thread = frame_sp->GetThread().get(); + + bool is_signed; + uint32_t count; + bool is_complex; + + RegisterContext *reg_ctx = thread->GetRegisterContext().get(); + + bool set_it_simple = false; + if (compiler_type.IsIntegerOrEnumerationType(is_signed) || + compiler_type.IsPointerType()) { + DataExtractor data; + Status data_error; + size_t num_bytes = new_value_sp->GetData(data, data_error); + if (data_error.Fail()) { + error.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", + data_error.AsCString()); + return error; + } + lldb::offset_t offset = 0; + if (num_bytes <= 8) { + const RegisterInfo *r0_info = reg_ctx->GetRegisterInfo( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); + if (num_bytes <= 4) { + uint32_t raw_value = data.GetMaxU32(&offset, num_bytes); + + if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value)) + set_it_simple = true; + } else { + uint32_t raw_value = data.GetMaxU32(&offset, 4); + + if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value)) { + const RegisterInfo *r1_info = reg_ctx->GetRegisterInfo( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2); + uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset); + + if (reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value)) + set_it_simple = true; + } + } + } else { + error.SetErrorString("We don't support returning longer than 64 bit " + "integer values at present."); + } + } else if (compiler_type.IsFloatingPointType(count, is_complex)) { + if (is_complex) + error.SetErrorString( + "We don't support returning complex values at present"); + else + error.SetErrorString( + "We don't support returning float values at present"); + } + + if (!set_it_simple) + error.SetErrorString( + "We only support setting simple integer return types at present."); + + return error; +} + +bool ABISysV_arm::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t lr_reg_num = dwarf_lr; + uint32_t sp_reg_num = dwarf_sp; + uint32_t pc_reg_num = dwarf_pc; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + + // Our Call Frame Address is the stack pointer value + row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0); + + // The previous PC is in the LR + row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true); + unwind_plan.AppendRow(row); + + // All other registers are the same. + + unwind_plan.SetSourceName("arm at-func-entry default"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + + return true; +} + +bool ABISysV_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + // TODO: Handle thumb + uint32_t fp_reg_num = dwarf_r11; + uint32_t pc_reg_num = dwarf_pc; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + const int32_t ptr_size = 4; + + row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size); + row->SetOffset(0); + + row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); + row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); + + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("arm default unwind plan"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); + + return true; +} + +// cf. "ARMv6 Function Calling Conventions" + +// ARMv7 on GNU/Linux general purpose reg rules: +// r0-r3 not preserved (used for argument passing) +// r4-r11 preserved (v1-v8) +// r12 not presrved +// r13 preserved (stack pointer) +// r14 preserved (link register) +// r15 preserved (pc) +// cpsr not preserved (different rules for different bits) + +// ARMv7 VFP register rules: +// d0-d7 not preserved (aka s0-s15, q0-q3) +// d8-d15 preserved (aka s16-s31, q4-q7) +// d16-d31 not preserved (aka q8-q15) + +bool ABISysV_arm::RegisterIsVolatile(const RegisterInfo *reg_info) { + if (reg_info) { + // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp) + const char *name = reg_info->name; + if (name[0] == 'r') { + switch (name[1]) { + case '0': + return name[2] == '\0'; // r0 + case '1': + switch (name[2]) { + case '\0': + return true; // r1 + case '2': + return name[3] == '\0'; // r12 + default: + break; + } + break; + + case '2': + return name[2] == '\0'; // r2 + case '3': + return name[2] == '\0'; // r3 + default: + break; + } + } else if (name[0] == 'd') { + switch (name[1]) { + case '0': + return name[2] == '\0'; // d0 is volatile + + case '1': + switch (name[2]) { + case '\0': + return true; // d1 is volatile + case '6': + case '7': + case '8': + case '9': + return name[3] == '\0'; // d16 - d19 are volatile + default: + break; + } + break; + + case '2': + switch (name[2]) { + case '\0': + return true; // d2 is volatile + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return name[3] == '\0'; // d20 - d29 are volatile + default: + break; + } + break; + + case '3': + switch (name[2]) { + case '\0': + return true; // d3 is volatile + case '0': + case '1': + return name[3] == '\0'; // d30 - d31 are volatile + default: + break; + } + break; + case '4': + case '5': + case '6': + case '7': + return name[2] == '\0'; // d4 - d7 are volatile + + default: + break; + } + } else if (name[0] == 's') { + switch (name[1]) { + case '0': + return name[2] == '\0'; // s0 is volatile + + case '1': + switch (name[2]) { + case '\0': + return true; // s1 is volatile + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + return name[3] == '\0'; // s10 - s15 are volatile + default: + break; + } + break; + + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return name[2] == '\0'; // s2 - s9 are volatile + + default: + break; + } + } else if (name[0] == 'q') { + switch (name[1]) { + case '1': + switch (name[2]) { + case '\0': + return true; // q1 is volatile + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + return true; // q10-q15 are volatile + default: + return false; + } + break; + + case '0': + case '2': + case '3': + return name[2] == '\0'; // q0-q3 are volatile + case '8': + case '9': + return name[2] == '\0'; // q8-q9 are volatile + default: + break; + } + } else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') + return true; + } + return false; +} + +void ABISysV_arm::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + "SysV ABI for arm targets", CreateInstance); +} + +void ABISysV_arm::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString ABISysV_arm::GetPluginNameStatic() { + static ConstString g_name("SysV-arm"); + return g_name; +} + +// PluginInterface protocol + +lldb_private::ConstString ABISysV_arm::GetPluginName() { + return GetPluginNameStatic(); +} + +uint32_t ABISysV_arm::GetPluginVersion() { return 1; } diff --git a/gnu/llvm/lldb/source/Plugins/ABI/ARM/ABISysV_arm.h b/gnu/llvm/lldb/source/Plugins/ABI/ARM/ABISysV_arm.h new file mode 100644 index 00000000000..f28f75ce4fe --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/ARM/ABISysV_arm.h @@ -0,0 +1,91 @@ +//===-- ABISysV_arm.h ----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_ARM_ABISYSV_ARM_H +#define LLDB_SOURCE_PLUGINS_ABI_ARM_ABISYSV_ARM_H + +#include "lldb/Target/ABI.h" +#include "lldb/lldb-private.h" + +class ABISysV_arm : public lldb_private::RegInfoBasedABI { +public: + ~ABISysV_arm() override = default; + + size_t GetRedZoneSize() const override; + + bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t func_addr, lldb::addr_t returnAddress, + llvm::ArrayRef args) const override; + + bool GetArgumentValues(lldb_private::Thread &thread, + lldb_private::ValueList &values) const override; + + lldb_private::Status + SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value) override; + + bool + CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override; + + bool CallFrameAddressIsValid(lldb::addr_t cfa) override { + // Make sure the stack call frame addresses are are 4 byte aligned + if (cfa & (4ull - 1ull)) + return false; // Not 4 byte aligned + if (cfa == 0) + return false; // Zero is not a valid stack address + return true; + } + + bool CodeAddressIsValid(lldb::addr_t pc) override { + // Just make sure the address is a valid 32 bit address. Bit zero + // might be set due to Thumb function calls, so don't enforce 2 byte + // alignment + return pc <= UINT32_MAX; + } + + lldb::addr_t FixCodeAddress(lldb::addr_t pc) override { + // ARM uses bit zero to signify a code address is thumb, so we must + // strip bit zero in any code addresses. + return pc & ~(lldb::addr_t)1; + } + + const lldb_private::RegisterInfo * + GetRegisterInfoArray(uint32_t &count) override; + + bool IsArmHardFloat(lldb_private::Thread &thread) const; + + // Static Functions + + static void Initialize(); + + static void Terminate(); + + static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); + + static lldb_private::ConstString GetPluginNameStatic(); + + // PluginInterface protocol + + lldb_private::ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + +protected: + lldb::ValueObjectSP + GetReturnValueObjectImpl(lldb_private::Thread &thread, + lldb_private::CompilerType &ast_type) const override; + +private: + using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance instead. +}; + +#endif // LLDB_SOURCE_PLUGINS_ABI_ARM_ABISYSV_ARM_H diff --git a/gnu/llvm/lldb/source/Plugins/ABI/ARM/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/ABI/ARM/CMakeLists.txt new file mode 100644 index 00000000000..0082296e5ad --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/ARM/CMakeLists.txt @@ -0,0 +1,13 @@ +add_lldb_library(lldbPluginABIARM PLUGIN + ABIARM.cpp + ABIMacOSX_arm.cpp + ABISysV_arm.cpp + + LINK_LIBS + lldbCore + lldbSymbol + lldbTarget + lldbPluginProcessUtility + LINK_COMPONENTS + Support + ) diff --git a/gnu/llvm/lldb/source/Plugins/ABI/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/ABI/CMakeLists.txt index 37a54479873..d7cc39be514 100644 --- a/gnu/llvm/lldb/source/Plugins/ABI/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/ABI/CMakeLists.txt @@ -1,31 +1,5 @@ -if ("AArch64" IN_LIST LLVM_TARGETS_TO_BUILD) - add_subdirectory(MacOSX-arm64) - add_subdirectory(SysV-arm64) -endif() -if ("ARM" IN_LIST LLVM_TARGETS_TO_BUILD) - add_subdirectory(MacOSX-arm) - add_subdirectory(SysV-arm) -endif() -if ("ARC" IN_LIST LLVM_TARGETS_TO_BUILD) - add_subdirectory(SysV-arc) -endif() -if ("Hexagon" IN_LIST LLVM_TARGETS_TO_BUILD) - add_subdirectory(SysV-hexagon) -endif() -if ("Mips" IN_LIST LLVM_TARGETS_TO_BUILD) - add_subdirectory(SysV-mips) - add_subdirectory(SysV-mips64) -endif() -if ("PowerPC" IN_LIST LLVM_TARGETS_TO_BUILD) - add_subdirectory(SysV-ppc) - add_subdirectory(SysV-ppc64) -endif() -if ("SystemZ" IN_LIST LLVM_TARGETS_TO_BUILD) - add_subdirectory(SysV-s390x) -endif() -if ("X86" IN_LIST LLVM_TARGETS_TO_BUILD) - add_subdirectory(SysV-i386) - add_subdirectory(SysV-x86_64) - add_subdirectory(MacOSX-i386) - add_subdirectory(Windows-x86_64) -endif() +foreach(target AArch64 ARM ARC Hexagon Mips PowerPC SystemZ X86) + if (${target} IN_LIST LLVM_TARGETS_TO_BUILD) + add_subdirectory(${target}) + endif() +endforeach() diff --git a/gnu/llvm/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp b/gnu/llvm/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp new file mode 100644 index 00000000000..32313d4cd81 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp @@ -0,0 +1,1357 @@ +//===-- ABISysV_hexagon.cpp -----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABISysV_hexagon.h" + +#include "llvm/ADT/Triple.h" +#include "llvm/IR/DerivedTypes.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Core/ValueObjectMemory.h" +#include "lldb/Core/ValueObjectRegister.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Status.h" + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE_ADV(ABISysV_hexagon, ABIHexagon) + +static RegisterInfo g_register_infos[] = { + // hexagon-core.xml + {"r00", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {0, 0, LLDB_INVALID_REGNUM, 0, 0}, + nullptr, + nullptr, + nullptr, + 0}, + {"r01", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {1, 1, LLDB_INVALID_REGNUM, 1, 1}, + nullptr, + nullptr, + nullptr, + 0}, + {"r02", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {2, 2, LLDB_INVALID_REGNUM, 2, 2}, + nullptr, + nullptr, + nullptr, + 0}, + {"r03", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {3, 3, LLDB_INVALID_REGNUM, 3, 3}, + nullptr, + nullptr, + nullptr, + 0}, + {"r04", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {4, 4, LLDB_INVALID_REGNUM, 4, 4}, + nullptr, + nullptr, + nullptr, + 0}, + {"r05", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {5, 5, LLDB_INVALID_REGNUM, 5, 5}, + nullptr, + nullptr, + nullptr, + 0}, + {"r06", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {6, 6, LLDB_INVALID_REGNUM, 6, 6}, + nullptr, + nullptr, + nullptr, + 0}, + {"r07", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {7, 7, LLDB_INVALID_REGNUM, 7, 7}, + nullptr, + nullptr, + nullptr, + 0}, + {"r08", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {8, 8, LLDB_INVALID_REGNUM, 8, 8}, + nullptr, + nullptr, + nullptr, + 0}, + {"r09", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {9, 9, LLDB_INVALID_REGNUM, 9, 9}, + nullptr, + nullptr, + nullptr, + 0}, + {"r10", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {10, 10, LLDB_INVALID_REGNUM, 10, 10}, + nullptr, + nullptr, + nullptr, + 0}, + {"r11", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {11, 11, LLDB_INVALID_REGNUM, 11, 11}, + nullptr, + nullptr, + nullptr, + 0}, + {"r12", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {12, 12, LLDB_INVALID_REGNUM, 12, 12}, + nullptr, + nullptr, + nullptr, + 0}, + {"r13", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {13, 13, LLDB_INVALID_REGNUM, 13, 13}, + nullptr, + nullptr, + nullptr, + 0}, + {"r14", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {14, 14, LLDB_INVALID_REGNUM, 14, 14}, + nullptr, + nullptr, + nullptr, + 0}, + {"r15", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {15, 15, LLDB_INVALID_REGNUM, 15, 15}, + nullptr, + nullptr, + nullptr, + 0}, + {"r16", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {16, 16, LLDB_INVALID_REGNUM, 16, 16}, + nullptr, + nullptr, + nullptr, + 0}, + {"r17", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {17, 17, LLDB_INVALID_REGNUM, 17, 17}, + nullptr, + nullptr, + nullptr, + 0}, + {"r18", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {18, 18, LLDB_INVALID_REGNUM, 18, 18}, + nullptr, + nullptr, + nullptr, + 0}, + {"r19", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {19, 19, LLDB_INVALID_REGNUM, 19, 19}, + nullptr, + nullptr, + nullptr, + 0}, + {"r20", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {20, 20, LLDB_INVALID_REGNUM, 20, 20}, + nullptr, + nullptr, + nullptr, + 0}, + {"r21", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {21, 21, LLDB_INVALID_REGNUM, 21, 21}, + nullptr, + nullptr, + nullptr, + 0}, + {"r22", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {22, 22, LLDB_INVALID_REGNUM, 22, 22}, + nullptr, + nullptr, + nullptr, + 0}, + {"r23", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {23, 23, LLDB_INVALID_REGNUM, 23, 23}, + nullptr, + nullptr, + nullptr, + 0}, + {"r24", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {24, 24, LLDB_INVALID_REGNUM, 24, 24}, + nullptr, + nullptr, + nullptr, + 0}, + {"r25", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {25, 25, LLDB_INVALID_REGNUM, 25, 25}, + nullptr, + nullptr, + nullptr, + 0}, + {"r26", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {26, 26, LLDB_INVALID_REGNUM, 26, 26}, + nullptr, + nullptr, + nullptr, + 0}, + {"r27", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {27, 27, LLDB_INVALID_REGNUM, 27, 27}, + nullptr, + nullptr, + nullptr, + 0}, + {"r28", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {28, 28, LLDB_INVALID_REGNUM, 28, 28}, + nullptr, + nullptr, + nullptr, + 0}, + {"sp", + "r29", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {29, 29, LLDB_REGNUM_GENERIC_SP, 29, 29}, + nullptr, + nullptr, + nullptr, + 0}, + {"fp", + "r30", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {30, 30, LLDB_REGNUM_GENERIC_FP, 30, 30}, + nullptr, + nullptr, + nullptr, + 0}, + {"lr", + "r31", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {31, 31, LLDB_REGNUM_GENERIC_RA, 31, 31}, + nullptr, + nullptr, + nullptr, + 0}, + {"sa0", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {32, 32, LLDB_INVALID_REGNUM, 32, 32}, + nullptr, + nullptr, + nullptr, + 0}, + {"lc0", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {33, 33, LLDB_INVALID_REGNUM, 33, 33}, + nullptr, + nullptr, + nullptr, + 0}, + {"sa1", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {34, 34, LLDB_INVALID_REGNUM, 34, 34}, + nullptr, + nullptr, + nullptr, + 0}, + {"lc1", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {35, 35, LLDB_INVALID_REGNUM, 35, 35}, + nullptr, + nullptr, + nullptr, + 0}, + // --> hexagon-v4/5/55/56-sim.xml + {"p3_0", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {36, 36, LLDB_INVALID_REGNUM, 36, 36}, + nullptr, + nullptr, + nullptr, + 0}, + // PADDING { + {"p00", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {37, 37, LLDB_INVALID_REGNUM, 37, 37}, + nullptr, + nullptr, + nullptr, + 0}, + // } + {"m0", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {38, 38, LLDB_INVALID_REGNUM, 38, 38}, + nullptr, + nullptr, + nullptr, + 0}, + {"m1", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {39, 39, LLDB_INVALID_REGNUM, 39, 39}, + nullptr, + nullptr, + nullptr, + 0}, + {"usr", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {40, 40, LLDB_INVALID_REGNUM, 40, 40}, + nullptr, + nullptr, + nullptr, + 0}, + {"pc", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41}, + nullptr, + nullptr, + nullptr, + 0}, + {"ugp", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {42, 42, LLDB_INVALID_REGNUM, 42, 42}, + nullptr, + nullptr, + nullptr, + 0}, + {"gp", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {43, 43, LLDB_INVALID_REGNUM, 43, 43}, + nullptr, + nullptr, + nullptr, + 0}, + {"cs0", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {44, 44, LLDB_INVALID_REGNUM, 44, 44}, + nullptr, + nullptr, + nullptr, + 0}, + {"cs1", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {45, 45, LLDB_INVALID_REGNUM, 45, 45}, + nullptr, + nullptr, + nullptr, + 0}, + // PADDING { + {"p01", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {46, 46, LLDB_INVALID_REGNUM, 46, 46}, + nullptr, + nullptr, + nullptr, + 0}, + {"p02", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {47, 47, LLDB_INVALID_REGNUM, 47, 47}, + nullptr, + nullptr, + nullptr, + 0}, + {"p03", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {48, 48, LLDB_INVALID_REGNUM, 48, 48}, + nullptr, + nullptr, + nullptr, + 0}, + {"p04", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {49, 49, LLDB_INVALID_REGNUM, 49, 49}, + nullptr, + nullptr, + nullptr, + 0}, + {"p05", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {50, 50, LLDB_INVALID_REGNUM, 50, 50}, + nullptr, + nullptr, + nullptr, + 0}, + {"p06", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {51, 51, LLDB_INVALID_REGNUM, 51, 51}, + nullptr, + nullptr, + nullptr, + 0}, + {"p07", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {52, 52, LLDB_INVALID_REGNUM, 52, 52}, + nullptr, + nullptr, + nullptr, + 0}, + {"p08", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {53, 53, LLDB_INVALID_REGNUM, 53, 53}, + nullptr, + nullptr, + nullptr, + 0}, + {"p09", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {54, 54, LLDB_INVALID_REGNUM, 54, 54}, + nullptr, + nullptr, + nullptr, + 0}, + {"p10", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {55, 55, LLDB_INVALID_REGNUM, 55, 55}, + nullptr, + nullptr, + nullptr, + 0}, + {"p11", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {56, 56, LLDB_INVALID_REGNUM, 56, 56}, + nullptr, + nullptr, + nullptr, + 0}, + {"p12", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {57, 57, LLDB_INVALID_REGNUM, 57, 57}, + nullptr, + nullptr, + nullptr, + 0}, + {"p13", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {58, 58, LLDB_INVALID_REGNUM, 58, 58}, + nullptr, + nullptr, + nullptr, + 0}, + {"p14", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {59, 59, LLDB_INVALID_REGNUM, 59, 59}, + nullptr, + nullptr, + nullptr, + 0}, + {"p15", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {60, 60, LLDB_INVALID_REGNUM, 60, 60}, + nullptr, + nullptr, + nullptr, + 0}, + {"p16", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {61, 61, LLDB_INVALID_REGNUM, 61, 61}, + nullptr, + nullptr, + nullptr, + 0}, + {"p17", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {62, 62, LLDB_INVALID_REGNUM, 62, 62}, + nullptr, + nullptr, + nullptr, + 0}, + {"p18", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {63, 63, LLDB_INVALID_REGNUM, 63, 63}, + nullptr, + nullptr, + nullptr, + 0}, + // } + {"sgp0", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {64, 64, LLDB_INVALID_REGNUM, 64, 64}, + nullptr, + nullptr, + nullptr, + 0}, + // PADDING { + {"p19", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {65, 65, LLDB_INVALID_REGNUM, 65, 65}, + nullptr, + nullptr, + nullptr, + 0}, + // } + {"stid", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {66, 66, LLDB_INVALID_REGNUM, 66, 66}, + nullptr, + nullptr, + nullptr, + 0}, + {"elr", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {67, 67, LLDB_INVALID_REGNUM, 67, 67}, + nullptr, + nullptr, + nullptr, + 0}, + {"badva0", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {68, 68, LLDB_INVALID_REGNUM, 68, 68}, + nullptr, + nullptr, + nullptr, + 0}, + {"badva1", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {69, 69, LLDB_INVALID_REGNUM, 69, 69}, + nullptr, + nullptr, + nullptr, + 0}, + {"ssr", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {70, 70, LLDB_INVALID_REGNUM, 70, 70}, + nullptr, + nullptr, + nullptr, + 0}, + {"ccr", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {71, 71, LLDB_INVALID_REGNUM, 71, 71}, + nullptr, + nullptr, + nullptr, + 0}, + {"htid", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {72, 72, LLDB_INVALID_REGNUM, 72, 72}, + nullptr, + nullptr, + nullptr, + 0}, + // PADDING { + {"p20", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {73, 73, LLDB_INVALID_REGNUM, 73, 73}, + nullptr, + nullptr, + nullptr, + 0}, + // } + {"imask", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {74, 74, LLDB_INVALID_REGNUM, 74, 74}, + nullptr, + nullptr, + nullptr, + 0}, + // PADDING { + {"p21", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {75, 75, LLDB_INVALID_REGNUM, 75, 75}, + nullptr, + nullptr, + nullptr, + 0}, + {"p22", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {76, 76, LLDB_INVALID_REGNUM, 76, 76}, + nullptr, + nullptr, + nullptr, + 0}, + {"p23", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {77, 77, LLDB_INVALID_REGNUM, 77, 77}, + nullptr, + nullptr, + nullptr, + 0}, + {"p24", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {78, 78, LLDB_INVALID_REGNUM, 78, 78}, + nullptr, + nullptr, + nullptr, + 0}, + {"p25", + "", + 4, + 0, + eEncodingInvalid, + eFormatInvalid, + {79, 79, LLDB_INVALID_REGNUM, 79, 79}, + nullptr, + nullptr, + nullptr, + 0}, + // } + {"g0", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {80, 80, LLDB_INVALID_REGNUM, 80, 80}, + nullptr, + nullptr, + nullptr, + 0}, + {"g1", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {81, 81, LLDB_INVALID_REGNUM, 81, 81}, + nullptr, + nullptr, + nullptr, + 0}, + {"g2", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {82, 82, LLDB_INVALID_REGNUM, 82, 82}, + nullptr, + nullptr, + nullptr, + 0}, + {"g3", + "", + 4, + 0, + eEncodingUint, + eFormatAddressInfo, + {83, 83, LLDB_INVALID_REGNUM, 83, 83}, + nullptr, + nullptr, + nullptr, + 0}}; + +static const uint32_t k_num_register_infos = + sizeof(g_register_infos) / sizeof(RegisterInfo); +static bool g_register_info_names_constified = false; + +const lldb_private::RegisterInfo * +ABISysV_hexagon::GetRegisterInfoArray(uint32_t &count) { + // Make the C-string names and alt_names for the register infos into const + // C-string values by having the ConstString unique the names in the global + // constant C-string pool. + if (!g_register_info_names_constified) { + g_register_info_names_constified = true; + for (uint32_t i = 0; i < k_num_register_infos; ++i) { + if (g_register_infos[i].name) + g_register_infos[i].name = + ConstString(g_register_infos[i].name).GetCString(); + if (g_register_infos[i].alt_name) + g_register_infos[i].alt_name = + ConstString(g_register_infos[i].alt_name).GetCString(); + } + } + count = k_num_register_infos; + return g_register_infos; +} + +/* + http://en.wikipedia.org/wiki/Red_zone_%28computing%29 + + In computing, a red zone is a fixed size area in memory beyond the stack + pointer that has not been + "allocated". This region of memory is not to be modified by + interrupt/exception/signal handlers. + This allows the space to be used for temporary data without the extra + overhead of modifying the + stack pointer. The x86-64 ABI mandates a 128 byte red zone.[1] The OpenRISC + toolchain assumes a + 128 byte red zone though it is not documented. +*/ +size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; } + +// Static Functions + +ABISP +ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { + if (arch.GetTriple().getArch() == llvm::Triple::hexagon) { + return ABISP( + new ABISysV_hexagon(std::move(process_sp), MakeMCRegisterInfo(arch))); + } + return ABISP(); +} + +bool ABISysV_hexagon::PrepareTrivialCall(Thread &thread, lldb::addr_t sp, + lldb::addr_t pc, lldb::addr_t ra, + llvm::ArrayRef args) const { + // we don't use the traditional trivial call specialized for jit + return false; +} + +/* + +// AD: +// . safeguard the current stack +// . how can we know that the called function will create its own frame +properly? +// . we could manually make a new stack first: +// 2. push RA +// 3. push FP +// 4. FP = SP +// 5. SP = SP ( since no locals in our temp frame ) + +// AD 6/05/2014 +// . variable argument list parameters are not passed via registers, they are +passed on +// the stack. This presents us with a problem, since we need to know when +the valist +// starts. Currently I can find out if a function is varg, but not how many +// real parameters it takes. Thus I don't know when to start spilling the +vargs. For +// the time being, to progress, I will assume that it takes on real parameter +before +// the vargs list starts. + +// AD 06/05/2014 +// . how do we adhere to the stack alignment requirements + +// AD 06/05/2014 +// . handle 64bit values and their register / stack requirements + +*/ +#define HEX_ABI_DEBUG 0 +bool ABISysV_hexagon::PrepareTrivialCall( + Thread &thread, lldb::addr_t sp, lldb::addr_t pc, lldb::addr_t ra, + llvm::Type &prototype, llvm::ArrayRef args) const { + // default number of register passed arguments for varg functions + const int nVArgRegParams = 1; + Status error; + + // grab the process so we have access to the memory for spilling + lldb::ProcessSP proc = thread.GetProcess(); + + // get the register context for modifying all of the registers + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return false; + + uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + if (pc_reg == LLDB_INVALID_REGNUM) + return false; + + uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); + if (ra_reg == LLDB_INVALID_REGNUM) + return false; + + uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); + if (sp_reg == LLDB_INVALID_REGNUM) + return false; + + // push host data onto target + for (size_t i = 0; i < args.size(); i++) { + const ABI::CallArgument &arg = args[i]; + // skip over target values + if (arg.type == ABI::CallArgument::TargetValue) + continue; + // round up to 8 byte multiple + size_t argSize = (arg.size | 0x7) + 1; + + // create space on the stack for this data + sp -= argSize; + + // write this argument onto the stack of the host process + proc->WriteMemory(sp, arg.data_up.get(), arg.size, error); + if (error.Fail()) + return false; + + // update the argument with the target pointer + // XXX: This is a gross hack for getting around the const + *const_cast(&arg.value) = sp; + } + +#if HEX_ABI_DEBUG + // print the original stack pointer + printf("sp : %04" PRIx64 " \n", sp); +#endif + + // make sure number of parameters matches prototype + assert(prototype.getFunctionNumParams() == args.size()); + + // check if this is a variable argument function + bool isVArg = prototype.isFunctionVarArg(); + + // number of arguments passed by register + int nRegArgs = nVArgRegParams; + if (!isVArg) { + // number of arguments is limited by [R0 : R5] space + nRegArgs = args.size(); + if (nRegArgs > 6) + nRegArgs = 6; + } + + // pass arguments that are passed via registers + for (int i = 0; i < nRegArgs; i++) { + // get the parameter as a u32 + uint32_t param = (uint32_t)args[i].value; + // write argument into register + if (!reg_ctx->WriteRegisterFromUnsigned(i, param)) + return false; + } + + // number of arguments to spill onto stack + int nSpillArgs = args.size() - nRegArgs; + // make space on the stack for arguments + sp -= 4 * nSpillArgs; + // align stack on an 8 byte boundary + if (sp & 7) + sp -= 4; + + // arguments that are passed on the stack + for (size_t i = nRegArgs, offs = 0; i < args.size(); i++) { + // get the parameter as a u32 + uint32_t param = (uint32_t)args[i].value; + // write argument to stack + proc->WriteMemory(sp + offs, (void *)¶m, sizeof(param), error); + if (!error.Success()) + return false; + // + offs += 4; + } + + // update registers with current function call state + reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc); + reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra); + reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp); + +#if HEX_ABI_DEBUG + // quick and dirty stack dumper for debugging + for (int i = -8; i < 8; i++) { + uint32_t data = 0; + lldb::addr_t addr = sp + i * 4; + proc->ReadMemory(addr, (void *)&data, sizeof(data), error); + printf("\n0x%04" PRIx64 " 0x%08x ", addr, data); + if (i == 0) + printf("<<-- sp"); + } + printf("\n"); +#endif + + return true; +} + +bool ABISysV_hexagon::GetArgumentValues(Thread &thread, + ValueList &values) const { + return false; +} + +Status +ABISysV_hexagon::SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value_sp) { + Status error; + return error; +} + +ValueObjectSP ABISysV_hexagon::GetReturnValueObjectSimple( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + return return_valobj_sp; +} + +ValueObjectSP ABISysV_hexagon::GetReturnValueObjectImpl( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + return return_valobj_sp; +} + +// called when we are on the first instruction of a new function for hexagon +// the return address is in RA (R31) +bool ABISysV_hexagon::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindGeneric); + unwind_plan.SetReturnAddressRegister(LLDB_REGNUM_GENERIC_RA); + + UnwindPlan::RowSP row(new UnwindPlan::Row); + + // Our Call Frame Address is the stack pointer value + row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_SP, 4); + row->SetOffset(0); + + // The previous PC is in the LR + row->SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC, + LLDB_REGNUM_GENERIC_RA, true); + unwind_plan.AppendRow(row); + + unwind_plan.SetSourceName("hexagon at-func-entry default"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + return true; +} + +bool ABISysV_hexagon::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindGeneric); + + uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP; + uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP; + uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + + row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP, 8); + + row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, -8, true); + row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, true); + row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); + + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("hexagon default unwind plan"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); + return true; +} + +/* + Register Usage Saved By + + R0 - R5 parameters(a) - + R6 - R15 Scratch(b) Caller + R16 - R27 Scratch Callee + R28 Scratch(b) Caller + R29 - R31 Stack Frames Callee(c) + P3:0 Processor State Caller + + a = the caller can change parameter values + b = R14 - R15 and R28 are used by the procedure linkage table + c = R29 - R31 are saved and restored by allocframe() and deallocframe() +*/ +bool ABISysV_hexagon::RegisterIsVolatile(const RegisterInfo *reg_info) { + return !RegisterIsCalleeSaved(reg_info); +} + +bool ABISysV_hexagon::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { + int reg = ((reg_info->byte_offset) / 4); + + bool save = (reg >= 16) && (reg <= 27); + save |= (reg >= 29) && (reg <= 32); + + return save; +} + +void ABISysV_hexagon::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + "System V ABI for hexagon targets", + CreateInstance); +} + +void ABISysV_hexagon::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString ABISysV_hexagon::GetPluginNameStatic() { + static ConstString g_name("sysv-hexagon"); + return g_name; +} + +// PluginInterface protocol + +lldb_private::ConstString ABISysV_hexagon::GetPluginName() { + return GetPluginNameStatic(); +} + +uint32_t ABISysV_hexagon::GetPluginVersion() { return 1; } + +// get value object specialized to work with llvm IR types +lldb::ValueObjectSP +ABISysV_hexagon::GetReturnValueObjectImpl(lldb_private::Thread &thread, + llvm::Type &retType) const { + Value value; + ValueObjectSP vObjSP; + + // get the current register context + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return vObjSP; + + // for now just pop R0 to find the return value + const lldb_private::RegisterInfo *r0_info = + reg_ctx->GetRegisterInfoAtIndex(0); + if (r0_info == nullptr) + return vObjSP; + + // void return type + if (retType.isVoidTy()) { + value.GetScalar() = 0; + } + // integer / pointer return type + else if (retType.isIntegerTy() || retType.isPointerTy()) { + // read r0 register value + lldb_private::RegisterValue r0_value; + if (!reg_ctx->ReadRegister(r0_info, r0_value)) + return vObjSP; + + // push r0 into value + uint32_t r0_u32 = r0_value.GetAsUInt32(); + + // account for integer size + if (retType.isIntegerTy() && retType.isSized()) { + uint64_t size = retType.getScalarSizeInBits(); + uint64_t mask = (1ull << size) - 1; + // mask out higher order bits then the type we expect + r0_u32 &= mask; + } + + value.GetScalar() = r0_u32; + } + // unsupported return type + else + return vObjSP; + + // pack the value into a ValueObjectSP + vObjSP = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(), + value, ConstString("")); + return vObjSP; +} diff --git a/gnu/llvm/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.h b/gnu/llvm/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.h new file mode 100644 index 00000000000..d6dab0c2e37 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.h @@ -0,0 +1,103 @@ +//===-- ABISysV_hexagon.h ----------------------------------------*- C++ +//-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_HEXAGON_ABISYSV_HEXAGON_H +#define LLDB_SOURCE_PLUGINS_ABI_HEXAGON_ABISYSV_HEXAGON_H + +#include "lldb/Target/ABI.h" +#include "lldb/lldb-private.h" + +class ABISysV_hexagon : public lldb_private::RegInfoBasedABI { +public: + ~ABISysV_hexagon() override = default; + + size_t GetRedZoneSize() const override; + + bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t functionAddress, + lldb::addr_t returnAddress, + llvm::ArrayRef args) const override; + + // special thread plan for GDB style non-jit function calls + bool + PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t functionAddress, lldb::addr_t returnAddress, + llvm::Type &prototype, + llvm::ArrayRef args) const override; + + bool GetArgumentValues(lldb_private::Thread &thread, + lldb_private::ValueList &values) const override; + + lldb_private::Status + SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value) override; + + lldb::ValueObjectSP + GetReturnValueObjectImpl(lldb_private::Thread &thread, + lldb_private::CompilerType &type) const override; + + // specialized to work with llvm IR types + lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, + llvm::Type &type) const override; + + bool + CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override; + + bool CallFrameAddressIsValid(lldb::addr_t cfa) override { + // Make sure the stack call frame addresses are 8 byte aligned + if (cfa & 0x07) + return false; // Not 8 byte aligned + if (cfa == 0) + return false; // Zero is not a valid stack address + return true; + } + + bool CodeAddressIsValid(lldb::addr_t pc) override { + // We have a 64 bit address space, so anything is valid as opcodes + // aren't fixed width... + return true; + } + + const lldb_private::RegisterInfo * + GetRegisterInfoArray(uint32_t &count) override; + + // Static Functions + + static void Initialize(); + + static void Terminate(); + + static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); + + static lldb_private::ConstString GetPluginNameStatic(); + + // PluginInterface protocol + + lldb_private::ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + +protected: + void CreateRegisterMapIfNeeded(); + + lldb::ValueObjectSP + GetReturnValueObjectSimple(lldb_private::Thread &thread, + lldb_private::CompilerType &ast_type) const; + + bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); + +private: + using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance instead. +}; + +#endif // LLDB_SOURCE_PLUGINS_ABI_HEXAGON_ABISYSV_HEXAGON_H diff --git a/gnu/llvm/lldb/source/Plugins/ABI/Hexagon/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/ABI/Hexagon/CMakeLists.txt new file mode 100644 index 00000000000..c985922a7b2 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/Hexagon/CMakeLists.txt @@ -0,0 +1,10 @@ +add_lldb_library(lldbPluginABIHexagon PLUGIN + ABISysV_hexagon.cpp + + LINK_LIBS + lldbCore + lldbSymbol + lldbTarget + LINK_COMPONENTS + Support + ) diff --git a/gnu/llvm/lldb/source/Plugins/ABI/Mips/ABIMips.cpp b/gnu/llvm/lldb/source/Plugins/ABI/Mips/ABIMips.cpp new file mode 100644 index 00000000000..16ef1faf9d9 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/Mips/ABIMips.cpp @@ -0,0 +1,24 @@ +//===-- Mips.h ------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABIMips.h" +#include "ABISysV_mips.h" +#include "ABISysV_mips64.h" +#include "lldb/Core/PluginManager.h" + +LLDB_PLUGIN_DEFINE(ABIMips) + +void ABIMips::Initialize() { + ABISysV_mips::Initialize(); + ABISysV_mips64::Initialize(); +} + +void ABIMips::Terminate() { + ABISysV_mips::Terminate(); + ABISysV_mips64::Terminate(); +} diff --git a/gnu/llvm/lldb/source/Plugins/ABI/Mips/ABIMips.h b/gnu/llvm/lldb/source/Plugins/ABI/Mips/ABIMips.h new file mode 100644 index 00000000000..dc7704de1c9 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/Mips/ABIMips.h @@ -0,0 +1,17 @@ +//===-- Mips.h -----------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_MIPS_ABIMIPS_H +#define LLDB_SOURCE_PLUGINS_ABI_MIPS_ABIMIPS_H + +class ABIMips { +public: + static void Initialize(); + static void Terminate(); +}; +#endif diff --git a/gnu/llvm/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp b/gnu/llvm/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp new file mode 100644 index 00000000000..d66e0926ad9 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp @@ -0,0 +1,1066 @@ +//===-- ABISysV_mips.cpp --------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABISysV_mips.h" + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Triple.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Core/ValueObjectMemory.h" +#include "lldb/Core/ValueObjectRegister.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Status.h" + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(ABISysV_mips) + +enum dwarf_regnums { + dwarf_r0 = 0, + dwarf_r1, + dwarf_r2, + dwarf_r3, + dwarf_r4, + dwarf_r5, + dwarf_r6, + dwarf_r7, + dwarf_r8, + dwarf_r9, + dwarf_r10, + dwarf_r11, + dwarf_r12, + dwarf_r13, + dwarf_r14, + dwarf_r15, + dwarf_r16, + dwarf_r17, + dwarf_r18, + dwarf_r19, + dwarf_r20, + dwarf_r21, + dwarf_r22, + dwarf_r23, + dwarf_r24, + dwarf_r25, + dwarf_r26, + dwarf_r27, + dwarf_r28, + dwarf_r29, + dwarf_r30, + dwarf_r31, + dwarf_sr, + dwarf_lo, + dwarf_hi, + dwarf_bad, + dwarf_cause, + dwarf_pc +}; + +static const RegisterInfo g_register_infos[] = { + // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME + // DWARF GENERIC PROCESS PLUGINS + // LLDB NATIVE VALUE REGS INVALIDATE REGS + // ======== ====== == === ============= =========== ============ + // ============== ============ ================= + // =================== ========== ================= + {"r0", + "zero", + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r1", + "AT", + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r2", + "v0", + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r3", + "v1", + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r4", + "arg1", + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r5", + "arg2", + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r6", + "arg3", + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r7", + "arg4", + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r8", + "arg5", + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r9", + "arg6", + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r10", + "arg7", + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r11", + "arg8", + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r12", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r13", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r14", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r15", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r16", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r17", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r18", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r19", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r20", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r21", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r22", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r23", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r24", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r25", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r26", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r27", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r28", + "gp", + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r29", + "sp", + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r29, dwarf_r29, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r30", + "fp", + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r30, dwarf_r30, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r31", + "ra", + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r31, dwarf_r31, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"sr", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_sr, dwarf_sr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"lo", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_lo, dwarf_lo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"hi", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_hi, dwarf_hi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"bad", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_bad, dwarf_bad, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"cause", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_cause, dwarf_cause, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"pc", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, +}; + +static const uint32_t k_num_register_infos = + llvm::array_lengthof(g_register_infos); + +const lldb_private::RegisterInfo * +ABISysV_mips::GetRegisterInfoArray(uint32_t &count) { + count = k_num_register_infos; + return g_register_infos; +} + +size_t ABISysV_mips::GetRedZoneSize() const { return 0; } + +// Static Functions + +ABISP +ABISysV_mips::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { + const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch(); + if ((arch_type == llvm::Triple::mips) || + (arch_type == llvm::Triple::mipsel)) { + return ABISP( + new ABISysV_mips(std::move(process_sp), MakeMCRegisterInfo(arch))); + } + return ABISP(); +} + +bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp, + addr_t func_addr, addr_t return_addr, + llvm::ArrayRef args) const { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (log) { + StreamString s; + s.Printf("ABISysV_mips::PrepareTrivialCall (tid = 0x%" PRIx64 + ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 + ", return_addr = 0x%" PRIx64, + thread.GetID(), (uint64_t)sp, (uint64_t)func_addr, + (uint64_t)return_addr); + + for (size_t i = 0; i < args.size(); ++i) + s.Printf(", arg%zd = 0x%" PRIx64, i + 1, args[i]); + s.PutCString(")"); + log->PutString(s.GetString()); + } + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return false; + + const RegisterInfo *reg_info = nullptr; + + RegisterValue reg_value; + + // Argument registers + const char *reg_names[] = {"r4", "r5", "r6", "r7"}; + + llvm::ArrayRef::iterator ai = args.begin(), ae = args.end(); + + // Write arguments to registers + for (size_t i = 0; i < llvm::array_lengthof(reg_names); ++i) { + if (ai == ae) + break; + + reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_ARG1 + i); + LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") into %s", i + 1, + args[i], reg_info->name); + + if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) + return false; + + ++ai; + } + + // If we have more than 4 arguments --Spill onto the stack + if (ai != ae) { + // No of arguments to go on stack + size_t num_stack_regs = args.size(); + + // Allocate needed space for args on the stack + sp -= (num_stack_regs * 4); + + // Keep the stack 8 byte aligned + sp &= ~(8ull - 1ull); + + // just using arg1 to get the right size + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); + + addr_t arg_pos = sp + 16; + + size_t i = 4; + for (; ai != ae; ++ai) { + reg_value.SetUInt32(*ai); + LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") at 0x%" PRIx64 "", + i + 1, args[i], arg_pos); + + if (reg_ctx + ->WriteRegisterValueToMemory(reg_info, arg_pos, + reg_info->byte_size, reg_value) + .Fail()) + return false; + arg_pos += reg_info->byte_size; + i++; + } + } + + Status error; + const RegisterInfo *pc_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + const RegisterInfo *sp_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); + const RegisterInfo *ra_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); + const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0); + const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0); + + LLDB_LOGF(log, "Writing R0: 0x%" PRIx64, (uint64_t)0); + + /* Write r0 with 0, in case we are stopped in syscall, + * such setting prevents automatic decrement of the PC. + * This clears the bug 23659 for MIPS. + */ + if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0)) + return false; + + LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp); + + // Set "sp" to the requested value + if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp)) + return false; + + LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr); + + // Set "ra" to the return address + if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr)) + return false; + + LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr); + + // Set pc to the address of the called function. + if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr)) + return false; + + LLDB_LOGF(log, "Writing r25: 0x%" PRIx64, (uint64_t)func_addr); + + // All callers of position independent functions must place the address of + // the called function in t9 (r25) + if (!reg_ctx->WriteRegisterFromUnsigned(r25_info, func_addr)) + return false; + + return true; +} + +bool ABISysV_mips::GetArgumentValues(Thread &thread, ValueList &values) const { + return false; +} + +Status ABISysV_mips::SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value_sp) { + Status error; + if (!new_value_sp) { + error.SetErrorString("Empty value object for return value."); + return error; + } + + CompilerType compiler_type = new_value_sp->GetCompilerType(); + if (!compiler_type) { + error.SetErrorString("Null clang type for return value."); + return error; + } + + Thread *thread = frame_sp->GetThread().get(); + + bool is_signed; + uint32_t count; + bool is_complex; + + RegisterContext *reg_ctx = thread->GetRegisterContext().get(); + + bool set_it_simple = false; + if (compiler_type.IsIntegerOrEnumerationType(is_signed) || + compiler_type.IsPointerType()) { + DataExtractor data; + Status data_error; + size_t num_bytes = new_value_sp->GetData(data, data_error); + if (data_error.Fail()) { + error.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", + data_error.AsCString()); + return error; + } + + lldb::offset_t offset = 0; + if (num_bytes <= 8) { + const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0); + if (num_bytes <= 4) { + uint32_t raw_value = data.GetMaxU32(&offset, num_bytes); + + if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) + set_it_simple = true; + } else { + uint32_t raw_value = data.GetMaxU32(&offset, 4); + + if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) { + const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0); + uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset); + + if (reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value)) + set_it_simple = true; + } + } + } else { + error.SetErrorString("We don't support returning longer than 64 bit " + "integer values at present."); + } + } else if (compiler_type.IsFloatingPointType(count, is_complex)) { + if (is_complex) + error.SetErrorString( + "We don't support returning complex values at present"); + else + error.SetErrorString( + "We don't support returning float values at present"); + } + + if (!set_it_simple) + error.SetErrorString( + "We only support setting simple integer return types at present."); + + return error; +} + +ValueObjectSP ABISysV_mips::GetReturnValueObjectSimple( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + return return_valobj_sp; +} + +ValueObjectSP ABISysV_mips::GetReturnValueObjectImpl( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + Value value; + + if (!return_compiler_type) + return return_valobj_sp; + + ExecutionContext exe_ctx(thread.shared_from_this()); + if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr) + return return_valobj_sp; + + Target *target = exe_ctx.GetTargetPtr(); + const ArchSpec target_arch = target->GetArchitecture(); + ByteOrder target_byte_order = target_arch.GetByteOrder(); + value.SetCompilerType(return_compiler_type); + uint32_t fp_flag = + target_arch.GetFlags() & lldb_private::ArchSpec::eMIPS_ABI_FP_mask; + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return return_valobj_sp; + + bool is_signed = false; + bool is_complex = false; + uint32_t count = 0; + + // In MIPS register "r2" (v0) holds the integer function return values + const RegisterInfo *r2_reg_info = reg_ctx->GetRegisterInfoByName("r2", 0); + 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) { + default: + return return_valobj_sp; + case 64: { + const RegisterInfo *r3_reg_info = reg_ctx->GetRegisterInfoByName("r3", 0); + uint64_t raw_value; + raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX; + raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0) & + UINT32_MAX)) + << 32; + if (is_signed) + value.GetScalar() = (int64_t)raw_value; + else + value.GetScalar() = (uint64_t)raw_value; + } break; + case 32: + if (is_signed) + value.GetScalar() = (int32_t)( + reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX); + else + value.GetScalar() = (uint32_t)( + reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX); + break; + case 16: + if (is_signed) + value.GetScalar() = (int16_t)( + reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT16_MAX); + else + value.GetScalar() = (uint16_t)( + reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT16_MAX); + break; + case 8: + if (is_signed) + value.GetScalar() = (int8_t)( + reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT8_MAX); + else + value.GetScalar() = (uint8_t)( + reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT8_MAX); + break; + } + } else if (return_compiler_type.IsPointerType()) { + uint32_t ptr = + thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_reg_info, 0) & + UINT32_MAX; + value.GetScalar() = ptr; + } else if (return_compiler_type.IsAggregateType()) { + // Structure/Vector is always passed in memory and pointer to that memory + // is passed in r2. + uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned( + reg_ctx->GetRegisterInfoByName("r2", 0), 0); + // We have got the address. Create a memory object out of it + return_valobj_sp = ValueObjectMemory::Create( + &thread, "", Address(mem_address, nullptr), return_compiler_type); + return return_valobj_sp; + } else if (return_compiler_type.IsFloatingPointType(count, is_complex)) { + if (IsSoftFloat(fp_flag)) { + uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0); + if (count != 1 && is_complex) + return return_valobj_sp; + switch (*bit_width) { + default: + return return_valobj_sp; + case 32: + static_assert(sizeof(float) == sizeof(uint32_t), ""); + value.GetScalar() = *((float *)(&raw_value)); + break; + case 64: + static_assert(sizeof(double) == sizeof(uint64_t), ""); + const RegisterInfo *r3_reg_info = + reg_ctx->GetRegisterInfoByName("r3", 0); + if (target_byte_order == eByteOrderLittle) + raw_value = + ((reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0)) << 32) | + raw_value; + else + raw_value = (raw_value << 32) | + reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0); + value.GetScalar() = *((double *)(&raw_value)); + break; + } + } + + else { + const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0); + RegisterValue f0_value; + DataExtractor f0_data; + reg_ctx->ReadRegister(f0_info, f0_value); + f0_value.GetData(f0_data); + lldb::offset_t offset = 0; + + if (count == 1 && !is_complex) { + switch (*bit_width) { + default: + return return_valobj_sp; + case 64: { + static_assert(sizeof(double) == sizeof(uint64_t), ""); + const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0); + RegisterValue f1_value; + DataExtractor f1_data; + reg_ctx->ReadRegister(f1_info, f1_value); + DataExtractor *copy_from_extractor = nullptr; + DataBufferSP data_sp(new DataBufferHeap(8, 0)); + DataExtractor return_ext( + data_sp, target_byte_order, + target->GetArchitecture().GetAddressByteSize()); + + if (target_byte_order == eByteOrderLittle) { + copy_from_extractor = &f0_data; + copy_from_extractor->CopyByteOrderedData( + offset, 4, data_sp->GetBytes(), 4, target_byte_order); + f1_value.GetData(f1_data); + copy_from_extractor = &f1_data; + copy_from_extractor->CopyByteOrderedData( + offset, 4, data_sp->GetBytes() + 4, 4, target_byte_order); + } else { + copy_from_extractor = &f0_data; + copy_from_extractor->CopyByteOrderedData( + offset, 4, data_sp->GetBytes() + 4, 4, target_byte_order); + f1_value.GetData(f1_data); + copy_from_extractor = &f1_data; + copy_from_extractor->CopyByteOrderedData( + offset, 4, data_sp->GetBytes(), 4, target_byte_order); + } + value.GetScalar() = (double)return_ext.GetDouble(&offset); + break; + } + case 32: { + static_assert(sizeof(float) == sizeof(uint32_t), ""); + value.GetScalar() = (float)f0_data.GetFloat(&offset); + break; + } + } + } else { + // not handled yet + return return_valobj_sp; + } + } + } else { + // not handled yet + return return_valobj_sp; + } + + // If we get here, we have a valid Value, so make our ValueObject out of it: + + return_valobj_sp = ValueObjectConstResult::Create( + thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); + return return_valobj_sp; +} + +bool ABISysV_mips::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + UnwindPlan::RowSP row(new UnwindPlan::Row); + + // Our Call Frame Address is the stack pointer value + row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0); + + // The previous PC is in the RA + row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true); + unwind_plan.AppendRow(row); + + // All other registers are the same. + + unwind_plan.SetSourceName("mips at-func-entry default"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetReturnAddressRegister(dwarf_r31); + return true; +} + +bool ABISysV_mips::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + UnwindPlan::RowSP row(new UnwindPlan::Row); + + row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0); + + row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true); + + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("mips default unwind plan"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); + return true; +} + +bool ABISysV_mips::RegisterIsVolatile(const RegisterInfo *reg_info) { + return !RegisterIsCalleeSaved(reg_info); +} + +bool ABISysV_mips::IsSoftFloat(uint32_t fp_flags) const { + return (fp_flags == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT); +} + +bool ABISysV_mips::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { + if (reg_info) { + // Preserved registers are : + // r16-r23, r28, r29, r30, r31 + const char *name = reg_info->name; + + if (name[0] == 'r') { + switch (name[1]) { + case '1': + if (name[2] == '6' || name[2] == '7' || name[2] == '8' || + name[2] == '9') // r16-r19 + return name[3] == '\0'; + break; + case '2': + if (name[2] == '0' || name[2] == '1' || name[2] == '2' || + name[2] == '3' // r20-r23 + || name[2] == '8' || name[2] == '9') // r28 and r29 + return name[3] == '\0'; + break; + case '3': + if (name[2] == '0' || name[2] == '1') // r30 and r31 + return name[3] == '\0'; + break; + } + + if (name[0] == 'g' && name[1] == 'p' && name[2] == '\0') // gp (r28) + return true; + if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp (r29) + return true; + if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp (r30) + return true; + if (name[0] == 'r' && name[1] == 'a' && name[2] == '\0') // ra (r31) + return true; + } + } + return false; +} + +void ABISysV_mips::Initialize() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), "System V ABI for mips targets", CreateInstance); +} + +void ABISysV_mips::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString ABISysV_mips::GetPluginNameStatic() { + static ConstString g_name("sysv-mips"); + return g_name; +} + +// PluginInterface protocol + +lldb_private::ConstString ABISysV_mips::GetPluginName() { + return GetPluginNameStatic(); +} + +uint32_t ABISysV_mips::GetPluginVersion() { return 1; } diff --git a/gnu/llvm/lldb/source/Plugins/ABI/Mips/ABISysV_mips.h b/gnu/llvm/lldb/source/Plugins/ABI/Mips/ABISysV_mips.h new file mode 100644 index 00000000000..715405e7ef9 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/Mips/ABISysV_mips.h @@ -0,0 +1,93 @@ +//===-- ABISysV_mips.h ----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_MIPS_ABISYSV_MIPS_H +#define LLDB_SOURCE_PLUGINS_ABI_MIPS_ABISYSV_MIPS_H + +#include "lldb/Target/ABI.h" +#include "lldb/lldb-private.h" + +class ABISysV_mips : public lldb_private::RegInfoBasedABI { +public: + ~ABISysV_mips() override = default; + + size_t GetRedZoneSize() const override; + + bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t functionAddress, + lldb::addr_t returnAddress, + llvm::ArrayRef args) const override; + + bool GetArgumentValues(lldb_private::Thread &thread, + lldb_private::ValueList &values) const override; + + lldb_private::Status + SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value) override; + + lldb::ValueObjectSP + GetReturnValueObjectImpl(lldb_private::Thread &thread, + lldb_private::CompilerType &type) const override; + + bool + CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override; + + bool IsSoftFloat(uint32_t fp_flag) const; + + bool CallFrameAddressIsValid(lldb::addr_t cfa) override { + // Make sure the stack call frame addresses are 8 byte aligned + if (cfa & (8ull - 1ull)) + return false; // Not 8 byte aligned + if (cfa == 0) + return false; // Zero is not a valid stack address + return true; + } + + bool CodeAddressIsValid(lldb::addr_t pc) override { + // Just make sure the address is a valid 32 bit address. Bit zero + // might be set due to MicroMIPS function calls, so don't enforce alignment. + return (pc <= UINT32_MAX); + } + + const lldb_private::RegisterInfo * + GetRegisterInfoArray(uint32_t &count) override; + + // Static Functions + + static void Initialize(); + + static void Terminate(); + + static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); + + static lldb_private::ConstString GetPluginNameStatic(); + + // PluginInterface protocol + + lldb_private::ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + +protected: + void CreateRegisterMapIfNeeded(); + + lldb::ValueObjectSP + GetReturnValueObjectSimple(lldb_private::Thread &thread, + lldb_private::CompilerType &ast_type) const; + + bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); + +private: + using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance instead. +}; + +#endif // LLDB_SOURCE_PLUGINS_ABI_MIPS_ABISYSV_MIPS_H diff --git a/gnu/llvm/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp b/gnu/llvm/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp new file mode 100644 index 00000000000..bb28a50e5f4 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp @@ -0,0 +1,1214 @@ +//===-- ABISysV_mips64.cpp ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABISysV_mips64.h" + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Triple.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Core/ValueObjectMemory.h" +#include "lldb/Core/ValueObjectRegister.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Status.h" + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(ABISysV_mips64) + +enum dwarf_regnums { + dwarf_r0 = 0, + dwarf_r1, + dwarf_r2, + dwarf_r3, + dwarf_r4, + dwarf_r5, + dwarf_r6, + dwarf_r7, + dwarf_r8, + dwarf_r9, + dwarf_r10, + dwarf_r11, + dwarf_r12, + dwarf_r13, + dwarf_r14, + dwarf_r15, + dwarf_r16, + dwarf_r17, + dwarf_r18, + dwarf_r19, + dwarf_r20, + dwarf_r21, + dwarf_r22, + dwarf_r23, + dwarf_r24, + dwarf_r25, + dwarf_r26, + dwarf_r27, + dwarf_r28, + dwarf_r29, + dwarf_r30, + dwarf_r31, + dwarf_sr, + dwarf_lo, + dwarf_hi, + dwarf_bad, + dwarf_cause, + dwarf_pc +}; + +static const RegisterInfo g_register_infos_mips64[] = { + // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME + // DWARF GENERIC PROCESS PLUGIN + // LLDB NATIVE + // ======== ====== == === ============= ========== ============= + // ================= ==================== ================= + // ==================== + {"r0", + "zero", + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r1", + "AT", + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r2", + "v0", + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r3", + "v1", + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r4", + "arg1", + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r5", + "arg2", + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r6", + "arg3", + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r7", + "arg4", + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r8", + "arg5", + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r9", + "arg6", + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r10", + "arg7", + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r11", + "arg8", + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r11, dwarf_r11, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r12", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r13", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r14", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r15", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r16", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r17", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r18", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r19", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r20", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r21", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r22", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r23", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r24", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r25", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r26", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r27", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r28", + "gp", + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r29", + "sp", + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r29, dwarf_r29, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r30", + "fp", + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r30, dwarf_r30, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"r31", + "ra", + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r31, dwarf_r31, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"sr", + nullptr, + 4, + 0, + eEncodingUint, + eFormatHex, + {dwarf_sr, dwarf_sr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"lo", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_lo, dwarf_lo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"hi", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_hi, dwarf_hi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"bad", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_bad, dwarf_bad, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"cause", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_cause, dwarf_cause, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"pc", + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, +}; + +static const uint32_t k_num_register_infos = + llvm::array_lengthof(g_register_infos_mips64); + +const lldb_private::RegisterInfo * +ABISysV_mips64::GetRegisterInfoArray(uint32_t &count) { + count = k_num_register_infos; + return g_register_infos_mips64; +} + +size_t ABISysV_mips64::GetRedZoneSize() const { return 0; } + +// Static Functions + +ABISP +ABISysV_mips64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { + if (arch.GetTriple().isMIPS64()) + return ABISP( + new ABISysV_mips64(std::move(process_sp), MakeMCRegisterInfo(arch))); + return ABISP(); +} + +bool ABISysV_mips64::PrepareTrivialCall(Thread &thread, addr_t sp, + addr_t func_addr, addr_t return_addr, + llvm::ArrayRef args) const { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (log) { + StreamString s; + s.Printf("ABISysV_mips64::PrepareTrivialCall (tid = 0x%" PRIx64 + ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 + ", return_addr = 0x%" PRIx64, + thread.GetID(), (uint64_t)sp, (uint64_t)func_addr, + (uint64_t)return_addr); + + for (size_t i = 0; i < args.size(); ++i) + s.Printf(", arg%zd = 0x%" PRIx64, i + 1, args[i]); + s.PutCString(")"); + log->PutString(s.GetString()); + } + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return false; + + const RegisterInfo *reg_info = nullptr; + + if (args.size() > 8) // TODO handle more than 8 arguments + return false; + + for (size_t i = 0; i < args.size(); ++i) { + reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_ARG1 + i); + LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") into %s", i + 1, + args[i], reg_info->name); + if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) + return false; + } + + // First, align the SP + + LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, + (uint64_t)sp, (uint64_t)(sp & ~0xfull)); + + sp &= ~(0xfull); // 16-byte alignment + + Status error; + const RegisterInfo *pc_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + const RegisterInfo *sp_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); + const RegisterInfo *ra_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); + const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0); + const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0); + + LLDB_LOGF(log, "Writing R0: 0x%" PRIx64, (uint64_t)0); + + /* Write r0 with 0, in case we are stopped in syscall, + * such setting prevents automatic decrement of the PC. + * This clears the bug 23659 for MIPS. + */ + if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0)) + return false; + + LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp); + + // Set "sp" to the requested value + if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp)) + return false; + + LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr); + + // Set "ra" to the return address + if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr)) + return false; + + LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr); + + // Set pc to the address of the called function. + if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr)) + return false; + + LLDB_LOGF(log, "Writing r25: 0x%" PRIx64, (uint64_t)func_addr); + + // All callers of position independent functions must place the address of + // the called function in t9 (r25) + if (!reg_ctx->WriteRegisterFromUnsigned(r25_info, func_addr)) + return false; + + return true; +} + +bool ABISysV_mips64::GetArgumentValues(Thread &thread, + ValueList &values) const { + return false; +} + +Status ABISysV_mips64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value_sp) { + Status error; + if (!new_value_sp) { + error.SetErrorString("Empty value object for return value."); + return error; + } + + CompilerType compiler_type = new_value_sp->GetCompilerType(); + if (!compiler_type) { + error.SetErrorString("Null clang type for return value."); + return error; + } + + Thread *thread = frame_sp->GetThread().get(); + + RegisterContext *reg_ctx = thread->GetRegisterContext().get(); + + if (!reg_ctx) + error.SetErrorString("no registers are available"); + + DataExtractor data; + Status data_error; + size_t num_bytes = new_value_sp->GetData(data, data_error); + if (data_error.Fail()) { + error.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", + data_error.AsCString()); + return error; + } + + const uint32_t type_flags = compiler_type.GetTypeInfo(nullptr); + + if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) { + if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) { + lldb::offset_t offset = 0; + + if (num_bytes <= 16) { + const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0); + if (num_bytes <= 8) { + uint64_t raw_value = data.GetMaxU64(&offset, num_bytes); + + if (!reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) + error.SetErrorString("failed to write register r2"); + } else { + uint64_t raw_value = data.GetMaxU64(&offset, 8); + if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) { + const RegisterInfo *r3_info = + reg_ctx->GetRegisterInfoByName("r3", 0); + raw_value = data.GetMaxU64(&offset, num_bytes - offset); + + if (!reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value)) + error.SetErrorString("failed to write register r3"); + } else + error.SetErrorString("failed to write register r2"); + } + } else { + error.SetErrorString("We don't support returning longer than 128 bit " + "integer values at present."); + } + } else if (type_flags & eTypeIsFloat) { + error.SetErrorString("TODO: Handle Float Types."); + } + } else if (type_flags & eTypeIsVector) { + error.SetErrorString("returning vector values are not supported"); + } + + return error; +} + +ValueObjectSP ABISysV_mips64::GetReturnValueObjectSimple( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + return return_valobj_sp; +} + +ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + Value value; + Status error; + + ExecutionContext exe_ctx(thread.shared_from_this()); + if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr) + return return_valobj_sp; + + value.SetCompilerType(return_compiler_type); + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return return_valobj_sp; + + Target *target = exe_ctx.GetTargetPtr(); + const ArchSpec target_arch = target->GetArchitecture(); + ByteOrder target_byte_order = target_arch.GetByteOrder(); + 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; + + const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0); + const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0); + + if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) { + value.SetValueType(Value::eValueTypeScalar); + + bool success = false; + if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) { + // Extract the register context so we can read arguments from registers + // In MIPS register "r2" (v0) holds the integer function return values + + uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0); + + const bool is_signed = (type_flags & eTypeIsSigned) != 0; + switch (*byte_size) { + default: + break; + + case sizeof(uint64_t): + if (is_signed) + value.GetScalar() = (int64_t)(raw_value); + else + value.GetScalar() = (uint64_t)(raw_value); + success = true; + break; + + case sizeof(uint32_t): + if (is_signed) + value.GetScalar() = (int32_t)(raw_value & UINT32_MAX); + else + value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX); + success = true; + break; + + case sizeof(uint16_t): + if (is_signed) + value.GetScalar() = (int16_t)(raw_value & UINT16_MAX); + else + value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX); + success = true; + break; + + case sizeof(uint8_t): + if (is_signed) + value.GetScalar() = (int8_t)(raw_value & UINT8_MAX); + else + value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX); + success = true; + break; + } + } else if (type_flags & eTypeIsFloat) { + if (type_flags & eTypeIsComplex) { + // Don't handle complex yet. + } else if (IsSoftFloat(fp_flag)) { + uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0); + switch (*byte_size) { + case 4: + value.GetScalar() = *((float *)(&raw_value)); + success = true; + break; + case 8: + value.GetScalar() = *((double *)(&raw_value)); + success = true; + break; + case 16: + uint64_t result[2]; + if (target_byte_order == eByteOrderLittle) { + result[0] = raw_value; + result[1] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0); + value.GetScalar() = *((long double *)(result)); + } else { + result[0] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0); + result[1] = raw_value; + value.GetScalar() = *((long double *)(result)); + } + success = true; + break; + } + + } else { + if (*byte_size <= sizeof(long double)) { + const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0); + + RegisterValue f0_value; + DataExtractor f0_data; + + reg_ctx->ReadRegister(f0_info, f0_value); + + f0_value.GetData(f0_data); + + lldb::offset_t offset = 0; + if (*byte_size == sizeof(float)) { + value.GetScalar() = (float)f0_data.GetFloat(&offset); + success = true; + } else if (*byte_size == sizeof(double)) { + value.GetScalar() = (double)f0_data.GetDouble(&offset); + success = true; + } else if (*byte_size == sizeof(long double)) { + const RegisterInfo *f2_info = + reg_ctx->GetRegisterInfoByName("f2", 0); + RegisterValue f2_value; + DataExtractor f2_data; + reg_ctx->ReadRegister(f2_info, f2_value); + DataExtractor *copy_from_extractor = nullptr; + DataBufferSP data_sp(new DataBufferHeap(16, 0)); + DataExtractor return_ext( + data_sp, target_byte_order, + target->GetArchitecture().GetAddressByteSize()); + + 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); + f2_value.GetData(f2_data); + copy_from_extractor = &f2_data; + copy_from_extractor->CopyByteOrderedData( + 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, + 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); + } + + return_valobj_sp = ValueObjectConstResult::Create( + &thread, return_compiler_type, ConstString(""), return_ext); + return return_valobj_sp; + } + } + } + } + + if (success) + return_valobj_sp = ValueObjectConstResult::Create( + thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); + } 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) { + DataBufferSP data_sp(new DataBufferHeap(16, 0)); + DataExtractor return_ext(data_sp, target_byte_order, + target->GetArchitecture().GetAddressByteSize()); + + RegisterValue r2_value, r3_value, f0_value, f1_value, f2_value; + // Tracks how much bytes of r2 and r3 registers we've consumed so far + uint32_t integer_bytes = 0; + + // True if return values are in FP return registers. + bool use_fp_regs = false; + // True if we found any non floating point field in structure. + bool found_non_fp_field = false; + // True if return values are in r2 register. + bool use_r2 = false; + // True if return values are in r3 register. + bool use_r3 = false; + // True if the result is copied into our data buffer + bool sucess = false; + std::string name; + bool is_complex; + uint32_t count; + const uint32_t num_children = return_compiler_type.GetNumFields(); + + // A structure consisting of one or two FP values (and nothing else) will + // be returned in the two FP return-value registers i.e fp0 and fp2. + if (num_children <= 2) { + uint64_t field_bit_offset = 0; + + // Check if this structure contains only floating point fields + for (uint32_t idx = 0; idx < num_children; idx++) { + CompilerType field_compiler_type = + return_compiler_type.GetFieldAtIndex(idx, name, &field_bit_offset, + nullptr, nullptr); + + if (field_compiler_type.IsFloatingPointType(count, is_complex)) + use_fp_regs = true; + else + found_non_fp_field = true; + } + + if (use_fp_regs && !found_non_fp_field) { + // We have one or two FP-only values in this structure. Get it from + // f0/f2 registers. + DataExtractor f0_data, f1_data, f2_data; + const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0); + const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0); + const RegisterInfo *f2_info = reg_ctx->GetRegisterInfoByName("f2", 0); + + reg_ctx->ReadRegister(f0_info, f0_value); + reg_ctx->ReadRegister(f2_info, f2_value); + + f0_value.GetData(f0_data); + + for (uint32_t idx = 0; idx < num_children; idx++) { + CompilerType field_compiler_type = + return_compiler_type.GetFieldAtIndex( + idx, name, &field_bit_offset, nullptr, nullptr); + 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]; + offset_t offset = 0; + + if (idx == 0) { + // This case is for long double type. + if (*field_byte_width == 16) { + + // If structure contains long double type, then it is returned + // in fp0/fp1 registers. + if (target_byte_order == eByteOrderLittle) { + return_value[0] = f0_data.GetU64(&offset); + reg_ctx->ReadRegister(f1_info, f1_value); + f1_value.GetData(f1_data); + offset = 0; + return_value[1] = f1_data.GetU64(&offset); + } else { + return_value[1] = f0_data.GetU64(&offset); + reg_ctx->ReadRegister(f1_info, f1_value); + f1_value.GetData(f1_data); + offset = 0; + return_value[0] = f1_data.GetU64(&offset); + } + + f0_data.SetData(return_value, *field_byte_width, + target_byte_order); + } + copy_from_extractor = &f0_data; // This is in f0, copy from + // register to our result + // structure + } else { + f2_value.GetData(f2_data); + // This is in f2, copy from register to our result structure + copy_from_extractor = &f2_data; + } + + // Sanity check to avoid crash + if (!copy_from_extractor || + *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, + target_byte_order); + } + + // The result is in our data buffer. Create a variable object out of + // it + return_valobj_sp = ValueObjectConstResult::Create( + &thread, return_compiler_type, ConstString(""), return_ext); + + return return_valobj_sp; + } + } + + // If we reach here, it means this structure either contains more than + // two fields or it contains at least one non floating point type. In + // that case, all fields are returned in GP return registers. + for (uint32_t idx = 0; idx < num_children; idx++) { + uint64_t field_bit_offset = 0; + bool is_signed; + uint32_t padding; + + CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex( + idx, name, &field_bit_offset, nullptr, nullptr); + 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 || *field_byte_width == 0) + break; + + uint32_t field_byte_offset = field_bit_offset / 8; + + if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) || + field_compiler_type.IsPointerType() || + field_compiler_type.IsFloatingPointType(count, is_complex)) { + padding = field_byte_offset - integer_bytes; + + if (integer_bytes < 8) { + // We have not yet consumed r2 completely. + 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 + + padding; // Increase the consumed bytes. + use_r2 = true; + } 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 + + padding; // Increase the consumed bytes. + use_r3 = true; + } + } + // 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; + use_r3 = true; + } else { + // There isn't any space left for this field, this should not + // happen as we have already checked the overall size is not + // greater than 16 bytes. For now, return a nullptr return value + // object. + return return_valobj_sp; + } + } + } + // Vector types up to 16 bytes are returned in GP return registers + if (type_flags & eTypeIsVector) { + if (*byte_size <= 8) + use_r2 = true; + else { + use_r2 = true; + use_r3 = true; + } + } + + if (use_r2) { + reg_ctx->ReadRegister(r2_info, r2_value); + + const size_t bytes_copied = r2_value.GetAsMemoryData( + r2_info, data_sp->GetBytes(), r2_info->byte_size, target_byte_order, + error); + if (bytes_copied != r2_info->byte_size) + return return_valobj_sp; + sucess = true; + } + if (use_r3) { + reg_ctx->ReadRegister(r3_info, r3_value); + const size_t bytes_copied = r3_value.GetAsMemoryData( + r3_info, data_sp->GetBytes() + r2_info->byte_size, + r3_info->byte_size, target_byte_order, error); + + if (bytes_copied != r3_info->byte_size) + return return_valobj_sp; + sucess = true; + } + if (sucess) { + // The result is in our data buffer. Create a variable object out of + // it + return_valobj_sp = ValueObjectConstResult::Create( + &thread, return_compiler_type, ConstString(""), return_ext); + } + return return_valobj_sp; + } + + // Any structure/vector greater than 16 bytes in size is returned in + // memory. The pointer to that memory is returned in r2. + uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned( + reg_ctx->GetRegisterInfoByName("r2", 0), 0); + + // We have got the address. Create a memory object out of it + return_valobj_sp = ValueObjectMemory::Create( + &thread, "", Address(mem_address, nullptr), return_compiler_type); + } + return return_valobj_sp; +} + +bool ABISysV_mips64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + UnwindPlan::RowSP row(new UnwindPlan::Row); + + // Our Call Frame Address is the stack pointer value + row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0); + + // The previous PC is in the RA + row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true); + unwind_plan.AppendRow(row); + + // All other registers are the same. + + unwind_plan.SetSourceName("mips64 at-func-entry default"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetReturnAddressRegister(dwarf_r31); + return true; +} + +bool ABISysV_mips64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + UnwindPlan::RowSP row(new UnwindPlan::Row); + + row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0); + + row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true); + + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("mips64 default unwind plan"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); + return true; +} + +bool ABISysV_mips64::RegisterIsVolatile(const RegisterInfo *reg_info) { + return !RegisterIsCalleeSaved(reg_info); +} + +bool ABISysV_mips64::IsSoftFloat(uint32_t fp_flag) const { + return (fp_flag == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT); +} + +bool ABISysV_mips64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { + if (reg_info) { + // Preserved registers are : + // r16-r23, r28, r29, r30, r31 + + int reg = ((reg_info->byte_offset) / 8); + + bool save = (reg >= 16) && (reg <= 23); + save |= (reg >= 28) && (reg <= 31); + + return save; + } + return false; +} + +void ABISysV_mips64::Initialize() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), "System V ABI for mips64 targets", CreateInstance); +} + +void ABISysV_mips64::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString ABISysV_mips64::GetPluginNameStatic() { + static ConstString g_name("sysv-mips64"); + return g_name; +} + +// PluginInterface protocol + +lldb_private::ConstString ABISysV_mips64::GetPluginName() { + return GetPluginNameStatic(); +} + +uint32_t ABISysV_mips64::GetPluginVersion() { return 1; } diff --git a/gnu/llvm/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.h b/gnu/llvm/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.h new file mode 100644 index 00000000000..91428216a73 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.h @@ -0,0 +1,106 @@ +//===-- ABISysV_mips64.h ----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_MIPS_ABISYSV_MIPS64_H +#define LLDB_SOURCE_PLUGINS_ABI_MIPS_ABISYSV_MIPS64_H + +#include "lldb/Target/ABI.h" +#include "lldb/lldb-private.h" + +class ABISysV_mips64 : public lldb_private::RegInfoBasedABI { +public: + ~ABISysV_mips64() override = default; + + size_t GetRedZoneSize() const override; + + bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t functionAddress, + lldb::addr_t returnAddress, + llvm::ArrayRef args) const override; + + bool GetArgumentValues(lldb_private::Thread &thread, + lldb_private::ValueList &values) const override; + + lldb_private::Status + SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value) override; + + lldb::ValueObjectSP + GetReturnValueObjectImpl(lldb_private::Thread &thread, + lldb_private::CompilerType &type) const override; + + bool + CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override; + + bool IsSoftFloat(uint32_t fp_flag) const; + + // The SysV mips ABI requires that stack frames be 16 byte aligned. + // When there is a trap handler on the stack, e.g. _sigtramp in userland + // code, we've seen that the stack pointer is often not aligned properly + // before the handler is invoked. This means that lldb will stop the unwind + // early -- before the function which caused the trap. + // + // To work around this, we relax that alignment to be just word-size + // (8-bytes). + // Allowing the trap handlers for user space would be easy (_sigtramp) but + // in other environments there can be a large number of different functions + // involved in async traps. + bool CallFrameAddressIsValid(lldb::addr_t cfa) override { + // Make sure the stack call frame addresses are 8 byte aligned + if (cfa & (8ull - 1ull)) + return false; // Not 8 byte aligned + if (cfa == 0) + return false; // Zero is not a valid stack address + return true; + } + + bool CodeAddressIsValid(lldb::addr_t pc) override { + if (pc & (4ull - 1ull)) + return false; // Not 4 byte aligned + + // Anything else if fair game.. + return true; + } + + const lldb_private::RegisterInfo * + GetRegisterInfoArray(uint32_t &count) override; + + // Static Functions + + static void Initialize(); + + static void Terminate(); + + static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); + + static lldb_private::ConstString GetPluginNameStatic(); + + // PluginInterface protocol + + lldb_private::ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + +protected: + void CreateRegisterMapIfNeeded(); + + lldb::ValueObjectSP + GetReturnValueObjectSimple(lldb_private::Thread &thread, + lldb_private::CompilerType &ast_type) const; + + bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); + +private: + using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance instead. +}; + +#endif // LLDB_SOURCE_PLUGINS_ABI_MIPS_ABISYSV_MIPS64_H diff --git a/gnu/llvm/lldb/source/Plugins/ABI/Mips/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/ABI/Mips/CMakeLists.txt new file mode 100644 index 00000000000..9c3b18a78da --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/Mips/CMakeLists.txt @@ -0,0 +1,12 @@ +add_lldb_library(lldbPluginABIMips PLUGIN + ABIMips.cpp + ABISysV_mips.cpp + ABISysV_mips64.cpp + + LINK_LIBS + lldbCore + lldbSymbol + lldbTarget + LINK_COMPONENTS + Support + ) diff --git a/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/ABIPowerPC.cpp b/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/ABIPowerPC.cpp new file mode 100644 index 00000000000..b561e3c93f5 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/ABIPowerPC.cpp @@ -0,0 +1,24 @@ +//===-- PowerPC.h ---------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABIPowerPC.h" +#include "ABISysV_ppc.h" +#include "ABISysV_ppc64.h" +#include "lldb/Core/PluginManager.h" + +LLDB_PLUGIN_DEFINE(ABIPowerPC) + +void ABIPowerPC::Initialize() { + ABISysV_ppc::Initialize(); + ABISysV_ppc64::Initialize(); +} + +void ABIPowerPC::Terminate() { + ABISysV_ppc::Terminate(); + ABISysV_ppc64::Terminate(); +} diff --git a/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/ABIPowerPC.h b/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/ABIPowerPC.h new file mode 100644 index 00000000000..5e745eae0a4 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/ABIPowerPC.h @@ -0,0 +1,17 @@ +//===-- PowerPC.h -----------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_POWERPC_ABIPOWERPC_H +#define LLDB_SOURCE_PLUGINS_ABI_POWERPC_ABIPOWERPC_H + +class ABIPowerPC { +public: + static void Initialize(); + static void Terminate(); +}; +#endif diff --git a/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp b/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp new file mode 100644 index 00000000000..6f5eded7b03 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp @@ -0,0 +1,982 @@ +//===-- ABISysV_ppc.cpp ---------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABISysV_ppc.h" + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Triple.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Core/ValueObjectMemory.h" +#include "lldb/Core/ValueObjectRegister.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Status.h" + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(ABISysV_ppc) + +enum dwarf_regnums { + dwarf_r0 = 0, + dwarf_r1, + dwarf_r2, + dwarf_r3, + dwarf_r4, + dwarf_r5, + dwarf_r6, + dwarf_r7, + dwarf_r8, + dwarf_r9, + dwarf_r10, + dwarf_r11, + dwarf_r12, + dwarf_r13, + dwarf_r14, + dwarf_r15, + dwarf_r16, + dwarf_r17, + dwarf_r18, + dwarf_r19, + dwarf_r20, + dwarf_r21, + dwarf_r22, + dwarf_r23, + dwarf_r24, + dwarf_r25, + dwarf_r26, + dwarf_r27, + dwarf_r28, + dwarf_r29, + dwarf_r30, + dwarf_r31, + dwarf_f0, + dwarf_f1, + dwarf_f2, + dwarf_f3, + dwarf_f4, + dwarf_f5, + dwarf_f6, + dwarf_f7, + dwarf_f8, + dwarf_f9, + dwarf_f10, + dwarf_f11, + dwarf_f12, + dwarf_f13, + dwarf_f14, + dwarf_f15, + dwarf_f16, + dwarf_f17, + dwarf_f18, + dwarf_f19, + dwarf_f20, + dwarf_f21, + dwarf_f22, + dwarf_f23, + dwarf_f24, + dwarf_f25, + dwarf_f26, + dwarf_f27, + dwarf_f28, + dwarf_f29, + dwarf_f30, + dwarf_f31, + dwarf_cr, + dwarf_fpscr, + dwarf_xer = 101, + dwarf_lr = 108, + dwarf_ctr, + dwarf_pc, + dwarf_cfa, +}; + +// Note that the size and offset will be updated by platform-specific classes. +#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ + { \ + #reg, alt, 8, 0, eEncodingUint, eFormatHex, {kind1, kind2, kind3, kind4 }, \ + nullptr, nullptr, nullptr, 0 \ + } + +static const RegisterInfo g_register_infos[] = { + // General purpose registers. eh_frame, DWARF, + // Generic, Process Plugin + DEFINE_GPR(r0, nullptr, dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r1, "sp", dwarf_r1, dwarf_r1, LLDB_REGNUM_GENERIC_SP, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r2, nullptr, dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r3, "arg1", dwarf_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG1, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r4, "arg2", dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG2, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r5, "arg3", dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG3, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r6, "arg4", dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG4, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r7, "arg5", dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG5, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r8, "arg6", dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG6, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r9, "arg7", dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG7, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r10, "arg8", dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG8, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r11, nullptr, dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r12, nullptr, dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r13, nullptr, dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r14, nullptr, dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r15, nullptr, dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r16, nullptr, dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r17, nullptr, dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r18, nullptr, dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r19, nullptr, dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r20, nullptr, dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r21, nullptr, dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r22, nullptr, dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r23, nullptr, dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r24, nullptr, dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r25, nullptr, dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r26, nullptr, dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r27, nullptr, dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r28, nullptr, dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r29, nullptr, dwarf_r29, dwarf_r29, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r30, nullptr, dwarf_r30, dwarf_r30, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(r31, nullptr, dwarf_r31, dwarf_r31, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(lr, "lr", dwarf_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, + LLDB_INVALID_REGNUM), + DEFINE_GPR(cr, "cr", dwarf_cr, dwarf_cr, LLDB_REGNUM_GENERIC_FLAGS, + LLDB_INVALID_REGNUM), + DEFINE_GPR(xer, "xer", dwarf_xer, dwarf_xer, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(ctr, "ctr", dwarf_ctr, dwarf_ctr, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM), + DEFINE_GPR(pc, "pc", dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, + LLDB_INVALID_REGNUM), + {nullptr, + nullptr, + 8, + 0, + eEncodingUint, + eFormatHex, + {dwarf_cfa, dwarf_cfa, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}}; + +static const uint32_t k_num_register_infos = + llvm::array_lengthof(g_register_infos); + +const lldb_private::RegisterInfo * +ABISysV_ppc::GetRegisterInfoArray(uint32_t &count) { + count = k_num_register_infos; + return g_register_infos; +} + +size_t ABISysV_ppc::GetRedZoneSize() const { return 224; } + +// Static Functions + +ABISP +ABISysV_ppc::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { + if (arch.GetTriple().getArch() == llvm::Triple::ppc) { + return ABISP( + new ABISysV_ppc(std::move(process_sp), MakeMCRegisterInfo(arch))); + } + return ABISP(); +} + +bool ABISysV_ppc::PrepareTrivialCall(Thread &thread, addr_t sp, + addr_t func_addr, addr_t return_addr, + llvm::ArrayRef args) const { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (log) { + StreamString s; + s.Printf("ABISysV_ppc::PrepareTrivialCall (tid = 0x%" PRIx64 + ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 + ", return_addr = 0x%" PRIx64, + thread.GetID(), (uint64_t)sp, (uint64_t)func_addr, + (uint64_t)return_addr); + + for (size_t i = 0; i < args.size(); ++i) + s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast(i + 1), + args[i]); + s.PutCString(")"); + log->PutString(s.GetString()); + } + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return false; + + const RegisterInfo *reg_info = nullptr; + + if (args.size() > 8) // TODO handle more than 8 arguments + return false; + + for (size_t i = 0; i < args.size(); ++i) { + reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_ARG1 + i); + LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", + static_cast(i + 1), args[i], reg_info->name); + if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) + return false; + } + + // First, align the SP + + LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, + (uint64_t)sp, (uint64_t)(sp & ~0xfull)); + + sp &= ~(0xfull); // 16-byte alignment + + sp -= 8; + + Status error; + const RegisterInfo *pc_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + const RegisterInfo *sp_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); + ProcessSP process_sp(thread.GetProcess()); + + RegisterValue reg_value; + + LLDB_LOGF(log, + "Pushing the return address onto the stack: 0x%" PRIx64 + ": 0x%" PRIx64, + (uint64_t)sp, (uint64_t)return_addr); + + // Save return address onto the stack + if (!process_sp->WritePointerToMemory(sp, return_addr, error)) + return false; + + // %r1 is set to the actual stack value. + + LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp); + + if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp)) + return false; + + // %pc is set to the address of the called function. + + LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr); + + if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr)) + return false; + + return true; +} + +static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, + bool is_signed, Thread &thread, + uint32_t *argument_register_ids, + unsigned int ¤t_argument_register, + addr_t ¤t_stack_argument) { + if (bit_width > 64) + return false; // Scalar can't hold large integer arguments + + if (current_argument_register < 6) { + scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned( + argument_register_ids[current_argument_register], 0); + current_argument_register++; + if (is_signed) + scalar.SignExtend(bit_width); + } else { + uint32_t byte_size = (bit_width + (8 - 1)) / 8; + Status error; + if (thread.GetProcess()->ReadScalarIntegerFromMemory( + current_stack_argument, byte_size, is_signed, scalar, error)) { + current_stack_argument += byte_size; + return true; + } + return false; + } + return true; +} + +bool ABISysV_ppc::GetArgumentValues(Thread &thread, ValueList &values) const { + unsigned int num_values = values.GetSize(); + unsigned int value_index; + + // Extract the register context so we can read arguments from registers + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + + if (!reg_ctx) + return false; + + // Get the pointer to the first stack argument so we have a place to start + // when reading data + + addr_t sp = reg_ctx->GetSP(0); + + if (!sp) + return false; + + addr_t current_stack_argument = sp + 48; // jump over return address + + uint32_t argument_register_ids[8]; + + argument_register_ids[0] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[1] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[2] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[3] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[4] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[5] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[6] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG7) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[7] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG8) + ->kinds[eRegisterKindLLDB]; + + unsigned int current_argument_register = 0; + + for (value_index = 0; value_index < num_values; ++value_index) { + Value *value = values.GetValueAtIndex(value_index); + + if (!value) + return false; + + // We currently only support extracting values with Clang QualTypes. Do we + // care about others? + CompilerType compiler_type = value->GetCompilerType(); + 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(), *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; +} + +Status ABISysV_ppc::SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value_sp) { + Status error; + if (!new_value_sp) { + error.SetErrorString("Empty value object for return value."); + return error; + } + + CompilerType compiler_type = new_value_sp->GetCompilerType(); + if (!compiler_type) { + error.SetErrorString("Null clang type for return value."); + return error; + } + + Thread *thread = frame_sp->GetThread().get(); + + bool is_signed; + uint32_t count; + bool is_complex; + + RegisterContext *reg_ctx = thread->GetRegisterContext().get(); + + bool set_it_simple = false; + if (compiler_type.IsIntegerOrEnumerationType(is_signed) || + compiler_type.IsPointerType()) { + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r3", 0); + + DataExtractor data; + Status data_error; + size_t num_bytes = new_value_sp->GetData(data, data_error); + if (data_error.Fail()) { + error.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", + data_error.AsCString()); + return error; + } + lldb::offset_t offset = 0; + if (num_bytes <= 8) { + uint64_t raw_value = data.GetMaxU64(&offset, num_bytes); + + if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value)) + set_it_simple = true; + } else { + error.SetErrorString("We don't support returning longer than 64 bit " + "integer values at present."); + } + } else if (compiler_type.IsFloatingPointType(count, is_complex)) { + if (is_complex) + error.SetErrorString( + "We don't support returning complex values at present"); + else { + 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); + if (data_error.Fail()) { + error.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", + data_error.AsCString()); + return error; + } + + unsigned char buffer[16]; + ByteOrder byte_order = data.GetByteOrder(); + + data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order); + set_it_simple = true; + } else { + // FIXME - don't know how to do 80 bit long doubles yet. + error.SetErrorString( + "We don't support returning float values > 64 bits at present"); + } + } + } + + if (!set_it_simple) { + // Okay we've got a structure or something that doesn't fit in a simple + // register. We should figure out where it really goes, but we don't + // support this yet. + error.SetErrorString("We only support setting simple integer and float " + "return types at present."); + } + + return error; +} + +ValueObjectSP ABISysV_ppc::GetReturnValueObjectSimple( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + Value value; + + if (!return_compiler_type) + return return_valobj_sp; + + // value.SetContext (Value::eContextTypeClangType, return_value_type); + value.SetCompilerType(return_compiler_type); + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return return_valobj_sp; + + const uint32_t type_flags = return_compiler_type.GetTypeInfo(); + if (type_flags & eTypeIsScalar) { + value.SetValueType(Value::eValueTypeScalar); + + bool success = false; + if (type_flags & eTypeIsInteger) { + // 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("r3", 0), 0); + const bool is_signed = (type_flags & eTypeIsSigned) != 0; + switch (*byte_size) { + default: + break; + + case sizeof(uint64_t): + if (is_signed) + value.GetScalar() = (int64_t)(raw_value); + else + value.GetScalar() = (uint64_t)(raw_value); + success = true; + break; + + case sizeof(uint32_t): + if (is_signed) + value.GetScalar() = (int32_t)(raw_value & UINT32_MAX); + else + value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX); + success = true; + break; + + case sizeof(uint16_t): + if (is_signed) + value.GetScalar() = (int16_t)(raw_value & UINT16_MAX); + else + value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX); + success = true; + break; + + case sizeof(uint8_t): + if (is_signed) + value.GetScalar() = (int8_t)(raw_value & UINT8_MAX); + else + value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX); + success = true; + break; + } + } else if (type_flags & eTypeIsFloat) { + if (type_flags & eTypeIsComplex) { + // Don't handle complex yet. + } else { + 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)) { + value.GetScalar() = (float)data.GetFloat(&offset); + success = true; + } else if (*byte_size == sizeof(double)) { + value.GetScalar() = (double)data.GetDouble(&offset); + success = true; + } + } + } + } + } + } + + if (success) + return_valobj_sp = ValueObjectConstResult::Create( + thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); + } else if (type_flags & eTypeIsPointer) { + unsigned r3_id = + reg_ctx->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB]; + value.GetScalar() = + (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0); + value.SetValueType(Value::eValueTypeScalar); + return_valobj_sp = ValueObjectConstResult::Create( + thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); + } else if (type_flags & eTypeIsVector) { + 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) { + ProcessSP process_sp(thread.GetProcess()); + if (process_sp) { + std::unique_ptr heap_data_up( + new DataBufferHeap(*byte_size, 0)); + const ByteOrder byte_order = process_sp->GetByteOrder(); + RegisterValue reg_value; + if (reg_ctx->ReadRegister(altivec_reg, reg_value)) { + Status error; + if (reg_value.GetAsMemoryData( + altivec_reg, heap_data_up->GetBytes(), + heap_data_up->GetByteSize(), byte_order, error)) { + DataExtractor data(DataBufferSP(heap_data_up.release()), + byte_order, + process_sp->GetTarget() + .GetArchitecture() + .GetAddressByteSize()); + return_valobj_sp = ValueObjectConstResult::Create( + &thread, return_compiler_type, ConstString(""), data); + } + } + } + } + } + } + } + + return return_valobj_sp; +} + +ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + + if (!return_compiler_type) + return return_valobj_sp; + + ExecutionContext exe_ctx(thread.shared_from_this()); + return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type); + if (return_valobj_sp) + return return_valobj_sp; + + RegisterContextSP reg_ctx_sp = thread.GetRegisterContext(); + if (!reg_ctx_sp) + return return_valobj_sp; + + 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) { + ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder(); + DataBufferSP data_sp(new DataBufferHeap(16, 0)); + DataExtractor return_ext(data_sp, target_byte_order, + target->GetArchitecture().GetAddressByteSize()); + + const RegisterInfo *r3_info = reg_ctx_sp->GetRegisterInfoByName("r3", 0); + const RegisterInfo *rdx_info = + reg_ctx_sp->GetRegisterInfoByName("rdx", 0); + + RegisterValue r3_value, rdx_value; + reg_ctx_sp->ReadRegister(r3_info, r3_value); + reg_ctx_sp->ReadRegister(rdx_info, rdx_value); + + DataExtractor r3_data, rdx_data; + + r3_value.GetData(r3_data); + rdx_value.GetData(rdx_data); + + uint32_t fp_bytes = + 0; // Tracks how much of the xmm registers we've consumed so far + uint32_t integer_bytes = + 0; // Tracks how much of the r3/rds registers we've consumed so far + + const uint32_t num_children = return_compiler_type.GetNumFields(); + + // Since we are in the small struct regime, assume we are not in memory. + is_memory = false; + + for (uint32_t idx = 0; idx < num_children; idx++) { + std::string name; + uint64_t field_bit_offset = 0; + bool is_signed; + bool is_complex; + uint32_t count; + + CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex( + idx, name, &field_bit_offset, nullptr, nullptr); + 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) { + is_memory = true; + break; + } + + uint32_t field_byte_width = *field_bit_width / 8; + uint32_t field_byte_offset = field_bit_offset / 8; + + DataExtractor *copy_from_extractor = nullptr; + uint32_t copy_from_offset = 0; + + if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) || + field_compiler_type.IsPointerType()) { + if (integer_bytes < 8) { + if (integer_bytes + field_byte_width <= 8) { + // This is in RAX, copy from register to our result structure: + copy_from_extractor = &r3_data; + copy_from_offset = integer_bytes; + integer_bytes += field_byte_width; + } else { + // The next field wouldn't fit in the remaining space, so we + // pushed it to rdx. + copy_from_extractor = &rdx_data; + copy_from_offset = 0; + integer_bytes = 8 + field_byte_width; + } + } else if (integer_bytes + field_byte_width <= 16) { + copy_from_extractor = &rdx_data; + copy_from_offset = integer_bytes - 8; + integer_bytes += field_byte_width; + } else { + // The last field didn't fit. I can't see how that would happen + // w/o the overall size being greater than 16 bytes. For now, + // return a nullptr return value object. + return return_valobj_sp; + } + } else if (field_compiler_type.IsFloatingPointType(count, is_complex)) { + // Structs with long doubles are always passed in memory. + if (*field_bit_width == 128) { + is_memory = true; + break; + } else if (*field_bit_width == 64) { + copy_from_offset = 0; + fp_bytes += field_byte_width; + } 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 + // will be stuffed into the appropriate GPR with them. + bool in_gpr; + if (field_byte_offset % 8 == 0) { + // We are at the beginning of one of the eightbytes, so check the + // next element (if any) + if (idx == num_children - 1) + in_gpr = false; + else { + uint64_t next_field_bit_offset = 0; + CompilerType next_field_compiler_type = + return_compiler_type.GetFieldAtIndex(idx + 1, name, + &next_field_bit_offset, + nullptr, nullptr); + if (next_field_compiler_type.IsIntegerOrEnumerationType( + is_signed)) + in_gpr = true; + else { + copy_from_offset = 0; + in_gpr = false; + } + } + } else if (field_byte_offset % 4 == 0) { + // We are inside of an eightbyte, so see if the field before us + // is floating point: This could happen if somebody put padding + // in the structure. + if (idx == 0) + in_gpr = false; + else { + uint64_t prev_field_bit_offset = 0; + CompilerType prev_field_compiler_type = + return_compiler_type.GetFieldAtIndex(idx - 1, name, + &prev_field_bit_offset, + nullptr, nullptr); + if (prev_field_compiler_type.IsIntegerOrEnumerationType( + is_signed)) + in_gpr = true; + else { + copy_from_offset = 4; + in_gpr = false; + } + } + } else { + is_memory = true; + continue; + } + + // Okay, we've figured out whether we are in GPR or XMM, now figure + // out which one. + if (in_gpr) { + if (integer_bytes < 8) { + // This is in RAX, copy from register to our result structure: + copy_from_extractor = &r3_data; + copy_from_offset = integer_bytes; + integer_bytes += field_byte_width; + } else { + copy_from_extractor = &rdx_data; + copy_from_offset = integer_bytes - 8; + integer_bytes += field_byte_width; + } + } else { + fp_bytes += field_byte_width; + } + } + } + + // These two tests are just sanity checks. If I somehow get the type + // calculation wrong above it is better to just return nothing than to + // assert or crash. + if (!copy_from_extractor) + return return_valobj_sp; + if (copy_from_offset + field_byte_width > + copy_from_extractor->GetByteSize()) + return return_valobj_sp; + + copy_from_extractor->CopyByteOrderedData( + copy_from_offset, field_byte_width, + data_sp->GetBytes() + field_byte_offset, field_byte_width, + target_byte_order); + } + + if (!is_memory) { + // The result is in our data buffer. Let's make a variable object out + // of it: + return_valobj_sp = ValueObjectConstResult::Create( + &thread, return_compiler_type, ConstString(""), return_ext); + } + } + + // FIXME: This is just taking a guess, r3 may very well no longer hold the + // return storage location. + // If we are going to do this right, when we make a new frame we should + // check to see if it uses a memory return, and if we are at the first + // instruction and if so stash away the return location. Then we would + // only return the memory return value if we know it is valid. + + if (is_memory) { + unsigned r3_id = + reg_ctx_sp->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB]; + lldb::addr_t storage_addr = + (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, + 0); + return_valobj_sp = ValueObjectMemory::Create( + &thread, "", Address(storage_addr, nullptr), return_compiler_type); + } + } + + return return_valobj_sp; +} + +bool ABISysV_ppc::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t lr_reg_num = dwarf_lr; + uint32_t sp_reg_num = dwarf_r1; + uint32_t pc_reg_num = dwarf_pc; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + + // Our Call Frame Address is the stack pointer value + row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0); + + // The previous PC is in the LR + row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true); + unwind_plan.AppendRow(row); + + // All other registers are the same. + + unwind_plan.SetSourceName("ppc at-func-entry default"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + + return true; +} + +bool ABISysV_ppc::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t sp_reg_num = dwarf_r1; + uint32_t pc_reg_num = dwarf_lr; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + + const int32_t ptr_size = 4; + row->GetCFAValue().SetIsRegisterDereferenced(sp_reg_num); + + row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 1, true); + row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); + + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("ppc default unwind plan"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); + unwind_plan.SetReturnAddressRegister(dwarf_lr); + return true; +} + +bool ABISysV_ppc::RegisterIsVolatile(const RegisterInfo *reg_info) { + return !RegisterIsCalleeSaved(reg_info); +} + +// See "Register Usage" in the +// "System V Application Binary Interface" +// "64-bit PowerPC ELF Application Binary Interface Supplement" current version +// is 1.9 released 2004 at http://refspecs.linuxfoundation.org/ELF/ppc/PPC- +// elf64abi-1.9.pdf + +bool ABISysV_ppc::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { + if (reg_info) { + // Preserved registers are : + // r1,r2,r13-r31 + // f14-f31 (not yet) + // v20-v31 (not yet) + // vrsave (not yet) + + const char *name = reg_info->name; + if (name[0] == 'r') { + if ((name[1] == '1' || name[1] == '2') && name[2] == '\0') + return true; + if (name[1] == '1' && name[2] > '2') + return true; + if ((name[1] == '2' || name[1] == '3') && name[2] != '\0') + return true; + } + + if (name[0] == 'f' && name[1] >= '0' && name[1] <= '9') { + if (name[3] == '1' && name[4] >= '4') + return true; + if ((name[3] == '2' || name[3] == '3') && name[4] != '\0') + return true; + } + + if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp + return true; + if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp + return true; + if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc + return true; + } + return false; +} + +void ABISysV_ppc::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + "System V ABI for ppc targets", CreateInstance); +} + +void ABISysV_ppc::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString ABISysV_ppc::GetPluginNameStatic() { + static ConstString g_name("sysv-ppc"); + return g_name; +} + +// PluginInterface protocol + +lldb_private::ConstString ABISysV_ppc::GetPluginName() { + return GetPluginNameStatic(); +} + +uint32_t ABISysV_ppc::GetPluginVersion() { return 1; } diff --git a/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.h b/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.h new file mode 100644 index 00000000000..4a586849e58 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.h @@ -0,0 +1,102 @@ +//===-- ABISysV_ppc.h ----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_POWERPC_ABISYSV_PPC_H +#define LLDB_SOURCE_PLUGINS_ABI_POWERPC_ABISYSV_PPC_H + +#include "lldb/Target/ABI.h" +#include "lldb/lldb-private.h" + +class ABISysV_ppc : public lldb_private::RegInfoBasedABI { +public: + ~ABISysV_ppc() override = default; + + size_t GetRedZoneSize() const override; + + bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t functionAddress, + lldb::addr_t returnAddress, + llvm::ArrayRef args) const override; + + bool GetArgumentValues(lldb_private::Thread &thread, + lldb_private::ValueList &values) const override; + + lldb_private::Status + SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value) override; + + lldb::ValueObjectSP + GetReturnValueObjectImpl(lldb_private::Thread &thread, + lldb_private::CompilerType &type) const override; + + bool + CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override; + + // The SysV ppc ABI requires that stack frames be 16 byte aligned. + // When there is a trap handler on the stack, e.g. _sigtramp in userland + // code, we've seen that the stack pointer is often not aligned properly + // before the handler is invoked. This means that lldb will stop the unwind + // early -- before the function which caused the trap. + // + // To work around this, we relax that alignment to be just word-size + // (8-bytes). + // Allowing the trap handlers for user space would be easy (_sigtramp) but + // in other environments there can be a large number of different functions + // involved in async traps. + bool CallFrameAddressIsValid(lldb::addr_t cfa) override { + // Make sure the stack call frame addresses are 8 byte aligned + if (cfa & (8ull - 1ull)) + return false; // Not 8 byte aligned + if (cfa == 0) + return false; // Zero is not a valid stack address + return true; + } + + bool CodeAddressIsValid(lldb::addr_t pc) override { + // We have a 64 bit address space, so anything is valid as opcodes + // aren't fixed width... + return true; + } + + const lldb_private::RegisterInfo * + GetRegisterInfoArray(uint32_t &count) override; + + // Static Functions + + static void Initialize(); + + static void Terminate(); + + static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); + + static lldb_private::ConstString GetPluginNameStatic(); + + // PluginInterface protocol + + lldb_private::ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + +protected: + void CreateRegisterMapIfNeeded(); + + lldb::ValueObjectSP + GetReturnValueObjectSimple(lldb_private::Thread &thread, + lldb_private::CompilerType &ast_type) const; + + bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); + +private: + using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance instead. +}; + +#endif // LLDB_SOURCE_PLUGINS_ABI_POWERPC_ABISYSV_PPC_H diff --git a/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp b/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp new file mode 100644 index 00000000000..251ac972fd7 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp @@ -0,0 +1,1087 @@ +//===-- ABISysV_ppc64.cpp -------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABISysV_ppc64.h" + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Triple.h" + +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" +#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/Value.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Core/ValueObjectMemory.h" +#include "lldb/Core/ValueObjectRegister.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Status.h" + +#include "clang/AST/ASTContext.h" +#include "clang/AST/Attr.h" +#include "clang/AST/Decl.h" + +#define DECLARE_REGISTER_INFOS_PPC64_STRUCT +#include "Plugins/Process/Utility/RegisterInfos_ppc64.h" +#undef DECLARE_REGISTER_INFOS_PPC64_STRUCT + +#define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT +#include "Plugins/Process/Utility/RegisterInfos_ppc64le.h" +#undef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(ABISysV_ppc64) + +const lldb_private::RegisterInfo * +ABISysV_ppc64::GetRegisterInfoArray(uint32_t &count) { + if (GetByteOrder() == lldb::eByteOrderLittle) { + count = llvm::array_lengthof(g_register_infos_ppc64le); + return g_register_infos_ppc64le; + } else { + count = llvm::array_lengthof(g_register_infos_ppc64); + return g_register_infos_ppc64; + } +} + +size_t ABISysV_ppc64::GetRedZoneSize() const { return 224; } + +lldb::ByteOrder ABISysV_ppc64::GetByteOrder() const { + return GetProcessSP()->GetByteOrder(); +} + +// Static Functions + +ABISP +ABISysV_ppc64::CreateInstance(lldb::ProcessSP process_sp, + const ArchSpec &arch) { + if (arch.GetTriple().isPPC64()) + return ABISP( + new ABISysV_ppc64(std::move(process_sp), MakeMCRegisterInfo(arch))); + return ABISP(); +} + +bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp, + addr_t func_addr, addr_t return_addr, + llvm::ArrayRef args) const { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (log) { + StreamString s; + s.Printf("ABISysV_ppc64::PrepareTrivialCall (tid = 0x%" PRIx64 + ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 + ", return_addr = 0x%" PRIx64, + thread.GetID(), (uint64_t)sp, (uint64_t)func_addr, + (uint64_t)return_addr); + + for (size_t i = 0; i < args.size(); ++i) + s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast(i + 1), + args[i]); + s.PutCString(")"); + log->PutString(s.GetString()); + } + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return false; + + const RegisterInfo *reg_info = nullptr; + + if (args.size() > 8) // TODO handle more than 8 arguments + return false; + + for (size_t i = 0; i < args.size(); ++i) { + reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_ARG1 + i); + LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", + static_cast(i + 1), args[i], reg_info->name); + if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) + return false; + } + + // First, align the SP + + LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, + (uint64_t)sp, (uint64_t)(sp & ~0xfull)); + + sp &= ~(0xfull); // 16-byte alignment + + sp -= 544; // allocate frame to save TOC, RA and SP. + + Status error; + uint64_t reg_value; + const RegisterInfo *pc_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + const RegisterInfo *sp_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); + ProcessSP process_sp(thread.GetProcess()); + const RegisterInfo *lr_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); + const RegisterInfo *r2_reg_info = reg_ctx->GetRegisterInfoAtIndex(2); + const RegisterInfo *r12_reg_info = reg_ctx->GetRegisterInfoAtIndex(12); + + // Save return address onto the stack. + LLDB_LOGF(log, + "Pushing the return address onto the stack: 0x%" PRIx64 + "(+16): 0x%" PRIx64, + (uint64_t)sp, (uint64_t)return_addr); + if (!process_sp->WritePointerToMemory(sp + 16, return_addr, error)) + return false; + + // Write the return address to link register. + LLDB_LOGF(log, "Writing LR: 0x%" PRIx64, (uint64_t)return_addr); + if (!reg_ctx->WriteRegisterFromUnsigned(lr_reg_info, return_addr)) + return false; + + // Write target address to %r12 register. + LLDB_LOGF(log, "Writing R12: 0x%" PRIx64, (uint64_t)func_addr); + if (!reg_ctx->WriteRegisterFromUnsigned(r12_reg_info, func_addr)) + return false; + + // Read TOC pointer value. + reg_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0); + + // Write TOC pointer onto the stack. + uint64_t stack_offset; + if (GetByteOrder() == lldb::eByteOrderLittle) + stack_offset = 24; + else + stack_offset = 40; + + LLDB_LOGF(log, "Writing R2 (TOC) at SP(0x%" PRIx64 ")+%d: 0x%" PRIx64, + (uint64_t)(sp + stack_offset), (int)stack_offset, + (uint64_t)reg_value); + if (!process_sp->WritePointerToMemory(sp + stack_offset, reg_value, error)) + return false; + + // Read the current SP value. + reg_value = reg_ctx->ReadRegisterAsUnsigned(sp_reg_info, 0); + + // Save current SP onto the stack. + LLDB_LOGF(log, "Writing SP at SP(0x%" PRIx64 ")+0: 0x%" PRIx64, (uint64_t)sp, + (uint64_t)reg_value); + if (!process_sp->WritePointerToMemory(sp, reg_value, error)) + return false; + + // %r1 is set to the actual stack value. + LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp); + + if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp)) + return false; + + // %pc is set to the address of the called function. + + LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr); + + if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr)) + return false; + + return true; +} + +static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, + bool is_signed, Thread &thread, + uint32_t *argument_register_ids, + unsigned int ¤t_argument_register, + addr_t ¤t_stack_argument) { + if (bit_width > 64) + return false; // Scalar can't hold large integer arguments + + if (current_argument_register < 6) { + scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned( + argument_register_ids[current_argument_register], 0); + current_argument_register++; + if (is_signed) + scalar.SignExtend(bit_width); + } else { + uint32_t byte_size = (bit_width + (8 - 1)) / 8; + Status error; + if (thread.GetProcess()->ReadScalarIntegerFromMemory( + current_stack_argument, byte_size, is_signed, scalar, error)) { + current_stack_argument += byte_size; + return true; + } + return false; + } + return true; +} + +bool ABISysV_ppc64::GetArgumentValues(Thread &thread, ValueList &values) const { + unsigned int num_values = values.GetSize(); + unsigned int value_index; + + // Extract the register context so we can read arguments from registers + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + + if (!reg_ctx) + return false; + + // Get the pointer to the first stack argument so we have a place to start + // when reading data + + addr_t sp = reg_ctx->GetSP(0); + + if (!sp) + return false; + + uint64_t stack_offset; + if (GetByteOrder() == lldb::eByteOrderLittle) + stack_offset = 32; + else + stack_offset = 48; + + // jump over return address. + addr_t current_stack_argument = sp + stack_offset; + uint32_t argument_register_ids[8]; + + for (size_t i = 0; i < 8; ++i) { + argument_register_ids[i] = + reg_ctx + ->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_ARG1 + i) + ->kinds[eRegisterKindLLDB]; + } + + unsigned int current_argument_register = 0; + + for (value_index = 0; value_index < num_values; ++value_index) { + Value *value = values.GetValueAtIndex(value_index); + + if (!value) + return false; + + // We currently only support extracting values with Clang QualTypes. Do we + // care about others? + CompilerType compiler_type = value->GetCompilerType(); + 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(), *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; +} + +Status ABISysV_ppc64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value_sp) { + Status error; + if (!new_value_sp) { + error.SetErrorString("Empty value object for return value."); + return error; + } + + CompilerType compiler_type = new_value_sp->GetCompilerType(); + if (!compiler_type) { + error.SetErrorString("Null clang type for return value."); + return error; + } + + Thread *thread = frame_sp->GetThread().get(); + + bool is_signed; + uint32_t count; + bool is_complex; + + RegisterContext *reg_ctx = thread->GetRegisterContext().get(); + + bool set_it_simple = false; + if (compiler_type.IsIntegerOrEnumerationType(is_signed) || + compiler_type.IsPointerType()) { + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r3", 0); + + DataExtractor data; + Status data_error; + size_t num_bytes = new_value_sp->GetData(data, data_error); + if (data_error.Fail()) { + error.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", + data_error.AsCString()); + return error; + } + lldb::offset_t offset = 0; + if (num_bytes <= 8) { + uint64_t raw_value = data.GetMaxU64(&offset, num_bytes); + + if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value)) + set_it_simple = true; + } else { + error.SetErrorString("We don't support returning longer than 64 bit " + "integer values at present."); + } + } else if (compiler_type.IsFloatingPointType(count, is_complex)) { + if (is_complex) + error.SetErrorString( + "We don't support returning complex values at present"); + else { + 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); + if (data_error.Fail()) { + error.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", + data_error.AsCString()); + return error; + } + + unsigned char buffer[16]; + ByteOrder byte_order = data.GetByteOrder(); + + data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order); + set_it_simple = true; + } else { + // FIXME - don't know how to do 80 bit long doubles yet. + error.SetErrorString( + "We don't support returning float values > 64 bits at present"); + } + } + } + + if (!set_it_simple) { + // Okay we've got a structure or something that doesn't fit in a simple + // register. We should figure out where it really goes, but we don't + // support this yet. + error.SetErrorString("We only support setting simple integer and float " + "return types at present."); + } + + return error; +} + +// +// ReturnValueExtractor +// + +namespace { + +#define LOG_PREFIX "ReturnValueExtractor: " + +class ReturnValueExtractor { + // This class represents a register, from which data may be extracted. + // + // It may be constructed by directly specifying its index (where 0 is the + // first register used to return values) or by specifying the offset of a + // given struct field, in which case the appropriated register index will be + // calculated. + class Register { + public: + enum Type { + GPR, // General Purpose Register + FPR // Floating Point Register + }; + + // main constructor + // + // offs - field offset in struct + Register(Type ty, uint32_t index, uint32_t offs, RegisterContext *reg_ctx, + ByteOrder byte_order) + : m_index(index), m_offs(offs % sizeof(uint64_t)), + m_avail(sizeof(uint64_t) - m_offs), m_type(ty), m_reg_ctx(reg_ctx), + m_byte_order(byte_order) {} + + // explicit index, no offset + Register(Type ty, uint32_t index, RegisterContext *reg_ctx, + ByteOrder byte_order) + : Register(ty, index, 0, reg_ctx, byte_order) {} + + // GPR, calculate index from offs + Register(uint32_t offs, RegisterContext *reg_ctx, ByteOrder byte_order) + : Register(GPR, offs / sizeof(uint64_t), offs, reg_ctx, byte_order) {} + + uint32_t Index() const { return m_index; } + + // register offset where data is located + uint32_t Offs() const { return m_offs; } + + // available bytes in this register + uint32_t Avail() const { return m_avail; } + + bool IsValid() const { + if (m_index > 7) { + LLDB_LOG(m_log, LOG_PREFIX + "No more than 8 registers should be used to return values"); + return false; + } + return true; + } + + std::string GetName() const { + if (m_type == GPR) + return ("r" + llvm::Twine(m_index + 3)).str(); + else + return ("f" + llvm::Twine(m_index + 1)).str(); + } + + // get raw register data + bool GetRawData(uint64_t &raw_data) { + const RegisterInfo *reg_info = + m_reg_ctx->GetRegisterInfoByName(GetName()); + if (!reg_info) { + LLDB_LOG(m_log, LOG_PREFIX "Failed to get RegisterInfo"); + return false; + } + + RegisterValue reg_val; + if (!m_reg_ctx->ReadRegister(reg_info, reg_val)) { + LLDB_LOG(m_log, LOG_PREFIX "ReadRegister() failed"); + return false; + } + + Status error; + uint32_t rc = reg_val.GetAsMemoryData( + reg_info, &raw_data, sizeof(raw_data), m_byte_order, error); + if (rc != sizeof(raw_data)) { + LLDB_LOG(m_log, LOG_PREFIX "GetAsMemoryData() failed"); + return false; + } + + return true; + } + + private: + uint32_t m_index; + uint32_t m_offs; + uint32_t m_avail; + Type m_type; + RegisterContext *m_reg_ctx; + ByteOrder m_byte_order; + Log *m_log = + lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + }; + + Register GetGPR(uint32_t index) const { + return Register(Register::GPR, index, m_reg_ctx, m_byte_order); + } + + Register GetFPR(uint32_t index) const { + return Register(Register::FPR, index, m_reg_ctx, m_byte_order); + } + + Register GetGPRByOffs(uint32_t offs) const { + return Register(offs, m_reg_ctx, m_byte_order); + } + +public: + // factory + static llvm::Expected Create(Thread &thread, + CompilerType &type) { + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return llvm::make_error( + LOG_PREFIX "Failed to get RegisterContext", + llvm::inconvertibleErrorCode()); + + ProcessSP process_sp = thread.GetProcess(); + if (!process_sp) + return llvm::make_error( + LOG_PREFIX "GetProcess() failed", llvm::inconvertibleErrorCode()); + + return ReturnValueExtractor(thread, type, reg_ctx, process_sp); + } + + // main method: get value of the type specified at construction time + ValueObjectSP GetValue() { + const uint32_t type_flags = m_type.GetTypeInfo(); + + // call the appropriate type handler + ValueSP value_sp; + ValueObjectSP valobj_sp; + if (type_flags & eTypeIsScalar) { + if (type_flags & eTypeIsInteger) { + value_sp = GetIntegerValue(0); + } else if (type_flags & eTypeIsFloat) { + if (type_flags & eTypeIsComplex) { + LLDB_LOG(m_log, LOG_PREFIX "Complex numbers are not supported yet"); + return ValueObjectSP(); + } else { + value_sp = GetFloatValue(m_type, 0); + } + } + } else if (type_flags & eTypeIsPointer) { + value_sp = GetPointerValue(0); + } + + if (value_sp) { + valobj_sp = ValueObjectConstResult::Create( + m_thread.GetStackFrameAtIndex(0).get(), *value_sp, ConstString("")); + } else if (type_flags & eTypeIsVector) { + valobj_sp = GetVectorValueObject(); + } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass) { + valobj_sp = GetStructValueObject(); + } + + return valobj_sp; + } + +private: + // data + Thread &m_thread; + CompilerType &m_type; + uint64_t m_byte_size; + std::unique_ptr m_data_up; + int32_t m_src_offs = 0; + int32_t m_dst_offs = 0; + bool m_packed = false; + Log *m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + RegisterContext *m_reg_ctx; + ProcessSP m_process_sp; + ByteOrder m_byte_order; + uint32_t m_addr_size; + + // methods + + // constructor + ReturnValueExtractor(Thread &thread, CompilerType &type, + RegisterContext *reg_ctx, ProcessSP process_sp) + : m_thread(thread), m_type(type), + m_byte_size(m_type.GetByteSize(nullptr).getValueOr(0)), + m_data_up(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( + process_sp->GetTarget().GetArchitecture().GetAddressByteSize()) {} + + // build a new scalar value + ValueSP NewScalarValue(CompilerType &type) { + ValueSP value_sp(new Value); + value_sp->SetCompilerType(type); + value_sp->SetValueType(Value::eValueTypeScalar); + return value_sp; + } + + // get an integer value in the specified register + ValueSP GetIntegerValue(uint32_t reg_index) { + uint64_t raw_value; + auto reg = GetGPR(reg_index); + if (!reg.GetRawData(raw_value)) + return ValueSP(); + + // build value from data + ValueSP value_sp(NewScalarValue(m_type)); + + uint32_t type_flags = m_type.GetTypeInfo(); + bool is_signed = (type_flags & eTypeIsSigned) != 0; + + switch (m_byte_size) { + case sizeof(uint64_t): + if (is_signed) + value_sp->GetScalar() = (int64_t)(raw_value); + else + value_sp->GetScalar() = (uint64_t)(raw_value); + break; + + case sizeof(uint32_t): + if (is_signed) + value_sp->GetScalar() = (int32_t)(raw_value & UINT32_MAX); + else + value_sp->GetScalar() = (uint32_t)(raw_value & UINT32_MAX); + break; + + case sizeof(uint16_t): + if (is_signed) + value_sp->GetScalar() = (int16_t)(raw_value & UINT16_MAX); + else + value_sp->GetScalar() = (uint16_t)(raw_value & UINT16_MAX); + break; + + case sizeof(uint8_t): + if (is_signed) + value_sp->GetScalar() = (int8_t)(raw_value & UINT8_MAX); + else + value_sp->GetScalar() = (uint8_t)(raw_value & UINT8_MAX); + break; + + default: + llvm_unreachable("Invalid integer size"); + } + + return value_sp; + } + + // get a floating point value on the specified register + ValueSP GetFloatValue(CompilerType &type, uint32_t reg_index) { + uint64_t raw_data; + auto reg = GetFPR(reg_index); + if (!reg.GetRawData(raw_data)) + return {}; + + // build value from data + ValueSP value_sp(NewScalarValue(type)); + + DataExtractor de(&raw_data, sizeof(raw_data), m_byte_order, m_addr_size); + + offset_t offset = 0; + 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; + + case sizeof(double): + value_sp->GetScalar() = de.GetDouble(&offset); + break; + + default: + llvm_unreachable("Invalid floating point size"); + } + + return value_sp; + } + + // get pointer value from register + ValueSP GetPointerValue(uint32_t reg_index) { + uint64_t raw_data; + auto reg = GetGPR(reg_index); + if (!reg.GetRawData(raw_data)) + return ValueSP(); + + // build value from raw data + ValueSP value_sp(NewScalarValue(m_type)); + value_sp->GetScalar() = raw_data; + return value_sp; + } + + // build the ValueObject from our data buffer + ValueObjectSP BuildValueObject() { + DataExtractor de(DataBufferSP(m_data_up.release()), m_byte_order, + m_addr_size); + return ValueObjectConstResult::Create(&m_thread, m_type, ConstString(""), + de); + } + + // get a vector return value + ValueObjectSP GetVectorValueObject() { + const uint32_t MAX_VRS = 2; + + // get first V register used to return values + const RegisterInfo *vr[MAX_VRS]; + vr[0] = m_reg_ctx->GetRegisterInfoByName("vr2"); + if (!vr[0]) { + LLDB_LOG(m_log, LOG_PREFIX "Failed to get vr2 RegisterInfo"); + return ValueObjectSP(); + } + + const uint32_t vr_size = vr[0]->byte_size; + size_t vrs = 1; + if (m_byte_size > 2 * vr_size) { + LLDB_LOG( + m_log, LOG_PREFIX + "Returning vectors that don't fit in 2 VR regs is not supported"); + return ValueObjectSP(); + } + + // load vr3, if needed + if (m_byte_size > vr_size) { + vrs++; + vr[1] = m_reg_ctx->GetRegisterInfoByName("vr3"); + if (!vr[1]) { + LLDB_LOG(m_log, LOG_PREFIX "Failed to get vr3 RegisterInfo"); + return ValueObjectSP(); + } + } + + // Get the whole contents of vector registers and let the logic here + // arrange the data properly. + + RegisterValue vr_val[MAX_VRS]; + Status error; + std::unique_ptr vr_data( + new DataBufferHeap(vrs * vr_size, 0)); + + for (uint32_t i = 0; i < vrs; i++) { + if (!m_reg_ctx->ReadRegister(vr[i], vr_val[i])) { + LLDB_LOG(m_log, LOG_PREFIX "Failed to read vector register contents"); + return ValueObjectSP(); + } + if (!vr_val[i].GetAsMemoryData(vr[i], vr_data->GetBytes() + i * vr_size, + vr_size, m_byte_order, error)) { + LLDB_LOG(m_log, LOG_PREFIX "Failed to extract vector register bytes"); + return ValueObjectSP(); + } + } + + // The compiler generated code seems to always put the vector elements at + // the end of the vector register, in case they don't occupy all of it. + // This offset variable handles this. + uint32_t offs = 0; + if (m_byte_size < vr_size) + offs = vr_size - m_byte_size; + + // copy extracted data to our buffer + memcpy(m_data_up->GetBytes(), vr_data->GetBytes() + offs, m_byte_size); + return BuildValueObject(); + } + + // get a struct return value + ValueObjectSP GetStructValueObject() { + // case 1: get from stack + if (m_byte_size > 2 * sizeof(uint64_t)) { + uint64_t addr; + auto reg = GetGPR(0); + if (!reg.GetRawData(addr)) + return {}; + + Status error; + size_t rc = m_process_sp->ReadMemory(addr, m_data_up->GetBytes(), + m_byte_size, error); + if (rc != m_byte_size) { + LLDB_LOG(m_log, LOG_PREFIX "Failed to read memory pointed by r3"); + return ValueObjectSP(); + } + return BuildValueObject(); + } + + // get number of children + const bool omit_empty_base_classes = true; + 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 {}; + } + + // case 2: homogeneous double or float aggregate + CompilerType elem_type; + if (m_type.IsHomogeneousAggregate(&elem_type)) { + uint32_t type_flags = elem_type.GetTypeInfo(); + 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 {}; + } + + for (uint32_t i = 0; i < n; i++) { + ValueSP val_sp = GetFloatValue(elem_type, i); + if (!val_sp) + return {}; + + // copy to buffer + Status error; + size_t rc = val_sp->GetScalar().GetAsMemoryData( + m_data_up->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 {}; + } + m_dst_offs += *elem_size; + } + return BuildValueObject(); + } + + // case 3: get from GPRs + + // first, check if this is a packed struct or not + TypeSystemClang *ast = + llvm::dyn_cast(m_type.GetTypeSystem()); + if (ast) { + clang::RecordDecl *record_decl = TypeSystemClang::GetAsRecordDecl(m_type); + + if (record_decl) { + auto attrs = record_decl->attrs(); + for (const auto &attr : attrs) { + if (attr->getKind() == clang::attr::Packed) { + m_packed = true; + break; + } + } + } + } + + LLDB_LOG(m_log, LOG_PREFIX "{0} struct", + m_packed ? "packed" : "not packed"); + + for (uint32_t i = 0; i < n; i++) { + std::string name; + uint32_t size; + GetChildType(i, name, size); + // NOTE: the offset returned by GetChildCompilerTypeAtIndex() + // can't be used because it never considers alignment bytes + // between struct fields. + LLDB_LOG(m_log, LOG_PREFIX "field={0}, size={1}", name, size); + if (!ExtractField(size)) + return ValueObjectSP(); + } + + return BuildValueObject(); + } + + // extract 'size' bytes at 'offs' from GPRs + bool ExtractFromRegs(int32_t offs, uint32_t size, void *buf) { + while (size) { + auto reg = GetGPRByOffs(offs); + if (!reg.IsValid()) + return false; + + uint32_t n = std::min(reg.Avail(), size); + uint64_t raw_data; + + if (!reg.GetRawData(raw_data)) + return false; + + memcpy(buf, (char *)&raw_data + reg.Offs(), n); + offs += n; + size -= n; + buf = (char *)buf + n; + } + return true; + } + + // extract one field from GPRs and put it in our buffer + bool ExtractField(uint32_t size) { + auto reg = GetGPRByOffs(m_src_offs); + if (!reg.IsValid()) + return false; + + // handle padding + if (!m_packed) { + uint32_t n = m_src_offs % size; + + // not 'size' bytes aligned + if (n) { + LLDB_LOG(m_log, + LOG_PREFIX "Extracting {0} alignment bytes at offset {1}", n, + m_src_offs); + // get alignment bytes + if (!ExtractFromRegs(m_src_offs, n, m_data_up->GetBytes() + m_dst_offs)) + return false; + m_src_offs += n; + m_dst_offs += n; + } + } + + // get field + LLDB_LOG(m_log, LOG_PREFIX "Extracting {0} field bytes at offset {1}", size, + m_src_offs); + if (!ExtractFromRegs(m_src_offs, size, m_data_up->GetBytes() + m_dst_offs)) + return false; + m_src_offs += size; + m_dst_offs += size; + return true; + } + + // get child + CompilerType GetChildType(uint32_t i, std::string &name, uint32_t &size) { + // GetChild constant inputs + const bool transparent_pointers = false; + const bool omit_empty_base_classes = true; + const bool ignore_array_bounds = false; + // GetChild output params + int32_t child_offs; + 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 = nullptr; + uint64_t language_flags; + ExecutionContext exe_ctx; + m_thread.CalculateExecutionContext(exe_ctx); + + return m_type.GetChildCompilerTypeAtIndex( + &exe_ctx, i, transparent_pointers, omit_empty_base_classes, + ignore_array_bounds, name, size, child_offs, child_bitfield_bit_size, + child_bitfield_bit_offset, child_is_base_class, + child_is_deref_of_parent, valobj, language_flags); + } +}; + +#undef LOG_PREFIX + +} // anonymous namespace + +ValueObjectSP +ABISysV_ppc64::GetReturnValueObjectSimple(Thread &thread, + CompilerType &type) const { + if (!type) + return ValueObjectSP(); + + auto exp_extractor = ReturnValueExtractor::Create(thread, type); + if (!exp_extractor) { + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + LLDB_LOG_ERROR(log, exp_extractor.takeError(), + "Extracting return value failed: {0}"); + return ValueObjectSP(); + } + + return exp_extractor.get().GetValue(); +} + +ValueObjectSP ABISysV_ppc64::GetReturnValueObjectImpl( + Thread &thread, CompilerType &return_compiler_type) const { + return GetReturnValueObjectSimple(thread, return_compiler_type); +} + +bool ABISysV_ppc64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t lr_reg_num; + uint32_t sp_reg_num; + uint32_t pc_reg_num; + + if (GetByteOrder() == lldb::eByteOrderLittle) { + lr_reg_num = ppc64le_dwarf::dwarf_lr_ppc64le; + sp_reg_num = ppc64le_dwarf::dwarf_r1_ppc64le; + pc_reg_num = ppc64le_dwarf::dwarf_pc_ppc64le; + } else { + lr_reg_num = ppc64_dwarf::dwarf_lr_ppc64; + sp_reg_num = ppc64_dwarf::dwarf_r1_ppc64; + pc_reg_num = ppc64_dwarf::dwarf_pc_ppc64; + } + + UnwindPlan::RowSP row(new UnwindPlan::Row); + + // Our Call Frame Address is the stack pointer value + row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0); + + // The previous PC is in the LR + row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true); + unwind_plan.AppendRow(row); + + // All other registers are the same. + + unwind_plan.SetSourceName("ppc64 at-func-entry default"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + + return true; +} + +bool ABISysV_ppc64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t sp_reg_num; + uint32_t pc_reg_num; + uint32_t cr_reg_num; + + if (GetByteOrder() == lldb::eByteOrderLittle) { + sp_reg_num = ppc64le_dwarf::dwarf_r1_ppc64le; + pc_reg_num = ppc64le_dwarf::dwarf_lr_ppc64le; + cr_reg_num = ppc64le_dwarf::dwarf_cr_ppc64le; + } else { + sp_reg_num = ppc64_dwarf::dwarf_r1_ppc64; + pc_reg_num = ppc64_dwarf::dwarf_lr_ppc64; + cr_reg_num = ppc64_dwarf::dwarf_cr_ppc64; + } + + UnwindPlan::RowSP row(new UnwindPlan::Row); + const int32_t ptr_size = 8; + row->GetCFAValue().SetIsRegisterDereferenced(sp_reg_num); + + row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 2, true); + row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); + row->SetRegisterLocationToAtCFAPlusOffset(cr_reg_num, ptr_size, true); + + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("ppc64 default unwind plan"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); + unwind_plan.SetReturnAddressRegister(pc_reg_num); + return true; +} + +bool ABISysV_ppc64::RegisterIsVolatile(const RegisterInfo *reg_info) { + return !RegisterIsCalleeSaved(reg_info); +} + +// See "Register Usage" in the +// "System V Application Binary Interface" +// "64-bit PowerPC ELF Application Binary Interface Supplement" current version +// is 2 released 2015 at +// https://members.openpowerfoundation.org/document/dl/576 +bool ABISysV_ppc64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { + if (reg_info) { + // Preserved registers are : + // r1,r2,r13-r31 + // cr2-cr4 (partially preserved) + // f14-f31 (not yet) + // v20-v31 (not yet) + // vrsave (not yet) + + const char *name = reg_info->name; + if (name[0] == 'r') { + if ((name[1] == '1' || name[1] == '2') && name[2] == '\0') + return true; + if (name[1] == '1' && name[2] > '2') + return true; + if ((name[1] == '2' || name[1] == '3') && name[2] != '\0') + return true; + } + + if (name[0] == 'f' && name[1] >= '0' && name[2] <= '9') { + if (name[2] == '\0') + return false; + if (name[1] == '1' && name[2] >= '4') + return true; + if ((name[1] == '2' || name[1] == '3') && name[2] != '\0') + return true; + } + + if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp + return true; + if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp + return false; + if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc + return true; + } + return false; +} + +void ABISysV_ppc64::Initialize() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), "System V ABI for ppc64 targets", CreateInstance); +} + +void ABISysV_ppc64::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString ABISysV_ppc64::GetPluginNameStatic() { + static ConstString g_name("sysv-ppc64"); + return g_name; +} + +// PluginInterface protocol + +lldb_private::ConstString ABISysV_ppc64::GetPluginName() { + return GetPluginNameStatic(); +} + +uint32_t ABISysV_ppc64::GetPluginVersion() { return 1; } diff --git a/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.h b/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.h new file mode 100644 index 00000000000..8dcf3ca48b5 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.h @@ -0,0 +1,104 @@ +//===-- ABISysV_ppc64.h ----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_POWERPC_ABISYSV_PPC64_H +#define LLDB_SOURCE_PLUGINS_ABI_POWERPC_ABISYSV_PPC64_H + +#include "lldb/Target/ABI.h" +#include "lldb/lldb-private.h" + +class ABISysV_ppc64 : public lldb_private::RegInfoBasedABI { +public: + ~ABISysV_ppc64() override = default; + + size_t GetRedZoneSize() const override; + + bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t functionAddress, + lldb::addr_t returnAddress, + llvm::ArrayRef args) const override; + + bool GetArgumentValues(lldb_private::Thread &thread, + lldb_private::ValueList &values) const override; + + lldb_private::Status + SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value) override; + + lldb::ValueObjectSP + GetReturnValueObjectImpl(lldb_private::Thread &thread, + lldb_private::CompilerType &type) const override; + + bool + CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override; + + // The SysV ppc64 ABI requires that stack frames be 16 byte aligned. + // When there is a trap handler on the stack, e.g. _sigtramp in userland + // code, we've seen that the stack pointer is often not aligned properly + // before the handler is invoked. This means that lldb will stop the unwind + // early -- before the function which caused the trap. + // + // To work around this, we relax that alignment to be just word-size + // (8-bytes). + // Allowing the trap handlers for user space would be easy (_sigtramp) but + // in other environments there can be a large number of different functions + // involved in async traps. + bool CallFrameAddressIsValid(lldb::addr_t cfa) override { + // Make sure the stack call frame addresses are 8 byte aligned + if (cfa & (8ull - 1ull)) + return false; // Not 8 byte aligned + if (cfa == 0) + return false; // Zero is not a valid stack address + return true; + } + + bool CodeAddressIsValid(lldb::addr_t pc) override { + // We have a 64 bit address space, so anything is valid as opcodes + // aren't fixed width... + return true; + } + + const lldb_private::RegisterInfo * + GetRegisterInfoArray(uint32_t &count) override; + + // Static Functions + + static void Initialize(); + + static void Terminate(); + + static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); + + static lldb_private::ConstString GetPluginNameStatic(); + + // PluginInterface protocol + + lldb_private::ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + +protected: + void CreateRegisterMapIfNeeded(); + + lldb::ValueObjectSP + GetReturnValueObjectSimple(lldb_private::Thread &thread, + lldb_private::CompilerType &ast_type) const; + + bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); + +private: + using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance instead. + + lldb::ByteOrder GetByteOrder() const; +}; + +#endif // LLDB_SOURCE_PLUGINS_ABI_POWERPC_ABISYSV_PPC64_H diff --git a/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/CMakeLists.txt new file mode 100644 index 00000000000..57d8e59a6d5 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/PowerPC/CMakeLists.txt @@ -0,0 +1,13 @@ +add_lldb_library(lldbPluginABIPowerPC PLUGIN + ABIPowerPC.cpp + ABISysV_ppc.cpp + ABISysV_ppc64.cpp + + LINK_LIBS + lldbCore + lldbSymbol + lldbTarget + lldbPluginTypeSystemClang + LINK_COMPONENTS + Support + ) diff --git a/gnu/llvm/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp b/gnu/llvm/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp new file mode 100644 index 00000000000..eced2adc759 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp @@ -0,0 +1,746 @@ +//===-- ABISysV_s390x.cpp -------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABISysV_s390x.h" + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Triple.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Core/ValueObjectMemory.h" +#include "lldb/Core/ValueObjectRegister.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Status.h" + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE_ADV(ABISysV_s390x, ABISystemZ) + +enum dwarf_regnums { + // General Purpose Registers + dwarf_r0_s390x = 0, + dwarf_r1_s390x, + dwarf_r2_s390x, + dwarf_r3_s390x, + dwarf_r4_s390x, + dwarf_r5_s390x, + dwarf_r6_s390x, + dwarf_r7_s390x, + dwarf_r8_s390x, + dwarf_r9_s390x, + dwarf_r10_s390x, + dwarf_r11_s390x, + dwarf_r12_s390x, + dwarf_r13_s390x, + dwarf_r14_s390x, + dwarf_r15_s390x, + // Floating Point Registers / Vector Registers 0-15 + dwarf_f0_s390x = 16, + dwarf_f2_s390x, + dwarf_f4_s390x, + dwarf_f6_s390x, + dwarf_f1_s390x, + dwarf_f3_s390x, + dwarf_f5_s390x, + dwarf_f7_s390x, + dwarf_f8_s390x, + dwarf_f10_s390x, + dwarf_f12_s390x, + dwarf_f14_s390x, + dwarf_f9_s390x, + dwarf_f11_s390x, + dwarf_f13_s390x, + dwarf_f15_s390x, + // Access Registers + dwarf_acr0_s390x = 48, + dwarf_acr1_s390x, + dwarf_acr2_s390x, + dwarf_acr3_s390x, + dwarf_acr4_s390x, + dwarf_acr5_s390x, + dwarf_acr6_s390x, + dwarf_acr7_s390x, + dwarf_acr8_s390x, + dwarf_acr9_s390x, + dwarf_acr10_s390x, + dwarf_acr11_s390x, + dwarf_acr12_s390x, + dwarf_acr13_s390x, + dwarf_acr14_s390x, + dwarf_acr15_s390x, + // Program Status Word + dwarf_pswm_s390x = 64, + dwarf_pswa_s390x, + // Vector Registers 16-31 + dwarf_v16_s390x = 68, + dwarf_v18_s390x, + dwarf_v20_s390x, + dwarf_v22_s390x, + dwarf_v17_s390x, + dwarf_v19_s390x, + dwarf_v21_s390x, + dwarf_v23_s390x, + dwarf_v24_s390x, + dwarf_v26_s390x, + dwarf_v28_s390x, + dwarf_v30_s390x, + dwarf_v25_s390x, + dwarf_v27_s390x, + dwarf_v29_s390x, + dwarf_v31_s390x, +}; + +// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB + +#define DEFINE_REG(name, size, alt, generic) \ + { \ + #name, alt, size, 0, eEncodingUint, eFormatHex, \ + {dwarf_##name##_s390x, dwarf_##name##_s390x, generic, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, \ + nullptr, nullptr, nullptr, 0 \ + } + +static RegisterInfo g_register_infos[] = { + DEFINE_REG(r0, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(r1, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(r2, 8, "arg1", LLDB_REGNUM_GENERIC_ARG1), + DEFINE_REG(r3, 8, "arg2", LLDB_REGNUM_GENERIC_ARG2), + DEFINE_REG(r4, 8, "arg3", LLDB_REGNUM_GENERIC_ARG3), + DEFINE_REG(r5, 8, "arg4", LLDB_REGNUM_GENERIC_ARG4), + DEFINE_REG(r6, 8, "arg5", LLDB_REGNUM_GENERIC_ARG5), + DEFINE_REG(r7, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(r8, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(r9, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(r10, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(r11, 8, "fp", LLDB_REGNUM_GENERIC_FP), + DEFINE_REG(r12, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(r13, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(r14, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(r15, 8, "sp", LLDB_REGNUM_GENERIC_SP), + DEFINE_REG(acr0, 4, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(acr1, 4, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(acr2, 4, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(acr3, 4, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(acr4, 4, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(acr5, 4, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(acr6, 4, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(acr7, 4, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(acr8, 4, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(acr9, 4, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(acr10, 4, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(acr11, 4, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(acr12, 4, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(acr13, 4, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(acr14, 4, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(acr15, 4, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(pswm, 8, "flags", LLDB_REGNUM_GENERIC_FLAGS), + DEFINE_REG(pswa, 8, "pc", LLDB_REGNUM_GENERIC_PC), + DEFINE_REG(f0, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(f1, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(f2, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(f3, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(f4, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(f5, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(f6, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(f7, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(f8, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(f9, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(f10, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(f11, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(f12, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(f13, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(f14, 8, nullptr, LLDB_INVALID_REGNUM), + DEFINE_REG(f15, 8, nullptr, LLDB_INVALID_REGNUM), +}; + +static const uint32_t k_num_register_infos = + llvm::array_lengthof(g_register_infos); +static bool g_register_info_names_constified = false; + +const lldb_private::RegisterInfo * +ABISysV_s390x::GetRegisterInfoArray(uint32_t &count) { + // Make the C-string names and alt_names for the register infos into const + // C-string values by having the ConstString unique the names in the global + // constant C-string pool. + if (!g_register_info_names_constified) { + g_register_info_names_constified = true; + for (uint32_t i = 0; i < k_num_register_infos; ++i) { + if (g_register_infos[i].name) + g_register_infos[i].name = + ConstString(g_register_infos[i].name).GetCString(); + if (g_register_infos[i].alt_name) + g_register_infos[i].alt_name = + ConstString(g_register_infos[i].alt_name).GetCString(); + } + } + count = k_num_register_infos; + return g_register_infos; +} + +size_t ABISysV_s390x::GetRedZoneSize() const { return 0; } + +// Static Functions + +ABISP +ABISysV_s390x::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { + if (arch.GetTriple().getArch() == llvm::Triple::systemz) { + return ABISP(new ABISysV_s390x(std::move(process_sp), MakeMCRegisterInfo(arch))); + } + return ABISP(); +} + +bool ABISysV_s390x::PrepareTrivialCall(Thread &thread, addr_t sp, + addr_t func_addr, addr_t return_addr, + llvm::ArrayRef args) const { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (log) { + StreamString s; + s.Printf("ABISysV_s390x::PrepareTrivialCall (tid = 0x%" PRIx64 + ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 + ", return_addr = 0x%" PRIx64, + thread.GetID(), (uint64_t)sp, (uint64_t)func_addr, + (uint64_t)return_addr); + + for (size_t i = 0; i < args.size(); ++i) + s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast(i + 1), + args[i]); + s.PutCString(")"); + log->PutString(s.GetString()); + } + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return false; + + const RegisterInfo *pc_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + const RegisterInfo *sp_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); + const RegisterInfo *ra_reg_info = reg_ctx->GetRegisterInfoByName("r14", 0); + ProcessSP process_sp(thread.GetProcess()); + + // Allocate a new stack frame and space for stack arguments if necessary + + addr_t arg_pos = 0; + if (args.size() > 5) { + sp -= 8 * (args.size() - 5); + arg_pos = sp; + } + + sp -= 160; + + // Process arguments + + for (size_t i = 0; i < args.size(); ++i) { + if (i < 5) { + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i); + LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", + static_cast(i + 1), args[i], reg_info->name); + if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) + return false; + } else { + Status error; + LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") onto stack", + static_cast(i + 1), args[i]); + if (!process_sp->WritePointerToMemory(arg_pos, args[i], error)) + return false; + arg_pos += 8; + } + } + + // %r14 is set to the return address + + LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr); + + if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr)) + return false; + + // %r15 is set to the actual stack value. + + LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp); + + if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp)) + return false; + + // %pc is set to the address of the called function. + + LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr); + + if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr)) + return false; + + return true; +} + +static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, + bool is_signed, Thread &thread, + uint32_t *argument_register_ids, + unsigned int ¤t_argument_register, + addr_t ¤t_stack_argument) { + if (bit_width > 64) + return false; // Scalar can't hold large integer arguments + + if (current_argument_register < 5) { + scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned( + argument_register_ids[current_argument_register], 0); + current_argument_register++; + if (is_signed) + scalar.SignExtend(bit_width); + } else { + uint32_t byte_size = (bit_width + (8 - 1)) / 8; + Status error; + if (thread.GetProcess()->ReadScalarIntegerFromMemory( + current_stack_argument + 8 - byte_size, byte_size, is_signed, + scalar, error)) { + current_stack_argument += 8; + return true; + } + return false; + } + return true; +} + +bool ABISysV_s390x::GetArgumentValues(Thread &thread, ValueList &values) const { + unsigned int num_values = values.GetSize(); + unsigned int value_index; + + // Extract the register context so we can read arguments from registers + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + + if (!reg_ctx) + return false; + + // Get the pointer to the first stack argument so we have a place to start + // when reading data + + addr_t sp = reg_ctx->GetSP(0); + + if (!sp) + return false; + + addr_t current_stack_argument = sp + 160; + + uint32_t argument_register_ids[5]; + + argument_register_ids[0] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[1] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[2] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[3] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[4] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5) + ->kinds[eRegisterKindLLDB]; + + unsigned int current_argument_register = 0; + + for (value_index = 0; value_index < num_values; ++value_index) { + Value *value = values.GetValueAtIndex(value_index); + + if (!value) + return false; + + // We currently only support extracting values with Clang QualTypes. Do we + // care about others? + CompilerType compiler_type = value->GetCompilerType(); + 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(), *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; +} + +Status ABISysV_s390x::SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value_sp) { + Status error; + if (!new_value_sp) { + error.SetErrorString("Empty value object for return value."); + return error; + } + + CompilerType compiler_type = new_value_sp->GetCompilerType(); + if (!compiler_type) { + error.SetErrorString("Null clang type for return value."); + return error; + } + + Thread *thread = frame_sp->GetThread().get(); + + bool is_signed; + uint32_t count; + bool is_complex; + + RegisterContext *reg_ctx = thread->GetRegisterContext().get(); + + bool set_it_simple = false; + if (compiler_type.IsIntegerOrEnumerationType(is_signed) || + compiler_type.IsPointerType()) { + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r2", 0); + + DataExtractor data; + Status data_error; + size_t num_bytes = new_value_sp->GetData(data, data_error); + if (data_error.Fail()) { + error.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", + data_error.AsCString()); + return error; + } + lldb::offset_t offset = 0; + if (num_bytes <= 8) { + uint64_t raw_value = data.GetMaxU64(&offset, num_bytes); + + if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value)) + set_it_simple = true; + } else { + error.SetErrorString("We don't support returning longer than 64 bit " + "integer values at present."); + } + } else if (compiler_type.IsFloatingPointType(count, is_complex)) { + if (is_complex) + error.SetErrorString( + "We don't support returning complex values at present"); + else { + 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; + Status data_error; + size_t num_bytes = new_value_sp->GetData(data, data_error); + if (data_error.Fail()) { + error.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", + data_error.AsCString()); + return error; + } + + unsigned char buffer[8]; + ByteOrder byte_order = data.GetByteOrder(); + + data.CopyByteOrderedData(0, num_bytes, buffer, 8, byte_order); + f0_value.SetBytes(buffer, 8, byte_order); + reg_ctx->WriteRegister(f0_info, f0_value); + set_it_simple = true; + } else { + // FIXME - don't know how to do long doubles yet. + error.SetErrorString( + "We don't support returning float values > 64 bits at present"); + } + } + } + + if (!set_it_simple) { + // Okay we've got a structure or something that doesn't fit in a simple + // register. We should figure out where it really goes, but we don't + // support this yet. + error.SetErrorString("We only support setting simple integer and float " + "return types at present."); + } + + return error; +} + +ValueObjectSP ABISysV_s390x::GetReturnValueObjectSimple( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + Value value; + + if (!return_compiler_type) + return return_valobj_sp; + + // value.SetContext (Value::eContextTypeClangType, return_value_type); + value.SetCompilerType(return_compiler_type); + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return return_valobj_sp; + + const uint32_t type_flags = return_compiler_type.GetTypeInfo(); + if (type_flags & eTypeIsScalar) { + value.SetValueType(Value::eValueTypeScalar); + + bool success = false; + if (type_flags & eTypeIsInteger) { + // 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) { + default: + break; + + case sizeof(uint64_t): + if (is_signed) + value.GetScalar() = (int64_t)(raw_value); + else + value.GetScalar() = (uint64_t)(raw_value); + success = true; + break; + + case sizeof(uint32_t): + if (is_signed) + value.GetScalar() = (int32_t)(raw_value & UINT32_MAX); + else + value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX); + success = true; + break; + + case sizeof(uint16_t): + if (is_signed) + value.GetScalar() = (int16_t)(raw_value & UINT16_MAX); + else + value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX); + success = true; + break; + + case sizeof(uint8_t): + if (is_signed) + value.GetScalar() = (int8_t)(raw_value & UINT8_MAX); + else + value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX); + success = true; + break; + } + } else if (type_flags & eTypeIsFloat) { + if (type_flags & eTypeIsComplex) { + // Don't handle complex yet. + } else { + 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)) { + value.GetScalar() = (float)data.GetFloat(&offset); + success = true; + } else if (*byte_size == sizeof(double)) { + value.GetScalar() = (double)data.GetDouble(&offset); + success = true; + } else if (*byte_size == sizeof(long double)) { + // Don't handle long double yet. + } + } + } + } + } + } + + if (success) + return_valobj_sp = ValueObjectConstResult::Create( + thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); + } else if (type_flags & eTypeIsPointer) { + unsigned r2_id = + reg_ctx->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB]; + value.GetScalar() = + (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_id, 0); + value.SetValueType(Value::eValueTypeScalar); + return_valobj_sp = ValueObjectConstResult::Create( + thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); + } + + return return_valobj_sp; +} + +ValueObjectSP ABISysV_s390x::GetReturnValueObjectImpl( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + + if (!return_compiler_type) + return return_valobj_sp; + + ExecutionContext exe_ctx(thread.shared_from_this()); + return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type); + if (return_valobj_sp) + return return_valobj_sp; + + RegisterContextSP reg_ctx_sp = thread.GetRegisterContext(); + if (!reg_ctx_sp) + return return_valobj_sp; + + if (return_compiler_type.IsAggregateType()) { + // FIXME: This is just taking a guess, r2 may very well no longer hold the + // return storage location. + // If we are going to do this right, when we make a new frame we should + // check to see if it uses a memory return, and if we are at the first + // instruction and if so stash away the return location. Then we would + // only return the memory return value if we know it is valid. + + unsigned r2_id = + reg_ctx_sp->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB]; + lldb::addr_t storage_addr = + (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_id, 0); + return_valobj_sp = ValueObjectMemory::Create( + &thread, "", Address(storage_addr, nullptr), return_compiler_type); + } + + return return_valobj_sp; +} + +bool ABISysV_s390x::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + UnwindPlan::RowSP row(new UnwindPlan::Row); + + // Our Call Frame Address is the stack pointer value + 160 + row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r15_s390x, 160); + + // The previous PC is in r14 + row->SetRegisterLocationToRegister(dwarf_pswa_s390x, dwarf_r14_s390x, true); + + // All other registers are the same. + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("s390x at-func-entry default"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + return true; +} + +bool ABISysV_s390x::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { + // There's really no default way to unwind on s390x. Trust the .eh_frame CFI, + // which should always be good. + return false; +} + +bool ABISysV_s390x::GetFallbackRegisterLocation( + const RegisterInfo *reg_info, + UnwindPlan::Row::RegisterLocation &unwind_regloc) { + // If a volatile register is being requested, we don't want to forward the + // next frame's register contents up the stack -- the register is not + // retrievable at this frame. + if (RegisterIsVolatile(reg_info)) { + unwind_regloc.SetUndefined(); + return true; + } + + return false; +} + +bool ABISysV_s390x::RegisterIsVolatile(const RegisterInfo *reg_info) { + return !RegisterIsCalleeSaved(reg_info); +} + +bool ABISysV_s390x::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { + if (reg_info) { + // Preserved registers are : + // r6-r13, r15 + // f8-f15 + + const char *name = reg_info->name; + if (name[0] == 'r') { + switch (name[1]) { + case '6': // r6 + case '7': // r7 + case '8': // r8 + case '9': // r9 + return name[2] == '\0'; + + case '1': // r10, r11, r12, r13, r15 + if ((name[2] >= '0' && name[2] <= '3') || name[2] == '5') + return name[3] == '\0'; + break; + + default: + break; + } + } + if (name[0] == 'f') { + switch (name[1]) { + case '8': // r8 + case '9': // r9 + return name[2] == '\0'; + + case '1': // r10, r11, r12, r13, r14, r15 + if (name[2] >= '0' && name[2] <= '5') + return name[3] == '\0'; + break; + + default: + break; + } + } + + // Accept shorter-variant versions + if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp + return true; + if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp + return true; + if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc + return true; + } + return false; +} + +void ABISysV_s390x::Initialize() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), "System V ABI for s390x targets", CreateInstance); +} + +void ABISysV_s390x::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString ABISysV_s390x::GetPluginNameStatic() { + static ConstString g_name("sysv-s390x"); + return g_name; +} + +// PluginInterface protocol + +lldb_private::ConstString ABISysV_s390x::GetPluginName() { + return GetPluginNameStatic(); +} + +uint32_t ABISysV_s390x::GetPluginVersion() { return 1; } diff --git a/gnu/llvm/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.h b/gnu/llvm/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.h new file mode 100644 index 00000000000..f8f41246565 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.h @@ -0,0 +1,94 @@ +//===-- ABISysV_s390x.h -----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_SYSTEMZ_ABISYSV_S390X_H +#define LLDB_SOURCE_PLUGINS_ABI_SYSTEMZ_ABISYSV_S390X_H + +#include "lldb/Target/ABI.h" +#include "lldb/lldb-private.h" + +class ABISysV_s390x : public lldb_private::RegInfoBasedABI { +public: + ~ABISysV_s390x() override = default; + + size_t GetRedZoneSize() const override; + + bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t functionAddress, + lldb::addr_t returnAddress, + llvm::ArrayRef args) const override; + + bool GetArgumentValues(lldb_private::Thread &thread, + lldb_private::ValueList &values) const override; + + lldb_private::Status + SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value) override; + + lldb::ValueObjectSP + GetReturnValueObjectImpl(lldb_private::Thread &thread, + lldb_private::CompilerType &type) const override; + + bool + CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override; + + bool GetFallbackRegisterLocation( + const lldb_private::RegisterInfo *reg_info, + lldb_private::UnwindPlan::Row::RegisterLocation &unwind_regloc) override; + + bool CallFrameAddressIsValid(lldb::addr_t cfa) override { + // Make sure the stack call frame addresses are 8 byte aligned + if (cfa & (8ull - 1ull)) + return false; // Not 8 byte aligned + if (cfa == 0) + return false; // Zero is not a valid stack address + return true; + } + + bool CodeAddressIsValid(lldb::addr_t pc) override { + // Code addressed must be 2 byte aligned + return (pc & 1ull) == 0; + } + + const lldb_private::RegisterInfo * + GetRegisterInfoArray(uint32_t &count) override; + + // Static Functions + + static void Initialize(); + + static void Terminate(); + + static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); + + static lldb_private::ConstString GetPluginNameStatic(); + + // PluginInterface protocol + + lldb_private::ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + +protected: + void CreateRegisterMapIfNeeded(); + + lldb::ValueObjectSP + GetReturnValueObjectSimple(lldb_private::Thread &thread, + lldb_private::CompilerType &ast_type) const; + + bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); + +private: + using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance instead. +}; + +#endif // LLDB_SOURCE_PLUGINS_ABI_SYSTEMZ_ABISYSV_S390X_H diff --git a/gnu/llvm/lldb/source/Plugins/ABI/SystemZ/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/ABI/SystemZ/CMakeLists.txt new file mode 100644 index 00000000000..8f23da07a69 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/SystemZ/CMakeLists.txt @@ -0,0 +1,10 @@ +add_lldb_library(lldbPluginABISystemZ PLUGIN + ABISysV_s390x.cpp + + LINK_LIBS + lldbCore + lldbSymbol + lldbTarget + LINK_COMPONENTS + Support + ) diff --git a/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp new file mode 100644 index 00000000000..89112deb2c4 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp @@ -0,0 +1,474 @@ +//===-- ABIMacOSX_i386.cpp ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABIMacOSX_i386.h" + +#include + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Triple.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#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; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(ABIMacOSX_i386) + +enum { + dwarf_eax = 0, + dwarf_ecx, + dwarf_edx, + dwarf_ebx, + dwarf_esp, + dwarf_ebp, + dwarf_esi, + dwarf_edi, + dwarf_eip, +}; + +size_t ABIMacOSX_i386::GetRedZoneSize() const { return 0; } + +// Static Functions + +ABISP +ABIMacOSX_i386::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { + if ((arch.GetTriple().getArch() == llvm::Triple::x86) && + (arch.GetTriple().isMacOSX() || arch.GetTriple().isiOS() || + arch.GetTriple().isWatchOS())) { + return ABISP( + new ABIMacOSX_i386(std::move(process_sp), MakeMCRegisterInfo(arch))); + } + return ABISP(); +} + +bool ABIMacOSX_i386::PrepareTrivialCall(Thread &thread, addr_t sp, + addr_t func_addr, addr_t return_addr, + llvm::ArrayRef args) const { + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return false; + uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); + + // When writing a register value down to memory, the register info used to + // write memory just needs to have the correct size of a 32 bit register, the + // actual register it pertains to is not important, just the size needs to be + // correct. Here we use "eax"... + const RegisterInfo *reg_info_32 = reg_ctx->GetRegisterInfoByName("eax"); + if (!reg_info_32) + return false; // TODO this should actually never happen + + // Make room for the argument(s) on the stack + + Status error; + RegisterValue reg_value; + + // Write any arguments onto the stack + sp -= 4 * args.size(); + + // Align the SP + sp &= ~(16ull - 1ull); // 16-byte alignment + + addr_t arg_pos = sp; + + for (addr_t arg : args) { + reg_value.SetUInt32(arg); + error = reg_ctx->WriteRegisterValueToMemory( + reg_info_32, arg_pos, reg_info_32->byte_size, reg_value); + if (error.Fail()) + return false; + arg_pos += 4; + } + + // The return address is pushed onto the stack (yes after we just set the + // alignment above!). + sp -= 4; + reg_value.SetUInt32(return_addr); + error = reg_ctx->WriteRegisterValueToMemory( + reg_info_32, sp, reg_info_32->byte_size, reg_value); + if (error.Fail()) + return false; + + // %esp is set to the actual stack value. + + if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp)) + return false; + + // %eip is set to the address of the called function. + + if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, func_addr)) + return false; + + return true; +} + +static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, + bool is_signed, Process *process, + addr_t ¤t_stack_argument) { + + uint32_t byte_size = (bit_width + (8 - 1)) / 8; + Status error; + if (process->ReadScalarIntegerFromMemory(current_stack_argument, byte_size, + is_signed, scalar, error)) { + current_stack_argument += byte_size; + return true; + } + return false; +} + +bool ABIMacOSX_i386::GetArgumentValues(Thread &thread, + ValueList &values) const { + unsigned int num_values = values.GetSize(); + unsigned int value_index; + + // Get the pointer to the first stack argument so we have a place to start + // when reading data + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + + if (!reg_ctx) + return false; + + addr_t sp = reg_ctx->GetSP(0); + + if (!sp) + return false; + + addr_t current_stack_argument = sp + 4; // jump over return address + + for (value_index = 0; value_index < num_values; ++value_index) { + Value *value = values.GetValueAtIndex(value_index); + + if (!value) + return false; + + // We currently only support extracting values with Clang QualTypes. Do we + // care about others? + CompilerType compiler_type(value->GetCompilerType()); + llvm::Optional bit_size = compiler_type.GetBitSize(&thread); + if (bit_size) { + bool 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(), *bit_size, false, + thread.GetProcess().get(), current_stack_argument); + } + } + + return true; +} + +Status ABIMacOSX_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value_sp) { + Status error; + if (!new_value_sp) { + error.SetErrorString("Empty value object for return value."); + return error; + } + + CompilerType compiler_type = new_value_sp->GetCompilerType(); + if (!compiler_type) { + error.SetErrorString("Null clang type for return value."); + return error; + } + + Thread *thread = frame_sp->GetThread().get(); + + bool is_signed; + uint32_t count; + bool is_complex; + + RegisterContext *reg_ctx = thread->GetRegisterContext().get(); + + bool set_it_simple = false; + if (compiler_type.IsIntegerOrEnumerationType(is_signed) || + compiler_type.IsPointerType()) { + DataExtractor data; + Status data_error; + size_t num_bytes = new_value_sp->GetData(data, data_error); + if (data_error.Fail()) { + error.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", + data_error.AsCString()); + return error; + } + lldb::offset_t offset = 0; + if (num_bytes <= 8) { + const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0); + if (num_bytes <= 4) { + uint32_t raw_value = data.GetMaxU32(&offset, num_bytes); + + if (reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value)) + set_it_simple = true; + } else { + uint32_t raw_value = data.GetMaxU32(&offset, 4); + + if (reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value)) { + const RegisterInfo *edx_info = + reg_ctx->GetRegisterInfoByName("edx", 0); + uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset); + + if (reg_ctx->WriteRegisterFromUnsigned(edx_info, raw_value)) + set_it_simple = true; + } + } + } else { + error.SetErrorString("We don't support returning longer than 64 bit " + "integer values at present."); + } + } else if (compiler_type.IsFloatingPointType(count, is_complex)) { + if (is_complex) + error.SetErrorString( + "We don't support returning complex values at present"); + else + error.SetErrorString( + "We don't support returning float values at present"); + } + + if (!set_it_simple) + error.SetErrorString( + "We only support setting simple integer return types at present."); + + return error; +} + +ValueObjectSP +ABIMacOSX_i386::GetReturnValueObjectImpl(Thread &thread, + CompilerType &compiler_type) const { + Value value; + ValueObjectSP return_valobj_sp; + + if (!compiler_type) + return return_valobj_sp; + + // value.SetContext (Value::eContextTypeClangType, + // compiler_type.GetOpaqueQualType()); + value.SetCompilerType(compiler_type); + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return return_valobj_sp; + + bool is_signed; + + if (compiler_type.IsIntegerOrEnumerationType(is_signed)) { + 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) { + default: + case 128: + // Scalar can't hold 128-bit literals, so we don't handle this + return return_valobj_sp; + case 64: + uint64_t raw_value; + raw_value = + thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & + 0xffffffff; + raw_value |= + (thread.GetRegisterContext()->ReadRegisterAsUnsigned(edx_id, 0) & + 0xffffffff) + << 32; + if (is_signed) + value.GetScalar() = (int64_t)raw_value; + else + value.GetScalar() = (uint64_t)raw_value; + break; + case 32: + if (is_signed) + value.GetScalar() = (int32_t)( + thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & + 0xffffffff); + else + value.GetScalar() = (uint32_t)( + thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & + 0xffffffff); + break; + case 16: + if (is_signed) + value.GetScalar() = (int16_t)( + thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & + 0xffff); + else + value.GetScalar() = (uint16_t)( + thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & + 0xffff); + break; + case 8: + if (is_signed) + value.GetScalar() = (int8_t)( + thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & + 0xff); + else + value.GetScalar() = (uint8_t)( + thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & + 0xff); + break; + } + } else if (compiler_type.IsPointerType()) { + unsigned eax_id = + reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB]; + uint32_t ptr = + thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & + 0xffffffff; + value.GetScalar() = ptr; + } else { + // not handled yet + return return_valobj_sp; + } + + // If we get here, we have a valid Value, so make our ValueObject out of it: + + return_valobj_sp = ValueObjectConstResult::Create( + thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); + return return_valobj_sp; +} + +// This defines the CFA as esp+4 +// the saved pc is at CFA-4 (i.e. esp+0) +// The saved esp is CFA+0 + +bool ABIMacOSX_i386::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t sp_reg_num = dwarf_esp; + uint32_t pc_reg_num = dwarf_eip; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 4); + row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false); + row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("i386 at-func-entry default"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + return true; +} + +// This defines the CFA as ebp+8 +// The saved pc is at CFA-4 (i.e. ebp+4) +// The saved ebp is at CFA-8 (i.e. ebp+0) +// The saved esp is CFA+0 + +bool ABIMacOSX_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t fp_reg_num = dwarf_ebp; + uint32_t sp_reg_num = dwarf_esp; + uint32_t pc_reg_num = dwarf_eip; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + const int32_t ptr_size = 4; + + row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size); + row->SetOffset(0); + + row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); + row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); + row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); + + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("i386 default unwind plan"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); + return true; +} + +bool ABIMacOSX_i386::RegisterIsVolatile(const RegisterInfo *reg_info) { + return !RegisterIsCalleeSaved(reg_info); +} + +// v. +// http://developer.apple.com/library/mac/#documentation/developertools/Conceptual/LowLevelABI/130 +// -IA- +// 32_Function_Calling_Conventions/IA32.html#//apple_ref/doc/uid/TP40002492-SW4 +// +// This document ("OS X ABI Function Call Guide", chapter "IA-32 Function +// Calling Conventions") says that the following registers on i386 are +// preserved aka non-volatile aka callee-saved: +// +// ebx, ebp, esi, edi, esp + +bool ABIMacOSX_i386::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { + if (reg_info) { + // Saved registers are ebx, ebp, esi, edi, esp, eip + const char *name = reg_info->name; + if (name[0] == 'e') { + switch (name[1]) { + case 'b': + if (name[2] == 'x' || name[2] == 'p') + return name[3] == '\0'; + break; + case 'd': + if (name[2] == 'i') + return name[3] == '\0'; + break; + case 'i': + if (name[2] == 'p') + return name[3] == '\0'; + break; + case 's': + if (name[2] == 'i' || name[2] == 'p') + return name[3] == '\0'; + break; + } + } + if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp + return true; + if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp + return true; + if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc + return true; + } + return false; +} + +void ABIMacOSX_i386::Initialize() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), "Mac OS X ABI for i386 targets", CreateInstance); +} + +void ABIMacOSX_i386::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString ABIMacOSX_i386::GetPluginNameStatic() { + static ConstString g_short_name("abi.macosx-i386"); + return g_short_name; +} + +// PluginInterface protocol + +lldb_private::ConstString ABIMacOSX_i386::GetPluginName() { + return GetPluginNameStatic(); +} + +uint32_t ABIMacOSX_i386::GetPluginVersion() { return 1; } diff --git a/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h new file mode 100644 index 00000000000..b8b25314416 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h @@ -0,0 +1,100 @@ +//===-- ABIMacOSX_i386.h ----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_X86_ABIMACOSX_I386_H +#define LLDB_SOURCE_PLUGINS_ABI_X86_ABIMACOSX_I386_H + +#include "Plugins/ABI/X86/ABIX86.h" +#include "lldb/Core/Value.h" +#include "lldb/lldb-private.h" + +class ABIMacOSX_i386 : public ABIX86 { +public: + ~ABIMacOSX_i386() override = default; + + size_t GetRedZoneSize() const override; + + bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t func_addr, lldb::addr_t return_addr, + llvm::ArrayRef args) const override; + + bool GetArgumentValues(lldb_private::Thread &thread, + lldb_private::ValueList &values) const override; + + lldb_private::Status + SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value) override; + + bool + CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override; + + // The Darwin i386 ABI requires that stack frames be 16 byte aligned. + // When there is a trap handler on the stack, e.g. _sigtramp in userland + // code, we've seen that the stack pointer is often not aligned properly + // before the handler is invoked. This means that lldb will stop the unwind + // early -- before the function which caused the trap. + // + // To work around this, we relax that alignment to be just word-size + // (4-bytes). + // Allowing the trap handlers for user space would be easy (_sigtramp) but + // in other environments there can be a large number of different functions + // involved in async traps. + // + // If we were to enforce 16-byte alignment, we also need to relax to 4-byte + // alignment for non-darwin i386 targets. + bool CallFrameAddressIsValid(lldb::addr_t cfa) override { + // Make sure the stack call frame addresses are are 4 byte aligned + if (cfa & (4ull - 1ull)) + return false; // Not 4 byte aligned + if (cfa == 0) + return false; // Zero is not a valid stack address + return true; + } + + bool CodeAddressIsValid(lldb::addr_t pc) override { + // Just make sure the address is a valid 32 bit address. + return pc <= UINT32_MAX; + } + + // Static Functions + + static void Initialize(); + + static void Terminate(); + + static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); + + // PluginInterface protocol + + static lldb_private::ConstString GetPluginNameStatic(); + + lldb_private::ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + +protected: + lldb::ValueObjectSP + GetReturnValueObjectImpl(lldb_private::Thread &thread, + lldb_private::CompilerType &ast_type) const override; + + bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); + + std::string GetMCName(std::string name) override { + MapRegisterName(name, "stmm", "st"); + return name; + } + +private: + using ABIX86::ABIX86; // Call CreateInstance instead. +}; + +#endif // LLDB_SOURCE_PLUGINS_ABI_X86_ABIMACOSX_I386_H diff --git a/gnu/llvm/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp new file mode 100644 index 00000000000..2ac87d1512e --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp @@ -0,0 +1,726 @@ +//===-- ABISysV_i386.cpp --------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +//===----------------------------------------------------------------------===// + +#include "ABISysV_i386.h" + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Triple.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Core/ValueObjectMemory.h" +#include "lldb/Core/ValueObjectRegister.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Status.h" + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(ABISysV_i386) + +// This source file uses the following document as a reference: +//==================================================================== +// System V Application Binary Interface +// Intel386 Architecture Processor Supplement, Version 1.0 +// Edited by +// H.J. Lu, David L Kreitzer, Milind Girkar, Zia Ansari +// +// (Based on +// System V Application Binary Interface, +// AMD64 Architecture Processor Supplement, +// Edited by +// H.J. Lu, Michael Matz, Milind Girkar, Jan Hubicka, +// Andreas Jaeger, Mark Mitchell) +// +// February 3, 2015 +//==================================================================== + +// DWARF Register Number Mapping +// See Table 2.14 of the reference document (specified on top of this file) +// Comment: Table 2.14 is followed till 'mm' entries. After that, all entries +// are ignored here. + +enum dwarf_regnums { + dwarf_eax = 0, + dwarf_ecx, + dwarf_edx, + dwarf_ebx, + dwarf_esp, + dwarf_ebp, + dwarf_esi, + dwarf_edi, + dwarf_eip, +}; + +// Static Functions + +ABISP +ABISysV_i386::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { + if (arch.GetTriple().getVendor() != llvm::Triple::Apple) { + if (arch.GetTriple().getArch() == llvm::Triple::x86) { + return ABISP( + new ABISysV_i386(std::move(process_sp), MakeMCRegisterInfo(arch))); + } + } + return ABISP(); +} + +bool ABISysV_i386::PrepareTrivialCall(Thread &thread, addr_t sp, + addr_t func_addr, addr_t return_addr, + llvm::ArrayRef args) const { + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + + if (!reg_ctx) + return false; + + uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); + + // While using register info to write a register value to memory, the + // register info just needs to have the correct size of a 32 bit register, + // the actual register it pertains to is not important, just the size needs + // to be correct. "eax" is used here for this purpose. + const RegisterInfo *reg_info_32 = reg_ctx->GetRegisterInfoByName("eax"); + if (!reg_info_32) + return false; // TODO this should actually never happen + + Status error; + RegisterValue reg_value; + + // Make room for the argument(s) on the stack + sp -= 4 * args.size(); + + // SP Alignment + sp &= ~(16ull - 1ull); // 16-byte alignment + + // Write arguments onto the stack + addr_t arg_pos = sp; + for (addr_t arg : args) { + reg_value.SetUInt32(arg); + error = reg_ctx->WriteRegisterValueToMemory( + reg_info_32, arg_pos, reg_info_32->byte_size, reg_value); + if (error.Fail()) + return false; + arg_pos += 4; + } + + // The return address is pushed onto the stack + sp -= 4; + reg_value.SetUInt32(return_addr); + error = reg_ctx->WriteRegisterValueToMemory( + reg_info_32, sp, reg_info_32->byte_size, reg_value); + if (error.Fail()) + return false; + + // Setting %esp to the actual stack value. + if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp)) + return false; + + // Setting %eip to the address of the called function. + if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, func_addr)) + return false; + + return true; +} + +static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, + bool is_signed, Process *process, + addr_t ¤t_stack_argument) { + uint32_t byte_size = (bit_width + (8 - 1)) / 8; + Status error; + + if (!process) + return false; + + if (process->ReadScalarIntegerFromMemory(current_stack_argument, byte_size, + is_signed, scalar, error)) { + current_stack_argument += byte_size; + return true; + } + return false; +} + +bool ABISysV_i386::GetArgumentValues(Thread &thread, ValueList &values) const { + unsigned int num_values = values.GetSize(); + unsigned int value_index; + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + + if (!reg_ctx) + return false; + + // Get pointer to the first stack argument + addr_t sp = reg_ctx->GetSP(0); + if (!sp) + return false; + + addr_t current_stack_argument = sp + 4; // jump over return address + + for (value_index = 0; value_index < num_values; ++value_index) { + Value *value = values.GetValueAtIndex(value_index); + + if (!value) + return false; + + // Currently: Support for extracting values with Clang QualTypes only. + CompilerType compiler_type(value->GetCompilerType()); + llvm::Optional bit_size = compiler_type.GetBitSize(&thread); + if (bit_size) { + bool 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(), *bit_size, false, + thread.GetProcess().get(), current_stack_argument); + } + } + } + return true; +} + +Status ABISysV_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value_sp) { + Status error; + if (!new_value_sp) { + error.SetErrorString("Empty value object for return value."); + return error; + } + + CompilerType compiler_type = new_value_sp->GetCompilerType(); + if (!compiler_type) { + error.SetErrorString("Null clang type for return value."); + return error; + } + + const uint32_t type_flags = compiler_type.GetTypeInfo(); + Thread *thread = frame_sp->GetThread().get(); + RegisterContext *reg_ctx = thread->GetRegisterContext().get(); + DataExtractor data; + Status data_error; + size_t num_bytes = new_value_sp->GetData(data, data_error); + bool register_write_successful = true; + + if (data_error.Fail()) { + error.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", + data_error.AsCString()); + return error; + } + + // Following "IF ELSE" block categorizes various 'Fundamental Data Types'. + // The terminology 'Fundamental Data Types' used here is adopted from Table + // 2.1 of the reference document (specified on top of this file) + + if (type_flags & eTypeIsPointer) // 'Pointer' + { + if (num_bytes != sizeof(uint32_t)) { + error.SetErrorString("Pointer to be returned is not 4 bytes wide"); + return error; + } + lldb::offset_t offset = 0; + const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0); + uint32_t raw_value = data.GetMaxU32(&offset, num_bytes); + register_write_successful = + reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value); + } else if ((type_flags & eTypeIsScalar) || + (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point' + { + lldb::offset_t offset = 0; + const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0); + + if (type_flags & eTypeIsInteger) // 'Integral' except enum + { + switch (num_bytes) { + default: + break; + case 16: + // For clang::BuiltinType::UInt128 & Int128 ToDo: Need to decide how to + // handle it + break; + case 8: { + uint32_t raw_value_low = data.GetMaxU32(&offset, 4); + const RegisterInfo *edx_info = reg_ctx->GetRegisterInfoByName("edx", 0); + uint32_t raw_value_high = data.GetMaxU32(&offset, num_bytes - offset); + register_write_successful = + (reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value_low) && + reg_ctx->WriteRegisterFromUnsigned(edx_info, raw_value_high)); + break; + } + case 4: + case 2: + case 1: { + uint32_t raw_value = data.GetMaxU32(&offset, num_bytes); + register_write_successful = + reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value); + break; + } + } + } else if (type_flags & eTypeIsEnumeration) // handles enum + { + uint32_t raw_value = data.GetMaxU32(&offset, num_bytes); + register_write_successful = + reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value); + } else if (type_flags & eTypeIsFloat) // 'Floating Point' + { + RegisterValue st0_value, fstat_value, ftag_value; + const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0); + const RegisterInfo *fstat_info = + reg_ctx->GetRegisterInfoByName("fstat", 0); + const RegisterInfo *ftag_info = reg_ctx->GetRegisterInfoByName("ftag", 0); + + /* According to Page 3-12 of document + System V Application Binary Interface, Intel386 Architecture Processor + Supplement, Fourth Edition + To return Floating Point values, all st% registers except st0 should be + empty after exiting from + a function. This requires setting fstat and ftag registers to specific + values. + fstat: The TOP field of fstat should be set to a value [0,7]. ABI doesn't + specify the specific + value of TOP in case of function return. Hence, we set the TOP field to 7 + by our choice. */ + uint32_t value_fstat_u32 = 0x00003800; + + /* ftag: Implication of setting TOP to 7 and indicating all st% registers + empty except st0 is to set + 7th bit of 4th byte of FXSAVE area to 1 and all other bits of this byte to + 0. This is in accordance + with the document Intel 64 and IA-32 Architectures Software Developer's + Manual, January 2015 */ + uint32_t value_ftag_u32 = 0x00000080; + + if (num_bytes <= 12) // handles float, double, long double, __float80 + { + long double value_long_dbl = 0.0; + if (num_bytes == 4) + value_long_dbl = data.GetFloat(&offset); + else if (num_bytes == 8) + value_long_dbl = data.GetDouble(&offset); + else if (num_bytes == 12) + value_long_dbl = data.GetLongDouble(&offset); + else { + error.SetErrorString("Invalid number of bytes for this return type"); + return error; + } + st0_value.SetLongDouble(value_long_dbl); + fstat_value.SetUInt32(value_fstat_u32); + ftag_value.SetUInt32(value_ftag_u32); + register_write_successful = + reg_ctx->WriteRegister(st0_info, st0_value) && + reg_ctx->WriteRegister(fstat_info, fstat_value) && + reg_ctx->WriteRegister(ftag_info, ftag_value); + } else if (num_bytes == 16) // handles __float128 + { + error.SetErrorString("Implementation is missing for this clang type."); + } + } else { + // Neither 'Integral' nor 'Floating Point'. If flow reaches here then + // check type_flags. This type_flags is not a valid type. + error.SetErrorString("Invalid clang type"); + } + } else { + /* 'Complex Floating Point', 'Packed', 'Decimal Floating Point' and + 'Aggregate' data types + are yet to be implemented */ + error.SetErrorString("Currently only Integral and Floating Point clang " + "types are supported."); + } + if (!register_write_successful) + error.SetErrorString("Register writing failed"); + return error; +} + +ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + Value value; + + if (!return_compiler_type) + return return_valobj_sp; + + value.SetCompilerType(return_compiler_type); + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return return_valobj_sp; + + const uint32_t type_flags = return_compiler_type.GetTypeInfo(); + + unsigned eax_id = + reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB]; + unsigned edx_id = + reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB]; + + // Following "IF ELSE" block categorizes various 'Fundamental Data Types'. + // The terminology 'Fundamental Data Types' used here is adopted from Table + // 2.1 of the reference document (specified on top of this file) + + if (type_flags & eTypeIsPointer) // 'Pointer' + { + uint32_t ptr = + thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & + 0xffffffff; + value.SetValueType(Value::eValueTypeScalar); + value.GetScalar() = ptr; + return_valobj_sp = ValueObjectConstResult::Create( + thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); + } else if ((type_flags & eTypeIsScalar) || + (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point' + { + value.SetValueType(Value::eValueTypeScalar); + 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 + { + const bool is_signed = ((type_flags & eTypeIsSigned) != 0); + uint64_t raw_value = + thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & + 0xffffffff; + raw_value |= + (thread.GetRegisterContext()->ReadRegisterAsUnsigned(edx_id, 0) & + 0xffffffff) + << 32; + + switch (*byte_size) { + default: + break; + + case 16: + // For clang::BuiltinType::UInt128 & Int128 ToDo: Need to decide how to + // handle it + break; + + case 8: + if (is_signed) + value.GetScalar() = (int64_t)(raw_value); + else + value.GetScalar() = (uint64_t)(raw_value); + success = true; + break; + + case 4: + if (is_signed) + value.GetScalar() = (int32_t)(raw_value & UINT32_MAX); + else + value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX); + success = true; + break; + + case 2: + if (is_signed) + value.GetScalar() = (int16_t)(raw_value & UINT16_MAX); + else + value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX); + success = true; + break; + + case 1: + if (is_signed) + value.GetScalar() = (int8_t)(raw_value & UINT8_MAX); + else + value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX); + success = true; + break; + } + + if (success) + return_valobj_sp = ValueObjectConstResult::Create( + thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); + } else if (type_flags & eTypeIsEnumeration) // handles enum + { + uint32_t enm = + thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & + 0xffffffff; + value.SetValueType(Value::eValueTypeScalar); + value.GetScalar() = enm; + return_valobj_sp = ValueObjectConstResult::Create( + thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); + } else if (type_flags & eTypeIsFloat) // 'Floating Point' + { + if (*byte_size <= 12) // handles float, double, long double, __float80 + { + const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0); + RegisterValue st0_value; + + if (reg_ctx->ReadRegister(st0_info, st0_value)) { + DataExtractor data; + if (st0_value.GetData(data)) { + lldb::offset_t offset = 0; + long double value_long_double = data.GetLongDouble(&offset); + + // 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 + // 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. + value.GetScalar() = value_long_double; + success = true; + } + } + } + + if (success) + return_valobj_sp = ValueObjectConstResult::Create( + thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); + } else if (*byte_size == 16) // handles __float128 + { + lldb::addr_t storage_addr = (uint32_t)( + thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & + 0xffffffff); + return_valobj_sp = ValueObjectMemory::Create( + &thread, "", Address(storage_addr, nullptr), return_compiler_type); + } + } else // Neither 'Integral' nor 'Floating Point' + { + // If flow reaches here then check type_flags This type_flags is + // unhandled + } + } else if (type_flags & eTypeIsComplex) // 'Complex Floating Point' + { + // ToDo: Yet to be implemented + } else if (type_flags & eTypeIsVector) // 'Packed' + { + 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) { + ProcessSP process_sp(thread.GetProcess()); + if (process_sp) { + std::unique_ptr heap_data_up( + new DataBufferHeap(*byte_size, 0)); + const ByteOrder byte_order = process_sp->GetByteOrder(); + RegisterValue reg_value; + if (reg_ctx->ReadRegister(vec_reg, reg_value)) { + Status error; + if (reg_value.GetAsMemoryData(vec_reg, heap_data_up->GetBytes(), + heap_data_up->GetByteSize(), + byte_order, error)) { + DataExtractor data(DataBufferSP(heap_data_up.release()), + byte_order, + process_sp->GetTarget() + .GetArchitecture() + .GetAddressByteSize()); + return_valobj_sp = ValueObjectConstResult::Create( + &thread, return_compiler_type, ConstString(""), data); + } + } + } + } 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_up( + new DataBufferHeap(*byte_size, 0)); + const ByteOrder byte_order = process_sp->GetByteOrder(); + RegisterValue reg_value; + RegisterValue reg_value2; + if (reg_ctx->ReadRegister(vec_reg, reg_value) && + reg_ctx->ReadRegister(vec_reg2, reg_value2)) { + + Status error; + if (reg_value.GetAsMemoryData(vec_reg, heap_data_up->GetBytes(), + vec_reg->byte_size, byte_order, + error) && + reg_value2.GetAsMemoryData( + vec_reg2, heap_data_up->GetBytes() + vec_reg->byte_size, + heap_data_up->GetByteSize() - vec_reg->byte_size, + byte_order, error)) { + DataExtractor data(DataBufferSP(heap_data_up.release()), + byte_order, + process_sp->GetTarget() + .GetArchitecture() + .GetAddressByteSize()); + return_valobj_sp = ValueObjectConstResult::Create( + &thread, return_compiler_type, ConstString(""), data); + } + } + } + } + } + } + } + } else // 'Decimal Floating Point' + { + // ToDo: Yet to be implemented + } + return return_valobj_sp; +} + +ValueObjectSP ABISysV_i386::GetReturnValueObjectImpl( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + + if (!return_compiler_type) + return return_valobj_sp; + + ExecutionContext exe_ctx(thread.shared_from_this()); + return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type); + if (return_valobj_sp) + return return_valobj_sp; + + RegisterContextSP reg_ctx_sp = thread.GetRegisterContext(); + if (!reg_ctx_sp) + return return_valobj_sp; + + if (return_compiler_type.IsAggregateType()) { + unsigned eax_id = + reg_ctx_sp->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB]; + lldb::addr_t storage_addr = (uint32_t)( + thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & + 0xffffffff); + return_valobj_sp = ValueObjectMemory::Create( + &thread, "", Address(storage_addr, nullptr), return_compiler_type); + } + + return return_valobj_sp; +} + +// This defines CFA as esp+4 +// The saved pc is at CFA-4 (i.e. esp+0) +// The saved esp is CFA+0 + +bool ABISysV_i386::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t sp_reg_num = dwarf_esp; + uint32_t pc_reg_num = dwarf_eip; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 4); + row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false); + row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("i386 at-func-entry default"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + return true; +} + +// This defines CFA as ebp+8 +// The saved pc is at CFA-4 (i.e. ebp+4) +// The saved ebp is at CFA-8 (i.e. ebp+0) +// The saved esp is CFA+0 + +bool ABISysV_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t fp_reg_num = dwarf_ebp; + uint32_t sp_reg_num = dwarf_esp; + uint32_t pc_reg_num = dwarf_eip; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + const int32_t ptr_size = 4; + + row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size); + row->SetOffset(0); + + row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); + row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); + row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); + + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("i386 default unwind plan"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); + return true; +} + +// According to "Register Usage" in reference document (specified on top of +// this source file) ebx, ebp, esi, edi and esp registers are preserved i.e. +// non-volatile i.e. callee-saved on i386 +bool ABISysV_i386::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { + if (!reg_info) + return false; + + // Saved registers are ebx, ebp, esi, edi, esp, eip + const char *name = reg_info->name; + if (name[0] == 'e') { + switch (name[1]) { + case 'b': + if (name[2] == 'x' || name[2] == 'p') + return name[3] == '\0'; + break; + case 'd': + if (name[2] == 'i') + return name[3] == '\0'; + break; + case 'i': + if (name[2] == 'p') + return name[3] == '\0'; + break; + case 's': + if (name[2] == 'i' || name[2] == 'p') + return name[3] == '\0'; + break; + } + } + + if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp + return true; + if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp + return true; + if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc + return true; + + return false; +} + +void ABISysV_i386::Initialize() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), "System V ABI for i386 targets", CreateInstance); +} + +void ABISysV_i386::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +// PluginInterface protocol + +lldb_private::ConstString ABISysV_i386::GetPluginNameStatic() { + static ConstString g_name("sysv-i386"); + return g_name; +} + +lldb_private::ConstString ABISysV_i386::GetPluginName() { + return GetPluginNameStatic(); +} diff --git a/gnu/llvm/lldb/source/Plugins/ABI/X86/ABISysV_i386.h b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABISysV_i386.h new file mode 100644 index 00000000000..1ebb107d36d --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABISysV_i386.h @@ -0,0 +1,103 @@ +//===------------------- ABISysV_i386.h -------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_X86_ABISYSV_I386_H +#define LLDB_SOURCE_PLUGINS_ABI_X86_ABISYSV_I386_H + +#include "Plugins/ABI/X86/ABIX86.h" +#include "lldb/lldb-private.h" + +class ABISysV_i386 : public ABIX86 { +public: + ~ABISysV_i386() override = default; + + size_t GetRedZoneSize() const override { + return 0; // There is no red zone for i386 Architecture + } + + bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t functionAddress, + lldb::addr_t returnAddress, + llvm::ArrayRef args) const override; + + bool GetArgumentValues(lldb_private::Thread &thread, + lldb_private::ValueList &values) const override; + + lldb_private::Status + SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value) override; + + lldb::ValueObjectSP + GetReturnValueObjectImpl(lldb_private::Thread &thread, + lldb_private::CompilerType &type) const override; + + bool + CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override { + return !RegisterIsCalleeSaved(reg_info); + } + + // The SysV i386 ABI requires that stack frames be 16 byte aligned. + // When there is a trap handler on the stack, e.g. _sigtramp in userland + // code, we've seen that the stack pointer is often not aligned properly + // before the handler is invoked. This means that lldb will stop the unwind + // early -- before the function which caused the trap. + // + // To work around this, we relax that alignment to be just word-size + // (4-bytes). + // Allowing the trap handlers for user space would be easy (_sigtramp) but + // in other environments there can be a large number of different functions + // involved in async traps. + + // ToDo: When __m256 arguments are passed then stack frames should be + // 32 byte aligned. Decide what to do for 32 byte alignment checking + bool CallFrameAddressIsValid(lldb::addr_t cfa) override { + // Make sure the stack call frame addresses are 4 byte aligned + if (cfa & (4ull - 1ull)) + return false; // Not 4 byte aligned + if (cfa == 0) + return false; // Zero is not a valid stack address + return true; + } + + bool CodeAddressIsValid(lldb::addr_t pc) override { + // Check whether the address is a valid 32 bit address + return (pc <= UINT32_MAX); + } + + // Static Functions + + static void Initialize(); + + static void Terminate(); + + static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); + + // PluginInterface protocol + + static lldb_private::ConstString GetPluginNameStatic(); + + lldb_private::ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override { return 1; } + +protected: + lldb::ValueObjectSP + GetReturnValueObjectSimple(lldb_private::Thread &thread, + lldb_private::CompilerType &ast_type) const; + + bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); + +private: + using ABIX86::ABIX86; // Call CreateInstance instead. +}; + +#endif // LLDB_SOURCE_PLUGINS_ABI_X86_ABISYSV_I386_H diff --git a/gnu/llvm/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp new file mode 100644 index 00000000000..7729e58f858 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp @@ -0,0 +1,964 @@ +//===-- ABISysV_x86_64.cpp ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABISysV_x86_64.h" + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/Triple.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Core/ValueObjectMemory.h" +#include "lldb/Core/ValueObjectRegister.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Status.h" + +#include + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(ABISysV_x86_64) + +enum dwarf_regnums { + dwarf_rax = 0, + dwarf_rdx, + dwarf_rcx, + dwarf_rbx, + dwarf_rsi, + dwarf_rdi, + dwarf_rbp, + dwarf_rsp, + dwarf_r8, + dwarf_r9, + dwarf_r10, + dwarf_r11, + dwarf_r12, + dwarf_r13, + dwarf_r14, + dwarf_r15, + dwarf_rip, +}; + +bool ABISysV_x86_64::GetPointerReturnRegister(const char *&name) { + name = "rax"; + return true; +} + +size_t ABISysV_x86_64::GetRedZoneSize() const { return 128; } + +// Static Functions + +ABISP +ABISysV_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { + const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch(); + const llvm::Triple::OSType os_type = arch.GetTriple().getOS(); + const llvm::Triple::EnvironmentType os_env = + arch.GetTriple().getEnvironment(); + if (arch_type == llvm::Triple::x86_64) { + switch(os_type) { + case llvm::Triple::OSType::IOS: + case llvm::Triple::OSType::TvOS: + case llvm::Triple::OSType::WatchOS: + switch (os_env) { + case llvm::Triple::EnvironmentType::MacABI: + case llvm::Triple::EnvironmentType::Simulator: + case llvm::Triple::EnvironmentType::UnknownEnvironment: + // UnknownEnvironment is needed for older compilers that don't + // support the simulator environment. + return ABISP(new ABISysV_x86_64(std::move(process_sp), + MakeMCRegisterInfo(arch))); + default: + return ABISP(); + } + case llvm::Triple::OSType::Darwin: + case llvm::Triple::OSType::FreeBSD: + case llvm::Triple::OSType::Linux: + case llvm::Triple::OSType::MacOSX: + case llvm::Triple::OSType::NetBSD: + case llvm::Triple::OSType::Solaris: + case llvm::Triple::OSType::UnknownOS: + return ABISP( + new ABISysV_x86_64(std::move(process_sp), MakeMCRegisterInfo(arch))); + default: + return ABISP(); + } + } + return ABISP(); +} + +bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp, + addr_t func_addr, addr_t return_addr, + llvm::ArrayRef args) const { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (log) { + StreamString s; + s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64 + ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 + ", return_addr = 0x%" PRIx64, + thread.GetID(), (uint64_t)sp, (uint64_t)func_addr, + (uint64_t)return_addr); + + for (size_t i = 0; i < args.size(); ++i) + s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast(i + 1), + args[i]); + s.PutCString(")"); + log->PutString(s.GetString()); + } + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return false; + + const RegisterInfo *reg_info = nullptr; + + if (args.size() > 6) // TODO handle more than 6 arguments + return false; + + for (size_t i = 0; i < args.size(); ++i) { + reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_ARG1 + i); + LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", + static_cast(i + 1), args[i], reg_info->name); + if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) + return false; + } + + // First, align the SP + + LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, + (uint64_t)sp, (uint64_t)(sp & ~0xfull)); + + sp &= ~(0xfull); // 16-byte alignment + + sp -= 8; + + Status error; + const RegisterInfo *pc_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + const RegisterInfo *sp_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); + ProcessSP process_sp(thread.GetProcess()); + + RegisterValue reg_value; + LLDB_LOGF(log, + "Pushing the return address onto the stack: 0x%" PRIx64 + ": 0x%" PRIx64, + (uint64_t)sp, (uint64_t)return_addr); + + // Save return address onto the stack + if (!process_sp->WritePointerToMemory(sp, return_addr, error)) + return false; + + // %rsp is set to the actual stack value. + + LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp); + + if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp)) + return false; + + // %rip is set to the address of the called function. + + LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr); + + if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr)) + return false; + + return true; +} + +static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, + bool is_signed, Thread &thread, + uint32_t *argument_register_ids, + unsigned int ¤t_argument_register, + addr_t ¤t_stack_argument) { + if (bit_width > 64) + return false; // Scalar can't hold large integer arguments + + if (current_argument_register < 6) { + scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned( + argument_register_ids[current_argument_register], 0); + current_argument_register++; + if (is_signed) + scalar.SignExtend(bit_width); + } else { + uint32_t byte_size = (bit_width + (8 - 1)) / 8; + Status error; + if (thread.GetProcess()->ReadScalarIntegerFromMemory( + current_stack_argument, byte_size, is_signed, scalar, error)) { + current_stack_argument += byte_size; + return true; + } + return false; + } + return true; +} + +bool ABISysV_x86_64::GetArgumentValues(Thread &thread, + ValueList &values) const { + unsigned int num_values = values.GetSize(); + unsigned int value_index; + + // Extract the register context so we can read arguments from registers + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + + if (!reg_ctx) + return false; + + // Get the pointer to the first stack argument so we have a place to start + // when reading data + + addr_t sp = reg_ctx->GetSP(0); + + if (!sp) + return false; + + addr_t current_stack_argument = sp + 8; // jump over return address + + uint32_t argument_register_ids[6]; + + argument_register_ids[0] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[1] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[2] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[3] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[4] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[5] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6) + ->kinds[eRegisterKindLLDB]; + + unsigned int current_argument_register = 0; + + for (value_index = 0; value_index < num_values; ++value_index) { + Value *value = values.GetValueAtIndex(value_index); + + if (!value) + return false; + + // We currently only support extracting values with Clang QualTypes. Do we + // care about others? + CompilerType compiler_type = value->GetCompilerType(); + 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(), *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; +} + +Status ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value_sp) { + Status error; + if (!new_value_sp) { + error.SetErrorString("Empty value object for return value."); + return error; + } + + CompilerType compiler_type = new_value_sp->GetCompilerType(); + if (!compiler_type) { + error.SetErrorString("Null clang type for return value."); + return error; + } + + Thread *thread = frame_sp->GetThread().get(); + + bool is_signed; + uint32_t count; + bool is_complex; + + RegisterContext *reg_ctx = thread->GetRegisterContext().get(); + + bool set_it_simple = false; + if (compiler_type.IsIntegerOrEnumerationType(is_signed) || + compiler_type.IsPointerType()) { + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0); + + DataExtractor data; + Status data_error; + size_t num_bytes = new_value_sp->GetData(data, data_error); + if (data_error.Fail()) { + error.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", + data_error.AsCString()); + return error; + } + lldb::offset_t offset = 0; + if (num_bytes <= 8) { + uint64_t raw_value = data.GetMaxU64(&offset, num_bytes); + + if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value)) + set_it_simple = true; + } else { + error.SetErrorString("We don't support returning longer than 64 bit " + "integer values at present."); + } + } else if (compiler_type.IsFloatingPointType(count, is_complex)) { + if (is_complex) + error.SetErrorString( + "We don't support returning complex values at present"); + else { + 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; + DataExtractor data; + Status data_error; + size_t num_bytes = new_value_sp->GetData(data, data_error); + if (data_error.Fail()) { + error.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", + data_error.AsCString()); + return error; + } + + unsigned char buffer[16]; + ByteOrder byte_order = data.GetByteOrder(); + + data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order); + xmm0_value.SetBytes(buffer, 16, byte_order); + reg_ctx->WriteRegister(xmm0_info, xmm0_value); + set_it_simple = true; + } else { + // FIXME - don't know how to do 80 bit long doubles yet. + error.SetErrorString( + "We don't support returning float values > 64 bits at present"); + } + } + } + + if (!set_it_simple) { + // Okay we've got a structure or something that doesn't fit in a simple + // register. We should figure out where it really goes, but we don't + // support this yet. + error.SetErrorString("We only support setting simple integer and float " + "return types at present."); + } + + return error; +} + +ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + Value value; + + if (!return_compiler_type) + return return_valobj_sp; + + // value.SetContext (Value::eContextTypeClangType, return_value_type); + value.SetCompilerType(return_compiler_type); + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return return_valobj_sp; + + const uint32_t type_flags = return_compiler_type.GetTypeInfo(); + if (type_flags & eTypeIsScalar) { + value.SetValueType(Value::eValueTypeScalar); + + bool success = false; + if (type_flags & eTypeIsInteger) { + // 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("rax", 0), 0); + const bool is_signed = (type_flags & eTypeIsSigned) != 0; + switch (*byte_size) { + default: + break; + + case sizeof(uint64_t): + if (is_signed) + value.GetScalar() = (int64_t)(raw_value); + else + value.GetScalar() = (uint64_t)(raw_value); + success = true; + break; + + case sizeof(uint32_t): + if (is_signed) + value.GetScalar() = (int32_t)(raw_value & UINT32_MAX); + else + value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX); + success = true; + break; + + case sizeof(uint16_t): + if (is_signed) + value.GetScalar() = (int16_t)(raw_value & UINT16_MAX); + else + value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX); + success = true; + break; + + case sizeof(uint8_t): + if (is_signed) + value.GetScalar() = (int8_t)(raw_value & UINT8_MAX); + else + value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX); + success = true; + break; + } + } else if (type_flags & eTypeIsFloat) { + if (type_flags & eTypeIsComplex) { + // Don't handle complex yet. + } else { + 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; + if (reg_ctx->ReadRegister(xmm0_info, xmm0_value)) { + DataExtractor data; + if (xmm0_value.GetData(data)) { + lldb::offset_t offset = 0; + if (*byte_size == sizeof(float)) { + value.GetScalar() = (float)data.GetFloat(&offset); + success = true; + } else if (*byte_size == sizeof(double)) { + value.GetScalar() = (double)data.GetDouble(&offset); + success = true; + } else if (*byte_size == sizeof(long double)) { + // Don't handle long double since that can be encoded as 80 bit + // floats... + } + } + } + } + } + } + + if (success) + return_valobj_sp = ValueObjectConstResult::Create( + thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); + } else if (type_flags & eTypeIsPointer) { + unsigned rax_id = + reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB]; + value.GetScalar() = + (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, + 0); + value.SetValueType(Value::eValueTypeScalar); + return_valobj_sp = ValueObjectConstResult::Create( + thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); + } else if (type_flags & eTypeIsVector) { + 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) { + ProcessSP process_sp(thread.GetProcess()); + if (process_sp) { + std::unique_ptr heap_data_up( + new DataBufferHeap(*byte_size, 0)); + const ByteOrder byte_order = process_sp->GetByteOrder(); + RegisterValue reg_value; + if (reg_ctx->ReadRegister(altivec_reg, reg_value)) { + Status error; + if (reg_value.GetAsMemoryData( + altivec_reg, heap_data_up->GetBytes(), + heap_data_up->GetByteSize(), byte_order, error)) { + DataExtractor data(DataBufferSP(heap_data_up.release()), + byte_order, + process_sp->GetTarget() + .GetArchitecture() + .GetAddressByteSize()); + return_valobj_sp = ValueObjectConstResult::Create( + &thread, return_compiler_type, ConstString(""), data); + } + } + } + } 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_up( + new DataBufferHeap(*byte_size, 0)); + const ByteOrder byte_order = process_sp->GetByteOrder(); + RegisterValue reg_value; + RegisterValue reg_value2; + if (reg_ctx->ReadRegister(altivec_reg, reg_value) && + reg_ctx->ReadRegister(altivec_reg2, reg_value2)) { + + Status error; + if (reg_value.GetAsMemoryData( + altivec_reg, heap_data_up->GetBytes(), + altivec_reg->byte_size, byte_order, error) && + reg_value2.GetAsMemoryData( + altivec_reg2, + heap_data_up->GetBytes() + altivec_reg->byte_size, + heap_data_up->GetByteSize() - altivec_reg->byte_size, + byte_order, error)) { + DataExtractor data(DataBufferSP(heap_data_up.release()), + byte_order, + process_sp->GetTarget() + .GetArchitecture() + .GetAddressByteSize()); + return_valobj_sp = ValueObjectConstResult::Create( + &thread, return_compiler_type, ConstString(""), data); + } + } + } + } + } + } + } + } + + return return_valobj_sp; +} + +// The compiler will flatten the nested aggregate type into single +// layer and push the value to stack +// This helper function will flatten an aggregate type +// and return true if it can be returned in register(s) by value +// return false if the aggregate is in memory +static bool FlattenAggregateType( + Thread &thread, ExecutionContext &exe_ctx, + CompilerType &return_compiler_type, + uint32_t data_byte_offset, + std::vector &aggregate_field_offsets, + std::vector &aggregate_compiler_types) { + + const uint32_t num_children = return_compiler_type.GetNumFields(); + for (uint32_t idx = 0; idx < num_children; ++idx) { + std::string name; + bool is_signed; + uint32_t count; + bool is_complex; + + uint64_t field_bit_offset = 0; + CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex( + idx, name, &field_bit_offset, nullptr, nullptr); + llvm::Optional field_bit_width = + field_compiler_type.GetBitSize(&thread); + + // if we don't know the size of the field (e.g. invalid type), exit + if (!field_bit_width || *field_bit_width == 0) { + return false; + } + + uint32_t field_byte_offset = field_bit_offset / 8 + data_byte_offset; + + const uint32_t field_type_flags = field_compiler_type.GetTypeInfo(); + if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) || + field_compiler_type.IsPointerType() || + field_compiler_type.IsFloatingPointType(count, is_complex)) { + aggregate_field_offsets.push_back(field_byte_offset); + aggregate_compiler_types.push_back(field_compiler_type); + } else if (field_type_flags & eTypeHasChildren) { + if (!FlattenAggregateType(thread, exe_ctx, field_compiler_type, + field_byte_offset, aggregate_field_offsets, + aggregate_compiler_types)) { + return false; + } + } + } + return true; +} + +ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + + if (!return_compiler_type) + return return_valobj_sp; + + ExecutionContext exe_ctx(thread.shared_from_this()); + return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type); + if (return_valobj_sp) + return return_valobj_sp; + + RegisterContextSP reg_ctx_sp = thread.GetRegisterContext(); + if (!reg_ctx_sp) + return return_valobj_sp; + + 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; + std::vector aggregate_field_offsets; + std::vector aggregate_compiler_types; + if (return_compiler_type.GetTypeSystem()->CanPassInRegisters( + return_compiler_type) && + *bit_width <= 128 && + FlattenAggregateType(thread, exe_ctx, return_compiler_type, + 0, aggregate_field_offsets, + aggregate_compiler_types)) { + ByteOrder byte_order = target->GetArchitecture().GetByteOrder(); + DataBufferSP data_sp(new DataBufferHeap(16, 0)); + DataExtractor return_ext(data_sp, byte_order, + target->GetArchitecture().GetAddressByteSize()); + + const RegisterInfo *rax_info = + reg_ctx_sp->GetRegisterInfoByName("rax", 0); + const RegisterInfo *rdx_info = + reg_ctx_sp->GetRegisterInfoByName("rdx", 0); + const RegisterInfo *xmm0_info = + reg_ctx_sp->GetRegisterInfoByName("xmm0", 0); + const RegisterInfo *xmm1_info = + reg_ctx_sp->GetRegisterInfoByName("xmm1", 0); + + RegisterValue rax_value, rdx_value, xmm0_value, xmm1_value; + reg_ctx_sp->ReadRegister(rax_info, rax_value); + reg_ctx_sp->ReadRegister(rdx_info, rdx_value); + reg_ctx_sp->ReadRegister(xmm0_info, xmm0_value); + reg_ctx_sp->ReadRegister(xmm1_info, xmm1_value); + + DataExtractor rax_data, rdx_data, xmm0_data, xmm1_data; + + rax_value.GetData(rax_data); + rdx_value.GetData(rdx_data); + xmm0_value.GetData(xmm0_data); + xmm1_value.GetData(xmm1_data); + + uint32_t fp_bytes = + 0; // Tracks how much of the xmm registers we've consumed so far + uint32_t integer_bytes = + 0; // Tracks how much of the rax/rds registers we've consumed so far + + // in case of the returned type is a subclass of non-abstract-base class + // it will have a padding to skip the base content + if (aggregate_field_offsets.size()) { + fp_bytes = aggregate_field_offsets[0]; + integer_bytes = aggregate_field_offsets[0]; + } + + const uint32_t num_children = aggregate_compiler_types.size(); + + // Since we are in the small struct regime, assume we are not in memory. + is_memory = false; + for (uint32_t idx = 0; idx < num_children; idx++) { + bool is_signed; + uint32_t count; + bool is_complex; + + CompilerType field_compiler_type = aggregate_compiler_types[idx]; + uint32_t field_byte_width = (uint32_t) (*field_compiler_type.GetByteSize(&thread)); + uint32_t field_byte_offset = aggregate_field_offsets[idx]; + + uint32_t field_bit_width = field_byte_width * 8; + + DataExtractor *copy_from_extractor = nullptr; + uint32_t copy_from_offset = 0; + + if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) || + field_compiler_type.IsPointerType()) { + if (integer_bytes < 8) { + if (integer_bytes + field_byte_width <= 8) { + // This is in RAX, copy from register to our result structure: + copy_from_extractor = &rax_data; + copy_from_offset = integer_bytes; + integer_bytes += field_byte_width; + } else { + // The next field wouldn't fit in the remaining space, so we + // pushed it to rdx. + copy_from_extractor = &rdx_data; + copy_from_offset = 0; + integer_bytes = 8 + field_byte_width; + } + } else if (integer_bytes + field_byte_width <= 16) { + copy_from_extractor = &rdx_data; + copy_from_offset = integer_bytes - 8; + integer_bytes += field_byte_width; + } else { + // The last field didn't fit. I can't see how that would happen + // w/o the overall size being greater than 16 bytes. For now, + // return a nullptr return value object. + return return_valobj_sp; + } + } else if (field_compiler_type.IsFloatingPointType(count, is_complex)) { + // Structs with long doubles are always passed in memory. + if (field_bit_width == 128) { + is_memory = true; + break; + } else if (field_bit_width == 64) { + // These have to be in a single xmm register. + if (fp_bytes == 0) + copy_from_extractor = &xmm0_data; + else + copy_from_extractor = &xmm1_data; + + copy_from_offset = 0; + fp_bytes += field_byte_width; + } 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 + // will be stuffed into the appropriate GPR with them. + bool in_gpr; + if (field_byte_offset % 8 == 0) { + // We are at the beginning of one of the eightbytes, so check the + // next element (if any) + if (idx == num_children - 1) { + in_gpr = false; + } else { + CompilerType next_field_compiler_type = + aggregate_compiler_types[idx + 1]; + if (next_field_compiler_type.IsIntegerOrEnumerationType( + is_signed)) { + in_gpr = true; + } else { + copy_from_offset = 0; + in_gpr = false; + } + } + } else if (field_byte_offset % 4 == 0) { + // We are inside of an eightbyte, so see if the field before us + // is floating point: This could happen if somebody put padding + // in the structure. + if (idx == 0) { + in_gpr = false; + } else { + CompilerType prev_field_compiler_type = + aggregate_compiler_types[idx - 1]; + if (prev_field_compiler_type.IsIntegerOrEnumerationType( + is_signed)) { + in_gpr = true; + } else { + copy_from_offset = 4; + in_gpr = false; + } + } + } else { + is_memory = true; + continue; + } + + // Okay, we've figured out whether we are in GPR or XMM, now figure + // out which one. + if (in_gpr) { + if (integer_bytes < 8) { + // This is in RAX, copy from register to our result structure: + copy_from_extractor = &rax_data; + copy_from_offset = integer_bytes; + integer_bytes += field_byte_width; + } else { + copy_from_extractor = &rdx_data; + copy_from_offset = integer_bytes - 8; + integer_bytes += field_byte_width; + } + } else { + if (fp_bytes < 8) + copy_from_extractor = &xmm0_data; + else + copy_from_extractor = &xmm1_data; + + fp_bytes += field_byte_width; + } + } + } + // These two tests are just sanity checks. If I somehow get the type + // calculation wrong above it is better to just return nothing than to + // assert or crash. + if (!copy_from_extractor) + return return_valobj_sp; + if (copy_from_offset + field_byte_width > + copy_from_extractor->GetByteSize()) + return return_valobj_sp; + copy_from_extractor->CopyByteOrderedData( + copy_from_offset, field_byte_width, + data_sp->GetBytes() + field_byte_offset, field_byte_width, + byte_order); + } + if (!is_memory) { + // The result is in our data buffer. Let's make a variable object out + // of it: + return_valobj_sp = ValueObjectConstResult::Create( + &thread, return_compiler_type, ConstString(""), return_ext); + } + } + + // FIXME: This is just taking a guess, rax may very well no longer hold the + // return storage location. + // If we are going to do this right, when we make a new frame we should + // check to see if it uses a memory return, and if we are at the first + // instruction and if so stash away the return location. Then we would + // only return the memory return value if we know it is valid. + + if (is_memory) { + unsigned rax_id = + reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB]; + lldb::addr_t storage_addr = + (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, + 0); + return_valobj_sp = ValueObjectMemory::Create( + &thread, "", Address(storage_addr, nullptr), return_compiler_type); + } + } + + return return_valobj_sp; +} + +// This defines the CFA as rsp+8 +// the saved pc is at CFA-8 (i.e. rsp+0) +// The saved rsp is CFA+0 + +bool ABISysV_x86_64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t sp_reg_num = dwarf_rsp; + uint32_t pc_reg_num = dwarf_rip; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 8); + row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false); + row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("x86_64 at-func-entry default"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + return true; +} + +// This defines the CFA as rbp+16 +// The saved pc is at CFA-8 (i.e. rbp+8) +// The saved rbp is at CFA-16 (i.e. rbp+0) +// The saved rsp is CFA+0 + +bool ABISysV_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t fp_reg_num = dwarf_rbp; + uint32_t sp_reg_num = dwarf_rsp; + uint32_t pc_reg_num = dwarf_rip; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + + const int32_t ptr_size = 8; + row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size); + row->SetOffset(0); + + row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); + row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); + row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); + + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("x86_64 default unwind plan"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); + return true; +} + +bool ABISysV_x86_64::RegisterIsVolatile(const RegisterInfo *reg_info) { + return !RegisterIsCalleeSaved(reg_info); +} + +// See "Register Usage" in the +// "System V Application Binary Interface" +// "AMD64 Architecture Processor Supplement" (or "x86-64(tm) Architecture +// Processor Supplement" in earlier revisions) (this doc is also commonly +// referred to as the x86-64/AMD64 psABI) Edited by Michael Matz, Jan Hubicka, +// Andreas Jaeger, and Mark Mitchell current version is 0.99.6 released +// 2012-07-02 at http://refspecs.linuxfoundation.org/elf/x86-64-abi-0.99.pdf +// It's being revised & updated at https://github.com/hjl-tools/x86-psABI/ + +bool ABISysV_x86_64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { + if (!reg_info) + return false; + assert(reg_info->name != nullptr && "unnamed register?"); + std::string Name = std::string(reg_info->name); + bool IsCalleeSaved = + llvm::StringSwitch(Name) + .Cases("r12", "r13", "r14", "r15", "rbp", "ebp", "rbx", "ebx", true) + .Cases("rip", "eip", "rsp", "esp", "sp", "fp", "pc", true) + .Default(false); + return IsCalleeSaved; +} + +uint32_t ABISysV_x86_64::GetGenericNum(llvm::StringRef name) { + return llvm::StringSwitch(name) + .Case("rip", LLDB_REGNUM_GENERIC_PC) + .Case("rsp", LLDB_REGNUM_GENERIC_SP) + .Case("rbp", LLDB_REGNUM_GENERIC_FP) + .Case("rflags", LLDB_REGNUM_GENERIC_FLAGS) + .Case("rdi", LLDB_REGNUM_GENERIC_ARG1) + .Case("rsi", LLDB_REGNUM_GENERIC_ARG2) + .Case("rdx", LLDB_REGNUM_GENERIC_ARG3) + .Case("rcx", LLDB_REGNUM_GENERIC_ARG4) + .Case("r8", LLDB_REGNUM_GENERIC_ARG5) + .Case("r9", LLDB_REGNUM_GENERIC_ARG6) + .Default(LLDB_INVALID_REGNUM); +} + +void ABISysV_x86_64::Initialize() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), "System V ABI for x86_64 targets", CreateInstance); +} + +void ABISysV_x86_64::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString ABISysV_x86_64::GetPluginNameStatic() { + static ConstString g_name("sysv-x86_64"); + return g_name; +} + +// PluginInterface protocol + +lldb_private::ConstString ABISysV_x86_64::GetPluginName() { + return GetPluginNameStatic(); +} + +uint32_t ABISysV_x86_64::GetPluginVersion() { return 1; } diff --git a/gnu/llvm/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.h b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.h new file mode 100644 index 00000000000..6dce4ce0f01 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.h @@ -0,0 +1,101 @@ +//===-- ABISysV_x86_64.h ----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_X86_ABISYSV_X86_64_H +#define LLDB_SOURCE_PLUGINS_ABI_X86_ABISYSV_X86_64_H + +#include "Plugins/ABI/X86/ABIX86_64.h" + +class ABISysV_x86_64 : public ABIX86_64 { +public: + ~ABISysV_x86_64() override = default; + + size_t GetRedZoneSize() const override; + + bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t functionAddress, + lldb::addr_t returnAddress, + llvm::ArrayRef args) const override; + + bool GetArgumentValues(lldb_private::Thread &thread, + lldb_private::ValueList &values) const override; + + lldb_private::Status + SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value) override; + + lldb::ValueObjectSP + GetReturnValueObjectImpl(lldb_private::Thread &thread, + lldb_private::CompilerType &type) const override; + + bool + CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override; + + // The SysV x86_64 ABI requires that stack frames be 16 byte aligned. + // When there is a trap handler on the stack, e.g. _sigtramp in userland + // code, we've seen that the stack pointer is often not aligned properly + // before the handler is invoked. This means that lldb will stop the unwind + // early -- before the function which caused the trap. + // + // To work around this, we relax that alignment to be just word-size + // (8-bytes). + // Allowing the trap handlers for user space would be easy (_sigtramp) but + // in other environments there can be a large number of different functions + // involved in async traps. + bool CallFrameAddressIsValid(lldb::addr_t cfa) override { + // Make sure the stack call frame addresses are 8 byte aligned + if (cfa & (8ull - 1ull)) + return false; // Not 8 byte aligned + if (cfa == 0) + return false; // Zero is not a valid stack address + return true; + } + + bool CodeAddressIsValid(lldb::addr_t pc) override { + // We have a 64 bit address space, so anything is valid as opcodes + // aren't fixed width... + return true; + } + + bool GetPointerReturnRegister(const char *&name) override; + + // Static Functions + + static void Initialize(); + + static void Terminate(); + + static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); + + static lldb_private::ConstString GetPluginNameStatic(); + + // PluginInterface protocol + + lldb_private::ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + +protected: + void CreateRegisterMapIfNeeded(); + + lldb::ValueObjectSP + GetReturnValueObjectSimple(lldb_private::Thread &thread, + lldb_private::CompilerType &ast_type) const; + + bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); + uint32_t GetGenericNum(llvm::StringRef reg) override; + +private: + using ABIX86_64::ABIX86_64; // Call CreateInstance instead. +}; + +#endif // LLDB_SOURCE_PLUGINS_ABI_X86_ABISYSV_X86_64_H diff --git a/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp new file mode 100644 index 00000000000..63b670b0727 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp @@ -0,0 +1,837 @@ +//===-- ABIWindows_x86_64.cpp ---------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABIWindows_x86_64.h" + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/Triple.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Core/ValueObjectMemory.h" +#include "lldb/Core/ValueObjectRegister.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Status.h" + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(ABIWindows_x86_64) + +enum dwarf_regnums { + dwarf_rax = 0, + dwarf_rdx, + dwarf_rcx, + dwarf_rbx, + dwarf_rsi, + dwarf_rdi, + dwarf_rbp, + dwarf_rsp, + dwarf_r8, + dwarf_r9, + dwarf_r10, + dwarf_r11, + dwarf_r12, + dwarf_r13, + dwarf_r14, + dwarf_r15, + dwarf_rip, + dwarf_xmm0, + dwarf_xmm1, + dwarf_xmm2, + dwarf_xmm3, + dwarf_xmm4, + dwarf_xmm5, + dwarf_xmm6, + dwarf_xmm7, + dwarf_xmm8, + dwarf_xmm9, + dwarf_xmm10, + dwarf_xmm11, + dwarf_xmm12, + dwarf_xmm13, + dwarf_xmm14, + dwarf_xmm15, + dwarf_stmm0, + dwarf_stmm1, + dwarf_stmm2, + dwarf_stmm3, + dwarf_stmm4, + dwarf_stmm5, + dwarf_stmm6, + dwarf_stmm7, + dwarf_ymm0, + dwarf_ymm1, + dwarf_ymm2, + dwarf_ymm3, + dwarf_ymm4, + dwarf_ymm5, + dwarf_ymm6, + dwarf_ymm7, + dwarf_ymm8, + dwarf_ymm9, + dwarf_ymm10, + dwarf_ymm11, + dwarf_ymm12, + dwarf_ymm13, + dwarf_ymm14, + dwarf_ymm15, + dwarf_bnd0 = 126, + dwarf_bnd1, + dwarf_bnd2, + dwarf_bnd3 +}; + +bool ABIWindows_x86_64::GetPointerReturnRegister(const char *&name) { + name = "rax"; + return true; +} + +size_t ABIWindows_x86_64::GetRedZoneSize() const { return 0; } + +//------------------------------------------------------------------ +// Static Functions +//------------------------------------------------------------------ + +ABISP +ABIWindows_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { + if (arch.GetTriple().getArch() == llvm::Triple::x86_64 && + arch.GetTriple().isOSWindows()) { + return ABISP( + new ABIWindows_x86_64(std::move(process_sp), MakeMCRegisterInfo(arch))); + } + return ABISP(); +} + +bool ABIWindows_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp, + addr_t func_addr, addr_t return_addr, + llvm::ArrayRef args) const { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (log) { + StreamString s; + s.Printf("ABIWindows_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64 + ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 + ", return_addr = 0x%" PRIx64, + thread.GetID(), (uint64_t)sp, (uint64_t)func_addr, + (uint64_t)return_addr); + + for (size_t i = 0; i < args.size(); ++i) + s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast(i + 1), + args[i]); + s.PutCString(")"); + log->PutString(s.GetString()); + } + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return false; + + const RegisterInfo *reg_info = nullptr; + + if (args.size() > 4) // Windows x64 only put first 4 arguments into registers + return false; + + for (size_t i = 0; i < args.size(); ++i) { + reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_ARG1 + i); + LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", + static_cast(i + 1), args[i], reg_info->name); + if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) + return false; + } + + // First, align the SP + + LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, + (uint64_t)sp, (uint64_t)(sp & ~0xfull)); + + sp &= ~(0xfull); // 16-byte alignment + + sp -= 8; // return address + + Status error; + const RegisterInfo *pc_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + const RegisterInfo *sp_reg_info = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); + ProcessSP process_sp(thread.GetProcess()); + + RegisterValue reg_value; + LLDB_LOGF(log, + "Pushing the return address onto the stack: 0x%" PRIx64 + ": 0x%" PRIx64, + (uint64_t)sp, (uint64_t)return_addr); + + // Save return address onto the stack + if (!process_sp->WritePointerToMemory(sp, return_addr, error)) + return false; + + // %rsp is set to the actual stack value. + + LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp); + + if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp)) + return false; + + // %rip is set to the address of the called function. + + LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr); + + if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr)) + return false; + + return true; +} + +static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, + bool is_signed, Thread &thread, + uint32_t *argument_register_ids, + unsigned int ¤t_argument_register, + addr_t ¤t_stack_argument) { + if (bit_width > 64) + return false; // Scalar can't hold large integer arguments + + if (current_argument_register < 4) { // Windows pass first 4 arguments to register + scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned( + argument_register_ids[current_argument_register], 0); + current_argument_register++; + if (is_signed) + scalar.SignExtend(bit_width); + return true; + } + uint32_t byte_size = (bit_width + (CHAR_BIT - 1)) / CHAR_BIT; + Status error; + if (thread.GetProcess()->ReadScalarIntegerFromMemory( + current_stack_argument, byte_size, is_signed, scalar, error)) { + current_stack_argument += byte_size; + return true; + } + return false; +} + +bool ABIWindows_x86_64::GetArgumentValues(Thread &thread, + ValueList &values) const { + unsigned int num_values = values.GetSize(); + unsigned int value_index; + + // Extract the register context so we can read arguments from registers + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + + if (!reg_ctx) + return false; + + // Get the pointer to the first stack argument so we have a place to start + // when reading data + + addr_t sp = reg_ctx->GetSP(0); + + if (!sp) + return false; + + addr_t current_stack_argument = sp + 8; // jump over return address + + uint32_t argument_register_ids[4]; + + argument_register_ids[0] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[1] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[2] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3) + ->kinds[eRegisterKindLLDB]; + argument_register_ids[3] = + reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4) + ->kinds[eRegisterKindLLDB]; + + unsigned int current_argument_register = 0; + + for (value_index = 0; value_index < num_values; ++value_index) { + Value *value = values.GetValueAtIndex(value_index); + + if (!value) + return false; + + CompilerType compiler_type = value->GetCompilerType(); + 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(), *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; +} + +Status ABIWindows_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value_sp) { + Status error; + if (!new_value_sp) { + error.SetErrorString("Empty value object for return value."); + return error; + } + + CompilerType compiler_type = new_value_sp->GetCompilerType(); + if (!compiler_type) { + error.SetErrorString("Null clang type for return value."); + return error; + } + + Thread *thread = frame_sp->GetThread().get(); + + bool is_signed; + uint32_t count; + bool is_complex; + + RegisterContext *reg_ctx = thread->GetRegisterContext().get(); + + bool set_it_simple = false; + if (compiler_type.IsIntegerOrEnumerationType(is_signed) || + compiler_type.IsPointerType()) { + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0); + + DataExtractor data; + Status data_error; + size_t num_bytes = new_value_sp->GetData(data, data_error); + if (data_error.Fail()) { + error.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", + data_error.AsCString()); + return error; + } + lldb::offset_t offset = 0; + if (num_bytes <= 8) { + uint64_t raw_value = data.GetMaxU64(&offset, num_bytes); + + if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value)) + set_it_simple = true; + } else { + error.SetErrorString("We don't support returning longer than 64 bit " + "integer values at present."); + } + } else if (compiler_type.IsFloatingPointType(count, is_complex)) { + if (is_complex) + error.SetErrorString( + "We don't support returning complex values at present"); + else { + 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; + DataExtractor data; + Status data_error; + size_t num_bytes = new_value_sp->GetData(data, data_error); + if (data_error.Fail()) { + error.SetErrorStringWithFormat( + "Couldn't convert return value to raw data: %s", + data_error.AsCString()); + return error; + } + + unsigned char buffer[16]; + ByteOrder byte_order = data.GetByteOrder(); + + data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order); + xmm0_value.SetBytes(buffer, 16, byte_order); + reg_ctx->WriteRegister(xmm0_info, xmm0_value); + set_it_simple = true; + } else { + // Windows doesn't support 80 bit FP + error.SetErrorString( + "Windows-x86_64 doesn't allow FP larger than 64 bits."); + } + } + } + + if (!set_it_simple) { + // Okay we've got a structure or something that doesn't fit in a simple + // register. + // TODO(wanyi): On Windows, if the return type is a struct: + // 1) smaller that 64 bits and return by value -> RAX + // 2) bigger than 64 bits, the caller will allocate memory for that struct + // and pass the struct pointer in RCX then return the pointer in RAX + error.SetErrorString("We only support setting simple integer and float " + "return types at present."); + } + + return error; +} + +ValueObjectSP ABIWindows_x86_64::GetReturnValueObjectSimple( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + Value value; + + if (!return_compiler_type) + return return_valobj_sp; + + value.SetCompilerType(return_compiler_type); + + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + return return_valobj_sp; + + const uint32_t type_flags = return_compiler_type.GetTypeInfo(); + if (type_flags & eTypeIsScalar) { + value.SetValueType(Value::eValueTypeScalar); + + bool success = false; + if (type_flags & eTypeIsInteger) { + // 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("rax", 0), 0); + const bool is_signed = (type_flags & eTypeIsSigned) != 0; + switch (*byte_size) { + default: + break; + + case sizeof(uint64_t): + if (is_signed) + value.GetScalar() = (int64_t)(raw_value); + else + value.GetScalar() = (uint64_t)(raw_value); + success = true; + break; + + case sizeof(uint32_t): + if (is_signed) + value.GetScalar() = (int32_t)(raw_value & UINT32_MAX); + else + value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX); + success = true; + break; + + case sizeof(uint16_t): + if (is_signed) + value.GetScalar() = (int16_t)(raw_value & UINT16_MAX); + else + value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX); + success = true; + break; + + case sizeof(uint8_t): + if (is_signed) + value.GetScalar() = (int8_t)(raw_value & UINT8_MAX); + else + value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX); + success = true; + break; + } + } else if (type_flags & eTypeIsFloat) { + if (type_flags & eTypeIsComplex) { + // Don't handle complex yet. + } else { + 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; + if (reg_ctx->ReadRegister(xmm0_info, xmm0_value)) { + DataExtractor data; + if (xmm0_value.GetData(data)) { + lldb::offset_t offset = 0; + if (*byte_size == sizeof(float)) { + value.GetScalar() = (float)data.GetFloat(&offset); + success = true; + } else if (*byte_size == sizeof(double)) { + // double and long double are the same on windows + value.GetScalar() = (double)data.GetDouble(&offset); + success = true; + } + } + } + } + } + } + + if (success) + return_valobj_sp = ValueObjectConstResult::Create( + thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); + } else if ((type_flags & eTypeIsPointer) || + (type_flags & eTypeInstanceIsPointer)) { + unsigned rax_id = + reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB]; + value.GetScalar() = + (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, + 0); + value.SetValueType(Value::eValueTypeScalar); + return_valobj_sp = ValueObjectConstResult::Create( + thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); + } else if (type_flags & eTypeIsVector) { + llvm::Optional byte_size = + return_compiler_type.GetByteSize(nullptr); + if (byte_size && *byte_size > 0) { + const RegisterInfo *xmm_reg = + reg_ctx->GetRegisterInfoByName("xmm0", 0); + if (xmm_reg == nullptr) + xmm_reg = reg_ctx->GetRegisterInfoByName("mm0", 0); + + if (xmm_reg) { + if (*byte_size <= xmm_reg->byte_size) { + ProcessSP process_sp(thread.GetProcess()); + if (process_sp) { + std::unique_ptr heap_data_up( + new DataBufferHeap(*byte_size, 0)); + const ByteOrder byte_order = process_sp->GetByteOrder(); + RegisterValue reg_value; + if (reg_ctx->ReadRegister(xmm_reg, reg_value)) { + Status error; + if (reg_value.GetAsMemoryData( + xmm_reg, heap_data_up->GetBytes(), + heap_data_up->GetByteSize(), byte_order, error)) { + DataExtractor data(DataBufferSP(heap_data_up.release()), + byte_order, + process_sp->GetTarget() + .GetArchitecture() + .GetAddressByteSize()); + return_valobj_sp = ValueObjectConstResult::Create( + &thread, return_compiler_type, ConstString(""), data); + } + } + } + } + } + } + } + + return return_valobj_sp; +} + +// The compiler will flatten the nested aggregate type into single +// layer and push the value to stack +// This helper function will flatten an aggregate type +// and return true if it can be returned in register(s) by value +// return false if the aggregate is in memory +static bool FlattenAggregateType( + Thread &thread, ExecutionContext &exe_ctx, + CompilerType &return_compiler_type, + uint32_t data_byte_offset, + std::vector &aggregate_field_offsets, + std::vector &aggregate_compiler_types) { + + const uint32_t num_children = return_compiler_type.GetNumFields(); + for (uint32_t idx = 0; idx < num_children; ++idx) { + std::string name; + bool is_signed; + uint32_t count; + bool is_complex; + + uint64_t field_bit_offset = 0; + CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex( + idx, name, &field_bit_offset, nullptr, nullptr); + llvm::Optional field_bit_width = + field_compiler_type.GetBitSize(&thread); + + // if we don't know the size of the field (e.g. invalid type), exit + if (!field_bit_width || *field_bit_width == 0) { + return false; + } + // If there are any unaligned fields, this is stored in memory. + if (field_bit_offset % *field_bit_width != 0) { + return false; + } + + // add overall offset + uint32_t field_byte_offset = field_bit_offset / 8 + data_byte_offset; + + const uint32_t field_type_flags = field_compiler_type.GetTypeInfo(); + if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) || + field_compiler_type.IsPointerType() || + field_compiler_type.IsFloatingPointType(count, is_complex)) { + aggregate_field_offsets.push_back(field_byte_offset); + aggregate_compiler_types.push_back(field_compiler_type); + } else if (field_type_flags & eTypeHasChildren) { + if (!FlattenAggregateType(thread, exe_ctx, field_compiler_type, + field_byte_offset, aggregate_field_offsets, + aggregate_compiler_types)) { + return false; + } + } + } + return true; +} + +ValueObjectSP ABIWindows_x86_64::GetReturnValueObjectImpl( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + + if (!return_compiler_type) { + return return_valobj_sp; + } + + // try extract value as if it's a simple type + return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type); + if (return_valobj_sp) { + return return_valobj_sp; + } + + RegisterContextSP reg_ctx_sp = thread.GetRegisterContext(); + if (!reg_ctx_sp) { + return return_valobj_sp; + } + + llvm::Optional bit_width = return_compiler_type.GetBitSize(&thread); + if (!bit_width) { + return return_valobj_sp; + } + + // if it's not simple or aggregate type, then we don't know how to handle it + if (!return_compiler_type.IsAggregateType()) { + return return_valobj_sp; + } + + ExecutionContext exe_ctx(thread.shared_from_this()); + Target *target = exe_ctx.GetTargetPtr(); + uint32_t max_register_value_bit_width = 64; + + // The scenario here is to have a struct/class which is POD + // if the return struct/class size is larger than 64 bits, + // the caller will allocate memory for it and pass the return addr in RCX + // then return the address in RAX + + // if the struct is returned by value in register (RAX) + // its size has to be: 1, 2, 4, 8, 16, 32, or 64 bits (aligned) + // for floating point, the return value will be copied over to RAX + bool is_memory = *bit_width > max_register_value_bit_width || + *bit_width & (*bit_width - 1); + std::vector aggregate_field_offsets; + std::vector aggregate_compiler_types; + if (!is_memory && + FlattenAggregateType(thread, exe_ctx, return_compiler_type, + 0, aggregate_field_offsets, + aggregate_compiler_types)) { + ByteOrder byte_order = target->GetArchitecture().GetByteOrder(); + DataBufferSP data_sp( + new DataBufferHeap(max_register_value_bit_width / 8, 0)); + DataExtractor return_ext(data_sp, byte_order, + target->GetArchitecture().GetAddressByteSize()); + + // The only register used to return struct/class by value + const RegisterInfo *rax_info = + reg_ctx_sp->GetRegisterInfoByName("rax", 0); + RegisterValue rax_value; + reg_ctx_sp->ReadRegister(rax_info, rax_value); + DataExtractor rax_data; + rax_value.GetData(rax_data); + + uint32_t used_bytes = + 0; // Tracks how much of the rax registers we've consumed so far + + // in case of the returned type is a subclass of non-abstract-base class + // it will have a padding to skip the base content + if (aggregate_field_offsets.size()) + used_bytes = aggregate_field_offsets[0]; + + const uint32_t num_children = aggregate_compiler_types.size(); + for (uint32_t idx = 0; idx < num_children; idx++) { + bool is_signed; + bool is_complex; + uint32_t count; + + CompilerType field_compiler_type = aggregate_compiler_types[idx]; + uint32_t field_byte_width = (uint32_t) (*field_compiler_type.GetByteSize(&thread)); + uint32_t field_byte_offset = aggregate_field_offsets[idx]; + + // this is unlikely w/o the overall size being greater than 8 bytes + // For now, return a nullptr return value object. + if (used_bytes >= 8 || used_bytes + field_byte_width > 8) { + return return_valobj_sp; + } + + DataExtractor *copy_from_extractor = nullptr; + uint32_t copy_from_offset = 0; + if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) || + field_compiler_type.IsPointerType() || + field_compiler_type.IsFloatingPointType(count, is_complex)) { + copy_from_extractor = &rax_data; + copy_from_offset = used_bytes; + used_bytes += field_byte_width; + } + // These two tests are just sanity checks. If I somehow get the type + // calculation wrong above it is better to just return nothing than to + // assert or crash. + if (!copy_from_extractor) { + return return_valobj_sp; + } + if (copy_from_offset + field_byte_width > + copy_from_extractor->GetByteSize()) { + return return_valobj_sp; + } + copy_from_extractor->CopyByteOrderedData(copy_from_offset, + field_byte_width, data_sp->GetBytes() + field_byte_offset, + field_byte_width, byte_order); + } + if (!is_memory) { + // The result is in our data buffer. Let's make a variable object out + // of it: + return_valobj_sp = ValueObjectConstResult::Create( + &thread, return_compiler_type, ConstString(""), return_ext); + } + } + + // The Windows x86_64 ABI specifies that the return address for MEMORY + // objects be placed in rax on exit from the function. + + // FIXME: This is just taking a guess, rax may very well no longer hold the + // return storage location. + // If we are going to do this right, when we make a new frame we should + // check to see if it uses a memory return, and if we are at the first + // instruction and if so stash away the return location. Then we would + // only return the memory return value if we know it is valid. + if (is_memory) { + unsigned rax_id = + reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB]; + lldb::addr_t storage_addr = + (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, + 0); + return_valobj_sp = ValueObjectMemory::Create( + &thread, "", Address(storage_addr, nullptr), return_compiler_type); + } + return return_valobj_sp; +} + +// This defines the CFA as rsp+8 +// the saved pc is at CFA-8 (i.e. rsp+0) +// The saved rsp is CFA+0 + +bool ABIWindows_x86_64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t sp_reg_num = dwarf_rsp; + uint32_t pc_reg_num = dwarf_rip; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 8); + row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false); + row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("x86_64 at-func-entry default"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + return true; +} + +// Windows-x86_64 doesn't use %rbp +// No available Unwind information for Windows-x86_64 (section .pdata) +// Let's use SysV-x86_64 one for now +bool ABIWindows_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t fp_reg_num = dwarf_rbp; + uint32_t sp_reg_num = dwarf_rsp; + uint32_t pc_reg_num = dwarf_rip; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + + const int32_t ptr_size = 8; + row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size); + row->SetOffset(0); + + row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); + row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); + row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); + + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("x86_64 default unwind plan"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + + return true; +} + +bool ABIWindows_x86_64::RegisterIsVolatile(const RegisterInfo *reg_info) { + return !RegisterIsCalleeSaved(reg_info); +} + +bool ABIWindows_x86_64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { + if (!reg_info) + return false; + assert(reg_info->name != nullptr && "unnamed register?"); + std::string Name = std::string(reg_info->name); + bool IsCalleeSaved = + llvm::StringSwitch(Name) + .Cases("rbx", "ebx", "rbp", "ebp", "rdi", "edi", "rsi", "esi", true) + .Cases("rsp", "esp", "r12", "r13", "r14", "r15", "sp", "fp", true) + .Cases("xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", + "xmm13", "xmm14", "xmm15", true) + .Default(false); + return IsCalleeSaved; +} + +uint32_t ABIWindows_x86_64::GetGenericNum(llvm::StringRef reg) { + return llvm::StringSwitch(reg) + .Case("rip", LLDB_REGNUM_GENERIC_PC) + .Case("rsp", LLDB_REGNUM_GENERIC_SP) + .Case("rbp", LLDB_REGNUM_GENERIC_FP) + .Case("rflags", LLDB_REGNUM_GENERIC_FLAGS) + .Case("rcx", LLDB_REGNUM_GENERIC_ARG1) + .Case("rdx", LLDB_REGNUM_GENERIC_ARG2) + .Case("r8", LLDB_REGNUM_GENERIC_ARG3) + .Case("r9", LLDB_REGNUM_GENERIC_ARG4) + .Default(LLDB_INVALID_REGNUM); +} + +void ABIWindows_x86_64::Initialize() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), "Windows ABI for x86_64 targets", CreateInstance); +} + +void ABIWindows_x86_64::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString ABIWindows_x86_64::GetPluginNameStatic() { + static ConstString g_name("windows-x86_64"); + return g_name; +} + +//------------------------------------------------------------------ +// PluginInterface protocol +//------------------------------------------------------------------ + +lldb_private::ConstString ABIWindows_x86_64::GetPluginName() { + return GetPluginNameStatic(); +} + +uint32_t ABIWindows_x86_64::GetPluginVersion() { return 1; } diff --git a/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h new file mode 100644 index 00000000000..89fc6e6ca21 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h @@ -0,0 +1,94 @@ +//===-- ABIWindows_x86_64.h ----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_X86_ABIWINDOWS_X86_64_H +#define LLDB_SOURCE_PLUGINS_ABI_X86_ABIWINDOWS_X86_64_H + +#include "Plugins/ABI/X86/ABIX86_64.h" + +class ABIWindows_x86_64 : public ABIX86_64 { +public: + ~ABIWindows_x86_64() override = default; + + size_t GetRedZoneSize() const override; + + bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t functionAddress, + lldb::addr_t returnAddress, + llvm::ArrayRef args) const override; + + bool GetArgumentValues(lldb_private::Thread &thread, + lldb_private::ValueList &values) const override; + + lldb_private::Status + SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value) override; + + lldb::ValueObjectSP + GetReturnValueObjectImpl(lldb_private::Thread &thread, + lldb_private::CompilerType &type) const override; + + bool + CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override; + + // In Windows_x86_64 ABI, stack will always be maintained 16-byte aligned + bool CallFrameAddressIsValid(lldb::addr_t cfa) override { + if (cfa & (16ull - 1ull)) + return false; // Not 16 byte aligned + if (cfa == 0) + return false; // Zero is not a valid stack address + return true; + } + + bool CodeAddressIsValid(lldb::addr_t pc) override { + // We have a 64 bit address space, so anything is valid as opcodes + // aren't fixed width... + return true; + } + + bool GetPointerReturnRegister(const char *&name) override; + + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + + static void Initialize(); + + static void Terminate(); + + static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); + + static lldb_private::ConstString GetPluginNameStatic(); + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + + lldb_private::ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + +protected: + void CreateRegisterMapIfNeeded(); + + lldb::ValueObjectSP + GetReturnValueObjectSimple(lldb_private::Thread &thread, + lldb_private::CompilerType &ast_type) const; + + bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); + uint32_t GetGenericNum(llvm::StringRef reg) override; + +private: + using ABIX86_64::ABIX86_64; // Call CreateInstance instead. +}; + +#endif // LLDB_SOURCE_PLUGINS_ABI_X86_ABIWINDOWS_X86_64_H diff --git a/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIX86.cpp b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIX86.cpp new file mode 100644 index 00000000000..bf5ab669417 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIX86.cpp @@ -0,0 +1,43 @@ +//===-- X86.h -------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABIX86.h" +#include "ABIMacOSX_i386.h" +#include "ABISysV_i386.h" +#include "ABISysV_x86_64.h" +#include "ABIWindows_x86_64.h" +#include "lldb/Core/PluginManager.h" + +LLDB_PLUGIN_DEFINE(ABIX86) + +void ABIX86::Initialize() { + ABIMacOSX_i386::Initialize(); + ABISysV_i386::Initialize(); + ABISysV_x86_64::Initialize(); + ABIWindows_x86_64::Initialize(); +} + +void ABIX86::Terminate() { + ABIMacOSX_i386::Terminate(); + ABISysV_i386::Terminate(); + ABISysV_x86_64::Terminate(); + ABIWindows_x86_64::Terminate(); +} + +uint32_t ABIX86::GetGenericNum(llvm::StringRef name) { + return llvm::StringSwitch(name) + .Case("eip", LLDB_REGNUM_GENERIC_PC) + .Case("esp", LLDB_REGNUM_GENERIC_SP) + .Case("ebp", LLDB_REGNUM_GENERIC_FP) + .Case("eflags", LLDB_REGNUM_GENERIC_FLAGS) + .Case("edi", LLDB_REGNUM_GENERIC_ARG1) + .Case("esi", LLDB_REGNUM_GENERIC_ARG2) + .Case("edx", LLDB_REGNUM_GENERIC_ARG3) + .Case("ecx", LLDB_REGNUM_GENERIC_ARG4) + .Default(LLDB_INVALID_REGNUM); +} diff --git a/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIX86.h b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIX86.h new file mode 100644 index 00000000000..22521cacf18 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIX86.h @@ -0,0 +1,24 @@ +//===-- X86.h ---------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_X86_ABIX86_H +#define LLDB_SOURCE_PLUGINS_ABI_X86_ABIX86_H + +#include "lldb/Target/ABI.h" + +class ABIX86 : public lldb_private::MCBasedABI { +public: + static void Initialize(); + static void Terminate(); + + uint32_t GetGenericNum(llvm::StringRef name) override; + +private: + using lldb_private::MCBasedABI::MCBasedABI; +}; +#endif diff --git a/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIX86_64.h b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIX86_64.h new file mode 100644 index 00000000000..e65c2d97d89 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/X86/ABIX86_64.h @@ -0,0 +1,26 @@ +//===-- ABIX86_64.h ---------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_X86_ABIX86_64_H +#define LLDB_SOURCE_PLUGINS_ABI_X86_ABIX86_64_H + +#include "lldb/Target/ABI.h" +#include "lldb/lldb-private.h" + +class ABIX86_64 : public lldb_private::MCBasedABI { +protected: + std::string GetMCName(std::string name) override { + MapRegisterName(name, "stmm", "st"); + return name; + } + +private: + using lldb_private::MCBasedABI::MCBasedABI; +}; + +#endif // LLDB_SOURCE_PLUGINS_ABI_X86_ABIX86_64_H diff --git a/gnu/llvm/lldb/source/Plugins/ABI/X86/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/ABI/X86/CMakeLists.txt new file mode 100644 index 00000000000..ec8ed622549 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ABI/X86/CMakeLists.txt @@ -0,0 +1,14 @@ +add_lldb_library(lldbPluginABIX86 PLUGIN + ABIX86.cpp + ABIMacOSX_i386.cpp + ABISysV_i386.cpp + ABISysV_x86_64.cpp + ABIWindows_x86_64.cpp + + LINK_LIBS + lldbCore + lldbSymbol + lldbTarget + LINK_COMPONENTS + Support + ) diff --git a/gnu/llvm/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp b/gnu/llvm/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp index 5b86df6c527..58c7cbb4530 100644 --- a/gnu/llvm/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp +++ b/gnu/llvm/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp @@ -1,4 +1,4 @@ -//===-- ArchitectureArm.cpp -------------------------------------*- C++ -*-===// +//===-- ArchitectureArm.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -17,6 +17,8 @@ using namespace lldb_private; using namespace lldb; +LLDB_PLUGIN_DEFINE(ArchitectureArm) + ConstString ArchitectureArm::GetPluginNameStatic() { return ConstString("arm"); } diff --git a/gnu/llvm/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.h b/gnu/llvm/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.h index 03e79ce524a..36b79c7c01a 100644 --- a/gnu/llvm/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.h +++ b/gnu/llvm/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGIN_ARCHITECTURE_ARM_H -#define LLDB_PLUGIN_ARCHITECTURE_ARM_H +#ifndef LLDB_SOURCE_PLUGINS_ARCHITECTURE_ARM_ARCHITECTUREARM_H +#define LLDB_SOURCE_PLUGINS_ARCHITECTURE_ARM_ARCHITECTUREARM_H #include "lldb/Core/Architecture.h" @@ -37,4 +37,4 @@ private: } // namespace lldb_private -#endif // LLDB_PLUGIN_ARCHITECTURE_ARM_H +#endif // LLDB_SOURCE_PLUGINS_ARCHITECTURE_ARM_ARCHITECTUREARM_H diff --git a/gnu/llvm/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp b/gnu/llvm/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp index 5f2f6eeb826..22508969cee 100644 --- a/gnu/llvm/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp +++ b/gnu/llvm/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp @@ -1,4 +1,4 @@ -//===-- ArchitectureMips.cpp -------------------------------------*- C++ -*-===// +//===-- ArchitectureMips.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -21,6 +21,8 @@ using namespace lldb_private; using namespace lldb; +LLDB_PLUGIN_DEFINE(ArchitectureMips) + ConstString ArchitectureMips::GetPluginNameStatic() { return ConstString("mips"); } @@ -118,9 +120,7 @@ lldb::addr_t ArchitectureMips::GetBreakableLoadAddress(lldb::addr_t addr, if (current_offset == 0) return addr; - ExecutionContext ctx; - target.CalculateExecutionContext(ctx); - auto insn = GetInstructionAtAddress(ctx, current_offset, addr); + auto insn = GetInstructionAtAddress(target, current_offset, addr); if (nullptr == insn || !insn->HasDelaySlot()) return addr; @@ -136,8 +136,7 @@ lldb::addr_t ArchitectureMips::GetBreakableLoadAddress(lldb::addr_t addr, } Instruction *ArchitectureMips::GetInstructionAtAddress( - const ExecutionContext &exe_ctx, const Address &resolved_addr, - addr_t symbol_offset) const { + Target &target, const Address &resolved_addr, addr_t symbol_offset) const { auto loop_count = symbol_offset / 2; @@ -169,10 +168,11 @@ Instruction *ArchitectureMips::GetInstructionAtAddress( 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); + disasm_sp->ParseInstructions(target, addr, + {Disassembler::Limit::Bytes, i * 2}, nullptr, + prefer_file_cache); uint32_t num_insns = disasm_sp->GetInstructionList().GetSize(); if (num_insns) { diff --git a/gnu/llvm/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.h b/gnu/llvm/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.h index a15991ff9eb..71ee60184b6 100644 --- a/gnu/llvm/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.h +++ b/gnu/llvm/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGIN_ARCHITECTURE_MIPS_H -#define LLDB_PLUGIN_ARCHITECTURE_MIPS_H +#ifndef LLDB_SOURCE_PLUGINS_ARCHITECTURE_MIPS_ARCHITECTUREMIPS_H +#define LLDB_SOURCE_PLUGINS_ARCHITECTURE_MIPS_ARCHITECTUREMIPS_H #include "lldb/Core/Architecture.h" #include "lldb/Utility/ArchSpec.h" @@ -35,11 +35,10 @@ public: AddressClass addr_class) const override; private: - Instruction *GetInstructionAtAddress(const ExecutionContext &exe_ctx, + Instruction *GetInstructionAtAddress(Target &target, 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) {} @@ -48,4 +47,4 @@ private: } // namespace lldb_private -#endif // LLDB_PLUGIN_ARCHITECTURE_MIPS_H +#endif // LLDB_SOURCE_PLUGINS_ARCHITECTURE_MIPS_ARCHITECTUREMIPS_H diff --git a/gnu/llvm/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp b/gnu/llvm/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp index 76eaa44546e..94301ecf052 100644 --- a/gnu/llvm/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp @@ -1,4 +1,4 @@ -//===-- ArchitecturePPC64.cpp -----------------------------------*- C++ -*-===// +//===-- ArchitecturePPC64.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -20,6 +20,8 @@ using namespace lldb_private; using namespace lldb; +LLDB_PLUGIN_DEFINE(ArchitecturePPC64) + ConstString ArchitecturePPC64::GetPluginNameStatic() { return ConstString("ppc64"); } diff --git a/gnu/llvm/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h b/gnu/llvm/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h index dc663b849c4..25210d37e53 100644 --- a/gnu/llvm/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h +++ b/gnu/llvm/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGIN_ARCHITECTURE_PPC64_H -#define LLDB_PLUGIN_ARCHITECTURE_PPC64_H +#ifndef LLDB_SOURCE_PLUGINS_ARCHITECTURE_PPC64_ARCHITECTUREPPC64_H +#define LLDB_SOURCE_PLUGINS_ARCHITECTURE_PPC64_ARCHITECTUREPPC64_H #include "lldb/Core/Architecture.h" @@ -38,4 +38,4 @@ private: } // namespace lldb_private -#endif // LLDB_PLUGIN_ARCHITECTURE_PPC64_H +#endif // LLDB_SOURCE_PLUGINS_ARCHITECTURE_PPC64_ARCHITECTUREPPC64_H diff --git a/gnu/llvm/lldb/source/Plugins/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/CMakeLists.txt index 5092b210a12..d91ba749f86 100644 --- a/gnu/llvm/lldb/source/Plugins/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/CMakeLists.txt @@ -19,4 +19,36 @@ add_subdirectory(StructuredData) add_subdirectory(SymbolFile) add_subdirectory(SystemRuntime) add_subdirectory(SymbolVendor) +add_subdirectory(TypeSystem) add_subdirectory(UnwindAssembly) + +set(LLDB_STRIPPED_PLUGINS) +get_property(LLDB_ALL_PLUGINS GLOBAL PROPERTY LLDB_PLUGINS) + +set(LLDB_ENUM_PLUGINS "") + +# FIXME: ProcessWindowsCommon needs to be initialized after all other process +# plugins but before ProcessGDBRemote. +set(LLDB_PROCESS_WINDOWS_PLUGIN "") +set(LLDB_PROCESS_GDB_PLUGIN "") + +foreach(p ${LLDB_ALL_PLUGINS}) + # Strip lldbPlugin form the plugin name. + string(SUBSTRING ${p} 10 -1 pStripped) + if(${pStripped} MATCHES "^ScriptInterpreter*") + set(LLDB_ENUM_PLUGINS "${LLDB_ENUM_PLUGINS}LLDB_SCRIPT_PLUGIN(${pStripped})\n") + elseif(${pStripped} STREQUAL "ProcessWindowsCommon") + set(LLDB_PROCESS_WINDOWS_PLUGIN "LLDB_PLUGIN(${pStripped})\n") + elseif(${pStripped} STREQUAL "ProcessGDBRemote") + set(LLDB_PROCESS_GDB_PLUGIN "LLDB_PLUGIN(${pStripped})\n") + else() + set(LLDB_ENUM_PLUGINS "${LLDB_ENUM_PLUGINS}LLDB_PLUGIN(${pStripped})\n") + endif() +endforeach(p) + +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/Plugins.def.in + ${CMAKE_CURRENT_BINARY_DIR}/Plugins.def + ) + +set_property(GLOBAL PROPERTY LLDB_PLUGINS_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/gnu/llvm/lldb/source/Plugins/Disassembler/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Disassembler/CMakeLists.txt index 6e3c904d5a6..bec56765b60 100644 --- a/gnu/llvm/lldb/source/Plugins/Disassembler/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/Disassembler/CMakeLists.txt @@ -1 +1 @@ -add_subdirectory(llvm) +add_subdirectory(LLVMC) diff --git a/gnu/llvm/lldb/source/Plugins/Disassembler/LLVMC/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Disassembler/LLVMC/CMakeLists.txt new file mode 100644 index 00000000000..51959cbbc99 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/Disassembler/LLVMC/CMakeLists.txt @@ -0,0 +1,14 @@ +add_lldb_library(lldbPluginDisassemblerLLVMC PLUGIN + DisassemblerLLVMC.cpp + + LINK_LIBS + lldbCore + lldbSymbol + lldbTarget + LINK_COMPONENTS + ${LLVM_TARGETS_TO_BUILD} + MC + MCDisassembler + RuntimeDyld + Support + ) diff --git a/gnu/llvm/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp b/gnu/llvm/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp new file mode 100644 index 00000000000..6427d8d176c --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp @@ -0,0 +1,1384 @@ +//===-- DisassemblerLLVMC.cpp ---------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "DisassemblerLLVMC.h" + +#include "llvm-c/Disassembler.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDisassembler/MCDisassembler.h" +#include "llvm/MC/MCDisassembler/MCExternalSymbolizer.h" +#include "llvm/MC/MCDisassembler/MCRelocationInfo.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCTargetOptions.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ScopedPrinter.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" + +#include "lldb/Core/Address.h" +#include "lldb/Core/Module.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/SectionLoadList.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Stream.h" + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(DisassemblerLLVMC) + +class DisassemblerLLVMC::MCDisasmInstance { +public: + static std::unique_ptr + Create(const char *triple, const char *cpu, const char *features_str, + unsigned flavor, DisassemblerLLVMC &owner); + + ~MCDisasmInstance() = default; + + uint64_t GetMCInst(const uint8_t *opcode_data, size_t opcode_data_len, + lldb::addr_t pc, llvm::MCInst &mc_inst) const; + void PrintMCInst(llvm::MCInst &mc_inst, std::string &inst_string, + std::string &comments_string); + void SetStyle(bool use_hex_immed, HexImmediateStyle hex_style); + bool CanBranch(llvm::MCInst &mc_inst) const; + bool HasDelaySlot(llvm::MCInst &mc_inst) const; + bool IsCall(llvm::MCInst &mc_inst) const; + +private: + MCDisasmInstance(std::unique_ptr &&instr_info_up, + std::unique_ptr &®_info_up, + std::unique_ptr &&subtarget_info_up, + std::unique_ptr &&asm_info_up, + std::unique_ptr &&context_up, + std::unique_ptr &&disasm_up, + std::unique_ptr &&instr_printer_up); + + std::unique_ptr m_instr_info_up; + std::unique_ptr m_reg_info_up; + std::unique_ptr m_subtarget_info_up; + std::unique_ptr m_asm_info_up; + std::unique_ptr m_context_up; + std::unique_ptr m_disasm_up; + std::unique_ptr m_instr_printer_up; +}; + +class InstructionLLVMC : public lldb_private::Instruction { +public: + InstructionLLVMC(DisassemblerLLVMC &disasm, + const lldb_private::Address &address, + AddressClass addr_class) + : Instruction(address, addr_class), + m_disasm_wp(std::static_pointer_cast( + disasm.shared_from_this())), + m_using_file_addr(false) {} + + ~InstructionLLVMC() override = default; + + bool DoesBranch() override { + VisitInstruction(); + return m_does_branch; + } + + bool HasDelaySlot() override { + VisitInstruction(); + return m_has_delay_slot; + } + + DisassemblerLLVMC::MCDisasmInstance *GetDisasmToUse(bool &is_alternate_isa) { + DisassemblerScope disasm(*this); + return GetDisasmToUse(is_alternate_isa, disasm); + } + + size_t Decode(const lldb_private::Disassembler &disassembler, + const lldb_private::DataExtractor &data, + lldb::offset_t data_offset) override { + // All we have to do is read the opcode which can be easy for some + // architectures + bool got_op = false; + 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(); + const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize(); + if (min_op_byte_size == max_op_byte_size) { + // Fixed size instructions, just read that amount of data. + if (!data.ValidOffsetForDataOfSize(data_offset, min_op_byte_size)) + return false; + + switch (min_op_byte_size) { + case 1: + m_opcode.SetOpcode8(data.GetU8(&data_offset), byte_order); + got_op = true; + break; + + case 2: + m_opcode.SetOpcode16(data.GetU16(&data_offset), byte_order); + got_op = true; + break; + + case 4: + m_opcode.SetOpcode32(data.GetU32(&data_offset), byte_order); + got_op = true; + break; + + case 8: + m_opcode.SetOpcode64(data.GetU64(&data_offset), byte_order); + got_op = true; + break; + + default: + m_opcode.SetOpcodeBytes(data.PeekData(data_offset, min_op_byte_size), + min_op_byte_size); + got_op = true; + break; + } + } + if (!got_op) { + bool is_alternate_isa = false; + DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr = + GetDisasmToUse(is_alternate_isa, disasm); + + const llvm::Triple::ArchType machine = arch.GetMachine(); + if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb) { + if (machine == llvm::Triple::thumb || is_alternate_isa) { + uint32_t thumb_opcode = data.GetU16(&data_offset); + if ((thumb_opcode & 0xe000) != 0xe000 || + ((thumb_opcode & 0x1800u) == 0)) { + m_opcode.SetOpcode16(thumb_opcode, byte_order); + m_is_valid = true; + } else { + thumb_opcode <<= 16; + thumb_opcode |= data.GetU16(&data_offset); + m_opcode.SetOpcode16_2(thumb_opcode, byte_order); + m_is_valid = true; + } + } else { + m_opcode.SetOpcode32(data.GetU32(&data_offset), byte_order); + m_is_valid = true; + } + } else { + // The opcode isn't evenly sized, so we need to actually use the llvm + // disassembler to parse it and get the size. + uint8_t *opcode_data = + const_cast(data.PeekData(data_offset, 1)); + const size_t opcode_data_len = data.BytesLeft(data_offset); + const addr_t pc = m_address.GetFileAddress(); + llvm::MCInst inst; + + const size_t inst_size = + mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst); + if (inst_size == 0) + m_opcode.Clear(); + else { + m_opcode.SetOpcodeBytes(opcode_data, inst_size); + m_is_valid = true; + } + } + } + return m_opcode.GetByteSize(); + } + return 0; + } + + void AppendComment(std::string &description) { + if (m_comment.empty()) + m_comment.swap(description); + else { + m_comment.append(", "); + m_comment.append(description); + } + } + + void CalculateMnemonicOperandsAndComment( + const lldb_private::ExecutionContext *exe_ctx) override { + DataExtractor data; + const AddressClass address_class = GetAddressClass(); + + if (m_opcode.GetData(data)) { + std::string out_string; + std::string comment_string; + + DisassemblerScope disasm(*this, exe_ctx); + if (disasm) { + DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr; + + if (address_class == AddressClass::eCodeAlternateISA) + mc_disasm_ptr = disasm->m_alternate_disasm_up.get(); + else + 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->m_data_from_file; + bool use_hex_immediates = true; + Disassembler::HexImmediateStyle hex_style = Disassembler::eHexStyleC; + + if (exe_ctx) { + Target *target = exe_ctx->GetTargetPtr(); + if (target) { + use_hex_immediates = target->GetUseHexImmediates(); + hex_style = target->GetHexImmediateStyle(); + + if (!data_from_file) { + const lldb::addr_t load_addr = m_address.GetLoadAddress(target); + if (load_addr != LLDB_INVALID_ADDRESS) { + pc = load_addr; + m_using_file_addr = false; + } + } + } + } + + const uint8_t *opcode_data = data.GetDataStart(); + const size_t opcode_data_len = data.GetByteSize(); + llvm::MCInst inst; + size_t inst_size = + mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst); + + if (inst_size > 0) { + mc_disasm_ptr->SetStyle(use_hex_immediates, hex_style); + mc_disasm_ptr->PrintMCInst(inst, out_string, comment_string); + + if (!comment_string.empty()) { + AppendComment(comment_string); + } + } + + if (inst_size == 0) { + m_comment.assign("unknown opcode"); + inst_size = m_opcode.GetByteSize(); + StreamString mnemonic_strm; + lldb::offset_t offset = 0; + lldb::ByteOrder byte_order = data.GetByteOrder(); + switch (inst_size) { + case 1: { + const uint8_t uval8 = data.GetU8(&offset); + m_opcode.SetOpcode8(uval8, byte_order); + m_opcode_name.assign(".byte"); + mnemonic_strm.Printf("0x%2.2x", uval8); + } break; + case 2: { + const uint16_t uval16 = data.GetU16(&offset); + m_opcode.SetOpcode16(uval16, byte_order); + m_opcode_name.assign(".short"); + mnemonic_strm.Printf("0x%4.4x", uval16); + } break; + case 4: { + const uint32_t uval32 = data.GetU32(&offset); + m_opcode.SetOpcode32(uval32, byte_order); + m_opcode_name.assign(".long"); + mnemonic_strm.Printf("0x%8.8x", uval32); + } break; + case 8: { + const uint64_t uval64 = data.GetU64(&offset); + m_opcode.SetOpcode64(uval64, byte_order); + m_opcode_name.assign(".quad"); + mnemonic_strm.Printf("0x%16.16" PRIx64, uval64); + } break; + default: + if (inst_size == 0) + return; + else { + const uint8_t *bytes = data.PeekData(offset, inst_size); + if (bytes == nullptr) + return; + m_opcode_name.assign(".byte"); + m_opcode.SetOpcodeBytes(bytes, inst_size); + mnemonic_strm.Printf("0x%2.2x", bytes[0]); + for (uint32_t i = 1; i < inst_size; ++i) + mnemonic_strm.Printf(" 0x%2.2x", bytes[i]); + } + break; + } + m_mnemonics = std::string(mnemonic_strm.GetString()); + return; + } + + static RegularExpression s_regex( + llvm::StringRef("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?")); + + llvm::SmallVector matches; + if (s_regex.Execute(out_string, &matches)) { + m_opcode_name = matches[1].str(); + m_mnemonics = matches[2].str(); + } + } + } + } + + bool IsValid() const { return m_is_valid; } + + bool UsingFileAddress() const { return m_using_file_addr; } + size_t GetByteSize() const { return m_opcode.GetByteSize(); } + + /// 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, + llvm::StringRef::const_iterator ose) { + while (osi != ose) { + switch (*osi) { + default: + return osi; + case ' ': + case '\t': + break; + } + ++osi; + } + + return osi; + } + + static std::pair + ConsumeChar(llvm::StringRef::const_iterator osi, const char c, + llvm::StringRef::const_iterator ose) { + bool found = false; + + osi = ConsumeWhitespace(osi, ose); + if (osi != ose && *osi == c) { + found = true; + ++osi; + } + + return std::make_pair(found, osi); + } + + static std::pair + ParseRegisterName(llvm::StringRef::const_iterator osi, + llvm::StringRef::const_iterator ose) { + Operand ret; + ret.m_type = Operand::Type::Register; + std::string str; + + osi = ConsumeWhitespace(osi, ose); + + while (osi != ose) { + if (*osi >= '0' && *osi <= '9') { + if (str.empty()) { + return std::make_pair(Operand(), osi); + } else { + str.push_back(*osi); + } + } else if (*osi >= 'a' && *osi <= 'z') { + str.push_back(*osi); + } else { + switch (*osi) { + default: + if (str.empty()) { + return std::make_pair(Operand(), osi); + } else { + ret.m_register = ConstString(str); + return std::make_pair(ret, osi); + } + case '%': + if (!str.empty()) { + return std::make_pair(Operand(), osi); + } + break; + } + } + ++osi; + } + + ret.m_register = ConstString(str); + return std::make_pair(ret, osi); + } + + static std::pair + ParseImmediate(llvm::StringRef::const_iterator osi, + llvm::StringRef::const_iterator ose) { + Operand ret; + ret.m_type = Operand::Type::Immediate; + std::string str; + bool is_hex = false; + + osi = ConsumeWhitespace(osi, ose); + + while (osi != ose) { + if (*osi >= '0' && *osi <= '9') { + str.push_back(*osi); + } else if (*osi >= 'a' && *osi <= 'f') { + if (is_hex) { + str.push_back(*osi); + } else { + return std::make_pair(Operand(), osi); + } + } else { + switch (*osi) { + default: + if (str.empty()) { + return std::make_pair(Operand(), osi); + } else { + ret.m_immediate = strtoull(str.c_str(), nullptr, 0); + return std::make_pair(ret, osi); + } + case 'x': + if (!str.compare("0")) { + is_hex = true; + str.push_back(*osi); + } else { + return std::make_pair(Operand(), osi); + } + break; + case '#': + case '$': + if (!str.empty()) { + return std::make_pair(Operand(), osi); + } + break; + case '-': + if (str.empty()) { + ret.m_negative = true; + } else { + return std::make_pair(Operand(), osi); + } + } + } + ++osi; + } + + ret.m_immediate = strtoull(str.c_str(), nullptr, 0); + return std::make_pair(ret, osi); + } + + // -0x5(%rax,%rax,2) + static std::pair + ParseIntelIndexedAccess(llvm::StringRef::const_iterator osi, + llvm::StringRef::const_iterator ose) { + std::pair offset_and_iterator = + ParseImmediate(osi, ose); + if (offset_and_iterator.first.IsValid()) { + osi = offset_and_iterator.second; + } + + bool found = false; + std::tie(found, osi) = ConsumeChar(osi, '(', ose); + if (!found) { + return std::make_pair(Operand(), osi); + } + + std::pair base_and_iterator = + ParseRegisterName(osi, ose); + if (base_and_iterator.first.IsValid()) { + osi = base_and_iterator.second; + } else { + return std::make_pair(Operand(), osi); + } + + std::tie(found, osi) = ConsumeChar(osi, ',', ose); + if (!found) { + return std::make_pair(Operand(), osi); + } + + std::pair index_and_iterator = + ParseRegisterName(osi, ose); + if (index_and_iterator.first.IsValid()) { + osi = index_and_iterator.second; + } else { + return std::make_pair(Operand(), osi); + } + + std::tie(found, osi) = ConsumeChar(osi, ',', ose); + if (!found) { + return std::make_pair(Operand(), osi); + } + + std::pair + multiplier_and_iterator = ParseImmediate(osi, ose); + if (index_and_iterator.first.IsValid()) { + osi = index_and_iterator.second; + } else { + return std::make_pair(Operand(), osi); + } + + std::tie(found, osi) = ConsumeChar(osi, ')', ose); + if (!found) { + return std::make_pair(Operand(), osi); + } + + Operand product; + product.m_type = Operand::Type::Product; + product.m_children.push_back(index_and_iterator.first); + product.m_children.push_back(multiplier_and_iterator.first); + + Operand index; + index.m_type = Operand::Type::Sum; + index.m_children.push_back(base_and_iterator.first); + index.m_children.push_back(product); + + if (offset_and_iterator.first.IsValid()) { + Operand offset; + offset.m_type = Operand::Type::Sum; + offset.m_children.push_back(offset_and_iterator.first); + offset.m_children.push_back(index); + + Operand deref; + deref.m_type = Operand::Type::Dereference; + deref.m_children.push_back(offset); + return std::make_pair(deref, osi); + } else { + Operand deref; + deref.m_type = Operand::Type::Dereference; + deref.m_children.push_back(index); + return std::make_pair(deref, osi); + } + } + + // -0x10(%rbp) + static std::pair + ParseIntelDerefAccess(llvm::StringRef::const_iterator osi, + llvm::StringRef::const_iterator ose) { + std::pair offset_and_iterator = + ParseImmediate(osi, ose); + if (offset_and_iterator.first.IsValid()) { + osi = offset_and_iterator.second; + } + + bool found = false; + std::tie(found, osi) = ConsumeChar(osi, '(', ose); + if (!found) { + return std::make_pair(Operand(), osi); + } + + std::pair base_and_iterator = + ParseRegisterName(osi, ose); + if (base_and_iterator.first.IsValid()) { + osi = base_and_iterator.second; + } else { + return std::make_pair(Operand(), osi); + } + + std::tie(found, osi) = ConsumeChar(osi, ')', ose); + if (!found) { + return std::make_pair(Operand(), osi); + } + + if (offset_and_iterator.first.IsValid()) { + Operand offset; + offset.m_type = Operand::Type::Sum; + offset.m_children.push_back(offset_and_iterator.first); + offset.m_children.push_back(base_and_iterator.first); + + Operand deref; + deref.m_type = Operand::Type::Dereference; + deref.m_children.push_back(offset); + return std::make_pair(deref, osi); + } else { + Operand deref; + deref.m_type = Operand::Type::Dereference; + deref.m_children.push_back(base_and_iterator.first); + return std::make_pair(deref, osi); + } + } + + // [sp, #8]! + static std::pair + ParseARMOffsetAccess(llvm::StringRef::const_iterator osi, + llvm::StringRef::const_iterator ose) { + bool found = false; + std::tie(found, osi) = ConsumeChar(osi, '[', ose); + if (!found) { + return std::make_pair(Operand(), osi); + } + + std::pair base_and_iterator = + ParseRegisterName(osi, ose); + if (base_and_iterator.first.IsValid()) { + osi = base_and_iterator.second; + } else { + return std::make_pair(Operand(), osi); + } + + std::tie(found, osi) = ConsumeChar(osi, ',', ose); + if (!found) { + return std::make_pair(Operand(), osi); + } + + std::pair offset_and_iterator = + ParseImmediate(osi, ose); + if (offset_and_iterator.first.IsValid()) { + osi = offset_and_iterator.second; + } + + std::tie(found, osi) = ConsumeChar(osi, ']', ose); + if (!found) { + return std::make_pair(Operand(), osi); + } + + Operand offset; + offset.m_type = Operand::Type::Sum; + offset.m_children.push_back(offset_and_iterator.first); + offset.m_children.push_back(base_and_iterator.first); + + Operand deref; + deref.m_type = Operand::Type::Dereference; + deref.m_children.push_back(offset); + return std::make_pair(deref, osi); + } + + // [sp] + static std::pair + ParseARMDerefAccess(llvm::StringRef::const_iterator osi, + llvm::StringRef::const_iterator ose) { + bool found = false; + std::tie(found, osi) = ConsumeChar(osi, '[', ose); + if (!found) { + return std::make_pair(Operand(), osi); + } + + std::pair base_and_iterator = + ParseRegisterName(osi, ose); + if (base_and_iterator.first.IsValid()) { + osi = base_and_iterator.second; + } else { + return std::make_pair(Operand(), osi); + } + + std::tie(found, osi) = ConsumeChar(osi, ']', ose); + if (!found) { + return std::make_pair(Operand(), osi); + } + + Operand deref; + deref.m_type = Operand::Type::Dereference; + deref.m_children.push_back(base_and_iterator.first); + return std::make_pair(deref, osi); + } + + static void DumpOperand(const Operand &op, Stream &s) { + switch (op.m_type) { + case Operand::Type::Dereference: + s.PutCString("*"); + DumpOperand(op.m_children[0], s); + break; + case Operand::Type::Immediate: + if (op.m_negative) { + s.PutCString("-"); + } + s.PutCString(llvm::to_string(op.m_immediate)); + break; + case Operand::Type::Invalid: + s.PutCString("Invalid"); + break; + case Operand::Type::Product: + s.PutCString("("); + DumpOperand(op.m_children[0], s); + s.PutCString("*"); + DumpOperand(op.m_children[1], s); + s.PutCString(")"); + break; + case Operand::Type::Register: + s.PutCString(op.m_register.GetStringRef()); + break; + case Operand::Type::Sum: + s.PutCString("("); + DumpOperand(op.m_children[0], s); + s.PutCString("+"); + DumpOperand(op.m_children[1], s); + s.PutCString(")"); + break; + } + } + + bool ParseOperands( + llvm::SmallVectorImpl &operands) override { + const char *operands_string = GetOperands(nullptr); + + if (!operands_string) { + return false; + } + + llvm::StringRef operands_ref(operands_string); + + llvm::StringRef::const_iterator osi = operands_ref.begin(); + llvm::StringRef::const_iterator ose = operands_ref.end(); + + while (osi != ose) { + Operand operand; + llvm::StringRef::const_iterator iter; + + if ((std::tie(operand, iter) = ParseIntelIndexedAccess(osi, ose), + operand.IsValid()) || + (std::tie(operand, iter) = ParseIntelDerefAccess(osi, ose), + operand.IsValid()) || + (std::tie(operand, iter) = ParseARMOffsetAccess(osi, ose), + operand.IsValid()) || + (std::tie(operand, iter) = ParseARMDerefAccess(osi, ose), + operand.IsValid()) || + (std::tie(operand, iter) = ParseRegisterName(osi, ose), + operand.IsValid()) || + (std::tie(operand, iter) = ParseImmediate(osi, ose), + operand.IsValid())) { + osi = iter; + operands.push_back(operand); + } else { + return false; + } + + std::pair found_and_iter = + ConsumeChar(osi, ',', ose); + if (found_and_iter.first) { + osi = found_and_iter.second; + } + + osi = ConsumeWhitespace(osi, ose); + } + + DisassemblerSP disasm_sp = m_disasm_wp.lock(); + + if (disasm_sp && operands.size() > 1) { + // TODO tie this into the MC Disassembler's notion of clobbers. + switch (disasm_sp->GetArchitecture().GetMachine()) { + default: + break; + case llvm::Triple::x86: + case llvm::Triple::x86_64: + operands[operands.size() - 1].m_clobbered = true; + break; + case llvm::Triple::arm: + operands[0].m_clobbered = true; + break; + } + } + + if (Log *log = + lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)) { + StreamString ss; + + ss.Printf("[%s] expands to %zu operands:\n", operands_string, + operands.size()); + for (const Operand &operand : operands) { + ss.PutCString(" "); + DumpOperand(operand, ss); + ss.PutCString("\n"); + } + + log->PutString(ss.GetString()); + } + + return true; + } + + bool IsCall() override { + VisitInstruction(); + return m_is_call; + } + +protected: + std::weak_ptr m_disasm_wp; + + bool m_is_valid = false; + bool m_using_file_addr; + bool m_has_visited_instruction = false; + + // Be conservative. If we didn't understand the instruction, say it: + // - Might branch + // - Does not have a delay slot + // - Is not a call + bool m_does_branch = true; + bool m_has_delay_slot = false; + bool m_is_call = false; + + void VisitInstruction() { + if (m_has_visited_instruction) + return; + + DisassemblerScope disasm(*this); + if (!disasm) + return; + + DataExtractor data; + if (!m_opcode.GetData(data)) + return; + + bool is_alternate_isa; + lldb::addr_t pc = m_address.GetFileAddress(); + DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr = + GetDisasmToUse(is_alternate_isa, disasm); + const uint8_t *opcode_data = data.GetDataStart(); + const size_t opcode_data_len = data.GetByteSize(); + llvm::MCInst inst; + const size_t inst_size = + mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst); + if (inst_size == 0) + return; + + m_has_visited_instruction = true; + m_does_branch = mc_disasm_ptr->CanBranch(inst); + m_has_delay_slot = mc_disasm_ptr->HasDelaySlot(inst); + m_is_call = mc_disasm_ptr->IsCall(inst); + } + +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 +DisassemblerLLVMC::MCDisasmInstance::Create(const char *triple, const char *cpu, + const char *features_str, + unsigned flavor, + DisassemblerLLVMC &owner) { + using Instance = std::unique_ptr; + + std::string Status; + const llvm::Target *curr_target = + llvm::TargetRegistry::lookupTarget(triple, Status); + if (!curr_target) + return Instance(); + + std::unique_ptr instr_info_up( + curr_target->createMCInstrInfo()); + if (!instr_info_up) + return Instance(); + + std::unique_ptr reg_info_up( + curr_target->createMCRegInfo(triple)); + if (!reg_info_up) + return Instance(); + + std::unique_ptr subtarget_info_up( + curr_target->createMCSubtargetInfo(triple, cpu, features_str)); + if (!subtarget_info_up) + return Instance(); + + llvm::MCTargetOptions MCOptions; + std::unique_ptr asm_info_up( + curr_target->createMCAsmInfo(*reg_info_up, triple, MCOptions)); + if (!asm_info_up) + return Instance(); + + std::unique_ptr context_up( + new llvm::MCContext(asm_info_up.get(), reg_info_up.get(), nullptr)); + if (!context_up) + return Instance(); + + std::unique_ptr disasm_up( + curr_target->createMCDisassembler(*subtarget_info_up, *context_up)); + if (!disasm_up) + return Instance(); + + std::unique_ptr rel_info_up( + curr_target->createMCRelocationInfo(triple, *context_up)); + if (!rel_info_up) + return Instance(); + + std::unique_ptr symbolizer_up( + curr_target->createMCSymbolizer( + triple, nullptr, DisassemblerLLVMC::SymbolLookupCallback, &owner, + context_up.get(), std::move(rel_info_up))); + disasm_up->setSymbolizer(std::move(symbolizer_up)); + + unsigned asm_printer_variant = + flavor == ~0U ? asm_info_up->getAssemblerDialect() : flavor; + + std::unique_ptr instr_printer_up( + curr_target->createMCInstPrinter(llvm::Triple{triple}, + asm_printer_variant, *asm_info_up, + *instr_info_up, *reg_info_up)); + if (!instr_printer_up) + return Instance(); + + return Instance( + new MCDisasmInstance(std::move(instr_info_up), std::move(reg_info_up), + std::move(subtarget_info_up), std::move(asm_info_up), + std::move(context_up), std::move(disasm_up), + std::move(instr_printer_up))); +} + +DisassemblerLLVMC::MCDisasmInstance::MCDisasmInstance( + std::unique_ptr &&instr_info_up, + std::unique_ptr &®_info_up, + std::unique_ptr &&subtarget_info_up, + std::unique_ptr &&asm_info_up, + std::unique_ptr &&context_up, + std::unique_ptr &&disasm_up, + std::unique_ptr &&instr_printer_up) + : m_instr_info_up(std::move(instr_info_up)), + m_reg_info_up(std::move(reg_info_up)), + m_subtarget_info_up(std::move(subtarget_info_up)), + m_asm_info_up(std::move(asm_info_up)), + m_context_up(std::move(context_up)), m_disasm_up(std::move(disasm_up)), + m_instr_printer_up(std::move(instr_printer_up)) { + assert(m_instr_info_up && m_reg_info_up && m_subtarget_info_up && + m_asm_info_up && m_context_up && m_disasm_up && m_instr_printer_up); +} + +uint64_t DisassemblerLLVMC::MCDisasmInstance::GetMCInst( + const uint8_t *opcode_data, size_t opcode_data_len, lldb::addr_t pc, + llvm::MCInst &mc_inst) const { + llvm::ArrayRef data(opcode_data, opcode_data_len); + llvm::MCDisassembler::DecodeStatus status; + + uint64_t new_inst_size; + status = m_disasm_up->getInstruction(mc_inst, new_inst_size, data, pc, + llvm::nulls()); + if (status == llvm::MCDisassembler::Success) + return new_inst_size; + else + return 0; +} + +void DisassemblerLLVMC::MCDisasmInstance::PrintMCInst( + llvm::MCInst &mc_inst, std::string &inst_string, + std::string &comments_string) { + llvm::raw_string_ostream inst_stream(inst_string); + llvm::raw_string_ostream comments_stream(comments_string); + + m_instr_printer_up->setCommentStream(comments_stream); + m_instr_printer_up->printInst(&mc_inst, 0, llvm::StringRef(), + *m_subtarget_info_up, inst_stream); + m_instr_printer_up->setCommentStream(llvm::nulls()); + comments_stream.flush(); + + static std::string g_newlines("\r\n"); + + for (size_t newline_pos = 0; + (newline_pos = comments_string.find_first_of(g_newlines, newline_pos)) != + comments_string.npos; + /**/) { + comments_string.replace(comments_string.begin() + newline_pos, + comments_string.begin() + newline_pos + 1, 1, ' '); + } +} + +void DisassemblerLLVMC::MCDisasmInstance::SetStyle( + bool use_hex_immed, HexImmediateStyle hex_style) { + m_instr_printer_up->setPrintImmHex(use_hex_immed); + switch (hex_style) { + case eHexStyleC: + m_instr_printer_up->setPrintHexStyle(llvm::HexStyle::C); + break; + case eHexStyleAsm: + m_instr_printer_up->setPrintHexStyle(llvm::HexStyle::Asm); + break; + } +} + +bool DisassemblerLLVMC::MCDisasmInstance::CanBranch( + llvm::MCInst &mc_inst) const { + return m_instr_info_up->get(mc_inst.getOpcode()) + .mayAffectControlFlow(mc_inst, *m_reg_info_up); +} + +bool DisassemblerLLVMC::MCDisasmInstance::HasDelaySlot( + llvm::MCInst &mc_inst) const { + return m_instr_info_up->get(mc_inst.getOpcode()).hasDelaySlot(); +} + +bool DisassemblerLLVMC::MCDisasmInstance::IsCall(llvm::MCInst &mc_inst) const { + return m_instr_info_up->get(mc_inst.getOpcode()).isCall(); +} + +DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch, + const char *flavor_string) + : Disassembler(arch, flavor_string), m_exe_ctx(nullptr), m_inst(nullptr), + m_data_from_file(false) { + if (!FlavorValidForArchSpec(arch, m_flavor.c_str())) { + m_flavor.assign("default"); + } + + unsigned flavor = ~0U; + llvm::Triple triple = arch.GetTriple(); + + // So far the only supported flavor is "intel" on x86. The base class will + // set this correctly coming in. + if (triple.getArch() == llvm::Triple::x86 || + triple.getArch() == llvm::Triple::x86_64) { + if (m_flavor == "intel") { + flavor = 1; + } else if (m_flavor == "att") { + flavor = 0; + } + } + + ArchSpec thumb_arch(arch); + if (triple.getArch() == llvm::Triple::arm) { + std::string thumb_arch_name(thumb_arch.GetTriple().getArchName().str()); + // Replace "arm" with "thumb" so we get all thumb variants correct + if (thumb_arch_name.size() > 3) { + thumb_arch_name.erase(0, 3); + thumb_arch_name.insert(0, "thumb"); + } else { + thumb_arch_name = "thumbv8.2a"; + } + thumb_arch.GetTriple().setArchName(llvm::StringRef(thumb_arch_name)); + } + + // If no sub architecture specified then use the most recent arm architecture + // so the disassembler will return all instruction. Without it we will see a + // lot of unknow opcode in case the code uses instructions which are not + // available in the oldest arm version (used when no sub architecture is + // specified) + if (triple.getArch() == llvm::Triple::arm && + 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 = ""; + + switch (arch.GetCore()) { + case ArchSpec::eCore_mips32: + case ArchSpec::eCore_mips32el: + cpu = "mips32"; + break; + case ArchSpec::eCore_mips32r2: + case ArchSpec::eCore_mips32r2el: + cpu = "mips32r2"; + break; + case ArchSpec::eCore_mips32r3: + case ArchSpec::eCore_mips32r3el: + cpu = "mips32r3"; + break; + case ArchSpec::eCore_mips32r5: + case ArchSpec::eCore_mips32r5el: + cpu = "mips32r5"; + break; + case ArchSpec::eCore_mips32r6: + case ArchSpec::eCore_mips32r6el: + cpu = "mips32r6"; + break; + case ArchSpec::eCore_mips64: + case ArchSpec::eCore_mips64el: + cpu = "mips64"; + break; + case ArchSpec::eCore_mips64r2: + case ArchSpec::eCore_mips64r2el: + cpu = "mips64r2"; + break; + case ArchSpec::eCore_mips64r3: + case ArchSpec::eCore_mips64r3el: + cpu = "mips64r3"; + break; + case ArchSpec::eCore_mips64r5: + case ArchSpec::eCore_mips64r5el: + cpu = "mips64r5"; + break; + case ArchSpec::eCore_mips64r6: + case ArchSpec::eCore_mips64r6el: + cpu = "mips64r6"; + break; + default: + cpu = ""; + break; + } + + if (arch.IsMIPS()) { + uint32_t arch_flags = arch.GetFlags(); + if (arch_flags & ArchSpec::eMIPSAse_msa) + features_str += "+msa,"; + if (arch_flags & ArchSpec::eMIPSAse_dsp) + features_str += "+dsp,"; + if (arch_flags & ArchSpec::eMIPSAse_dspr2) + features_str += "+dspr2,"; + } + + // If any AArch64 variant, enable the ARMv8.5 ISA with SVE extensions so we + // can disassemble newer instructions. + if (triple.getArch() == llvm::Triple::aarch64 || + triple.getArch() == llvm::Triple::aarch64_32) + features_str += "+v8.5a,+sve2"; + + if ((triple.getArch() == llvm::Triple::aarch64 || + triple.getArch() == llvm::Triple::aarch64_32) + && triple.getVendor() == llvm::Triple::Apple) { + cpu = "apple-latest"; + } + + // We use m_disasm_up.get() to tell whether we are valid or not, so if this + // isn't good for some reason, we won't be valid and FindPlugin will fail and + // we won't get used. + m_disasm_up = MCDisasmInstance::Create(triple_str, cpu, features_str.c_str(), + flavor, *this); + + llvm::Triple::ArchType llvm_arch = triple.getArch(); + + // For arm CPUs that can execute arm or thumb instructions, also create a + // thumb instruction disassembler. + if (llvm_arch == llvm::Triple::arm) { + std::string thumb_triple(thumb_arch.GetTriple().getTriple()); + m_alternate_disasm_up = + MCDisasmInstance::Create(thumb_triple.c_str(), "", features_str.c_str(), + flavor, *this); + if (!m_alternate_disasm_up) + m_disasm_up.reset(); + + } else if (arch.IsMIPS()) { + /* Create alternate disassembler for MIPS16 and microMIPS */ + uint32_t arch_flags = arch.GetFlags(); + if (arch_flags & ArchSpec::eMIPSAse_mips16) + features_str += "+mips16,"; + else if (arch_flags & ArchSpec::eMIPSAse_micromips) + features_str += "+micromips,"; + + m_alternate_disasm_up = MCDisasmInstance::Create( + triple_str, cpu, features_str.c_str(), flavor, *this); + if (!m_alternate_disasm_up) + m_disasm_up.reset(); + } +} + +DisassemblerLLVMC::~DisassemblerLLVMC() = default; + +Disassembler *DisassemblerLLVMC::CreateInstance(const ArchSpec &arch, + const char *flavor) { + if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch) { + std::unique_ptr disasm_up( + new DisassemblerLLVMC(arch, flavor)); + + if (disasm_up.get() && disasm_up->IsValid()) + return disasm_up.release(); + } + return nullptr; +} + +size_t DisassemblerLLVMC::DecodeInstructions(const Address &base_addr, + const DataExtractor &data, + lldb::offset_t data_offset, + size_t num_instructions, + bool append, bool data_from_file) { + if (!append) + m_instruction_list.Clear(); + + if (!IsValid()) + return 0; + + m_data_from_file = data_from_file; + uint32_t data_cursor = data_offset; + const size_t data_byte_size = data.GetByteSize(); + uint32_t instructions_parsed = 0; + Address inst_addr(base_addr); + + while (data_cursor < data_byte_size && + instructions_parsed < num_instructions) { + + AddressClass address_class = AddressClass::eCode; + + if (m_alternate_disasm_up) + address_class = inst_addr.GetAddressClass(); + + InstructionSP inst_sp( + new InstructionLLVMC(*this, inst_addr, address_class)); + + if (!inst_sp) + break; + + uint32_t inst_size = inst_sp->Decode(*this, data, data_cursor); + + if (inst_size == 0) + break; + + m_instruction_list.Append(inst_sp); + data_cursor += inst_size; + inst_addr.Slide(inst_size); + instructions_parsed++; + } + + return data_cursor - data_offset; +} + +void DisassemblerLLVMC::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + "Disassembler that uses LLVM MC to disassemble " + "i386, x86_64, ARM, and ARM64.", + CreateInstance); + + llvm::InitializeAllTargetInfos(); + llvm::InitializeAllTargetMCs(); + llvm::InitializeAllAsmParsers(); + llvm::InitializeAllDisassemblers(); +} + +void DisassemblerLLVMC::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +ConstString DisassemblerLLVMC::GetPluginNameStatic() { + static ConstString g_name("llvm-mc"); + return g_name; +} + +int DisassemblerLLVMC::OpInfoCallback(void *disassembler, uint64_t pc, + uint64_t offset, uint64_t size, + int tag_type, void *tag_bug) { + return static_cast(disassembler) + ->OpInfo(pc, offset, size, tag_type, tag_bug); +} + +const char *DisassemblerLLVMC::SymbolLookupCallback(void *disassembler, + uint64_t value, + uint64_t *type, uint64_t pc, + const char **name) { + return static_cast(disassembler) + ->SymbolLookup(value, type, pc, name); +} + +bool DisassemblerLLVMC::FlavorValidForArchSpec( + const lldb_private::ArchSpec &arch, const char *flavor) { + llvm::Triple triple = arch.GetTriple(); + if (flavor == nullptr || strcmp(flavor, "default") == 0) + return true; + + if (triple.getArch() == llvm::Triple::x86 || + triple.getArch() == llvm::Triple::x86_64) { + return strcmp(flavor, "intel") == 0 || strcmp(flavor, "att") == 0; + } else + return false; +} + +bool DisassemblerLLVMC::IsValid() const { return m_disasm_up.operator bool(); } + +int DisassemblerLLVMC::OpInfo(uint64_t PC, uint64_t Offset, uint64_t Size, + int tag_type, void *tag_bug) { + switch (tag_type) { + default: + break; + case 1: + memset(tag_bug, 0, sizeof(::LLVMOpInfo1)); + break; + } + return 0; +} + +const char *DisassemblerLLVMC::SymbolLookup(uint64_t value, uint64_t *type_ptr, + uint64_t pc, const char **name) { + if (*type_ptr) { + if (m_exe_ctx && m_inst) { + // std::string remove_this_prior_to_checkin; + Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : nullptr; + Address value_so_addr; + Address pc_so_addr; + if (m_inst->UsingFileAddress()) { + ModuleSP module_sp(m_inst->GetAddress().GetModule()); + if (module_sp) { + module_sp->ResolveFileAddress(value, value_so_addr); + module_sp->ResolveFileAddress(pc, pc_so_addr); + } + } else if (target && !target->GetSectionLoadList().IsEmpty()) { + target->GetSectionLoadList().ResolveLoadAddress(value, value_so_addr); + target->GetSectionLoadList().ResolveLoadAddress(pc, pc_so_addr); + } + + SymbolContext sym_ctx; + const SymbolContextItem resolve_scope = + eSymbolContextFunction | eSymbolContextSymbol; + if (pc_so_addr.IsValid() && pc_so_addr.GetModule()) { + pc_so_addr.GetModule()->ResolveSymbolContextForAddress( + pc_so_addr, resolve_scope, sym_ctx); + } + + if (value_so_addr.IsValid() && value_so_addr.GetSection()) { + StreamString ss; + + bool format_omitting_current_func_name = false; + if (sym_ctx.symbol || sym_ctx.function) { + AddressRange range; + if (sym_ctx.GetAddressRange(resolve_scope, 0, false, range) && + range.GetBaseAddress().IsValid() && + range.ContainsLoadAddress(value_so_addr, target)) { + format_omitting_current_func_name = true; + } + } + + // If the "value" address (the target address we're symbolicating) is + // inside the same SymbolContext as the current instruction pc + // (pc_so_addr), don't print the full function name - just print it + // with DumpStyleNoFunctionName style, e.g. "<+36>". + if (format_omitting_current_func_name) { + value_so_addr.Dump(&ss, target, Address::DumpStyleNoFunctionName, + Address::DumpStyleSectionNameOffset); + } else { + value_so_addr.Dump( + &ss, target, + Address::DumpStyleResolvedDescriptionNoFunctionArguments, + Address::DumpStyleSectionNameOffset); + } + + if (!ss.GetString().empty()) { + // If Address::Dump returned a multi-line description, most commonly + // seen when we have multiple levels of inlined functions at an + // address, only show the first line. + std::string str = std::string(ss.GetString()); + size_t first_eol_char = str.find_first_of("\r\n"); + if (first_eol_char != std::string::npos) { + str.erase(first_eol_char); + } + m_inst->AppendComment(str); + } + } + } + } + + *type_ptr = LLVMDisassembler_ReferenceType_InOut_None; + *name = nullptr; + return nullptr; +} + +// PluginInterface protocol +ConstString DisassemblerLLVMC::GetPluginName() { return GetPluginNameStatic(); } + +uint32_t DisassemblerLLVMC::GetPluginVersion() { return 1; } diff --git a/gnu/llvm/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h b/gnu/llvm/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h new file mode 100644 index 00000000000..9b3741bdd18 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h @@ -0,0 +1,85 @@ +//===-- DisassemblerLLVMC.h -------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_DISASSEMBLER_LLVMC_DISASSEMBLERLLVMC_H +#define LLDB_SOURCE_PLUGINS_DISASSEMBLER_LLVMC_DISASSEMBLERLLVMC_H + +#include +#include +#include + +#include "lldb/Core/Address.h" +#include "lldb/Core/Disassembler.h" +#include "lldb/Core/PluginManager.h" + +class InstructionLLVMC; + +class DisassemblerLLVMC : public lldb_private::Disassembler { +public: + DisassemblerLLVMC(const lldb_private::ArchSpec &arch, + const char *flavor /* = NULL */); + + ~DisassemblerLLVMC() override; + + // Static Functions + static void Initialize(); + + static void Terminate(); + + static lldb_private::ConstString GetPluginNameStatic(); + + static lldb_private::Disassembler * + CreateInstance(const lldb_private::ArchSpec &arch, const char *flavor); + + size_t DecodeInstructions(const lldb_private::Address &base_addr, + const lldb_private::DataExtractor &data, + lldb::offset_t data_offset, size_t num_instructions, + bool append, bool data_from_file) override; + + // PluginInterface protocol + lldb_private::ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + +protected: + friend class InstructionLLVMC; + + bool FlavorValidForArchSpec(const lldb_private::ArchSpec &arch, + const char *flavor) override; + + bool IsValid() const; + + int OpInfo(uint64_t PC, uint64_t Offset, uint64_t Size, int TagType, + void *TagBug); + + const char *SymbolLookup(uint64_t ReferenceValue, uint64_t *ReferenceType, + uint64_t ReferencePC, const char **ReferenceName); + + static int OpInfoCallback(void *DisInfo, uint64_t PC, uint64_t Offset, + uint64_t Size, int TagType, void *TagBug); + + static const char *SymbolLookupCallback(void *DisInfo, + uint64_t ReferenceValue, + uint64_t *ReferenceType, + uint64_t ReferencePC, + const char **ReferenceName); + + const lldb_private::ExecutionContext *m_exe_ctx; + InstructionLLVMC *m_inst; + std::mutex m_mutex; + bool m_data_from_file; + + // Since we need to make two actual MC Disassemblers for ARM (ARM & THUMB), + // and there's a bit of goo to set up and own in the MC disassembler world, + // this class was added to manage the actual disassemblers. + class MCDisasmInstance; + std::unique_ptr m_disasm_up; + std::unique_ptr m_alternate_disasm_up; +}; + +#endif // LLDB_SOURCE_PLUGINS_DISASSEMBLER_LLVMC_DISASSEMBLERLLVMC_H diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/DynamicLoader/CMakeLists.txt index 9f3b2ab0e50..f357fea02ef 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/CMakeLists.txt @@ -4,3 +4,4 @@ add_subdirectory(POSIX-DYLD) add_subdirectory(Static) add_subdirectory(Hexagon-DYLD) add_subdirectory(Windows-DYLD) +add_subdirectory(wasm-DYLD) diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp index 6019a1cc760..68a0335682d 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp @@ -1,5 +1,4 @@ -//===-- DynamicLoaderDarwinKernel.cpp -----------------------------*- C++ -//-*-===// +//===-- DynamicLoaderDarwinKernel.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -45,6 +44,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(DynamicLoaderDarwinKernel) + // Progressively greater amounts of scanning we will allow For some targets // very early in startup, we can't do any random reads of memory or we can // crash the device so a setting is needed that can completely disable the @@ -244,6 +245,7 @@ DynamicLoaderDarwinKernel::SearchForKernelWithDebugHints(Process *process) { Status read_err; addr_t kernel_addresses_64[] = { + 0xfffffff000002010ULL, 0xfffffff000004010ULL, // newest arm64 devices 0xffffff8000004010ULL, // 2014-2015-ish arm64 devices 0xffffff8000002010ULL, // oldest arm64 devices diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h index eb31c40916c..8659cd575bc 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DynamicLoaderDarwinKernel_h_ -#define liblldb_DynamicLoaderDarwinKernel_h_ +#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_DARWIN_KERNEL_DYNAMICLOADERDARWINKERNEL_H +#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_DARWIN_KERNEL_DYNAMICLOADERDARWINKERNEL_H #include #include @@ -296,7 +296,9 @@ protected: lldb::user_id_t m_break_id; private: - DISALLOW_COPY_AND_ASSIGN(DynamicLoaderDarwinKernel); + DynamicLoaderDarwinKernel(const DynamicLoaderDarwinKernel &) = delete; + const DynamicLoaderDarwinKernel & + operator=(const DynamicLoaderDarwinKernel &) = delete; }; -#endif // liblldb_DynamicLoaderDarwinKernel_h_ +#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_DARWIN_KERNEL_DYNAMICLOADERDARWINKERNEL_H diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp index 5b19647a27b..fe86b292907 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp @@ -1,4 +1,4 @@ -//===-- DynamicLoaderHexagonDYLD.cpp ----------------------------*- C++ -*-===// +//===-- DynamicLoaderHexagonDYLD.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,6 +25,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(DynamicLoaderHexagonDYLD) + // Aidan 21/05/2014 // // Notes about hexagon dynamic loading: @@ -418,8 +420,8 @@ DynamicLoaderHexagonDYLD::GetStepThroughTrampolinePlan(Thread &thread, if (sym == nullptr || !sym->IsTrampoline()) return thread_plan_sp; - const ConstString sym_name = sym->GetMangled().GetName( - lldb::eLanguageTypeUnknown, Mangled::ePreferMangled); + const ConstString sym_name = + sym->GetMangled().GetName(Mangled::ePreferMangled); if (!sym_name) return thread_plan_sp; diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h index c171513c549..2d39ce06a8d 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DynamicLoaderHexagonDYLD_h_ -#define liblldb_DynamicLoaderHexagonDYLD_h_ +#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_DYNAMICLOADERHEXAGONDYLD_H +#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_DYNAMICLOADERHEXAGONDYLD_H #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Target/DynamicLoader.h" @@ -132,7 +132,9 @@ private: const lldb_private::SectionList * GetSectionListFromModule(const lldb::ModuleSP module) const; - DISALLOW_COPY_AND_ASSIGN(DynamicLoaderHexagonDYLD); + DynamicLoaderHexagonDYLD(const DynamicLoaderHexagonDYLD &) = delete; + const DynamicLoaderHexagonDYLD & + operator=(const DynamicLoaderHexagonDYLD &) = delete; }; -#endif // liblldb_DynamicLoaderHexagonDYLD_h_ +#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_DYNAMICLOADERHEXAGONDYLD_H diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp index f4788816d4e..af76056af68 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp @@ -1,4 +1,4 @@ -//===-- HexagonDYLDRendezvous.cpp -------------------------------*- C++ -*-===// +//===-- HexagonDYLDRendezvous.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h index 70fc12b7fab..5707f8858f6 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_HexagonDYLDRendezvous_H_ -#define liblldb_HexagonDYLDRendezvous_H_ +#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_HEXAGONDYLDRENDEZVOUS_H +#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_HEXAGONDYLDRENDEZVOUS_H #include #include @@ -243,4 +243,4 @@ protected: bool FindMetadata(const char *name, PThreadField field, uint32_t &value); }; -#endif // liblldb_HexagonDYLDRendezvous_H_ +#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_HEXAGONDYLDRENDEZVOUS_H diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt index 515c82dcaca..c470bc6e833 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt @@ -11,6 +11,7 @@ add_lldb_library(lldbPluginDynamicLoaderMacOSXDYLD PLUGIN lldbSymbol lldbTarget lldbUtility + lldbPluginTypeSystemClang LINK_COMPONENTS Support ) diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp index 70064a57d2f..7b0d6f343c0 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp @@ -1,4 +1,4 @@ -//===-- DynamicLoaderDarwin.cpp -----------------------------*- C++ -*-===// +//===-- DynamicLoaderDarwin.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -16,7 +16,6 @@ #include "lldb/Core/Section.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Host/FileSystem.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/ABI.h" @@ -32,6 +31,7 @@ #include "lldb/Utility/State.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN #ifdef ENABLE_DEBUG_PRINTF @@ -383,9 +383,10 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo( mh->GetValueForKey("filetype")->GetAsInteger()->GetValue(); if (image->HasKey("min_version_os_name")) { - std::string os_name = image->GetValueForKey("min_version_os_name") - ->GetAsString() - ->GetValue(); + std::string os_name = + std::string(image->GetValueForKey("min_version_os_name") + ->GetAsString() + ->GetValue()); if (os_name == "macosx") image_infos[i].os_type = llvm::Triple::MacOSX; else if (os_name == "ios" || os_name == "iphoneos") @@ -399,13 +400,22 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo( else if (os_name == "maccatalyst") { image_infos[i].os_type = llvm::Triple::IOS; image_infos[i].os_env = llvm::Triple::MacABI; + } else if (os_name == "iossimulator") { + image_infos[i].os_type = llvm::Triple::IOS; + image_infos[i].os_env = llvm::Triple::Simulator; + } else if (os_name == "tvossimulator") { + image_infos[i].os_type = llvm::Triple::TvOS; + image_infos[i].os_env = llvm::Triple::Simulator; + } else if (os_name == "watchossimulator") { + image_infos[i].os_type = llvm::Triple::WatchOS; + image_infos[i].os_env = llvm::Triple::Simulator; } } if (image->HasKey("min_version_os_sdk")) { image_infos[i].min_version_os_sdk = - image->GetValueForKey("min_version_os_sdk") - ->GetAsString() - ->GetValue(); + std::string(image->GetValueForKey("min_version_os_sdk") + ->GetAsString() + ->GetValue()); } // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't @@ -671,19 +681,17 @@ bool DynamicLoaderDarwin::AddModulesUsingImageInfos( loaded_module_list.AppendIfNeeded(image_module_sp); } - // macCataylst support: - // Update the module's platform with the DYLD info. + // To support macCatalyst and legacy iOS simulator, + // update the module's platform with the DYLD info. ArchSpec dyld_spec = image_infos[idx].GetArchitecture(); - if (dyld_spec.GetTriple().getOS() == llvm::Triple::IOS && - dyld_spec.GetTriple().getEnvironment() == llvm::Triple::MacABI) { + auto &dyld_triple = dyld_spec.GetTriple(); + if ((dyld_triple.getEnvironment() == llvm::Triple::MacABI && + dyld_triple.getOS() == llvm::Triple::IOS) || + (dyld_triple.getEnvironment() == llvm::Triple::Simulator && + (dyld_triple.getOS() == llvm::Triple::IOS || + dyld_triple.getOS() == llvm::Triple::TvOS || + dyld_triple.getOS() == llvm::Triple::WatchOS))) image_module_sp->MergeArchitecture(dyld_spec); - const auto &target_triple = target.GetArchitecture().GetTriple(); - // If dyld reports the process as being loaded as MACCATALYST, - // force-update the target's architecture to MACCATALYST. - if (!(target_triple.getOS() == llvm::Triple::IOS && - target_triple.getEnvironment() == llvm::Triple::MacABI)) - target.SetArchitecture(dyld_spec); - } } } @@ -745,13 +753,23 @@ lldb_private::ArchSpec DynamicLoaderDarwin::ImageInfo::GetArchitecture() const { // Update the module's platform with the DYLD info. lldb_private::ArchSpec arch_spec(lldb_private::eArchTypeMachO, header.cputype, header.cpusubtype); - if (os_type == llvm::Triple::IOS && os_env == llvm::Triple::MacABI) { - llvm::Triple triple(llvm::Twine("x86_64-apple-ios") + min_version_os_sdk + - "-macabi"); + if (os_env == llvm::Triple::MacABI && os_type == llvm::Triple::IOS) { + llvm::Triple triple(llvm::Twine(arch_spec.GetArchitectureName()) + + "-apple-ios" + min_version_os_sdk + "-macabi"); ArchSpec maccatalyst_spec(triple); if (arch_spec.IsCompatibleMatch(maccatalyst_spec)) arch_spec.MergeFrom(maccatalyst_spec); } + if (os_env == llvm::Triple::Simulator && + (os_type == llvm::Triple::IOS || os_type == llvm::Triple::TvOS || + os_type == llvm::Triple::WatchOS)) { + llvm::Triple triple(llvm::Twine(arch_spec.GetArchitectureName()) + + "-apple-" + llvm::Triple::getOSTypeName(os_type) + + min_version_os_sdk + "-simulator"); + ArchSpec sim_spec(triple); + if (arch_spec.IsCompatibleMatch(sim_spec)) + arch_spec.MergeFrom(sim_spec); + } return arch_spec; } @@ -838,8 +856,8 @@ DynamicLoaderDarwin::GetStepThroughTrampolinePlan(Thread &thread, std::vector
addresses; if (current_symbol->IsTrampoline()) { - ConstString trampoline_name = current_symbol->GetMangled().GetName( - current_symbol->GetLanguage(), Mangled::ePreferMangled); + ConstString trampoline_name = + current_symbol->GetMangled().GetName(Mangled::ePreferMangled); if (trampoline_name) { const ModuleList &images = target_sp->GetImages(); @@ -980,8 +998,8 @@ DynamicLoaderDarwin::GetStepThroughTrampolinePlan(Thread &thread, void DynamicLoaderDarwin::FindEquivalentSymbols( lldb_private::Symbol *original_symbol, lldb_private::ModuleList &images, lldb_private::SymbolContextList &equivalent_symbols) { - ConstString trampoline_name = original_symbol->GetMangled().GetName( - original_symbol->GetLanguage(), Mangled::ePreferMangled); + ConstString trampoline_name = + original_symbol->GetMangled().GetName(Mangled::ePreferMangled); if (!trampoline_name) return; @@ -1072,8 +1090,8 @@ DynamicLoaderDarwin::GetThreadLocalData(const lldb::ModuleSP module_sp, } StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(0); if (frame_sp) { - ClangASTContext *clang_ast_context = - ClangASTContext::GetScratch(target); + TypeSystemClang *clang_ast_context = + TypeSystemClang::GetScratch(target); if (!clang_ast_context) return LLDB_INVALID_ADDRESS; diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h b/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h index ea7a900d39c..4c9a27f0853 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DynamicLoaderDarwin_h_ -#define liblldb_DynamicLoaderDarwin_h_ +#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWIN_H +#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWIN_H #include #include @@ -238,9 +238,10 @@ protected: mutable std::recursive_mutex m_mutex; private: - DISALLOW_COPY_AND_ASSIGN(DynamicLoaderDarwin); + DynamicLoaderDarwin(const DynamicLoaderDarwin &) = delete; + const DynamicLoaderDarwin &operator=(const DynamicLoaderDarwin &) = delete; }; } // namespace lldb_private -#endif // liblldb_DynamicLoaderDarwin_h_ +#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWIN_H diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp b/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp index fd7d94f4598..7bc14061ffe 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp @@ -1,4 +1,4 @@ -//===-- DynamicLoaderMacOS.cpp -----------------------------*- C++ -*-===// +//===-- DynamicLoaderMacOS.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -11,7 +11,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Target/ABI.h" @@ -24,6 +23,8 @@ #include "DynamicLoaderDarwin.h" #include "DynamicLoaderMacOS.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" + using namespace lldb; using namespace lldb_private; @@ -222,8 +223,8 @@ bool DynamicLoaderMacOS::NotifyBreakpointHit(void *baton, // Build up the value array to store the three arguments given above, then // get the values from the ABI: - ClangASTContext *clang_ast_context = - ClangASTContext::GetScratch(process->GetTarget()); + TypeSystemClang *clang_ast_context = + TypeSystemClang::GetScratch(process->GetTarget()); if (!clang_ast_context) return false; @@ -481,8 +482,8 @@ bool DynamicLoaderMacOS::GetSharedCacheInformation( info_dict->HasKey("shared_cache_base_address")) { base_address = info_dict->GetValueForKey("shared_cache_base_address") ->GetIntegerValue(LLDB_INVALID_ADDRESS); - std::string uuid_str = - info_dict->GetValueForKey("shared_cache_uuid")->GetStringValue(); + std::string uuid_str = std::string( + info_dict->GetValueForKey("shared_cache_uuid")->GetStringValue()); if (!uuid_str.empty()) uuid.SetFromStringRef(uuid_str); if (!info_dict->GetValueForKey("no_shared_cache")->GetBooleanValue()) diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h b/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h index 9ccb3bcbde1..12e294e89e8 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h @@ -14,8 +14,8 @@ // array of load addresses for solibs loaded and unloaded. The SPI will tell us // about both dyld and the executable, in addition to all of the usual solibs. -#ifndef liblldb_DynamicLoaderMacOS_h_ -#define liblldb_DynamicLoaderMacOS_h_ +#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERMACOS_H +#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERMACOS_H #include #include @@ -105,7 +105,8 @@ protected: // the "reason:exec" annotation. private: - DISALLOW_COPY_AND_ASSIGN(DynamicLoaderMacOS); + DynamicLoaderMacOS(const DynamicLoaderMacOS &) = delete; + const DynamicLoaderMacOS &operator=(const DynamicLoaderMacOS &) = delete; }; -#endif // liblldb_DynamicLoaderMacOS_h_ +#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERMACOS_H diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp index 253215b60c6..d425b358723 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp @@ -1,4 +1,4 @@ -//===-- DynamicLoaderMacOSXDYLD.cpp -----------------------------*- C++ -*-===// +//===-- DynamicLoaderMacOSXDYLD.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,13 +6,17 @@ // //===----------------------------------------------------------------------===// +#include "DynamicLoaderMacOSXDYLD.h" +#include "DynamicLoaderDarwin.h" +#include "DynamicLoaderMacOS.h" +#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/ABI.h" @@ -26,11 +30,6 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" -#include "DynamicLoaderDarwin.h" -#include "DynamicLoaderMacOSXDYLD.h" - -#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" - //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN #ifdef ENABLE_DEBUG_PRINTF #include @@ -48,6 +47,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(DynamicLoaderMacOSXDYLD) + // Create an instance of this class. This function is filled into the plugin // info class that gets handed out by the plugin factory and allows the lldb to // instantiate an instance of this class. @@ -341,8 +342,8 @@ bool DynamicLoaderMacOSXDYLD::NotifyBreakpointHit( // Build up the value array to store the three arguments given above, then // get the values from the ABI: - ClangASTContext *clang_ast_context = - ClangASTContext::GetScratch(process->GetTarget()); + TypeSystemClang *clang_ast_context = + TypeSystemClang::GetScratch(process->GetTarget()); if (!clang_ast_context) return false; @@ -480,17 +481,17 @@ bool DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure() { offset = 0; m_dyld_all_image_infos.version = data.GetU32(&offset); m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset); - m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset); - m_dyld_all_image_infos.notification = data.GetPointer(&offset); + m_dyld_all_image_infos.dylib_info_addr = data.GetAddress(&offset); + m_dyld_all_image_infos.notification = data.GetAddress(&offset); m_dyld_all_image_infos.processDetachedFromSharedRegion = data.GetU8(&offset); m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset); // Adjust for padding. offset += addr_size - 2; - m_dyld_all_image_infos.dyldImageLoadAddress = data.GetPointer(&offset); + m_dyld_all_image_infos.dyldImageLoadAddress = data.GetAddress(&offset); if (m_dyld_all_image_infos.version >= 11) { offset += addr_size * 8; - uint64_t dyld_all_image_infos_addr = data.GetPointer(&offset); + uint64_t dyld_all_image_infos_addr = data.GetAddress(&offset); // When we started, we were given the actual address of the // all_image_infos struct (probably via TASK_DYLD_INFO) in memory - @@ -670,9 +671,9 @@ bool DynamicLoaderMacOSXDYLD::ReadImageInfos( for (size_t i = 0; i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset); i++) { - image_infos[i].address = info_data_ref.GetPointer(&info_data_offset); - lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset); - image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset); + image_infos[i].address = info_data_ref.GetAddress(&info_data_offset); + lldb::addr_t path_addr = info_data_ref.GetAddress(&info_data_offset); + image_infos[i].mod_date = info_data_ref.GetAddress(&info_data_offset); char raw_path[PATH_MAX]; m_process->ReadCStringFromMemory(path_addr, raw_path, sizeof(raw_path), @@ -1121,9 +1122,11 @@ bool DynamicLoaderMacOSXDYLD::GetSharedCacheInformation( void DynamicLoaderMacOSXDYLD::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance); + DynamicLoaderMacOS::Initialize(); } void DynamicLoaderMacOSXDYLD::Terminate() { + DynamicLoaderMacOS::Terminate(); PluginManager::UnregisterPlugin(CreateInstance); } diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h b/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h index 00b2ebf373d..21bf5875dc1 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h @@ -17,8 +17,8 @@ // dyld SPI functions to get the same information without reading internal dyld // data structures. -#ifndef liblldb_DynamicLoaderMacOSXDYLD_h_ -#define liblldb_DynamicLoaderMacOSXDYLD_h_ +#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERMACOSXDYLD_H +#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERMACOSXDYLD_H #include #include @@ -169,7 +169,9 @@ protected: bool m_process_image_addr_is_all_images_infos; private: - DISALLOW_COPY_AND_ASSIGN(DynamicLoaderMacOSXDYLD); + DynamicLoaderMacOSXDYLD(const DynamicLoaderMacOSXDYLD &) = delete; + const DynamicLoaderMacOSXDYLD & + operator=(const DynamicLoaderMacOSXDYLD &) = delete; }; -#endif // liblldb_DynamicLoaderMacOSXDYLD_h_ +#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERMACOSXDYLD_H diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp index 9ec8794a4e2..15b3805003a 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp @@ -1,4 +1,4 @@ -//===-- DYLDRendezvous.cpp --------------------------------------*- C++ -*-===// +//===-- DYLDRendezvous.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -419,7 +419,6 @@ bool DYLDRendezvous::SOEntryIsMainExecutable(const SOEntry &entry) { switch (triple.getOS()) { case llvm::Triple::FreeBSD: case llvm::Triple::NetBSD: - case llvm::Triple::OpenBSD: return entry.file_spec == m_exe_file_spec; case llvm::Triple::Linux: if (triple.isAndroid()) diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h index 536eeeaaf33..b028120eb0d 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Rendezvous_H_ -#define liblldb_Rendezvous_H_ +#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_POSIX_DYLD_DYLDRENDEZVOUS_H +#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_POSIX_DYLD_DYLDRENDEZVOUS_H #include #include diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index 580629149f0..ac60af5336e 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -1,4 +1,4 @@ -//===-- DynamicLoaderPOSIXDYLD.cpp ------------------------------*- C++ -*-===// +//===-- DynamicLoaderPOSIXDYLD.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -29,6 +29,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE_ADV(DynamicLoaderPOSIXDYLD, DynamicLoaderPosixDYLD) + void DynamicLoaderPOSIXDYLD::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance); @@ -60,8 +62,7 @@ DynamicLoader *DynamicLoaderPOSIXDYLD::CreateInstance(Process *process, process->GetTarget().GetArchitecture().GetTriple(); if (triple_ref.getOS() == llvm::Triple::FreeBSD || triple_ref.getOS() == llvm::Triple::Linux || - triple_ref.getOS() == llvm::Triple::NetBSD || - triple_ref.getOS() == llvm::Triple::OpenBSD) + triple_ref.getOS() == llvm::Triple::NetBSD) create = true; } diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h b/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h index 0630d1eb11d..a7fcdfbadea 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DynamicLoaderPOSIXDYLD_h_ -#define liblldb_DynamicLoaderPOSIXDYLD_h_ +#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_POSIX_DYLD_DYNAMICLOADERPOSIXDYLD_H +#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_POSIX_DYLD_DYNAMICLOADERPOSIXDYLD_H #include #include @@ -136,7 +136,7 @@ protected: void LoadVDSO(); - // Loading an interpreter module (if present) assumming m_interpreter_base + // Loading an interpreter module (if present) assuming m_interpreter_base // already points to its base address. lldb::ModuleSP LoadInterpreterModule(); @@ -159,7 +159,9 @@ protected: bool AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override; private: - DISALLOW_COPY_AND_ASSIGN(DynamicLoaderPOSIXDYLD); + DynamicLoaderPOSIXDYLD(const DynamicLoaderPOSIXDYLD &) = delete; + const DynamicLoaderPOSIXDYLD & + operator=(const DynamicLoaderPOSIXDYLD &) = delete; }; -#endif // liblldb_DynamicLoaderPOSIXDYLD_h_ +#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_POSIX_DYLD_DYNAMICLOADERPOSIXDYLD_H diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp index 6bc951c4d35..48762fe6e0c 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp @@ -1,4 +1,4 @@ -//===-- DynamicLoaderStatic.cpp ---------------------------------*- C++ -*-===// +//===-- DynamicLoaderStatic.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -17,6 +17,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(DynamicLoaderStatic) + // Create an instance of this class. This function is filled into the plugin // info class that gets handed out by the plugin factory and allows the lldb to // instantiate an instance of this class. @@ -27,8 +29,19 @@ DynamicLoader *DynamicLoaderStatic::CreateInstance(Process *process, const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple(); const llvm::Triple::OSType os_type = triple_ref.getOS(); - if ((os_type == llvm::Triple::UnknownOS)) - create = true; + const llvm::Triple::ArchType arch_type = triple_ref.getArch(); + if (os_type == llvm::Triple::UnknownOS) { + // The WASM and Hexagon plugin check the ArchType rather than the OSType, + // so explicitly reject those here. + switch(arch_type) { + case llvm::Triple::hexagon: + case llvm::Triple::wasm32: + case llvm::Triple::wasm64: + break; + default: + create = true; + } + } } if (!create) { diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h index fa9aded7286..ce78804f9a9 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DynamicLoaderStatic_h_ -#define liblldb_DynamicLoaderStatic_h_ +#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_STATIC_DYNAMICLOADERSTATIC_H +#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_STATIC_DYNAMICLOADERSTATIC_H #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/Process.h" @@ -53,7 +53,8 @@ public: private: void LoadAllImagesAtFileAddresses(); - DISALLOW_COPY_AND_ASSIGN(DynamicLoaderStatic); + DynamicLoaderStatic(const DynamicLoaderStatic &) = delete; + const DynamicLoaderStatic &operator=(const DynamicLoaderStatic &) = delete; }; -#endif // liblldb_DynamicLoaderStatic_h_ +#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_STATIC_DYNAMICLOADERSTATIC_H diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp index 25ab30e9db9..7f9504b9b3a 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp @@ -1,5 +1,4 @@ -//===-- DynamicLoaderWindowsDYLD.cpp --------------------------------*- C++ -//-*-===// +//===-- DynamicLoaderWindowsDYLD.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -24,6 +23,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(DynamicLoaderWindowsDYLD) + DynamicLoaderWindowsDYLD::DynamicLoaderWindowsDYLD(Process *process) : DynamicLoader(process) {} @@ -191,9 +192,8 @@ DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread, // Max size of an instruction in x86 is 15 bytes. AddressRange range(pc, 2 * 15); - ExecutionContext exe_ctx(m_process->GetTarget()); DisassemblerSP disassembler_sp = Disassembler::DisassembleRange( - arch, nullptr, nullptr, exe_ctx, range, true); + arch, nullptr, nullptr, m_process->GetTarget(), range, true); if (!disassembler_sp) { return ThreadPlanSP(); } @@ -212,6 +212,7 @@ DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread, auto first_insn = insn_list->GetInstructionAtIndex(0); auto second_insn = insn_list->GetInstructionAtIndex(1); + ExecutionContext exe_ctx(m_process->GetTarget()); if (first_insn == nullptr || second_insn == nullptr || strcmp(first_insn->GetMnemonic(&exe_ctx), "jmpl") != 0 || strcmp(second_insn->GetMnemonic(&exe_ctx), "nop") != 0) { diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h index 100689a6312..502a4c160dd 100644 --- a/gnu/llvm/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Plugins_Process_Windows_DynamicLoaderWindowsDYLD_h_ -#define liblldb_Plugins_Process_Windows_DynamicLoaderWindowsDYLD_h_ +#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_WINDOWS_DYLD_DYNAMICLOADERWINDOWSDYLD_H +#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_WINDOWS_DYLD_DYNAMICLOADERWINDOWSDYLD_H #include "lldb/Target/DynamicLoader.h" #include "lldb/lldb-forward.h" @@ -51,4 +51,4 @@ private: } // namespace lldb_private -#endif // liblldb_Plugins_Process_Windows_DynamicLoaderWindowsDYLD_h_ +#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_WINDOWS_DYLD_DYNAMICLOADERWINDOWSDYLD_H diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/wasm-DYLD/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/DynamicLoader/wasm-DYLD/CMakeLists.txt new file mode 100644 index 00000000000..a4a4ac7b44e --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/wasm-DYLD/CMakeLists.txt @@ -0,0 +1,9 @@ +add_lldb_library(lldbPluginDynamicLoaderWasmDYLD PLUGIN + DynamicLoaderWasmDYLD.cpp + + LINK_LIBS + lldbCore + lldbTarget + LINK_COMPONENTS + Support + ) diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp b/gnu/llvm/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp new file mode 100644 index 00000000000..ae7e011eaa5 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp @@ -0,0 +1,70 @@ +//===-- DynamicLoaderWasmDYLD.cpp -----------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "DynamicLoaderWasmDYLD.h" + +#include "Plugins/ObjectFile/wasm/ObjectFileWasm.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Section.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/Log.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::wasm; + +LLDB_PLUGIN_DEFINE(DynamicLoaderWasmDYLD) + +DynamicLoaderWasmDYLD::DynamicLoaderWasmDYLD(Process *process) + : DynamicLoader(process) {} + +void DynamicLoaderWasmDYLD::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance); +} + +ConstString DynamicLoaderWasmDYLD::GetPluginNameStatic() { + static ConstString g_plugin_name("wasm-dyld"); + return g_plugin_name; +} + +const char *DynamicLoaderWasmDYLD::GetPluginDescriptionStatic() { + return "Dynamic loader plug-in that watches for shared library " + "loads/unloads in WebAssembly engines."; +} + +DynamicLoader *DynamicLoaderWasmDYLD::CreateInstance(Process *process, + bool force) { + bool should_create = force; + if (!should_create) { + should_create = + (process->GetTarget().GetArchitecture().GetTriple().getArch() == + llvm::Triple::wasm32); + } + + if (should_create) + return new DynamicLoaderWasmDYLD(process); + + return nullptr; +} + +void DynamicLoaderWasmDYLD::DidAttach() { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + LLDB_LOGF(log, "DynamicLoaderWasmDYLD::%s()", __FUNCTION__); + + // Ask the process for the list of loaded WebAssembly modules. + auto error = m_process->LoadModules(); + LLDB_LOG_ERROR(log, std::move(error), "Couldn't load modules: {0}"); +} + +ThreadPlanSP DynamicLoaderWasmDYLD::GetStepThroughTrampolinePlan(Thread &thread, + bool stop) { + return ThreadPlanSP(); +} diff --git a/gnu/llvm/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h b/gnu/llvm/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h new file mode 100644 index 00000000000..4a18972bb84 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h @@ -0,0 +1,48 @@ +//===-- DynamicLoaderWasmDYLD.h ---------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Plugins_DynamicLoaderWasmDYLD_h_ +#define liblldb_Plugins_DynamicLoaderWasmDYLD_h_ + +#include "lldb/Target/DynamicLoader.h" + +namespace lldb_private { +namespace wasm { + +class DynamicLoaderWasmDYLD : public DynamicLoader { +public: + DynamicLoaderWasmDYLD(Process *process); + + static void Initialize(); + static void Terminate() {} + + static ConstString GetPluginNameStatic(); + static const char *GetPluginDescriptionStatic(); + + static DynamicLoader *CreateInstance(Process *process, bool force); + + /// DynamicLoader + /// \{ + void DidAttach() override; + void DidLaunch() override {} + Status CanLoadImage() override { return Status(); } + lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, + bool stop) override; + /// \} + + /// PluginInterface protocol. + /// \{ + ConstString GetPluginName() override { return GetPluginNameStatic(); } + uint32_t GetPluginVersion() override { return 1; } + /// \} +}; + +} // namespace wasm +} // namespace lldb_private + +#endif // liblldb_Plugins_DynamicLoaderWasmDYLD_h_ diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp index 77bb9544ea4..39ba5f4e9e4 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp @@ -1,4 +1,4 @@ -//===-- ASTResultSynthesizer.cpp --------------------------------*- C++ -*-===// +//===-- ASTResultSynthesizer.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,10 +8,10 @@ #include "ASTResultSynthesizer.h" +#include "ClangASTImporter.h" #include "ClangPersistentVariables.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangASTImporter.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Target/Target.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" @@ -248,48 +248,37 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body, // For Lvalues // // - In AST result synthesis (here!) the expression E is transformed into an - // initialization - // T *$__lldb_expr_result_ptr = &E. + // initialization T *$__lldb_expr_result_ptr = &E. // // - In structure allocation, a pointer-sized slot is allocated in the - // struct that is to be - // passed into the expression. + // struct that is to be passed into the expression. // // - In IR transformations, reads and writes to $__lldb_expr_result_ptr are - // redirected at - // an entry in the struct ($__lldb_arg) passed into the expression. - // (Other persistent - // variables are treated similarly, having been materialized as - // references, but in those - // cases the value of the reference itself is never modified.) + // redirected at an entry in the struct ($__lldb_arg) passed into the + // expression. (Other persistent variables are treated similarly, having + // been materialized as references, but in those cases the value of the + // reference itself is never modified.) // // - During materialization, $0 (the result persistent variable) is ignored. // // - During dematerialization, $0 is marked up as a load address with value - // equal to the - // contents of the structure entry. + // equal to the contents of the structure entry. // // For Rvalues // // - In AST result synthesis the expression E is transformed into an - // initialization - // static T $__lldb_expr_result = E. + // initialization static T $__lldb_expr_result = E. // // - In structure allocation, a pointer-sized slot is allocated in the - // struct that is to be - // passed into the expression. + // struct that is to be passed into the expression. // // - In IR transformations, an instruction is inserted at the beginning of - // the function to - // dereference the pointer resident in the slot. Reads and writes to - // $__lldb_expr_result - // are redirected at that dereferenced version. Guard variables for the - // static variable - // are excised. + // the function to dereference the pointer resident in the slot. Reads and + // writes to $__lldb_expr_result are redirected at that dereferenced + // version. Guard variables for the static variable are excised. // // - During materialization, $0 (the result persistent variable) is - // populated with the location - // of a newly-allocated area of memory. + // populated with the location of a newly-allocated area of memory. // // - During dematerialization, $0 is ignored. @@ -325,7 +314,8 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body, else result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result_ptr"); - m_sema->RequireCompleteType(SourceLocation(), expr_qual_type, + m_sema->RequireCompleteType(last_expr->getSourceRange().getBegin(), + expr_qual_type, clang::diag::err_incomplete_type); QualType ptr_qual_type; @@ -453,13 +443,13 @@ void ASTResultSynthesizer::CommitPersistentDecls() { return; auto *persistent_vars = llvm::cast(state); - ClangASTContext *scratch_ctx = ClangASTContext::GetScratch(m_target); + TypeSystemClang *scratch_ctx = TypeSystemClang::GetScratch(m_target); for (clang::NamedDecl *decl : m_decls) { StringRef name = decl->getName(); ConstString name_cs(name.str().c_str()); - Decl *D_scratch = m_target.GetClangASTImporter()->DeportDecl( + Decl *D_scratch = persistent_vars->GetClangASTImporter()->DeportDecl( &scratch_ctx->getASTContext(), decl); if (!D_scratch) { diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h index 0b0f3b97705..9de823bc75a 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h @@ -6,13 +6,20 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ASTResultSynthesizer_h_ -#define liblldb_ASTResultSynthesizer_h_ +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTRESULTSYNTHESIZER_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTRESULTSYNTHESIZER_H -#include "lldb/Core/ClangForward.h" #include "lldb/Target/Target.h" #include "clang/Sema/SemaConsumer.h" +namespace clang { +class CompoundStmt; +class DeclContext; +class NamedDecl; +class ObjCMethodDecl; +class TypeDecl; +} // namespace clang + namespace lldb_private { /// \class ASTResultSynthesizer ASTResultSynthesizer.h @@ -163,4 +170,4 @@ private: } // namespace lldb_private -#endif // liblldb_ASTResultSynthesizer_h_ +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTRESULTSYNTHESIZER_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp index a164d48ae3e..40f0de40da5 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp @@ -1,4 +1,4 @@ -//===-- ASTStructExtractor.cpp ----------------------------------*- C++ -*-===// +//===-- ASTStructExtractor.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h index 078cf095975..c285f640889 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h @@ -6,13 +6,12 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ASTStructExtractor_h_ -#define liblldb_ASTStructExtractor_h_ +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTSTRUCTEXTRACTOR_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTSTRUCTEXTRACTOR_H #include "ClangExpressionVariable.h" #include "ClangFunctionCaller.h" -#include "lldb/Core/ClangForward.h" #include "clang/Sema/SemaConsumer.h" namespace lldb_private { @@ -129,4 +128,4 @@ private: } // namespace lldb_private -#endif // liblldb_ASTStructExtractor_h_ +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTSTRUCTEXTRACTOR_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp index bbdf4e31c5a..1e438ed9d73 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp @@ -1,4 +1,4 @@ -//===-- ASTUtils.cpp --------------------------------------------*- C++ -*-===// +//===-- ASTUtils.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h index d429e8c3855..3787c572d45 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h @@ -6,9 +6,10 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ASTUtils_h_ -#define liblldb_ASTUtils_h_ +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H +#include "clang/Basic/Module.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/MultiplexExternalSemaSource.h" #include "clang/Sema/Sema.h" @@ -71,7 +72,7 @@ public: return m_Source->getModule(ID); } - llvm::Optional + llvm::Optional getSourceDescriptor(unsigned ID) override { return m_Source->getSourceDescriptor(ID); } @@ -576,4 +577,4 @@ public: }; } // namespace lldb_private -#endif // liblldb_ASTUtils_h_ +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/CMakeLists.txt index e92d089cab1..69696b9aa76 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/CMakeLists.txt @@ -2,25 +2,31 @@ if(NOT LLDB_BUILT_STANDALONE) set(tablegen_deps intrinsics_gen) endif() -add_lldb_library(lldbPluginExpressionParserClang PLUGIN +add_lldb_library(lldbPluginExpressionParserClang ASTResultSynthesizer.cpp ASTStructExtractor.cpp ASTUtils.cpp + ClangASTImporter.cpp + ClangASTMetadata.cpp ClangASTSource.cpp ClangDeclVendor.cpp ClangExpressionDeclMap.cpp ClangExpressionParser.cpp ClangExpressionSourceCode.cpp ClangExpressionVariable.cpp + ClangExternalASTSourceCallbacks.cpp ClangFunctionCaller.cpp ClangHost.cpp ClangModulesDeclVendor.cpp ClangPersistentVariables.cpp ClangUserExpression.cpp + ClangUtil.cpp ClangUtilityFunction.cpp CppModuleConfiguration.cpp + CxxModuleHandler.cpp IRForTarget.cpp IRDynamicChecks.cpp + NameSearchContext.cpp DEPENDS ${tablegen_deps} @@ -35,6 +41,9 @@ add_lldb_library(lldbPluginExpressionParserClang PLUGIN lldbUtility lldbPluginCPlusPlusLanguage lldbPluginCPPRuntime + lldbPluginObjCRuntime + lldbPluginRenderScriptRuntime + lldbPluginTypeSystemClang CLANG_LIBS clangAST clangCodeGen diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp new file mode 100644 index 00000000000..ac16738933a --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp @@ -0,0 +1,1212 @@ +//===-- ClangASTImporter.cpp ----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/Module.h" +#include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/Log.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclObjC.h" +#include "clang/Sema/Lookup.h" +#include "clang/Sema/Sema.h" +#include "llvm/Support/raw_ostream.h" + +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" +#include "Plugins/ExpressionParser/Clang/ClangASTSource.h" +#include "Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" + +#include + +using namespace lldb_private; +using namespace clang; + +CompilerType ClangASTImporter::CopyType(TypeSystemClang &dst_ast, + const CompilerType &src_type) { + clang::ASTContext &dst_clang_ast = dst_ast.getASTContext(); + + TypeSystemClang *src_ast = + llvm::dyn_cast_or_null(src_type.GetTypeSystem()); + if (!src_ast) + return CompilerType(); + + clang::ASTContext &src_clang_ast = src_ast->getASTContext(); + + clang::QualType src_qual_type = ClangUtil::GetQualType(src_type); + + ImporterDelegateSP delegate_sp(GetDelegate(&dst_clang_ast, &src_clang_ast)); + if (!delegate_sp) + return CompilerType(); + + ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, &dst_clang_ast); + + llvm::Expected ret_or_error = delegate_sp->Import(src_qual_type); + if (!ret_or_error) { + Log *log = + lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + LLDB_LOG_ERROR(log, ret_or_error.takeError(), + "Couldn't import type: {0}"); + return CompilerType(); + } + + lldb::opaque_compiler_type_t dst_clang_type = ret_or_error->getAsOpaquePtr(); + + if (dst_clang_type) + return CompilerType(&dst_ast, dst_clang_type); + return CompilerType(); +} + +clang::Decl *ClangASTImporter::CopyDecl(clang::ASTContext *dst_ast, + clang::Decl *decl) { + ImporterDelegateSP delegate_sp; + + clang::ASTContext *src_ast = &decl->getASTContext(); + delegate_sp = GetDelegate(dst_ast, src_ast); + + ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, dst_ast); + + if (!delegate_sp) + return nullptr; + + llvm::Expected result = delegate_sp->Import(decl); + if (!result) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + LLDB_LOG_ERROR(log, result.takeError(), "Couldn't import decl: {0}"); + if (log) { + lldb::user_id_t user_id = LLDB_INVALID_UID; + ClangASTMetadata *metadata = GetDeclMetadata(decl); + if (metadata) + user_id = metadata->GetUserID(); + + if (NamedDecl *named_decl = dyn_cast(decl)) + LLDB_LOG(log, + " [ClangASTImporter] WARNING: Failed to import a {0} " + "'{1}', metadata {2}", + decl->getDeclKindName(), named_decl->getNameAsString(), + user_id); + else + LLDB_LOG(log, + " [ClangASTImporter] WARNING: Failed to import a {0}, " + "metadata {1}", + decl->getDeclKindName(), user_id); + } + return nullptr; + } + + return *result; +} + +class DeclContextOverride { +private: + struct Backup { + clang::DeclContext *decl_context; + clang::DeclContext *lexical_decl_context; + }; + + llvm::DenseMap m_backups; + + void OverrideOne(clang::Decl *decl) { + if (m_backups.find(decl) != m_backups.end()) { + return; + } + + m_backups[decl] = {decl->getDeclContext(), decl->getLexicalDeclContext()}; + + decl->setDeclContext(decl->getASTContext().getTranslationUnitDecl()); + decl->setLexicalDeclContext(decl->getASTContext().getTranslationUnitDecl()); + } + + bool ChainPassesThrough( + clang::Decl *decl, clang::DeclContext *base, + clang::DeclContext *(clang::Decl::*contextFromDecl)(), + clang::DeclContext *(clang::DeclContext::*contextFromContext)()) { + for (DeclContext *decl_ctx = (decl->*contextFromDecl)(); decl_ctx; + decl_ctx = (decl_ctx->*contextFromContext)()) { + if (decl_ctx == base) { + return true; + } + } + + return false; + } + + clang::Decl *GetEscapedChild(clang::Decl *decl, + clang::DeclContext *base = nullptr) { + if (base) { + // decl's DeclContext chains must pass through base. + + if (!ChainPassesThrough(decl, base, &clang::Decl::getDeclContext, + &clang::DeclContext::getParent) || + !ChainPassesThrough(decl, base, &clang::Decl::getLexicalDeclContext, + &clang::DeclContext::getLexicalParent)) { + return decl; + } + } else { + base = clang::dyn_cast(decl); + + if (!base) { + return nullptr; + } + } + + if (clang::DeclContext *context = + clang::dyn_cast(decl)) { + for (clang::Decl *decl : context->decls()) { + if (clang::Decl *escaped_child = GetEscapedChild(decl)) { + return escaped_child; + } + } + } + + return nullptr; + } + + void Override(clang::Decl *decl) { + if (clang::Decl *escaped_child = GetEscapedChild(decl)) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + LLDB_LOG(log, + " [ClangASTImporter] DeclContextOverride couldn't " + "override ({0}Decl*){1} - its child ({2}Decl*){3} escapes", + decl->getDeclKindName(), decl, escaped_child->getDeclKindName(), + escaped_child); + lldbassert(0 && "Couldn't override!"); + } + + OverrideOne(decl); + } + +public: + DeclContextOverride() {} + + void OverrideAllDeclsFromContainingFunction(clang::Decl *decl) { + for (DeclContext *decl_context = decl->getLexicalDeclContext(); + decl_context; decl_context = decl_context->getLexicalParent()) { + DeclContext *redecl_context = decl_context->getRedeclContext(); + + if (llvm::isa(redecl_context) && + llvm::isa(redecl_context->getLexicalParent())) { + for (clang::Decl *child_decl : decl_context->decls()) { + Override(child_decl); + } + } + } + } + + ~DeclContextOverride() { + for (const std::pair &backup : m_backups) { + backup.first->setDeclContext(backup.second.decl_context); + backup.first->setLexicalDeclContext(backup.second.lexical_decl_context); + } + } +}; + +namespace { +/// Completes all imported TagDecls at the end of the scope. +/// +/// While in a CompleteTagDeclsScope, every decl that could be completed will +/// be completed at the end of the scope (including all Decls that are +/// imported while completing the original Decls). +class CompleteTagDeclsScope : public ClangASTImporter::NewDeclListener { + ClangASTImporter::ImporterDelegateSP m_delegate; + llvm::SmallVector m_decls_to_complete; + llvm::SmallPtrSet m_decls_already_completed; + clang::ASTContext *m_dst_ctx; + clang::ASTContext *m_src_ctx; + ClangASTImporter &importer; + +public: + /// Constructs a CompleteTagDeclsScope. + /// \param importer The ClangASTImporter that we should observe. + /// \param dst_ctx The ASTContext to which Decls are imported. + /// \param src_ctx The ASTContext from which Decls are imported. + explicit CompleteTagDeclsScope(ClangASTImporter &importer, + clang::ASTContext *dst_ctx, + clang::ASTContext *src_ctx) + : m_delegate(importer.GetDelegate(dst_ctx, src_ctx)), m_dst_ctx(dst_ctx), + m_src_ctx(src_ctx), importer(importer) { + m_delegate->SetImportListener(this); + } + + virtual ~CompleteTagDeclsScope() { + ClangASTImporter::ASTContextMetadataSP to_context_md = + importer.GetContextMetadata(m_dst_ctx); + + // Complete all decls we collected until now. + while (!m_decls_to_complete.empty()) { + NamedDecl *decl = m_decls_to_complete.pop_back_val(); + m_decls_already_completed.insert(decl); + + // We should only complete decls coming from the source context. + assert(to_context_md->m_origins[decl].ctx == m_src_ctx); + + Decl *original_decl = to_context_md->m_origins[decl].decl; + + // Complete the decl now. + TypeSystemClang::GetCompleteDecl(m_src_ctx, original_decl); + if (auto *tag_decl = dyn_cast(decl)) { + if (auto *original_tag_decl = dyn_cast(original_decl)) { + if (original_tag_decl->isCompleteDefinition()) { + m_delegate->ImportDefinitionTo(tag_decl, original_tag_decl); + tag_decl->setCompleteDefinition(true); + } + } + + tag_decl->setHasExternalLexicalStorage(false); + tag_decl->setHasExternalVisibleStorage(false); + } else if (auto *container_decl = dyn_cast(decl)) { + container_decl->setHasExternalLexicalStorage(false); + container_decl->setHasExternalVisibleStorage(false); + } + + to_context_md->m_origins.erase(decl); + } + + // Stop listening to imported decls. We do this after clearing the + // Decls we needed to import to catch all Decls they might have pulled in. + m_delegate->RemoveImportListener(); + } + + void NewDeclImported(clang::Decl *from, clang::Decl *to) override { + // Filter out decls that we can't complete later. + if (!isa(to) && !isa(to)) + return; + RecordDecl *from_record_decl = dyn_cast(from); + // We don't need to complete injected class name decls. + if (from_record_decl && from_record_decl->isInjectedClassName()) + return; + + NamedDecl *to_named_decl = dyn_cast(to); + // Check if we already completed this type. + if (m_decls_already_completed.count(to_named_decl) != 0) + return; + m_decls_to_complete.push_back(to_named_decl); + } +}; +} // namespace + +CompilerType ClangASTImporter::DeportType(TypeSystemClang &dst, + const CompilerType &src_type) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + TypeSystemClang *src_ctxt = + llvm::cast(src_type.GetTypeSystem()); + + LLDB_LOG(log, + " [ClangASTImporter] DeportType called on ({0}Type*){1} " + "from (ASTContext*){2} to (ASTContext*){3}", + src_type.GetTypeName(), src_type.GetOpaqueQualType(), + &src_ctxt->getASTContext(), &dst.getASTContext()); + + DeclContextOverride decl_context_override; + + if (auto *t = ClangUtil::GetQualType(src_type)->getAs()) + decl_context_override.OverrideAllDeclsFromContainingFunction(t->getDecl()); + + CompleteTagDeclsScope complete_scope(*this, &dst.getASTContext(), + &src_ctxt->getASTContext()); + return CopyType(dst, src_type); +} + +clang::Decl *ClangASTImporter::DeportDecl(clang::ASTContext *dst_ctx, + clang::Decl *decl) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + clang::ASTContext *src_ctx = &decl->getASTContext(); + LLDB_LOG(log, + " [ClangASTImporter] DeportDecl called on ({0}Decl*){1} from " + "(ASTContext*){2} to (ASTContext*){3}", + decl->getDeclKindName(), decl, src_ctx, dst_ctx); + + DeclContextOverride decl_context_override; + + decl_context_override.OverrideAllDeclsFromContainingFunction(decl); + + clang::Decl *result; + { + CompleteTagDeclsScope complete_scope(*this, dst_ctx, src_ctx); + result = CopyDecl(dst_ctx, decl); + } + + if (!result) + return nullptr; + + LLDB_LOG(log, + " [ClangASTImporter] DeportDecl deported ({0}Decl*){1} to " + "({2}Decl*){3}", + decl->getDeclKindName(), decl, result->getDeclKindName(), result); + + return result; +} + +bool ClangASTImporter::CanImport(const CompilerType &type) { + if (!ClangUtil::IsClangType(type)) + return false; + + // TODO: remove external completion BOOL + // CompleteAndFetchChildren should get the Decl out and check for the + + clang::QualType qual_type( + ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type))); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: { + const clang::CXXRecordDecl *cxx_record_decl = + qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) { + if (GetDeclOrigin(cxx_record_decl).Valid()) + return true; + } + } break; + + case clang::Type::Enum: { + clang::EnumDecl *enum_decl = + llvm::cast(qual_type)->getDecl(); + if (enum_decl) { + if (GetDeclOrigin(enum_decl).Valid()) + return true; + } + } break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: { + const clang::ObjCObjectType *objc_class_type = + llvm::dyn_cast(qual_type); + if (objc_class_type) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + // We currently can't complete objective C types through the newly added + // ASTContext because it only supports TagDecl objects right now... + if (class_interface_decl) { + if (GetDeclOrigin(class_interface_decl).Valid()) + return true; + } + } + } break; + + case clang::Type::Typedef: + return CanImport(CompilerType(type.GetTypeSystem(), + llvm::cast(qual_type) + ->getDecl() + ->getUnderlyingType() + .getAsOpaquePtr())); + + case clang::Type::Auto: + return CanImport(CompilerType(type.GetTypeSystem(), + llvm::cast(qual_type) + ->getDeducedType() + .getAsOpaquePtr())); + + case clang::Type::Elaborated: + return CanImport(CompilerType(type.GetTypeSystem(), + llvm::cast(qual_type) + ->getNamedType() + .getAsOpaquePtr())); + + case clang::Type::Paren: + return CanImport(CompilerType( + type.GetTypeSystem(), + llvm::cast(qual_type)->desugar().getAsOpaquePtr())); + + default: + break; + } + + return false; +} + +bool ClangASTImporter::Import(const CompilerType &type) { + if (!ClangUtil::IsClangType(type)) + return false; + // TODO: remove external completion BOOL + // CompleteAndFetchChildren should get the Decl out and check for the + + clang::QualType qual_type( + ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type))); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: { + const clang::CXXRecordDecl *cxx_record_decl = + qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) { + if (GetDeclOrigin(cxx_record_decl).Valid()) + return CompleteAndFetchChildren(qual_type); + } + } break; + + case clang::Type::Enum: { + clang::EnumDecl *enum_decl = + llvm::cast(qual_type)->getDecl(); + if (enum_decl) { + if (GetDeclOrigin(enum_decl).Valid()) + return CompleteAndFetchChildren(qual_type); + } + } break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: { + const clang::ObjCObjectType *objc_class_type = + llvm::dyn_cast(qual_type); + if (objc_class_type) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + // We currently can't complete objective C types through the newly added + // ASTContext because it only supports TagDecl objects right now... + if (class_interface_decl) { + if (GetDeclOrigin(class_interface_decl).Valid()) + return CompleteAndFetchChildren(qual_type); + } + } + } break; + + case clang::Type::Typedef: + return Import(CompilerType(type.GetTypeSystem(), + llvm::cast(qual_type) + ->getDecl() + ->getUnderlyingType() + .getAsOpaquePtr())); + + case clang::Type::Auto: + return Import(CompilerType(type.GetTypeSystem(), + llvm::cast(qual_type) + ->getDeducedType() + .getAsOpaquePtr())); + + case clang::Type::Elaborated: + return Import(CompilerType(type.GetTypeSystem(), + llvm::cast(qual_type) + ->getNamedType() + .getAsOpaquePtr())); + + case clang::Type::Paren: + return Import(CompilerType( + type.GetTypeSystem(), + llvm::cast(qual_type)->desugar().getAsOpaquePtr())); + + default: + break; + } + return false; +} + +bool ClangASTImporter::CompleteType(const CompilerType &compiler_type) { + if (!CanImport(compiler_type)) + return false; + + if (Import(compiler_type)) { + TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type); + return true; + } + + TypeSystemClang::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), + false); + return false; +} + +bool ClangASTImporter::LayoutRecordType( + const clang::RecordDecl *record_decl, uint64_t &bit_size, + uint64_t &alignment, + llvm::DenseMap &field_offsets, + llvm::DenseMap + &base_offsets, + llvm::DenseMap + &vbase_offsets) { + RecordDeclToLayoutMap::iterator pos = + m_record_decl_to_layout_map.find(record_decl); + bool success = false; + base_offsets.clear(); + vbase_offsets.clear(); + if (pos != m_record_decl_to_layout_map.end()) { + bit_size = pos->second.bit_size; + alignment = pos->second.alignment; + field_offsets.swap(pos->second.field_offsets); + base_offsets.swap(pos->second.base_offsets); + vbase_offsets.swap(pos->second.vbase_offsets); + m_record_decl_to_layout_map.erase(pos); + success = true; + } else { + bit_size = 0; + alignment = 0; + field_offsets.clear(); + } + return success; +} + +void ClangASTImporter::SetRecordLayout(clang::RecordDecl *decl, + const LayoutInfo &layout) { + m_record_decl_to_layout_map.insert(std::make_pair(decl, layout)); +} + +bool ClangASTImporter::CompleteTagDecl(clang::TagDecl *decl) { + DeclOrigin decl_origin = GetDeclOrigin(decl); + + if (!decl_origin.Valid()) + return false; + + if (!TypeSystemClang::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) + return false; + + ImporterDelegateSP delegate_sp( + GetDelegate(&decl->getASTContext(), decl_origin.ctx)); + + ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, + &decl->getASTContext()); + if (delegate_sp) + delegate_sp->ImportDefinitionTo(decl, decl_origin.decl); + + return true; +} + +bool ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl, + clang::TagDecl *origin_decl) { + clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext(); + + if (!TypeSystemClang::GetCompleteDecl(origin_ast_ctx, origin_decl)) + return false; + + ImporterDelegateSP delegate_sp( + GetDelegate(&decl->getASTContext(), origin_ast_ctx)); + + if (delegate_sp) + delegate_sp->ImportDefinitionTo(decl, origin_decl); + + ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); + + OriginMap &origins = context_md->m_origins; + + origins[decl] = DeclOrigin(origin_ast_ctx, origin_decl); + + return true; +} + +bool ClangASTImporter::CompleteObjCInterfaceDecl( + clang::ObjCInterfaceDecl *interface_decl) { + DeclOrigin decl_origin = GetDeclOrigin(interface_decl); + + if (!decl_origin.Valid()) + return false; + + if (!TypeSystemClang::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) + return false; + + ImporterDelegateSP delegate_sp( + GetDelegate(&interface_decl->getASTContext(), decl_origin.ctx)); + + if (delegate_sp) + delegate_sp->ImportDefinitionTo(interface_decl, decl_origin.decl); + + if (ObjCInterfaceDecl *super_class = interface_decl->getSuperClass()) + RequireCompleteType(clang::QualType(super_class->getTypeForDecl(), 0)); + + return true; +} + +bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) { + if (!RequireCompleteType(type)) + return false; + + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + + if (const TagType *tag_type = type->getAs()) { + TagDecl *tag_decl = tag_type->getDecl(); + + DeclOrigin decl_origin = GetDeclOrigin(tag_decl); + + if (!decl_origin.Valid()) + return false; + + ImporterDelegateSP delegate_sp( + GetDelegate(&tag_decl->getASTContext(), decl_origin.ctx)); + + ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, + &tag_decl->getASTContext()); + + TagDecl *origin_tag_decl = llvm::dyn_cast(decl_origin.decl); + + for (Decl *origin_child_decl : origin_tag_decl->decls()) { + llvm::Expected imported_or_err = + delegate_sp->Import(origin_child_decl); + if (!imported_or_err) { + LLDB_LOG_ERROR(log, imported_or_err.takeError(), + "Couldn't import decl: {0}"); + return false; + } + } + + if (RecordDecl *record_decl = dyn_cast(origin_tag_decl)) + record_decl->setHasLoadedFieldsFromExternalStorage(true); + + return true; + } + + if (const ObjCObjectType *objc_object_type = type->getAs()) { + if (ObjCInterfaceDecl *objc_interface_decl = + objc_object_type->getInterface()) { + DeclOrigin decl_origin = GetDeclOrigin(objc_interface_decl); + + if (!decl_origin.Valid()) + return false; + + ImporterDelegateSP delegate_sp( + GetDelegate(&objc_interface_decl->getASTContext(), decl_origin.ctx)); + + ObjCInterfaceDecl *origin_interface_decl = + llvm::dyn_cast(decl_origin.decl); + + for (Decl *origin_child_decl : origin_interface_decl->decls()) { + llvm::Expected imported_or_err = + delegate_sp->Import(origin_child_decl); + if (!imported_or_err) { + LLDB_LOG_ERROR(log, imported_or_err.takeError(), + "Couldn't import decl: {0}"); + return false; + } + } + + return true; + } + return false; + } + + return true; +} + +bool ClangASTImporter::RequireCompleteType(clang::QualType type) { + if (type.isNull()) + return false; + + if (const TagType *tag_type = type->getAs()) { + TagDecl *tag_decl = tag_type->getDecl(); + + if (tag_decl->getDefinition() || tag_decl->isBeingDefined()) + return true; + + return CompleteTagDecl(tag_decl); + } + if (const ObjCObjectType *objc_object_type = type->getAs()) { + if (ObjCInterfaceDecl *objc_interface_decl = + objc_object_type->getInterface()) + return CompleteObjCInterfaceDecl(objc_interface_decl); + return false; + } + if (const ArrayType *array_type = type->getAsArrayTypeUnsafe()) + return RequireCompleteType(array_type->getElementType()); + if (const AtomicType *atomic_type = type->getAs()) + return RequireCompleteType(atomic_type->getPointeeType()); + + return true; +} + +ClangASTMetadata *ClangASTImporter::GetDeclMetadata(const clang::Decl *decl) { + DeclOrigin decl_origin = GetDeclOrigin(decl); + + if (decl_origin.Valid()) { + TypeSystemClang *ast = TypeSystemClang::GetASTContext(decl_origin.ctx); + return ast->GetMetadata(decl_origin.decl); + } + TypeSystemClang *ast = TypeSystemClang::GetASTContext(&decl->getASTContext()); + return ast->GetMetadata(decl); +} + +ClangASTImporter::DeclOrigin +ClangASTImporter::GetDeclOrigin(const clang::Decl *decl) { + ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); + + OriginMap &origins = context_md->m_origins; + + OriginMap::iterator iter = origins.find(decl); + + if (iter != origins.end()) + return iter->second; + return DeclOrigin(); +} + +void ClangASTImporter::SetDeclOrigin(const clang::Decl *decl, + clang::Decl *original_decl) { + ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); + + OriginMap &origins = context_md->m_origins; + + OriginMap::iterator iter = origins.find(decl); + + if (iter != origins.end()) { + iter->second.decl = original_decl; + iter->second.ctx = &original_decl->getASTContext(); + return; + } + origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl); +} + +void ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl, + NamespaceMapSP &namespace_map) { + ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); + + context_md->m_namespace_maps[decl] = namespace_map; +} + +ClangASTImporter::NamespaceMapSP +ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl) { + ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); + + NamespaceMetaMap &namespace_maps = context_md->m_namespace_maps; + + NamespaceMetaMap::iterator iter = namespace_maps.find(decl); + + if (iter != namespace_maps.end()) + return iter->second; + return NamespaceMapSP(); +} + +void ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl) { + assert(decl); + ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); + + const DeclContext *parent_context = decl->getDeclContext(); + const NamespaceDecl *parent_namespace = + dyn_cast(parent_context); + NamespaceMapSP parent_map; + + if (parent_namespace) + parent_map = GetNamespaceMap(parent_namespace); + + NamespaceMapSP new_map; + + new_map = std::make_shared(); + + if (context_md->m_map_completer) { + std::string namespace_string = decl->getDeclName().getAsString(); + + context_md->m_map_completer->CompleteNamespaceMap( + new_map, ConstString(namespace_string.c_str()), parent_map); + } + + context_md->m_namespace_maps[decl] = new_map; +} + +void ClangASTImporter::ForgetDestination(clang::ASTContext *dst_ast) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + LLDB_LOG(log, + " [ClangASTImporter] Forgetting destination (ASTContext*){0}", + dst_ast); + + m_metadata_map.erase(dst_ast); +} + +void ClangASTImporter::ForgetSource(clang::ASTContext *dst_ast, + clang::ASTContext *src_ast) { + ASTContextMetadataSP md = MaybeGetContextMetadata(dst_ast); + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + LLDB_LOG(log, + " [ClangASTImporter] Forgetting source->dest " + "(ASTContext*){0}->(ASTContext*){1}", + src_ast, dst_ast); + + if (!md) + return; + + md->m_delegates.erase(src_ast); + + for (OriginMap::iterator iter = md->m_origins.begin(); + iter != md->m_origins.end();) { + if (iter->second.ctx == src_ast) + md->m_origins.erase(iter++); + else + ++iter; + } +} + +ClangASTImporter::MapCompleter::~MapCompleter() { return; } + +llvm::Expected +ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) { + if (m_std_handler) { + llvm::Optional D = m_std_handler->Import(From); + if (D) { + // Make sure we don't use this decl later to map it back to it's original + // decl. The decl the CxxModuleHandler created has nothing to do with + // the one from debug info, and linking those two would just cause the + // ASTImporter to try 'updating' the module decl with the minimal one from + // the debug info. + m_decls_to_ignore.insert(*D); + return *D; + } + } + + // Check which ASTContext this declaration originally came from. + DeclOrigin origin = m_master.GetDeclOrigin(From); + // If it originally came from the target ASTContext then we can just + // pretend that the original is the one we imported. This can happen for + // example when inspecting a persistent declaration from the scratch + // ASTContext (which will provide the declaration when parsing the + // expression and then we later try to copy the declaration back to the + // scratch ASTContext to store the result). + // Without this check we would ask the ASTImporter to import a declaration + // into the same ASTContext where it came from (which doesn't make a lot of + // sense). + if (origin.Valid() && origin.ctx == &getToContext()) { + RegisterImportedDecl(From, origin.decl); + return origin.decl; + } + + // This declaration came originally from another ASTContext. Instead of + // copying our potentially incomplete 'From' Decl we instead go to the + // original ASTContext and copy the original to the target. This is not + // only faster than first completing our current decl and then copying it + // to the target, but it also prevents that indirectly copying the same + // declaration to the same target requires the ASTImporter to merge all + // the different decls that appear to come from different ASTContexts (even + // though all these different source ASTContexts just got a copy from + // one source AST). + if (origin.Valid()) { + auto R = m_master.CopyDecl(&getToContext(), origin.decl); + if (R) { + RegisterImportedDecl(From, R); + return R; + } + } + + // If we have a forcefully completed type, try to find an actual definition + // for it in other modules. + const ClangASTMetadata *md = m_master.GetDeclMetadata(From); + auto *td = dyn_cast(From); + if (td && md && md->IsForcefullyCompleted()) { + Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + LLDB_LOG(log, + "[ClangASTImporter] Searching for a complete definition of {0} in " + "other modules", + td->getName()); + Expected dc_or_err = ImportContext(td->getDeclContext()); + if (!dc_or_err) + return dc_or_err.takeError(); + Expected dn_or_err = Import(td->getDeclName()); + if (!dn_or_err) + return dn_or_err.takeError(); + DeclContext *dc = *dc_or_err; + DeclContext::lookup_result lr = dc->lookup(*dn_or_err); + if (lr.size()) { + clang::Decl *lookup_found = lr.front(); + RegisterImportedDecl(From, lookup_found); + m_decls_to_ignore.insert(lookup_found); + return lookup_found; + } else + LLDB_LOG(log, "[ClangASTImporter] Complete definition not found"); + } + + return ASTImporter::ImportImpl(From); +} + +void ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo( + clang::Decl *to, clang::Decl *from) { + // We might have a forward declaration from a shared library that we + // gave external lexical storage so that Clang asks us about the full + // definition when it needs it. In this case the ASTImporter isn't aware + // that the forward decl from the shared library is the actual import + // target but would create a second declaration that would then be defined. + // We want that 'to' is actually complete after this function so let's + // tell the ASTImporter that 'to' was imported from 'from'. + MapImported(from, to); + ASTImporter::Imported(from, to); + + /* + if (to_objc_interface) + to_objc_interface->startDefinition(); + + CXXRecordDecl *to_cxx_record = dyn_cast(to); + + if (to_cxx_record) + to_cxx_record->startDefinition(); + */ + + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + + if (llvm::Error err = ImportDefinition(from)) { + LLDB_LOG_ERROR(log, std::move(err), + "[ClangASTImporter] Error during importing definition: {0}"); + return; + } + + if (clang::TagDecl *to_tag = dyn_cast(to)) { + if (clang::TagDecl *from_tag = dyn_cast(from)) { + to_tag->setCompleteDefinition(from_tag->isCompleteDefinition()); + + if (Log *log_ast = + lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST)) { + std::string name_string; + if (NamedDecl *from_named_decl = dyn_cast(from)) { + llvm::raw_string_ostream name_stream(name_string); + from_named_decl->printName(name_stream); + name_stream.flush(); + } + LLDB_LOG(log_ast, "==== [ClangASTImporter][TUDecl: {0}] Imported " + "({1}Decl*){2}, named {3} (from " + "(Decl*){4})", + static_cast(to->getTranslationUnitDecl()), + from->getDeclKindName(), static_cast(to), name_string, + static_cast(from)); + + // Log the AST of the TU. + std::string ast_string; + llvm::raw_string_ostream ast_stream(ast_string); + to->getTranslationUnitDecl()->dump(ast_stream); + LLDB_LOG(log_ast, "{0}", ast_string); + } + } + } + + // If we're dealing with an Objective-C class, ensure that the inheritance + // has been set up correctly. The ASTImporter may not do this correctly if + // the class was originally sourced from symbols. + + if (ObjCInterfaceDecl *to_objc_interface = dyn_cast(to)) { + do { + ObjCInterfaceDecl *to_superclass = to_objc_interface->getSuperClass(); + + if (to_superclass) + break; // we're not going to override it if it's set + + ObjCInterfaceDecl *from_objc_interface = + dyn_cast(from); + + if (!from_objc_interface) + break; + + ObjCInterfaceDecl *from_superclass = from_objc_interface->getSuperClass(); + + if (!from_superclass) + break; + + llvm::Expected imported_from_superclass_decl = + Import(from_superclass); + + if (!imported_from_superclass_decl) { + LLDB_LOG_ERROR(log, imported_from_superclass_decl.takeError(), + "Couldn't import decl: {0}"); + break; + } + + ObjCInterfaceDecl *imported_from_superclass = + dyn_cast(*imported_from_superclass_decl); + + if (!imported_from_superclass) + break; + + if (!to_objc_interface->hasDefinition()) + to_objc_interface->startDefinition(); + + to_objc_interface->setSuperClass(m_source_ctx->getTrivialTypeSourceInfo( + m_source_ctx->getObjCInterfaceType(imported_from_superclass))); + } while (false); + } +} + +/// Takes a CXXMethodDecl and completes the return type if necessary. This +/// is currently only necessary for virtual functions with covariant return +/// types where Clang's CodeGen expects that the underlying records are already +/// completed. +static void MaybeCompleteReturnType(ClangASTImporter &importer, + CXXMethodDecl *to_method) { + if (!to_method->isVirtual()) + return; + QualType return_type = to_method->getReturnType(); + if (!return_type->isPointerType() && !return_type->isReferenceType()) + return; + + clang::RecordDecl *rd = return_type->getPointeeType()->getAsRecordDecl(); + if (!rd) + return; + if (rd->getDefinition()) + return; + + importer.CompleteTagDecl(rd); +} + +/// Recreate a module with its parents in \p to_source and return its id. +static OptionalClangModuleID +RemapModule(OptionalClangModuleID from_id, + ClangExternalASTSourceCallbacks &from_source, + ClangExternalASTSourceCallbacks &to_source) { + if (!from_id.HasValue()) + return {}; + clang::Module *module = from_source.getModule(from_id.GetValue()); + OptionalClangModuleID parent = RemapModule( + from_source.GetIDForModule(module->Parent), from_source, to_source); + TypeSystemClang &to_ts = to_source.GetTypeSystem(); + return to_ts.GetOrCreateClangModule(module->Name, parent, module->IsFramework, + module->IsExplicit); +} + +void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from, + clang::Decl *to) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + // Some decls shouldn't be tracked here because they were not created by + // copying 'from' to 'to'. Just exit early for those. + if (m_decls_to_ignore.count(to)) + return clang::ASTImporter::Imported(from, to); + + // Transfer module ownership information. + auto *from_source = llvm::dyn_cast_or_null( + getFromContext().getExternalSource()); + // Can also be a ClangASTSourceProxy. + auto *to_source = llvm::dyn_cast_or_null( + getToContext().getExternalSource()); + if (from_source && to_source) { + OptionalClangModuleID from_id(from->getOwningModuleID()); + OptionalClangModuleID to_id = + RemapModule(from_id, *from_source, *to_source); + TypeSystemClang &to_ts = to_source->GetTypeSystem(); + to_ts.SetOwningModule(to, to_id); + } + + lldb::user_id_t user_id = LLDB_INVALID_UID; + ClangASTMetadata *metadata = m_master.GetDeclMetadata(from); + if (metadata) + user_id = metadata->GetUserID(); + + if (log) { + if (NamedDecl *from_named_decl = dyn_cast(from)) { + std::string name_string; + llvm::raw_string_ostream name_stream(name_string); + from_named_decl->printName(name_stream); + name_stream.flush(); + + LLDB_LOG(log, + " [ClangASTImporter] Imported ({0}Decl*){1}, named {2} (from " + "(Decl*){3}), metadata {4}", + from->getDeclKindName(), to, name_string, from, user_id); + } else { + LLDB_LOG(log, + " [ClangASTImporter] Imported ({0}Decl*){1} (from " + "(Decl*){2}), metadata {3}", + from->getDeclKindName(), to, from, user_id); + } + } + + ASTContextMetadataSP to_context_md = + m_master.GetContextMetadata(&to->getASTContext()); + ASTContextMetadataSP from_context_md = + m_master.MaybeGetContextMetadata(m_source_ctx); + + if (from_context_md) { + OriginMap &origins = from_context_md->m_origins; + + OriginMap::iterator origin_iter = origins.find(from); + + if (origin_iter != origins.end()) { + if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() || + user_id != LLDB_INVALID_UID) { + if (origin_iter->second.ctx != &to->getASTContext()) + to_context_md->m_origins[to] = origin_iter->second; + } + + ImporterDelegateSP direct_completer = + m_master.GetDelegate(&to->getASTContext(), origin_iter->second.ctx); + + if (direct_completer.get() != this) + direct_completer->ASTImporter::Imported(origin_iter->second.decl, to); + + LLDB_LOG(log, + " [ClangASTImporter] Propagated origin " + "(Decl*){0}/(ASTContext*){1} from (ASTContext*){2} to " + "(ASTContext*){3}", + origin_iter->second.decl, origin_iter->second.ctx, + &from->getASTContext(), &to->getASTContext()); + } else { + if (m_new_decl_listener) + m_new_decl_listener->NewDeclImported(from, to); + + if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() || + user_id != LLDB_INVALID_UID) { + to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from); + } + + LLDB_LOG(log, + " [ClangASTImporter] Decl has no origin information in " + "(ASTContext*){0}", + &from->getASTContext()); + } + + if (auto *to_namespace = dyn_cast(to)) { + auto *from_namespace = cast(from); + + NamespaceMetaMap &namespace_maps = from_context_md->m_namespace_maps; + + NamespaceMetaMap::iterator namespace_map_iter = + namespace_maps.find(from_namespace); + + if (namespace_map_iter != namespace_maps.end()) + to_context_md->m_namespace_maps[to_namespace] = + namespace_map_iter->second; + } + } else { + to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from); + + LLDB_LOG(log, + " [ClangASTImporter] Sourced origin " + "(Decl*){0}/(ASTContext*){1} into (ASTContext*){2}", + from, m_source_ctx, &to->getASTContext()); + } + + if (auto *to_tag_decl = dyn_cast(to)) { + to_tag_decl->setHasExternalLexicalStorage(); + to_tag_decl->getPrimaryContext()->setMustBuildLookupTable(); + auto from_tag_decl = cast(from); + + LLDB_LOG( + log, + " [ClangASTImporter] To is a TagDecl - attributes {0}{1} [{2}->{3}]", + (to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""), + (to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""), + (from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"), + (to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete")); + } + + if (auto *to_namespace_decl = dyn_cast(to)) { + m_master.BuildNamespaceMap(to_namespace_decl); + to_namespace_decl->setHasExternalVisibleStorage(); + } + + if (auto *to_container_decl = dyn_cast(to)) { + to_container_decl->setHasExternalLexicalStorage(); + to_container_decl->setHasExternalVisibleStorage(); + + if (log) { + if (ObjCInterfaceDecl *to_interface_decl = + llvm::dyn_cast(to_container_decl)) { + LLDB_LOG( + log, + " [ClangASTImporter] To is an ObjCInterfaceDecl - attributes " + "{0}{1}{2}", + (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""), + (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""), + (to_interface_decl->hasDefinition() ? " HasDefinition" : "")); + } else { + LLDB_LOG( + log, " [ClangASTImporter] To is an {0}Decl - attributes {1}{2}", + ((Decl *)to_container_decl)->getDeclKindName(), + (to_container_decl->hasExternalLexicalStorage() ? " Lexical" : ""), + (to_container_decl->hasExternalVisibleStorage() ? " Visible" : "")); + } + } + } + + if (clang::CXXMethodDecl *to_method = dyn_cast(to)) + MaybeCompleteReturnType(m_master, to_method); +} + +clang::Decl * +ClangASTImporter::ASTImporterDelegate::GetOriginalDecl(clang::Decl *To) { + return m_master.GetDeclOrigin(To).decl; +} diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h new file mode 100644 index 00000000000..6ceec774914 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h @@ -0,0 +1,328 @@ +//===-- ClangASTImporter.h --------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTIMPORTER_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTIMPORTER_H + +#include +#include +#include +#include + +#include "clang/AST/ASTImporter.h" +#include "clang/AST/CharUnits.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/FileSystemOptions.h" + +#include "lldb/Host/FileSystem.h" +#include "lldb/Symbol/CompilerDeclContext.h" +#include "lldb/lldb-types.h" + +#include "Plugins/ExpressionParser/Clang/CxxModuleHandler.h" + +#include "llvm/ADT/DenseMap.h" + +namespace lldb_private { + +class ClangASTMetadata; +class TypeSystemClang; + +class ClangASTImporter { +public: + struct LayoutInfo { + LayoutInfo() = default; + typedef llvm::DenseMap + OffsetMap; + + uint64_t bit_size = 0; + uint64_t alignment = 0; + llvm::DenseMap field_offsets; + OffsetMap base_offsets; + OffsetMap vbase_offsets; + }; + + ClangASTImporter() + : m_file_manager(clang::FileSystemOptions(), + FileSystem::Instance().GetVirtualFileSystem()) {} + + CompilerType CopyType(TypeSystemClang &dst, const CompilerType &src_type); + + clang::Decl *CopyDecl(clang::ASTContext *dst_ctx, clang::Decl *decl); + + CompilerType DeportType(TypeSystemClang &dst, const CompilerType &src_type); + + clang::Decl *DeportDecl(clang::ASTContext *dst_ctx, clang::Decl *decl); + + /// Sets the layout for the given RecordDecl. The layout will later be + /// used by Clang's during code generation. Not calling this function for + /// a RecordDecl will cause that Clang's codegen tries to layout the + /// record by itself. + /// + /// \param decl The RecordDecl to set the layout for. + /// \param layout The layout for the record. + void SetRecordLayout(clang::RecordDecl *decl, const LayoutInfo &layout); + + bool LayoutRecordType( + const clang::RecordDecl *record_decl, uint64_t &bit_size, + uint64_t &alignment, + llvm::DenseMap &field_offsets, + llvm::DenseMap + &base_offsets, + llvm::DenseMap + &vbase_offsets); + + bool CanImport(const CompilerType &type); + + bool Import(const CompilerType &type); + + bool CompleteType(const CompilerType &compiler_type); + + bool CompleteTagDecl(clang::TagDecl *decl); + + bool CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin); + + bool CompleteObjCInterfaceDecl(clang::ObjCInterfaceDecl *interface_decl); + + bool CompleteAndFetchChildren(clang::QualType type); + + bool RequireCompleteType(clang::QualType type); + + void SetDeclOrigin(const clang::Decl *decl, clang::Decl *original_decl); + + ClangASTMetadata *GetDeclMetadata(const clang::Decl *decl); + + // + // Namespace maps + // + + typedef std::pair NamespaceMapItem; + typedef std::vector NamespaceMap; + typedef std::shared_ptr NamespaceMapSP; + + void RegisterNamespaceMap(const clang::NamespaceDecl *decl, + NamespaceMapSP &namespace_map); + + NamespaceMapSP GetNamespaceMap(const clang::NamespaceDecl *decl); + + void BuildNamespaceMap(const clang::NamespaceDecl *decl); + + // + // Completers for maps + // + + class MapCompleter { + public: + virtual ~MapCompleter(); + + virtual void CompleteNamespaceMap(NamespaceMapSP &namespace_map, + ConstString name, + NamespaceMapSP &parent_map) const = 0; + }; + + void InstallMapCompleter(clang::ASTContext *dst_ctx, + MapCompleter &completer) { + ASTContextMetadataSP context_md; + ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); + + if (context_md_iter == m_metadata_map.end()) { + context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx)); + m_metadata_map[dst_ctx] = context_md; + } else { + context_md = context_md_iter->second; + } + + context_md->m_map_completer = &completer; + } + + void ForgetDestination(clang::ASTContext *dst_ctx); + void ForgetSource(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx); + + struct DeclOrigin { + DeclOrigin() : ctx(nullptr), decl(nullptr) {} + + DeclOrigin(clang::ASTContext *_ctx, clang::Decl *_decl) + : ctx(_ctx), decl(_decl) {} + + DeclOrigin(const DeclOrigin &rhs) { + ctx = rhs.ctx; + decl = rhs.decl; + } + + void operator=(const DeclOrigin &rhs) { + ctx = rhs.ctx; + decl = rhs.decl; + } + + bool Valid() { return (ctx != nullptr || decl != nullptr); } + + clang::ASTContext *ctx; + clang::Decl *decl; + }; + + typedef llvm::DenseMap OriginMap; + + /// Listener interface used by the ASTImporterDelegate to inform other code + /// about decls that have been imported the first time. + struct NewDeclListener { + virtual ~NewDeclListener() = default; + /// A decl has been imported for the first time. + virtual void NewDeclImported(clang::Decl *from, clang::Decl *to) = 0; + }; + + /// ASTImporter that intercepts and records the import process of the + /// underlying ASTImporter. + /// + /// This class updates the map from declarations to their original + /// declarations and can record declarations that have been imported in a + /// certain interval. + /// + /// When intercepting a declaration import, the ASTImporterDelegate uses the + /// CxxModuleHandler to replace any missing or malformed declarations with + /// their counterpart from a C++ module. + struct ASTImporterDelegate : public clang::ASTImporter { + ASTImporterDelegate(ClangASTImporter &master, clang::ASTContext *target_ctx, + clang::ASTContext *source_ctx) + : clang::ASTImporter(*target_ctx, master.m_file_manager, *source_ctx, + master.m_file_manager, true /*minimal*/), + m_master(master), m_source_ctx(source_ctx) { + setODRHandling(clang::ASTImporter::ODRHandlingType::Liberal); + } + + /// Scope guard that attaches a CxxModuleHandler to an ASTImporterDelegate + /// and deattaches it at the end of the scope. Supports being used multiple + /// times on the same ASTImporterDelegate instance in nested scopes. + class CxxModuleScope { + /// The handler we attach to the ASTImporterDelegate. + CxxModuleHandler m_handler; + /// The ASTImporterDelegate we are supposed to attach the handler to. + ASTImporterDelegate &m_delegate; + /// True iff we attached the handler to the ASTImporterDelegate. + bool m_valid = false; + + public: + CxxModuleScope(ASTImporterDelegate &delegate, clang::ASTContext *dst_ctx) + : m_delegate(delegate) { + // If the delegate doesn't have a CxxModuleHandler yet, create one + // and attach it. + if (!delegate.m_std_handler) { + m_handler = CxxModuleHandler(delegate, dst_ctx); + m_valid = true; + delegate.m_std_handler = &m_handler; + } + } + ~CxxModuleScope() { + if (m_valid) { + // Make sure no one messed with the handler we placed. + assert(m_delegate.m_std_handler == &m_handler); + m_delegate.m_std_handler = nullptr; + } + } + }; + + void ImportDefinitionTo(clang::Decl *to, clang::Decl *from); + + void Imported(clang::Decl *from, clang::Decl *to) override; + + clang::Decl *GetOriginalDecl(clang::Decl *To) override; + + void SetImportListener(NewDeclListener *listener) { + assert(m_new_decl_listener == nullptr && "Already attached a listener?"); + m_new_decl_listener = listener; + } + void RemoveImportListener() { m_new_decl_listener = nullptr; } + + protected: + llvm::Expected ImportImpl(clang::Decl *From) override; + + private: + /// Decls we should ignore when mapping decls back to their original + /// ASTContext. Used by the CxxModuleHandler to mark declarations that + /// were created from the 'std' C++ module to prevent that the Importer + /// tries to sync them with the broken equivalent in the debug info AST. + llvm::SmallPtrSet m_decls_to_ignore; + ClangASTImporter &m_master; + clang::ASTContext *m_source_ctx; + CxxModuleHandler *m_std_handler = nullptr; + /// The currently attached listener. + NewDeclListener *m_new_decl_listener = nullptr; + }; + + typedef std::shared_ptr ImporterDelegateSP; + typedef llvm::DenseMap DelegateMap; + typedef llvm::DenseMap + NamespaceMetaMap; + + struct ASTContextMetadata { + ASTContextMetadata(clang::ASTContext *dst_ctx) + : m_dst_ctx(dst_ctx), m_delegates(), m_origins(), m_namespace_maps(), + m_map_completer(nullptr) {} + + clang::ASTContext *m_dst_ctx; + DelegateMap m_delegates; + OriginMap m_origins; + + NamespaceMetaMap m_namespace_maps; + MapCompleter *m_map_completer; + }; + + typedef std::shared_ptr ASTContextMetadataSP; + typedef llvm::DenseMap + ContextMetadataMap; + + ContextMetadataMap m_metadata_map; + + ASTContextMetadataSP GetContextMetadata(clang::ASTContext *dst_ctx) { + ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); + + if (context_md_iter == m_metadata_map.end()) { + ASTContextMetadataSP context_md = + ASTContextMetadataSP(new ASTContextMetadata(dst_ctx)); + m_metadata_map[dst_ctx] = context_md; + return context_md; + } + return context_md_iter->second; + } + + ASTContextMetadataSP MaybeGetContextMetadata(clang::ASTContext *dst_ctx) { + ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); + + if (context_md_iter != m_metadata_map.end()) + return context_md_iter->second; + return ASTContextMetadataSP(); + } + + ImporterDelegateSP GetDelegate(clang::ASTContext *dst_ctx, + clang::ASTContext *src_ctx) { + ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx); + + DelegateMap &delegates = context_md->m_delegates; + DelegateMap::iterator delegate_iter = delegates.find(src_ctx); + + if (delegate_iter == delegates.end()) { + ImporterDelegateSP delegate = + ImporterDelegateSP(new ASTImporterDelegate(*this, dst_ctx, src_ctx)); + delegates[src_ctx] = delegate; + return delegate; + } + return delegate_iter->second; + } + + DeclOrigin GetDeclOrigin(const clang::Decl *decl); + + clang::FileManager m_file_manager; + typedef llvm::DenseMap + RecordDeclToLayoutMap; + + RecordDeclToLayoutMap m_record_decl_to_layout_map; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTIMPORTER_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.cpp new file mode 100644 index 00000000000..42933c78b02 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.cpp @@ -0,0 +1,35 @@ +//===-- ClangASTMetadata.cpp ----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" +#include "lldb/Utility/Stream.h" + +using namespace lldb_private; + +void ClangASTMetadata::Dump(Stream *s) { + lldb::user_id_t uid = GetUserID(); + + if (uid != LLDB_INVALID_UID) { + s->Printf("uid=0x%" PRIx64, uid); + } + + uint64_t isa_ptr = GetISAPtr(); + if (isa_ptr != 0) { + s->Printf("isa_ptr=0x%" PRIx64, isa_ptr); + } + + const char *obj_ptr_name = GetObjectPtrName(); + if (obj_ptr_name) { + s->Printf("obj_ptr_name=\"%s\" ", obj_ptr_name); + } + + if (m_is_dynamic_cxx) { + s->Printf("is_dynamic_cxx=%i ", m_is_dynamic_cxx); + } + s->EOL(); +} diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.h new file mode 100644 index 00000000000..d3bcde2ced7 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.h @@ -0,0 +1,110 @@ +//===-- ClangASTMetadata.h --------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTMETADATA_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTMETADATA_H + +#include "lldb/Core/dwarf.h" +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" + +namespace lldb_private { + +class ClangASTMetadata { +public: + ClangASTMetadata() + : m_user_id(0), m_union_is_user_id(false), m_union_is_isa_ptr(false), + m_has_object_ptr(false), m_is_self(false), m_is_dynamic_cxx(true), + m_is_forcefully_completed(false) {} + + bool GetIsDynamicCXXType() const { return m_is_dynamic_cxx; } + + void SetIsDynamicCXXType(bool b) { m_is_dynamic_cxx = b; } + + void SetUserID(lldb::user_id_t user_id) { + m_user_id = user_id; + m_union_is_user_id = true; + m_union_is_isa_ptr = false; + } + + lldb::user_id_t GetUserID() const { + if (m_union_is_user_id) + return m_user_id; + else + return LLDB_INVALID_UID; + } + + void SetISAPtr(uint64_t isa_ptr) { + m_isa_ptr = isa_ptr; + m_union_is_user_id = false; + m_union_is_isa_ptr = true; + } + + uint64_t GetISAPtr() const { + if (m_union_is_isa_ptr) + return m_isa_ptr; + else + return 0; + } + + void SetObjectPtrName(const char *name) { + m_has_object_ptr = true; + if (strcmp(name, "self") == 0) + m_is_self = true; + else if (strcmp(name, "this") == 0) + m_is_self = false; + else + m_has_object_ptr = false; + } + + lldb::LanguageType GetObjectPtrLanguage() const { + if (m_has_object_ptr) { + if (m_is_self) + return lldb::eLanguageTypeObjC; + else + return lldb::eLanguageTypeC_plus_plus; + } + return lldb::eLanguageTypeUnknown; + } + + const char *GetObjectPtrName() const { + if (m_has_object_ptr) { + if (m_is_self) + return "self"; + else + return "this"; + } else + return nullptr; + } + + bool HasObjectPtr() const { return m_has_object_ptr; } + + /// A type is "forcefully completed" if it was declared complete to satisfy an + /// AST invariant (e.g. base classes must be complete types), but in fact we + /// were not able to find a actual definition for it. + bool IsForcefullyCompleted() const { return m_is_forcefully_completed; } + + void SetIsForcefullyCompleted(bool value = true) { + m_is_forcefully_completed = true; + } + + void Dump(Stream *s); + +private: + union { + lldb::user_id_t m_user_id; + uint64_t m_isa_ptr; + }; + + bool m_union_is_user_id : 1, m_union_is_isa_ptr : 1, m_has_object_ptr : 1, + m_is_self : 1, m_is_dynamic_cxx : 1, m_is_forcefully_completed : 1; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTMETADATA_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp index 42927ab6cc8..6fe85a1298f 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -1,4 +1,4 @@ -//===-- ClangASTSource.cpp ---------------------------------------*- C++-*-===// +//===-- ClangASTSource.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,8 +13,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/CompilerDeclContext.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/SymbolFile.h" @@ -23,8 +21,11 @@ #include "lldb/Utility/Log.h" #include "clang/AST/ASTContext.h" #include "clang/AST/RecordLayout.h" +#include "clang/Basic/SourceManager.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include #include @@ -49,14 +50,16 @@ private: }; } -ClangASTSource::ClangASTSource(const lldb::TargetSP &target, - const lldb::ClangASTImporterSP &importer) - : m_import_in_progress(false), m_lookups_enabled(false), m_target(target), - m_ast_context(nullptr), m_active_lexical_decls(), m_active_lookups() { - m_ast_importer_sp = importer; +ClangASTSource::ClangASTSource( + const lldb::TargetSP &target, + const std::shared_ptr &importer) + : m_lookups_enabled(false), m_target(target), m_ast_context(nullptr), + m_ast_importer_sp(importer), m_active_lexical_decls(), + m_active_lookups() { + assert(m_ast_importer_sp && "No ClangASTImporter passed to ClangASTSource?"); } -void ClangASTSource::InstallASTContext(ClangASTContext &clang_ast_context) { +void ClangASTSource::InstallASTContext(TypeSystemClang &clang_ast_context) { m_ast_context = &clang_ast_context.getASTContext(); m_clang_ast_context = &clang_ast_context; m_file_manager = &m_ast_context->getSourceManager().getFileManager(); @@ -64,18 +67,15 @@ void ClangASTSource::InstallASTContext(ClangASTContext &clang_ast_context) { } ClangASTSource::~ClangASTSource() { - if (!m_ast_importer_sp) - return; - m_ast_importer_sp->ForgetDestination(m_ast_context); if (!m_target) return; // We are in the process of destruction, don't create clang ast context on // demand by passing false to - // Target::GetScratchClangASTContext(create_on_demand). - ClangASTContext *scratch_clang_ast_context = - ClangASTContext::GetScratch(*m_target, false); + // Target::GetScratchTypeSystemClang(create_on_demand). + TypeSystemClang *scratch_clang_ast_context = + TypeSystemClang::GetScratch(*m_target, false); if (!scratch_clang_ast_context) return; @@ -103,16 +103,8 @@ bool ClangASTSource::FindExternalVisibleDeclsByName( return false; } - if (GetImportInProgress()) { - SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); - return false; - } - std::string decl_name(clang_decl_name.getAsString()); - // if (m_decl_map.DoingASTImport ()) - // return DeclContext::lookup_result(); - // switch (clang_decl_name.getNameKind()) { // Normal identifiers. case DeclarationName::Identifier: { @@ -141,7 +133,7 @@ bool ClangASTSource::FindExternalVisibleDeclsByName( case DeclarationName::ObjCMultiArgSelector: { llvm::SmallVector method_decls; - NameSearchContext method_search_context(*this, method_decls, + NameSearchContext method_search_context(*m_clang_ast_context, method_decls, clang_decl_name, decl_ctx); FindObjCMethodDecls(method_search_context); @@ -179,154 +171,134 @@ bool ClangASTSource::FindExternalVisibleDeclsByName( return false; } m_active_lookups.insert(uniqued_const_decl_name); - // static uint32_t g_depth = 0; - // ++g_depth; - // printf("[%5u] FindExternalVisibleDeclsByName() \"%s\"\n", g_depth, - // uniqued_const_decl_name); llvm::SmallVector name_decls; - NameSearchContext name_search_context(*this, name_decls, clang_decl_name, - decl_ctx); + NameSearchContext name_search_context(*m_clang_ast_context, name_decls, + clang_decl_name, decl_ctx); FindExternalVisibleDecls(name_search_context); SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, name_decls); - // --g_depth; m_active_lookups.erase(uniqued_const_decl_name); return (name_decls.size() != 0); } -void ClangASTSource::CompleteType(TagDecl *tag_decl) { +TagDecl *ClangASTSource::FindCompleteType(const TagDecl *decl) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; - - if (log) { - LLDB_LOGF(log, - " CompleteTagDecl[%u] on (ASTContext*)%p Completing " - "(TagDecl*)%p named %s", - current_id, static_cast(m_ast_context), - static_cast(tag_decl), tag_decl->getName().str().c_str()); - - LLDB_LOG(log, " CTD[%u] Before:\n{0}", current_id, - ClangUtil::DumpDecl(tag_decl)); - } - - auto iter = m_active_lexical_decls.find(tag_decl); - if (iter != m_active_lexical_decls.end()) - return; - m_active_lexical_decls.insert(tag_decl); - ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl); + if (const NamespaceDecl *namespace_context = + dyn_cast(decl->getDeclContext())) { + ClangASTImporter::NamespaceMapSP namespace_map = + m_ast_importer_sp->GetNamespaceMap(namespace_context); - if (!m_ast_importer_sp) { - return; - } + LLDB_LOGV(log, " CTD Inspecting namespace map{0} ({1} entries)", + namespace_map.get(), namespace_map->size()); - if (!m_ast_importer_sp->CompleteTagDecl(tag_decl)) { - // We couldn't complete the type. Maybe there's a definition somewhere - // else that can be completed. - - LLDB_LOGF(log, - " CTD[%u] Type could not be completed in the module in " - "which it was first found.", - current_id); + if (!namespace_map) + return nullptr; - bool found = false; + for (const ClangASTImporter::NamespaceMapItem &item : *namespace_map) { + LLDB_LOG(log, " CTD Searching namespace {0} in module {1}", + item.second.GetName(), item.first->GetFileSpec().GetFilename()); - DeclContext *decl_ctx = tag_decl->getDeclContext(); + TypeList types; - if (const NamespaceDecl *namespace_context = - dyn_cast(decl_ctx)) { - ClangASTImporter::NamespaceMapSP namespace_map = - m_ast_importer_sp->GetNamespaceMap(namespace_context); + ConstString name(decl->getName()); - if (log && log->GetVerbose()) - LLDB_LOGF(log, " CTD[%u] Inspecting namespace map %p (%d entries)", - current_id, static_cast(namespace_map.get()), - static_cast(namespace_map->size())); + item.first->FindTypesInNamespace(name, item.second, UINT32_MAX, types); - if (!namespace_map) - return; + for (uint32_t ti = 0, te = types.GetSize(); ti != te; ++ti) { + lldb::TypeSP type = types.GetTypeAtIndex(ti); - for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), - e = namespace_map->end(); - i != e && !found; ++i) { - LLDB_LOGF(log, " CTD[%u] Searching namespace %s in module %s", - current_id, i->second.GetName().AsCString(), - i->first->GetFileSpec().GetFilename().GetCString()); + if (!type) + continue; - TypeList types; + CompilerType clang_type(type->GetFullCompilerType()); - ConstString name(tag_decl->getName().str().c_str()); + if (!ClangUtil::IsClangType(clang_type)) + continue; - i->first->FindTypesInNamespace(name, &i->second, UINT32_MAX, types); + const TagType *tag_type = + ClangUtil::GetQualType(clang_type)->getAs(); - for (uint32_t ti = 0, te = types.GetSize(); ti != te && !found; ++ti) { - lldb::TypeSP type = types.GetTypeAtIndex(ti); + if (!tag_type) + continue; - if (!type) - continue; + TagDecl *candidate_tag_decl = + const_cast(tag_type->getDecl()); - CompilerType clang_type(type->GetFullCompilerType()); + if (TypeSystemClang::GetCompleteDecl( + &candidate_tag_decl->getASTContext(), candidate_tag_decl)) + return candidate_tag_decl; + } + } + } else { + TypeList types; - if (!ClangUtil::IsClangType(clang_type)) - continue; + ConstString name(decl->getName()); - const TagType *tag_type = - ClangUtil::GetQualType(clang_type)->getAs(); + const ModuleList &module_list = m_target->GetImages(); - if (!tag_type) - continue; + bool exact_match = false; + llvm::DenseSet searched_symbol_files; + module_list.FindTypes(nullptr, name, exact_match, UINT32_MAX, + searched_symbol_files, types); - TagDecl *candidate_tag_decl = - const_cast(tag_type->getDecl()); + for (uint32_t ti = 0, te = types.GetSize(); ti != te; ++ti) { + lldb::TypeSP type = types.GetTypeAtIndex(ti); - if (m_ast_importer_sp->CompleteTagDeclWithOrigin(tag_decl, - candidate_tag_decl)) - found = true; - } - } - } else { - TypeList types; + if (!type) + continue; - ConstString name(tag_decl->getName().str().c_str()); + CompilerType clang_type(type->GetFullCompilerType()); - const ModuleList &module_list = m_target->GetImages(); + if (!ClangUtil::IsClangType(clang_type)) + continue; - bool exact_match = false; - llvm::DenseSet searched_symbol_files; - module_list.FindTypes(nullptr, name, exact_match, UINT32_MAX, - searched_symbol_files, types); + const TagType *tag_type = + ClangUtil::GetQualType(clang_type)->getAs(); - for (uint32_t ti = 0, te = types.GetSize(); ti != te && !found; ++ti) { - lldb::TypeSP type = types.GetTypeAtIndex(ti); + if (!tag_type) + continue; - if (!type) - continue; + TagDecl *candidate_tag_decl = const_cast(tag_type->getDecl()); - CompilerType clang_type(type->GetFullCompilerType()); + // We have found a type by basename and we need to make sure the decl + // contexts are the same before we can try to complete this type with + // another + if (!TypeSystemClang::DeclsAreEquivalent(const_cast(decl), + candidate_tag_decl)) + continue; - if (!ClangUtil::IsClangType(clang_type)) - continue; + if (TypeSystemClang::GetCompleteDecl(&candidate_tag_decl->getASTContext(), + candidate_tag_decl)) + return candidate_tag_decl; + } + } + return nullptr; +} - const TagType *tag_type = - ClangUtil::GetQualType(clang_type)->getAs(); +void ClangASTSource::CompleteType(TagDecl *tag_decl) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - if (!tag_type) - continue; + if (log) { + LLDB_LOG(log, + " CompleteTagDecl on (ASTContext*){0} Completing " + "(TagDecl*){1} named {2}", + m_clang_ast_context->getDisplayName(), tag_decl, + tag_decl->getName()); - TagDecl *candidate_tag_decl = - const_cast(tag_type->getDecl()); + LLDB_LOG(log, " CTD Before:\n{0}", ClangUtil::DumpDecl(tag_decl)); + } - // We have found a type by basename and we need to make sure the decl - // contexts are the same before we can try to complete this type with - // another - if (!ClangASTContext::DeclsAreEquivalent(tag_decl, candidate_tag_decl)) - continue; + auto iter = m_active_lexical_decls.find(tag_decl); + if (iter != m_active_lexical_decls.end()) + return; + m_active_lexical_decls.insert(tag_decl); + ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl); - if (m_ast_importer_sp->CompleteTagDeclWithOrigin(tag_decl, - candidate_tag_decl)) - found = true; - } - } + if (!m_ast_importer_sp->CompleteTagDecl(tag_decl)) { + // We couldn't complete the type. Maybe there's a definition somewhere + // else that can be completed. + if (TagDecl *alternate = FindCompleteType(tag_decl)) + m_ast_importer_sp->CompleteTagDeclWithOrigin(tag_decl, alternate); } LLDB_LOG(log, " [CTD] After:\n{0}", ClangUtil::DumpDecl(tag_decl)); @@ -335,19 +307,14 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) { void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - LLDB_LOGF(log, - " [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing " - "an ObjCInterfaceDecl named %s", - static_cast(m_ast_context), - interface_decl->getName().str().c_str()); + LLDB_LOG(log, + " [CompleteObjCInterfaceDecl] on (ASTContext*){0} '{1}' " + "Completing an ObjCInterfaceDecl named {1}", + m_ast_context, m_clang_ast_context->getDisplayName(), + interface_decl->getName()); LLDB_LOG(log, " [COID] Before:\n{0}", ClangUtil::DumpDecl(interface_decl)); - if (!m_ast_importer_sp) { - lldbassert(0 && "No mechanism for completing a type!"); - return; - } - ClangASTImporter::DeclOrigin original = m_ast_importer_sp->GetDeclOrigin(interface_decl); if (original.Valid()) { @@ -368,10 +335,8 @@ void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) { interface_decl->getSuperClass() != interface_decl) CompleteType(interface_decl->getSuperClass()); - if (log) { - LLDB_LOGF(log, " [COID] After:"); - LLDB_LOG(log, " [COID] {0}", ClangUtil::DumpDecl(interface_decl)); - } + LLDB_LOG(log, " [COID] After:"); + LLDB_LOG(log, " [COID] {0}", ClangUtil::DumpDecl(interface_decl)); } clang::ObjCInterfaceDecl *ClangASTSource::GetCompleteObjCInterface( @@ -420,9 +385,6 @@ void ClangASTSource::FindExternalLexicalDecls( llvm::function_ref predicate, llvm::SmallVectorImpl &decls) { - if (!m_ast_importer_sp) - return; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); const Decl *context_decl = dyn_cast(decl_context); @@ -436,29 +398,27 @@ void ClangASTSource::FindExternalLexicalDecls( m_active_lexical_decls.insert(context_decl); ScopedLexicalDeclEraser eraser(m_active_lexical_decls, context_decl); - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; - if (log) { if (const NamedDecl *context_named_decl = dyn_cast(context_decl)) - LLDB_LOGF( - log, - "FindExternalLexicalDecls[%u] on (ASTContext*)%p in '%s' (%sDecl*)%p", - current_id, static_cast(m_ast_context), - context_named_decl->getNameAsString().c_str(), - context_decl->getDeclKindName(), - static_cast(context_decl)); + LLDB_LOG(log, + "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in " + "'{2}' (%sDecl*){3}", + m_ast_context, m_clang_ast_context->getDisplayName(), + context_named_decl->getNameAsString().c_str(), + context_decl->getDeclKindName(), + static_cast(context_decl)); else if (context_decl) - LLDB_LOGF( - log, "FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p", - current_id, static_cast(m_ast_context), - context_decl->getDeclKindName(), - static_cast(context_decl)); + LLDB_LOG(log, + "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in " + "({2}Decl*){3}", + m_ast_context, m_clang_ast_context->getDisplayName(), + context_decl->getDeclKindName(), + static_cast(context_decl)); else - LLDB_LOGF( - log, - "FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context", - current_id, static_cast(m_ast_context)); + LLDB_LOG(log, + "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in a " + "NULL context", + m_ast_context, m_clang_ast_context->getDisplayName()); } ClangASTImporter::DeclOrigin original = m_ast_importer_sp->GetDeclOrigin(context_decl); @@ -466,10 +426,10 @@ void ClangASTSource::FindExternalLexicalDecls( if (!original.Valid()) return; - LLDB_LOG( - log, " FELD[{0}] Original decl (ASTContext*){1:x} (Decl*){2:x}:\n{3}", - current_id, static_cast(original.ctx), - static_cast(original.decl), ClangUtil::DumpDecl(original.decl)); + LLDB_LOG(log, " FELD Original decl {0} (Decl*){1:x}:\n{2}", + static_cast(original.ctx), + static_cast(original.decl), + ClangUtil::DumpDecl(original.decl)); if (ObjCInterfaceDecl *original_iface_decl = dyn_cast(original.decl)) { @@ -499,10 +459,7 @@ void ClangASTSource::FindExternalLexicalDecls( // Indicates whether we skipped any Decls of the original DeclContext. bool SkippedDecls = false; - for (TagDecl::decl_iterator iter = original_decl_context->decls_begin(); - iter != original_decl_context->decls_end(); ++iter) { - Decl *decl = *iter; - + for (Decl *decl : original_decl_context->decls()) { // The predicate function returns true if the passed declaration kind is // the one we are looking for. // See clang::ExternalASTSource::FindExternalLexicalDecls() @@ -511,13 +468,13 @@ void ClangASTSource::FindExternalLexicalDecls( std::string ast_dump = ClangUtil::DumpDecl(decl); if (const NamedDecl *context_named_decl = dyn_cast(context_decl)) - LLDB_LOGF(log, " FELD[%d] Adding [to %sDecl %s] lexical %sDecl %s", - current_id, context_named_decl->getDeclKindName(), - context_named_decl->getNameAsString().c_str(), - decl->getDeclKindName(), ast_dump.c_str()); + LLDB_LOG(log, " FELD Adding [to {0}Decl {1}] lexical {2}Decl {3}", + context_named_decl->getDeclKindName(), + context_named_decl->getName(), decl->getDeclKindName(), + ast_dump); else - LLDB_LOGF(log, " FELD[%d] Adding lexical %sDecl %s", current_id, - decl->getDeclKindName(), ast_dump.c_str()); + LLDB_LOG(log, " FELD Adding lexical {0}Decl {1}", + decl->getDeclKindName(), ast_dump); } Decl *copied_decl = CopyDecl(decl); @@ -556,56 +513,29 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; - if (log) { if (!context.m_decl_context) - LLDB_LOGF(log, - "ClangASTSource::FindExternalVisibleDecls[%u] on " - "(ASTContext*)%p for '%s' in a NULL DeclContext", - current_id, static_cast(m_ast_context), - name.GetCString()); + LLDB_LOG(log, + "ClangASTSource::FindExternalVisibleDecls on " + "(ASTContext*){0} '{1}' for '{2}' in a NULL DeclContext", + m_ast_context, m_clang_ast_context->getDisplayName(), name); else if (const NamedDecl *context_named_decl = dyn_cast(context.m_decl_context)) - LLDB_LOGF(log, - "ClangASTSource::FindExternalVisibleDecls[%u] on " - "(ASTContext*)%p for '%s' in '%s'", - current_id, static_cast(m_ast_context), - name.GetCString(), - context_named_decl->getNameAsString().c_str()); + LLDB_LOG(log, + "ClangASTSource::FindExternalVisibleDecls on " + "(ASTContext*){0} '{1}' for '{2}' in '{3}'", + m_ast_context, m_clang_ast_context->getDisplayName(), name, + context_named_decl->getName()); else - LLDB_LOGF(log, - "ClangASTSource::FindExternalVisibleDecls[%u] on " - "(ASTContext*)%p for '%s' in a '%s'", - current_id, static_cast(m_ast_context), - name.GetCString(), context.m_decl_context->getDeclKindName()); + LLDB_LOG(log, + "ClangASTSource::FindExternalVisibleDecls on " + "(ASTContext*){0} '{1}' for '{2}' in a '{3}'", + m_ast_context, m_clang_ast_context->getDisplayName(), name, + context.m_decl_context->getDeclKindName()); } - context.m_namespace_map = std::make_shared(); - - if (const NamespaceDecl *namespace_context = - dyn_cast(context.m_decl_context)) { - ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp ? - m_ast_importer_sp->GetNamespaceMap(namespace_context) : nullptr; - - if (log && log->GetVerbose()) - LLDB_LOGF(log, " CAS::FEVD[%u] Inspecting namespace map %p (%d entries)", - current_id, static_cast(namespace_map.get()), - static_cast(namespace_map->size())); - - if (!namespace_map) - return; - - for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), - e = namespace_map->end(); - i != e; ++i) { - LLDB_LOGF(log, " CAS::FEVD[%u] Searching namespace %s in module %s", - current_id, i->second.GetName().AsCString(), - i->first->GetFileSpec().GetFilename().GetCString()); - - FindExternalVisibleDecls(context, i->first, i->second, current_id); - } + if (isa(context.m_decl_context)) { + LookupInNamespace(context); } else if (isa(context.m_decl_context)) { FindObjCPropertyAndIvarDecls(context); } else if (!isa(context.m_decl_context)) { @@ -614,18 +544,15 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) { } else { CompilerDeclContext namespace_decl; - LLDB_LOGF(log, " CAS::FEVD[%u] Searching the root namespace", current_id); + LLDB_LOG(log, " CAS::FEVD Searching the root namespace"); - FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl, - current_id); + FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl); } if (!context.m_namespace_map->empty()) { if (log && log->GetVerbose()) - LLDB_LOGF(log, - " CAS::FEVD[%u] Registering namespace map %p (%d entries)", - current_id, static_cast(context.m_namespace_map.get()), - static_cast(context.m_namespace_map->size())); + LLDB_LOG(log, " CAS::FEVD Registering namespace map {0} ({1} entries)", + context.m_namespace_map.get(), context.m_namespace_map->size()); NamespaceDecl *clang_namespace_decl = AddNamespace(context, context.m_namespace_map); @@ -658,7 +585,7 @@ bool ClangASTSource::IgnoreName(const ConstString name, void ClangASTSource::FindExternalVisibleDecls( NameSearchContext &context, lldb::ModuleSP module_sp, - CompilerDeclContext &namespace_decl, unsigned int current_id) { + CompilerDeclContext &namespace_decl) { assert(m_ast_context); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); @@ -672,196 +599,113 @@ void ClangASTSource::FindExternalVisibleDecls( if (!m_target) return; - if (module_sp && namespace_decl) { - CompilerDeclContext found_namespace_decl; - - if (SymbolFile *symbol_file = module_sp->GetSymbolFile()) { - found_namespace_decl = symbol_file->FindNamespace(name, &namespace_decl); + FillNamespaceMap(context, module_sp, namespace_decl); - if (found_namespace_decl) { - context.m_namespace_map->push_back( - std::pair( - module_sp, found_namespace_decl)); - - LLDB_LOGF(log, " CAS::FEVD[%u] Found namespace %s in module %s", - current_id, name.GetCString(), - module_sp->GetFileSpec().GetFilename().GetCString()); - } - } - } else { - const ModuleList &target_images = m_target->GetImages(); - std::lock_guard guard(target_images.GetMutex()); + if (context.m_found_type) + return; - for (size_t i = 0, e = target_images.GetSize(); i < e; ++i) { - lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i); + TypeList types; + const bool exact_match = true; + llvm::DenseSet searched_symbol_files; + if (module_sp && namespace_decl) + module_sp->FindTypesInNamespace(name, namespace_decl, 1, types); + else { + m_target->GetImages().FindTypes(module_sp.get(), name, exact_match, 1, + searched_symbol_files, types); + } - if (!image) - continue; + if (size_t num_types = types.GetSize()) { + for (size_t ti = 0; ti < num_types; ++ti) { + lldb::TypeSP type_sp = types.GetTypeAtIndex(ti); - CompilerDeclContext found_namespace_decl; + if (log) { + const char *name_string = type_sp->GetName().GetCString(); - SymbolFile *symbol_file = image->GetSymbolFile(); + LLDB_LOG(log, " CAS::FEVD Matching type found for \"{0}\": {1}", name, + (name_string ? name_string : "")); + } - if (!symbol_file) - continue; + CompilerType full_type = type_sp->GetFullCompilerType(); - found_namespace_decl = symbol_file->FindNamespace(name, &namespace_decl); + CompilerType copied_clang_type(GuardedCopyType(full_type)); - if (found_namespace_decl) { - context.m_namespace_map->push_back( - std::pair( - image, found_namespace_decl)); + if (!copied_clang_type) { + LLDB_LOG(log, " CAS::FEVD - Couldn't export a type"); - LLDB_LOGF(log, " CAS::FEVD[%u] Found namespace %s in module %s", - current_id, name.GetCString(), - image->GetFileSpec().GetFilename().GetCString()); + continue; } - } - } - do { - if (context.m_found.type) - break; + context.AddTypeDecl(copied_clang_type); - TypeList types; - const bool exact_match = true; - llvm::DenseSet searched_symbol_files; - if (module_sp && namespace_decl) - module_sp->FindTypesInNamespace(name, &namespace_decl, 1, types); - else { - m_target->GetImages().FindTypes(module_sp.get(), name, exact_match, 1, - searched_symbol_files, types); + context.m_found_type = true; + break; } + } - if (size_t num_types = types.GetSize()) { - for (size_t ti = 0; ti < num_types; ++ti) { - lldb::TypeSP type_sp = types.GetTypeAtIndex(ti); - - if (log) { - const char *name_string = type_sp->GetName().GetCString(); + if (!context.m_found_type) { + // Try the modules next. + FindDeclInModules(context, name); + } - LLDB_LOGF(log, " CAS::FEVD[%u] Matching type found for \"%s\": %s", - current_id, name.GetCString(), - (name_string ? name_string : "")); - } + if (!context.m_found_type) { + FindDeclInObjCRuntime(context, name); + } +} - CompilerType full_type = type_sp->GetFullCompilerType(); +void ClangASTSource::FillNamespaceMap( + NameSearchContext &context, lldb::ModuleSP module_sp, + const CompilerDeclContext &namespace_decl) { + const ConstString name(context.m_decl_name.getAsString().c_str()); + if (IgnoreName(name, true)) + return; - CompilerType copied_clang_type(GuardedCopyType(full_type)); + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - if (!copied_clang_type) { - LLDB_LOGF(log, " CAS::FEVD[%u] - Couldn't export a type", - current_id); + if (module_sp && namespace_decl) { + CompilerDeclContext found_namespace_decl; - continue; - } + if (SymbolFile *symbol_file = module_sp->GetSymbolFile()) { + found_namespace_decl = symbol_file->FindNamespace(name, namespace_decl); - context.AddTypeDecl(copied_clang_type); + if (found_namespace_decl) { + context.m_namespace_map->push_back( + std::pair( + module_sp, found_namespace_decl)); - context.m_found.type = true; - break; + LLDB_LOG(log, " CAS::FEVD Found namespace {0} in module {1}", name, + module_sp->GetFileSpec().GetFilename()); } } + return; + } - if (!context.m_found.type) { - // Try the modules next. - - do { - if (ClangModulesDeclVendor *modules_decl_vendor = - m_target->GetClangModulesDeclVendor()) { - bool append = false; - uint32_t max_matches = 1; - std::vector decls; - - if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls)) - break; - - if (log) { - LLDB_LOGF(log, - " CAS::FEVD[%u] Matching entity found for \"%s\" in " - "the modules", - current_id, name.GetCString()); - } - - clang::NamedDecl *const decl_from_modules = decls[0]; - - if (llvm::isa(decl_from_modules) || - llvm::isa(decl_from_modules) || - llvm::isa(decl_from_modules)) { - clang::Decl *copied_decl = CopyDecl(decl_from_modules); - clang::NamedDecl *copied_named_decl = - copied_decl ? dyn_cast(copied_decl) : nullptr; - - if (!copied_named_decl) { - LLDB_LOGF( - log, - " CAS::FEVD[%u] - Couldn't export a type from the modules", - current_id); - - break; - } - - context.AddNamedDecl(copied_named_decl); - - context.m_found.type = true; - } - } - } while (false); - } - - if (!context.m_found.type) { - do { - // Couldn't find any types elsewhere. Try the Objective-C runtime if - // one exists. - - lldb::ProcessSP process(m_target->GetProcessSP()); - - if (!process) - break; - - ObjCLanguageRuntime *language_runtime( - ObjCLanguageRuntime::Get(*process)); - - if (!language_runtime) - break; - - DeclVendor *decl_vendor = language_runtime->GetDeclVendor(); + const ModuleList &target_images = m_target->GetImages(); + std::lock_guard guard(target_images.GetMutex()); - if (!decl_vendor) - break; + for (size_t i = 0, e = target_images.GetSize(); i < e; ++i) { + lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i); - bool append = false; - uint32_t max_matches = 1; - std::vector decls; + if (!image) + continue; - auto *clang_decl_vendor = llvm::cast(decl_vendor); - if (!clang_decl_vendor->FindDecls(name, append, max_matches, decls)) - break; + CompilerDeclContext found_namespace_decl; - if (log) { - LLDB_LOGF( - log, - " CAS::FEVD[%u] Matching type found for \"%s\" in the runtime", - current_id, name.GetCString()); - } + SymbolFile *symbol_file = image->GetSymbolFile(); - clang::Decl *copied_decl = CopyDecl(decls[0]); - clang::NamedDecl *copied_named_decl = - copied_decl ? dyn_cast(copied_decl) : nullptr; + if (!symbol_file) + continue; - if (!copied_named_decl) { - LLDB_LOGF(log, - " CAS::FEVD[%u] - Couldn't export a type from the runtime", - current_id); + found_namespace_decl = symbol_file->FindNamespace(name, namespace_decl); - break; - } + if (found_namespace_decl) { + context.m_namespace_map->push_back( + std::pair(image, + found_namespace_decl)); - context.AddNamedDecl(copied_named_decl); - } while (false); + LLDB_LOG(log, " CAS::FEVD Found namespace {0} in module {1}", name, + image->GetFileSpec().GetFilename()); } - - } while (false); + } } template class TaggedASTDecl { @@ -915,8 +759,8 @@ DeclFromParser DeclFromUser::Import(ClangASTSource &source) { } bool ClangASTSource::FindObjCMethodDeclsWithOrigin( - unsigned int current_id, NameSearchContext &context, - ObjCInterfaceDecl *original_interface_decl, const char *log_info) { + NameSearchContext &context, ObjCInterfaceDecl *original_interface_decl, + const char *log_info) { const DeclarationName &decl_name(context.m_decl_name); clang::ASTContext *original_ctx = &original_interface_decl->getASTContext(); @@ -951,7 +795,7 @@ bool ClangASTSource::FindObjCMethodDeclsWithOrigin( llvm::SmallVector methods; - ClangASTContext::GetCompleteDecl(original_ctx, original_interface_decl); + TypeSystemClang::GetCompleteDecl(original_ctx, original_interface_decl); if (ObjCMethodDecl *instance_method_decl = original_interface_decl->lookupInstanceMethod(original_selector)) { @@ -987,7 +831,7 @@ bool ClangASTSource::FindObjCMethodDeclsWithOrigin( Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - LLDB_LOG(log, " CAS::FOMD[{0}] found ({1}) {2}", current_id, log_info, + LLDB_LOG(log, " CAS::FOMD found ({0}) {1}", log_info, ClangUtil::DumpDecl(copied_method_decl)); context.AddNamedDecl(copied_method_decl); @@ -996,11 +840,91 @@ bool ClangASTSource::FindObjCMethodDeclsWithOrigin( return true; } -void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { +void ClangASTSource::FindDeclInModules(NameSearchContext &context, + ConstString name) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; + ClangModulesDeclVendor *modules_decl_vendor = + m_target->GetClangModulesDeclVendor(); + if (!modules_decl_vendor) + return; + + bool append = false; + uint32_t max_matches = 1; + std::vector decls; + + if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls)) + return; + + LLDB_LOG(log, " CAS::FEVD Matching entity found for \"{0}\" in the modules", + name); + + clang::NamedDecl *const decl_from_modules = decls[0]; + + if (llvm::isa(decl_from_modules) || + llvm::isa(decl_from_modules) || + llvm::isa(decl_from_modules)) { + clang::Decl *copied_decl = CopyDecl(decl_from_modules); + clang::NamedDecl *copied_named_decl = + copied_decl ? dyn_cast(copied_decl) : nullptr; + + if (!copied_named_decl) { + LLDB_LOG(log, " CAS::FEVD - Couldn't export a type from the modules"); + + return; + } + + context.AddNamedDecl(copied_named_decl); + + context.m_found_type = true; + } +} + +void ClangASTSource::FindDeclInObjCRuntime(NameSearchContext &context, + ConstString name) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + lldb::ProcessSP process(m_target->GetProcessSP()); + + if (!process) + return; + + ObjCLanguageRuntime *language_runtime(ObjCLanguageRuntime::Get(*process)); + + if (!language_runtime) + return; + + DeclVendor *decl_vendor = language_runtime->GetDeclVendor(); + + if (!decl_vendor) + return; + + bool append = false; + uint32_t max_matches = 1; + std::vector decls; + + auto *clang_decl_vendor = llvm::cast(decl_vendor); + if (!clang_decl_vendor->FindDecls(name, append, max_matches, decls)) + return; + + LLDB_LOG(log, " CAS::FEVD Matching type found for \"{0}\" in the runtime", + name); + + clang::Decl *copied_decl = CopyDecl(decls[0]); + clang::NamedDecl *copied_named_decl = + copied_decl ? dyn_cast(copied_decl) : nullptr; + + if (!copied_named_decl) { + LLDB_LOG(log, " CAS::FEVD - Couldn't export a type from the runtime"); + + return; + } + + context.AddNamedDecl(copied_named_decl); +} + +void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); const DeclarationName &decl_name(context.m_decl_name); const DeclContext *decl_ctx(context.m_decl_context); @@ -1020,8 +944,8 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { ObjCInterfaceDecl *original_interface_decl = dyn_cast(original.decl); - if (FindObjCMethodDeclsWithOrigin(current_id, context, - original_interface_decl, "at origin")) + if (FindObjCMethodDeclsWithOrigin(context, original_interface_decl, + "at origin")) return; // found it, no need to look any further } while (false); @@ -1046,12 +970,11 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { ConstString selector_name(ss.GetString()); - LLDB_LOGF(log, - "ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p " - "for selector [%s %s]", - current_id, static_cast(m_ast_context), - interface_decl->getNameAsString().c_str(), - selector_name.AsCString()); + LLDB_LOG(log, + "ClangASTSource::FindObjCMethodDecls on (ASTContext*){0} '{1}' " + "for selector [{2} {3}]", + m_ast_context, m_clang_ast_context->getDisplayName(), + interface_decl->getName(), selector_name); SymbolContextList sc_list; const bool include_symbols = false; @@ -1148,7 +1071,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { continue; ObjCMethodDecl *method_decl = - ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx); + TypeSystemClang::DeclContextGetAsObjCMethodDecl(function_decl_ctx); if (!method_decl) continue; @@ -1171,7 +1094,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { if (!copied_method_decl) continue; - LLDB_LOG(log, " CAS::FOMD[{0}] found (in symbols)\n{1}", current_id, + LLDB_LOG(log, " CAS::FOMD found (in symbols)\n{0}", ClangUtil::DumpDecl(copied_method_decl)); context.AddNamedDecl(copied_method_decl); @@ -1199,13 +1122,12 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { if (complete_interface_decl == interface_decl) break; // already checked this one - LLDB_LOGF(log, - "CAS::FOPD[%d] trying origin " - "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...", - current_id, static_cast(complete_interface_decl), - static_cast(&complete_iface_decl->getASTContext())); + LLDB_LOG(log, + "CAS::FOPD trying origin " + "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...", + complete_interface_decl, &complete_iface_decl->getASTContext()); - FindObjCMethodDeclsWithOrigin(current_id, context, complete_interface_decl, + FindObjCMethodDeclsWithOrigin(context, complete_interface_decl, "in debug info"); return; @@ -1232,8 +1154,8 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { if (!interface_decl_from_modules) break; - if (FindObjCMethodDeclsWithOrigin( - current_id, context, interface_decl_from_modules, "in modules")) + if (FindObjCMethodDeclsWithOrigin(context, interface_decl_from_modules, + "in modules")) return; } } while (false); @@ -1273,13 +1195,13 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { if (!runtime_interface_decl) break; - FindObjCMethodDeclsWithOrigin(current_id, context, runtime_interface_decl, + FindObjCMethodDeclsWithOrigin(context, runtime_interface_decl, "in runtime"); } while (false); } static bool FindObjCPropertyAndIvarDeclsWithOrigin( - unsigned int current_id, NameSearchContext &context, ClangASTSource &source, + NameSearchContext &context, ClangASTSource &source, DeclFromUser &origin_iface_decl) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); @@ -1301,7 +1223,7 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin( DeclFromParser parser_property_decl( origin_property_decl.Import(source)); if (parser_property_decl.IsValid()) { - LLDB_LOG(log, " CAS::FOPD[{0}] found\n{1}", current_id, + LLDB_LOG(log, " CAS::FOPD found\n{0}", ClangUtil::DumpDecl(parser_property_decl.decl)); context.AddNamedDecl(parser_property_decl.decl); @@ -1316,10 +1238,8 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin( DeclFromParser parser_ivar_decl( origin_ivar_decl.Import(source)); if (parser_ivar_decl.IsValid()) { - if (log) { - LLDB_LOG(log, " CAS::FOPD[{0}] found\n{1}", current_id, - ClangUtil::DumpDecl(parser_ivar_decl.decl)); - } + LLDB_LOG(log, " CAS::FOPD found\n{0}", + ClangUtil::DumpDecl(parser_ivar_decl.decl)); context.AddNamedDecl(parser_ivar_decl.decl); found = true; @@ -1332,9 +1252,6 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin( void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; - DeclFromParser parser_iface_decl( cast(context.m_decl_context)); DeclFromUser origin_iface_decl( @@ -1342,23 +1259,20 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { ConstString class_name(parser_iface_decl->getNameAsString().c_str()); - LLDB_LOGF(log, - "ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on " - "(ASTContext*)%p for '%s.%s'", - current_id, static_cast(m_ast_context), - parser_iface_decl->getNameAsString().c_str(), - context.m_decl_name.getAsString().c_str()); + LLDB_LOG(log, + "ClangASTSource::FindObjCPropertyAndIvarDecls on " + "(ASTContext*){0} '{1}' for '{2}.{3}'", + m_ast_context, m_clang_ast_context->getDisplayName(), + parser_iface_decl->getName(), context.m_decl_name.getAsString()); - if (FindObjCPropertyAndIvarDeclsWithOrigin( - current_id, context, *this, origin_iface_decl)) + if (FindObjCPropertyAndIvarDeclsWithOrigin(context, *this, origin_iface_decl)) return; - LLDB_LOGF(log, - "CAS::FOPD[%d] couldn't find the property on origin " - "(ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching " - "elsewhere...", - current_id, static_cast(origin_iface_decl.decl), - static_cast(&origin_iface_decl->getASTContext())); + LLDB_LOG(log, + "CAS::FOPD couldn't find the property on origin " + "(ObjCInterfaceDecl*){0}/(ASTContext*){1}, searching " + "elsewhere...", + origin_iface_decl.decl, &origin_iface_decl->getASTContext()); SymbolContext null_sc; TypeList type_list; @@ -1379,14 +1293,12 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { if (complete_iface_decl.decl == origin_iface_decl.decl) break; // already checked this one - LLDB_LOGF(log, - "CAS::FOPD[%d] trying origin " - "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...", - current_id, static_cast(complete_iface_decl.decl), - static_cast(&complete_iface_decl->getASTContext())); + LLDB_LOG(log, + "CAS::FOPD trying origin " + "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...", + complete_iface_decl.decl, &complete_iface_decl->getASTContext()); - FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this, - complete_iface_decl); + FindObjCPropertyAndIvarDeclsWithOrigin(context, *this, complete_iface_decl); return; } while (false); @@ -1414,14 +1326,13 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { if (!interface_decl_from_modules.IsValid()) break; - LLDB_LOGF( - log, - "CAS::FOPD[%d] trying module " - "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...", - current_id, static_cast(interface_decl_from_modules.decl), - static_cast(&interface_decl_from_modules->getASTContext())); + LLDB_LOG(log, + "CAS::FOPD[{0}] trying module " + "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...", + interface_decl_from_modules.decl, + &interface_decl_from_modules->getASTContext()); - if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this, + if (FindObjCPropertyAndIvarDeclsWithOrigin(context, *this, interface_decl_from_modules)) return; } while (false); @@ -1459,19 +1370,43 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { if (!interface_decl_from_runtime.IsValid()) break; - LLDB_LOGF( - log, - "CAS::FOPD[%d] trying runtime " - "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...", - current_id, static_cast(interface_decl_from_runtime.decl), - static_cast(&interface_decl_from_runtime->getASTContext())); + LLDB_LOG(log, + "CAS::FOPD[{0}] trying runtime " + "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...", + interface_decl_from_runtime.decl, + &interface_decl_from_runtime->getASTContext()); - if (FindObjCPropertyAndIvarDeclsWithOrigin( - current_id, context, *this, interface_decl_from_runtime)) + if (FindObjCPropertyAndIvarDeclsWithOrigin(context, *this, + interface_decl_from_runtime)) return; } while (false); } +void ClangASTSource::LookupInNamespace(NameSearchContext &context) { + const NamespaceDecl *namespace_context = + dyn_cast(context.m_decl_context); + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + ClangASTImporter::NamespaceMapSP namespace_map = + m_ast_importer_sp->GetNamespaceMap(namespace_context); + + LLDB_LOGV(log, " CAS::FEVD Inspecting namespace map {0} ({1} entries)", + namespace_map.get(), namespace_map->size()); + + if (!namespace_map) + return; + + for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), + e = namespace_map->end(); + i != e; ++i) { + LLDB_LOG(log, " CAS::FEVD Searching namespace {0} in module {1}", + i->second.GetName(), i->first->GetFileSpec().GetFilename()); + + FindExternalVisibleDecls(context, i->first, i->second); + } +} + typedef llvm::DenseMap FieldOffsetMap; typedef llvm::DenseMap BaseOffsetMap; @@ -1557,17 +1492,14 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, FieldOffsetMap &field_offsets, BaseOffsetMap &base_offsets, BaseOffsetMap &virtual_base_offsets) { - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - LLDB_LOGF(log, - "LayoutRecordType[%u] on (ASTContext*)%p for (RecordDecl*)%p " - "[name = '%s']", - current_id, static_cast(m_ast_context), - static_cast(record), - record->getNameAsString().c_str()); + LLDB_LOG(log, + "LayoutRecordType on (ASTContext*){0} '{1}' for (RecordDecl*)" + "{3} [name = '{4}']", + m_ast_context, m_clang_ast_context->getDisplayName(), record, + record->getName()); DeclFromParser parser_record(record); DeclFromUser origin_record( @@ -1580,7 +1512,7 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, BaseOffsetMap origin_base_offsets; BaseOffsetMap origin_virtual_base_offsets; - ClangASTContext::GetCompleteDecl( + TypeSystemClang::GetCompleteDecl( &origin_record->getASTContext(), const_cast(origin_record.decl)); @@ -1631,25 +1563,23 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, m_ast_context->getCharWidth(); if (log) { - LLDB_LOGF(log, "LRT[%u] returned:", current_id); - LLDB_LOGF(log, "LRT[%u] Original = (RecordDecl*)%p", current_id, - static_cast(origin_record.decl)); - LLDB_LOGF(log, "LRT[%u] Size = %" PRId64, current_id, size); - LLDB_LOGF(log, "LRT[%u] Alignment = %" PRId64, current_id, alignment); - LLDB_LOGF(log, "LRT[%u] Fields:", current_id); + LLDB_LOG(log, "LRT returned:"); + LLDB_LOG(log, "LRT Original = (RecordDecl*)%p", + static_cast(origin_record.decl)); + LLDB_LOG(log, "LRT Size = %" PRId64, size); + LLDB_LOG(log, "LRT Alignment = %" PRId64, alignment); + LLDB_LOG(log, "LRT Fields:"); for (RecordDecl::field_iterator fi = record->field_begin(), fe = record->field_end(); fi != fe; ++fi) { - LLDB_LOGF(log, - "LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64 - " bits", - current_id, static_cast(*fi), - fi->getNameAsString().c_str(), field_offsets[*fi]); + LLDB_LOG(log, + "LRT (FieldDecl*){0}, Name = '{1}', Offset = {2} bits", + *fi, fi->getName(), field_offsets[*fi]); } DeclFromParser parser_cxx_record = DynCast(parser_record); if (parser_cxx_record.IsValid()) { - LLDB_LOGF(log, "LRT[%u] Bases:", current_id); + LLDB_LOG(log, "LRT Bases:"); for (CXXRecordDecl::base_class_const_iterator bi = parser_cxx_record->bases_begin(), be = parser_cxx_record->bases_end(); @@ -1662,19 +1592,17 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, DeclFromParser base_cxx_record = DynCast(base_record); - LLDB_LOGF( - log, - "LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64 - " chars", - current_id, (is_virtual ? "Virtual " : ""), - static_cast(base_cxx_record.decl), - base_cxx_record.decl->getNameAsString().c_str(), - (is_virtual - ? virtual_base_offsets[base_cxx_record.decl].getQuantity() - : base_offsets[base_cxx_record.decl].getQuantity())); + LLDB_LOG(log, + "LRT {0}(CXXRecordDecl*){1}, Name = '{2}', Offset = " + "{3} chars", + (is_virtual ? "Virtual " : ""), base_cxx_record.decl, + base_cxx_record.decl->getName(), + (is_virtual + ? virtual_base_offsets[base_cxx_record.decl].getQuantity() + : base_offsets[base_cxx_record.decl].getQuantity())); } } else { - LLDB_LOGF(log, "LRD[%u] Not a CXXRecord, so no bases", current_id); + LLDB_LOG(log, "LRD Not a CXXRecord, so no bases"); } } @@ -1684,25 +1612,21 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, void ClangASTSource::CompleteNamespaceMap( ClangASTImporter::NamespaceMapSP &namespace_map, ConstString name, ClangASTImporter::NamespaceMapSP &parent_map) const { - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); if (log) { if (parent_map && parent_map->size()) - LLDB_LOGF(log, - "CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for " - "namespace %s in namespace %s", - current_id, static_cast(m_ast_context), - name.GetCString(), - parent_map->begin()->second.GetName().AsCString()); + LLDB_LOG(log, + "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching " + "for namespace {2} in namespace {3}", + m_ast_context, m_clang_ast_context->getDisplayName(), name, + parent_map->begin()->second.GetName()); else - LLDB_LOGF(log, - "CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for " - "namespace %s", - current_id, static_cast(m_ast_context), - name.GetCString()); + LLDB_LOG(log, + "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching " + "for namespace {2}", + m_ast_context, m_clang_ast_context->getDisplayName(), name); } if (parent_map) { @@ -1720,7 +1644,7 @@ void ClangASTSource::CompleteNamespaceMap( continue; found_namespace_decl = - symbol_file->FindNamespace(name, &module_parent_namespace_decl); + symbol_file->FindNamespace(name, module_parent_namespace_decl); if (!found_namespace_decl) continue; @@ -1728,9 +1652,8 @@ void ClangASTSource::CompleteNamespaceMap( namespace_map->push_back(std::pair( module_sp, found_namespace_decl)); - LLDB_LOGF(log, " CMN[%u] Found namespace %s in module %s", current_id, - name.GetCString(), - module_sp->GetFileSpec().GetFilename().GetCString()); + LLDB_LOG(log, " CMN Found namespace {0} in module {1}", name, + module_sp->GetFileSpec().GetFilename()); } } else { const ModuleList &target_images = m_target->GetImages(); @@ -1752,7 +1675,7 @@ void ClangASTSource::CompleteNamespaceMap( continue; found_namespace_decl = - symbol_file->FindNamespace(name, &null_namespace_decl); + symbol_file->FindNamespace(name, null_namespace_decl); if (!found_namespace_decl) continue; @@ -1760,9 +1683,8 @@ void ClangASTSource::CompleteNamespaceMap( namespace_map->push_back(std::pair( image, found_namespace_decl)); - LLDB_LOGF(log, " CMN[%u] Found namespace %s in module %s", current_id, - name.GetCString(), - image->GetFileSpec().GetFilename().GetCString()); + LLDB_LOG(log, " CMN[{0}] Found namespace {0} in module {1}", name, + image->GetFileSpec().GetFilename()); } } } @@ -1776,11 +1698,11 @@ NamespaceDecl *ClangASTSource::AddNamespace( const CompilerDeclContext &namespace_decl = namespace_decls->begin()->second; clang::ASTContext *src_ast = - ClangASTContext::DeclContextGetClangASTContext(namespace_decl); + TypeSystemClang::DeclContextGetTypeSystemClang(namespace_decl); if (!src_ast) return nullptr; clang::NamespaceDecl *src_namespace_decl = - ClangASTContext::DeclContextGetAsNamespaceDecl(namespace_decl); + TypeSystemClang::DeclContextGetAsNamespaceDecl(namespace_decl); if (!src_namespace_decl) return nullptr; @@ -1804,42 +1726,21 @@ NamespaceDecl *ClangASTSource::AddNamespace( } clang::Decl *ClangASTSource::CopyDecl(Decl *src_decl) { - if (m_ast_importer_sp) { - return m_ast_importer_sp->CopyDecl(m_ast_context, src_decl); - } else { - lldbassert(0 && "No mechanism for copying a decl!"); - return nullptr; - } + return m_ast_importer_sp->CopyDecl(m_ast_context, src_decl); } ClangASTImporter::DeclOrigin ClangASTSource::GetDeclOrigin(const clang::Decl *decl) { - if (m_ast_importer_sp) { - return m_ast_importer_sp->GetDeclOrigin(decl); - } else { - // this can happen early enough that no ExternalASTSource is installed. - return ClangASTImporter::DeclOrigin(); - } + return m_ast_importer_sp->GetDeclOrigin(decl); } CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) { - ClangASTContext *src_ast = - llvm::dyn_cast_or_null(src_type.GetTypeSystem()); + TypeSystemClang *src_ast = + llvm::dyn_cast_or_null(src_type.GetTypeSystem()); if (src_ast == nullptr) return CompilerType(); - SetImportInProgress(true); - - QualType copied_qual_type; - - if (m_ast_importer_sp) { - copied_qual_type = ClangUtil::GetQualType( - m_ast_importer_sp->CopyType(*m_clang_ast_context, src_type)); - } else { - lldbassert(0 && "No mechanism for copying a type!"); - return CompilerType(); - } - - SetImportInProgress(false); + QualType copied_qual_type = ClangUtil::GetQualType( + m_ast_importer_sp->CopyType(*m_clang_ast_context, src_type)); if (copied_qual_type.getAsOpaquePtr() && copied_qual_type->getCanonicalTypeInternal().isNull()) @@ -1849,170 +1750,3 @@ CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) { return m_clang_ast_context->GetType(copied_qual_type); } - -clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) { - assert(type && "Type for variable must be valid!"); - - if (!type.IsValid()) - return nullptr; - - ClangASTContext *lldb_ast = - llvm::dyn_cast(type.GetTypeSystem()); - if (!lldb_ast) - return nullptr; - - IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo(); - - clang::ASTContext &ast = lldb_ast->getASTContext(); - - clang::NamedDecl *Decl = VarDecl::Create( - ast, const_cast(m_decl_context), SourceLocation(), - SourceLocation(), ii, ClangUtil::GetQualType(type), nullptr, SC_Static); - m_decls.push_back(Decl); - - return Decl; -} - -clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type, - bool extern_c) { - assert(type && "Type for variable must be valid!"); - - if (!type.IsValid()) - return nullptr; - - if (m_function_types.count(type)) - return nullptr; - - ClangASTContext *lldb_ast = - llvm::dyn_cast(type.GetTypeSystem()); - if (!lldb_ast) - return nullptr; - - m_function_types.insert(type); - - QualType qual_type(ClangUtil::GetQualType(type)); - - clang::ASTContext &ast = lldb_ast->getASTContext(); - - const bool isInlineSpecified = false; - const bool hasWrittenPrototype = true; - const bool isConstexprSpecified = false; - - clang::DeclContext *context = const_cast(m_decl_context); - - if (extern_c) { - context = LinkageSpecDecl::Create( - ast, context, SourceLocation(), SourceLocation(), - clang::LinkageSpecDecl::LanguageIDs::lang_c, false); - } - - // Pass the identifier info for functions the decl_name is needed for - // operators - clang::DeclarationName decl_name = - m_decl_name.getNameKind() == DeclarationName::Identifier - ? m_decl_name.getAsIdentifierInfo() - : m_decl_name; - - clang::FunctionDecl *func_decl = FunctionDecl::Create( - ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type, - nullptr, SC_Extern, isInlineSpecified, hasWrittenPrototype, - isConstexprSpecified ? CSK_constexpr : CSK_unspecified); - - // We have to do more than just synthesize the FunctionDecl. We have to - // synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do - // this, we raid the function's FunctionProtoType for types. - - const FunctionProtoType *func_proto_type = - qual_type.getTypePtr()->getAs(); - - if (func_proto_type) { - unsigned NumArgs = func_proto_type->getNumParams(); - unsigned ArgIndex; - - SmallVector parm_var_decls; - - for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex) { - QualType arg_qual_type(func_proto_type->getParamType(ArgIndex)); - - parm_var_decls.push_back( - ParmVarDecl::Create(ast, const_cast(context), - SourceLocation(), SourceLocation(), nullptr, - arg_qual_type, nullptr, SC_Static, nullptr)); - } - - func_decl->setParams(ArrayRef(parm_var_decls)); - } else { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - - LLDB_LOGF(log, "Function type wasn't a FunctionProtoType"); - } - - // If this is an operator (e.g. operator new or operator==), only insert the - // declaration we inferred from the symbol if we can provide the correct - // number of arguments. We shouldn't really inject random decl(s) for - // functions that are analyzed semantically in a special way, otherwise we - // will crash in clang. - clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS; - if (func_proto_type && - ClangASTContext::IsOperator(decl_name.getAsString().c_str(), op_kind)) { - if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount( - false, op_kind, func_proto_type->getNumParams())) - return nullptr; - } - m_decls.push_back(func_decl); - - return func_decl; -} - -clang::NamedDecl *NameSearchContext::AddGenericFunDecl() { - FunctionProtoType::ExtProtoInfo proto_info; - - proto_info.Variadic = true; - - QualType generic_function_type(m_ast_source.m_ast_context->getFunctionType( - m_ast_source.m_ast_context->UnknownAnyTy, // result - ArrayRef(), // argument types - proto_info)); - - return AddFunDecl( - m_ast_source.m_clang_ast_context->GetType(generic_function_type), true); -} - -clang::NamedDecl * -NameSearchContext::AddTypeDecl(const CompilerType &clang_type) { - if (ClangUtil::IsClangType(clang_type)) { - QualType qual_type = ClangUtil::GetQualType(clang_type); - - if (const TypedefType *typedef_type = - llvm::dyn_cast(qual_type)) { - TypedefNameDecl *typedef_name_decl = typedef_type->getDecl(); - - m_decls.push_back(typedef_name_decl); - - return (NamedDecl *)typedef_name_decl; - } else if (const TagType *tag_type = qual_type->getAs()) { - TagDecl *tag_decl = tag_type->getDecl(); - - m_decls.push_back(tag_decl); - - return tag_decl; - } else if (const ObjCObjectType *objc_object_type = - qual_type->getAs()) { - ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface(); - - m_decls.push_back((NamedDecl *)interface_decl); - - return (NamedDecl *)interface_decl; - } - } - return nullptr; -} - -void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result) { - for (clang::NamedDecl *decl : result) - m_decls.push_back(decl); -} - -void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) { - m_decls.push_back(decl); -} diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h index 3149b4266b2..14761fbeb26 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h @@ -6,12 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ClangASTSource_h_ -#define liblldb_ClangASTSource_h_ +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H #include -#include "lldb/Symbol/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/NameSearchContext.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Target/Target.h" #include "clang/AST/ExternalASTSource.h" @@ -42,7 +43,7 @@ public: /// \param[in] importer /// The ClangASTImporter to use. ClangASTSource(const lldb::TargetSP &target, - const lldb::ClangASTImporterSP &importer); + const std::shared_ptr &importer); /// Destructor ~ClangASTSource() override; @@ -60,7 +61,7 @@ public: } void MaterializeVisibleDecls(const clang::DeclContext *DC) { return; } - void InstallASTContext(ClangASTContext &ast_context); + void InstallASTContext(TypeSystemClang &ast_context); // // APIs for ExternalASTSource @@ -196,11 +197,6 @@ public: clang::Sema *getSema(); - void SetImportInProgress(bool import_in_progress) { - m_import_in_progress = import_in_progress; - } - bool GetImportInProgress() { return m_import_in_progress; } - void SetLookupsEnabled(bool lookups_enabled) { m_lookups_enabled = lookups_enabled; } @@ -282,14 +278,9 @@ protected: /// /// \param[in] namespace_decl /// If valid and module is non-NULL, the parent namespace. - /// - /// \param[in] current_id - /// The ID for the current FindExternalVisibleDecls invocation, - /// for logging purposes. void FindExternalVisibleDecls(NameSearchContext &context, lldb::ModuleSP module, - CompilerDeclContext &namespace_decl, - unsigned int current_id); + CompilerDeclContext &namespace_decl); /// Find all Objective-C methods matching a given selector. /// @@ -307,7 +298,13 @@ protected: /// is the containing object. void FindObjCPropertyAndIvarDecls(NameSearchContext &context); - /// A wrapper for ClangASTContext::CopyType that sets a flag that + /// Performs lookup into a namespace. + /// + /// \param context + /// The NameSearchContext for a lookup inside a namespace. + void LookupInNamespace(NameSearchContext &context); + + /// A wrapper for TypeSystemClang::CopyType that sets a flag that /// indicates that we should not respond to queries during import. /// /// \param[in] src_type @@ -331,7 +328,6 @@ public: /// global lookup for performance reasons. bool IgnoreName(const ConstString name, bool ignore_all_dollar_names); -public: /// Copies a single Decl into the parser's AST context. /// /// \param[in] src_decl @@ -346,139 +342,51 @@ public: /// \param[in] decl /// The Decl whose origin is to be found. /// - /// \param[out] original_decl - /// A pointer whose target is filled in with the original Decl. - /// - /// \param[in] original_ctx - /// A pointer whose target is filled in with the original's ASTContext. - /// /// \return /// True if lookup succeeded; false otherwise. ClangASTImporter::DeclOrigin GetDeclOrigin(const clang::Decl *decl); + /// Returns the TypeSystem that uses this ClangASTSource instance as it's + /// ExternalASTSource. + TypeSystemClang *GetTypeSystem() const { return m_clang_ast_context; } + protected: bool FindObjCMethodDeclsWithOrigin( - unsigned int current_id, NameSearchContext &context, + NameSearchContext &context, clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info); + void FindDeclInModules(NameSearchContext &context, ConstString name); + void FindDeclInObjCRuntime(NameSearchContext &context, ConstString name); + + /// Fills the namespace map of the given NameSearchContext. + /// + /// \param context The NameSearchContext with the namespace map to fill. + /// \param module_sp The module to search for namespaces or a nullptr if + /// the current target should be searched. + /// \param namespace_decl The DeclContext in which to search for namespaces. + void FillNamespaceMap(NameSearchContext &context, lldb::ModuleSP module_sp, + const CompilerDeclContext &namespace_decl); + + clang::TagDecl *FindCompleteType(const clang::TagDecl *decl); + friend struct NameSearchContext; - bool m_import_in_progress; bool m_lookups_enabled; /// The target to use in finding variables and types. const lldb::TargetSP m_target; /// The AST context requests are coming in for. clang::ASTContext *m_ast_context; - /// The ClangASTContext for m_ast_context. - ClangASTContext *m_clang_ast_context; + /// The TypeSystemClang for m_ast_context. + TypeSystemClang *m_clang_ast_context; /// The file manager paired with the AST context. clang::FileManager *m_file_manager; /// The target's AST importer. - lldb::ClangASTImporterSP m_ast_importer_sp; + std::shared_ptr m_ast_importer_sp; std::set m_active_lexical_decls; std::set m_active_lookups; }; -/// \class NameSearchContext ClangASTSource.h -/// "lldb/Expression/ClangASTSource.h" Container for all objects relevant to a -/// single name lookup -/// -/// LLDB needs to create Decls for entities it finds. This class communicates -/// what name is being searched for and provides helper functions to construct -/// Decls given appropriate type information. -struct NameSearchContext { - /// The AST source making the request. - ClangASTSource &m_ast_source; - /// The list of declarations already constructed. - llvm::SmallVectorImpl &m_decls; - /// The mapping of all namespaces found for this request back to their - /// modules. - ClangASTImporter::NamespaceMapSP m_namespace_map; - /// The name being looked for. - const clang::DeclarationName &m_decl_name; - /// The DeclContext to put declarations into. - const clang::DeclContext *m_decl_context; - /// All the types of functions that have been reported, so we don't - /// report conflicts. - llvm::SmallSet m_function_types; - - struct { - bool variable : 1; - bool function_with_type_info : 1; - bool function : 1; - bool local_vars_nsp : 1; - bool type : 1; - } m_found; - - /// Constructor - /// - /// Initializes class variables. - /// - /// \param[in] astSource - /// A reference to the AST source making a request. - /// - /// \param[in] decls - /// A reference to a list into which new Decls will be placed. This - /// list is typically empty when the function is called. - /// - /// \param[in] name - /// The name being searched for (always an Identifier). - /// - /// \param[in] dc - /// The DeclContext to register Decls in. - NameSearchContext(ClangASTSource &astSource, - llvm::SmallVectorImpl &decls, - clang::DeclarationName &name, const clang::DeclContext *dc) - : m_ast_source(astSource), m_decls(decls), m_decl_name(name), - m_decl_context(dc) { - memset(&m_found, 0, sizeof(m_found)); - } - - /// Create a VarDecl with the name being searched for and the provided type - /// and register it in the right places. - /// - /// \param[in] type - /// The opaque QualType for the VarDecl being registered. - clang::NamedDecl *AddVarDecl(const CompilerType &type); - - /// Create a FunDecl with the name being searched for and the provided type - /// and register it in the right places. - /// - /// \param[in] type - /// The opaque QualType for the FunDecl being registered. - /// - /// \param[in] extern_c - /// If true, build an extern "C" linkage specification for this. - clang::NamedDecl *AddFunDecl(const CompilerType &type, bool extern_c = false); - - /// Create a FunDecl with the name being searched for and generic type (i.e. - /// intptr_t NAME_GOES_HERE(...)) and register it in the right places. - clang::NamedDecl *AddGenericFunDecl(); - - /// Create a TypeDecl with the name being searched for and the provided type - /// and register it in the right places. - /// - /// \param[in] compiler_type - /// The opaque QualType for the TypeDecl being registered. - clang::NamedDecl *AddTypeDecl(const CompilerType &compiler_type); - - /// Add Decls from the provided DeclContextLookupResult to the list of - /// results. - /// - /// \param[in] result - /// The DeclContextLookupResult, usually returned as the result - /// of querying a DeclContext. - void AddLookupResult(clang::DeclContextLookupResult result); - - /// Add a NamedDecl to the list of results. - /// - /// \param[in] decl - /// The NamedDecl, usually returned as the result - /// of querying a DeclContext. - void AddNamedDecl(clang::NamedDecl *decl); -}; - } // namespace lldb_private -#endif // liblldb_ClangASTSource_h_ +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp index c87507a2585..867d4ff0a90 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp @@ -1,4 +1,4 @@ -//===-- ClangDeclVendor.cpp -------------------------------------*- C++ -*-===// +//===-- ClangDeclVendor.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,8 +7,9 @@ //===----------------------------------------------------------------------===// #include "Plugins/ExpressionParser/Clang/ClangDeclVendor.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Utility/ConstString.h" using namespace lldb_private; @@ -22,7 +23,7 @@ uint32_t ClangDeclVendor::FindDecls(ConstString name, bool append, std::vector compiler_decls; uint32_t ret = FindDecls(name, /*append*/ false, max_matches, compiler_decls); for (CompilerDecl compiler_decl : compiler_decls) { - clang::Decl *d = static_cast(compiler_decl.GetOpaqueDecl()); + clang::Decl *d = ClangUtil::GetDecl(compiler_decl); clang::NamedDecl *nd = llvm::cast(d); decls.push_back(nd); } diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h index 0c888de0884..bf52bec4b1f 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h @@ -6,12 +6,15 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ClangDeclVendor_h_ -#define liblldb_ClangDeclVendor_h_ +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGDECLVENDOR_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGDECLVENDOR_H -#include "lldb/Core/ClangForward.h" #include "lldb/Symbol/DeclVendor.h" +namespace clang { +class NamedDecl; +} + namespace lldb_private { // A clang specialized extension to DeclVendor. @@ -32,7 +35,8 @@ public: } private: - DISALLOW_COPY_AND_ASSIGN(ClangDeclVendor); + ClangDeclVendor(const ClangDeclVendor &) = delete; + const ClangDeclVendor &operator=(const ClangDeclVendor &) = delete; }; } // namespace lldb_private diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h index 48cd1c4b99f..7459b715dbe 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_ClangDiagnostic_h -#define lldb_ClangDiagnostic_h +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGDIAGNOSTIC_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGDIAGNOSTIC_H #include @@ -47,4 +47,4 @@ private: }; } // namespace lldb_private -#endif /* lldb_ClangDiagnostic_h */ +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGDIAGNOSTIC_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp index bf3023be5f6..8c49898e1d6 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -1,4 +1,4 @@ -//===-- ClangExpressionDeclMap.cpp -----------------------------*- C++ -*-===// +//===-- ClangExpressionDeclMap.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -11,15 +11,15 @@ #include "ClangASTSource.h" #include "ClangModulesDeclVendor.h" #include "ClangPersistentVariables.h" +#include "ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Address.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Expression/Materializer.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" @@ -65,8 +65,8 @@ const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars"; ClangExpressionDeclMap::ClangExpressionDeclMap( bool keep_result_in_memory, Materializer::PersistentVariableDelegate *result_delegate, - const lldb::TargetSP &target, const lldb::ClangASTImporterSP &importer, - ValueObject *ctx_obj) + const lldb::TargetSP &target, + const std::shared_ptr &importer, ValueObject *ctx_obj) : ClangASTSource(target, importer), m_found_entities(), m_struct_members(), m_keep_result_in_memory(keep_result_in_memory), m_result_delegate(result_delegate), m_ctx_obj(ctx_obj), m_parser_vars(), @@ -109,7 +109,7 @@ bool ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx, m_parser_vars->m_persistent_vars = llvm::cast( target->GetPersistentExpressionStateForLanguage(eLanguageTypeC)); - if (!ClangASTContext::GetScratch(*target)) + if (!TypeSystemClang::GetScratch(*target)) return false; } @@ -174,19 +174,14 @@ ClangExpressionDeclMap::TargetInfo ClangExpressionDeclMap::GetTargetInfo() { return ret; } -TypeFromUser ClangExpressionDeclMap::DeportType(ClangASTContext &target, - ClangASTContext &source, +TypeFromUser ClangExpressionDeclMap::DeportType(TypeSystemClang &target, + TypeSystemClang &source, TypeFromParser parser_type) { - assert(&target == ClangASTContext::GetScratch(*m_target)); + assert(&target == TypeSystemClang::GetScratch(*m_target)); assert((TypeSystem *)&source == parser_type.GetTypeSystem()); assert(&source.getASTContext() == m_ast_context); - if (m_ast_importer_sp) { - return TypeFromUser(m_ast_importer_sp->DeportType(target, parser_type)); - } else { - lldbassert(0 && "No mechanism for deporting a type!"); - return TypeFromUser(); - } + return TypeFromUser(m_ast_importer_sp->DeportType(target, parser_type)); } bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl, @@ -196,8 +191,8 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl, bool is_lvalue) { assert(m_parser_vars.get()); - ClangASTContext *ast = - llvm::dyn_cast_or_null(parser_type.GetTypeSystem()); + TypeSystemClang *ast = + llvm::dyn_cast_or_null(parser_type.GetTypeSystem()); if (ast == nullptr) return false; @@ -209,7 +204,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl, if (target == nullptr) return false; - auto *clang_ast_context = ClangASTContext::GetScratch(*target); + auto *clang_ast_context = TypeSystemClang::GetScratch(*target); if (!clang_ast_context) return false; @@ -231,7 +226,6 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl, var->GetParserVars(GetParserID()); parser_vars->m_named_decl = decl; - parser_vars->m_parser_type = parser_type; var->EnableJITVars(GetParserID()); @@ -248,14 +242,14 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl, if (target == nullptr) return false; - ClangASTContext *context = ClangASTContext::GetScratch(*target); + TypeSystemClang *context = TypeSystemClang::GetScratch(*target); if (!context) return false; TypeFromUser user_type = DeportType(*context, *ast, parser_type); if (!user_type.GetOpaqueQualType()) { - LLDB_LOGF(log, "Persistent variable's type wasn't copied successfully"); + LLDB_LOG(log, "Persistent variable's type wasn't copied successfully"); return false; } @@ -297,7 +291,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl, var->m_flags |= ClangExpressionVariable::EVKeepInTarget; } - LLDB_LOGF(log, "Created persistent variable with flags 0x%hx", var->m_flags); + LLDB_LOG(log, "Created persistent variable with flags {0:x}", var->m_flags); var->EnableParserVars(GetParserID()); @@ -305,7 +299,6 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl, var->GetParserVars(GetParserID()); parser_vars->m_named_decl = decl; - parser_vars->m_parser_type = parser_type; return true; } @@ -339,9 +332,8 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl, if (!var) return false; - LLDB_LOGF(log, "Adding value for (NamedDecl*)%p [%s - %s] to the structure", - static_cast(decl), name.GetCString(), - var->GetName().GetCString()); + LLDB_LOG(log, "Adding value for (NamedDecl*)%p [%s - %s] to the structure", + decl, name, var->GetName()); // We know entity->m_parser_vars is valid because we used a parser variable // to find it @@ -355,8 +347,7 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl, llvm::cast(var)->GetJITVars(GetParserID())) { // We already laid this out; do not touch - LLDB_LOGF(log, "Already placed at 0x%llx", - (unsigned long long)jit_vars->m_offset); + LLDB_LOG(log, "Already placed at {0:x}", jit_vars->m_offset); } llvm::cast(var)->EnableJITVars(GetParserID()); @@ -391,7 +382,7 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl, if (!err.Success()) return false; - LLDB_LOGF(log, "Placed at 0x%llx", (unsigned long long)offset); + LLDB_LOG(log, "Placed at {0:x}", offset); jit_vars->m_offset = offset; // TODO DoStructLayout() should not change this. @@ -600,7 +591,7 @@ addr_t ClangExpressionDeclMap::GetSymbolAddress(ConstString name, lldb::VariableSP ClangExpressionDeclMap::FindGlobalVariable( Target &target, ModuleSP &module, ConstString name, - CompilerDeclContext *namespace_decl) { + const CompilerDeclContext &namespace_decl) { VariableList vars; if (module && namespace_decl) @@ -613,7 +604,7 @@ lldb::VariableSP ClangExpressionDeclMap::FindGlobalVariable( return vars.GetVariableAtIndex(0); } -ClangASTContext *ClangExpressionDeclMap::GetClangASTContext() { +TypeSystemClang *ClangExpressionDeclMap::GetTypeSystemClang() { StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); if (frame == nullptr) return nullptr; @@ -627,7 +618,7 @@ ClangASTContext *ClangExpressionDeclMap::GetClangASTContext() { if (!frame_decl_context) return nullptr; - return llvm::dyn_cast_or_null( + return llvm::dyn_cast_or_null( frame_decl_context.GetTypeSystem()); } @@ -641,34 +632,23 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - if (GetImportInProgress()) { - if (log && log->GetVerbose()) - LLDB_LOGF(log, "Ignoring a query during an import"); - return; - } - - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; - if (log) { if (!context.m_decl_context) - LLDB_LOGF(log, - "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for " - "'%s' in a NULL DeclContext", - current_id, name.GetCString()); + LLDB_LOG(log, + "ClangExpressionDeclMap::FindExternalVisibleDecls for " + "'{0}' in a NULL DeclContext", + name); else if (const NamedDecl *context_named_decl = dyn_cast(context.m_decl_context)) - LLDB_LOGF(log, - "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for " - "'%s' in '%s'", - current_id, name.GetCString(), - context_named_decl->getNameAsString().c_str()); + LLDB_LOG(log, + "ClangExpressionDeclMap::FindExternalVisibleDecls for " + "'{0}' in '{1}'", + name, context_named_decl->getNameAsString()); else - LLDB_LOGF(log, - "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for " - "'%s' in a '%s'", - current_id, name.GetCString(), - context.m_decl_context->getDeclKindName()); + LLDB_LOG(log, + "ClangExpressionDeclMap::FindExternalVisibleDecls for " + "'{0}' in a '{1}'", + name, context.m_decl_context->getDeclKindName()); } if (const NamespaceDecl *namespace_context = @@ -678,42 +658,31 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( CompilerDeclContext compiler_decl_ctx = m_clang_ast_context->CreateDeclContext( const_cast(context.m_decl_context)); - FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx, - current_id); + FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx); return; } ClangASTImporter::NamespaceMapSP namespace_map = - m_ast_importer_sp - ? m_ast_importer_sp->GetNamespaceMap(namespace_context) - : ClangASTImporter::NamespaceMapSP(); + m_ast_importer_sp->GetNamespaceMap(namespace_context); if (!namespace_map) return; - if (log && log->GetVerbose()) - log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)", - current_id, static_cast(namespace_map.get()), - (int)namespace_map->size()); + LLDB_LOGV(log, " CEDM::FEVD Inspecting (NamespaceMap*){0:x} ({1} entries)", + namespace_map.get(), namespace_map->size()); - for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), - e = namespace_map->end(); - i != e; ++i) { - if (log) - log->Printf(" CEDM::FEVD[%u] Searching namespace %s in module %s", - current_id, i->second.GetName().AsCString(), - i->first->GetFileSpec().GetFilename().GetCString()); + for (ClangASTImporter::NamespaceMapItem &n : *namespace_map) { + LLDB_LOG(log, " CEDM::FEVD Searching namespace {0} in module {1}", + n.second.GetName(), n.first->GetFileSpec().GetFilename()); - FindExternalVisibleDecls(context, i->first, i->second, current_id); + FindExternalVisibleDecls(context, n.first, n.second); } } else if (isa(context.m_decl_context)) { CompilerDeclContext namespace_decl; - if (log) - log->Printf(" CEDM::FEVD[%u] Searching the root namespace", current_id); + LLDB_LOG(log, " CEDM::FEVD Searching the root namespace"); - FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl, - current_id); + FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl); } ClangASTSource::FindExternalVisibleDecls(context); @@ -734,7 +703,7 @@ clang::NamedDecl *ClangExpressionDeclMap::GetPersistentDecl(ConstString name) { if (!target) return nullptr; - ClangASTContext::GetScratch(*target); + TypeSystemClang::GetScratch(*target); if (!m_parser_vars->m_persistent_vars) return nullptr; @@ -742,8 +711,7 @@ clang::NamedDecl *ClangExpressionDeclMap::GetPersistentDecl(ConstString name) { } void ClangExpressionDeclMap::SearchPersistenDecls(NameSearchContext &context, - const ConstString name, - unsigned int current_id) { + const ConstString name) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); NamedDecl *persistent_decl = GetPersistentDecl(name); @@ -766,14 +734,12 @@ void ClangExpressionDeclMap::SearchPersistenDecls(NameSearchContext &context, MaybeRegisterFunctionBody(parser_function_decl); } - LLDB_LOGF(log, " CEDM::FEVD[%u] Found persistent decl %s", current_id, - name.GetCString()); + LLDB_LOG(log, " CEDM::FEVD Found persistent decl %s", name); context.AddNamedDecl(parser_named_decl); } -void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context, - unsigned int current_id) { +void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); @@ -788,8 +754,7 @@ void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context, if (!ctx_obj_ptr || status.Fail()) return; - AddThisType(context, TypeFromUser(m_ctx_obj->GetCompilerType()), - current_id); + AddContextClassType(context, TypeFromUser(m_ctx_obj->GetCompilerType())); m_struct_vars->m_object_pointer_type = TypeFromUser(ctx_obj_ptr->GetCompilerType()); @@ -814,7 +779,7 @@ void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context, return; clang::CXXMethodDecl *method_decl = - ClangASTContext::DeclContextGetAsCXXMethodDecl(function_decl_ctx); + TypeSystemClang::DeclContextGetAsCXXMethodDecl(function_decl_ctx); if (method_decl) { clang::CXXRecordDecl *class_decl = method_decl->getParent(); @@ -824,10 +789,10 @@ void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context, TypeFromUser class_user_type(class_qual_type.getAsOpaquePtr(), function_decl_ctx.GetTypeSystem()); - LLDB_LOG(log, " CEDM::FEVD[{0}] Adding type for $__lldb_class: {1}", - current_id, class_qual_type.getAsString()); + LLDB_LOG(log, " CEDM::FEVD Adding type for $__lldb_class: {1}", + class_qual_type.getAsString()); - AddThisType(context, class_user_type, current_id); + AddContextClassType(context, class_user_type); if (method_decl->isInstance()) { // self is a pointer to the object @@ -866,17 +831,16 @@ void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context, TypeFromUser pointee_type = this_type->GetForwardCompilerType().GetPointeeType(); - LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_class: {1}", current_id, + LLDB_LOG(log, " FEVD Adding type for $__lldb_class: {1}", ClangUtil::GetQualType(pointee_type).getAsString()); - AddThisType(context, pointee_type, current_id); + AddContextClassType(context, pointee_type); TypeFromUser this_user_type(this_type->GetFullCompilerType()); m_struct_vars->m_object_pointer_type = this_user_type; } } -void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context, - unsigned int current_id) { +void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); @@ -887,7 +851,7 @@ void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context, if (!ctx_obj_ptr || status.Fail()) return; - AddOneType(context, TypeFromUser(m_ctx_obj->GetCompilerType()), current_id); + AddOneType(context, TypeFromUser(m_ctx_obj->GetCompilerType())); m_struct_vars->m_object_pointer_type = TypeFromUser(ctx_obj_ptr->GetCompilerType()); @@ -915,7 +879,7 @@ void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context, return; clang::ObjCMethodDecl *method_decl = - ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx); + TypeSystemClang::DeclContextGetAsObjCMethodDecl(function_decl_ctx); if (method_decl) { ObjCInterfaceDecl *self_interface = method_decl->getClassInterface(); @@ -933,9 +897,9 @@ void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context, function_decl_ctx.GetTypeSystem()); LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_objc_class: {1}", - current_id, ClangUtil::ToString(interface_type)); + ClangUtil::ToString(interface_type)); - AddOneType(context, class_user_type, current_id); + AddOneType(context, class_user_type); if (method_decl->isInstanceMethod()) { // self is a pointer to the object @@ -984,10 +948,10 @@ void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context, CompilerType self_clang_type = self_type->GetFullCompilerType(); - if (ClangASTContext::IsObjCClassType(self_clang_type)) { + if (TypeSystemClang::IsObjCClassType(self_clang_type)) { return; } - if (!ClangASTContext::IsObjCObjectPointerType(self_clang_type)) + if (!TypeSystemClang::IsObjCObjectPointerType(self_clang_type)) return; self_clang_type = self_clang_type.GetPointeeType(); @@ -995,11 +959,11 @@ void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context, return; LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_objc_class: {1}", - current_id, ClangUtil::ToString(self_type->GetFullCompilerType())); + ClangUtil::ToString(self_type->GetFullCompilerType())); TypeFromUser class_user_type(self_clang_type); - AddOneType(context, class_user_type, current_id); + AddOneType(context, class_user_type); TypeFromUser self_user_type(self_type->GetFullCompilerType()); @@ -1015,25 +979,25 @@ void ClangExpressionDeclMap::LookupLocalVarNamespace( if (!frame_decl_context) return; - ClangASTContext *frame_ast = llvm::dyn_cast_or_null( + TypeSystemClang *frame_ast = llvm::dyn_cast_or_null( frame_decl_context.GetTypeSystem()); if (!frame_ast) return; clang::NamespaceDecl *namespace_decl = m_clang_ast_context->GetUniqueNamespaceDeclaration( - g_lldb_local_vars_namespace_cstr, nullptr); + g_lldb_local_vars_namespace_cstr, nullptr, OptionalClangModuleID()); if (!namespace_decl) return; name_context.AddNamedDecl(namespace_decl); clang::DeclContext *ctxt = clang::Decl::castToDeclContext(namespace_decl); ctxt->setHasExternalVisibleStorage(true); - name_context.m_found.local_vars_nsp = true; + name_context.m_found_local_vars_nsp = true; } void ClangExpressionDeclMap::LookupInModulesDeclVendor( - NameSearchContext &context, ConstString name, unsigned current_id) { + NameSearchContext &context, ConstString name) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); if (!m_target) @@ -1054,16 +1018,14 @@ void ClangExpressionDeclMap::LookupInModulesDeclVendor( clang::NamedDecl *const decl_from_modules = decls[0]; LLDB_LOG(log, - " CAS::FEVD[{0}] Matching decl found for " + " CAS::FEVD Matching decl found for " "\"{1}\" in the modules", - current_id, name); + name); clang::Decl *copied_decl = CopyDecl(decl_from_modules); if (!copied_decl) { - LLDB_LOG(log, - " CAS::FEVD[{0}] - Couldn't export a " - "declaration from the modules", - current_id); + LLDB_LOG(log, " CAS::FEVD - Couldn't export a " + "declaration from the modules"); return; } @@ -1072,17 +1034,17 @@ void ClangExpressionDeclMap::LookupInModulesDeclVendor( context.AddNamedDecl(copied_function); - context.m_found.function_with_type_info = true; - context.m_found.function = true; + context.m_found_function_with_type_info = true; + context.m_found_function = true; } else if (auto copied_var = dyn_cast(copied_decl)) { context.AddNamedDecl(copied_var); - context.m_found.variable = true; + context.m_found_variable = true; } } bool ClangExpressionDeclMap::LookupLocalVariable( - NameSearchContext &context, ConstString name, unsigned current_id, - SymbolContext &sym_ctx, CompilerDeclContext &namespace_decl) { + NameSearchContext &context, ConstString name, SymbolContext &sym_ctx, + const CompilerDeclContext &namespace_decl) { if (sym_ctx.block == nullptr) return false; @@ -1117,8 +1079,8 @@ bool ClangExpressionDeclMap::LookupLocalVariable( if (var && !variable_found) { variable_found = true; ValueObjectSP valobj = ValueObjectVariable::Create(frame, var); - AddOneVariable(context, var, valobj, current_id); - context.m_found.variable = true; + AddOneVariable(context, var, valobj); + context.m_found_variable = true; } } return variable_found; @@ -1148,7 +1110,7 @@ SymbolContextList ClangExpressionDeclMap::SearchFunctionsInSymbolContexts( decl_infos.reserve(num_indices); clang::DeclContext *frame_decl_ctx = (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext(); - ClangASTContext *ast = llvm::dyn_cast_or_null( + TypeSystemClang *ast = llvm::dyn_cast_or_null( frame_decl_context.GetTypeSystem()); for (uint32_t index = 0; index < num_indices; ++index) { @@ -1222,11 +1184,9 @@ SymbolContextList ClangExpressionDeclMap::SearchFunctionsInSymbolContexts( return sc_func_list; } -void ClangExpressionDeclMap::LookupFunction(NameSearchContext &context, - lldb::ModuleSP module_sp, - ConstString name, - CompilerDeclContext &namespace_decl, - unsigned current_id) { +void ClangExpressionDeclMap::LookupFunction( + NameSearchContext &context, lldb::ModuleSP module_sp, ConstString name, + const CompilerDeclContext &namespace_decl) { if (!m_parser_vars) return; @@ -1246,7 +1206,7 @@ void ClangExpressionDeclMap::LookupFunction(NameSearchContext &context, if (namespace_decl && module_sp) { const bool include_symbols = false; - module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase, + module_sp->FindFunctions(name, namespace_decl, eFunctionNameTypeBase, include_symbols, include_inlines, sc_list); } else if (target && !namespace_decl) { const bool include_symbols = true; @@ -1304,9 +1264,9 @@ void ClangExpressionDeclMap::LookupFunction(NameSearchContext &context, if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr)) continue; - AddOneFunction(context, sym_ctx.function, nullptr, current_id); - context.m_found.function_with_type_info = true; - context.m_found.function = true; + AddOneFunction(context, sym_ctx.function, nullptr); + context.m_found_function_with_type_info = true; + context.m_found_function = true; } else if (sym_ctx.symbol) { if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target) { sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target); @@ -1321,26 +1281,26 @@ void ClangExpressionDeclMap::LookupFunction(NameSearchContext &context, } } - if (!context.m_found.function_with_type_info) { + if (!context.m_found_function_with_type_info) { for (clang::NamedDecl *decl : decls_from_modules) { if (llvm::isa(decl)) { clang::NamedDecl *copied_decl = llvm::cast_or_null(CopyDecl(decl)); if (copied_decl) { context.AddNamedDecl(copied_decl); - context.m_found.function_with_type_info = true; + context.m_found_function_with_type_info = true; } } } } - if (!context.m_found.function_with_type_info) { + if (!context.m_found_function_with_type_info) { if (extern_symbol) { - AddOneFunction(context, nullptr, extern_symbol, current_id); - context.m_found.function = true; + AddOneFunction(context, nullptr, extern_symbol); + context.m_found_function = true; } else if (non_extern_symbol) { - AddOneFunction(context, nullptr, non_extern_symbol, current_id); - context.m_found.function = true; + AddOneFunction(context, nullptr, non_extern_symbol); + context.m_found_function = true; } } } @@ -1348,7 +1308,7 @@ void ClangExpressionDeclMap::LookupFunction(NameSearchContext &context, void ClangExpressionDeclMap::FindExternalVisibleDecls( NameSearchContext &context, lldb::ModuleSP module_sp, - CompilerDeclContext &namespace_decl, unsigned int current_id) { + const CompilerDeclContext &namespace_decl) { assert(m_ast_context); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); @@ -1373,16 +1333,16 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( // Try the persistent decls, which take precedence over all else. if (!namespace_decl) - SearchPersistenDecls(context, name, current_id); + SearchPersistenDecls(context, name); if (name.GetStringRef().startswith("$") && !namespace_decl) { if (name == "$__lldb_class") { - LookUpLldbClass(context, current_id); + LookUpLldbClass(context); return; } if (name == "$__lldb_objc_class") { - LookUpLldbObjCClass(context, current_id); + LookUpLldbObjCClass(context); return; } if (name == g_lldb_local_vars_namespace_cstr) { @@ -1402,7 +1362,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( m_parser_vars->m_persistent_vars->GetVariable(name)); if (pvar_sp) { - AddOneVariable(context, pvar_sp, current_id); + AddOneVariable(context, pvar_sp); return; } @@ -1415,10 +1375,9 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( reg_name)); if (reg_info) { - LLDB_LOGF(log, " CEDM::FEVD[%u] Found register %s", current_id, - reg_info->name); + LLDB_LOG(log, " CEDM::FEVD Found register {0}", reg_info->name); - AddOneRegister(context, reg_info, current_id); + AddOneRegister(context, reg_info); } } return; @@ -1427,29 +1386,29 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( bool local_var_lookup = !namespace_decl || (namespace_decl.GetName() == g_lldb_local_vars_namespace_cstr); if (frame && local_var_lookup) - if (LookupLocalVariable(context, name, current_id, sym_ctx, namespace_decl)) + if (LookupLocalVariable(context, name, sym_ctx, namespace_decl)) return; if (target) { ValueObjectSP valobj; VariableSP var; - var = FindGlobalVariable(*target, module_sp, name, &namespace_decl); + var = FindGlobalVariable(*target, module_sp, name, namespace_decl); if (var) { valobj = ValueObjectVariable::Create(target, var); - AddOneVariable(context, var, valobj, current_id); - context.m_found.variable = true; + AddOneVariable(context, var, valobj); + context.m_found_variable = true; return; } } - LookupFunction(context, module_sp, name, namespace_decl, current_id); + LookupFunction(context, module_sp, name, namespace_decl); // Try the modules next. - if (!context.m_found.function_with_type_info) - LookupInModulesDeclVendor(context, name, current_id); + if (!context.m_found_function_with_type_info) + LookupInModulesDeclVendor(context, name); - if (target && !context.m_found.variable && !namespace_decl) { + if (target && !context.m_found_variable && !namespace_decl) { // We couldn't find a non-symbol variable for this. Now we'll hunt for a // generic data symbol, and -- if it is found -- treat it as a variable. Status error; @@ -1471,8 +1430,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( m_ast_context->getDiagnostics().getCustomDiagID( clang::DiagnosticsEngine::Level::Warning, "%0"); m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str(); - AddOneGenericVariable(context, *data_symbol, current_id); - context.m_found.variable = true; + AddOneGenericVariable(context, *data_symbol); + context.m_found_variable = true; } } } @@ -1486,25 +1445,22 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var, Type *var_type = var->GetType(); if (!var_type) { - if (log) - log->PutCString("Skipped a definition because it has no type"); + LLDB_LOG(log, "Skipped a definition because it has no type"); return false; } CompilerType var_clang_type = var_type->GetFullCompilerType(); if (!var_clang_type) { - if (log) - log->PutCString("Skipped a definition because it has no Clang type"); + LLDB_LOG(log, "Skipped a definition because it has no Clang type"); return false; } - ClangASTContext *clang_ast = llvm::dyn_cast_or_null( + TypeSystemClang *clang_ast = llvm::dyn_cast_or_null( var_type->GetForwardCompilerType().GetTypeSystem()); if (!clang_ast) { - if (log) - log->PutCString("Skipped a definition because it has no Clang AST"); + LLDB_LOG(log, "Skipped a definition because it has no Clang AST"); return false; } @@ -1521,7 +1477,7 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var, const_value_extractor.GetByteSize()); var_location.SetValueType(Value::eValueTypeHostAddress); } else { - LLDB_LOGF(log, "Error evaluating constant variable: %s", err.AsCString()); + LLDB_LOG(log, "Error evaluating constant variable: {0}", err.AsCString()); return false; } } @@ -1529,8 +1485,8 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var, CompilerType type_to_use = GuardedCopyType(var_clang_type); if (!type_to_use) { - LLDB_LOGF(log, - "Couldn't copy a variable's type into the parser's AST context"); + LLDB_LOG(log, + "Couldn't copy a variable's type into the parser's AST context"); return false; } @@ -1567,8 +1523,7 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var, void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, VariableSP var, - ValueObjectSP valobj, - unsigned int current_id) { + ValueObjectSP valobj) { assert(m_parser_vars.get()); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); @@ -1611,7 +1566,6 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, entity->EnableParserVars(GetParserID()); ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID()); - parser_vars->m_parser_type = pt; parser_vars->m_named_decl = var_decl; parser_vars->m_llvm_value = nullptr; parser_vars->m_lldb_value = var_location; @@ -1620,15 +1574,12 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, if (is_reference) entity->m_flags |= ClangExpressionVariable::EVTypeIsReference; - LLDB_LOG(log, - " CEDM::FEVD[{0}] Found variable {1}, returned\n{2} (original {3})", - current_id, decl_name, ClangUtil::DumpDecl(var_decl), - ClangUtil::ToString(ut)); + LLDB_LOG(log, " CEDM::FEVD Found variable {1}, returned\n{2} (original {3})", + decl_name, ClangUtil::DumpDecl(var_decl), ClangUtil::ToString(ut)); } void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, - ExpressionVariableSP &pvar_sp, - unsigned int current_id) { + ExpressionVariableSP &pvar_sp) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); TypeFromUser user_type( @@ -1637,8 +1588,8 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, TypeFromParser parser_type(GuardedCopyType(user_type)); if (!parser_type.GetOpaqueQualType()) { - LLDB_LOGF(log, " CEDM::FEVD[%u] Couldn't import type for pvar %s", - current_id, pvar_sp->GetName().GetCString()); + LLDB_LOG(log, " CEDM::FEVD Couldn't import type for pvar {0}", + pvar_sp->GetName()); return; } @@ -1650,18 +1601,16 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, ClangExpressionVariable::ParserVars *parser_vars = llvm::cast(pvar_sp.get()) ->GetParserVars(GetParserID()); - parser_vars->m_parser_type = parser_type; parser_vars->m_named_decl = var_decl; parser_vars->m_llvm_value = nullptr; parser_vars->m_lldb_value.Clear(); - LLDB_LOG(log, " CEDM::FEVD[{0}] Added pvar {1}, returned\n{2}", current_id, + LLDB_LOG(log, " CEDM::FEVD Added pvar {1}, returned\n{2}", pvar_sp->GetName(), ClangUtil::DumpDecl(var_decl)); } void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, - const Symbol &symbol, - unsigned int current_id) { + const Symbol &symbol) { assert(m_parser_vars.get()); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); @@ -1671,7 +1620,7 @@ void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, if (target == nullptr) return; - ClangASTContext *scratch_ast_context = ClangASTContext::GetScratch(*target); + TypeSystemClang *scratch_ast_context = TypeSystemClang::GetScratch(*target); if (!scratch_ast_context) return; @@ -1704,18 +1653,16 @@ void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, parser_vars->m_lldb_value.GetScalar() = symbol_load_addr; parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress); - parser_vars->m_parser_type = parser_type; parser_vars->m_named_decl = var_decl; parser_vars->m_llvm_value = nullptr; parser_vars->m_lldb_sym = &symbol; - LLDB_LOG(log, " CEDM::FEVD[{0}] Found variable {1}, returned\n{2}", - current_id, decl_name, ClangUtil::DumpDecl(var_decl)); + LLDB_LOG(log, " CEDM::FEVD Found variable {1}, returned\n{2}", decl_name, + ClangUtil::DumpDecl(var_decl)); } void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context, - const RegisterInfo *reg_info, - unsigned int current_id) { + const RegisterInfo *reg_info) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); CompilerType clang_type = @@ -1723,8 +1670,8 @@ void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context, reg_info->encoding, reg_info->byte_size * 8); if (!clang_type) { - LLDB_LOGF(log, " Tried to add a type for %s, but couldn't get one", - context.m_decl_name.getAsString().c_str()); + LLDB_LOG(log, " Tried to add a type for {0}, but couldn't get one", + context.m_decl_name.getAsString()); return; } @@ -1744,20 +1691,18 @@ void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context, entity->EnableParserVars(GetParserID()); ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID()); - parser_vars->m_parser_type = parser_clang_type; parser_vars->m_named_decl = var_decl; parser_vars->m_llvm_value = nullptr; parser_vars->m_lldb_value.Clear(); entity->m_flags |= ClangExpressionVariable::EVBareRegister; - LLDB_LOG(log, " CEDM::FEVD[{0}] Added register {1}, returned\n{2}", - current_id, context.m_decl_name.getAsString(), - ClangUtil::DumpDecl(var_decl)); + LLDB_LOG(log, " CEDM::FEVD Added register {1}, returned\n{2}", + context.m_decl_name.getAsString(), ClangUtil::DumpDecl(var_decl)); } void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, - Function *function, Symbol *symbol, - unsigned int current_id) { + Function *function, + Symbol *symbol) { assert(m_parser_vars.get()); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); @@ -1780,7 +1725,7 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, if (!extern_c) { TypeSystem *type_system = function->GetDeclContext().GetTypeSystem(); - if (llvm::isa(type_system)) { + if (llvm::isa(type_system)) { clang::DeclContext *src_decl_context = (clang::DeclContext *)function->GetDeclContext() .GetOpaqueDeclContext(); @@ -1800,9 +1745,9 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, function->DumpSymbolContext(&ss); LLDB_LOG(log, - " CEDM::FEVD[{0}] Imported decl for function template" + " CEDM::FEVD Imported decl for function template" " {1} (description {2}), returned\n{3}", - current_id, copied_function_template->getNameAsString(), + copied_function_template->getNameAsString(), ss.GetData(), ClangUtil::DumpDecl(copied_function_template)); } @@ -1819,35 +1764,31 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, function->DumpSymbolContext(&ss); LLDB_LOG(log, - " CEDM::FEVD[{0}]] Imported decl for function {1} " + " CEDM::FEVD Imported decl for function {1} " "(description {2}), returned\n{3}", - current_id, copied_function_decl->getNameAsString(), - ss.GetData(), ClangUtil::DumpDecl(copied_function_decl)); + copied_function_decl->getNameAsString(), ss.GetData(), + ClangUtil::DumpDecl(copied_function_decl)); } context.AddNamedDecl(copied_function_decl); return; } else { - if (log) { - LLDB_LOGF(log, " Failed to import the function decl for '%s'", - src_function_decl->getName().str().c_str()); - } + LLDB_LOG(log, " Failed to import the function decl for '{0}'", + src_function_decl->getName()); } } } } if (!function_type) { - if (log) - log->PutCString(" Skipped a function because it has no type"); + LLDB_LOG(log, " Skipped a function because it has no type"); return; } function_clang_type = function_type->GetFullCompilerType(); if (!function_clang_type) { - if (log) - log->PutCString(" Skipped a function because it has no Clang type"); + LLDB_LOG(log, " Skipped a function because it has no Clang type"); return; } @@ -1858,24 +1799,17 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, function_decl = context.AddFunDecl(copied_function_type, extern_c); if (!function_decl) { - if (log) { - LLDB_LOGF( - log, - " Failed to create a function decl for '%s' {0x%8.8" PRIx64 "}", - function_type->GetName().GetCString(), function_type->GetID()); - } + LLDB_LOG(log, " Failed to create a function decl for '{0}' ({1:x})", + function_type->GetName(), function_type->GetID()); return; } } else { // We failed to copy the type we found - if (log) { - LLDB_LOGF(log, - " Failed to import the function type '%s' {0x%8.8" PRIx64 - "} into the expression parser AST contenxt", - function_type->GetName().GetCString(), - function_type->GetID()); - } + LLDB_LOG(log, + " Failed to import the function type '{0}' ({1:x})" + " into the expression parser AST contenxt", + function_type->GetName(), function_type->GetID()); return; } @@ -1884,8 +1818,7 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, function_decl = context.AddGenericFunDecl(); is_indirect_function = symbol->IsIndirect(); } else { - if (log) - log->PutCString(" AddOneFunction called with no function and no symbol"); + LLDB_LOG(log, " AddOneFunction called with no function and no symbol"); return; } @@ -1931,25 +1864,22 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, Address::DumpStyleResolvedDescription); LLDB_LOG(log, - " CEDM::FEVD[{0}] Found {1} function {2} (description {3}), " + " CEDM::FEVD Found {1} function {2} (description {3}), " "returned\n{4}", - current_id, (function ? "specific" : "generic"), decl_name, - ss.GetData(), ClangUtil::DumpDecl(function_decl)); + (function ? "specific" : "generic"), decl_name, ss.GetData(), + ClangUtil::DumpDecl(function_decl)); } } -void ClangExpressionDeclMap::AddThisType(NameSearchContext &context, - const TypeFromUser &ut, - unsigned int current_id) { +void ClangExpressionDeclMap::AddContextClassType(NameSearchContext &context, + const TypeFromUser &ut) { CompilerType copied_clang_type = GuardedCopyType(ut); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); if (!copied_clang_type) { - if (log) - LLDB_LOGF( - log, - "ClangExpressionDeclMap::AddThisType - Couldn't import the type"); + LLDB_LOG(log, + "ClangExpressionDeclMap::AddThisType - Couldn't import the type"); return; } @@ -2009,16 +1939,14 @@ void ClangExpressionDeclMap::AddThisType(NameSearchContext &context, } void ClangExpressionDeclMap::AddOneType(NameSearchContext &context, - const TypeFromUser &ut, - unsigned int current_id) { + const TypeFromUser &ut) { CompilerType copied_clang_type = GuardedCopyType(ut); if (!copied_clang_type) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - if (log) - LLDB_LOGF( - log, "ClangExpressionDeclMap::AddOneType - Couldn't import the type"); + LLDB_LOG(log, + "ClangExpressionDeclMap::AddOneType - Couldn't import the type"); return; } diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h index 722f5e15a2a..6974535a899 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ClangExpressionDeclMap_h_ -#define liblldb_ClangExpressionDeclMap_h_ +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H #include #include @@ -17,7 +17,6 @@ #include "ClangASTSource.h" #include "ClangExpressionVariable.h" -#include "lldb/Core/ClangForward.h" #include "lldb/Core/Value.h" #include "lldb/Expression/Materializer.h" #include "lldb/Symbol/SymbolContext.h" @@ -29,6 +28,8 @@ namespace lldb_private { +class ClangPersistentVariables; + /// \class ClangExpressionDeclMap ClangExpressionDeclMap.h /// "lldb/Expression/ClangExpressionDeclMap.h" Manages named entities that are /// defined in LLDB's debug information. @@ -79,8 +80,8 @@ public: ClangExpressionDeclMap( bool keep_result_in_memory, Materializer::PersistentVariableDelegate *result_delegate, - const lldb::TargetSP &target, const lldb::ClangASTImporterSP &importer, - ValueObject *ctx_obj); + const lldb::TargetSP &target, + const std::shared_ptr &importer, ValueObject *ctx_obj); /// Destructor ~ClangExpressionDeclMap() override; @@ -274,14 +275,9 @@ public: /// /// \param[in] namespace_decl /// If valid and module is non-NULL, the parent namespace. - /// - /// \param[in] current_id - /// The ID for the current FindExternalVisibleDecls invocation, - /// for logging purposes. void FindExternalVisibleDecls(NameSearchContext &context, lldb::ModuleSP module, - CompilerDeclContext &namespace_decl, - unsigned int current_id); + const CompilerDeclContext &namespace_decl); protected: /// Retrieves the declaration with the given name from the storage of @@ -335,7 +331,8 @@ private: ///that receives new top-level ///functions. private: - DISALLOW_COPY_AND_ASSIGN(ParserVars); + ParserVars(const ParserVars &) = delete; + const ParserVars &operator=(const ParserVars &) = delete; }; std::unique_ptr m_parser_vars; @@ -394,32 +391,19 @@ private: /// /// \param[in] name /// The name of the entities that need to be found. - /// - /// \param[in] current_id - /// The ID for the current FindExternalVisibleDecls invocation, - /// for logging purposes. - void SearchPersistenDecls(NameSearchContext &context, const ConstString name, - unsigned int current_id); + void SearchPersistenDecls(NameSearchContext &context, const ConstString name); /// Handles looking up $__lldb_class which requires special treatment. /// /// \param[in] context /// The NameSearchContext that can construct Decls for this name. - /// - /// \param[in] current_id - /// The ID for the current FindExternalVisibleDecls invocation, - /// for logging purposes. - void LookUpLldbClass(NameSearchContext &context, unsigned int current_id); + void LookUpLldbClass(NameSearchContext &context); /// Handles looking up $__lldb_objc_class which requires special treatment. /// /// \param[in] context /// The NameSearchContext that can construct Decls for this name. - /// - /// \param[in] current_id - /// The ID for the current FindExternalVisibleDecls invocation, - /// for logging purposes. - void LookUpLldbObjCClass(NameSearchContext &context, unsigned int current_id); + void LookUpLldbObjCClass(NameSearchContext &context); /// Handles looking up the synthetic namespace that contains our local /// variables for the current frame. @@ -438,12 +422,7 @@ private: /// /// \param[in] name /// The name of the entities that need to be found. - /// - /// \param[in] current_id - /// The ID for the current FindExternalVisibleDecls invocation, - /// for logging purposes. - void LookupInModulesDeclVendor(NameSearchContext &context, ConstString name, - unsigned current_id); + void LookupInModulesDeclVendor(NameSearchContext &context, ConstString name); /// Looks up a local variable. /// @@ -453,10 +432,6 @@ private: /// \param[in] name /// The name of the entities that need to be found. /// - /// \param[in] current_id - /// The ID for the current FindExternalVisibleDecls invocation, - /// for logging purposes. - /// /// \param[in] sym_ctx /// The current SymbolContext of this frame. /// @@ -466,8 +441,8 @@ private: /// \return /// True iff a local variable was found. bool LookupLocalVariable(NameSearchContext &context, ConstString name, - unsigned current_id, SymbolContext &sym_ctx, - CompilerDeclContext &namespace_decl); + SymbolContext &sym_ctx, + const CompilerDeclContext &namespace_decl); /// Searches for functions in the given SymbolContextList. /// @@ -499,13 +474,9 @@ private: /// /// \param[in] namespace_decl /// If valid and module is non-NULL, the parent namespace. - /// - /// \param[in] current_id - /// The ID for the current FindExternalVisibleDecls invocation, - /// for logging purposes. void LookupFunction(NameSearchContext &context, lldb::ModuleSP module_sp, - ConstString name, CompilerDeclContext &namespace_decl, - unsigned current_id); + ConstString name, + const CompilerDeclContext &namespace_decl); /// Given a target, find a variable that matches the given name and type. /// @@ -523,9 +494,9 @@ private: /// /// \return /// The LLDB Variable found, or NULL if none was found. - lldb::VariableSP FindGlobalVariable(Target &target, lldb::ModuleSP &module, - ConstString name, - CompilerDeclContext *namespace_decl); + lldb::VariableSP + FindGlobalVariable(Target &target, lldb::ModuleSP &module, ConstString name, + const CompilerDeclContext &namespace_decl); /// Get the value of a variable in a given execution context and return the /// associated Types if needed. @@ -565,7 +536,7 @@ private: /// \param[in] valobj /// The LLDB ValueObject for that variable. void AddOneVariable(NameSearchContext &context, lldb::VariableSP var, - lldb::ValueObjectSP valobj, unsigned int current_id); + lldb::ValueObjectSP valobj); /// Use the NameSearchContext to generate a Decl for the given persistent /// variable, and put it in the list of found entities. @@ -575,18 +546,12 @@ private: /// /// \param[in] pvar_sp /// The persistent variable that needs a Decl. - /// - /// \param[in] current_id - /// The ID of the current invocation of FindExternalVisibleDecls - /// for logging purposes. void AddOneVariable(NameSearchContext &context, - lldb::ExpressionVariableSP &pvar_sp, - unsigned int current_id); + lldb::ExpressionVariableSP &pvar_sp); /// Use the NameSearchContext to generate a Decl for the given LLDB symbol /// (treated as a variable), and put it in the list of found entities. - void AddOneGenericVariable(NameSearchContext &context, const Symbol &symbol, - unsigned int current_id); + void AddOneGenericVariable(NameSearchContext &context, const Symbol &symbol); /// Use the NameSearchContext to generate a Decl for the given function. /// (Functions are not placed in the Tuple list.) Can handle both fully @@ -602,8 +567,7 @@ private: /// \param[in] sym /// The Symbol that corresponds to a function that needs to be /// created with generic type (unitptr_t foo(...)). - void AddOneFunction(NameSearchContext &context, Function *fun, Symbol *sym, - unsigned int current_id); + void AddOneFunction(NameSearchContext &context, Function *fun, Symbol *sym); /// Use the NameSearchContext to generate a Decl for the given register. /// @@ -612,8 +576,7 @@ private: /// /// \param[in] reg_info /// The information corresponding to that register. - void AddOneRegister(NameSearchContext &context, const RegisterInfo *reg_info, - unsigned int current_id); + void AddOneRegister(NameSearchContext &context, const RegisterInfo *reg_info); /// Use the NameSearchContext to generate a Decl for the given type. (Types /// are not placed in the Tuple list.) @@ -623,38 +586,40 @@ private: /// /// \param[in] type /// The type that needs to be created. - void AddOneType(NameSearchContext &context, const TypeFromUser &type, - unsigned int current_id); + void AddOneType(NameSearchContext &context, const TypeFromUser &type); - /// Generate a Decl for "*this" and add a member function declaration to it - /// for the expression, then report it. + /// Adds the class in which the expression is evaluated to the lookup and + /// prepares the class to be used as a context for expression evaluation (for + /// example, it creates a fake member function that will contain the + /// expression LLDB is trying to evaluate). /// /// \param[in] context - /// The NameSearchContext to use when constructing the Decl. + /// The NameSearchContext to which the class should be added as a lookup + /// result. /// /// \param[in] type - /// The type for *this. - void AddThisType(NameSearchContext &context, const TypeFromUser &type, - unsigned int current_id); + /// The type of the class that serves as the evaluation context. + void AddContextClassType(NameSearchContext &context, + const TypeFromUser &type); /// Move a type out of the current ASTContext into another, but make sure to /// export all components of the type also. /// /// \param[in] target - /// The ClangASTContext to move to. + /// The TypeSystemClang to move to. /// \param[in] source - /// The ClangASTContext to move from. This is assumed to be going away. + /// The TypeSystemClang to move from. This is assumed to be going away. /// \param[in] parser_type /// The type as it appears in the source context. /// /// \return /// Returns the moved type, or an empty type if there was a problem. - TypeFromUser DeportType(ClangASTContext &target, ClangASTContext &source, + TypeFromUser DeportType(TypeSystemClang &target, TypeSystemClang &source, TypeFromParser parser_type); - ClangASTContext *GetClangASTContext(); + TypeSystemClang *GetTypeSystemClang(); }; } // namespace lldb_private -#endif // liblldb_ClangExpressionDeclMap_h_ +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h index 48da5abb912..e33e5df2223 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h @@ -6,21 +6,24 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ClangExpression_h_ -#define liblldb_ClangExpression_h_ +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONHELPER_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONHELPER_H #include #include #include - -#include "lldb/Core/ClangForward.h" #include "lldb/Expression/ExpressionTypeSystemHelper.h" #include "lldb/lldb-forward.h" #include "lldb/lldb-private.h" +namespace clang { +class ASTConsumer; +} + namespace lldb_private { +class ClangExpressionDeclMap; class RecordingMemoryManager; // ClangExpressionHelper @@ -57,4 +60,4 @@ protected: } // namespace lldb_private -#endif // liblldb_ClangExpression_h_ +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONHELPER_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index 8abd1494288..6ff028cf698 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -1,4 +1,4 @@ -//===-- ClangExpressionParser.cpp -------------------------------*- C++ -*-===// +//===-- ClangExpressionParser.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -67,6 +67,7 @@ #include "IRForTarget.h" #include "ModuleDependencyCollector.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/Module.h" @@ -75,7 +76,6 @@ #include "lldb/Expression/IRInterpreter.h" #include "lldb/Host/File.h" #include "lldb/Host/HostInfo.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Language.h" @@ -91,6 +91,7 @@ #include "lldb/Utility/StringList.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" +#include "Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h" #include #include @@ -146,21 +147,40 @@ public: llvm::StringRef getErrorString() { return m_error_stream.GetString(); } }; +static void AddAllFixIts(ClangDiagnostic *diag, const clang::Diagnostic &Info) { + for (auto &fix_it : Info.getFixItHints()) { + if (fix_it.isNull()) + continue; + diag->AddFixitHint(fix_it); + } +} + class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer { public: ClangDiagnosticManagerAdapter(DiagnosticOptions &opts) { - DiagnosticOptions *m_options = new DiagnosticOptions(opts); - m_options->ShowPresumedLoc = true; - m_options->ShowLevel = false; - m_os.reset(new llvm::raw_string_ostream(m_output)); - m_passthrough.reset( - new clang::TextDiagnosticPrinter(*m_os, m_options, false)); + DiagnosticOptions *options = new DiagnosticOptions(opts); + options->ShowPresumedLoc = true; + options->ShowLevel = false; + m_os = std::make_shared(m_output); + m_passthrough = + std::make_shared(*m_os, options); } void ResetManager(DiagnosticManager *manager = nullptr) { m_manager = manager; } + /// Returns the last ClangDiagnostic message that the DiagnosticManager + /// received or a nullptr if the DiagnosticMangager hasn't seen any + /// Clang diagnostics yet. + ClangDiagnostic *MaybeGetLastClangDiag() const { + if (m_manager->Diagnostics().empty()) + return nullptr; + lldb_private::Diagnostic *diag = m_manager->Diagnostics().back().get(); + ClangDiagnostic *clang_diag = dyn_cast(diag); + return clang_diag; + } + void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) override { if (!m_manager) { @@ -180,6 +200,9 @@ public: return; } + // Update error/warning counters. + DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info); + // Render diagnostic message to m_output. m_output.clear(); m_passthrough->HandleDiagnostic(DiagLevel, Info); @@ -203,11 +226,29 @@ public: case DiagnosticsEngine::Level::Note: m_manager->AppendMessageToDiagnostic(m_output); make_new_diagnostic = false; + + // 'note:' diagnostics for errors and warnings can also contain Fix-Its. + // We add these Fix-Its to the last error diagnostic to make sure + // that we later have all Fix-Its related to an 'error' diagnostic when + // we apply them to the user expression. + auto *clang_diag = MaybeGetLastClangDiag(); + // If we don't have a previous diagnostic there is nothing to do. + // If the previous diagnostic already has its own Fix-Its, assume that + // the 'note:' Fix-It is just an alternative way to solve the issue and + // ignore these Fix-Its. + if (!clang_diag || clang_diag->HasFixIts()) + break; + // Ignore all Fix-Its that are not associated with an error. + if (clang_diag->GetSeverity() != eDiagnosticSeverityError) + break; + AddAllFixIts(clang_diag, Info); + break; } if (make_new_diagnostic) { // ClangDiagnostic messages are expected to have no whitespace/newlines // around them. - std::string stripped_output = llvm::StringRef(m_output).trim(); + std::string stripped_output = + std::string(llvm::StringRef(m_output).trim()); auto new_diagnostic = std::make_unique( stripped_output, severity, Info.getID()); @@ -216,20 +257,18 @@ public: // enough context in an expression for the warning to be useful. // FIXME: Should we try to filter out FixIts that apply to our generated // code, and not the user's expression? - if (severity == eDiagnosticSeverityError) { - size_t num_fixit_hints = Info.getNumFixItHints(); - for (size_t i = 0; i < num_fixit_hints; i++) { - const clang::FixItHint &fixit = Info.getFixItHint(i); - if (!fixit.isNull()) - new_diagnostic->AddFixitHint(fixit); - } - } + if (severity == eDiagnosticSeverityError) + AddAllFixIts(new_diagnostic.get(), Info); m_manager->AddDiagnostic(std::move(new_diagnostic)); } } - clang::TextDiagnosticPrinter *GetPassthrough() { return m_passthrough.get(); } + void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override { + m_passthrough->BeginSourceFile(LO, PP); + } + + void EndSourceFile() override { m_passthrough->EndSourceFile(); } private: DiagnosticManager *m_manager = nullptr; @@ -253,9 +292,9 @@ static void SetupModuleHeaderPaths(CompilerInstance *compiler, } llvm::SmallString<128> module_cache; - auto props = ModuleList::GetGlobalModuleListProperties(); + const auto &props = ModuleList::GetGlobalModuleListProperties(); props.GetClangModulesCachePath().GetPath(module_cache); - search_opts.ModuleCachePath = module_cache.str(); + search_opts.ModuleCachePath = std::string(module_cache.str()); LLDB_LOG(log, "Using module cache path: {0}", module_cache.c_str()); search_opts.ResourceDir = GetClangResourceDir().GetPath(); @@ -279,28 +318,27 @@ ClangExpressionParser::ClangExpressionParser( // We can't compile expressions without a target. So if the exe_scope is // null or doesn't have a target, then we just need to get out of here. I'll - // lldb_assert and not make any of the compiler objects since + // lldbassert and not make any of the compiler objects since // I can't return errors directly from the constructor. Further calls will // check if the compiler was made and // bag out if it wasn't. if (!exe_scope) { - lldb_assert(exe_scope, "Can't make an expression parser with a null scope.", - __FUNCTION__, __FILE__, __LINE__); + lldbassert(exe_scope && + "Can't make an expression parser with a null scope."); return; } lldb::TargetSP target_sp; target_sp = exe_scope->CalculateTarget(); if (!target_sp) { - lldb_assert(target_sp.get(), - "Can't make an expression parser with a null target.", - __FUNCTION__, __FILE__, __LINE__); + lldbassert(target_sp.get() && + "Can't make an expression parser with a null target."); return; } // 1. Create a new compiler instance. - m_compiler.reset(new CompilerInstance()); + m_compiler = std::make_unique(); // When capturing a reproducer, hook up the file collector with clang to // collector modules and headers. @@ -391,9 +429,13 @@ ClangExpressionParser::ClangExpressionParser( // target. In this case, a specialized language runtime is available and we // can query it for extra options. For 99% of use cases, this will not be // needed and should be provided when basic platform detection is not enough. - if (lang_rt) + // FIXME: Generalize this. Only RenderScriptRuntime currently supports this + // currently. Hardcoding this isn't ideal but it's better than LanguageRuntime + // having knowledge of clang::TargetOpts. + if (auto *renderscript_rt = + llvm::dyn_cast_or_null(lang_rt)) overridden_target_opts = - lang_rt->GetOverrideExprOptions(m_compiler->getTargetOpts()); + renderscript_rt->GetOverrideExprOptions(m_compiler->getTargetOpts()); if (overridden_target_opts) if (log && log->GetVerbose()) { @@ -606,11 +648,12 @@ ClangExpressionParser::ClangExpressionParser( m_compiler->createASTContext(); clang::ASTContext &ast_context = m_compiler->getASTContext(); - m_ast_context.reset(new ClangASTContext(ast_context)); + m_ast_context = std::make_unique( + "Expression ASTContext for '" + m_filename + "'", ast_context); std::string module_name("$__lldb_module"); - m_llvm_context.reset(new LLVMContext()); + m_llvm_context = std::make_unique(); m_code_generator.reset(CreateLLVMCodeGen( m_compiler->getDiagnostics(), module_name, m_compiler->getHeaderSearchOpts(), m_compiler->getPreprocessorOpts(), @@ -631,11 +674,33 @@ class CodeComplete : public CodeCompleteConsumer { 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; + struct CompletionWithPriority { + CompletionResult::Completion completion; + /// See CodeCompletionResult::Priority; + unsigned Priority; + + /// Establishes a deterministic order in a list of CompletionWithPriority. + /// The order returned here is the order in which the completions are + /// displayed to the user. + bool operator<(const CompletionWithPriority &o) const { + // High priority results should come first. + if (Priority != o.Priority) + return Priority > o.Priority; + + // Identical priority, so just make sure it's a deterministic order. + return completion.GetUniqueKey() < o.completion.GetUniqueKey(); + } + }; + + /// The stored completions. + /// Warning: These are in a non-deterministic order until they are sorted + /// and returned back to the caller. + std::vector m_completions; + /// 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. @@ -652,7 +717,7 @@ class CodeComplete : public CodeCompleteConsumer { /// 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) { + StringRef dropUnrelatedFrontTokens(StringRef cmd) const { if (cmd.empty()) return cmd; @@ -673,18 +738,18 @@ class CodeComplete : public CodeCompleteConsumer { } /// Removes the last identifier token from the given cmd line. - StringRef removeLastToken(StringRef cmd) { + StringRef removeLastToken(StringRef cmd) const { while (!cmd.empty() && IsIdChar(cmd.back())) { cmd = cmd.drop_back(); } return cmd; } - /// Attemps to merge the given completion from the given position into the + /// Attempts 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 completion) const { StringRef existing_command = existing.substr(0, pos); // We rewrite the last token with the completion, so let's drop that // token from the command. @@ -706,11 +771,10 @@ public: /// \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) + CodeComplete(clang::LangOptions ops, std::string expr, unsigned position) : CodeCompleteConsumer(CodeCompleteOptions()), m_info(std::make_shared()), m_expr(expr), - m_position(position), m_request(request), m_desc_policy(ops) { + m_position(position), m_desc_policy(ops) { // Ensure that the printing policy is producing a description that is as // short as possible. @@ -723,9 +787,6 @@ public: m_desc_policy.Bool = true; } - /// Deregisters and destroys this code-completion consumer. - ~CodeComplete() override {} - /// \name Code-completion filtering /// Check if the result should be filtered out. bool isResultFilteredOut(StringRef Filter, @@ -753,6 +814,85 @@ public: return true; } +private: + /// Generate the completion strings for the given CodeCompletionResult. + /// Note that this function has to process results that could come in + /// non-deterministic order, so this function should have no side effects. + /// To make this easier to enforce, this function and all its parameters + /// should always be const-qualified. + /// \return Returns llvm::None if no completion should be provided for the + /// given CodeCompletionResult. + llvm::Optional + getCompletionForResult(const CodeCompletionResult &R) const { + 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; + } + // We also filter some internal lldb identifiers here. The user + // shouldn't see these. + if (llvm::StringRef(ToInsert).startswith("$__lldb_")) + return llvm::None; + if (ToInsert.empty()) + return llvm::None; + // 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); + + CompletionResult::Completion completion(CompletionSuggestion, Description, + CompletionMode::Normal); + return {{completion, R.Priority}}; + } + +public: + /// Adds the completions to the given CompletionRequest. + void GetCompletions(CompletionRequest &request) { + // Bring m_completions into a deterministic order and pass it on to the + // CompletionRequest. + llvm::sort(m_completions); + + for (const CompletionWithPriority &C : m_completions) + request.AddCompletion(C.completion.GetCompletion(), + C.completion.GetDescription(), + C.completion.GetMode()); + } + /// \name Code-completion callbacks /// Process the finalized code-completion results. void ProcessCodeCompleteResults(Sema &SemaRef, CodeCompletionContext Context, @@ -771,59 +911,11 @@ public: 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_")) + llvm::Optional CompletionAndPriority = + getCompletionForResult(R); + if (!CompletionAndPriority) 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); - } + m_completions.push_back(*CompletionAndPriority); } } @@ -860,12 +952,13 @@ bool ClangExpressionParser::Complete(CompletionRequest &request, unsigned line, // the LLVMUserExpression which exposes the right API. This should never fail // as we always have a ClangUserExpression whenever we call this. ClangUserExpression *llvm_expr = cast(&m_expr); - CodeComplete CC(request, m_compiler->getLangOpts(), llvm_expr->GetUserText(), + CodeComplete CC(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); + CC.GetCompletions(request); return true; } @@ -881,7 +974,6 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager, ClangDiagnosticManagerAdapter *adapter = static_cast( m_compiler->getDiagnostics().getClient()); - auto diag_buf = adapter->GetPassthrough(); adapter->ResetManager(&diagnostic_manager); @@ -936,8 +1028,8 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager, source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer))); } - diag_buf->BeginSourceFile(m_compiler->getLangOpts(), - &m_compiler->getPreprocessor()); + adapter->BeginSourceFile(m_compiler->getLangOpts(), + &m_compiler->getPreprocessor()); ClangExpressionHelper *type_system_helper = dyn_cast(m_expr.GetTypeSystemHelper()); @@ -961,11 +1053,11 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager, std::unique_ptr Consumer; if (ast_transformer) { - Consumer.reset(new ASTConsumerForwarder(ast_transformer)); + Consumer = std::make_unique(ast_transformer); } else if (m_code_generator) { - Consumer.reset(new ASTConsumerForwarder(m_code_generator.get())); + Consumer = std::make_unique(m_code_generator.get()); } else { - Consumer.reset(new ASTConsumer()); + Consumer = std::make_unique(); } clang::ASTContext &ast_context = m_compiler->getASTContext(); @@ -1022,9 +1114,9 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager, // original behavior of ParseAST (which also destroys the Sema after parsing). m_compiler->setSema(nullptr); - diag_buf->EndSourceFile(); + adapter->EndSourceFile(); - unsigned num_errors = diag_buf->getNumErrors(); + unsigned num_errors = adapter->getNumErrors(); if (m_pp_callbacks && m_pp_callbacks->hasErrors()) { num_errors++; @@ -1065,6 +1157,28 @@ ClangExpressionParser::GetClangTargetABI(const ArchSpec &target_arch) { return abi; } +/// Applies the given Fix-It hint to the given commit. +static void ApplyFixIt(const FixItHint &fixit, clang::edit::Commit &commit) { + // This is cobbed from clang::Rewrite::FixItRewriter. + if (fixit.CodeToInsert.empty()) { + if (fixit.InsertFromRange.isValid()) { + commit.insertFromRange(fixit.RemoveRange.getBegin(), + fixit.InsertFromRange, /*afterToken=*/false, + fixit.BeforePreviousInsertions); + return; + } + commit.remove(fixit.RemoveRange); + return; + } + if (fixit.RemoveRange.isTokenRange() || + fixit.RemoveRange.getBegin() != fixit.RemoveRange.getEnd()) { + commit.replace(fixit.RemoveRange, fixit.CodeToInsert); + return; + } + commit.insert(fixit.RemoveRange.getBegin(), fixit.CodeToInsert, + /*afterToken=*/false, fixit.BeforePreviousInsertions); +} + bool ClangExpressionParser::RewriteExpression( DiagnosticManager &diagnostic_manager) { clang::SourceManager &source_manager = m_compiler->getSourceManager(); @@ -1096,26 +1210,12 @@ bool ClangExpressionParser::RewriteExpression( for (const auto &diag : diagnostic_manager.Diagnostics()) { const auto *diagnostic = llvm::dyn_cast(diag.get()); - if (diagnostic && diagnostic->HasFixIts()) { - for (const FixItHint &fixit : diagnostic->FixIts()) { - // This is cobbed from clang::Rewrite::FixItRewriter. - if (fixit.CodeToInsert.empty()) { - if (fixit.InsertFromRange.isValid()) { - commit.insertFromRange(fixit.RemoveRange.getBegin(), - fixit.InsertFromRange, /*afterToken=*/false, - fixit.BeforePreviousInsertions); - } else - commit.remove(fixit.RemoveRange); - } else { - if (fixit.RemoveRange.isTokenRange() || - fixit.RemoveRange.getBegin() != fixit.RemoveRange.getEnd()) - commit.replace(fixit.RemoveRange, fixit.CodeToInsert); - else - commit.insert(fixit.RemoveRange.getBegin(), fixit.CodeToInsert, - /*afterToken=*/false, fixit.BeforePreviousInsertions); - } - } - } + if (!diagnostic) + continue; + if (!diagnostic->HasFixIts()) + continue; + for (const FixItHint &fixit : diagnostic->FixIts()) + ApplyFixIt(fixit, commit); } // FIXME - do we want to try to propagate specific errors here? @@ -1230,18 +1330,13 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution( type_system_helper->DeclMap(); // result can be NULL if (decl_map) { - Target *target = exe_ctx.GetTargetPtr(); - auto &error_stream = target->GetDebugger().GetErrorStream(); + StreamString error_stream; IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(), *execution_unit_sp, error_stream, function_name.AsCString()); - bool ir_can_run = - ir_for_target.runOnModule(*execution_unit_sp->GetModule()); - - if (!ir_can_run) { - err.SetErrorString( - "The expression could not be prepared to run in the target"); + if (!ir_for_target.runOnModule(*execution_unit_sp->GetModule())) { + err.SetErrorString(error_stream.GetString()); return err; } diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h index 4a410cecb94..6afee22da8d 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h @@ -6,10 +6,9 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ClangExpressionParser_h_ -#define liblldb_ClangExpressionParser_h_ +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONPARSER_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONPARSER_H -#include "lldb/Core/ClangForward.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/ExpressionParser.h" #include "lldb/Utility/ArchSpec.h" @@ -19,13 +18,20 @@ #include #include +namespace llvm { +class LLVMContext; +} + namespace clang { +class CodeGenerator; class CodeCompleteConsumer; -} +class CompilerInstance; +} // namespace clang namespace lldb_private { class IRExecutionUnit; +class TypeSystemClang; /// \class ClangExpressionParser ClangExpressionParser.h /// "lldb/Expression/ClangExpressionParser.h" Encapsulates an instance of @@ -171,7 +177,7 @@ private: class LLDBPreprocessorCallbacks; LLDBPreprocessorCallbacks *m_pp_callbacks; ///< Called when the preprocessor ///encounters module imports - std::unique_ptr m_ast_context; + std::unique_ptr m_ast_context; std::vector m_include_directories; /// File name used for the user expression. @@ -179,4 +185,4 @@ private: }; } -#endif // liblldb_ClangExpressionParser_h_ +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONPARSER_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp index 7ebb5fee1ec..a429963277d 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp @@ -1,4 +1,4 @@ -//===-- ClangExpressionSourceCode.cpp ---------------------------*- C++ -*-===// +//===-- ClangExpressionSourceCode.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,6 +9,7 @@ #include "ClangExpressionSourceCode.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" #include "llvm/ADT/StringRef.h" @@ -173,8 +174,8 @@ static void AddMacros(const DebugMacros *dm, CompileUnit *comp_unit, lldb_private::ClangExpressionSourceCode::ClangExpressionSourceCode( llvm::StringRef filename, llvm::StringRef name, llvm::StringRef prefix, - llvm::StringRef body, Wrapping wrap) - : ExpressionSourceCode(name, prefix, body, wrap) { + llvm::StringRef body, Wrapping wrap, WrapKind wrap_kind) + : ExpressionSourceCode(name, prefix, body, wrap), m_wrap_kind(wrap_kind) { // Use #line markers to pretend that we have a single-line source file // containing only the user expression. This will hide our wrapper code // from the user when we render diagnostics with Clang. @@ -260,10 +261,9 @@ TokenVerifier::TokenVerifier(std::string body) { } } -static void AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp, - StreamString &stream, - const std::string &expr, - lldb::LanguageType wrapping_language) { +void ClangExpressionSourceCode::AddLocalVariableDecls( + const lldb::VariableListSP &var_list_sp, StreamString &stream, + const std::string &expr) const { TokenVerifier tokens(expr); for (size_t i = 0; i < var_list_sp->GetSize(); i++) { @@ -280,13 +280,12 @@ static void AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp, if (!expr.empty() && !tokens.hasToken(var_name.GetStringRef())) continue; - if ((var_name == "self" || var_name == "_cmd") && - (wrapping_language == lldb::eLanguageTypeObjC || - wrapping_language == lldb::eLanguageTypeObjC_plus_plus)) + const bool is_objc = m_wrap_kind == WrapKind::ObjCInstanceMethod || + m_wrap_kind == WrapKind::ObjCStaticMethod; + if ((var_name == "self" || var_name == "_cmd") && is_objc) continue; - if (var_name == "this" && - wrapping_language == lldb::eLanguageTypeC_plus_plus) + if (var_name == "this" && m_wrap_kind == WrapKind::CppMemberFunction) continue; stream.Printf("using $__lldb_local_vars::%s;\n", var_name.AsCString()); @@ -294,9 +293,8 @@ static void AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp, } bool ClangExpressionSourceCode::GetText( - std::string &text, lldb::LanguageType wrapping_language, bool static_method, - ExecutionContext &exe_ctx, bool add_locals, bool force_add_all_locals, - llvm::ArrayRef modules) const { + std::string &text, ExecutionContext &exe_ctx, bool add_locals, + bool force_add_all_locals, llvm::ArrayRef modules) const { const char *target_specific_defines = "typedef signed char BOOL;\n"; std::string module_macros; @@ -373,21 +371,11 @@ bool ClangExpressionSourceCode::GetText( lldb::VariableListSP var_list_sp = frame->GetInScopeVariableList(false, true); AddLocalVariableDecls(var_list_sp, lldb_local_var_decls, - force_add_all_locals ? "" : m_body, - wrapping_language); + force_add_all_locals ? "" : m_body); } } if (m_wrap) { - switch (wrapping_language) { - default: - return false; - case lldb::eLanguageTypeC: - case lldb::eLanguageTypeC_plus_plus: - case lldb::eLanguageTypeObjC: - break; - } - // Generate a list of @import statements that will import the specified // module into our expression. std::string module_imports; @@ -406,22 +394,12 @@ bool ClangExpressionSourceCode::GetText( // First construct a tagged form of the user expression so we can find it // later: std::string tagged_body; - switch (wrapping_language) { - default: - tagged_body = m_body; - break; - case lldb::eLanguageTypeC: - case lldb::eLanguageTypeC_plus_plus: - case lldb::eLanguageTypeObjC: - tagged_body.append(m_start_marker); - tagged_body.append(m_body); - tagged_body.append(m_end_marker); - break; - } - switch (wrapping_language) { - default: - break; - case lldb::eLanguageTypeC: + tagged_body.append(m_start_marker); + tagged_body.append(m_body); + tagged_body.append(m_end_marker); + + switch (m_wrap_kind) { + case WrapKind::Function: wrap_stream.Printf("%s" "void \n" "%s(void *$__lldb_arg) \n" @@ -432,7 +410,7 @@ bool ClangExpressionSourceCode::GetText( module_imports.c_str(), m_name.c_str(), lldb_local_var_decls.GetData(), tagged_body.c_str()); break; - case lldb::eLanguageTypeC_plus_plus: + case WrapKind::CppMemberFunction: wrap_stream.Printf("%s" "void \n" "$__lldb_class::%s(void *$__lldb_arg) \n" @@ -443,42 +421,42 @@ bool ClangExpressionSourceCode::GetText( module_imports.c_str(), m_name.c_str(), lldb_local_var_decls.GetData(), tagged_body.c_str()); break; - case lldb::eLanguageTypeObjC: - if (static_method) { - wrap_stream.Printf( - "%s" - "@interface $__lldb_objc_class ($__lldb_category) \n" - "+(void)%s:(void *)$__lldb_arg; \n" - "@end \n" - "@implementation $__lldb_objc_class ($__lldb_category) \n" - "+(void)%s:(void *)$__lldb_arg \n" - "{ \n" - " %s; \n" - "%s" - "} \n" - "@end \n", - module_imports.c_str(), m_name.c_str(), m_name.c_str(), - lldb_local_var_decls.GetData(), tagged_body.c_str()); - } else { - wrap_stream.Printf( - "%s" - "@interface $__lldb_objc_class ($__lldb_category) \n" - "-(void)%s:(void *)$__lldb_arg; \n" - "@end \n" - "@implementation $__lldb_objc_class ($__lldb_category) \n" - "-(void)%s:(void *)$__lldb_arg \n" - "{ \n" - " %s; \n" - "%s" - "} \n" - "@end \n", - module_imports.c_str(), m_name.c_str(), m_name.c_str(), - lldb_local_var_decls.GetData(), tagged_body.c_str()); - } + case WrapKind::ObjCInstanceMethod: + wrap_stream.Printf( + "%s" + "@interface $__lldb_objc_class ($__lldb_category) \n" + "-(void)%s:(void *)$__lldb_arg; \n" + "@end \n" + "@implementation $__lldb_objc_class ($__lldb_category) \n" + "-(void)%s:(void *)$__lldb_arg \n" + "{ \n" + " %s; \n" + "%s" + "} \n" + "@end \n", + module_imports.c_str(), m_name.c_str(), m_name.c_str(), + lldb_local_var_decls.GetData(), tagged_body.c_str()); + break; + + case WrapKind::ObjCStaticMethod: + wrap_stream.Printf( + "%s" + "@interface $__lldb_objc_class ($__lldb_category) \n" + "+(void)%s:(void *)$__lldb_arg; \n" + "@end \n" + "@implementation $__lldb_objc_class ($__lldb_category) \n" + "+(void)%s:(void *)$__lldb_arg \n" + "{ \n" + " %s; \n" + "%s" + "} \n" + "@end \n", + module_imports.c_str(), m_name.c_str(), m_name.c_str(), + lldb_local_var_decls.GetData(), tagged_body.c_str()); break; } - text = wrap_stream.GetString(); + text = std::string(wrap_stream.GetString()); } else { text.append(m_body); } @@ -487,17 +465,7 @@ bool ClangExpressionSourceCode::GetText( } bool ClangExpressionSourceCode::GetOriginalBodyBounds( - std::string transformed_text, lldb::LanguageType wrapping_language, - size_t &start_loc, size_t &end_loc) { - switch (wrapping_language) { - default: - return false; - case lldb::eLanguageTypeC: - case lldb::eLanguageTypeC_plus_plus: - case lldb::eLanguageTypeObjC: - break; - } - + std::string transformed_text, size_t &start_loc, size_t &end_loc) { start_loc = transformed_text.find(m_start_marker); if (start_loc == std::string::npos) return false; diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h index 1d159670b96..9a54f0e3ad8 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ClangExpressionSourceCode_h -#define liblldb_ClangExpressionSourceCode_h +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONSOURCECODE_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONSOURCECODE_H #include "lldb/Expression/Expression.h" #include "lldb/Expression/ExpressionSourceCode.h" @@ -28,20 +28,30 @@ public: static const llvm::StringRef g_prefix_file_name; static const char *g_expression_prefix; + /// The possible ways an expression can be wrapped. + enum class WrapKind { + /// Wrapped in a non-static member function of a C++ class. + CppMemberFunction, + /// Wrapped in an instance Objective-C method. + ObjCInstanceMethod, + /// Wrapped in a static Objective-C method. + ObjCStaticMethod, + /// Wrapped in a non-member function. + /// Note that this is also used for static member functions of a C++ class. + Function + }; + static ClangExpressionSourceCode *CreateWrapped(llvm::StringRef filename, llvm::StringRef prefix, - llvm::StringRef body) { + llvm::StringRef body, + WrapKind wrap_kind) { return new ClangExpressionSourceCode(filename, "$__lldb_expr", prefix, body, - Wrap); + Wrap, wrap_kind); } /// Generates the source code that will evaluate the expression. /// /// \param text output parameter containing the source code string. - /// \param wrapping_language If the expression is supossed to be wrapped, - /// then this is the language that should be used for that. - /// \param static_method True iff the expression is valuated inside a static - /// Objective-C method. /// \param exe_ctx The execution context in which the expression will be /// evaluated. /// \param add_locals True iff local variables should be injected into the @@ -51,8 +61,7 @@ public: /// \param modules A list of (C++) modules that the expression should import. /// /// \return true iff the source code was successfully generated. - bool GetText(std::string &text, lldb::LanguageType wrapping_language, - bool static_method, ExecutionContext &exe_ctx, bool add_locals, + bool GetText(std::string &text, ExecutionContext &exe_ctx, bool add_locals, bool force_add_all_locals, llvm::ArrayRef modules) const; @@ -60,19 +69,24 @@ public: // passed to CreateWrapped. Return true if the bounds could be found. This // will also work on text with FixItHints applied. bool GetOriginalBodyBounds(std::string transformed_text, - lldb::LanguageType wrapping_language, size_t &start_loc, size_t &end_loc); protected: ClangExpressionSourceCode(llvm::StringRef filename, llvm::StringRef name, llvm::StringRef prefix, llvm::StringRef body, - Wrapping wrap); + Wrapping wrap, WrapKind wrap_kind); private: + void AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp, + StreamString &stream, + const std::string &expr) const; + /// String marking the start of the user expression. std::string m_start_marker; /// String marking the end of the user expression. std::string m_end_marker; + /// How the expression has been wrapped. + const WrapKind m_wrap_kind; }; } // namespace lldb_private diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp index b5a2c80b534..9af92e194da 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp @@ -1,4 +1,4 @@ -//===-- ClangExpressionVariable.cpp -----------------------------*- C++ -*-===// +//===-- ClangExpressionVariable.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h index 0e6de28ee4d..58d589962ab 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ClangExpressionVariable_h_ -#define liblldb_ClangExpressionVariable_h_ +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H #include #include @@ -19,7 +19,6 @@ #include "llvm/Support/Casting.h" -#include "lldb/Core/ClangForward.h" #include "lldb/Core/Value.h" #include "lldb/Expression/ExpressionVariable.h" #include "lldb/Symbol/TaggedASTType.h" @@ -30,6 +29,10 @@ namespace llvm { class Value; } +namespace clang { +class NamedDecl; +} + namespace lldb_private { class ValueObjectConstResult; @@ -114,11 +117,9 @@ public: class ParserVars { public: ParserVars() - : m_parser_type(), m_named_decl(nullptr), m_llvm_value(nullptr), + : m_named_decl(nullptr), m_llvm_value(nullptr), m_lldb_value(), m_lldb_var(), m_lldb_sym(nullptr) {} - TypeFromParser - m_parser_type; ///< The type of the variable according to the parser const clang::NamedDecl *m_named_decl; ///< The Decl corresponding to this variable llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable; @@ -196,9 +197,11 @@ public: } /// Members - DISALLOW_COPY_AND_ASSIGN(ClangExpressionVariable); + ClangExpressionVariable(const ClangExpressionVariable &) = delete; + const ClangExpressionVariable & + operator=(const ClangExpressionVariable &) = delete; }; } // namespace lldb_private -#endif // liblldb_ClangExpressionVariable_h_ +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp new file mode 100644 index 00000000000..390afb458b5 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp @@ -0,0 +1,88 @@ +//===-- ClangExternalASTSourceCallbacks.cpp -------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" + +#include "clang/AST/Decl.h" +#include "clang/AST/DeclObjC.h" + +using namespace lldb_private; + +char ClangExternalASTSourceCallbacks::ID; + +void ClangExternalASTSourceCallbacks::CompleteType(clang::TagDecl *tag_decl) { + m_ast.CompleteTagDecl(tag_decl); +} + +void ClangExternalASTSourceCallbacks::CompleteType( + clang::ObjCInterfaceDecl *objc_decl) { + m_ast.CompleteObjCInterfaceDecl(objc_decl); +} + +bool ClangExternalASTSourceCallbacks::layoutRecordType( + const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, + llvm::DenseMap &FieldOffsets, + llvm::DenseMap &BaseOffsets, + llvm::DenseMap + &VirtualBaseOffsets) { + return m_ast.LayoutRecordType(Record, Size, Alignment, FieldOffsets, + BaseOffsets, VirtualBaseOffsets); +} + +void ClangExternalASTSourceCallbacks::FindExternalLexicalDecls( + const clang::DeclContext *decl_ctx, + llvm::function_ref IsKindWeWant, + llvm::SmallVectorImpl &decls) { + if (decl_ctx) { + clang::TagDecl *tag_decl = llvm::dyn_cast( + const_cast(decl_ctx)); + if (tag_decl) + CompleteType(tag_decl); + } +} + +bool ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName( + const clang::DeclContext *DC, clang::DeclarationName Name) { + llvm::SmallVector decls; + // Objective-C methods are not added into the LookupPtr when they originate + // from an external source. SetExternalVisibleDeclsForName() adds them. + if (auto *oid = llvm::dyn_cast(DC)) { + clang::ObjCContainerDecl::method_range noload_methods(oid->noload_decls()); + for (auto *omd : noload_methods) + if (omd->getDeclName() == Name) + decls.push_back(omd); + } + return !SetExternalVisibleDeclsForName(DC, Name, decls).empty(); +} + +OptionalClangModuleID +ClangExternalASTSourceCallbacks::RegisterModule(clang::Module *module) { + m_modules.push_back(module); + unsigned id = m_modules.size(); + m_ids.insert({module, id}); + return OptionalClangModuleID(id); +} + +llvm::Optional +ClangExternalASTSourceCallbacks::getSourceDescriptor(unsigned id) { + if (clang::Module *module = getModule(id)) + return {*module}; + return {}; +} + +clang::Module *ClangExternalASTSourceCallbacks::getModule(unsigned id) { + if (id && id <= m_modules.size()) + return m_modules[id - 1]; + return nullptr; +} + +OptionalClangModuleID +ClangExternalASTSourceCallbacks::GetIDForModule(clang::Module *module) { + return OptionalClangModuleID(m_ids[module]); +} diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h new file mode 100644 index 00000000000..69088d9c82a --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h @@ -0,0 +1,66 @@ +//===-- ClangExternalASTSourceCallbacks.h -----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXTERNALASTSOURCECALLBACKS_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXTERNALASTSOURCECALLBACKS_H + +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" +#include "clang/Basic/Module.h" + +namespace lldb_private { + +class ClangExternalASTSourceCallbacks : public clang::ExternalASTSource { + /// LLVM RTTI support. + static char ID; + +public: + /// LLVM RTTI support. + bool isA(const void *ClassID) const override { return ClassID == &ID; } + static bool classof(const clang::ExternalASTSource *s) { return s->isA(&ID); } + + ClangExternalASTSourceCallbacks(TypeSystemClang &ast) : m_ast(ast) {} + + void FindExternalLexicalDecls( + const clang::DeclContext *DC, + llvm::function_ref IsKindWeWant, + llvm::SmallVectorImpl &Result) override; + + bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC, + clang::DeclarationName Name) override; + + void CompleteType(clang::TagDecl *tag_decl) override; + + void CompleteType(clang::ObjCInterfaceDecl *objc_decl) override; + + bool layoutRecordType( + const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, + llvm::DenseMap &FieldOffsets, + llvm::DenseMap + &BaseOffsets, + llvm::DenseMap + &VirtualBaseOffsets) override; + + TypeSystemClang &GetTypeSystem() const { return m_ast; } + + /// Module-related methods. + /// \{ + llvm::Optional + getSourceDescriptor(unsigned ID) override; + clang::Module *getModule(unsigned ID) override; + OptionalClangModuleID RegisterModule(clang::Module *module); + OptionalClangModuleID GetIDForModule(clang::Module *module); + /// \} +private: + TypeSystemClang &m_ast; + std::vector m_modules; + llvm::DenseMap m_ids; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXTERNALASTSOURCECALLBACKS_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp index 7f7c0a97f53..0c9ad202103 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp @@ -1,4 +1,4 @@ -//===-- ClangFunctionCaller.cpp ---------------------------------*- C++ -*-===// +//===-- ClangFunctionCaller.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -21,12 +21,12 @@ #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/IR/Module.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Module.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectList.h" #include "lldb/Expression/IRExecutionUnit.h" #include "lldb/Interpreter/CommandReturnObject.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Type.h" #include "lldb/Target/ExecutionContext.h" @@ -209,8 +209,8 @@ ClangFunctionCaller::CompileFunction(lldb::ThreadSP thread_to_use_sp, clang::ASTConsumer * ClangFunctionCaller::ClangFunctionCallerHelper::ASTTransformer( clang::ASTConsumer *passthrough) { - m_struct_extractor.reset(new ASTStructExtractor( - passthrough, m_owner.GetWrapperStructName(), m_owner)); + m_struct_extractor = std::make_unique( + passthrough, m_owner.GetWrapperStructName(), m_owner); return m_struct_extractor.get(); } diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h index 150a913152d..8060b8c0aed 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h @@ -6,13 +6,12 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ClangFunctionCaller_h_ -#define liblldb_ClangFunctionCaller_h_ +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGFUNCTIONCALLER_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGFUNCTIONCALLER_H #include "ClangExpressionHelper.h" #include "lldb/Core/Address.h" -#include "lldb/Core/ClangForward.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectList.h" #include "lldb/Expression/FunctionCaller.h" @@ -150,4 +149,4 @@ private: } // namespace lldb_private -#endif // liblldb_ClangFunctionCaller_h_ +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGFUNCTIONCALLER_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp index 42d3f22014d..8abb7e42057 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp @@ -1,4 +1,4 @@ -//===-- ClangHost.cpp -------------------------------------------*- C++ -*-===// +//===-- ClangHost.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -67,10 +67,10 @@ static bool DefaultComputeClangResourceDirectory(FileSpec &lldb_shlib_spec, llvm::sys::path::native(relative_path); llvm::sys::path::append(clang_dir, relative_path); if (!verify || VerifyClangPath(clang_dir)) { - LLDB_LOGF(log, - "DefaultComputeClangResourceDir: Setting ClangResourceDir " - "to \"%s\", verify = %s", - clang_dir.str().str().c_str(), verify ? "true" : "false"); + LLDB_LOG(log, + "DefaultComputeClangResourceDir: Setting ClangResourceDir " + "to \"{0}\", verify = {1}", + clang_dir.str(), verify ? "true" : "false"); file_spec.GetDirectory().SetString(clang_dir); FileSystem::Instance().Resolve(file_spec); return true; diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.h index 9d49188178c..d6809909a62 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGHOST_H -#define LLDB_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGHOST_H +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGHOST_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGHOST_H namespace lldb_private { diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp index 0696c669f2e..95acb883774 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp @@ -1,4 +1,4 @@ -//===-- ClangModulesDeclVendor.cpp ------------------------------*- C++ -*-===// +//===-- ClangModulesDeclVendor.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,11 +6,10 @@ // //===----------------------------------------------------------------------===// -#include - #include "clang/Basic/TargetInfo.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendActions.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorOptions.h" #include "clang/Parse/Parser.h" @@ -24,10 +23,10 @@ #include "ClangModulesDeclVendor.h" #include "ModuleDependencyCollector.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ModuleList.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/SourceModule.h" #include "lldb/Target/Target.h" @@ -37,6 +36,9 @@ #include "lldb/Utility/Reproducer.h" #include "lldb/Utility/StreamString.h" +#include +#include + using namespace lldb_private; namespace { @@ -54,10 +56,21 @@ public: void DumpDiagnostics(Stream &error_stream); + void BeginSourceFile(const clang::LangOptions &LangOpts, + const clang::Preprocessor *PP = nullptr) override; + void EndSourceFile() override; + private: typedef std::pair IDAndDiagnostic; std::vector m_diagnostics; + /// The DiagnosticPrinter used for creating the full diagnostic messages + /// that are stored in m_diagnostics. + std::shared_ptr m_diag_printer; + /// Output stream of m_diag_printer. + std::shared_ptr m_os; + /// Output string filled by m_os. Will be reused for different diagnostics. + std::string m_output; Log *m_log; }; @@ -108,25 +121,30 @@ private: typedef std::set ImportedModuleSet; ImportedModuleMap m_imported_modules; ImportedModuleSet m_user_imported_modules; - // We assume that every ASTContext has an ClangASTContext, so we also store - // a custom ClangASTContext for our internal ASTContext. - std::unique_ptr m_ast_context; + // We assume that every ASTContext has an TypeSystemClang, so we also store + // a custom TypeSystemClang for our internal ASTContext. + std::unique_ptr m_ast_context; }; } // anonymous namespace StoringDiagnosticConsumer::StoringDiagnosticConsumer() { m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + + clang::DiagnosticOptions *m_options = new clang::DiagnosticOptions(); + m_os = std::make_shared(m_output); + m_diag_printer = + std::make_shared(*m_os, m_options); } void StoringDiagnosticConsumer::HandleDiagnostic( clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info) { - llvm::SmallVector diagnostic_string; + // Print the diagnostic to m_output. + m_output.clear(); + m_diag_printer->HandleDiagnostic(DiagLevel, info); + m_os->flush(); - info.FormatDiagnostic(diagnostic_string); - - m_diagnostics.push_back( - IDAndDiagnostic(DiagLevel, std::string(diagnostic_string.data(), - diagnostic_string.size()))); + // Store the diagnostic for later. + m_diagnostics.push_back(IDAndDiagnostic(DiagLevel, m_output)); } void StoringDiagnosticConsumer::ClearDiagnostics() { m_diagnostics.clear(); } @@ -144,6 +162,15 @@ void StoringDiagnosticConsumer::DumpDiagnostics(Stream &error_stream) { } } +void StoringDiagnosticConsumer::BeginSourceFile( + const clang::LangOptions &LangOpts, const clang::Preprocessor *PP) { + m_diag_printer->BeginSourceFile(LangOpts, PP); +} + +void StoringDiagnosticConsumer::EndSourceFile() { + m_diag_printer->EndSourceFile(); +} + ClangModulesDeclVendor::ClangModulesDeclVendor() : ClangDeclVendor(eClangModuleDeclVendor) {} @@ -159,8 +186,10 @@ ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl( m_compiler_instance(std::move(compiler_instance)), m_parser(std::move(parser)) { - // Initialize our ClangASTContext. - m_ast_context.reset(new ClangASTContext(m_compiler_instance->getASTContext())); + // Initialize our TypeSystemClang. + m_ast_context = + std::make_unique("ClangModulesDeclVendor ASTContext", + m_compiler_instance->getASTContext()); } void ClangModulesDeclVendorImpl::ReportModuleExportsHelper( @@ -382,7 +411,7 @@ ClangModulesDeclVendorImpl::FindDecls(ConstString name, bool append, if (num_matches >= max_matches) return num_matches; - decls.push_back(CompilerDecl(m_ast_context.get(), named_decl)); + decls.push_back(m_ast_context->GetCompilerDecl(named_decl)); ++num_matches; } @@ -601,10 +630,10 @@ ClangModulesDeclVendor::Create(Target &target) { { llvm::SmallString<128> path; - auto props = ModuleList::GetGlobalModuleListProperties(); + const auto &props = ModuleList::GetGlobalModuleListProperties(); props.GetClangModulesCachePath().GetPath(path); std::string module_cache_argument("-fmodules-cache-path="); - module_cache_argument.append(path.str()); + module_cache_argument.append(std::string(path.str())); compiler_invocation_arguments.push_back(module_cache_argument); } diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h index e099b59041d..f04d1b07f03 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h @@ -6,10 +6,9 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ClangModulesDeclVendor_h -#define liblldb_ClangModulesDeclVendor_h +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGMODULESDECLVENDOR_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGMODULESDECLVENDOR_H -#include "lldb/Core/ClangForward.h" #include "lldb/Symbol/SourceModule.h" #include "lldb/Target/Platform.h" @@ -113,4 +112,4 @@ public: } // namespace lldb_private -#endif // liblldb_ClangModulesDeclVendor_h +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGMODULESDECLVENDOR_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp index 41d62a462ab..42afac9edb0 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp @@ -1,4 +1,4 @@ -//===-- ClangPersistentVariables.cpp ----------------------------*- C++ -*-===// +//===-- ClangPersistentVariables.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,9 +7,10 @@ //===----------------------------------------------------------------------===// #include "ClangPersistentVariables.h" +#include "ClangASTImporter.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Value.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" @@ -82,7 +83,7 @@ ClangPersistentVariables::GetCompilerTypeFromPersistentDecl( void ClangPersistentVariables::RegisterPersistentDecl(ConstString name, clang::NamedDecl *decl, - ClangASTContext *ctx) { + TypeSystemClang *ctx) { PersistentDecl p = {decl, ctx}; m_persistent_decls.insert(std::make_pair(name.GetCString(), p)); @@ -99,3 +100,22 @@ clang::NamedDecl * ClangPersistentVariables::GetPersistentDecl(ConstString name) { return m_persistent_decls.lookup(name.GetCString()).m_decl; } + +std::shared_ptr +ClangPersistentVariables::GetClangASTImporter() { + if (!m_ast_importer_sp) { + m_ast_importer_sp = std::make_shared(); + } + return m_ast_importer_sp; +} + +ConstString +ClangPersistentVariables::GetNextPersistentVariableName(bool is_error) { + llvm::SmallString<64> name; + { + llvm::raw_svector_ostream os(name); + os << GetPersistentVariablePrefix(is_error) + << m_next_persistent_variable_id++; + } + return ConstString(name); +} diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h index 434196b35fd..f888b2d56e6 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ClangPersistentVariables_h_ -#define liblldb_ClangPersistentVariables_h_ +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGPERSISTENTVARIABLES_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGPERSISTENTVARIABLES_H #include "llvm/ADT/DenseMap.h" @@ -18,6 +18,9 @@ namespace lldb_private { +class ClangASTImporter; +class TypeSystemClang; + /// \class ClangPersistentVariables ClangPersistentVariables.h /// "lldb/Expression/ClangPersistentVariables.h" Manages persistent values /// that need to be preserved between expression invocations. @@ -36,6 +39,8 @@ public: return pv->getKind() == PersistentExpressionState::eKindClang; } + std::shared_ptr GetClangASTImporter(); + lldb::ExpressionVariableSP CreatePersistentVariable(const lldb::ValueObjectSP &valobj_sp) override; @@ -46,9 +51,7 @@ public: void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override; - llvm::StringRef GetPersistentVariablePrefix(bool is_error) const override { - return "$"; - } + ConstString GetNextPersistentVariableName(bool is_error = false) override; /// Returns the next file name that should be used for user expressions. std::string GetNextExprFileName() { @@ -63,7 +66,7 @@ public: GetCompilerTypeFromPersistentDecl(ConstString type_name) override; void RegisterPersistentDecl(ConstString name, clang::NamedDecl *decl, - ClangASTContext *ctx); + TypeSystemClang *ctx); clang::NamedDecl *GetPersistentDecl(ConstString name); @@ -75,6 +78,12 @@ public: return m_hand_loaded_clang_modules; } +protected: + llvm::StringRef + GetPersistentVariablePrefix(bool is_error = false) const override { + return "$"; + } + private: /// The counter used by GetNextExprFileName. uint32_t m_next_user_file_id = 0; @@ -84,8 +93,8 @@ private: struct PersistentDecl { /// The persistent decl. clang::NamedDecl *m_decl = nullptr; - /// The ClangASTContext for the ASTContext of m_decl. - ClangASTContext *m_context = nullptr; + /// The TypeSystemClang for the ASTContext of m_decl. + TypeSystemClang *m_context = nullptr; }; typedef llvm::DenseMap PersistentDeclMap; @@ -96,8 +105,9 @@ private: m_hand_loaded_clang_modules; ///< These are Clang modules we hand-loaded; ///these are the highest- ///< priority source for macros. + std::shared_ptr m_ast_importer_sp; }; } // namespace lldb_private -#endif // liblldb_ClangPersistentVariables_h_ +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGPERSISTENTVARIABLES_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp index 6698797617a..a28b4a7fb42 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp @@ -1,4 +1,4 @@ -//===-- ClangUserExpression.cpp ---------------------------------*- C++ -*-===// +//===-- ClangUserExpression.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -20,6 +20,7 @@ #include "ClangUserExpression.h" #include "ASTResultSynthesizer.h" +#include "ClangASTMetadata.h" #include "ClangDiagnostic.h" #include "ClangExpressionDeclMap.h" #include "ClangExpressionParser.h" @@ -27,6 +28,7 @@ #include "ClangPersistentVariables.h" #include "CppModuleConfiguration.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/StreamFile.h" @@ -37,8 +39,6 @@ #include "lldb/Expression/Materializer.h" #include "lldb/Host/HostInfo.h" #include "lldb/Symbol/Block.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangASTMetadata.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" @@ -154,7 +154,7 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) { } m_needs_object_ptr = true; } else if (clang::CXXMethodDecl *method_decl = - ClangASTContext::DeclContextGetAsCXXMethodDecl(decl_context)) { + TypeSystemClang::DeclContextGetAsCXXMethodDecl(decl_context)) { if (m_allow_cxx && method_decl->isInstance()) { if (m_enforce_valid_object) { lldb::VariableListSP variable_list_sp( @@ -183,7 +183,7 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) { m_needs_object_ptr = true; } } else if (clang::ObjCMethodDecl *method_decl = - ClangASTContext::DeclContextGetAsObjCMethodDecl( + TypeSystemClang::DeclContextGetAsObjCMethodDecl( decl_context)) { if (m_allow_objc) { if (m_enforce_valid_object) { @@ -216,7 +216,7 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) { m_in_static_method = true; } } else if (clang::FunctionDecl *function_decl = - ClangASTContext::DeclContextGetAsFunctionDecl(decl_context)) { + TypeSystemClang::DeclContextGetAsFunctionDecl(decl_context)) { // We might also have a function that said in the debug information that it // captured an object pointer. The best way to deal with getting to the // ivars at present is by pretending that this is a method of a class in @@ -224,7 +224,7 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) { // that here. ClangASTMetadata *metadata = - ClangASTContext::DeclContextGetMetaData(decl_context, function_decl); + TypeSystemClang::DeclContextGetMetaData(decl_context, function_decl); if (metadata && metadata->HasObjectPtr()) { lldb::LanguageType language = metadata->GetObjectPtrLanguage(); if (language == lldb::eLanguageTypeC_plus_plus) { @@ -292,9 +292,9 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) { return; } - if (ClangASTContext::IsObjCClassType(self_clang_type)) { + if (TypeSystemClang::IsObjCClassType(self_clang_type)) { return; - } else if (ClangASTContext::IsObjCObjectPointerType( + } else if (TypeSystemClang::IsObjCObjectPointerType( self_clang_type)) { m_in_objectivec_method = true; m_needs_object_ptr = true; @@ -347,50 +347,70 @@ bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_man return true; } -static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target) { - if (ClangModulesDeclVendor *decl_vendor = - target->GetClangModulesDeclVendor()) { - auto *persistent_state = llvm::cast( - target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC)); - if (!persistent_state) - return; - const ClangModulesDeclVendor::ModuleVector &hand_imported_modules = - persistent_state->GetHandLoadedClangModules(); - ClangModulesDeclVendor::ModuleVector modules_for_macros; +static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target, + DiagnosticManager &diagnostic_manager) { + ClangModulesDeclVendor *decl_vendor = target->GetClangModulesDeclVendor(); + if (!decl_vendor) + return; - for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules) { - modules_for_macros.push_back(module); - } + if (!target->GetEnableAutoImportClangModules()) + return; - if (target->GetEnableAutoImportClangModules()) { - if (StackFrame *frame = exe_ctx.GetFramePtr()) { - if (Block *block = frame->GetFrameBlock()) { - SymbolContext sc; + auto *persistent_state = llvm::cast( + target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC)); + if (!persistent_state) + return; - block->CalculateSymbolContext(&sc); + StackFrame *frame = exe_ctx.GetFramePtr(); + if (!frame) + return; - if (sc.comp_unit) { - StreamString error_stream; + Block *block = frame->GetFrameBlock(); + if (!block) + return; + SymbolContext sc; - decl_vendor->AddModulesForCompileUnit( - *sc.comp_unit, modules_for_macros, error_stream); - } - } - } - } + block->CalculateSymbolContext(&sc); + + if (!sc.comp_unit) + return; + StreamString error_stream; + + ClangModulesDeclVendor::ModuleVector modules_for_macros = + persistent_state->GetHandLoadedClangModules(); + if (decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros, + error_stream)) + return; + + // Failed to load some modules, so emit the error stream as a diagnostic. + if (!error_stream.Empty()) { + // The error stream already contains several Clang diagnostics that might + // be either errors or warnings, so just print them all as one remark + // diagnostic to prevent that the message starts with "error: error:". + diagnostic_manager.PutString(eDiagnosticSeverityRemark, + error_stream.GetString()); + return; } + + diagnostic_manager.PutString(eDiagnosticSeverityError, + "Unknown error while loading modules needed for " + "current compilation unit."); } -void ClangUserExpression::UpdateLanguageForExpr() { - m_expr_lang = lldb::LanguageType::eLanguageTypeUnknown; - if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) - return; +ClangExpressionSourceCode::WrapKind ClangUserExpression::GetWrapKind() const { + assert(m_options.GetExecutionPolicy() != eExecutionPolicyTopLevel && + "Top level expressions aren't wrapped."); + using Kind = ClangExpressionSourceCode::WrapKind; if (m_in_cplusplus_method) - m_expr_lang = lldb::eLanguageTypeC_plus_plus; - else if (m_in_objectivec_method) - m_expr_lang = lldb::eLanguageTypeObjC; - else - m_expr_lang = lldb::eLanguageTypeC; + return Kind::CppMemberFunction; + else if (m_in_objectivec_method) { + if (m_in_static_method) + return Kind::ObjCStaticMethod; + return Kind::ObjCInstanceMethod; + } + // Not in any kind of 'special' function, so just wrap it in a normal C + // function. + return Kind::Function; } void ClangUserExpression::CreateSourceCode( @@ -404,10 +424,9 @@ void ClangUserExpression::CreateSourceCode( m_transformed_text = m_expr_text; } else { m_source_code.reset(ClangExpressionSourceCode::CreateWrapped( - m_filename, prefix.c_str(), m_expr_text.c_str())); + m_filename, prefix, m_expr_text, GetWrapKind())); - if (!m_source_code->GetText(m_transformed_text, m_expr_lang, - m_in_static_method, exe_ctx, !m_ctx_obj, + if (!m_source_code->GetText(m_transformed_text, exe_ctx, !m_ctx_obj, for_completion, modules_to_import)) { diagnostic_manager.PutString(eDiagnosticSeverityError, "couldn't construct expression body"); @@ -419,7 +438,7 @@ void ClangUserExpression::CreateSourceCode( std::size_t original_start; std::size_t original_end; bool found_bounds = m_source_code->GetOriginalBodyBounds( - m_transformed_text, m_expr_lang, original_start, original_end); + m_transformed_text, original_start, original_end); if (found_bounds) m_user_expression_start_pos = original_start; } @@ -530,7 +549,7 @@ bool ClangUserExpression::PrepareForParsing( ApplyObjcCastHack(m_expr_text); - SetupDeclVendor(exe_ctx, m_target); + SetupDeclVendor(exe_ctx, m_target, diagnostic_manager); CppModuleConfiguration module_config = GetModuleConfig(m_language, exe_ctx); llvm::ArrayRef imported_modules = @@ -544,7 +563,6 @@ bool ClangUserExpression::PrepareForParsing( llvm::make_range(m_include_directories.begin(), m_include_directories.end())); - UpdateLanguageForExpr(); CreateSourceCode(diagnostic_manager, exe_ctx, imported_modules, for_completion); return true; @@ -577,7 +595,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, // Parse the expression // - m_materializer_up.reset(new Materializer()); + m_materializer_up = std::make_unique(); ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory); @@ -616,15 +634,13 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, if (parser.RewriteExpression(diagnostic_manager)) { size_t fixed_start; size_t fixed_end; - const std::string &fixed_expression = - diagnostic_manager.GetFixedExpression(); + m_fixed_text = diagnostic_manager.GetFixedExpression(); // Retrieve the original expression in case we don't have a top level // expression (which has no surrounding source code). - if (m_source_code && - m_source_code->GetOriginalBodyBounds(fixed_expression, m_expr_lang, - fixed_start, fixed_end)) + if (m_source_code && m_source_code->GetOriginalBodyBounds( + m_fixed_text, fixed_start, fixed_end)) m_fixed_text = - fixed_expression.substr(fixed_start, fixed_end - fixed_start); + m_fixed_text.substr(fixed_start, fixed_end - fixed_start); } } return false; @@ -659,7 +675,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, const char *error_cstr = static_init_error.AsCString(); if (error_cstr && error_cstr[0]) diagnostic_manager.Printf(eDiagnosticSeverityError, - "couldn't run static initializers: %s\n", + "%s\n", error_cstr); else diagnostic_manager.PutString(eDiagnosticSeverityError, @@ -767,7 +783,7 @@ bool ClangUserExpression::Complete(ExecutionContext &exe_ctx, // Parse the expression // - m_materializer_up.reset(new Materializer()); + m_materializer_up = std::make_unique(); ResetDeclMap(exe_ctx, m_result_delegate, /*keep result in memory*/ true); @@ -896,16 +912,23 @@ void ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap( Materializer::PersistentVariableDelegate &delegate, bool keep_result_in_memory, ValueObject *ctx_obj) { - m_expr_decl_map_up.reset(new ClangExpressionDeclMap( - keep_result_in_memory, &delegate, exe_ctx.GetTargetSP(), - exe_ctx.GetTargetRef().GetClangASTImporter(), ctx_obj)); + std::shared_ptr ast_importer; + auto *state = exe_ctx.GetTargetSP()->GetPersistentExpressionStateForLanguage( + lldb::eLanguageTypeC); + if (state) { + auto *persistent_vars = llvm::cast(state); + ast_importer = persistent_vars->GetClangASTImporter(); + } + m_expr_decl_map_up = std::make_unique( + keep_result_in_memory, &delegate, exe_ctx.GetTargetSP(), ast_importer, + ctx_obj); } clang::ASTConsumer * ClangUserExpression::ClangUserExpressionHelper::ASTTransformer( clang::ASTConsumer *passthrough) { - m_result_synthesizer_up.reset( - new ASTResultSynthesizer(passthrough, m_top_level, m_target)); + m_result_synthesizer_up = std::make_unique( + passthrough, m_top_level, m_target); return m_result_synthesizer_up.get(); } @@ -917,9 +940,7 @@ void ClangUserExpression::ClangUserExpressionHelper::CommitPersistentDecls() { } ConstString ClangUserExpression::ResultDelegate::GetName() { - auto prefix = m_persistent_state->GetPersistentVariablePrefix(); - return m_persistent_state->GetNextPersistentVariableName(*m_target_sp, - prefix); + return m_persistent_state->GetNextPersistentVariableName(false); } void ClangUserExpression::ResultDelegate::DidDematerialize( diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h index 00cbffa7fd6..f734069655e 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ClangUserExpression_h_ -#define liblldb_ClangUserExpression_h_ +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUSEREXPRESSION_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUSEREXPRESSION_H #include @@ -20,7 +20,6 @@ #include "IRForTarget.h" #include "lldb/Core/Address.h" -#include "lldb/Core/ClangForward.h" #include "lldb/Expression/LLVMUserExpression.h" #include "lldb/Expression/Materializer.h" #include "lldb/Target/ExecutionContext.h" @@ -186,7 +185,8 @@ private: ExecutionContext &exe_ctx, std::vector modules_to_import, bool for_completion); - void UpdateLanguageForExpr(); + /// Defines how the current expression should be wrapped. + ClangExpressionSourceCode::WrapKind GetWrapKind() const; bool SetupPersistentState(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx); bool PrepareForParsing(DiagnosticManager &diagnostic_manager, @@ -209,8 +209,6 @@ private: lldb::TargetSP m_target_sp; }; - /// The language type of the current expression. - lldb::LanguageType m_expr_lang = lldb::eLanguageTypeUnknown; /// The include directories that should be used when parsing the expression. std::vector m_include_directories; @@ -251,4 +249,4 @@ private: } // namespace lldb_private -#endif // liblldb_ClangUserExpression_h_ +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUSEREXPRESSION_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.cpp new file mode 100644 index 00000000000..a7f5dce8558 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.cpp @@ -0,0 +1,87 @@ +//===-- ClangUtil.cpp -----------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// A collection of helper methods and data structures for manipulating clang +// types and decls. +//===----------------------------------------------------------------------===// + +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" + +using namespace clang; +using namespace lldb_private; + +bool ClangUtil::IsClangType(const CompilerType &ct) { + // Invalid types are never Clang types. + if (!ct) + return false; + + if (llvm::dyn_cast_or_null(ct.GetTypeSystem()) == nullptr) + return false; + + if (!ct.GetOpaqueQualType()) + return false; + + return true; +} + +clang::Decl *ClangUtil::GetDecl(const CompilerDecl &decl) { + assert(llvm::isa(decl.GetTypeSystem())); + return static_cast(decl.GetOpaqueDecl()); +} + +QualType ClangUtil::GetQualType(const CompilerType &ct) { + // Make sure we have a clang type before making a clang::QualType + if (!IsClangType(ct)) + return QualType(); + + return QualType::getFromOpaquePtr(ct.GetOpaqueQualType()); +} + +QualType ClangUtil::GetCanonicalQualType(const CompilerType &ct) { + if (!IsClangType(ct)) + return QualType(); + + return GetQualType(ct).getCanonicalType(); +} + +CompilerType ClangUtil::RemoveFastQualifiers(const CompilerType &ct) { + if (!IsClangType(ct)) + return ct; + + QualType qual_type(GetQualType(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(); +} + +std::string ClangUtil::DumpDecl(const clang::Decl *d) { + if (!d) + return "nullptr"; + + std::string result; + llvm::raw_string_ostream stream(result); + bool deserialize = false; + d->dump(stream, deserialize); + + stream.flush(); + return result; +} + +std::string ClangUtil::ToString(const clang::Type *t) { + return clang::QualType(t, 0).getAsString(); +} + +std::string ClangUtil::ToString(const CompilerType &c) { + return ClangUtil::GetQualType(c).getAsString(); +} diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.h new file mode 100644 index 00000000000..50cae42bc7c --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.h @@ -0,0 +1,50 @@ +//===-- ClangUtil.h ---------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// A collection of helper methods and data structures for manipulating clang +// types and decls. +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUTIL_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUTIL_H + +#include "clang/AST/DeclBase.h" +#include "clang/AST/Type.h" + +#include "lldb/Symbol/CompilerType.h" + +namespace clang { +class TagDecl; +} + +namespace lldb_private { +struct ClangUtil { + static bool IsClangType(const CompilerType &ct); + + /// Returns the clang::Decl of the given CompilerDecl. + /// CompilerDecl has to be valid and represent a clang::Decl. + static clang::Decl *GetDecl(const CompilerDecl &decl); + + static clang::QualType GetQualType(const CompilerType &ct); + + static clang::QualType GetCanonicalQualType(const CompilerType &ct); + + static CompilerType RemoveFastQualifiers(const CompilerType &ct); + + static clang::TagDecl *GetAsTagDecl(const CompilerType &type); + + /// Returns a textual representation of the given Decl's AST. Does not + /// deserialize any child nodes. + static std::string DumpDecl(const clang::Decl *d); + /// Returns a textual representation of the given type. + static std::string ToString(const clang::Type *t); + /// Returns a textual representation of the given CompilerType (assuming + /// its underlying type is a Clang type). + static std::string ToString(const CompilerType &c); +}; +} + +#endif diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp index 199e4898e11..25ec982220a 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp @@ -1,4 +1,4 @@ -//===-- ClangUtilityFunction.cpp ---------------------------------*- C++-*-===// +//===-- ClangUtilityFunction.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -12,6 +12,7 @@ #include "ClangExpressionDeclMap.h" #include "ClangExpressionParser.h" #include "ClangExpressionSourceCode.h" +#include "ClangPersistentVariables.h" #include #if HAVE_SYS_TYPES_H @@ -159,7 +160,14 @@ bool ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager, void ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap( ExecutionContext &exe_ctx, bool keep_result_in_memory) { - m_expr_decl_map_up.reset(new ClangExpressionDeclMap( - keep_result_in_memory, nullptr, exe_ctx.GetTargetSP(), - exe_ctx.GetTargetRef().GetClangASTImporter(), nullptr)); + std::shared_ptr ast_importer; + auto *state = exe_ctx.GetTargetSP()->GetPersistentExpressionStateForLanguage( + lldb::eLanguageTypeC); + if (state) { + auto *persistent_vars = llvm::cast(state); + ast_importer = persistent_vars->GetClangASTImporter(); + } + m_expr_decl_map_up = std::make_unique( + keep_result_in_memory, nullptr, exe_ctx.GetTargetSP(), ast_importer, + nullptr); } diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h index 9efaa0254c3..1f2dd5fdbec 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ClangUtilityFunction_h_ -#define liblldb_ClangUtilityFunction_h_ +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUTILITYFUNCTION_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUTILITYFUNCTION_H #include #include @@ -15,7 +15,6 @@ #include "ClangExpressionHelper.h" -#include "lldb/Core/ClangForward.h" #include "lldb/Expression/UtilityFunction.h" #include "lldb/lldb-forward.h" #include "lldb/lldb-private.h" @@ -107,4 +106,4 @@ private: } // namespace lldb_private -#endif // liblldb_ClangUtilityFunction_h_ +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUTILITYFUNCTION_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp index 51ae73285b5..f1272c67d20 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp @@ -73,7 +73,7 @@ CppModuleConfiguration::CppModuleConfiguration( llvm::SmallString<256> resource_dir; llvm::sys::path::append(resource_dir, GetClangResourceDir().GetPath(), "include"); - m_resource_inc = resource_dir.str(); + m_resource_inc = std::string(resource_dir.str()); // This order matches the way Clang orders these directories. m_include_dirs = {m_std_inc.Get(), m_resource_inc, m_c_inc.Get()}; diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h index 8e892e37d0d..235ac2bd090 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CppModuleConfiguration_h_ -#define liblldb_CppModuleConfiguration_h_ +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CPPMODULECONFIGURATION_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CPPMODULECONFIGURATION_H #include #include @@ -56,7 +56,7 @@ class CppModuleConfiguration { bool analyzeFile(const FileSpec &f); public: - /// Creates a configuraiton by analyzing the given list of used source files. + /// Creates a configuration by analyzing the given list of used source files. /// /// Currently only looks at the used paths and doesn't actually access the /// files on the disk. diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp new file mode 100644 index 00000000000..2f8cf1846ee --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp @@ -0,0 +1,289 @@ +//===-- CxxModuleHandler.cpp ----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "Plugins/ExpressionParser/Clang/CxxModuleHandler.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" + +#include "lldb/Utility/Log.h" +#include "clang/Sema/Lookup.h" +#include "llvm/Support/Error.h" + +using namespace lldb_private; +using namespace clang; + +CxxModuleHandler::CxxModuleHandler(ASTImporter &importer, ASTContext *target) + : m_importer(&importer), + m_sema(TypeSystemClang::GetASTContext(target)->getSema()) { + + std::initializer_list supported_names = { + // containers + "deque", + "forward_list", + "list", + "queue", + "stack", + "vector", + // pointers + "shared_ptr", + "unique_ptr", + "weak_ptr", + // utility + "allocator", + }; + m_supported_templates.insert(supported_names.begin(), supported_names.end()); +} + +/// Builds a list of scopes that point into the given context. +/// +/// \param sema The sema that will be using the scopes. +/// \param ctxt The context that the scope should look into. +/// \param result A list of scopes. The scopes need to be freed by the caller +/// (except the TUScope which is owned by the sema). +static void makeScopes(Sema &sema, DeclContext *ctxt, + std::vector &result) { + // FIXME: The result should be a list of unique_ptrs, but the TUScope makes + // this currently impossible as it's owned by the Sema. + + if (auto parent = ctxt->getParent()) { + makeScopes(sema, parent, result); + + Scope *scope = + new Scope(result.back(), Scope::DeclScope, sema.getDiagnostics()); + scope->setEntity(ctxt); + result.push_back(scope); + } else + result.push_back(sema.TUScope); +} + +/// Uses the Sema to look up the given name in the given DeclContext. +static std::unique_ptr +emulateLookupInCtxt(Sema &sema, llvm::StringRef name, DeclContext *ctxt) { + IdentifierInfo &ident = sema.getASTContext().Idents.get(name); + + std::unique_ptr lookup_result; + lookup_result = std::make_unique(sema, DeclarationName(&ident), + SourceLocation(), + Sema::LookupOrdinaryName); + + // Usually during parsing we already encountered the scopes we would use. But + // here don't have these scopes so we have to emulate the behavior of the + // Sema during parsing. + std::vector scopes; + makeScopes(sema, ctxt, scopes); + + // Now actually perform the lookup with the sema. + sema.LookupName(*lookup_result, scopes.back()); + + // Delete all the allocated scopes beside the translation unit scope (which + // has depth 0). + for (Scope *s : scopes) + if (s->getDepth() != 0) + delete s; + + return lookup_result; +} + +/// Error class for handling problems when finding a certain DeclContext. +struct MissingDeclContext : public llvm::ErrorInfo { + + static char ID; + + MissingDeclContext(DeclContext *context, std::string error) + : m_context(context), m_error(error) {} + + DeclContext *m_context; + std::string m_error; + + void log(llvm::raw_ostream &OS) const override { + OS << llvm::formatv("error when reconstructing context of kind {0}:{1}", + m_context->getDeclKindName(), m_error); + } + + std::error_code convertToErrorCode() const override { + return llvm::inconvertibleErrorCode(); + } +}; + +char MissingDeclContext::ID = 0; + +/// Given a foreign decl context, this function finds the equivalent local +/// decl context in the ASTContext of the given Sema. Potentially deserializes +/// decls from the 'std' module if necessary. +static llvm::Expected +getEqualLocalDeclContext(Sema &sema, DeclContext *foreign_ctxt) { + + // Inline namespaces don't matter for lookups, so let's skip them. + while (foreign_ctxt && foreign_ctxt->isInlineNamespace()) + foreign_ctxt = foreign_ctxt->getParent(); + + // If the foreign context is the TU, we just return the local TU. + if (foreign_ctxt->isTranslationUnit()) + return sema.getASTContext().getTranslationUnitDecl(); + + // Recursively find/build the parent DeclContext. + llvm::Expected parent = + getEqualLocalDeclContext(sema, foreign_ctxt->getParent()); + if (!parent) + return parent; + + // We currently only support building namespaces. + if (foreign_ctxt->isNamespace()) { + NamedDecl *ns = llvm::dyn_cast(foreign_ctxt); + llvm::StringRef ns_name = ns->getName(); + + auto lookup_result = emulateLookupInCtxt(sema, ns_name, *parent); + for (NamedDecl *named_decl : *lookup_result) { + if (DeclContext *DC = llvm::dyn_cast(named_decl)) + return DC->getPrimaryContext(); + } + return llvm::make_error( + foreign_ctxt, + "Couldn't find namespace " + ns->getQualifiedNameAsString()); + } + + return llvm::make_error(foreign_ctxt, "Unknown context "); +} + +/// Returns true iff tryInstantiateStdTemplate supports instantiating a template +/// with the given template arguments. +static bool templateArgsAreSupported(ArrayRef a) { + for (const TemplateArgument &arg : a) { + switch (arg.getKind()) { + case TemplateArgument::Type: + case TemplateArgument::Integral: + break; + default: + // TemplateArgument kind hasn't been handled yet. + return false; + } + } + return true; +} + +/// Constructor function for Clang declarations. Ensures that the created +/// declaration is registered with the ASTImporter. +template +T *createDecl(ASTImporter &importer, Decl *from_d, Args &&... args) { + T *to_d = T::Create(std::forward(args)...); + importer.RegisterImportedDecl(from_d, to_d); + return to_d; +} + +llvm::Optional CxxModuleHandler::tryInstantiateStdTemplate(Decl *d) { + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + + // If we don't have a template to instiantiate, then there is nothing to do. + auto td = dyn_cast(d); + if (!td) + return {}; + + // We only care about templates in the std namespace. + if (!td->getDeclContext()->isStdNamespace()) + return {}; + + // We have a list of supported template names. + if (m_supported_templates.find(td->getName()) == m_supported_templates.end()) + return {}; + + // Early check if we even support instantiating this template. We do this + // before we import anything into the target AST. + auto &foreign_args = td->getTemplateInstantiationArgs(); + if (!templateArgsAreSupported(foreign_args.asArray())) + return {}; + + // Find the local DeclContext that corresponds to the DeclContext of our + // decl we want to import. + llvm::Expected to_context = + getEqualLocalDeclContext(*m_sema, td->getDeclContext()); + if (!to_context) { + LLDB_LOG_ERROR(log, to_context.takeError(), + "Got error while searching equal local DeclContext for decl " + "'{1}':\n{0}", + td->getName()); + return {}; + } + + // Look up the template in our local context. + std::unique_ptr lookup = + emulateLookupInCtxt(*m_sema, td->getName(), *to_context); + + ClassTemplateDecl *new_class_template = nullptr; + for (auto LD : *lookup) { + if ((new_class_template = dyn_cast(LD))) + break; + } + if (!new_class_template) + return {}; + + // Import the foreign template arguments. + llvm::SmallVector imported_args; + + // If this logic is changed, also update templateArgsAreSupported. + for (const TemplateArgument &arg : foreign_args.asArray()) { + switch (arg.getKind()) { + case TemplateArgument::Type: { + llvm::Expected type = m_importer->Import(arg.getAsType()); + if (!type) { + LLDB_LOG_ERROR(log, type.takeError(), "Couldn't import type: {0}"); + return {}; + } + imported_args.push_back(TemplateArgument(*type)); + break; + } + case TemplateArgument::Integral: { + llvm::APSInt integral = arg.getAsIntegral(); + llvm::Expected type = + m_importer->Import(arg.getIntegralType()); + if (!type) { + LLDB_LOG_ERROR(log, type.takeError(), "Couldn't import type: {0}"); + return {}; + } + imported_args.push_back( + TemplateArgument(d->getASTContext(), integral, *type)); + break; + } + default: + assert(false && "templateArgsAreSupported not updated?"); + } + } + + // Find the class template specialization declaration that + // corresponds to these arguments. + void *InsertPos = nullptr; + ClassTemplateSpecializationDecl *result = + new_class_template->findSpecialization(imported_args, InsertPos); + + if (result) { + // We found an existing specialization in the module that fits our arguments + // so we can treat it as the result and register it with the ASTImporter. + m_importer->RegisterImportedDecl(d, result); + return result; + } + + // Instantiate the template. + result = createDecl( + *m_importer, d, m_sema->getASTContext(), + new_class_template->getTemplatedDecl()->getTagKind(), + new_class_template->getDeclContext(), + new_class_template->getTemplatedDecl()->getLocation(), + new_class_template->getLocation(), new_class_template, imported_args, + nullptr); + + new_class_template->AddSpecialization(result, InsertPos); + if (new_class_template->isOutOfLine()) + result->setLexicalDeclContext( + new_class_template->getLexicalDeclContext()); + return result; +} + +llvm::Optional CxxModuleHandler::Import(Decl *d) { + if (!isValid()) + return {}; + + return tryInstantiateStdTemplate(d); +} diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.h new file mode 100644 index 00000000000..6490af7f897 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.h @@ -0,0 +1,65 @@ +//===-- CxxModuleHandler.h --------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CXXMODULEHANDLER_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CXXMODULEHANDLER_H + +#include "clang/AST/ASTImporter.h" +#include "clang/Sema/Sema.h" +#include "llvm/ADT/StringSet.h" + +namespace lldb_private { + +/// Handles importing decls into an ASTContext with an attached C++ module. +/// +/// This class searches a C++ module (which must be attached to the target +/// ASTContext) for an equivalent decl to the one that should be imported. +/// If the decl that is found in the module is a suitable replacement +/// for the decl that should be imported, the module decl will be treated as +/// the result of the import process. +/// +/// If the Decl that should be imported is a template specialization +/// that doesn't exist yet in the target ASTContext (e.g. `std::vector`), +/// then this class tries to create the template specialization in the target +/// ASTContext. This is only possible if the CxxModuleHandler can determine +/// that instantiating this template is safe to do, e.g. because the target +/// decl is a container class from the STL. +class CxxModuleHandler { + /// The ASTImporter that should be used to import any Decls which aren't + /// directly handled by this class itself. + clang::ASTImporter *m_importer = nullptr; + + /// The Sema instance of the target ASTContext. + clang::Sema *m_sema = nullptr; + + /// List of template names this class currently supports. These are the + /// template names inside the 'std' namespace such as 'vector' or 'list'. + llvm::StringSet<> m_supported_templates; + + /// Tries to manually instantiate the given foreign template in the target + /// context (designated by m_sema). + llvm::Optional tryInstantiateStdTemplate(clang::Decl *d); + +public: + CxxModuleHandler() = default; + CxxModuleHandler(clang::ASTImporter &importer, clang::ASTContext *target); + + /// Attempts to import the given decl into the target ASTContext by + /// deserializing it from the 'std' module. This function returns a Decl if a + /// Decl has been deserialized from the 'std' module. Otherwise this function + /// returns nothing. + llvm::Optional Import(clang::Decl *d); + + /// Returns true iff this instance is capable of importing any declarations + /// in the target ASTContext. + bool isValid() const { return m_sema != nullptr; } +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CXXMODULEHANDLER_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp index d5ffb9529f3..b92f00ec2b6 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp @@ -1,4 +1,4 @@ -//===-- IRDynamicChecks.cpp -------------------------------------*- C++ -*-===// +//===-- IRDynamicChecks.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -181,8 +181,8 @@ protected: /// /// \param[in] inst /// The instruction to be instrumented. - void RegisterInstruction(llvm::Instruction &i) { - m_to_instrument.push_back(&i); + void RegisterInstruction(llvm::Instruction &inst) { + m_to_instrument.push_back(&inst); } /// Determine whether a single instruction is interesting to instrument, @@ -465,7 +465,7 @@ protected: } static llvm::Function *GetCalledFunction(llvm::CallInst *inst) { - return GetFunction(inst->getCalledValue()); + return GetFunction(inst->getCalledOperand()); } bool InspectInstruction(llvm::Instruction &i) override { diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h index 5b9c8007ab7..a4de527e451 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_IRDynamicChecks_h_ -#define liblldb_IRDynamicChecks_h_ +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRDYNAMICCHECKS_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRDYNAMICCHECKS_H #include "lldb/Expression/DynamicCheckerFunctions.h" #include "lldb/lldb-types.h" @@ -124,4 +124,4 @@ private: } // namespace lldb_private -#endif // liblldb_IRDynamicChecks_h_ +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRDYNAMICCHECKS_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp index 103a7ee46f3..8511e554509 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp @@ -1,4 +1,4 @@ -//===-- IRForTarget.cpp -----------------------------------------*- C++ -*-===// +//===-- IRForTarget.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,7 +9,9 @@ #include "IRForTarget.h" #include "ClangExpressionDeclMap.h" +#include "ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/InstrTypes.h" @@ -27,8 +29,6 @@ #include "lldb/Core/dwarf.h" #include "lldb/Expression/IRExecutionUnit.h" #include "lldb/Expression/IRInterpreter.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataBufferHeap.h" @@ -283,17 +283,13 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { clang::QualType element_qual_type = pointer_pointertype->getPointeeType(); m_result_type = lldb_private::TypeFromParser( - element_qual_type.getAsOpaquePtr(), - lldb_private::ClangASTContext::GetASTContext( - &result_decl->getASTContext())); + m_decl_map->GetTypeSystem()->GetType(element_qual_type)); } else if (pointer_objcobjpointertype) { clang::QualType element_qual_type = clang::QualType(pointer_objcobjpointertype->getObjectType(), 0); m_result_type = lldb_private::TypeFromParser( - element_qual_type.getAsOpaquePtr(), - lldb_private::ClangASTContext::GetASTContext( - &result_decl->getASTContext())); + m_decl_map->GetTypeSystem()->GetType(element_qual_type)); } else { LLDB_LOG(log, "Expected result to have pointer type, but it did not"); @@ -305,9 +301,7 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { } } else { m_result_type = lldb_private::TypeFromParser( - result_var->getType().getAsOpaquePtr(), - lldb_private::ClangASTContext::GetASTContext( - &result_decl->getASTContext())); + m_decl_map->GetTypeSystem()->GetType(result_var->getType())); } lldb::TargetSP target_sp(m_execution_unit.GetTarget()); @@ -433,7 +427,7 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str, m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str, missing_weak); if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS || missing_weak) { - log->PutCString("Couldn't find CFStringCreateWithBytes in the target"); + LLDB_LOG(log, "Couldn't find CFStringCreateWithBytes in the target"); m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C " "constant string requires " @@ -823,7 +817,8 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) { if (!omvn_initializer_array->isString()) return false; - std::string omvn_initializer_string = omvn_initializer_array->getAsString(); + std::string omvn_initializer_string = + std::string(omvn_initializer_array->getAsString()); LLDB_LOG(log, "Found Objective-C selector reference \"{0}\"", omvn_initializer_string); @@ -981,7 +976,8 @@ bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) { if (!ocn_initializer_array->isString()) return false; - std::string ocn_initializer_string = ocn_initializer_array->getAsString(); + std::string ocn_initializer_string = + std::string(ocn_initializer_array->getAsString()); LLDB_LOG(log, "Found Objective-C class reference \"{0}\"", ocn_initializer_string); @@ -1092,8 +1088,7 @@ bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) { clang::VarDecl *decl = reinterpret_cast(ptr); lldb_private::TypeFromParser result_decl_type( - decl->getType().getAsOpaquePtr(), - lldb_private::ClangASTContext::GetASTContext(&decl->getASTContext())); + m_decl_map->GetTypeSystem()->GetType(decl->getType())); StringRef decl_name(decl->getName()); lldb_private::ConstString persistent_variable_name(decl_name.data(), @@ -1125,7 +1120,9 @@ bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) { // Now, since the variable is a pointer variable, we will drop in a load of // that pointer variable. - LoadInst *persistent_load = new LoadInst(persistent_global, "", alloc); + LoadInst *persistent_load = + new LoadInst(persistent_global->getType()->getPointerElementType(), + persistent_global, "", alloc); LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(alloc), PrintValue(persistent_load)); @@ -1223,10 +1220,8 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) { if (value_decl == nullptr) return false; - lldb_private::CompilerType compiler_type( - lldb_private::ClangASTContext::GetASTContext( - &value_decl->getASTContext()), - value_decl->getType().getAsOpaquePtr()); + lldb_private::CompilerType compiler_type = + m_decl_map->GetTypeSystem()->GetType(value_decl->getType()); const Type *value_type = nullptr; @@ -1400,7 +1395,7 @@ bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) { if (func && func->getName() == "__cxa_atexit") remove = true; - llvm::Value *val = call->getCalledValue(); + llvm::Value *val = call->getCalledOperand(); if (val && val->getName() == "__cxa_atexit") remove = true; @@ -1799,7 +1794,9 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) { get_element_ptr, value->getType()->getPointerTo(), "", entry_instruction); - LoadInst *load = new LoadInst(bit_cast, "", entry_instruction); + LoadInst *load = + new LoadInst(bit_cast->getType()->getPointerElementType(), + bit_cast, "", entry_instruction); return load; } else { @@ -1845,7 +1842,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) { lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); m_module = &llvm_module; - m_target_data.reset(new DataLayout(m_module)); + m_target_data = std::make_unique(m_module); m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(), m_target_data->getPointerSizeInBits()); diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h index 262e8ee0c06..ebfc0cae626 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h @@ -7,10 +7,9 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_IRForTarget_h_ -#define liblldb_IRForTarget_h_ +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRFORTARGET_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRFORTARGET_H -#include "lldb/Core/ClangForward.h" #include "lldb/Symbol/TaggedASTType.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" @@ -38,6 +37,10 @@ class DataLayout; class Value; } +namespace clang { +class NamedDecl; +} + namespace lldb_private { class ClangExpressionDeclMap; class IRExecutionUnit; @@ -506,4 +509,4 @@ private: bool CompleteDataAllocation(); }; -#endif // liblldb_IRForTarget_h_ +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRFORTARGET_H diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h index 7553860f249..b7b6640c481 100644 --- a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ModuleDependencyCollector_h_ -#define liblldb_ModuleDependencyCollector_h_ +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_MODULEDEPENDENCYCOLLECTOR_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_MODULEDEPENDENCYCOLLECTOR_H #include "clang/Frontend/Utils.h" #include "llvm/ADT/StringRef.h" diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp new file mode 100644 index 00000000000..c1f88889f1d --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp @@ -0,0 +1,179 @@ +//===-- NameSearchContext.cpp ---------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "NameSearchContext.h" +#include "ClangUtil.h" + +using namespace clang; +using namespace lldb_private; + +clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) { + assert(type && "Type for variable must be valid!"); + + if (!type.IsValid()) + return nullptr; + + TypeSystemClang *lldb_ast = + llvm::dyn_cast(type.GetTypeSystem()); + if (!lldb_ast) + return nullptr; + + IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo(); + + clang::ASTContext &ast = lldb_ast->getASTContext(); + + clang::NamedDecl *Decl = VarDecl::Create( + ast, const_cast(m_decl_context), SourceLocation(), + SourceLocation(), ii, ClangUtil::GetQualType(type), nullptr, SC_Static); + m_decls.push_back(Decl); + + return Decl; +} + +clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type, + bool extern_c) { + assert(type && "Type for variable must be valid!"); + + if (!type.IsValid()) + return nullptr; + + if (m_function_types.count(type)) + return nullptr; + + TypeSystemClang *lldb_ast = + llvm::dyn_cast(type.GetTypeSystem()); + if (!lldb_ast) + return nullptr; + + m_function_types.insert(type); + + QualType qual_type(ClangUtil::GetQualType(type)); + + clang::ASTContext &ast = lldb_ast->getASTContext(); + + const bool isInlineSpecified = false; + const bool hasWrittenPrototype = true; + const bool isConstexprSpecified = false; + + clang::DeclContext *context = const_cast(m_decl_context); + + if (extern_c) { + context = LinkageSpecDecl::Create( + ast, context, SourceLocation(), SourceLocation(), + clang::LinkageSpecDecl::LanguageIDs::lang_c, false); + } + + // Pass the identifier info for functions the decl_name is needed for + // operators + clang::DeclarationName decl_name = + m_decl_name.getNameKind() == DeclarationName::Identifier + ? m_decl_name.getAsIdentifierInfo() + : m_decl_name; + + clang::FunctionDecl *func_decl = FunctionDecl::Create( + ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type, + nullptr, SC_Extern, isInlineSpecified, hasWrittenPrototype, + isConstexprSpecified ? CSK_constexpr : CSK_unspecified); + + // We have to do more than just synthesize the FunctionDecl. We have to + // synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do + // this, we raid the function's FunctionProtoType for types. + + const FunctionProtoType *func_proto_type = + qual_type.getTypePtr()->getAs(); + + if (func_proto_type) { + unsigned NumArgs = func_proto_type->getNumParams(); + unsigned ArgIndex; + + SmallVector parm_var_decls; + + for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex) { + QualType arg_qual_type(func_proto_type->getParamType(ArgIndex)); + + parm_var_decls.push_back( + ParmVarDecl::Create(ast, const_cast(context), + SourceLocation(), SourceLocation(), nullptr, + arg_qual_type, nullptr, SC_Static, nullptr)); + } + + func_decl->setParams(ArrayRef(parm_var_decls)); + } else { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + LLDB_LOG(log, "Function type wasn't a FunctionProtoType"); + } + + // If this is an operator (e.g. operator new or operator==), only insert the + // declaration we inferred from the symbol if we can provide the correct + // number of arguments. We shouldn't really inject random decl(s) for + // functions that are analyzed semantically in a special way, otherwise we + // will crash in clang. + clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS; + if (func_proto_type && + TypeSystemClang::IsOperator(decl_name.getAsString().c_str(), op_kind)) { + if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount( + false, op_kind, func_proto_type->getNumParams())) + return nullptr; + } + m_decls.push_back(func_decl); + + return func_decl; +} + +clang::NamedDecl *NameSearchContext::AddGenericFunDecl() { + FunctionProtoType::ExtProtoInfo proto_info; + + proto_info.Variadic = true; + + QualType generic_function_type( + GetASTContext().getFunctionType(GetASTContext().UnknownAnyTy, // result + ArrayRef(), // argument types + proto_info)); + + return AddFunDecl(m_clang_ts.GetType(generic_function_type), true); +} + +clang::NamedDecl * +NameSearchContext::AddTypeDecl(const CompilerType &clang_type) { + if (ClangUtil::IsClangType(clang_type)) { + QualType qual_type = ClangUtil::GetQualType(clang_type); + + if (const TypedefType *typedef_type = + llvm::dyn_cast(qual_type)) { + TypedefNameDecl *typedef_name_decl = typedef_type->getDecl(); + + m_decls.push_back(typedef_name_decl); + + return (NamedDecl *)typedef_name_decl; + } else if (const TagType *tag_type = qual_type->getAs()) { + TagDecl *tag_decl = tag_type->getDecl(); + + m_decls.push_back(tag_decl); + + return tag_decl; + } else if (const ObjCObjectType *objc_object_type = + qual_type->getAs()) { + ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface(); + + m_decls.push_back((NamedDecl *)interface_decl); + + return (NamedDecl *)interface_decl; + } + } + return nullptr; +} + +void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result) { + for (clang::NamedDecl *decl : result) + m_decls.push_back(decl); +} + +void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) { + m_decls.push_back(decl); +} diff --git a/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.h b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.h new file mode 100644 index 00000000000..dc8621dd6ab --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.h @@ -0,0 +1,124 @@ +//===-- NameSearchContext.h -------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_NAME_SEARCH_CONTEXT_H +#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_NAME_SEARCH_CONTEXT_H + +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" +#include "lldb/Symbol/CompilerType.h" +#include "llvm/ADT/SmallSet.h" + +namespace lldb_private { + +/// \class NameSearchContext ClangASTSource.h +/// "lldb/Expression/ClangASTSource.h" Container for all objects relevant to a +/// single name lookup +/// +/// LLDB needs to create Decls for entities it finds. This class communicates +/// what name is being searched for and provides helper functions to construct +/// Decls given appropriate type information. +struct NameSearchContext { + /// The type system of the AST from which the lookup originated. + TypeSystemClang &m_clang_ts; + /// The list of declarations already constructed. + llvm::SmallVectorImpl &m_decls; + /// The mapping of all namespaces found for this request back to their + /// modules. + ClangASTImporter::NamespaceMapSP m_namespace_map; + /// The name being looked for. + const clang::DeclarationName m_decl_name; + /// The DeclContext to put declarations into. + const clang::DeclContext *m_decl_context; + /// All the types of functions that have been reported, so we don't + /// report conflicts. + llvm::SmallSet m_function_types; + + bool m_found_variable = false; + bool m_found_function_with_type_info = false; + bool m_found_function = false; + bool m_found_local_vars_nsp = false; + bool m_found_type = false; + + /// Constructor + /// + /// Initializes class variables. + /// + /// \param[in] clang_ts + /// The TypeSystemClang from which the request originates. + /// + /// \param[in] decls + /// A reference to a list into which new Decls will be placed. This + /// list is typically empty when the function is called. + /// + /// \param[in] name + /// The name being searched for (always an Identifier). + /// + /// \param[in] dc + /// The DeclContext to register Decls in. + NameSearchContext(TypeSystemClang &clang_ts, + llvm::SmallVectorImpl &decls, + clang::DeclarationName name, const clang::DeclContext *dc) + : m_clang_ts(clang_ts), m_decls(decls), + m_namespace_map(std::make_shared()), + m_decl_name(name), m_decl_context(dc) { + ; + } + + /// Create a VarDecl with the name being searched for and the provided type + /// and register it in the right places. + /// + /// \param[in] type + /// The opaque QualType for the VarDecl being registered. + clang::NamedDecl *AddVarDecl(const CompilerType &type); + + /// Create a FunDecl with the name being searched for and the provided type + /// and register it in the right places. + /// + /// \param[in] type + /// The opaque QualType for the FunDecl being registered. + /// + /// \param[in] extern_c + /// If true, build an extern "C" linkage specification for this. + clang::NamedDecl *AddFunDecl(const CompilerType &type, bool extern_c = false); + + /// Create a FunDecl with the name being searched for and generic type (i.e. + /// intptr_t NAME_GOES_HERE(...)) and register it in the right places. + clang::NamedDecl *AddGenericFunDecl(); + + /// Create a TypeDecl with the name being searched for and the provided type + /// and register it in the right places. + /// + /// \param[in] compiler_type + /// The opaque QualType for the TypeDecl being registered. + clang::NamedDecl *AddTypeDecl(const CompilerType &compiler_type); + + /// Add Decls from the provided DeclContextLookupResult to the list of + /// results. + /// + /// \param[in] result + /// The DeclContextLookupResult, usually returned as the result + /// of querying a DeclContext. + void AddLookupResult(clang::DeclContextLookupResult result); + + /// Add a NamedDecl to the list of results. + /// + /// \param[in] decl + /// The NamedDecl, usually returned as the result + /// of querying a DeclContext. + void AddNamedDecl(clang::NamedDecl *decl); + +private: + clang::ASTContext &GetASTContext() const { + return m_clang_ts.getASTContext(); + } +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_NAME_SEARCH_CONTEXT_H diff --git a/gnu/llvm/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/gnu/llvm/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index ff142e6f35f..555912780df 100644 --- a/gnu/llvm/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/gnu/llvm/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -1,4 +1,4 @@ -//===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===// +//===-- EmulateInstructionARM.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -30,6 +30,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionARM, InstructionARM) + // Convenient macro definitions. #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS) #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS) @@ -603,9 +605,6 @@ static uint32_t CountITSize(uint32_t ITMask) { // First count the trailing zeros of the IT mask. uint32_t TZ = llvm::countTrailingZeros(ITMask); if (TZ > 3) { -#ifdef LLDB_CONFIGURATION_DEBUG - printf("Encoding error: IT Mask '0000'\n"); -#endif return 0; } return (4 - TZ); @@ -620,15 +619,9 @@ bool ITSession::InitIT(uint32_t bits7_0) { // A8.6.50 IT unsigned short FirstCond = Bits32(bits7_0, 7, 4); if (FirstCond == 0xF) { -#ifdef LLDB_CONFIGURATION_DEBUG - printf("Encoding error: IT FirstCond '1111'\n"); -#endif return false; } if (FirstCond == 0xE && ITCounter != 1) { -#ifdef LLDB_CONFIGURATION_DEBUG - printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); -#endif return false; } @@ -7230,7 +7223,7 @@ bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode, return true; } -// LDRH (literal) caculates an address from the PC value and an immediate +// LDRH (literal) calculates an address from the PC value and an immediate // offset, loads a halfword from memory, // zero-extends it to form a 32-bit word, and writes it to a register. bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode, @@ -8516,7 +8509,7 @@ bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode, return true; } -// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and +// UXTB extracts an 8-bit value from a register, zero-extends it to 32 bits, and // writes the result to the destination // register. You can specify a rotation by 0, 8, 16, or 24 bits before // extracting the 8-bit value. @@ -14368,7 +14361,7 @@ bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) { if (!success) return false; - if (auto_advance_pc && (after_pc_value == orig_pc_value)) { + if (after_pc_value == orig_pc_value) { after_pc_value += m_opcode.GetByteSize(); EmulateInstruction::Context context; diff --git a/gnu/llvm/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/gnu/llvm/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h index 13d7fc061be..d15d80c97e3 100644 --- a/gnu/llvm/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h +++ b/gnu/llvm/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_EmulateInstructionARM_h_ -#define lldb_EmulateInstructionARM_h_ +#ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM_EMULATEINSTRUCTIONARM_H +#define LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM_EMULATEINSTRUCTIONARM_H #include "Plugins/Process/Utility/ARMDefines.h" #include "lldb/Core/EmulateInstruction.h" @@ -783,4 +783,4 @@ protected: } // namespace lldb_private -#endif // lldb_EmulateInstructionARM_h_ +#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM_EMULATEINSTRUCTIONARM_H diff --git a/gnu/llvm/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp b/gnu/llvm/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp index 11c7677c201..aef08baa8ae 100644 --- a/gnu/llvm/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp +++ b/gnu/llvm/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp @@ -1,4 +1,4 @@ -//===-- EmulationStateARM.cpp -----------------------------------*- C++ -*-===// +//===-- EmulationStateARM.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h b/gnu/llvm/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h index e5af37a2150..955c7c64205 100644 --- a/gnu/llvm/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h +++ b/gnu/llvm/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_EmulationStateARM_h_ -#define lldb_EmulationStateARM_h_ +#ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM_EMULATIONSTATEARM_H +#define LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM_EMULATIONSTATEARM_H #include @@ -73,7 +73,8 @@ private: // uint32_t to a data buffer heap // type. - DISALLOW_COPY_AND_ASSIGN(EmulationStateARM); + EmulationStateARM(const EmulationStateARM &) = delete; + const EmulationStateARM &operator=(const EmulationStateARM &) = delete; }; -#endif // lldb_EmulationStateARM_h_ +#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM_EMULATIONSTATEARM_H diff --git a/gnu/llvm/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp b/gnu/llvm/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp index 3e06fca2504..9b0c06bccca 100644 --- a/gnu/llvm/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp @@ -1,4 +1,4 @@ -//===-- EmulateInstructionARM64.cpp ------------------------------*- C++-*-===// +//===-- EmulateInstructionARM64.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,8 +8,6 @@ #include "EmulateInstructionARM64.h" -#include - #include "lldb/Core/Address.h" #include "lldb/Core/PluginManager.h" #include "lldb/Symbol/UnwindPlan.h" @@ -18,10 +16,14 @@ #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Stream.h" +#include "llvm/Support/CheckedArithmetic.h" + #include "Plugins/Process/Utility/ARMDefines.h" #include "Plugins/Process/Utility/ARMUtils.h" #include "Plugins/Process/Utility/lldb-arm64-register-enums.h" +#include + #define GPR_OFFSET(idx) ((idx)*8) #define GPR_OFFSET_NAME(reg) 0 #define FPU_OFFSET(idx) ((idx)*16) @@ -47,6 +49,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionARM64, InstructionARM64) + static bool LLDBTableGetRegisterInfo(uint32_t reg_num, RegisterInfo ®_info) { if (reg_num >= llvm::array_lengthof(g_register_infos_arm64_le)) return false; @@ -83,23 +87,6 @@ static inline uint64_t LSL(uint64_t x, integer shift) { return x << shift; } -// AddWithCarry() -// =============== -static inline uint64_t -AddWithCarry(uint32_t N, uint64_t x, uint64_t y, bit carry_in, - EmulateInstructionARM64::ProcState &proc_state) { - uint64_t unsigned_sum = UInt(x) + UInt(y) + UInt(carry_in); - int64_t signed_sum = SInt(x) + SInt(y) + UInt(carry_in); - uint64_t result = unsigned_sum; - if (N < 64) - result = Bits64(result, N - 1, 0); - proc_state.N = Bit64(result, N - 1); - proc_state.Z = IsZero(result); - proc_state.C = UInt(result) == unsigned_sum; - proc_state.V = SInt(result) == signed_sum; - return result; -} - // ConstrainUnpredictable() // ======================== @@ -415,20 +402,12 @@ bool EmulateInstructionARM64::EvaluateInstruction(uint32_t evaluate_options) { if (opcode_data == nullptr) return false; - // printf ("opcode template for 0x%8.8x: %s\n", opcode, opcode_data->name); const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; bool success = false; - // if (m_opcode_cpsr == 0 || m_ignore_conditions == false) - // { - // m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindLLDB, - // gpr_cpsr_arm64, - // 0, - // &success); - // } // Only return false if we are unable to read the CPSR if we care about // conditions @@ -454,7 +433,7 @@ bool EmulateInstructionARM64::EvaluateInstruction(uint32_t evaluate_options) { if (!success) return false; - if (auto_advance_pc && (new_pc_value == orig_pc_value)) { + if (new_pc_value == orig_pc_value) { EmulateInstruction::Context context; context.type = eContextAdvancePC; context.SetNoArgs(); @@ -588,6 +567,24 @@ bool EmulateInstructionARM64::ConditionHolds(const uint32_t cond) { return result; } +uint64_t EmulateInstructionARM64:: +AddWithCarry(uint32_t N, uint64_t x, uint64_t y, bit carry_in, + EmulateInstructionARM64::ProcState &proc_state) { + uint64_t unsigned_sum = UInt(x) + UInt(y) + UInt(carry_in); + llvm::Optional signed_sum = llvm::checkedAdd(SInt(x), SInt(y)); + bool overflow = !signed_sum; + if (!overflow) + overflow |= !llvm::checkedAdd(*signed_sum, SInt(carry_in)); + uint64_t result = unsigned_sum; + if (N < 64) + result = Bits64(result, N - 1, 0); + proc_state.N = Bit64(result, N - 1); + proc_state.Z = IsZero(result); + proc_state.C = UInt(result) != unsigned_sum; + proc_state.V = overflow; + return result; +} + bool EmulateInstructionARM64::EmulateADDSUBImm(const uint32_t opcode) { // integer d = UInt(Rd); // integer n = UInt(Rn); @@ -783,10 +780,6 @@ bool EmulateInstructionARM64::EmulateLDPSTP(const uint32_t opcode) { RegisterValue data_Rt; RegisterValue data_Rt2; - - // if (vector) - // CheckFPEnabled(false); - RegisterInfo reg_info_base; RegisterInfo reg_info_Rt; RegisterInfo reg_info_Rt2; diff --git a/gnu/llvm/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h b/gnu/llvm/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h index 03a57a2cf92..11ad8a99b0f 100644 --- a/gnu/llvm/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h +++ b/gnu/llvm/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef EmulateInstructionARM64_h_ -#define EmulateInstructionARM64_h_ +#ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM64_EMULATEINSTRUCTIONARM64_H +#define LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM64_EMULATEINSTRUCTIONARM64_H #include "Plugins/Process/Utility/ARMDefines.h" #include "lldb/Core/EmulateInstruction.h" @@ -152,6 +152,9 @@ public: } ProcState; protected: + static uint64_t AddWithCarry(uint32_t N, uint64_t x, uint64_t y, bool carry_in, + EmulateInstructionARM64::ProcState &proc_state); + typedef struct { uint32_t mask; uint32_t value; @@ -189,4 +192,4 @@ protected: bool m_ignore_conditions; }; -#endif // EmulateInstructionARM64_h_ +#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM64_EMULATEINSTRUCTIONARM64_H diff --git a/gnu/llvm/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/gnu/llvm/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp index b55eeb0eaf4..d4cb726fc7e 100644 --- a/gnu/llvm/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp +++ b/gnu/llvm/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp @@ -1,4 +1,4 @@ -//===-- EmulateInstructionMIPS.cpp -------------------------------*- C++-*-===// +//===-- EmulateInstructionMIPS.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -40,6 +40,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionMIPS, InstructionMIPS) + #define UInt(x) ((uint64_t)x) #define integer int64_t @@ -157,8 +159,8 @@ EmulateInstructionMIPS::EmulateInstructionMIPS( target->createMCSubtargetInfo(triple.getTriple(), cpu, features)); assert(m_asm_info.get() && m_subtype_info.get()); - m_context.reset( - new llvm::MCContext(m_asm_info.get(), m_reg_info.get(), nullptr)); + m_context = std::make_unique(m_asm_info.get(), + m_reg_info.get(), nullptr); assert(m_context.get()); m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context)); diff --git a/gnu/llvm/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h b/gnu/llvm/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h index cd447ae4975..61291c72987 100644 --- a/gnu/llvm/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h +++ b/gnu/llvm/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef EmulateInstructionMIPS_h_ -#define EmulateInstructionMIPS_h_ +#ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_MIPS_EMULATEINSTRUCTIONMIPS_H +#define LLDB_SOURCE_PLUGINS_INSTRUCTION_MIPS_EMULATEINSTRUCTIONMIPS_H namespace llvm { class MCDisassembler; @@ -203,7 +203,7 @@ protected: bool nonvolatile_reg_p(uint32_t regnum); - const char *GetRegisterName(unsigned reg_num, bool altnernate_name); + const char *GetRegisterName(unsigned reg_num, bool alternate_name); private: std::unique_ptr m_disasm; @@ -218,4 +218,4 @@ private: bool m_use_alt_disaasm; }; -#endif // EmulateInstructionMIPS_h_ +#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_MIPS_EMULATEINSTRUCTIONMIPS_H diff --git a/gnu/llvm/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/gnu/llvm/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp index 3baf942bc17..4ccaf0de075 100644 --- a/gnu/llvm/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp @@ -1,4 +1,4 @@ -//===-- EmulateInstructionMIPS64.cpp -----------------------------*- C++-*-===// +//===-- EmulateInstructionMIPS64.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -40,6 +40,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionMIPS64, InstructionMIPS64) + #define UInt(x) ((uint64_t)x) #define integer int64_t @@ -161,8 +163,8 @@ EmulateInstructionMIPS64::EmulateInstructionMIPS64( target->createMCSubtargetInfo(triple.getTriple(), cpu, features)); assert(m_asm_info.get() && m_subtype_info.get()); - m_context.reset( - new llvm::MCContext(m_asm_info.get(), m_reg_info.get(), nullptr)); + m_context = std::make_unique(m_asm_info.get(), + m_reg_info.get(), nullptr); assert(m_context.get()); m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context)); diff --git a/gnu/llvm/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h b/gnu/llvm/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h index 953a0935bd0..c4ae2296c5d 100644 --- a/gnu/llvm/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h +++ b/gnu/llvm/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef EmulateInstructionMIPS64_h_ -#define EmulateInstructionMIPS64_h_ +#ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_MIPS64_EMULATEINSTRUCTIONMIPS64_H +#define LLDB_SOURCE_PLUGINS_INSTRUCTION_MIPS64_EMULATEINSTRUCTIONMIPS64_H #include "lldb/Core/EmulateInstruction.h" #include "lldb/Interpreter/OptionValue.h" @@ -168,7 +168,7 @@ protected: bool nonvolatile_reg_p(uint64_t regnum); - const char *GetRegisterName(unsigned reg_num, bool altnernate_name); + const char *GetRegisterName(unsigned reg_num, bool alternate_name); private: std::unique_ptr m_disasm; @@ -179,4 +179,4 @@ private: std::unique_ptr m_insn_info; }; -#endif // EmulateInstructionMIPS64_h_ +#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_MIPS64_EMULATEINSTRUCTIONMIPS64_H diff --git a/gnu/llvm/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp b/gnu/llvm/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp index 4b8d8dd2228..5d97513c0be 100644 --- a/gnu/llvm/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp @@ -1,4 +1,4 @@ -//===-- EmulateInstructionPPC64.cpp ------------------------------*- C++-*-===// +//===-- EmulateInstructionPPC64.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,6 +25,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionPPC64, InstructionPPC64) + EmulateInstructionPPC64::EmulateInstructionPPC64(const ArchSpec &arch) : EmulateInstruction(arch) {} @@ -196,7 +198,7 @@ bool EmulateInstructionPPC64::EvaluateInstruction(uint32_t evaluate_options) { if (!success) return false; - if (auto_advance_pc && (new_pc_value == orig_pc_value)) { + if (new_pc_value == orig_pc_value) { EmulateInstruction::Context context; context.type = eContextAdvancePC; context.SetNoArgs(); diff --git a/gnu/llvm/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h b/gnu/llvm/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h index bf239770b93..02d2bce8f05 100644 --- a/gnu/llvm/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h +++ b/gnu/llvm/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef EmulateInstructionPPC64_h_ -#define EmulateInstructionPPC64_h_ +#ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_PPC64_EMULATEINSTRUCTIONPPC64_H +#define LLDB_SOURCE_PLUGINS_INSTRUCTION_PPC64_EMULATEINSTRUCTIONPPC64_H #include "lldb/Core/EmulateInstruction.h" #include "lldb/Interpreter/OptionValue.h" @@ -89,4 +89,4 @@ private: } // namespace lldb_private -#endif // EmulateInstructionPPC64_h_ +#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_PPC64_EMULATEINSTRUCTIONPPC64_H diff --git a/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/ASan/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/ASan/CMakeLists.txt index dc7464fd193..0b290270184 100644 --- a/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/ASan/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/ASan/CMakeLists.txt @@ -1,5 +1,5 @@ add_lldb_library(lldbPluginInstrumentationRuntimeASan PLUGIN - ASanRuntime.cpp + InstrumentationRuntimeASan.cpp LINK_LIBS lldbBreakpoint diff --git a/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp new file mode 100644 index 00000000000..e78ea3a6848 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp @@ -0,0 +1,327 @@ +//===-- InstrumentationRuntimeASan.cpp ------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "InstrumentationRuntimeASan.h" + +#include "lldb/Breakpoint/StoppointCallbackContext.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginInterface.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/Expression/UserExpression.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Target/InstrumentationRuntimeStopInfo.h" +#include "lldb/Target/StopInfo.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Stream.h" + +#include "llvm/ADT/StringSwitch.h" + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(InstrumentationRuntimeASan) + +lldb::InstrumentationRuntimeSP +InstrumentationRuntimeASan::CreateInstance(const lldb::ProcessSP &process_sp) { + return InstrumentationRuntimeSP(new InstrumentationRuntimeASan(process_sp)); +} + +void InstrumentationRuntimeASan::Initialize() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), "AddressSanitizer instrumentation runtime plugin.", + CreateInstance, GetTypeStatic); +} + +void InstrumentationRuntimeASan::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString InstrumentationRuntimeASan::GetPluginNameStatic() { + return ConstString("AddressSanitizer"); +} + +lldb::InstrumentationRuntimeType InstrumentationRuntimeASan::GetTypeStatic() { + return eInstrumentationRuntimeTypeAddressSanitizer; +} + +InstrumentationRuntimeASan::~InstrumentationRuntimeASan() { Deactivate(); } + +const RegularExpression & +InstrumentationRuntimeASan::GetPatternForRuntimeLibrary() { + // FIXME: This shouldn't include the "dylib" suffix. + static RegularExpression regex( + llvm::StringRef("libclang_rt.asan_(.*)_dynamic\\.dylib")); + return regex; +} + +bool InstrumentationRuntimeASan::CheckIfRuntimeIsValid( + const lldb::ModuleSP module_sp) { + const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType( + ConstString("__asan_get_alloc_stack"), lldb::eSymbolTypeAny); + + return symbol != nullptr; +} + +const char *address_sanitizer_retrieve_report_data_prefix = R"( +extern "C" +{ +int __asan_report_present(); +void *__asan_get_report_pc(); +void *__asan_get_report_bp(); +void *__asan_get_report_sp(); +void *__asan_get_report_address(); +const char *__asan_get_report_description(); +int __asan_get_report_access_type(); +size_t __asan_get_report_access_size(); +} +)"; + +const char *address_sanitizer_retrieve_report_data_command = R"( +struct { + int present; + int access_type; + void *pc; + void *bp; + void *sp; + void *address; + size_t access_size; + const char *description; +} t; + +t.present = __asan_report_present(); +t.access_type = __asan_get_report_access_type(); +t.pc = __asan_get_report_pc(); +t.bp = __asan_get_report_bp(); +t.sp = __asan_get_report_sp(); +t.address = __asan_get_report_address(); +t.access_size = __asan_get_report_access_size(); +t.description = __asan_get_report_description(); +t +)"; + +StructuredData::ObjectSP InstrumentationRuntimeASan::RetrieveReportData() { + ProcessSP process_sp = GetProcessSP(); + if (!process_sp) + return StructuredData::ObjectSP(); + + ThreadSP thread_sp = + process_sp->GetThreadList().GetExpressionExecutionThread(); + StackFrameSP frame_sp = thread_sp->GetSelectedFrame(); + + if (!frame_sp) + return StructuredData::ObjectSP(); + + EvaluateExpressionOptions options; + options.SetUnwindOnError(true); + options.SetTryAllThreads(true); + options.SetStopOthers(true); + options.SetIgnoreBreakpoints(true); + options.SetTimeout(process_sp->GetUtilityExpressionTimeout()); + options.SetPrefix(address_sanitizer_retrieve_report_data_prefix); + options.SetAutoApplyFixIts(false); + options.SetLanguage(eLanguageTypeObjC_plus_plus); + + ValueObjectSP return_value_sp; + ExecutionContext exe_ctx; + Status eval_error; + frame_sp->CalculateExecutionContext(exe_ctx); + ExpressionResults result = UserExpression::Evaluate( + exe_ctx, options, address_sanitizer_retrieve_report_data_command, "", + return_value_sp, eval_error); + if (result != eExpressionCompleted) { + process_sp->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf( + "Warning: Cannot evaluate AddressSanitizer expression:\n%s\n", + eval_error.AsCString()); + return StructuredData::ObjectSP(); + } + + int present = return_value_sp->GetValueForExpressionPath(".present") + ->GetValueAsUnsigned(0); + if (present != 1) + return StructuredData::ObjectSP(); + + addr_t pc = + return_value_sp->GetValueForExpressionPath(".pc")->GetValueAsUnsigned(0); + /* commented out because rdar://problem/18533301 + addr_t bp = + return_value_sp->GetValueForExpressionPath(".bp")->GetValueAsUnsigned(0); + addr_t sp = + return_value_sp->GetValueForExpressionPath(".sp")->GetValueAsUnsigned(0); + */ + addr_t address = return_value_sp->GetValueForExpressionPath(".address") + ->GetValueAsUnsigned(0); + addr_t access_type = + return_value_sp->GetValueForExpressionPath(".access_type") + ->GetValueAsUnsigned(0); + addr_t access_size = + return_value_sp->GetValueForExpressionPath(".access_size") + ->GetValueAsUnsigned(0); + addr_t description_ptr = + return_value_sp->GetValueForExpressionPath(".description") + ->GetValueAsUnsigned(0); + std::string description; + Status error; + process_sp->ReadCStringFromMemory(description_ptr, description, error); + + StructuredData::Dictionary *dict = new StructuredData::Dictionary(); + dict->AddStringItem("instrumentation_class", "AddressSanitizer"); + dict->AddStringItem("stop_type", "fatal_error"); + dict->AddIntegerItem("pc", pc); + /* commented out because rdar://problem/18533301 + dict->AddIntegerItem("bp", bp); + dict->AddIntegerItem("sp", sp); + */ + dict->AddIntegerItem("address", address); + dict->AddIntegerItem("access_type", access_type); + dict->AddIntegerItem("access_size", access_size); + dict->AddStringItem("description", description); + + return StructuredData::ObjectSP(dict); +} + +std::string +InstrumentationRuntimeASan::FormatDescription(StructuredData::ObjectSP report) { + std::string description = std::string(report->GetAsDictionary() + ->GetValueForKey("description") + ->GetAsString() + ->GetValue()); + return llvm::StringSwitch(description) + .Case("heap-use-after-free", "Use of deallocated memory") + .Case("heap-buffer-overflow", "Heap buffer overflow") + .Case("stack-buffer-underflow", "Stack buffer underflow") + .Case("initialization-order-fiasco", "Initialization order problem") + .Case("stack-buffer-overflow", "Stack buffer overflow") + .Case("stack-use-after-return", "Use of stack memory after return") + .Case("use-after-poison", "Use of poisoned memory") + .Case("container-overflow", "Container overflow") + .Case("stack-use-after-scope", "Use of out-of-scope stack memory") + .Case("global-buffer-overflow", "Global buffer overflow") + .Case("unknown-crash", "Invalid memory access") + .Case("stack-overflow", "Stack space exhausted") + .Case("null-deref", "Dereference of null pointer") + .Case("wild-jump", "Jump to non-executable address") + .Case("wild-addr-write", "Write through wild pointer") + .Case("wild-addr-read", "Read from wild pointer") + .Case("wild-addr", "Access through wild pointer") + .Case("signal", "Deadly signal") + .Case("double-free", "Deallocation of freed memory") + .Case("new-delete-type-mismatch", + "Deallocation size different from allocation size") + .Case("bad-free", "Deallocation of non-allocated memory") + .Case("alloc-dealloc-mismatch", + "Mismatch between allocation and deallocation APIs") + .Case("bad-malloc_usable_size", "Invalid argument to malloc_usable_size") + .Case("bad-__sanitizer_get_allocated_size", + "Invalid argument to __sanitizer_get_allocated_size") + .Case("param-overlap", + "Call to function disallowing overlapping memory ranges") + .Case("negative-size-param", "Negative size used when accessing memory") + .Case("bad-__sanitizer_annotate_contiguous_container", + "Invalid argument to __sanitizer_annotate_contiguous_container") + .Case("odr-violation", "Symbol defined in multiple translation units") + .Case( + "invalid-pointer-pair", + "Comparison or arithmetic on pointers from different memory regions") + // for unknown report codes just show the code + .Default("AddressSanitizer detected: " + description); +} + +bool InstrumentationRuntimeASan::NotifyBreakpointHit( + void *baton, StoppointCallbackContext *context, user_id_t break_id, + user_id_t break_loc_id) { + assert(baton && "null baton"); + if (!baton) + return false; + + InstrumentationRuntimeASan *const instance = + static_cast(baton); + + ProcessSP process_sp = instance->GetProcessSP(); + + if (process_sp->GetModIDRef().IsLastResumeForUserExpression()) + return false; + + StructuredData::ObjectSP report = instance->RetrieveReportData(); + std::string description; + if (report) { + description = instance->FormatDescription(report); + } + // Make sure this is the right process + if (process_sp && process_sp == context->exe_ctx_ref.GetProcessSP()) { + ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP(); + if (thread_sp) + thread_sp->SetStopInfo(InstrumentationRuntimeStopInfo:: + CreateStopReasonWithInstrumentationData( + *thread_sp, description, report)); + + StreamFileSP stream_sp( + process_sp->GetTarget().GetDebugger().GetOutputStreamSP()); + if (stream_sp) { + stream_sp->Printf("AddressSanitizer report breakpoint hit. Use 'thread " + "info -s' to get extended information about the " + "report.\n"); + } + return true; // Return true to stop the target + } else + return false; // Let target run +} + +void InstrumentationRuntimeASan::Activate() { + if (IsActive()) + return; + + ProcessSP process_sp = GetProcessSP(); + if (!process_sp) + return; + + ConstString symbol_name("__asan::AsanDie()"); + const Symbol *symbol = GetRuntimeModuleSP()->FindFirstSymbolWithNameAndType( + symbol_name, eSymbolTypeCode); + + if (symbol == nullptr) + return; + + if (!symbol->ValueIsAddress() || !symbol->GetAddressRef().IsValid()) + return; + + Target &target = process_sp->GetTarget(); + addr_t symbol_address = symbol->GetAddressRef().GetOpcodeLoadAddress(&target); + + if (symbol_address == LLDB_INVALID_ADDRESS) + return; + + bool internal = true; + bool hardware = false; + Breakpoint *breakpoint = + process_sp->GetTarget() + .CreateBreakpoint(symbol_address, internal, hardware) + .get(); + breakpoint->SetCallback(InstrumentationRuntimeASan::NotifyBreakpointHit, this, + true); + breakpoint->SetBreakpointKind("address-sanitizer-report"); + SetBreakpointID(breakpoint->GetID()); + + SetActive(true); +} + +void InstrumentationRuntimeASan::Deactivate() { + if (GetBreakpointID() != LLDB_INVALID_BREAK_ID) { + ProcessSP process_sp = GetProcessSP(); + if (process_sp) { + process_sp->GetTarget().RemoveBreakpointByID(GetBreakpointID()); + SetBreakpointID(LLDB_INVALID_BREAK_ID); + } + } + SetActive(false); +} diff --git a/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h new file mode 100644 index 00000000000..cde0a961335 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h @@ -0,0 +1,66 @@ +//===-- InstrumentationRuntimeASan.h ----------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_ASAN_INSTRUMENTATIONRUNTIMEASAN_H +#define LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_ASAN_INSTRUMENTATIONRUNTIMEASAN_H + +#include "lldb/Target/InstrumentationRuntime.h" +#include "lldb/Target/Process.h" +#include "lldb/Utility/StructuredData.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class InstrumentationRuntimeASan : public lldb_private::InstrumentationRuntime { +public: + ~InstrumentationRuntimeASan() override; + + static lldb::InstrumentationRuntimeSP + CreateInstance(const lldb::ProcessSP &process_sp); + + static void Initialize(); + + static void Terminate(); + + static lldb_private::ConstString GetPluginNameStatic(); + + static lldb::InstrumentationRuntimeType GetTypeStatic(); + + lldb_private::ConstString GetPluginName() override { + return GetPluginNameStatic(); + } + + virtual lldb::InstrumentationRuntimeType GetType() { return GetTypeStatic(); } + + uint32_t GetPluginVersion() override { return 1; } + +private: + InstrumentationRuntimeASan(const lldb::ProcessSP &process_sp) + : lldb_private::InstrumentationRuntime(process_sp) {} + + const RegularExpression &GetPatternForRuntimeLibrary() override; + + bool CheckIfRuntimeIsValid(const lldb::ModuleSP module_sp) override; + + void Activate() override; + + void Deactivate(); + + static bool NotifyBreakpointHit(void *baton, + StoppointCallbackContext *context, + lldb::user_id_t break_id, + lldb::user_id_t break_loc_id); + + StructuredData::ObjectSP RetrieveReportData(); + + std::string FormatDescription(StructuredData::ObjectSP report); +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_ASAN_INSTRUMENTATIONRUNTIMEASAN_H diff --git a/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/CMakeLists.txt index 440b176b270..8095658452d 100644 --- a/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/CMakeLists.txt @@ -1,5 +1,5 @@ add_lldb_library(lldbPluginInstrumentationRuntimeMainThreadChecker PLUGIN - MainThreadCheckerRuntime.cpp + InstrumentationRuntimeMainThreadChecker.cpp LINK_LIBS lldbBreakpoint diff --git a/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp new file mode 100644 index 00000000000..72d28c34745 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp @@ -0,0 +1,283 @@ +//===-- InstrumentationRuntimeMainThreadChecker.cpp -----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "InstrumentationRuntimeMainThreadChecker.h" + +#include "Plugins/Process/Utility/HistoryThread.h" +#include "lldb/Breakpoint/StoppointCallbackContext.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/Variable.h" +#include "lldb/Symbol/VariableList.h" +#include "lldb/Target/InstrumentationRuntimeStopInfo.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/RegularExpression.h" + +#include + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(InstrumentationRuntimeMainThreadChecker) + +InstrumentationRuntimeMainThreadChecker:: + ~InstrumentationRuntimeMainThreadChecker() { + Deactivate(); +} + +lldb::InstrumentationRuntimeSP +InstrumentationRuntimeMainThreadChecker::CreateInstance( + const lldb::ProcessSP &process_sp) { + return InstrumentationRuntimeSP( + new InstrumentationRuntimeMainThreadChecker(process_sp)); +} + +void InstrumentationRuntimeMainThreadChecker::Initialize() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), + "MainThreadChecker instrumentation runtime plugin.", CreateInstance, + GetTypeStatic); +} + +void InstrumentationRuntimeMainThreadChecker::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString +InstrumentationRuntimeMainThreadChecker::GetPluginNameStatic() { + return ConstString("MainThreadChecker"); +} + +lldb::InstrumentationRuntimeType +InstrumentationRuntimeMainThreadChecker::GetTypeStatic() { + return eInstrumentationRuntimeTypeMainThreadChecker; +} + +const RegularExpression & +InstrumentationRuntimeMainThreadChecker::GetPatternForRuntimeLibrary() { + static RegularExpression regex(llvm::StringRef("libMainThreadChecker.dylib")); + return regex; +} + +bool InstrumentationRuntimeMainThreadChecker::CheckIfRuntimeIsValid( + const lldb::ModuleSP module_sp) { + static ConstString test_sym("__main_thread_checker_on_report"); + const Symbol *symbol = + module_sp->FindFirstSymbolWithNameAndType(test_sym, lldb::eSymbolTypeAny); + return symbol != nullptr; +} + +StructuredData::ObjectSP +InstrumentationRuntimeMainThreadChecker::RetrieveReportData( + ExecutionContextRef exe_ctx_ref) { + ProcessSP process_sp = GetProcessSP(); + if (!process_sp) + return StructuredData::ObjectSP(); + + ThreadSP thread_sp = exe_ctx_ref.GetThreadSP(); + StackFrameSP frame_sp = thread_sp->GetSelectedFrame(); + ModuleSP runtime_module_sp = GetRuntimeModuleSP(); + Target &target = process_sp->GetTarget(); + + if (!frame_sp) + return StructuredData::ObjectSP(); + + RegisterContextSP regctx_sp = frame_sp->GetRegisterContext(); + if (!regctx_sp) + return StructuredData::ObjectSP(); + + const RegisterInfo *reginfo = regctx_sp->GetRegisterInfoByName("arg1"); + if (!reginfo) + return StructuredData::ObjectSP(); + + uint64_t apiname_ptr = regctx_sp->ReadRegisterAsUnsigned(reginfo, 0); + if (!apiname_ptr) + return StructuredData::ObjectSP(); + + std::string apiName = ""; + Status read_error; + target.ReadCStringFromMemory(apiname_ptr, apiName, read_error); + if (read_error.Fail()) + return StructuredData::ObjectSP(); + + std::string className = ""; + std::string selector = ""; + if (apiName.substr(0, 2) == "-[") { + size_t spacePos = apiName.find(" "); + if (spacePos != std::string::npos) { + className = apiName.substr(2, spacePos - 2); + selector = apiName.substr(spacePos + 1, apiName.length() - spacePos - 2); + } + } + + // Gather the PCs of the user frames in the backtrace. + StructuredData::Array *trace = new StructuredData::Array(); + auto trace_sp = StructuredData::ObjectSP(trace); + StackFrameSP responsible_frame; + for (unsigned I = 0; I < thread_sp->GetStackFrameCount(); ++I) { + StackFrameSP frame = thread_sp->GetStackFrameAtIndex(I); + Address addr = frame->GetFrameCodeAddress(); + if (addr.GetModule() == runtime_module_sp) // Skip PCs from the runtime. + continue; + + // The first non-runtime frame is responsible for the bug. + if (!responsible_frame) + responsible_frame = frame; + + // First frame in stacktrace should point to a real PC, not return address. + if (I != 0 && trace->GetSize() == 0) { + addr.Slide(-1); + } + + lldb::addr_t PC = addr.GetLoadAddress(&target); + trace->AddItem(StructuredData::ObjectSP(new StructuredData::Integer(PC))); + } + + auto *d = new StructuredData::Dictionary(); + auto dict_sp = StructuredData::ObjectSP(d); + d->AddStringItem("instrumentation_class", "MainThreadChecker"); + d->AddStringItem("api_name", apiName); + d->AddStringItem("class_name", className); + d->AddStringItem("selector", selector); + d->AddStringItem("description", + apiName + " must be used from main thread only"); + d->AddIntegerItem("tid", thread_sp->GetIndexID()); + d->AddItem("trace", trace_sp); + return dict_sp; +} + +bool InstrumentationRuntimeMainThreadChecker::NotifyBreakpointHit( + void *baton, StoppointCallbackContext *context, user_id_t break_id, + user_id_t break_loc_id) { + assert(baton && "null baton"); + if (!baton) + return false; ///< false => resume execution. + + InstrumentationRuntimeMainThreadChecker *const instance = + static_cast(baton); + + ProcessSP process_sp = instance->GetProcessSP(); + ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP(); + if (!process_sp || !thread_sp || + process_sp != context->exe_ctx_ref.GetProcessSP()) + return false; + + if (process_sp->GetModIDRef().IsLastResumeForUserExpression()) + return false; + + StructuredData::ObjectSP report = + instance->RetrieveReportData(context->exe_ctx_ref); + + if (report) { + std::string description = std::string(report->GetAsDictionary() + ->GetValueForKey("description") + ->GetAsString() + ->GetValue()); + thread_sp->SetStopInfo( + InstrumentationRuntimeStopInfo::CreateStopReasonWithInstrumentationData( + *thread_sp, description, report)); + return true; + } + + return false; +} + +void InstrumentationRuntimeMainThreadChecker::Activate() { + if (IsActive()) + return; + + ProcessSP process_sp = GetProcessSP(); + if (!process_sp) + return; + + ModuleSP runtime_module_sp = GetRuntimeModuleSP(); + + ConstString symbol_name("__main_thread_checker_on_report"); + const Symbol *symbol = runtime_module_sp->FindFirstSymbolWithNameAndType( + symbol_name, eSymbolTypeCode); + + if (symbol == nullptr) + return; + + if (!symbol->ValueIsAddress() || !symbol->GetAddressRef().IsValid()) + return; + + Target &target = process_sp->GetTarget(); + addr_t symbol_address = symbol->GetAddressRef().GetOpcodeLoadAddress(&target); + + if (symbol_address == LLDB_INVALID_ADDRESS) + return; + + Breakpoint *breakpoint = + process_sp->GetTarget() + .CreateBreakpoint(symbol_address, /*internal=*/true, + /*hardware=*/false) + .get(); + breakpoint->SetCallback( + InstrumentationRuntimeMainThreadChecker::NotifyBreakpointHit, this, true); + breakpoint->SetBreakpointKind("main-thread-checker-report"); + SetBreakpointID(breakpoint->GetID()); + + SetActive(true); +} + +void InstrumentationRuntimeMainThreadChecker::Deactivate() { + SetActive(false); + + auto BID = GetBreakpointID(); + if (BID == LLDB_INVALID_BREAK_ID) + return; + + if (ProcessSP process_sp = GetProcessSP()) { + process_sp->GetTarget().RemoveBreakpointByID(BID); + SetBreakpointID(LLDB_INVALID_BREAK_ID); + } +} + +lldb::ThreadCollectionSP +InstrumentationRuntimeMainThreadChecker::GetBacktracesFromExtendedStopInfo( + StructuredData::ObjectSP info) { + ThreadCollectionSP threads; + threads = std::make_shared(); + + ProcessSP process_sp = GetProcessSP(); + + if (info->GetObjectForDotSeparatedPath("instrumentation_class") + ->GetStringValue() != "MainThreadChecker") + return threads; + + std::vector PCs; + auto trace = info->GetObjectForDotSeparatedPath("trace")->GetAsArray(); + trace->ForEach([&PCs](StructuredData::Object *PC) -> bool { + PCs.push_back(PC->GetAsInteger()->GetValue()); + return true; + }); + + if (PCs.empty()) + return threads; + + StructuredData::ObjectSP thread_id_obj = + info->GetObjectForDotSeparatedPath("tid"); + tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0; + + HistoryThread *history_thread = new HistoryThread(*process_sp, tid, PCs); + ThreadSP new_thread_sp(history_thread); + + // Save this in the Process' ExtendedThreadList so a strong pointer retains + // the object + process_sp->GetExtendedThreadList().AddThread(new_thread_sp); + threads->AddThread(new_thread_sp); + + return threads; +} diff --git a/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.h b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.h new file mode 100644 index 00000000000..1435ae8d367 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.h @@ -0,0 +1,68 @@ +//===-- InstrumentationRuntimeMainThreadChecker.h----------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_MAINTHREADCHECKER_INSTRUMENTATIONRUNTIMEMAINTHREADCHECKER_H +#define LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_MAINTHREADCHECKER_INSTRUMENTATIONRUNTIMEMAINTHREADCHECKER_H + +#include "lldb/Target/ABI.h" +#include "lldb/Target/InstrumentationRuntime.h" +#include "lldb/Utility/StructuredData.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class InstrumentationRuntimeMainThreadChecker + : public lldb_private::InstrumentationRuntime { +public: + ~InstrumentationRuntimeMainThreadChecker() override; + + static lldb::InstrumentationRuntimeSP + CreateInstance(const lldb::ProcessSP &process_sp); + + static void Initialize(); + + static void Terminate(); + + static lldb_private::ConstString GetPluginNameStatic(); + + static lldb::InstrumentationRuntimeType GetTypeStatic(); + + lldb_private::ConstString GetPluginName() override { + return GetPluginNameStatic(); + } + + virtual lldb::InstrumentationRuntimeType GetType() { return GetTypeStatic(); } + + uint32_t GetPluginVersion() override { return 1; } + + lldb::ThreadCollectionSP + GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info) override; + +private: + InstrumentationRuntimeMainThreadChecker(const lldb::ProcessSP &process_sp) + : lldb_private::InstrumentationRuntime(process_sp) {} + + const RegularExpression &GetPatternForRuntimeLibrary() override; + + bool CheckIfRuntimeIsValid(const lldb::ModuleSP module_sp) override; + + void Activate() override; + + void Deactivate(); + + static bool NotifyBreakpointHit(void *baton, + StoppointCallbackContext *context, + lldb::user_id_t break_id, + lldb::user_id_t break_loc_id); + + StructuredData::ObjectSP RetrieveReportData(ExecutionContextRef exe_ctx_ref); +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_MAINTHREADCHECKER_INSTRUMENTATIONRUNTIMEMAINTHREADCHECKER_H diff --git a/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/TSan/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/TSan/CMakeLists.txt index 4dcd34131b8..a388cbb2ddf 100644 --- a/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/TSan/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/TSan/CMakeLists.txt @@ -1,5 +1,5 @@ add_lldb_library(lldbPluginInstrumentationRuntimeTSan PLUGIN - TSanRuntime.cpp + InstrumentationRuntimeTSan.cpp LINK_LIBS lldbBreakpoint diff --git a/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp new file mode 100644 index 00000000000..50f0faefa0f --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp @@ -0,0 +1,1066 @@ +//===-- InstrumentationRuntimeTSan.cpp ------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "InstrumentationRuntimeTSan.h" + +#include "Plugins/Process/Utility/HistoryThread.h" +#include "lldb/Breakpoint/StoppointCallbackContext.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginInterface.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/Expression/UserExpression.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/Variable.h" +#include "lldb/Symbol/VariableList.h" +#include "lldb/Target/InstrumentationRuntimeStopInfo.h" +#include "lldb/Target/SectionLoadList.h" +#include "lldb/Target/StopInfo.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Stream.h" + +#include + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(InstrumentationRuntimeTSan) + +lldb::InstrumentationRuntimeSP +InstrumentationRuntimeTSan::CreateInstance(const lldb::ProcessSP &process_sp) { + return InstrumentationRuntimeSP(new InstrumentationRuntimeTSan(process_sp)); +} + +void InstrumentationRuntimeTSan::Initialize() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), "ThreadSanitizer instrumentation runtime plugin.", + CreateInstance, GetTypeStatic); +} + +void InstrumentationRuntimeTSan::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString InstrumentationRuntimeTSan::GetPluginNameStatic() { + return ConstString("ThreadSanitizer"); +} + +lldb::InstrumentationRuntimeType InstrumentationRuntimeTSan::GetTypeStatic() { + return eInstrumentationRuntimeTypeThreadSanitizer; +} + +InstrumentationRuntimeTSan::~InstrumentationRuntimeTSan() { Deactivate(); } + +const char *thread_sanitizer_retrieve_report_data_prefix = R"( +extern "C" +{ + void *__tsan_get_current_report(); + int __tsan_get_report_data(void *report, const char **description, int *count, + int *stack_count, int *mop_count, int *loc_count, + int *mutex_count, int *thread_count, + int *unique_tid_count, void **sleep_trace, + unsigned long trace_size); + int __tsan_get_report_stack(void *report, unsigned long idx, void **trace, + unsigned long trace_size); + int __tsan_get_report_mop(void *report, unsigned long idx, int *tid, void **addr, + int *size, int *write, int *atomic, void **trace, + unsigned long trace_size); + int __tsan_get_report_loc(void *report, unsigned long idx, const char **type, + void **addr, unsigned long *start, unsigned long *size, int *tid, + int *fd, int *suppressable, void **trace, + unsigned long trace_size); + int __tsan_get_report_mutex(void *report, unsigned long idx, unsigned long *mutex_id, void **addr, + int *destroyed, void **trace, unsigned long trace_size); + int __tsan_get_report_thread(void *report, unsigned long idx, int *tid, unsigned long *os_id, + int *running, const char **name, int *parent_tid, + void **trace, unsigned long trace_size); + int __tsan_get_report_unique_tid(void *report, unsigned long idx, int *tid); + + // TODO: dlsym won't work on Windows. + void *dlsym(void* handle, const char* symbol); + int (*ptr__tsan_get_report_loc_object_type)(void *report, unsigned long idx, const char **object_type); +} + +const int REPORT_TRACE_SIZE = 128; +const int REPORT_ARRAY_SIZE = 4; + +struct data { + void *report; + const char *description; + int report_count; + + void *sleep_trace[REPORT_TRACE_SIZE]; + + int stack_count; + struct { + int idx; + void *trace[REPORT_TRACE_SIZE]; + } stacks[REPORT_ARRAY_SIZE]; + + int mop_count; + struct { + int idx; + int tid; + int size; + int write; + int atomic; + void *addr; + void *trace[REPORT_TRACE_SIZE]; + } mops[REPORT_ARRAY_SIZE]; + + int loc_count; + struct { + int idx; + const char *type; + void *addr; + unsigned long start; + unsigned long size; + int tid; + int fd; + int suppressable; + void *trace[REPORT_TRACE_SIZE]; + const char *object_type; + } locs[REPORT_ARRAY_SIZE]; + + int mutex_count; + struct { + int idx; + unsigned long mutex_id; + void *addr; + int destroyed; + void *trace[REPORT_TRACE_SIZE]; + } mutexes[REPORT_ARRAY_SIZE]; + + int thread_count; + struct { + int idx; + int tid; + unsigned long os_id; + int running; + const char *name; + int parent_tid; + void *trace[REPORT_TRACE_SIZE]; + } threads[REPORT_ARRAY_SIZE]; + + int unique_tid_count; + struct { + int idx; + int tid; + } unique_tids[REPORT_ARRAY_SIZE]; +}; +)"; + +const char *thread_sanitizer_retrieve_report_data_command = R"( +data t = {0}; + +ptr__tsan_get_report_loc_object_type = (typeof(ptr__tsan_get_report_loc_object_type))(void *)dlsym((void*)-2 /*RTLD_DEFAULT*/, "__tsan_get_report_loc_object_type"); + +t.report = __tsan_get_current_report(); +__tsan_get_report_data(t.report, &t.description, &t.report_count, &t.stack_count, &t.mop_count, &t.loc_count, &t.mutex_count, &t.thread_count, &t.unique_tid_count, t.sleep_trace, REPORT_TRACE_SIZE); + +if (t.stack_count > REPORT_ARRAY_SIZE) t.stack_count = REPORT_ARRAY_SIZE; +for (int i = 0; i < t.stack_count; i++) { + t.stacks[i].idx = i; + __tsan_get_report_stack(t.report, i, t.stacks[i].trace, REPORT_TRACE_SIZE); +} + +if (t.mop_count > REPORT_ARRAY_SIZE) t.mop_count = REPORT_ARRAY_SIZE; +for (int i = 0; i < t.mop_count; i++) { + t.mops[i].idx = i; + __tsan_get_report_mop(t.report, i, &t.mops[i].tid, &t.mops[i].addr, &t.mops[i].size, &t.mops[i].write, &t.mops[i].atomic, t.mops[i].trace, REPORT_TRACE_SIZE); +} + +if (t.loc_count > REPORT_ARRAY_SIZE) t.loc_count = REPORT_ARRAY_SIZE; +for (int i = 0; i < t.loc_count; i++) { + t.locs[i].idx = i; + __tsan_get_report_loc(t.report, i, &t.locs[i].type, &t.locs[i].addr, &t.locs[i].start, &t.locs[i].size, &t.locs[i].tid, &t.locs[i].fd, &t.locs[i].suppressable, t.locs[i].trace, REPORT_TRACE_SIZE); + if (ptr__tsan_get_report_loc_object_type) + ptr__tsan_get_report_loc_object_type(t.report, i, &t.locs[i].object_type); +} + +if (t.mutex_count > REPORT_ARRAY_SIZE) t.mutex_count = REPORT_ARRAY_SIZE; +for (int i = 0; i < t.mutex_count; i++) { + t.mutexes[i].idx = i; + __tsan_get_report_mutex(t.report, i, &t.mutexes[i].mutex_id, &t.mutexes[i].addr, &t.mutexes[i].destroyed, t.mutexes[i].trace, REPORT_TRACE_SIZE); +} + +if (t.thread_count > REPORT_ARRAY_SIZE) t.thread_count = REPORT_ARRAY_SIZE; +for (int i = 0; i < t.thread_count; i++) { + t.threads[i].idx = i; + __tsan_get_report_thread(t.report, i, &t.threads[i].tid, &t.threads[i].os_id, &t.threads[i].running, &t.threads[i].name, &t.threads[i].parent_tid, t.threads[i].trace, REPORT_TRACE_SIZE); +} + +if (t.unique_tid_count > REPORT_ARRAY_SIZE) t.unique_tid_count = REPORT_ARRAY_SIZE; +for (int i = 0; i < t.unique_tid_count; i++) { + t.unique_tids[i].idx = i; + __tsan_get_report_unique_tid(t.report, i, &t.unique_tids[i].tid); +} + +t; +)"; + +static StructuredData::Array * +CreateStackTrace(ValueObjectSP o, + const std::string &trace_item_name = ".trace") { + StructuredData::Array *trace = new StructuredData::Array(); + ValueObjectSP trace_value_object = + o->GetValueForExpressionPath(trace_item_name.c_str()); + size_t count = trace_value_object->GetNumChildren(); + for (size_t j = 0; j < count; j++) { + addr_t trace_addr = + trace_value_object->GetChildAtIndex(j, true)->GetValueAsUnsigned(0); + if (trace_addr == 0) + break; + trace->AddItem( + StructuredData::ObjectSP(new StructuredData::Integer(trace_addr))); + } + return trace; +} + +static StructuredData::Array *ConvertToStructuredArray( + ValueObjectSP return_value_sp, const std::string &items_name, + const std::string &count_name, + std::function const + &callback) { + StructuredData::Array *array = new StructuredData::Array(); + unsigned int count = + return_value_sp->GetValueForExpressionPath(count_name.c_str()) + ->GetValueAsUnsigned(0); + ValueObjectSP objects = + return_value_sp->GetValueForExpressionPath(items_name.c_str()); + for (unsigned int i = 0; i < count; i++) { + ValueObjectSP o = objects->GetChildAtIndex(i, true); + StructuredData::Dictionary *dict = new StructuredData::Dictionary(); + + callback(o, dict); + + array->AddItem(StructuredData::ObjectSP(dict)); + } + return array; +} + +static std::string RetrieveString(ValueObjectSP return_value_sp, + ProcessSP process_sp, + const std::string &expression_path) { + addr_t ptr = + return_value_sp->GetValueForExpressionPath(expression_path.c_str()) + ->GetValueAsUnsigned(0); + std::string str; + Status error; + process_sp->ReadCStringFromMemory(ptr, str, error); + return str; +} + +static void +GetRenumberedThreadIds(ProcessSP process_sp, ValueObjectSP data, + std::map &thread_id_map) { + ConvertToStructuredArray( + data, ".threads", ".thread_count", + [process_sp, &thread_id_map](ValueObjectSP o, + StructuredData::Dictionary *dict) { + uint64_t thread_id = + o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0); + uint64_t thread_os_id = + o->GetValueForExpressionPath(".os_id")->GetValueAsUnsigned(0); + user_id_t lldb_user_id = 0; + + bool can_update = true; + ThreadSP lldb_thread = process_sp->GetThreadList().FindThreadByID( + thread_os_id, can_update); + if (lldb_thread) { + lldb_user_id = lldb_thread->GetIndexID(); + } else { + // This isn't a live thread anymore. Ask process to assign a new + // Index ID (or return an old one if we've already seen this + // thread_os_id). It will also make sure that no new threads are + // assigned this Index ID. + lldb_user_id = process_sp->AssignIndexIDToThread(thread_os_id); + } + + thread_id_map[thread_id] = lldb_user_id; + }); +} + +static user_id_t Renumber(uint64_t id, + std::map &thread_id_map) { + auto IT = thread_id_map.find(id); + if (IT == thread_id_map.end()) + return 0; + + return IT->second; +} + +StructuredData::ObjectSP InstrumentationRuntimeTSan::RetrieveReportData( + ExecutionContextRef exe_ctx_ref) { + ProcessSP process_sp = GetProcessSP(); + if (!process_sp) + return StructuredData::ObjectSP(); + + ThreadSP thread_sp = exe_ctx_ref.GetThreadSP(); + StackFrameSP frame_sp = thread_sp->GetSelectedFrame(); + + if (!frame_sp) + return StructuredData::ObjectSP(); + + EvaluateExpressionOptions options; + options.SetUnwindOnError(true); + options.SetTryAllThreads(true); + options.SetStopOthers(true); + options.SetIgnoreBreakpoints(true); + options.SetTimeout(process_sp->GetUtilityExpressionTimeout()); + options.SetPrefix(thread_sanitizer_retrieve_report_data_prefix); + options.SetAutoApplyFixIts(false); + options.SetLanguage(eLanguageTypeObjC_plus_plus); + + ValueObjectSP main_value; + ExecutionContext exe_ctx; + Status eval_error; + frame_sp->CalculateExecutionContext(exe_ctx); + ExpressionResults result = UserExpression::Evaluate( + exe_ctx, options, thread_sanitizer_retrieve_report_data_command, "", + main_value, eval_error); + if (result != eExpressionCompleted) { + process_sp->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf( + "Warning: Cannot evaluate ThreadSanitizer expression:\n%s\n", + eval_error.AsCString()); + return StructuredData::ObjectSP(); + } + + std::map thread_id_map; + GetRenumberedThreadIds(process_sp, main_value, thread_id_map); + + StructuredData::Dictionary *dict = new StructuredData::Dictionary(); + dict->AddStringItem("instrumentation_class", "ThreadSanitizer"); + dict->AddStringItem("issue_type", + RetrieveString(main_value, process_sp, ".description")); + dict->AddIntegerItem("report_count", + main_value->GetValueForExpressionPath(".report_count") + ->GetValueAsUnsigned(0)); + dict->AddItem("sleep_trace", StructuredData::ObjectSP(CreateStackTrace( + main_value, ".sleep_trace"))); + + StructuredData::Array *stacks = ConvertToStructuredArray( + main_value, ".stacks", ".stack_count", + [thread_sp](ValueObjectSP o, StructuredData::Dictionary *dict) { + dict->AddIntegerItem( + "index", + o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0)); + dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o))); + // "stacks" happen on the current thread + dict->AddIntegerItem("thread_id", thread_sp->GetIndexID()); + }); + dict->AddItem("stacks", StructuredData::ObjectSP(stacks)); + + StructuredData::Array *mops = ConvertToStructuredArray( + main_value, ".mops", ".mop_count", + [&thread_id_map](ValueObjectSP o, StructuredData::Dictionary *dict) { + dict->AddIntegerItem( + "index", + o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0)); + dict->AddIntegerItem( + "thread_id", + Renumber( + o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0), + thread_id_map)); + dict->AddIntegerItem( + "size", + o->GetValueForExpressionPath(".size")->GetValueAsUnsigned(0)); + dict->AddBooleanItem( + "is_write", + o->GetValueForExpressionPath(".write")->GetValueAsUnsigned(0)); + dict->AddBooleanItem( + "is_atomic", + o->GetValueForExpressionPath(".atomic")->GetValueAsUnsigned(0)); + dict->AddIntegerItem( + "address", + o->GetValueForExpressionPath(".addr")->GetValueAsUnsigned(0)); + dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o))); + }); + dict->AddItem("mops", StructuredData::ObjectSP(mops)); + + StructuredData::Array *locs = ConvertToStructuredArray( + main_value, ".locs", ".loc_count", + [process_sp, &thread_id_map](ValueObjectSP o, + StructuredData::Dictionary *dict) { + dict->AddIntegerItem( + "index", + o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0)); + dict->AddStringItem("type", RetrieveString(o, process_sp, ".type")); + dict->AddIntegerItem( + "address", + o->GetValueForExpressionPath(".addr")->GetValueAsUnsigned(0)); + dict->AddIntegerItem( + "start", + o->GetValueForExpressionPath(".start")->GetValueAsUnsigned(0)); + dict->AddIntegerItem( + "size", + o->GetValueForExpressionPath(".size")->GetValueAsUnsigned(0)); + dict->AddIntegerItem( + "thread_id", + Renumber( + o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0), + thread_id_map)); + dict->AddIntegerItem( + "file_descriptor", + o->GetValueForExpressionPath(".fd")->GetValueAsUnsigned(0)); + dict->AddIntegerItem("suppressable", + o->GetValueForExpressionPath(".suppressable") + ->GetValueAsUnsigned(0)); + dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o))); + dict->AddStringItem("object_type", + RetrieveString(o, process_sp, ".object_type")); + }); + dict->AddItem("locs", StructuredData::ObjectSP(locs)); + + StructuredData::Array *mutexes = ConvertToStructuredArray( + main_value, ".mutexes", ".mutex_count", + [](ValueObjectSP o, StructuredData::Dictionary *dict) { + dict->AddIntegerItem( + "index", + o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0)); + dict->AddIntegerItem( + "mutex_id", + o->GetValueForExpressionPath(".mutex_id")->GetValueAsUnsigned(0)); + dict->AddIntegerItem( + "address", + o->GetValueForExpressionPath(".addr")->GetValueAsUnsigned(0)); + dict->AddIntegerItem( + "destroyed", + o->GetValueForExpressionPath(".destroyed")->GetValueAsUnsigned(0)); + dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o))); + }); + dict->AddItem("mutexes", StructuredData::ObjectSP(mutexes)); + + StructuredData::Array *threads = ConvertToStructuredArray( + main_value, ".threads", ".thread_count", + [process_sp, &thread_id_map](ValueObjectSP o, + StructuredData::Dictionary *dict) { + dict->AddIntegerItem( + "index", + o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0)); + dict->AddIntegerItem( + "thread_id", + Renumber( + o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0), + thread_id_map)); + dict->AddIntegerItem( + "thread_os_id", + o->GetValueForExpressionPath(".os_id")->GetValueAsUnsigned(0)); + dict->AddIntegerItem( + "running", + o->GetValueForExpressionPath(".running")->GetValueAsUnsigned(0)); + dict->AddStringItem("name", RetrieveString(o, process_sp, ".name")); + dict->AddIntegerItem( + "parent_thread_id", + Renumber(o->GetValueForExpressionPath(".parent_tid") + ->GetValueAsUnsigned(0), + thread_id_map)); + dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o))); + }); + dict->AddItem("threads", StructuredData::ObjectSP(threads)); + + StructuredData::Array *unique_tids = ConvertToStructuredArray( + main_value, ".unique_tids", ".unique_tid_count", + [&thread_id_map](ValueObjectSP o, StructuredData::Dictionary *dict) { + dict->AddIntegerItem( + "index", + o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0)); + dict->AddIntegerItem( + "tid", + Renumber( + o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0), + thread_id_map)); + }); + dict->AddItem("unique_tids", StructuredData::ObjectSP(unique_tids)); + + return StructuredData::ObjectSP(dict); +} + +std::string +InstrumentationRuntimeTSan::FormatDescription(StructuredData::ObjectSP report) { + std::string description = std::string(report->GetAsDictionary() + ->GetValueForKey("issue_type") + ->GetAsString() + ->GetValue()); + + if (description == "data-race") { + return "Data race"; + } else if (description == "data-race-vptr") { + return "Data race on C++ virtual pointer"; + } else if (description == "heap-use-after-free") { + return "Use of deallocated memory"; + } else if (description == "heap-use-after-free-vptr") { + return "Use of deallocated C++ virtual pointer"; + } else if (description == "thread-leak") { + return "Thread leak"; + } else if (description == "locked-mutex-destroy") { + return "Destruction of a locked mutex"; + } else if (description == "mutex-double-lock") { + return "Double lock of a mutex"; + } else if (description == "mutex-invalid-access") { + return "Use of an uninitialized or destroyed mutex"; + } else if (description == "mutex-bad-unlock") { + return "Unlock of an unlocked mutex (or by a wrong thread)"; + } else if (description == "mutex-bad-read-lock") { + return "Read lock of a write locked mutex"; + } else if (description == "mutex-bad-read-unlock") { + return "Read unlock of a write locked mutex"; + } else if (description == "signal-unsafe-call") { + return "Signal-unsafe call inside a signal handler"; + } else if (description == "errno-in-signal-handler") { + return "Overwrite of errno in a signal handler"; + } else if (description == "lock-order-inversion") { + return "Lock order inversion (potential deadlock)"; + } else if (description == "external-race") { + return "Race on a library object"; + } else if (description == "swift-access-race") { + return "Swift access race"; + } + + // for unknown report codes just show the code + return description; +} + +static std::string Sprintf(const char *format, ...) { + StreamString s; + va_list args; + va_start(args, format); + s.PrintfVarArg(format, args); + va_end(args); + return std::string(s.GetString()); +} + +static std::string GetSymbolNameFromAddress(ProcessSP process_sp, addr_t addr) { + lldb_private::Address so_addr; + if (!process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(addr, + so_addr)) + return ""; + + lldb_private::Symbol *symbol = so_addr.CalculateSymbolContextSymbol(); + if (!symbol) + return ""; + + std::string sym_name = symbol->GetName().GetCString(); + return sym_name; +} + +static void GetSymbolDeclarationFromAddress(ProcessSP process_sp, addr_t addr, + Declaration &decl) { + lldb_private::Address so_addr; + if (!process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(addr, + so_addr)) + return; + + lldb_private::Symbol *symbol = so_addr.CalculateSymbolContextSymbol(); + if (!symbol) + return; + + ConstString sym_name = symbol->GetMangled().GetName(Mangled::ePreferMangled); + + ModuleSP module = symbol->CalculateSymbolContextModule(); + if (!module) + return; + + VariableList var_list; + module->FindGlobalVariables(sym_name, CompilerDeclContext(), 1U, var_list); + if (var_list.GetSize() < 1) + return; + + VariableSP var = var_list.GetVariableAtIndex(0); + decl = var->GetDeclaration(); +} + +addr_t InstrumentationRuntimeTSan::GetFirstNonInternalFramePc( + StructuredData::ObjectSP trace, bool skip_one_frame) { + ProcessSP process_sp = GetProcessSP(); + ModuleSP runtime_module_sp = GetRuntimeModuleSP(); + + StructuredData::Array *trace_array = trace->GetAsArray(); + for (size_t i = 0; i < trace_array->GetSize(); i++) { + if (skip_one_frame && i == 0) + continue; + + addr_t addr; + if (!trace_array->GetItemAtIndexAsInteger(i, addr)) + continue; + + lldb_private::Address so_addr; + if (!process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress( + addr, so_addr)) + continue; + + if (so_addr.GetModule() == runtime_module_sp) + continue; + + return addr; + } + + return 0; +} + +std::string +InstrumentationRuntimeTSan::GenerateSummary(StructuredData::ObjectSP report) { + ProcessSP process_sp = GetProcessSP(); + + std::string summary = std::string(report->GetAsDictionary() + ->GetValueForKey("description") + ->GetAsString() + ->GetValue()); + bool skip_one_frame = + report->GetObjectForDotSeparatedPath("issue_type")->GetStringValue() == + "external-race"; + + addr_t pc = 0; + if (report->GetAsDictionary() + ->GetValueForKey("mops") + ->GetAsArray() + ->GetSize() > 0) + pc = GetFirstNonInternalFramePc(report->GetAsDictionary() + ->GetValueForKey("mops") + ->GetAsArray() + ->GetItemAtIndex(0) + ->GetAsDictionary() + ->GetValueForKey("trace"), + skip_one_frame); + + if (report->GetAsDictionary() + ->GetValueForKey("stacks") + ->GetAsArray() + ->GetSize() > 0) + pc = GetFirstNonInternalFramePc(report->GetAsDictionary() + ->GetValueForKey("stacks") + ->GetAsArray() + ->GetItemAtIndex(0) + ->GetAsDictionary() + ->GetValueForKey("trace"), + skip_one_frame); + + if (pc != 0) { + summary = summary + " in " + GetSymbolNameFromAddress(process_sp, pc); + } + + if (report->GetAsDictionary() + ->GetValueForKey("locs") + ->GetAsArray() + ->GetSize() > 0) { + StructuredData::ObjectSP loc = report->GetAsDictionary() + ->GetValueForKey("locs") + ->GetAsArray() + ->GetItemAtIndex(0); + std::string object_type = std::string(loc->GetAsDictionary() + ->GetValueForKey("object_type") + ->GetAsString() + ->GetValue()); + if (!object_type.empty()) { + summary = "Race on " + object_type + " object"; + } + addr_t addr = loc->GetAsDictionary() + ->GetValueForKey("address") + ->GetAsInteger() + ->GetValue(); + if (addr == 0) + addr = loc->GetAsDictionary() + ->GetValueForKey("start") + ->GetAsInteger() + ->GetValue(); + + if (addr != 0) { + std::string global_name = GetSymbolNameFromAddress(process_sp, addr); + if (!global_name.empty()) { + summary = summary + " at " + global_name; + } else { + summary = summary + " at " + Sprintf("0x%llx", addr); + } + } else { + int fd = loc->GetAsDictionary() + ->GetValueForKey("file_descriptor") + ->GetAsInteger() + ->GetValue(); + if (fd != 0) { + summary = summary + " on file descriptor " + Sprintf("%d", fd); + } + } + } + + return summary; +} + +addr_t InstrumentationRuntimeTSan::GetMainRacyAddress( + StructuredData::ObjectSP report) { + addr_t result = (addr_t)-1; + + report->GetObjectForDotSeparatedPath("mops")->GetAsArray()->ForEach( + [&result](StructuredData::Object *o) -> bool { + addr_t addr = + o->GetObjectForDotSeparatedPath("address")->GetIntegerValue(); + if (addr < result) + result = addr; + return true; + }); + + return (result == (addr_t)-1) ? 0 : result; +} + +std::string InstrumentationRuntimeTSan::GetLocationDescription( + StructuredData::ObjectSP report, addr_t &global_addr, + std::string &global_name, std::string &filename, uint32_t &line) { + std::string result = ""; + + ProcessSP process_sp = GetProcessSP(); + + if (report->GetAsDictionary() + ->GetValueForKey("locs") + ->GetAsArray() + ->GetSize() > 0) { + StructuredData::ObjectSP loc = report->GetAsDictionary() + ->GetValueForKey("locs") + ->GetAsArray() + ->GetItemAtIndex(0); + std::string type = std::string( + loc->GetAsDictionary()->GetValueForKey("type")->GetStringValue()); + if (type == "global") { + global_addr = loc->GetAsDictionary() + ->GetValueForKey("address") + ->GetAsInteger() + ->GetValue(); + global_name = GetSymbolNameFromAddress(process_sp, global_addr); + if (!global_name.empty()) { + result = Sprintf("'%s' is a global variable (0x%llx)", + global_name.c_str(), global_addr); + } else { + result = Sprintf("0x%llx is a global variable", global_addr); + } + + Declaration decl; + GetSymbolDeclarationFromAddress(process_sp, global_addr, decl); + if (decl.GetFile()) { + filename = decl.GetFile().GetPath(); + line = decl.GetLine(); + } + } else if (type == "heap") { + addr_t addr = loc->GetAsDictionary() + ->GetValueForKey("start") + ->GetAsInteger() + ->GetValue(); + long size = loc->GetAsDictionary() + ->GetValueForKey("size") + ->GetAsInteger() + ->GetValue(); + std::string object_type = std::string(loc->GetAsDictionary() + ->GetValueForKey("object_type") + ->GetAsString() + ->GetValue()); + if (!object_type.empty()) { + result = Sprintf("Location is a %ld-byte %s object at 0x%llx", size, + object_type.c_str(), addr); + } else { + result = + Sprintf("Location is a %ld-byte heap object at 0x%llx", size, addr); + } + } else if (type == "stack") { + int tid = loc->GetAsDictionary() + ->GetValueForKey("thread_id") + ->GetAsInteger() + ->GetValue(); + result = Sprintf("Location is stack of thread %d", tid); + } else if (type == "tls") { + int tid = loc->GetAsDictionary() + ->GetValueForKey("thread_id") + ->GetAsInteger() + ->GetValue(); + result = Sprintf("Location is TLS of thread %d", tid); + } else if (type == "fd") { + int fd = loc->GetAsDictionary() + ->GetValueForKey("file_descriptor") + ->GetAsInteger() + ->GetValue(); + result = Sprintf("Location is file descriptor %d", fd); + } + } + + return result; +} + +bool InstrumentationRuntimeTSan::NotifyBreakpointHit( + void *baton, StoppointCallbackContext *context, user_id_t break_id, + user_id_t break_loc_id) { + assert(baton && "null baton"); + if (!baton) + return false; + + InstrumentationRuntimeTSan *const instance = + static_cast(baton); + + ProcessSP process_sp = instance->GetProcessSP(); + + if (process_sp->GetModIDRef().IsLastResumeForUserExpression()) + return false; + + StructuredData::ObjectSP report = + instance->RetrieveReportData(context->exe_ctx_ref); + std::string stop_reason_description; + if (report) { + std::string issue_description = instance->FormatDescription(report); + report->GetAsDictionary()->AddStringItem("description", issue_description); + stop_reason_description = issue_description + " detected"; + report->GetAsDictionary()->AddStringItem("stop_description", + stop_reason_description); + std::string summary = instance->GenerateSummary(report); + report->GetAsDictionary()->AddStringItem("summary", summary); + addr_t main_address = instance->GetMainRacyAddress(report); + report->GetAsDictionary()->AddIntegerItem("memory_address", main_address); + + addr_t global_addr = 0; + std::string global_name = ""; + std::string location_filename = ""; + uint32_t location_line = 0; + std::string location_description = instance->GetLocationDescription( + report, global_addr, global_name, location_filename, location_line); + report->GetAsDictionary()->AddStringItem("location_description", + location_description); + if (global_addr != 0) { + report->GetAsDictionary()->AddIntegerItem("global_address", global_addr); + } + if (!global_name.empty()) { + report->GetAsDictionary()->AddStringItem("global_name", global_name); + } + if (location_filename != "") { + report->GetAsDictionary()->AddStringItem("location_filename", + location_filename); + report->GetAsDictionary()->AddIntegerItem("location_line", location_line); + } + + bool all_addresses_are_same = true; + report->GetObjectForDotSeparatedPath("mops")->GetAsArray()->ForEach( + [&all_addresses_are_same, + main_address](StructuredData::Object *o) -> bool { + addr_t addr = + o->GetObjectForDotSeparatedPath("address")->GetIntegerValue(); + if (main_address != addr) + all_addresses_are_same = false; + return true; + }); + report->GetAsDictionary()->AddBooleanItem("all_addresses_are_same", + all_addresses_are_same); + } + + // Make sure this is the right process + if (process_sp && process_sp == context->exe_ctx_ref.GetProcessSP()) { + ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP(); + if (thread_sp) + thread_sp->SetStopInfo( + InstrumentationRuntimeStopInfo:: + CreateStopReasonWithInstrumentationData( + *thread_sp, stop_reason_description, report)); + + StreamFile &s = process_sp->GetTarget().GetDebugger().GetOutputStream(); + s.Printf("ThreadSanitizer report breakpoint hit. Use 'thread " + "info -s' to get extended information about the " + "report.\n"); + + return true; // Return true to stop the target + } else + return false; // Let target run +} + +const RegularExpression & +InstrumentationRuntimeTSan::GetPatternForRuntimeLibrary() { + static RegularExpression regex(llvm::StringRef("libclang_rt.tsan_")); + return regex; +} + +bool InstrumentationRuntimeTSan::CheckIfRuntimeIsValid( + const lldb::ModuleSP module_sp) { + static ConstString g_tsan_get_current_report("__tsan_get_current_report"); + const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType( + g_tsan_get_current_report, lldb::eSymbolTypeAny); + return symbol != nullptr; +} + +void InstrumentationRuntimeTSan::Activate() { + if (IsActive()) + return; + + ProcessSP process_sp = GetProcessSP(); + if (!process_sp) + return; + + ConstString symbol_name("__tsan_on_report"); + const Symbol *symbol = GetRuntimeModuleSP()->FindFirstSymbolWithNameAndType( + symbol_name, eSymbolTypeCode); + + if (symbol == nullptr) + return; + + if (!symbol->ValueIsAddress() || !symbol->GetAddressRef().IsValid()) + return; + + Target &target = process_sp->GetTarget(); + addr_t symbol_address = symbol->GetAddressRef().GetOpcodeLoadAddress(&target); + + if (symbol_address == LLDB_INVALID_ADDRESS) + return; + + bool internal = true; + bool hardware = false; + Breakpoint *breakpoint = + process_sp->GetTarget() + .CreateBreakpoint(symbol_address, internal, hardware) + .get(); + breakpoint->SetCallback(InstrumentationRuntimeTSan::NotifyBreakpointHit, this, + true); + breakpoint->SetBreakpointKind("thread-sanitizer-report"); + SetBreakpointID(breakpoint->GetID()); + + SetActive(true); +} + +void InstrumentationRuntimeTSan::Deactivate() { + if (GetBreakpointID() != LLDB_INVALID_BREAK_ID) { + ProcessSP process_sp = GetProcessSP(); + if (process_sp) { + process_sp->GetTarget().RemoveBreakpointByID(GetBreakpointID()); + SetBreakpointID(LLDB_INVALID_BREAK_ID); + } + } + SetActive(false); +} +static std::string GenerateThreadName(const std::string &path, + StructuredData::Object *o, + StructuredData::ObjectSP main_info) { + std::string result = "additional information"; + + if (path == "mops") { + int size = o->GetObjectForDotSeparatedPath("size")->GetIntegerValue(); + int thread_id = + o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue(); + bool is_write = + o->GetObjectForDotSeparatedPath("is_write")->GetBooleanValue(); + bool is_atomic = + o->GetObjectForDotSeparatedPath("is_atomic")->GetBooleanValue(); + addr_t addr = o->GetObjectForDotSeparatedPath("address")->GetIntegerValue(); + + std::string addr_string = Sprintf(" at 0x%llx", addr); + + if (main_info->GetObjectForDotSeparatedPath("all_addresses_are_same") + ->GetBooleanValue()) { + addr_string = ""; + } + + if (main_info->GetObjectForDotSeparatedPath("issue_type") + ->GetStringValue() == "external-race") { + result = Sprintf("%s access by thread %d", + is_write ? "mutating" : "read-only", thread_id); + } else if (main_info->GetObjectForDotSeparatedPath("issue_type") + ->GetStringValue() == "swift-access-race") { + result = Sprintf("modifying access by thread %d", thread_id); + } else { + result = Sprintf("%s%s of size %d%s by thread %d", + is_atomic ? "atomic " : "", is_write ? "write" : "read", + size, addr_string.c_str(), thread_id); + } + } + + if (path == "threads") { + int thread_id = + o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue(); + result = Sprintf("Thread %d created", thread_id); + } + + if (path == "locs") { + std::string type = std::string( + o->GetAsDictionary()->GetValueForKey("type")->GetStringValue()); + int thread_id = + o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue(); + int fd = + o->GetObjectForDotSeparatedPath("file_descriptor")->GetIntegerValue(); + if (type == "heap") { + result = Sprintf("Heap block allocated by thread %d", thread_id); + } else if (type == "fd") { + result = + Sprintf("File descriptor %d created by thread %t", fd, thread_id); + } + } + + if (path == "mutexes") { + int mutex_id = + o->GetObjectForDotSeparatedPath("mutex_id")->GetIntegerValue(); + + result = Sprintf("Mutex M%d created", mutex_id); + } + + if (path == "stacks") { + int thread_id = + o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue(); + result = Sprintf("Thread %d", thread_id); + } + + result[0] = toupper(result[0]); + + return result; +} + +static void AddThreadsForPath(const std::string &path, + ThreadCollectionSP threads, ProcessSP process_sp, + StructuredData::ObjectSP info) { + info->GetObjectForDotSeparatedPath(path)->GetAsArray()->ForEach( + [process_sp, threads, path, info](StructuredData::Object *o) -> bool { + std::vector pcs; + o->GetObjectForDotSeparatedPath("trace")->GetAsArray()->ForEach( + [&pcs](StructuredData::Object *pc) -> bool { + pcs.push_back(pc->GetAsInteger()->GetValue()); + return true; + }); + + if (pcs.size() == 0) + return true; + + StructuredData::ObjectSP thread_id_obj = + o->GetObjectForDotSeparatedPath("thread_os_id"); + tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0; + + HistoryThread *history_thread = + new HistoryThread(*process_sp, tid, pcs); + ThreadSP new_thread_sp(history_thread); + new_thread_sp->SetName(GenerateThreadName(path, o, info).c_str()); + + // Save this in the Process' ExtendedThreadList so a strong pointer + // retains the object + process_sp->GetExtendedThreadList().AddThread(new_thread_sp); + threads->AddThread(new_thread_sp); + + return true; + }); +} + +lldb::ThreadCollectionSP +InstrumentationRuntimeTSan::GetBacktracesFromExtendedStopInfo( + StructuredData::ObjectSP info) { + ThreadCollectionSP threads; + threads = std::make_shared(); + + if (info->GetObjectForDotSeparatedPath("instrumentation_class") + ->GetStringValue() != "ThreadSanitizer") + return threads; + + ProcessSP process_sp = GetProcessSP(); + + AddThreadsForPath("stacks", threads, process_sp, info); + AddThreadsForPath("mops", threads, process_sp, info); + AddThreadsForPath("locs", threads, process_sp, info); + AddThreadsForPath("mutexes", threads, process_sp, info); + AddThreadsForPath("threads", threads, process_sp, info); + + return threads; +} diff --git a/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.h b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.h new file mode 100644 index 00000000000..35a878d90af --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.h @@ -0,0 +1,81 @@ +//===-- InstrumentationRuntimeTSan.h ----------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_TSAN_INSTRUMENTATIONRUNTIMETSAN_H +#define LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_TSAN_INSTRUMENTATIONRUNTIMETSAN_H + +#include "lldb/Target/ABI.h" +#include "lldb/Target/InstrumentationRuntime.h" +#include "lldb/Utility/StructuredData.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class InstrumentationRuntimeTSan : public lldb_private::InstrumentationRuntime { +public: + ~InstrumentationRuntimeTSan() override; + + static lldb::InstrumentationRuntimeSP + CreateInstance(const lldb::ProcessSP &process_sp); + + static void Initialize(); + + static void Terminate(); + + static lldb_private::ConstString GetPluginNameStatic(); + + static lldb::InstrumentationRuntimeType GetTypeStatic(); + + lldb_private::ConstString GetPluginName() override { + return GetPluginNameStatic(); + } + + virtual lldb::InstrumentationRuntimeType GetType() { return GetTypeStatic(); } + + uint32_t GetPluginVersion() override { return 1; } + + lldb::ThreadCollectionSP + GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info) override; + +private: + InstrumentationRuntimeTSan(const lldb::ProcessSP &process_sp) + : lldb_private::InstrumentationRuntime(process_sp) {} + + const RegularExpression &GetPatternForRuntimeLibrary() override; + + bool CheckIfRuntimeIsValid(const lldb::ModuleSP module_sp) override; + + void Activate() override; + + void Deactivate(); + + static bool NotifyBreakpointHit(void *baton, + StoppointCallbackContext *context, + lldb::user_id_t break_id, + lldb::user_id_t break_loc_id); + + StructuredData::ObjectSP RetrieveReportData(ExecutionContextRef exe_ctx_ref); + + std::string FormatDescription(StructuredData::ObjectSP report); + + std::string GenerateSummary(StructuredData::ObjectSP report); + + lldb::addr_t GetMainRacyAddress(StructuredData::ObjectSP report); + + std::string GetLocationDescription(StructuredData::ObjectSP report, + lldb::addr_t &global_addr, + std::string &global_name, + std::string &filename, uint32_t &line); + + lldb::addr_t GetFirstNonInternalFramePc(StructuredData::ObjectSP trace, + bool skip_one_frame = false); +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_TSAN_INSTRUMENTATIONRUNTIMETSAN_H diff --git a/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/UBSan/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/UBSan/CMakeLists.txt index 984bf86f83b..12e1956bbe8 100644 --- a/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/UBSan/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/UBSan/CMakeLists.txt @@ -1,5 +1,5 @@ add_lldb_library(lldbPluginInstrumentationRuntimeUBSan PLUGIN - UBSanRuntime.cpp + InstrumentationRuntimeUBSan.cpp LINK_LIBS lldbBreakpoint diff --git a/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp new file mode 100644 index 00000000000..b60eb53f3d4 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp @@ -0,0 +1,338 @@ +//===-- InstrumentationRuntimeUBSan.cpp -----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "InstrumentationRuntimeUBSan.h" + +#include "Plugins/Process/Utility/HistoryThread.h" +#include "lldb/Breakpoint/StoppointCallbackContext.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginInterface.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/Expression/UserExpression.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/Variable.h" +#include "lldb/Symbol/VariableList.h" +#include "lldb/Target/InstrumentationRuntimeStopInfo.h" +#include "lldb/Target/SectionLoadList.h" +#include "lldb/Target/StopInfo.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Stream.h" +#include + +#include + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(InstrumentationRuntimeUBSan) + +InstrumentationRuntimeUBSan::~InstrumentationRuntimeUBSan() { Deactivate(); } + +lldb::InstrumentationRuntimeSP +InstrumentationRuntimeUBSan::CreateInstance(const lldb::ProcessSP &process_sp) { + return InstrumentationRuntimeSP(new InstrumentationRuntimeUBSan(process_sp)); +} + +void InstrumentationRuntimeUBSan::Initialize() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), + "UndefinedBehaviorSanitizer instrumentation runtime plugin.", + CreateInstance, GetTypeStatic); +} + +void InstrumentationRuntimeUBSan::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString InstrumentationRuntimeUBSan::GetPluginNameStatic() { + return ConstString("UndefinedBehaviorSanitizer"); +} + +lldb::InstrumentationRuntimeType InstrumentationRuntimeUBSan::GetTypeStatic() { + return eInstrumentationRuntimeTypeUndefinedBehaviorSanitizer; +} + +static const char *ub_sanitizer_retrieve_report_data_prefix = R"( +extern "C" { +void +__ubsan_get_current_report_data(const char **OutIssueKind, + const char **OutMessage, const char **OutFilename, unsigned *OutLine, + unsigned *OutCol, char **OutMemoryAddr); +} + +struct data { + const char *issue_kind; + const char *message; + const char *filename; + unsigned line; + unsigned col; + char *memory_addr; +}; +)"; + +static const char *ub_sanitizer_retrieve_report_data_command = R"( +data t; +__ubsan_get_current_report_data(&t.issue_kind, &t.message, &t.filename, &t.line, + &t.col, &t.memory_addr); +t; +)"; + +static addr_t RetrieveUnsigned(ValueObjectSP return_value_sp, + ProcessSP process_sp, + const std::string &expression_path) { + return return_value_sp->GetValueForExpressionPath(expression_path.c_str()) + ->GetValueAsUnsigned(0); +} + +static std::string RetrieveString(ValueObjectSP return_value_sp, + ProcessSP process_sp, + const std::string &expression_path) { + addr_t ptr = RetrieveUnsigned(return_value_sp, process_sp, expression_path); + std::string str; + Status error; + process_sp->ReadCStringFromMemory(ptr, str, error); + return str; +} + +StructuredData::ObjectSP InstrumentationRuntimeUBSan::RetrieveReportData( + ExecutionContextRef exe_ctx_ref) { + ProcessSP process_sp = GetProcessSP(); + if (!process_sp) + return StructuredData::ObjectSP(); + + ThreadSP thread_sp = exe_ctx_ref.GetThreadSP(); + StackFrameSP frame_sp = thread_sp->GetSelectedFrame(); + ModuleSP runtime_module_sp = GetRuntimeModuleSP(); + Target &target = process_sp->GetTarget(); + + if (!frame_sp) + return StructuredData::ObjectSP(); + + StreamFileSP Stream = target.GetDebugger().GetOutputStreamSP(); + + EvaluateExpressionOptions options; + options.SetUnwindOnError(true); + options.SetTryAllThreads(true); + options.SetStopOthers(true); + options.SetIgnoreBreakpoints(true); + options.SetTimeout(process_sp->GetUtilityExpressionTimeout()); + options.SetPrefix(ub_sanitizer_retrieve_report_data_prefix); + options.SetAutoApplyFixIts(false); + options.SetLanguage(eLanguageTypeObjC_plus_plus); + + ValueObjectSP main_value; + ExecutionContext exe_ctx; + Status eval_error; + frame_sp->CalculateExecutionContext(exe_ctx); + ExpressionResults result = UserExpression::Evaluate( + exe_ctx, options, ub_sanitizer_retrieve_report_data_command, "", + main_value, eval_error); + if (result != eExpressionCompleted) { + target.GetDebugger().GetAsyncOutputStream()->Printf( + "Warning: Cannot evaluate UndefinedBehaviorSanitizer expression:\n%s\n", + eval_error.AsCString()); + return StructuredData::ObjectSP(); + } + + // Gather the PCs of the user frames in the backtrace. + StructuredData::Array *trace = new StructuredData::Array(); + auto trace_sp = StructuredData::ObjectSP(trace); + for (unsigned I = 0; I < thread_sp->GetStackFrameCount(); ++I) { + const Address FCA = + thread_sp->GetStackFrameAtIndex(I)->GetFrameCodeAddress(); + if (FCA.GetModule() == runtime_module_sp) // Skip PCs from the runtime. + continue; + + lldb::addr_t PC = FCA.GetLoadAddress(&target); + trace->AddItem(StructuredData::ObjectSP(new StructuredData::Integer(PC))); + } + + std::string IssueKind = RetrieveString(main_value, process_sp, ".issue_kind"); + std::string ErrMessage = RetrieveString(main_value, process_sp, ".message"); + std::string Filename = RetrieveString(main_value, process_sp, ".filename"); + unsigned Line = RetrieveUnsigned(main_value, process_sp, ".line"); + unsigned Col = RetrieveUnsigned(main_value, process_sp, ".col"); + uintptr_t MemoryAddr = + RetrieveUnsigned(main_value, process_sp, ".memory_addr"); + + auto *d = new StructuredData::Dictionary(); + auto dict_sp = StructuredData::ObjectSP(d); + d->AddStringItem("instrumentation_class", "UndefinedBehaviorSanitizer"); + d->AddStringItem("description", IssueKind); + d->AddStringItem("summary", ErrMessage); + d->AddStringItem("filename", Filename); + d->AddIntegerItem("line", Line); + d->AddIntegerItem("col", Col); + d->AddIntegerItem("memory_address", MemoryAddr); + d->AddIntegerItem("tid", thread_sp->GetID()); + d->AddItem("trace", trace_sp); + return dict_sp; +} + +static std::string GetStopReasonDescription(StructuredData::ObjectSP report) { + llvm::StringRef stop_reason_description_ref; + report->GetAsDictionary()->GetValueForKeyAsString( + "description", stop_reason_description_ref); + std::string stop_reason_description = + std::string(stop_reason_description_ref); + + if (!stop_reason_description.size()) { + stop_reason_description = "Undefined behavior detected"; + } else { + stop_reason_description[0] = toupper(stop_reason_description[0]); + for (unsigned I = 1; I < stop_reason_description.size(); ++I) + if (stop_reason_description[I] == '-') + stop_reason_description[I] = ' '; + } + return stop_reason_description; +} + +bool InstrumentationRuntimeUBSan::NotifyBreakpointHit( + void *baton, StoppointCallbackContext *context, user_id_t break_id, + user_id_t break_loc_id) { + assert(baton && "null baton"); + if (!baton) + return false; ///< false => resume execution. + + InstrumentationRuntimeUBSan *const instance = + static_cast(baton); + + ProcessSP process_sp = instance->GetProcessSP(); + ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP(); + if (!process_sp || !thread_sp || + process_sp != context->exe_ctx_ref.GetProcessSP()) + return false; + + if (process_sp->GetModIDRef().IsLastResumeForUserExpression()) + return false; + + StructuredData::ObjectSP report = + instance->RetrieveReportData(context->exe_ctx_ref); + + if (report) { + thread_sp->SetStopInfo( + InstrumentationRuntimeStopInfo::CreateStopReasonWithInstrumentationData( + *thread_sp, GetStopReasonDescription(report), report)); + return true; + } + + return false; +} + +const RegularExpression & +InstrumentationRuntimeUBSan::GetPatternForRuntimeLibrary() { + static RegularExpression regex(llvm::StringRef("libclang_rt\\.(a|t|ub)san_")); + return regex; +} + +bool InstrumentationRuntimeUBSan::CheckIfRuntimeIsValid( + const lldb::ModuleSP module_sp) { + static ConstString ubsan_test_sym("__ubsan_on_report"); + const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType( + ubsan_test_sym, lldb::eSymbolTypeAny); + return symbol != nullptr; +} + +// FIXME: Factor out all the logic we have in common with the {a,t}san plugins. +void InstrumentationRuntimeUBSan::Activate() { + if (IsActive()) + return; + + ProcessSP process_sp = GetProcessSP(); + if (!process_sp) + return; + + ModuleSP runtime_module_sp = GetRuntimeModuleSP(); + + ConstString symbol_name("__ubsan_on_report"); + const Symbol *symbol = runtime_module_sp->FindFirstSymbolWithNameAndType( + symbol_name, eSymbolTypeCode); + + if (symbol == nullptr) + return; + + if (!symbol->ValueIsAddress() || !symbol->GetAddressRef().IsValid()) + return; + + Target &target = process_sp->GetTarget(); + addr_t symbol_address = symbol->GetAddressRef().GetOpcodeLoadAddress(&target); + + if (symbol_address == LLDB_INVALID_ADDRESS) + return; + + Breakpoint *breakpoint = + process_sp->GetTarget() + .CreateBreakpoint(symbol_address, /*internal=*/true, + /*hardware=*/false) + .get(); + breakpoint->SetCallback(InstrumentationRuntimeUBSan::NotifyBreakpointHit, + this, true); + breakpoint->SetBreakpointKind("undefined-behavior-sanitizer-report"); + SetBreakpointID(breakpoint->GetID()); + + SetActive(true); +} + +void InstrumentationRuntimeUBSan::Deactivate() { + SetActive(false); + + auto BID = GetBreakpointID(); + if (BID == LLDB_INVALID_BREAK_ID) + return; + + if (ProcessSP process_sp = GetProcessSP()) { + process_sp->GetTarget().RemoveBreakpointByID(BID); + SetBreakpointID(LLDB_INVALID_BREAK_ID); + } +} + +lldb::ThreadCollectionSP +InstrumentationRuntimeUBSan::GetBacktracesFromExtendedStopInfo( + StructuredData::ObjectSP info) { + ThreadCollectionSP threads; + threads = std::make_shared(); + + ProcessSP process_sp = GetProcessSP(); + + if (info->GetObjectForDotSeparatedPath("instrumentation_class") + ->GetStringValue() != "UndefinedBehaviorSanitizer") + return threads; + + std::vector PCs; + auto trace = info->GetObjectForDotSeparatedPath("trace")->GetAsArray(); + trace->ForEach([&PCs](StructuredData::Object *PC) -> bool { + PCs.push_back(PC->GetAsInteger()->GetValue()); + return true; + }); + + if (PCs.empty()) + return threads; + + StructuredData::ObjectSP thread_id_obj = + info->GetObjectForDotSeparatedPath("tid"); + tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0; + + HistoryThread *history_thread = new HistoryThread(*process_sp, tid, PCs); + ThreadSP new_thread_sp(history_thread); + std::string stop_reason_description = GetStopReasonDescription(info); + new_thread_sp->SetName(stop_reason_description.c_str()); + + // Save this in the Process' ExtendedThreadList so a strong pointer retains + // the object + process_sp->GetExtendedThreadList().AddThread(new_thread_sp); + threads->AddThread(new_thread_sp); + + return threads; +} diff --git a/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.h b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.h new file mode 100644 index 00000000000..813c3006960 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.h @@ -0,0 +1,68 @@ +//===-- InstrumentationRuntimeUBSan.h ---------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_UBSAN_INSTRUMENTATIONRUNTIMEUBSAN_H +#define LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_UBSAN_INSTRUMENTATIONRUNTIMEUBSAN_H + +#include "lldb/Target/ABI.h" +#include "lldb/Target/InstrumentationRuntime.h" +#include "lldb/Utility/StructuredData.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class InstrumentationRuntimeUBSan + : public lldb_private::InstrumentationRuntime { +public: + ~InstrumentationRuntimeUBSan() override; + + static lldb::InstrumentationRuntimeSP + CreateInstance(const lldb::ProcessSP &process_sp); + + static void Initialize(); + + static void Terminate(); + + static lldb_private::ConstString GetPluginNameStatic(); + + static lldb::InstrumentationRuntimeType GetTypeStatic(); + + lldb_private::ConstString GetPluginName() override { + return GetPluginNameStatic(); + } + + virtual lldb::InstrumentationRuntimeType GetType() { return GetTypeStatic(); } + + uint32_t GetPluginVersion() override { return 1; } + + lldb::ThreadCollectionSP + GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info) override; + +private: + InstrumentationRuntimeUBSan(const lldb::ProcessSP &process_sp) + : lldb_private::InstrumentationRuntime(process_sp) {} + + const RegularExpression &GetPatternForRuntimeLibrary() override; + + bool CheckIfRuntimeIsValid(const lldb::ModuleSP module_sp) override; + + void Activate() override; + + void Deactivate(); + + static bool NotifyBreakpointHit(void *baton, + StoppointCallbackContext *context, + lldb::user_id_t break_id, + lldb::user_id_t break_loc_id); + + StructuredData::ObjectSP RetrieveReportData(ExecutionContextRef exe_ctx_ref); +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_UBSAN_INSTRUMENTATIONRUNTIMEUBSAN_H diff --git a/gnu/llvm/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp b/gnu/llvm/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp index fff44123539..cbeef600ba9 100644 --- a/gnu/llvm/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp +++ b/gnu/llvm/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp @@ -1,4 +1,4 @@ -//===-- JITLoaderGDB.cpp ----------------------------------------*- C++ -*-===// +//===-- JITLoaderGDB.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -32,6 +32,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(JITLoaderGDB) + // Debug Interface Structures enum jit_actions_t { JIT_NOACTION = 0, JIT_REGISTER_FN, JIT_UNREGISTER_FN }; @@ -132,9 +134,9 @@ bool ReadJITEntry(const addr_t from_addr, Process *process, DataExtractor extractor(data.GetBytes(), data.GetByteSize(), process->GetByteOrder(), sizeof(ptr_t)); lldb::offset_t offset = 0; - entry->next_entry = extractor.GetPointer(&offset); - entry->prev_entry = extractor.GetPointer(&offset); - entry->symfile_addr = extractor.GetPointer(&offset); + entry->next_entry = extractor.GetAddress(&offset); + entry->prev_entry = extractor.GetAddress(&offset); + entry->symfile_addr = extractor.GetAddress(&offset); offset = llvm::alignTo(offset, uint64_align_bytes); entry->symfile_size = extractor.GetU64(&offset); diff --git a/gnu/llvm/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.h b/gnu/llvm/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.h index 2a2537c3edd..42377f43529 100644 --- a/gnu/llvm/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.h +++ b/gnu/llvm/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_JITLoaderGDB_h_ -#define liblldb_JITLoaderGDB_h_ +#ifndef LLDB_SOURCE_PLUGINS_JITLOADER_GDB_JITLOADERGDB_H +#define LLDB_SOURCE_PLUGINS_JITLOADER_GDB_JITLOADERGDB_H #include @@ -77,4 +77,4 @@ private: lldb::addr_t m_jit_descriptor_addr; }; -#endif // liblldb_JITLoaderGDB_h_ +#endif // LLDB_SOURCE_PLUGINS_JITLOADER_GDB_JITLOADERGDB_H diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp index 5cfd978774f..42f6bd9ffb7 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp @@ -1,4 +1,4 @@ -//===-- BlockPointer.cpp ----------------------------------------*- C++ -*-===// +//===-- BlockPointer.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,14 +8,14 @@ #include "BlockPointer.h" +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangASTImporter.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/Target.h" - #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" @@ -45,18 +45,24 @@ public: if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR( lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS), - std::move(err), "Failed to get scratch ClangASTContext"); + std::move(err), "Failed to get scratch TypeSystemClang"); return; } - ClangASTContext *clang_ast_context = - llvm::dyn_cast(&type_system_or_err.get()); + TypeSystemClang *clang_ast_context = + llvm::dyn_cast(&type_system_or_err.get()); if (!clang_ast_context) { return; } - ClangASTImporterSP clang_ast_importer = target_sp->GetClangASTImporter(); + std::shared_ptr clang_ast_importer; + auto *state = target_sp->GetPersistentExpressionStateForLanguage( + lldb::eLanguageTypeC_plus_plus); + if (state) { + auto *persistent_vars = llvm::cast(state); + clang_ast_importer = persistent_vars->GetClangASTImporter(); + } if (!clang_ast_importer) { return; diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.h b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.h index 624c17a6a6a..23f3f7b34b4 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.h +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_BlockPointer_h_ -#define liblldb_BlockPointer_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_BLOCKPOINTER_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_BLOCKPOINTER_H #include "lldb/lldb-forward.h" @@ -22,4 +22,4 @@ BlockPointerSyntheticFrontEndCreator(CXXSyntheticChildren *, } // namespace formatters } // namespace lldb_private -#endif // liblldb_BlockPointer_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_BLOCKPOINTER_H diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt index ea36c7ec80d..2a541a9e528 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt @@ -29,6 +29,7 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN lldbUtility lldbPluginClangCommon lldbPluginCPPRuntime + lldbPluginTypeSystemClang LINK_COMPONENTS Support diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 4385a60f586..08e43ae6b3e 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -1,4 +1,4 @@ -//===-- CPlusPlusLanguage.cpp -----------------------------------*- C++ -*-===// +//===-- CPlusPlusLanguage.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -43,6 +43,8 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; +LLDB_PLUGIN_DEFINE(CPlusPlusLanguage) + void CPlusPlusLanguage::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), "C++ Language", CreateInstance); @@ -68,7 +70,9 @@ uint32_t CPlusPlusLanguage::GetPluginVersion() { return 1; } // Static Functions Language *CPlusPlusLanguage::CreateInstance(lldb::LanguageType language) { - if (Language::LanguageIsCPlusPlus(language)) + // Use plugin for C++ but not for Objective-C++ (which has its own plugin). + if (Language::LanguageIsCPlusPlus(language) && + language != eLanguageTypeObjC_plus_plus) return new CPlusPlusLanguage(); return nullptr; } @@ -125,7 +129,7 @@ static bool IsTrivialBasename(const llvm::StringRef &basename) { return false; // Empty string or "~" if (!std::isalpha(basename[idx]) && basename[idx] != '_') - return false; // First charater (after removing the possible '~'') isn't in + return false; // First character (after removing the possible '~'') isn't in // [A-Za-z_] // Read all characters matching [A-Za-z_0-9] @@ -230,7 +234,7 @@ std::string CPlusPlusLanguage::MethodName::GetScopeQualifiedName() { if (!m_parsed) Parse(); if (m_context.empty()) - return m_basename; + return std::string(m_basename); std::string res; res += m_context; @@ -609,6 +613,15 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { "shared_ptr synthetic children", ConstString("^(std::__[[:alnum:]]+::)shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true); + + ConstString libcxx_std_unique_ptr_regex( + "^std::__[[:alnum:]]+::unique_ptr<.+>(( )?&)?$"); + AddCXXSynthetic( + cpp_category_sp, + lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator, + "unique_ptr synthetic children", libcxx_std_unique_ptr_regex, + stl_synth_flags, true); + AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, @@ -713,6 +726,10 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { "libc++ std::weak_ptr summary provider", ConstString("^std::__[[:alnum:]]+::weak_ptr<.+>(( )?&)?$"), stl_summary_flags, true); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::LibcxxUniquePointerSummaryProvider, + "libc++ std::unique_ptr summary provider", + libcxx_std_unique_ptr_regex, stl_summary_flags, true); AddCXXSynthetic( cpp_category_sp, diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h index 4ed45bc904c..89dea08a2c5 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CPlusPlusLanguage_h_ -#define liblldb_CPlusPlusLanguage_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSLANGUAGE_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSLANGUAGE_H #include #include @@ -133,4 +133,4 @@ public: } // namespace lldb_private -#endif // liblldb_CPlusPlusLanguage_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSLANGUAGE_H diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp index 932db17b964..eca36fff18f 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp @@ -1,4 +1,4 @@ -//===-- CPlusPlusNameParser.cpp ---------------------------------*- C++ -*-===// +//===-- CPlusPlusNameParser.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -329,6 +329,37 @@ bool CPlusPlusNameParser::ConsumeOperator() { } const auto &token = Peek(); + + // When clang generates debug info it adds template parameters to names. + // Since clang doesn't add a space between the name and the template parameter + // in some cases we are not generating valid C++ names e.g.: + // + // operator< + // + // In some of these cases we will not parse them correctly. This fixes the + // issue by detecting this case and inserting tok::less in place of + // tok::lessless and returning successfully that we consumed the operator. + if (token.getKind() == tok::lessless) { + // Make sure we have more tokens before attempting to look ahead one more. + if (m_next_token_index + 1 < m_tokens.size()) { + // Look ahead two tokens. + clang::Token n_token = m_tokens[m_next_token_index + 1]; + // If we find ( or < then this is indeed operator<< no need for fix. + if (n_token.getKind() != tok::l_paren && n_token.getKind() != tok::less) { + clang::Token tmp_tok; + tmp_tok.startToken(); + tmp_tok.setLength(1); + tmp_tok.setLocation(token.getLocation().getLocWithOffset(1)); + tmp_tok.setKind(tok::less); + + m_tokens[m_next_token_index] = tmp_tok; + + start_position.Remove(); + return true; + } + } + } + switch (token.getKind()) { case tok::kw_new: case tok::kw_delete: diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h index 414c3a00915..6fe6b12725b 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CPlusPlusNameParser_h_ -#define liblldb_CPlusPlusNameParser_h_ - +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSNAMEPARSER_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSNAMEPARSER_H #include "clang/Lex/Lexer.h" #include "llvm/ADT/Optional.h" @@ -174,4 +173,4 @@ private: } // namespace lldb_private -#endif // liblldb_CPlusPlusNameParser_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSNAMEPARSER_H diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp index 3ea7589d8e4..41bbd2b01a1 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp @@ -1,4 +1,4 @@ -//===-- CxxStringTypes.cpp --------------------------------------*- C++ -*-===// +//===-- CxxStringTypes.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,13 +10,13 @@ #include "llvm/Support/ConvertUTF.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/DataFormatters/StringPrinter.h" #include "lldb/DataFormatters/TypeSummary.h" #include "lldb/Host/Time.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/ProcessStructReader.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h index 35498b3b568..2713ded4592 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CxxStringTypes_h_ -#define liblldb_CxxStringTypes_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CXXSTRINGTYPES_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CXXSTRINGTYPES_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -46,4 +46,4 @@ bool WCharSummaryProvider(ValueObject &valobj, Stream &stream, } // namespace formatters } // namespace lldb_private -#endif // liblldb_CxxStringTypes_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CXXSTRINGTYPES_H diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp index ecadaef7a87..84dd09a47d8 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -1,4 +1,4 @@ -//===-- LibCxx.cpp ----------------------------------------------*- C++ -*-===// +//===-- LibCxx.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,7 +8,6 @@ #include "LibCxx.h" -#include "llvm/ADT/ScopeExit.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/FormatEntity.h" #include "lldb/Core/ValueObject.h" @@ -17,7 +16,6 @@ #include "lldb/DataFormatters/StringPrinter.h" #include "lldb/DataFormatters/TypeSummary.h" #include "lldb/DataFormatters/VectorIterator.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/ProcessStructReader.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" @@ -27,6 +25,7 @@ #include "lldb/Utility/Stream.h" #include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" using namespace lldb; using namespace lldb_private; @@ -145,6 +144,43 @@ bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider( return true; } +bool lldb_private::formatters::LibcxxUniquePointerSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { + ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); + if (!valobj_sp) + return false; + + ValueObjectSP ptr_sp( + valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true)); + if (!ptr_sp) + return false; + + ptr_sp = GetValueOfLibCXXCompressedPair(*ptr_sp); + if (!ptr_sp) + return false; + + if (ptr_sp->GetValueAsUnsigned(0) == 0) { + stream.Printf("nullptr"); + return true; + } else { + bool print_pointee = false; + Status error; + ValueObjectSP pointee_sp = ptr_sp->Dereference(error); + if (pointee_sp && error.Success()) { + if (pointee_sp->DumpPrintableRepresentation( + stream, ValueObject::eValueObjectRepresentationStyleSummary, + lldb::eFormatInvalid, + ValueObject::PrintableRepresentationSpecialCases::eDisable, + false)) + print_pointee = true; + } + if (!print_pointee) + stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0)); + } + + return true; +} + /* (lldb) fr var ibeg --raw --ptr-depth 1 (std::__1::__map_iteratorGetValueAsUnsigned(LLDB_INVALID_ADDRESS)); m_pair_ptr = nullptr; if (addr && addr != LLDB_INVALID_ADDRESS) { - ClangASTContext *ast_ctx = - llvm::dyn_cast_or_null(pair_type.GetTypeSystem()); + TypeSystemClang *ast_ctx = + llvm::dyn_cast_or_null(pair_type.GetTypeSystem()); if (!ast_ctx) return false; CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( @@ -450,6 +486,67 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator( : nullptr); } +lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd:: + LibcxxUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) + : SyntheticChildrenFrontEnd(*valobj_sp), m_compressed_pair_sp() { + if (valobj_sp) + Update(); +} + +lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd:: + ~LibcxxUniquePtrSyntheticFrontEnd() = default; + +SyntheticChildrenFrontEnd * +lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator( + CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { + return (valobj_sp ? new LibcxxUniquePtrSyntheticFrontEnd(valobj_sp) + : nullptr); +} + +size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd:: + CalculateNumChildren() { + return (m_compressed_pair_sp ? 1 : 0); +} + +lldb::ValueObjectSP +lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::GetChildAtIndex( + size_t idx) { + if (!m_compressed_pair_sp) + return lldb::ValueObjectSP(); + + if (idx != 0) + return lldb::ValueObjectSP(); + + return m_compressed_pair_sp; +} + +bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::Update() { + ValueObjectSP valobj_sp = m_backend.GetSP(); + if (!valobj_sp) + return false; + + ValueObjectSP ptr_sp( + valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true)); + if (!ptr_sp) + return false; + + m_compressed_pair_sp = GetValueOfLibCXXCompressedPair(*ptr_sp); + + return false; +} + +bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd:: + MightHaveChildren() { + return true; +} + +size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd:: + GetIndexOfChildWithName(ConstString name) { + if (name == "__value_") + return 0; + return UINT32_MAX; +} + bool lldb_private::formatters::LibcxxContainerSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { if (valobj.IsPointerType()) { @@ -469,22 +566,20 @@ enum LibcxxStringLayoutMode { eLibcxxStringLayoutModeInvalid = 0xffff }; -// this function abstracts away the layout and mode details of a libc++ string -// and returns the address of the data and the size ready for callers to -// consume -static bool ExtractLibcxxStringInfo(ValueObject &valobj, - ValueObjectSP &location_sp, - uint64_t &size) { +/// Determine the size in bytes of \p valobj (a libc++ std::string object) and +/// extract its data payload. Return the size + payload pair. +static llvm::Optional> +ExtractLibcxxStringInfo(ValueObject &valobj) { ValueObjectSP D(valobj.GetChildAtIndexPath({0, 0, 0, 0})); if (!D) - return false; + return {}; ValueObjectSP layout_decider( D->GetChildAtIndexPath(llvm::ArrayRef({0, 0}))); // this child should exist if (!layout_decider) - return false; + return {}; ConstString g_data_name("__data_"); ConstString g_size_name("__size_"); @@ -498,13 +593,13 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj, if (layout == eLibcxxStringLayoutModeDSC) { ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 1, 0})); if (!size_mode) - return false; + return {}; if (size_mode->GetName() != g_size_name) { // we are hitting the padding structure, move along size_mode = D->GetChildAtIndexPath({1, 1, 1}); if (!size_mode) - return false; + return {}; } size_mode_value = (size_mode->GetValueAsUnsigned(0)); @@ -512,7 +607,7 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj, } else { ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 0, 0})); if (!size_mode) - return false; + return {}; size_mode_value = (size_mode->GetValueAsUnsigned(0)); short_mode = ((size_mode_value & 1) == 0); @@ -521,36 +616,58 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj, if (short_mode) { ValueObjectSP s(D->GetChildAtIndex(1, true)); if (!s) - return false; - location_sp = s->GetChildAtIndex( + return {}; + ValueObjectSP location_sp = s->GetChildAtIndex( (layout == eLibcxxStringLayoutModeDSC) ? 0 : 1, true); - size = (layout == eLibcxxStringLayoutModeDSC) - ? size_mode_value - : ((size_mode_value >> 1) % 256); - return (location_sp.get() != nullptr); - } else { - ValueObjectSP l(D->GetChildAtIndex(0, true)); - if (!l) - return false; - // we can use the layout_decider object as the data pointer - location_sp = (layout == eLibcxxStringLayoutModeDSC) - ? layout_decider - : l->GetChildAtIndex(2, true); - ValueObjectSP size_vo(l->GetChildAtIndex(1, true)); - if (!size_vo || !location_sp) - return false; - size = size_vo->GetValueAsUnsigned(0); - return true; + const uint64_t size = (layout == eLibcxxStringLayoutModeDSC) + ? size_mode_value + : ((size_mode_value >> 1) % 256); + + // When the small-string optimization takes place, the data must fit in the + // inline string buffer (23 bytes on x86_64/Darwin). If it doesn't, it's + // likely that the string isn't initialized and we're reading garbage. + ExecutionContext exe_ctx(location_sp->GetExecutionContextRef()); + const llvm::Optional max_bytes = + location_sp->GetCompilerType().GetByteSize( + exe_ctx.GetBestExecutionContextScope()); + if (!max_bytes || size > *max_bytes || !location_sp) + return {}; + + return std::make_pair(size, location_sp); } + + ValueObjectSP l(D->GetChildAtIndex(0, true)); + if (!l) + return {}; + // we can use the layout_decider object as the data pointer + ValueObjectSP location_sp = (layout == eLibcxxStringLayoutModeDSC) + ? layout_decider + : l->GetChildAtIndex(2, true); + ValueObjectSP size_vo(l->GetChildAtIndex(1, true)); + const unsigned capacity_index = + (layout == eLibcxxStringLayoutModeDSC) ? 2 : 0; + ValueObjectSP capacity_vo(l->GetChildAtIndex(capacity_index, true)); + if (!size_vo || !location_sp || !capacity_vo) + return {}; + const uint64_t size = size_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET); + const uint64_t capacity = + capacity_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET); + if (size == LLDB_INVALID_OFFSET || capacity == LLDB_INVALID_OFFSET || + capacity < size) + return {}; + return std::make_pair(size, location_sp); } bool lldb_private::formatters::LibcxxWStringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options) { - uint64_t size = 0; - ValueObjectSP location_sp; - if (!ExtractLibcxxStringInfo(valobj, location_sp, size)) + auto string_info = ExtractLibcxxStringInfo(valobj); + if (!string_info) return false; + uint64_t size; + ValueObjectSP location_sp; + std::tie(size, location_sp) = *string_info; + if (size == 0) { stream.Printf("L\"\""); return true; @@ -558,10 +675,8 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider( if (!location_sp) return false; - DataExtractor extractor; StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); - if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) { const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary(); if (size > max_size) { @@ -569,11 +684,15 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider( options.SetIsTruncated(true); } } - location_sp->GetPointeeData(extractor, 0, size); + + DataExtractor extractor; + const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size); + if (bytes_read < size) + return false; // std::wstring::size() is measured in 'characters', not bytes - ClangASTContext *ast_context = - ClangASTContext::GetScratch(*valobj.GetTargetSP()); + TypeSystemClang *ast_context = + TypeSystemClang::GetScratch(*valobj.GetTargetSP()); if (!ast_context) return false; @@ -591,40 +710,35 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider( switch (*wchar_t_size) { case 1: - StringPrinter::ReadBufferAndDumpToStream< + return StringPrinter::ReadBufferAndDumpToStream< lldb_private::formatters::StringPrinter::StringElementType::UTF8>( options); break; case 2: - lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream< + return StringPrinter::ReadBufferAndDumpToStream< lldb_private::formatters::StringPrinter::StringElementType::UTF16>( options); break; case 4: - lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream< + return StringPrinter::ReadBufferAndDumpToStream< lldb_private::formatters::StringPrinter::StringElementType::UTF32>( options); - break; - - default: - stream.Printf("size for wchar_t is not valid"); - return true; } - - return true; + return false; } template bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options, - std::string prefix_token = "") { - uint64_t size = 0; - ValueObjectSP location_sp; - - if (!ExtractLibcxxStringInfo(valobj, location_sp, size)) + std::string prefix_token) { + auto string_info = ExtractLibcxxStringInfo(valobj); + if (!string_info) return false; + uint64_t size; + ValueObjectSP location_sp; + std::tie(size, location_sp) = *string_info; if (size == 0) { stream.Printf("\"\""); @@ -636,7 +750,6 @@ bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream, StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); - DataExtractor extractor; if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) { const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary(); if (size > max_size) { @@ -644,41 +757,55 @@ bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream, options.SetIsTruncated(true); } } - location_sp->GetPointeeData(extractor, 0, size); + + DataExtractor extractor; + const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size); + if (bytes_read < size) + return false; options.SetData(extractor); options.SetStream(&stream); - if (prefix_token.empty()) options.SetPrefixToken(nullptr); else options.SetPrefixToken(prefix_token); - options.SetQuote('"'); options.SetSourceSize(size); options.SetBinaryZeroIsTerminator(false); - StringPrinter::ReadBufferAndDumpToStream(options); + return StringPrinter::ReadBufferAndDumpToStream(options); +} +template +static bool formatStringImpl(ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &summary_options, + std::string prefix_token) { + StreamString scratch_stream; + const bool success = LibcxxStringSummaryProvider( + valobj, scratch_stream, summary_options, prefix_token); + if (success) + stream << scratch_stream.GetData(); + else + stream << "Summary Unavailable"; return true; } bool lldb_private::formatters::LibcxxStringSummaryProviderASCII( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options) { - return LibcxxStringSummaryProvider( - valobj, stream, summary_options); + return formatStringImpl( + valobj, stream, summary_options, ""); } bool lldb_private::formatters::LibcxxStringSummaryProviderUTF16( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options) { - return LibcxxStringSummaryProvider( + return formatStringImpl( valobj, stream, summary_options, "u"); } bool lldb_private::formatters::LibcxxStringSummaryProviderUTF32( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options) { - return LibcxxStringSummaryProvider( + return formatStringImpl( valobj, stream, summary_options, "U"); } diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h index 214f5512e4a..ea5a7c17817 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_LibCxx_h_ -#define liblldb_LibCxx_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXX_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXX_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -43,6 +43,10 @@ bool LibcxxSmartPointerSummaryProvider( const TypeSummaryOptions &options); // libc++ std::shared_ptr<> and std::weak_ptr<> +// libc++ std::unique_ptr<> +bool LibcxxUniquePointerSummaryProvider(ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); + bool LibcxxFunctionSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); // libc++ std::function<> @@ -107,6 +111,26 @@ private: lldb::ByteOrder m_byte_order; }; +class LibcxxUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: + LibcxxUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + + size_t CalculateNumChildren() override; + + lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + + bool Update() override; + + bool MightHaveChildren() override; + + size_t GetIndexOfChildWithName(ConstString name) override; + + ~LibcxxUniquePtrSyntheticFrontEnd() override; + +private: + lldb::ValueObjectSP m_compressed_pair_sp; +}; + SyntheticChildrenFrontEnd * LibcxxBitsetSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); @@ -115,6 +139,10 @@ SyntheticChildrenFrontEnd * LibcxxSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); +SyntheticChildrenFrontEnd * +LibcxxUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *, + lldb::ValueObjectSP); + SyntheticChildrenFrontEnd * LibcxxStdVectorSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); @@ -156,4 +184,4 @@ LibcxxVariantFrontEndCreator(CXXSyntheticChildren *, } // namespace formatters } // namespace lldb_private -#endif // liblldb_LibCxx_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXX_H diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp index b4e7a1703e4..45d4322e93d 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp @@ -1,5 +1,4 @@ -//===-- LibCxxAtomic.cpp ------------------------------------------*- C++ -//-*-===// +//===-- LibCxxAtomic.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "LibCxxAtomic.h" +#include "lldb/DataFormatters/FormattersHelpers.h" using namespace lldb; using namespace lldb_private; @@ -101,8 +101,6 @@ public: size_t GetIndexOfChildWithName(ConstString name) override; - lldb::ValueObjectSP GetSyntheticValue() override; - private: ValueObject *m_real_child; }; @@ -128,26 +126,20 @@ bool lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd:: size_t lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd:: CalculateNumChildren() { - return m_real_child ? m_real_child->GetNumChildren() : 0; + return m_real_child ? 1 : 0; } lldb::ValueObjectSP lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetChildAtIndex( size_t idx) { - return m_real_child ? m_real_child->GetChildAtIndex(idx, true) : nullptr; + if (idx == 0) + return m_real_child->GetSP()->Clone(ConstString("Value")); + return nullptr; } size_t lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd:: GetIndexOfChildWithName(ConstString name) { - return m_real_child ? m_real_child->GetIndexOfChildWithName(name) - : UINT32_MAX; -} - -lldb::ValueObjectSP lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd:: - GetSyntheticValue() { - if (m_real_child && m_real_child->CanProvideValue()) - return m_real_child->GetSP(); - return nullptr; + return formatters::ExtractIndexFromString(name.GetCString()); } SyntheticChildrenFrontEnd * diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h index 8be833dd82f..6fcceb645c7 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_LibCxxAtomic_h_ -#define liblldb_LibCxxAtomic_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXXATOMIC_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXXATOMIC_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -30,4 +30,4 @@ LibcxxAtomicSyntheticFrontEndCreator(CXXSyntheticChildren *, } // namespace formatters } // namespace lldb_private -#endif // liblldb_LibCxxAtomic_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXXATOMIC_H diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp index 78c453cd1b3..6de4637a6a4 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxBitset.cpp ----------------------------------------*- C++ -*-===// +//===-- LibCxxBitset.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// #include "LibCxx.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Target.h" using namespace lldb; diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp index 79c7434f617..65e88d114fc 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxInitializerList.cpp -------------------------------*- C++ -*-===// +//===-- LibCxxInitializerList.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp index f5281f2ce53..0d5ae16a0b2 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxList.cpp ------------------------------------------*- C++ -*-===// +//===-- LibCxxList.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,10 +8,10 @@ #include "LibCxx.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Endian.h" @@ -290,15 +290,6 @@ ValueObjectSP ForwardListFrontEnd::GetChildAtIndex(size_t idx) { m_element_type); } -static ValueObjectSP GetValueOfCompressedPair(ValueObject &pair) { - ValueObjectSP value = pair.GetChildMemberWithName(ConstString("__value_"), true); - if (! value) { - // pre-r300140 member name - value = pair.GetChildMemberWithName(ConstString("__first_"), true); - } - return value; -} - bool ForwardListFrontEnd::Update() { AbstractListFrontEnd::Update(); @@ -311,7 +302,7 @@ bool ForwardListFrontEnd::Update() { m_backend.GetChildMemberWithName(ConstString("__before_begin_"), true)); if (!impl_sp) return false; - impl_sp = GetValueOfCompressedPair(*impl_sp); + impl_sp = GetValueOfLibCXXCompressedPair(*impl_sp); if (!impl_sp) return false; m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get(); @@ -332,7 +323,7 @@ size_t ListFrontEnd::CalculateNumChildren() { ValueObjectSP size_alloc( m_backend.GetChildMemberWithName(ConstString("__size_alloc_"), true)); if (size_alloc) { - ValueObjectSP value = GetValueOfCompressedPair(*size_alloc); + ValueObjectSP value = GetValueOfLibCXXCompressedPair(*size_alloc); if (value) { m_count = value->GetValueAsUnsigned(UINT32_MAX); } diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index f6d8d4d9a7e..64a199e24e4 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxMap.cpp -------------------------------------------*- C++ -*-===// +//===-- LibCxxMap.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,10 +8,10 @@ #include "LibCxx.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Endian.h" @@ -298,8 +298,8 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( UINT32_MAX) { m_skip_size = bit_offset / 8u; } else { - ClangASTContext *ast_ctx = - llvm::dyn_cast_or_null(node_type.GetTypeSystem()); + TypeSystemClang *ast_ctx = + llvm::dyn_cast_or_null(node_type.GetTypeSystem()); if (!ast_ctx) return; CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp index b1ad171d0b0..c0c81963285 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxOptional.cpp --------------------------------------*- C++ -*-===// +//===-- LibCxxOptional.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -26,11 +26,12 @@ public: bool MightHaveChildren() override { return true; } bool Update() override; - size_t CalculateNumChildren() override { return m_size; } + size_t CalculateNumChildren() override { return m_has_value ? 1U : 0U; } ValueObjectSP GetChildAtIndex(size_t idx) override; private: - size_t m_size = 0; + /// True iff the option contains a value. + bool m_has_value = false; }; } // namespace @@ -44,13 +45,13 @@ bool OptionalFrontEnd::Update() { // __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); + m_has_value = engaged_sp->GetValueAsUnsigned(0) == 1; return false; } ValueObjectSP OptionalFrontEnd::GetChildAtIndex(size_t idx) { - if (idx >= m_size) + if (!m_has_value) return ValueObjectSP(); // __val_ contains the underlying value of an optional if it has one. @@ -71,7 +72,7 @@ ValueObjectSP OptionalFrontEnd::GetChildAtIndex(size_t idx) { if (!holder_type) return ValueObjectSP(); - return val_sp->Clone(ConstString(llvm::formatv("Value").str())); + return val_sp->Clone(ConstString("Value")); } SyntheticChildrenFrontEnd * diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp index 2f06d684f95..616ffdca107 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxQueue.cpp -----------------------------------------*- C++ -*-===// +//===-- LibCxxQueue.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp index 45294e25f0f..a113fe98c6b 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxTuple.cpp -----------------------------------------*- C++ -*-===// +//===-- LibCxxTuple.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp index b2c38c915c8..3a441973fc7 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxUnorderedMap.cpp ----------------------------------*- C++ -*-===// +//===-- LibCxxUnorderedMap.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,10 +8,10 @@ #include "LibCxx.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Endian.h" diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp index 62945bd3ce8..951bf2896fb 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxVariant.cpp --------------------------------------*- C++ -*-===// +//===-- LibCxxVariant.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -60,10 +60,10 @@ using namespace lldb_private; 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 }; +// 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) { @@ -71,14 +71,14 @@ LibcxxVariantGetIndexValidity(ValueObjectSP &impl_sp) { impl_sp->GetChildMemberWithName(ConstString("__index"), true)); if (!index_sp) - return LibcxxVariantIndexValidity::INVALID; + return LibcxxVariantIndexValidity::Invalid; int64_t index_value = index_sp->GetValueAsSigned(0); if (index_value == -1) - return LibcxxVariantIndexValidity::NPOS; + return LibcxxVariantIndexValidity::NPos; - return LibcxxVariantIndexValidity::VALID; + return LibcxxVariantIndexValidity::Valid; } llvm::Optional LibcxxVariantIndexValue(ValueObjectSP &impl_sp) { @@ -129,10 +129,10 @@ bool LibcxxVariantSummaryProvider(ValueObject &valobj, Stream &stream, LibcxxVariantIndexValidity validity = LibcxxVariantGetIndexValidity(impl_sp); - if (validity == LibcxxVariantIndexValidity::INVALID) + if (validity == LibcxxVariantIndexValidity::Invalid) return false; - if (validity == LibcxxVariantIndexValidity::NPOS) { + if (validity == LibcxxVariantIndexValidity::NPos) { stream.Printf(" No Value"); return true; } @@ -159,7 +159,7 @@ bool LibcxxVariantSummaryProvider(ValueObject &valobj, Stream &stream, if (!template_type) return false; - stream.Printf(" Active Type = %s ", template_type.GetTypeName().GetCString()); + stream << " Active Type = " << template_type.GetDisplayTypeName() << " "; return true; } @@ -196,10 +196,10 @@ bool VariantFrontEnd::Update() { LibcxxVariantIndexValidity validity = LibcxxVariantGetIndexValidity(impl_sp); - if (validity == LibcxxVariantIndexValidity::INVALID) + if (validity == LibcxxVariantIndexValidity::Invalid) return false; - if (validity == LibcxxVariantIndexValidity::NPOS) + if (validity == LibcxxVariantIndexValidity::NPos) return true; m_size = 1; @@ -242,7 +242,7 @@ ValueObjectSP VariantFrontEnd::GetChildAtIndex(size_t idx) { if (!head_value) return ValueObjectSP(); - return head_value->Clone(ConstString(ConstString("Value").AsCString())); + return head_value->Clone(ConstString("Value")); } SyntheticChildrenFrontEnd * diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h index 65db5aeaa99..b4c27ccb9d7 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_LibCxxVariant_h_ -#define liblldb_LibCxxVariant_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXXVARIANT_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXXVARIANT_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -27,4 +27,4 @@ SyntheticChildrenFrontEnd *LibcxxVariantFrontEndCreator(CXXSyntheticChildren *, } // namespace formatters } // namespace lldb_private -#endif // liblldb_LibCxxVariant_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXXVARIANT_H diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp index bcd7442bc66..43f76b0df81 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxVector.cpp ----------------------------------------*- C++ -*-===// +//===-- LibCxxVector.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp index 0e0f6663c92..b4af67ecee0 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -1,4 +1,4 @@ -//===-- LibStdcpp.cpp -------------------------------------------*- C++ -*-===// +//===-- LibStdcpp.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,11 +8,11 @@ #include "LibStdcpp.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/StringPrinter.h" #include "lldb/DataFormatters/VectorIterator.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Endian.h" @@ -259,6 +259,7 @@ bool lldb_private::formatters::LibStdcppStringSummaryProvider( if (error.Fail()) return false; options.SetSourceSize(size_of_data); + options.SetHasSourceSize(true); if (!StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::UTF8>(options)) { @@ -319,6 +320,7 @@ bool lldb_private::formatters::LibStdcppWStringSummaryProvider( if (error.Fail()) return false; options.SetSourceSize(size_of_data); + options.SetHasSourceSize(true); options.SetPrefixToken("L"); switch (wchar_size) { diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h index e7f88d667c1..9e41aa0ffc0 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_LibStdCpp_h_ -#define liblldb_LibStdCpp_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBSTDCPP_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBSTDCPP_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -56,4 +56,4 @@ LibStdcppUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *, } // namespace formatters } // namespace lldb_private -#endif // liblldb_LibStdCpp_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBSTDCPP_H diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp index 0ac7b8f8e02..7ba59ff9d1a 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp @@ -1,4 +1,4 @@ -//===-- LibStdcppTuple.cpp --------------------------------------*- C++ -*-===// +//===-- LibStdcppTuple.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp index cceb511cdc4..0b34b4e2fc8 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp @@ -1,4 +1,4 @@ -//===-- LibStdcppUniquePointer.cpp ------------------------------*- C++ -*-===// +//===-- LibStdcppUniquePointer.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp index 248c51acea4..b24bcc1344e 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp @@ -1,4 +1,4 @@ -//===-- MSVCUndecoratedNameParser.cpp ---------------------------*- C++ -*-===// +//===-- MSVCUndecoratedNameParser.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h index 6e20877cae1..e5b60a0a1d5 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h +++ b/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_MSVCUndecoratedNameParser_h_ -#define liblldb_MSVCUndecoratedNameParser_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_MSVCUNDECORATEDNAMEPARSER_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_MSVCUNDECORATEDNAMEPARSER_H #include diff --git a/gnu/llvm/lldb/source/Plugins/Language/ClangCommon/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Language/ClangCommon/CMakeLists.txt index 854320dd312..980d788afc7 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ClangCommon/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/Language/ClangCommon/CMakeLists.txt @@ -1,4 +1,4 @@ -add_lldb_library(lldbPluginClangCommon PLUGIN +add_lldb_library(lldbPluginClangCommon ClangHighlighter.cpp LINK_LIBS diff --git a/gnu/llvm/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp b/gnu/llvm/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp index 3e77b164673..aaf578c6f72 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp @@ -1,4 +1,4 @@ -//===-- ClangHighlighter.cpp ------------------------------------*- C++ -*-===// +//===-- ClangHighlighter.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,6 +13,7 @@ #include "lldb/Utility/AnsiTerminal.h" #include "lldb/Utility/StreamString.h" +#include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" #include "llvm/ADT/StringSet.h" diff --git a/gnu/llvm/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.h b/gnu/llvm/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.h index f459f942469..5257c728ca5 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.h +++ b/gnu/llvm/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ClangHighlighter_h_ -#define liblldb_ClangHighlighter_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CLANGCOMMON_CLANGHIGHLIGHTER_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CLANGCOMMON_CLANGHIGHLIGHTER_H #include "lldb/Utility/Stream.h" #include "llvm/ADT/StringSet.h" @@ -34,4 +34,4 @@ public: } // namespace lldb_private -#endif // liblldb_ClangHighlighter_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CLANGCOMMON_CLANGHIGHLIGHTER_H diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/CF.cpp b/gnu/llvm/lldb/source/Plugins/Language/ObjC/CF.cpp index 5bca260616e..2610468b17f 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/CF.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/CF.cpp @@ -1,5 +1,4 @@ -//===-- CF.cpp ----------------------------------------------------*- C++ -//-*-===// +//===-- CF.cpp ------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,10 +8,10 @@ #include "CF.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Language.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" @@ -30,7 +29,7 @@ using namespace lldb_private::formatters; bool lldb_private::formatters::CFAbsoluteTimeSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { time_t epoch = GetOSXEpoch(); - epoch = epoch + (time_t)valobj.GetValueAsUnsigned(0); + epoch = epoch + (time_t)valobj.GetValueAsSigned(0); tm *tm_date = localtime(&epoch); if (!tm_date) return false; diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/CF.h b/gnu/llvm/lldb/source/Plugins/Language/ObjC/CF.h index 2abb56d407e..6165e1c235b 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/CF.h +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/CF.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CF_h_ -#define liblldb_CF_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_CF_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_CF_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -29,4 +29,4 @@ bool CFAbsoluteTimeSummaryProvider(ValueObject &valobj, Stream &stream, } // namespace formatters } // namespace lldb_private -#endif // liblldb_CF_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_CF_H diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/CFBasicHash.cpp b/gnu/llvm/lldb/source/Plugins/Language/ObjC/CFBasicHash.cpp new file mode 100644 index 00000000000..42cda0146f2 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/CFBasicHash.cpp @@ -0,0 +1,114 @@ +#include "CFBasicHash.h" + +#include "lldb/Utility/Endian.h" + +using namespace lldb; +using namespace lldb_private; + +bool CFBasicHash::IsValid() const { + if (m_address != LLDB_INVALID_ADDRESS) { + if (m_ptr_size == 4 && m_ht_32) + return true; + else if (m_ptr_size == 8 && m_ht_64) + return true; + else + return false; + } + return false; +} + +bool CFBasicHash::Update(addr_t addr, ExecutionContextRef exe_ctx_rf) { + if (addr == LLDB_INVALID_ADDRESS || !addr) + return false; + + m_address = addr; + m_exe_ctx_ref = exe_ctx_rf; + m_ptr_size = + m_exe_ctx_ref.GetTargetSP()->GetArchitecture().GetAddressByteSize(); + m_byte_order = m_exe_ctx_ref.GetTargetSP()->GetArchitecture().GetByteOrder(); + + if (m_ptr_size == 4) + return UpdateFor(m_ht_32); + else if (m_ptr_size == 8) + return UpdateFor(m_ht_64); + return false; + + llvm_unreachable( + "Unsupported architecture. Only 32bits and 64bits supported."); +} + +template +bool CFBasicHash::UpdateFor(std::unique_ptr<__CFBasicHash> &m_ht) { + if (m_byte_order != endian::InlHostByteOrder()) + return false; + + Status error; + Target *target = m_exe_ctx_ref.GetTargetSP().get(); + addr_t addr = m_address.GetLoadAddress(target); + size_t size = sizeof(typename __CFBasicHash::RuntimeBase) + + sizeof(typename __CFBasicHash::Bits); + + m_ht = std::make_unique<__CFBasicHash>(); + m_exe_ctx_ref.GetProcessSP()->ReadMemory(addr, m_ht.get(), + size, error); + if (error.Fail()) + return false; + + m_mutable = !(m_ht->base.cfinfoa & (1 << 6)); + m_multi = m_ht->bits.counts_offset; + m_type = static_cast(m_ht->bits.keys_offset); + addr_t ptr_offset = addr + size; + size_t ptr_count = GetPointerCount(); + size = ptr_count * sizeof(T); + + m_exe_ctx_ref.GetProcessSP()->ReadMemory(ptr_offset, m_ht->pointers, size, + error); + + if (error.Fail()) { + m_ht = nullptr; + return false; + } + + return true; +} + +size_t CFBasicHash::GetCount() const { + if (!IsValid()) + return 0; + + if (!m_multi) + return (m_ptr_size == 4) ? m_ht_32->bits.used_buckets + : m_ht_64->bits.used_buckets; + + // FIXME: Add support for multi + return 0; +} + +size_t CFBasicHash::GetPointerCount() const { + if (!IsValid()) + return 0; + + if (m_multi) + return 3; // Bits::counts_offset; + return (m_type == HashType::dict) + 1; +} + +addr_t CFBasicHash::GetKeyPointer() const { + if (!IsValid()) + return LLDB_INVALID_ADDRESS; + + if (m_ptr_size == 4) + return m_ht_32->pointers[m_ht_32->bits.keys_offset]; + + return m_ht_64->pointers[m_ht_64->bits.keys_offset]; +} + +addr_t CFBasicHash::GetValuePointer() const { + if (!IsValid()) + return LLDB_INVALID_ADDRESS; + + if (m_ptr_size == 4) + return m_ht_32->pointers[0]; + + return m_ht_64->pointers[0]; +} diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/CFBasicHash.h b/gnu/llvm/lldb/source/Plugins/Language/ObjC/CFBasicHash.h new file mode 100644 index 00000000000..fd30f5f7845 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/CFBasicHash.h @@ -0,0 +1,76 @@ +//===-- CFBasicHash.h -------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_CFBASICHASH_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_CFBASICHASH_H + +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" + +namespace lldb_private { + +class CFBasicHash { +public: + enum class HashType { set = 0, dict }; + + CFBasicHash() = default; + ~CFBasicHash() = default; + + bool Update(lldb::addr_t addr, ExecutionContextRef exe_ctx_rf); + + bool IsValid() const; + + bool IsMutable() const { return m_mutable; }; + bool IsMultiVariant() const { return m_multi; } + HashType GetType() const { return m_type; } + + size_t GetCount() const; + lldb::addr_t GetKeyPointer() const; + lldb::addr_t GetValuePointer() const; + +private: + template struct __CFBasicHash { + struct RuntimeBase { + T cfisa; + T cfinfoa; + } base; + + struct Bits { + uint16_t __reserved0; + uint16_t __reserved1 : 2; + uint16_t keys_offset : 1; + uint16_t counts_offset : 2; + uint16_t counts_width : 2; + uint16_t __reserved2 : 9; + uint32_t used_buckets; // number of used buckets + uint64_t deleted : 16; // number of elements deleted + uint64_t num_buckets_idx : 8; // index to number of buckets + uint64_t __reserved3 : 40; + uint64_t __reserved4; + } bits; + + T pointers[3]; + }; + template bool UpdateFor(std::unique_ptr<__CFBasicHash> &m_ht); + + size_t GetPointerCount() const; + + uint32_t m_ptr_size = UINT32_MAX; + lldb::ByteOrder m_byte_order = lldb::eByteOrderInvalid; + Address m_address = LLDB_INVALID_ADDRESS; + std::unique_ptr<__CFBasicHash> m_ht_32 = nullptr; + std::unique_ptr<__CFBasicHash> m_ht_64 = nullptr; + ExecutionContextRef m_exe_ctx_ref; + bool m_mutable = true; + bool m_multi = false; + HashType m_type; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_CFBASICHASH_H diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Language/ObjC/CMakeLists.txt index ebb96c29908..c998d5455de 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/CMakeLists.txt @@ -11,6 +11,7 @@ endif () add_lldb_library(lldbPluginObjCLanguage PLUGIN ObjCLanguage.cpp CF.cpp + CFBasicHash.cpp Cocoa.cpp CoreMedia.cpp NSArray.cpp @@ -31,6 +32,7 @@ add_lldb_library(lldbPluginObjCLanguage PLUGIN lldbUtility lldbPluginAppleObjCRuntime lldbPluginClangCommon + lldbPluginTypeSystemClang CLANG_LIBS clangAST diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/Cocoa.cpp b/gnu/llvm/lldb/source/Plugins/Language/ObjC/Cocoa.cpp index 8a81abbaedb..648fc4adf24 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/Cocoa.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/Cocoa.cpp @@ -1,4 +1,4 @@ -//===-- Cocoa.cpp -----------------------------------------------*- C++ -*-===// +//===-- Cocoa.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,6 +8,7 @@ #include "Cocoa.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" @@ -15,7 +16,6 @@ #include "lldb/DataFormatters/StringPrinter.h" #include "lldb/DataFormatters/TypeSummary.h" #include "lldb/Host/Time.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Language.h" #include "lldb/Target/Process.h" #include "lldb/Target/ProcessStructReader.h" @@ -818,13 +818,14 @@ bool lldb_private::formatters::NSDateSummaryProvider( static const ConstString g___NSDate("__NSDate"); static const ConstString g___NSTaggedDate("__NSTaggedDate"); static const ConstString g_NSCalendarDate("NSCalendarDate"); + static const ConstString g_NSConstantDate("NSConstantDate"); 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)) { + (class_name == g___NSTaggedDate) || (class_name == g_NSConstantDate)) { 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)); @@ -850,8 +851,14 @@ bool lldb_private::formatters::NSDateSummaryProvider( } else return false; - if (date_value == -63114076800) { - stream.Printf("0001-12-30 00:00:00 +0000"); + // FIXME: It seems old dates are not formatted according to NSDate's calendar + // so we hardcode distantPast's value so that it looks like LLDB is doing + // the right thing. + + // The relative time in seconds from Cocoa Epoch to [NSDate distantPast]. + const double RelSecondsFromCocoaEpochToNSDateDistantPast = -63114076800; + if (date_value == RelSecondsFromCocoaEpochToNSDateDistantPast) { + stream.Printf("0001-01-01 00:00:00 UTC"); return true; } @@ -867,7 +874,7 @@ bool lldb_private::formatters::NSDateSummaryProvider( // is generally true and POSIXly happy, but might break if a library vendor // decides to get creative time_t epoch = GetOSXEpoch(); - epoch = epoch + (time_t)date_value; + epoch = epoch + static_cast(std::floor(date_value)); tm *tm_date = gmtime(&epoch); if (!tm_date) return false; @@ -902,8 +909,7 @@ bool lldb_private::formatters::ObjCClassSummaryProvider( if (class_name.IsEmpty()) return false; - if (ConstString cs = - Mangled(class_name).GetDemangledName(lldb::eLanguageTypeUnknown)) + if (ConstString cs = Mangled(class_name).GetDemangledName()) class_name = cs; stream.Printf("%s", class_name.AsCString("")); diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/Cocoa.h b/gnu/llvm/lldb/source/Plugins/Language/ObjC/Cocoa.h index 388e6f03aa0..a195d622ce5 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/Cocoa.h +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/Cocoa.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Cocoa_h_ -#define liblldb_Cocoa_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_COCOA_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_COCOA_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -113,4 +113,4 @@ public: } // namespace formatters } // namespace lldb_private -#endif // liblldb_Cocoa_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_COCOA_H diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp b/gnu/llvm/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp index 247429da1b0..ac2f45b8354 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp @@ -1,5 +1,4 @@ -//===-- CoreMedia.cpp --------------------------------------------*- C++ -//-*-===// +//===-- CoreMedia.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/CoreMedia.h b/gnu/llvm/lldb/source/Plugins/Language/ObjC/CoreMedia.h index 79abb67b9d7..7fd8560d20e 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/CoreMedia.h +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/CoreMedia.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CoreMedia_h_ -#define liblldb_CoreMedia_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_COREMEDIA_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_COREMEDIA_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -22,4 +22,4 @@ bool CMTimeSummaryProvider(ValueObject &valobj, Stream &stream, } // namespace formatters } // namespace lldb_private -#endif // liblldb_CF_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_COREMEDIA_H diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSArray.cpp b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSArray.cpp index 73335aff2fd..8d648d8a086 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSArray.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSArray.cpp @@ -1,4 +1,4 @@ -//===-- NSArray.cpp ---------------------------------------------*- C++ -*-===// +//===-- NSArray.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,16 +7,17 @@ //===----------------------------------------------------------------------===// #include "clang/AST/ASTContext.h" +#include "clang/Basic/TargetInfo.h" #include "Cocoa.h" #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/Expression/FunctionCaller.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Language.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" @@ -97,42 +98,46 @@ private: }; namespace Foundation1010 { - struct DataDescriptor_32 { - uint32_t _used; - uint32_t _offset; - uint32_t _size : 28; - uint64_t _priv1 : 4; - uint32_t _priv2; - uint32_t _data; - }; - - struct DataDescriptor_64 { - uint64_t _used; - uint64_t _offset; - uint64_t _size : 60; - uint64_t _priv1 : 4; - uint32_t _priv2; - uint64_t _data; - }; + namespace { + struct DataDescriptor_32 { + uint32_t _used; + uint32_t _offset; + uint32_t _size : 28; + uint64_t _priv1 : 4; + uint32_t _priv2; + uint32_t _data; + }; + + struct DataDescriptor_64 { + uint64_t _used; + uint64_t _offset; + uint64_t _size : 60; + uint64_t _priv1 : 4; + uint32_t _priv2; + uint64_t _data; + }; + } using NSArrayMSyntheticFrontEnd = GenericNSArrayMSyntheticFrontEnd; } namespace Foundation1428 { - struct DataDescriptor_32 { - uint32_t _used; - uint32_t _offset; - uint32_t _size; - uint32_t _data; - }; - - struct DataDescriptor_64 { - uint64_t _used; - uint64_t _offset; - uint64_t _size; - uint64_t _data; - }; + namespace { + struct DataDescriptor_32 { + uint32_t _used; + uint32_t _offset; + uint32_t _size; + uint32_t _data; + }; + + struct DataDescriptor_64 { + uint64_t _used; + uint64_t _offset; + uint64_t _size; + uint64_t _data; + }; + } using NSArrayMSyntheticFrontEnd = GenericNSArrayMSyntheticFrontEnd; @@ -436,7 +441,7 @@ lldb_private::formatters::NSArrayMSyntheticFrontEndBase::NSArrayMSyntheticFrontE : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), m_id_type() { if (valobj_sp) { - auto *clang_ast_context = ClangASTContext::GetScratch( + auto *clang_ast_context = TypeSystemClang::GetScratch( *valobj_sp->GetExecutionContextRef().GetTargetSP()); if (clang_ast_context) m_id_type = CompilerType( @@ -528,7 +533,7 @@ lldb_private::formatters::NSArrayMSyntheticFrontEndBase::GetIndexOfChildWithName template lldb_private::formatters:: GenericNSArrayMSyntheticFrontEnd:: - ~GenericNSArrayMSyntheticFrontEnd() { + ~GenericNSArrayMSyntheticFrontEnd() { delete m_data_32; m_data_32 = nullptr; delete m_data_64; @@ -584,7 +589,7 @@ lldb_private::formatters::GenericNSArrayISyntheticFrontEnd:: if (valobj_sp) { CompilerType type = valobj_sp->GetCompilerType(); if (type) { - auto *clang_ast_context = ClangASTContext::GetScratch( + auto *clang_ast_context = TypeSystemClang::GetScratch( *valobj_sp->GetExecutionContextRef().GetTargetSP()); if (clang_ast_context) m_id_type = clang_ast_context->GetType( @@ -595,7 +600,7 @@ lldb_private::formatters::GenericNSArrayISyntheticFrontEnd:: template lldb_private::formatters::GenericNSArrayISyntheticFrontEnd:: - ~GenericNSArrayISyntheticFrontEnd() { + ~GenericNSArrayISyntheticFrontEnd() { delete m_data_32; m_data_32 = nullptr; delete m_data_64; @@ -753,7 +758,7 @@ lldb_private::formatters::NSArray1SyntheticFrontEnd::GetChildAtIndex( if (idx == 0) { auto *clang_ast_context = - ClangASTContext::GetScratch(*m_backend.GetTargetSP()); + TypeSystemClang::GetScratch(*m_backend.GetTargetSP()); if (clang_ast_context) { CompilerType id_type( clang_ast_context->GetBasicType(lldb::eBasicTypeObjCID)); diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp index ae00674c49f..3dc07678f92 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp @@ -1,4 +1,4 @@ -//===-- NSDictionary.cpp ----------------------------------------*- C++ -*-===// +//===-- NSDictionary.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,14 +10,15 @@ #include "clang/AST/DeclCXX.h" +#include "CFBasicHash.h" #include "NSDictionary.h" #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Language.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" @@ -65,7 +66,7 @@ NSDictionary_Additionals::GetAdditionalSynthetics() { static CompilerType GetLLDBNSPairType(TargetSP target_sp) { CompilerType compiler_type; - ClangASTContext *target_ast_context = ClangASTContext::GetScratch(*target_sp); + TypeSystemClang *target_ast_context = TypeSystemClang::GetScratch(*target_sp); if (target_ast_context) { ConstString g___lldb_autogen_nspair("__lldb_autogen_nspair"); @@ -76,18 +77,19 @@ static CompilerType GetLLDBNSPairType(TargetSP target_sp) { if (!compiler_type) { compiler_type = target_ast_context->CreateRecordType( - nullptr, lldb::eAccessPublic, g___lldb_autogen_nspair.GetCString(), - clang::TTK_Struct, lldb::eLanguageTypeC); + nullptr, OptionalClangModuleID(), lldb::eAccessPublic, + g___lldb_autogen_nspair.GetCString(), clang::TTK_Struct, + lldb::eLanguageTypeC); if (compiler_type) { - ClangASTContext::StartTagDeclarationDefinition(compiler_type); + TypeSystemClang::StartTagDeclarationDefinition(compiler_type); CompilerType id_compiler_type = target_ast_context->GetBasicType(eBasicTypeObjCID); - ClangASTContext::AddFieldToRecordType( + TypeSystemClang::AddFieldToRecordType( compiler_type, "key", id_compiler_type, lldb::eAccessPublic, 0); - ClangASTContext::AddFieldToRecordType( + TypeSystemClang::AddFieldToRecordType( compiler_type, "value", id_compiler_type, lldb::eAccessPublic, 0); - ClangASTContext::CompleteTagDeclarationDefinition(compiler_type); + TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type); } } } @@ -139,6 +141,37 @@ private: std::vector m_children; }; +class NSCFDictionarySyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: + NSCFDictionarySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + + size_t CalculateNumChildren() override; + + lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + + bool Update() override; + + bool MightHaveChildren() override; + + size_t GetIndexOfChildWithName(ConstString name) override; + +private: + struct DictionaryItemDescriptor { + lldb::addr_t key_ptr; + lldb::addr_t val_ptr; + lldb::ValueObjectSP valobj_sp; + }; + + ExecutionContextRef m_exe_ctx_ref; + uint8_t m_ptr_size; + lldb::ByteOrder m_order; + + CFBasicHash m_hashtable; + + CompilerType m_pair_type; + std::vector m_children; +}; + class NSDictionary1SyntheticFrontEnd : public SyntheticChildrenFrontEnd { public: NSDictionary1SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); @@ -245,64 +278,67 @@ namespace Foundation1100 { } namespace Foundation1428 { - struct DataDescriptor_32 { - uint32_t _used : 26; - uint32_t _kvo : 1; - uint32_t _size; - uint32_t _buffer; - uint64_t GetSize() { return _size; } - }; - - struct DataDescriptor_64 { - uint64_t _used : 58; - uint32_t _kvo : 1; - uint64_t _size; - uint64_t _buffer; - uint64_t GetSize() { return _size; } - }; - - - + namespace { + struct DataDescriptor_32 { + uint32_t _used : 26; + uint32_t _kvo : 1; + uint32_t _size; + uint32_t _buffer; + uint64_t GetSize() { return _size; } + }; + + struct DataDescriptor_64 { + uint64_t _used : 58; + uint32_t _kvo : 1; + uint64_t _size; + uint64_t _buffer; + uint64_t GetSize() { return _size; } + }; + } + using NSDictionaryMSyntheticFrontEnd = GenericNSDictionaryMSyntheticFrontEnd; } namespace Foundation1437 { - static const uint64_t NSDictionaryCapacities[] = { - 0, 3, 7, 13, 23, 41, 71, 127, 191, 251, 383, 631, 1087, 1723, - 2803, 4523, 7351, 11959, 19447, 31231, 50683, 81919, 132607, - 214519, 346607, 561109, 907759, 1468927, 2376191, 3845119, - 6221311, 10066421, 16287743, 26354171, 42641881, 68996069, - 111638519, 180634607, 292272623, 472907251 - }; - - static const size_t NSDictionaryNumSizeBuckets = sizeof(NSDictionaryCapacities) / sizeof(uint64_t); - - struct DataDescriptor_32 { - uint32_t _buffer; - uint32_t _muts; - uint32_t _used : 25; - uint32_t _kvo : 1; - uint32_t _szidx : 6; + namespace { + static const uint64_t NSDictionaryCapacities[] = { + 0, 3, 7, 13, 23, 41, 71, 127, 191, 251, 383, 631, 1087, 1723, + 2803, 4523, 7351, 11959, 19447, 31231, 50683, 81919, 132607, + 214519, 346607, 561109, 907759, 1468927, 2376191, 3845119, + 6221311, 10066421, 16287743, 26354171, 42641881, 68996069, + 111638519, 180634607, 292272623, 472907251 + }; + + static const size_t NSDictionaryNumSizeBuckets = + sizeof(NSDictionaryCapacities) / sizeof(uint64_t); + + struct DataDescriptor_32 { + uint32_t _buffer; + uint32_t _muts; + uint32_t _used : 25; + uint32_t _kvo : 1; + uint32_t _szidx : 6; - uint64_t GetSize() { - return (_szidx) >= NSDictionaryNumSizeBuckets ? - 0 : NSDictionaryCapacities[_szidx]; - } - }; - - struct DataDescriptor_64 { - uint64_t _buffer; - uint32_t _muts; - uint32_t _used : 25; - uint32_t _kvo : 1; - uint32_t _szidx : 6; + uint64_t GetSize() { + return (_szidx) >= NSDictionaryNumSizeBuckets ? + 0 : NSDictionaryCapacities[_szidx]; + } + }; + + struct DataDescriptor_64 { + uint64_t _buffer; + uint32_t _muts; + uint32_t _used : 25; + uint32_t _kvo : 1; + uint32_t _szidx : 6; - uint64_t GetSize() { - return (_szidx) >= NSDictionaryNumSizeBuckets ? - 0 : NSDictionaryCapacities[_szidx]; - } - }; + uint64_t GetSize() { + return (_szidx) >= NSDictionaryNumSizeBuckets ? + 0 : NSDictionaryCapacities[_szidx]; + } + }; + } using NSDictionaryMSyntheticFrontEnd = GenericNSDictionaryMSyntheticFrontEnd; @@ -375,7 +411,9 @@ bool lldb_private::formatters::NSDictionarySummaryProvider( static const ConstString g_DictionaryMImmutable("__NSDictionaryM_Immutable"); static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI"); static const ConstString g_Dictionary0("__NSDictionary0"); - static const ConstString g_DictionaryCF("__NSCFDictionary"); + static const ConstString g_DictionaryCF("__CFDictionary"); + static const ConstString g_DictionaryNSCF("__NSCFDictionary"); + static const ConstString g_DictionaryCFRef("CFDictionaryRef"); if (class_name.IsEmpty()) return false; @@ -386,9 +424,9 @@ bool lldb_private::formatters::NSDictionarySummaryProvider( ptr_size, 0, error); if (error.Fail()) return false; + value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); - } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy || - class_name == g_DictionaryCF) { + } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy) { AppleObjCRuntime *apple_runtime = llvm::dyn_cast_or_null(runtime); Status error; @@ -406,8 +444,15 @@ bool lldb_private::formatters::NSDictionarySummaryProvider( value = 1; } else if (class_name == g_Dictionary0) { value = 0; - } - else { + } else if (class_name == g_DictionaryCF || + class_name == g_DictionaryNSCF || + class_name == g_DictionaryCFRef) { + ExecutionContext exe_ctx(process_sp); + CFBasicHash cfbh; + if (!cfbh.Update(valobj_addr, exe_ctx)) + return false; + value = cfbh.GetCount(); + } else { auto &map(NSDictionary_Additionals::GetAdditionalSummaries()); for (auto &candidate : map) { if (candidate.first && candidate.first->Match(class_name)) @@ -465,6 +510,9 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator( static const ConstString g_DictionaryImmutable("__NSDictionaryM_Immutable"); static const ConstString g_DictionaryMLegacy("__NSDictionaryM_Legacy"); static const ConstString g_Dictionary0("__NSDictionary0"); + static const ConstString g_DictionaryCF("__CFDictionary"); + static const ConstString g_DictionaryNSCF("__NSCFDictionary"); + static const ConstString g_DictionaryCFRef("CFDictionaryRef"); if (class_name.IsEmpty()) return nullptr; @@ -483,6 +531,10 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator( return (new Foundation1100::NSDictionaryMSyntheticFrontEnd(valobj_sp)); } else if (class_name == g_Dictionary1) { return (new NSDictionary1SyntheticFrontEnd(valobj_sp)); + } else if (class_name == g_DictionaryCF || + class_name == g_DictionaryNSCF || + class_name == g_DictionaryCFRef) { + return (new NSCFDictionarySyntheticFrontEnd(valobj_sp)); } else { auto &map(NSDictionary_Additionals::GetAdditionalSynthetics()); for (auto &candidate : map) { @@ -640,6 +692,140 @@ lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex( return dict_item.valobj_sp; } +lldb_private::formatters::NSCFDictionarySyntheticFrontEnd:: + NSCFDictionarySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) + : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), + m_order(lldb::eByteOrderInvalid), m_hashtable(), m_pair_type() {} + +size_t lldb_private::formatters::NSCFDictionarySyntheticFrontEnd:: + GetIndexOfChildWithName(ConstString name) { + const char *item_name = name.GetCString(); + const uint32_t idx = ExtractIndexFromString(item_name); + if (idx < UINT32_MAX && idx >= CalculateNumChildren()) + return UINT32_MAX; + return idx; +} + +size_t lldb_private::formatters::NSCFDictionarySyntheticFrontEnd:: + CalculateNumChildren() { + if (!m_hashtable.IsValid()) + return 0; + return m_hashtable.GetCount(); +} + +bool lldb_private::formatters::NSCFDictionarySyntheticFrontEnd::Update() { + m_children.clear(); + ValueObjectSP valobj_sp = m_backend.GetSP(); + m_ptr_size = 0; + if (!valobj_sp) + return false; + m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); + + lldb::ProcessSP process_sp(valobj_sp->GetProcessSP()); + if (!process_sp) + return false; + m_ptr_size = process_sp->GetAddressByteSize(); + m_order = process_sp->GetByteOrder(); + return m_hashtable.Update(valobj_sp->GetValueAsUnsigned(0), m_exe_ctx_ref); +} + +bool lldb_private::formatters::NSCFDictionarySyntheticFrontEnd:: + MightHaveChildren() { + return true; +} + +lldb::ValueObjectSP +lldb_private::formatters::NSCFDictionarySyntheticFrontEnd::GetChildAtIndex( + size_t idx) { + lldb::addr_t m_keys_ptr = m_hashtable.GetKeyPointer(); + lldb::addr_t m_values_ptr = m_hashtable.GetValuePointer(); + + const uint32_t num_children = CalculateNumChildren(); + + if (idx >= num_children) + return lldb::ValueObjectSP(); + + if (m_children.empty()) { + ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP(); + if (!process_sp) + return lldb::ValueObjectSP(); + + Status error; + lldb::addr_t key_at_idx = 0, val_at_idx = 0; + + uint32_t tries = 0; + uint32_t test_idx = 0; + + // Iterate over inferior memory, reading key/value pointers by shifting each + // cursor by test_index * m_ptr_size. Returns an empty ValueObject if a read + // fails, otherwise, continue until the number of tries matches the number + // of childen. + while (tries < num_children) { + key_at_idx = m_keys_ptr + (test_idx * m_ptr_size); + val_at_idx = m_values_ptr + (test_idx * m_ptr_size); + + key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error); + if (error.Fail()) + return lldb::ValueObjectSP(); + val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error); + if (error.Fail()) + return lldb::ValueObjectSP(); + + test_idx++; + + if (!key_at_idx || !val_at_idx) + continue; + tries++; + + DictionaryItemDescriptor descriptor = {key_at_idx, val_at_idx, + lldb::ValueObjectSP()}; + + m_children.push_back(descriptor); + } + } + + if (idx >= m_children.size()) // should never happen + return lldb::ValueObjectSP(); + + DictionaryItemDescriptor &dict_item = m_children[idx]; + if (!dict_item.valobj_sp) { + if (!m_pair_type.IsValid()) { + TargetSP target_sp(m_backend.GetTargetSP()); + if (!target_sp) + return ValueObjectSP(); + m_pair_type = GetLLDBNSPairType(target_sp); + } + if (!m_pair_type.IsValid()) + return ValueObjectSP(); + + DataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0)); + + switch (m_ptr_size) { + case 0: // architecture has no clue - fail + return lldb::ValueObjectSP(); + case 4: { + uint32_t *data_ptr = reinterpret_cast(buffer_sp->GetBytes()); + *data_ptr = dict_item.key_ptr; + *(data_ptr + 1) = dict_item.val_ptr; + } break; + case 8: { + uint64_t *data_ptr = reinterpret_cast(buffer_sp->GetBytes()); + *data_ptr = dict_item.key_ptr; + *(data_ptr + 1) = dict_item.val_ptr; + } break; + default: + lldbassert(false && "pointer size is not 4 nor 8"); + } + + StreamString idx_name; + idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); + DataExtractor data(buffer_sp, m_order, m_ptr_size); + dict_item.valobj_sp = CreateValueObjectFromData(idx_name.GetString(), data, + m_exe_ctx_ref, m_pair_type); + } + return dict_item.valobj_sp; +} + lldb_private::formatters::NSDictionary1SyntheticFrontEnd:: NSDictionary1SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_pair(nullptr) {} @@ -724,7 +910,7 @@ lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd:: template lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd:: - ~GenericNSDictionaryMSyntheticFrontEnd() { + ~GenericNSDictionaryMSyntheticFrontEnd() { delete m_data_32; m_data_32 = nullptr; delete m_data_64; @@ -732,8 +918,8 @@ lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd:: } template -size_t -lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd:: GetIndexOfChildWithName(ConstString name) { +size_t lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd< + D32, D64>::GetIndexOfChildWithName(ConstString name) { const char *item_name = name.GetCString(); uint32_t idx = ExtractIndexFromString(item_name); if (idx < UINT32_MAX && idx >= CalculateNumChildren()) @@ -782,7 +968,7 @@ lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd:: } if (error.Fail()) return false; - return false; + return true; } template @@ -794,9 +980,8 @@ lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd:: template lldb::ValueObjectSP -lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd:: - GetChildAtIndex( - size_t idx) { +lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd< + D32, D64>::GetChildAtIndex(size_t idx) { lldb::addr_t m_keys_ptr; lldb::addr_t m_values_ptr; if (m_data_32) { @@ -884,7 +1069,6 @@ lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd:: return dict_item.valobj_sp; } - lldb_private::formatters::Foundation1100:: NSDictionaryMSyntheticFrontEnd:: NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSDictionary.h b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSDictionary.h index 44d56f9c2c6..57dacd6759d 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSDictionary.h +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSDictionary.h @@ -1,5 +1,4 @@ -//===-- NSDictionary.h ---------------------------------------------------*- C++ -//-*-===// +//===-- NSDictionary.h ------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_NSDictionary_h_ -#define liblldb_NSDictionary_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSDICTIONARY_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSDICTIONARY_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -91,4 +90,4 @@ public: } // namespace formatters } // namespace lldb_private -#endif // liblldb_NSDictionary_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSDICTIONARY_H diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSError.cpp b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSError.cpp index 94a97c8ad03..aa1103cb342 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSError.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSError.cpp @@ -1,4 +1,4 @@ -//===-- NSError.cpp ---------------------------------------------*- C++ -*-===// +//===-- NSError.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,10 +10,10 @@ #include "Cocoa.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/ProcessStructReader.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" @@ -87,7 +87,7 @@ bool lldb_private::formatters::NSError_SummaryProvider( ValueObjectSP domain_str_sp = ValueObject::CreateValueObjectFromData( "domain_str", isw.GetAsData(process_sp->GetByteOrder()), valobj.GetExecutionContextRef(), - ClangASTContext::GetScratch(process_sp->GetTarget()) + TypeSystemClang::GetScratch(process_sp->GetTarget()) ->GetBasicType(lldb::eBasicTypeVoid) .GetPointerType()); @@ -156,7 +156,7 @@ public: m_child_sp = CreateValueObjectFromData( "_userInfo", isw.GetAsData(process_sp->GetByteOrder()), m_backend.GetExecutionContextRef(), - ClangASTContext::GetScratch(process_sp->GetTarget()) + TypeSystemClang::GetScratch(process_sp->GetTarget()) ->GetBasicType(lldb::eBasicTypeObjCID)); return false; } diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSException.cpp b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSException.cpp index 9150787361c..c6bae5e1c00 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSException.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSException.cpp @@ -1,4 +1,4 @@ -//===-- NSException.cpp -----------------------------------------*- C++ -*-===// +//===-- NSException.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,7 +13,6 @@ #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/ProcessStructReader.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" @@ -23,6 +22,7 @@ #include "Plugins/Language/ObjC/NSString.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" using namespace lldb; using namespace lldb_private; @@ -69,7 +69,7 @@ static bool ExtractFields(ValueObject &valobj, ValueObjectSP *name_sp, InferiorSizedWord userinfo_isw(userinfo, *process_sp); InferiorSizedWord reserved_isw(reserved, *process_sp); - auto *clang_ast_context = ClangASTContext::GetScratch(process_sp->GetTarget()); + auto *clang_ast_context = TypeSystemClang::GetScratch(process_sp->GetTarget()); if (!clang_ast_context) return false; diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp index 587dd13870a..d962f39611b 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp @@ -1,4 +1,4 @@ -//===-- NSIndexPath.cpp -----------------------------------------*- C++ -*-===// +//===-- NSIndexPath.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,11 +8,11 @@ #include "Cocoa.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/DataFormatters/TypeSynthetic.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" @@ -53,7 +53,7 @@ public: if (!type_system) return false; - ClangASTContext *ast = ClangASTContext::GetScratch( + TypeSystemClang *ast = TypeSystemClang::GetScratch( *m_backend.GetExecutionContextRef().GetTargetSP()); if (!ast) return false; diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSSet.cpp b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSSet.cpp index ebaa990fb74..4dbbe6fbddf 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSSet.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSSet.cpp @@ -1,4 +1,4 @@ -//===-- NSSet.cpp -----------------------------------------------*- C++ -*-===// +//===-- NSSet.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,12 +7,13 @@ //===----------------------------------------------------------------------===// #include "NSSet.h" +#include "CFBasicHash.h" #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Language.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" @@ -79,6 +80,36 @@ private: std::vector m_children; }; +class NSCFSetSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: + NSCFSetSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + + size_t CalculateNumChildren() override; + + lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + + bool Update() override; + + bool MightHaveChildren() override; + + size_t GetIndexOfChildWithName(ConstString name) override; + +private: + struct SetItemDescriptor { + lldb::addr_t item_ptr; + lldb::ValueObjectSP valobj_sp; + }; + + ExecutionContextRef m_exe_ctx_ref; + uint8_t m_ptr_size; + lldb::ByteOrder m_order; + + CFBasicHash m_hashtable; + + CompilerType m_pair_type; + std::vector m_children; +}; + template class GenericNSSetMSyntheticFrontEnd : public SyntheticChildrenFrontEnd { public: @@ -245,21 +276,25 @@ bool lldb_private::formatters::NSSetSummaryProvider( uint64_t value = 0; - ConstString class_name_cs = descriptor->GetClassName(); - const char *class_name = class_name_cs.GetCString(); + ConstString class_name(descriptor->GetClassName()); - if (!class_name || !*class_name) + static const ConstString g_SetI("__NSSetI"); + static const ConstString g_OrderedSetI("__NSOrderedSetI"); + static const ConstString g_SetM("__NSSetM"); + static const ConstString g_SetCF("__NSCFSet"); + static const ConstString g_SetCFRef("CFSetRef"); + + if (class_name.IsEmpty()) return false; - if (!strcmp(class_name, "__NSSetI") || - !strcmp(class_name, "__NSOrderedSetI")) { + if (class_name == g_SetI || class_name == g_OrderedSetI) { Status error; value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error); if (error.Fail()) return false; value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); - } else if (!strcmp(class_name, "__NSSetM")) { + } else if (class_name == g_SetM) { AppleObjCRuntime *apple_runtime = llvm::dyn_cast_or_null(runtime); Status error; @@ -272,9 +307,15 @@ bool lldb_private::formatters::NSSetSummaryProvider( } if (error.Fail()) return false; + } else if (class_name == g_SetCF || class_name == g_SetCFRef) { + ExecutionContext exe_ctx(process_sp); + CFBasicHash cfbh; + if (!cfbh.Update(valobj_addr, exe_ctx)) + return false; + value = cfbh.GetCount(); } else { auto &map(NSSet_Additionals::GetAdditionalSummaries()); - auto iter = map.find(class_name_cs), end = map.end(); + auto iter = map.find(class_name), end = map.end(); if (iter != end) return iter->second(valobj, stream, options); else @@ -321,16 +362,20 @@ lldb_private::formatters::NSSetSyntheticFrontEndCreator( if (!descriptor || !descriptor->IsValid()) return nullptr; - ConstString class_name_cs = descriptor->GetClassName(); - const char *class_name = class_name_cs.GetCString(); + ConstString class_name = descriptor->GetClassName(); - if (!class_name || !*class_name) + static const ConstString g_SetI("__NSSetI"); + static const ConstString g_OrderedSetI("__NSOrderedSetI"); + static const ConstString g_SetM("__NSSetM"); + static const ConstString g_SetCF("__NSCFSet"); + static const ConstString g_SetCFRef("CFSetRef"); + + if (class_name.IsEmpty()) return nullptr; - if (!strcmp(class_name, "__NSSetI") || - !strcmp(class_name, "__NSOrderedSetI")) { + if (class_name == g_SetI || class_name == g_OrderedSetI) { return (new NSSetISyntheticFrontEnd(valobj_sp)); - } else if (!strcmp(class_name, "__NSSetM")) { + } else if (class_name == g_SetM) { AppleObjCRuntime *apple_runtime = llvm::dyn_cast_or_null(runtime); if (apple_runtime) { @@ -343,9 +388,11 @@ lldb_private::formatters::NSSetSyntheticFrontEndCreator( } else { return (new Foundation1300::NSSetMSyntheticFrontEnd(valobj_sp)); } + } else if (class_name == g_SetCF || class_name == g_SetCFRef) { + return (new NSCFSetSyntheticFrontEnd(valobj_sp)); } else { auto &map(NSSet_Additionals::GetAdditionalSynthetics()); - auto iter = map.find(class_name_cs), end = map.end(); + auto iter = map.find(class_name), end = map.end(); if (iter != end) return iter->second(synth, valobj_sp); return nullptr; @@ -475,16 +522,18 @@ lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex(size_t idx) { auto ptr_size = process_sp->GetAddressByteSize(); DataBufferHeap buffer(ptr_size, 0); switch (ptr_size) { - case 0: // architecture has no clue?? - fail + case 0: // architecture has no clue - fail return lldb::ValueObjectSP(); case 4: - *((uint32_t *)buffer.GetBytes()) = (uint32_t)set_item.item_ptr; + *reinterpret_cast(buffer.GetBytes()) = + static_cast(set_item.item_ptr); break; case 8: - *((uint64_t *)buffer.GetBytes()) = (uint64_t)set_item.item_ptr; + *reinterpret_cast(buffer.GetBytes()) = + static_cast(set_item.item_ptr); break; default: - assert(false && "pointer size is not 4 nor 8 - get out of here ASAP"); + lldbassert(false && "pointer size is not 4 nor 8"); } StreamString idx_name; idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); @@ -501,6 +550,128 @@ lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex(size_t idx) { return set_item.valobj_sp; } +lldb_private::formatters::NSCFSetSyntheticFrontEnd::NSCFSetSyntheticFrontEnd( + lldb::ValueObjectSP valobj_sp) + : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), + m_order(lldb::eByteOrderInvalid), m_hashtable(), m_pair_type() {} + +size_t +lldb_private::formatters::NSCFSetSyntheticFrontEnd::GetIndexOfChildWithName( + ConstString name) { + const char *item_name = name.GetCString(); + const uint32_t idx = ExtractIndexFromString(item_name); + if (idx < UINT32_MAX && idx >= CalculateNumChildren()) + return UINT32_MAX; + return idx; +} + +size_t +lldb_private::formatters::NSCFSetSyntheticFrontEnd::CalculateNumChildren() { + if (!m_hashtable.IsValid()) + return 0; + return m_hashtable.GetCount(); +} + +bool lldb_private::formatters::NSCFSetSyntheticFrontEnd::Update() { + m_children.clear(); + ValueObjectSP valobj_sp = m_backend.GetSP(); + m_ptr_size = 0; + if (!valobj_sp) + return false; + m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); + + lldb::ProcessSP process_sp(valobj_sp->GetProcessSP()); + if (!process_sp) + return false; + m_ptr_size = process_sp->GetAddressByteSize(); + m_order = process_sp->GetByteOrder(); + return m_hashtable.Update(valobj_sp->GetValueAsUnsigned(0), m_exe_ctx_ref); +} + +bool lldb_private::formatters::NSCFSetSyntheticFrontEnd::MightHaveChildren() { + return true; +} + +lldb::ValueObjectSP +lldb_private::formatters::NSCFSetSyntheticFrontEnd::GetChildAtIndex( + size_t idx) { + lldb::addr_t m_values_ptr = m_hashtable.GetValuePointer(); + + const uint32_t num_children = CalculateNumChildren(); + + if (idx >= num_children) + return lldb::ValueObjectSP(); + + if (m_children.empty()) { + ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP(); + if (!process_sp) + return lldb::ValueObjectSP(); + + Status error; + lldb::addr_t val_at_idx = 0; + + uint32_t tries = 0; + uint32_t test_idx = 0; + + // Iterate over inferior memory, reading value pointers by shifting the + // cursor by test_index * m_ptr_size. Returns an empty ValueObject if a read + // fails, otherwise, continue until the number of tries matches the number + // of childen. + while (tries < num_children) { + val_at_idx = m_values_ptr + (test_idx * m_ptr_size); + + val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error); + if (error.Fail()) + return lldb::ValueObjectSP(); + + test_idx++; + + if (!val_at_idx) + continue; + tries++; + + SetItemDescriptor descriptor = {val_at_idx, lldb::ValueObjectSP()}; + + m_children.push_back(descriptor); + } + } + + if (idx >= m_children.size()) // should never happen + return lldb::ValueObjectSP(); + + SetItemDescriptor &set_item = m_children[idx]; + if (!set_item.valobj_sp) { + + DataBufferSP buffer_sp(new DataBufferHeap(m_ptr_size, 0)); + + switch (m_ptr_size) { + case 0: // architecture has no clue - fail + return lldb::ValueObjectSP(); + case 4: + *reinterpret_cast(buffer_sp->GetBytes()) = + static_cast(set_item.item_ptr); + break; + case 8: + *reinterpret_cast(buffer_sp->GetBytes()) = + static_cast(set_item.item_ptr); + break; + default: + lldbassert(false && "pointer size is not 4 nor 8"); + } + StreamString idx_name; + idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); + + DataExtractor data(buffer_sp, m_order, m_ptr_size); + + set_item.valobj_sp = CreateValueObjectFromData( + idx_name.GetString(), data, m_exe_ctx_ref, + m_backend.GetCompilerType().GetBasicTypeFromAST( + lldb::eBasicTypeObjCID)); + } + + return set_item.valobj_sp; +} + template lldb_private::formatters:: GenericNSSetMSyntheticFrontEnd::GenericNSSetMSyntheticFrontEnd( @@ -513,7 +684,7 @@ lldb_private::formatters:: template lldb_private::formatters:: - GenericNSSetMSyntheticFrontEnd::~GenericNSSetMSyntheticFrontEnd() { + GenericNSSetMSyntheticFrontEnd::~GenericNSSetMSyntheticFrontEnd() { delete m_data_32; m_data_32 = nullptr; delete m_data_64; diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSSet.h b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSSet.h index f11b6d406de..3ad1f694bef 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSSet.h +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSSet.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_NSSet_h_ -#define liblldb_NSSet_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSSET_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSSET_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -36,4 +36,4 @@ public: } // namespace formatters } // namespace lldb_private -#endif // liblldb_NSSet_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSSET_H diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSString.cpp b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSString.cpp index ce54d657374..b9d0d73cbc2 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSString.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSString.cpp @@ -1,5 +1,4 @@ -//===-- NSString.cpp ----------------------------------------------*- C++ -//-*-===// +//===-- NSString.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,11 +8,11 @@ #include "NSString.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/DataFormatters/StringPrinter.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Language.h" #include "lldb/Target/ProcessStructReader.h" #include "lldb/Target/Target.h" @@ -35,7 +34,7 @@ NSString_Additionals::GetAdditionalSummaries() { static CompilerType GetNSPathStore2Type(Target &target) { static ConstString g_type_name("__lldb_autogen_nspathstore2"); - ClangASTContext *ast_ctx = ClangASTContext::GetScratch(target); + TypeSystemClang *ast_ctx = TypeSystemClang::GetScratch(target); if (!ast_ctx) return CompilerType(); @@ -171,11 +170,11 @@ bool lldb_private::formatters::NSStringSummaryProvider( options.SetStream(&stream); options.SetQuote('"'); options.SetSourceSize(explicit_length); + options.SetHasSourceSize(has_explicit_length); options.SetNeedsZeroTermination(false); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(false); - options.SetLanguage(summary_options.GetLanguage()); return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::UTF16>(options); } else { @@ -183,11 +182,11 @@ bool lldb_private::formatters::NSStringSummaryProvider( options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetSourceSize(explicit_length); + options.SetHasSourceSize(has_explicit_length); options.SetNeedsZeroTermination(false); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(false); - options.SetLanguage(summary_options.GetLanguage()); return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::ASCII>(options); } @@ -200,9 +199,9 @@ bool lldb_private::formatters::NSStringSummaryProvider( options.SetStream(&stream); options.SetQuote('"'); options.SetSourceSize(explicit_length); + options.SetHasSourceSize(has_explicit_length); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); - options.SetLanguage(summary_options.GetLanguage()); return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::ASCII>(options); } else if (is_unicode) { @@ -222,11 +221,11 @@ bool lldb_private::formatters::NSStringSummaryProvider( options.SetStream(&stream); options.SetQuote('"'); options.SetSourceSize(explicit_length); + options.SetHasSourceSize(has_explicit_length); options.SetNeedsZeroTermination(!has_explicit_length); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(!has_explicit_length); - options.SetLanguage(summary_options.GetLanguage()); return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::UTF16>(options); } else if (is_path_store) { @@ -242,11 +241,11 @@ bool lldb_private::formatters::NSStringSummaryProvider( options.SetStream(&stream); options.SetQuote('"'); options.SetSourceSize(explicit_length); + options.SetHasSourceSize(has_explicit_length); options.SetNeedsZeroTermination(!has_explicit_length); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(!has_explicit_length); - options.SetLanguage(summary_options.GetLanguage()); return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::UTF16>(options); } else if (is_inline) { @@ -264,11 +263,11 @@ bool lldb_private::formatters::NSStringSummaryProvider( options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetSourceSize(explicit_length); + options.SetHasSourceSize(has_explicit_length); options.SetNeedsZeroTermination(!has_explicit_length); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(!has_explicit_length); - options.SetLanguage(summary_options.GetLanguage()); if (has_explicit_length) return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::UTF8>(options); @@ -287,9 +286,9 @@ bool lldb_private::formatters::NSStringSummaryProvider( options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetSourceSize(explicit_length); + options.SetHasSourceSize(has_explicit_length); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); - options.SetLanguage(summary_options.GetLanguage()); return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::ASCII>(options); } diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSString.h b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSString.h index 699d8eb36f8..a68cc6c056b 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSString.h +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/NSString.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_NSString_h_ -#define liblldb_NSString_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSSTRING_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSSTRING_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -39,4 +39,4 @@ public: } // namespace formatters } // namespace lldb_private -#endif // liblldb_CF_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSSTRING_H diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/gnu/llvm/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp index 3be548ad414..29391daaab9 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp @@ -1,4 +1,4 @@ -//===-- ObjCLanguage.cpp ----------------------------------------*- C++ -*-===// +//===-- ObjCLanguage.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,12 +10,12 @@ #include "ObjCLanguage.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/DataVisualization.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Target/Target.h" #include "lldb/Utility/ConstString.h" @@ -37,6 +37,8 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; +LLDB_PLUGIN_DEFINE(ObjCLanguage) + void ObjCLanguage::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), "Objective-C Language", CreateInstance); @@ -444,6 +446,10 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { lldb_private::formatters::NSDictionarySummaryProvider, "NSDictionary summary provider", ConstString("CFDictionaryRef"), appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSDictionarySummaryProvider, + "NSDictionary summary provider", ConstString("__CFDictionary"), + appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider, "NSDictionary summary provider", @@ -464,6 +470,9 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider, "__NSCFSet summary", ConstString("__NSCFSet"), appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSSetSummaryProvider, + "__CFSet summary", ConstString("__CFSet"), appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider, "__NSSetI summary", ConstString("__NSSetI"), appkit_flags); @@ -582,6 +591,11 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("CFMutableDictionaryRef"), ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic( + objc_category_sp, + lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, + "NSDictionary synthetic children", ConstString("__CFDictionary"), + ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSErrorSyntheticFrontEndCreator, @@ -604,6 +618,15 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSSetM synthetic children", ConstString("__NSSetM"), ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic(objc_category_sp, + lldb_private::formatters::NSSetSyntheticFrontEndCreator, + "__NSCFSet synthetic children", ConstString("__NSCFSet"), + ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic(objc_category_sp, + lldb_private::formatters::NSSetSyntheticFrontEndCreator, + "CFSetRef synthetic children", ConstString("CFSetRef"), + ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic( objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSMutableSet synthetic children", ConstString("NSMutableSet"), @@ -620,6 +643,10 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSOrderedSetM synthetic children", ConstString("__NSOrderedSetM"), ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic(objc_category_sp, + lldb_private::formatters::NSSetSyntheticFrontEndCreator, + "__CFSet synthetic children", ConstString("__CFSet"), + ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSIndexPathSyntheticFrontEndCreator, diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/gnu/llvm/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h index 3e2cc097299..bed62a5c447 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ObjCLanguage_h_ -#define liblldb_ObjCLanguage_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCLANGUAGE_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCLANGUAGE_H #include #include @@ -160,4 +160,4 @@ public: } // namespace lldb_private -#endif // liblldb_ObjCLanguage_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCLANGUAGE_H diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp b/gnu/llvm/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp index 81b3c5807c4..0a4017eda43 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp @@ -1,5 +1,4 @@ -//===-- ObjCPlusPlusLanguage.cpp --------------------------------------*- C++ -//-*-===// +//===-- ObjCPlusPlusLanguage.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -15,6 +14,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(ObjCPlusPlusLanguage) + bool ObjCPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const { const auto suffixes = {".h", ".mm"}; for (auto suffix : suffixes) { diff --git a/gnu/llvm/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h b/gnu/llvm/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h index 6224a3f47b3..4b3d2365334 100644 --- a/gnu/llvm/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h +++ b/gnu/llvm/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ObjCPlusPlusLanguage_h_ -#define liblldb_ObjCPlusPlusLanguage_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJCPLUSPLUS_OBJCPLUSPLUSLANGUAGE_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJCPLUSPLUS_OBJCPLUSPLUSLANGUAGE_H #include "Plugins/Language/ClangCommon/ClangHighlighter.h" #include "lldb/Target/Language.h" @@ -48,4 +48,4 @@ public: } // namespace lldb_private -#endif // liblldb_CPlusPlusLanguage_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJCPLUSPLUS_OBJCPLUSPLUSLANGUAGE_H diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt index 508a361aa6d..1717b0a8966 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt @@ -1,4 +1,4 @@ -add_lldb_library(lldbPluginCPPRuntime PLUGIN +add_lldb_library(lldbPluginCPPRuntime CPPLanguageRuntime.cpp LINK_LIBS diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index d556aae1c45..8aa803a8553 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -1,4 +1,4 @@ -//===-- CPPLanguageRuntime.cpp +//===-- CPPLanguageRuntime.cpp---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -20,7 +20,6 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Core/UniqueCStringMap.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContext.h" @@ -44,7 +43,7 @@ CPPLanguageRuntime::~CPPLanguageRuntime() {} CPPLanguageRuntime::CPPLanguageRuntime(Process *process) : LanguageRuntime(process) {} -bool CPPLanguageRuntime::IsWhitelistedRuntimeValue(ConstString name) { +bool CPPLanguageRuntime::IsAllowedRuntimeValue(ConstString name) { return name == g_this; } diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h index abdd79fcd7b..5b00590e630 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CPPLanguageRuntime_h_ -#define liblldb_CPPLanguageRuntime_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_CPPLANGUAGERUNTIME_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_CPPLANGUAGERUNTIME_H #include @@ -69,7 +69,7 @@ public: /// Obtain a ThreadPlan to get us into C++ constructs such as std::function. /// /// \param[in] thread - /// Curent thrad of execution. + /// Current thrad of execution. /// /// \param[in] stop_others /// True if other threads should pause during execution. @@ -79,7 +79,7 @@ public: lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, bool stop_others) override; - bool IsWhitelistedRuntimeValue(ConstString name) override; + bool IsAllowedRuntimeValue(ConstString name) override; protected: // Classes that inherit from CPPLanguageRuntime can see and modify these CPPLanguageRuntime(Process *process); @@ -90,9 +90,10 @@ private: OperatorStringToCallableInfoMap CallableLookupCache; - DISALLOW_COPY_AND_ASSIGN(CPPLanguageRuntime); + CPPLanguageRuntime(const CPPLanguageRuntime &) = delete; + const CPPLanguageRuntime &operator=(const CPPLanguageRuntime &) = delete; }; } // namespace lldb_private -#endif // liblldb_CPPLanguageRuntime_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_CPPLANGUAGERUNTIME_H diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/CMakeLists.txt index 52c297d944b..5ab494414ac 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/CMakeLists.txt @@ -8,4 +8,5 @@ add_lldb_library(lldbPluginCXXItaniumABI PLUGIN lldbSymbol lldbTarget lldbPluginCPPRuntime + lldbPluginTypeSystemClang ) diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp index 9efb021caa8..3ab32641d9c 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -1,5 +1,4 @@ -//===-- ItaniumABILanguageRuntime.cpp --------------------------------------*- -//C++ -*-===// +//===-- ItaniumABILanguageRuntime.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,6 +8,7 @@ #include "ItaniumABILanguageRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/Module.h" @@ -21,7 +21,6 @@ #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/Interpreter/CommandReturnObject.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/TypeList.h" @@ -41,6 +40,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE_ADV(ItaniumABILanguageRuntime, CXXItaniumABI) + static const char *vtable_demangled_prefix = "vtable for "; char ItaniumABILanguageRuntime::ID = 0; @@ -73,9 +74,7 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress( Symbol *symbol = sc.symbol; if (symbol != nullptr) { const char *name = - symbol->GetMangled() - .GetDemangledName(lldb::eLanguageTypeC_plus_plus) - .AsCString(); + symbol->GetMangled().GetDemangledName().AsCString(); if (name && strstr(name, vtable_demangled_prefix) == name) { Log *log( lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); @@ -118,7 +117,7 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress( if (class_types.GetSize() == 1) { type_sp = class_types.GetTypeAtIndex(0); if (type_sp) { - if (ClangASTContext::IsCXXClassType( + if (TypeSystemClang::IsCXXClassType( type_sp->GetForwardCompilerType())) { LLDB_LOGF( log, @@ -150,7 +149,7 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress( for (i = 0; i < class_types.GetSize(); i++) { type_sp = class_types.GetTypeAtIndex(i); if (type_sp) { - if (ClangASTContext::IsCXXClassType( + if (TypeSystemClang::IsCXXClassType( type_sp->GetForwardCompilerType())) { LLDB_LOGF( log, @@ -238,7 +237,7 @@ bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress( if (!type) return true; - if (ClangASTContext::AreTypesSame(in_value.GetCompilerType(), type)) { + if (TypeSystemClang::AreTypesSame(in_value.GetCompilerType(), type)) { // The dynamic type we found was the same type, so we don't have a // dynamic type here... return false; @@ -358,8 +357,7 @@ protected: Mangled mangled(name); if (mangled.GuessLanguage() == lldb::eLanguageTypeC_plus_plus) { - ConstString demangled( - mangled.GetDisplayDemangledName(lldb::eLanguageTypeC_plus_plus)); + ConstString demangled(mangled.GetDisplayDemangledName()); demangled_any = true; result.AppendMessageWithFormat("%s ---> %s\n", entry.c_str(), demangled.GetCString()); @@ -420,12 +418,13 @@ lldb_private::ConstString ItaniumABILanguageRuntime::GetPluginName() { uint32_t ItaniumABILanguageRuntime::GetPluginVersion() { return 1; } BreakpointResolverSP ItaniumABILanguageRuntime::CreateExceptionResolver( - Breakpoint *bkpt, bool catch_bp, bool throw_bp) { + const BreakpointSP &bkpt, bool catch_bp, bool throw_bp) { return CreateExceptionResolver(bkpt, catch_bp, throw_bp, false); } BreakpointResolverSP ItaniumABILanguageRuntime::CreateExceptionResolver( - Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions) { + const BreakpointSP &bkpt, bool catch_bp, bool throw_bp, + bool for_expressions) { // One complication here is that most users DON'T want to stop at // __cxa_allocate_expression, but until we can do anything better with // predicting unwinding the expression parser does. So we have two forms of @@ -536,8 +535,8 @@ ValueObjectSP ItaniumABILanguageRuntime::GetExceptionObjectForThread( if (!thread_sp->SafeToCallFunctions()) return {}; - ClangASTContext *clang_ast_context = - ClangASTContext::GetScratch(m_process->GetTarget()); + TypeSystemClang *clang_ast_context = + TypeSystemClang::GetScratch(m_process->GetTarget()); if (!clang_ast_context) return {}; diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h index 97cc81b8681..d591527d925 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ItaniumABILanguageRuntime_h_ -#define liblldb_ItaniumABILanguageRuntime_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_ITANIUMABI_ITANIUMABILANGUAGERUNTIME_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_ITANIUMABI_ITANIUMABILANGUAGERUNTIME_H #include #include @@ -66,9 +66,9 @@ public: bool ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) override; - lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt, - bool catch_bp, - bool throw_bp) override; + lldb::BreakpointResolverSP + CreateExceptionResolver(const lldb::BreakpointSP &bkpt, + bool catch_bp, bool throw_bp) override; lldb::SearchFilterSP CreateExceptionSearchFilter() override; @@ -81,10 +81,9 @@ public: uint32_t GetPluginVersion() override; protected: - lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt, - bool catch_bp, - bool throw_bp, - bool for_expressions); + lldb::BreakpointResolverSP + CreateExceptionResolver(const lldb::BreakpointSP &bkpt, + bool catch_bp, bool throw_bp, bool for_expressions); lldb::BreakpointSP CreateExceptionBreakpoint(bool catch_bp, bool throw_bp, bool for_expressions, @@ -114,4 +113,4 @@ private: } // namespace lldb_private -#endif // liblldb_ItaniumABILanguageRuntime_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_ITANIUMABI_ITANIUMABILANGUAGERUNTIME_H diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp index 859b693477a..bdd5c29db84 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp @@ -1,5 +1,4 @@ -//===-- AppleObjCClassDescriptorV2.cpp -----------------------------*- C++ -//-*-===// +//===-- AppleObjCClassDescriptorV2.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -17,7 +16,7 @@ using namespace lldb_private; bool ClassDescriptorV2::Read_objc_class( Process *process, std::unique_ptr &objc_class) const { - objc_class.reset(new objc_class_t); + objc_class = std::make_unique(); bool ret = objc_class->Read(process, m_objc_class_ptr); @@ -198,14 +197,14 @@ bool ClassDescriptorV2::Read_class_row( return false; if (class_row_t_flags & RW_REALIZED) { - class_rw.reset(new class_rw_t); + class_rw = std::make_unique(); if (!class_rw->Read(process, objc_class.m_data_ptr)) { class_rw.reset(); return false; } - class_ro.reset(new class_ro_t); + class_ro = std::make_unique(); if (!class_ro->Read(process, class_rw->m_ro_ptr)) { class_rw.reset(); @@ -213,7 +212,7 @@ bool ClassDescriptorV2::Read_class_row( return false; } } else { - class_ro.reset(new class_ro_t); + class_ro = std::make_unique(); if (!class_ro->Read(process, objc_class.m_data_ptr)) { class_ro.reset(); @@ -242,15 +241,20 @@ bool ClassDescriptorV2::method_list_t::Read(Process *process, lldb::offset_t cursor = 0; - m_entsize = extractor.GetU32_unchecked(&cursor) & ~(uint32_t)3; + uint32_t entsize = extractor.GetU32_unchecked(&cursor); + m_is_small = (entsize & 0x80000000) != 0; + m_has_direct_selector = (entsize & 0x40000000) != 0; + m_entsize = entsize & 0xfffc; m_count = extractor.GetU32_unchecked(&cursor); m_first_ptr = addr + cursor; return true; } -bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr) { - size_t size = GetSize(process); +bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr, + bool is_small, bool has_direct_sel) { + size_t ptr_size = process->GetAddressByteSize(); + size_t size = GetSize(process, is_small); DataBufferHeap buffer(size, '\0'); Status error; @@ -261,13 +265,30 @@ bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr) { } DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), - process->GetAddressByteSize()); - + ptr_size); lldb::offset_t cursor = 0; - m_name_ptr = extractor.GetAddress_unchecked(&cursor); - m_types_ptr = extractor.GetAddress_unchecked(&cursor); - m_imp_ptr = extractor.GetAddress_unchecked(&cursor); + if (is_small) { + uint32_t nameref_offset = extractor.GetU32_unchecked(&cursor); + uint32_t types_offset = extractor.GetU32_unchecked(&cursor); + uint32_t imp_offset = extractor.GetU32_unchecked(&cursor); + + m_name_ptr = addr + nameref_offset; + + if (!has_direct_sel) { + // The SEL offset points to a SELRef. We need to dereference twice. + m_name_ptr = process->ReadUnsignedIntegerFromMemory(m_name_ptr, ptr_size, + 0, error); + if (!error.Success()) + return false; + } + m_types_ptr = addr + 4 + types_offset; + m_imp_ptr = addr + 8 + imp_offset; + } else { + m_name_ptr = extractor.GetAddress_unchecked(&cursor); + m_types_ptr = extractor.GetAddress_unchecked(&cursor); + m_imp_ptr = extractor.GetAddress_unchecked(&cursor); + } process->ReadCStringFromMemory(m_name_ptr, m_name, error); if (error.Fail()) { @@ -358,19 +379,24 @@ bool ClassDescriptorV2::Describe( if (instance_method_func) { std::unique_ptr base_method_list; - base_method_list.reset(new method_list_t); + base_method_list = std::make_unique(); if (!base_method_list->Read(process, class_ro->m_baseMethods_ptr)) return false; - if (base_method_list->m_entsize != method_t::GetSize(process)) + bool is_small = base_method_list->m_is_small; + bool has_direct_selector = base_method_list->m_has_direct_selector; + + if (base_method_list->m_entsize != method_t::GetSize(process, is_small)) return false; std::unique_ptr method; - method.reset(new method_t); + method = std::make_unique(); for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i) { - method->Read(process, base_method_list->m_first_ptr + - (i * base_method_list->m_entsize)); + method->Read(process, + base_method_list->m_first_ptr + + (i * base_method_list->m_entsize), + is_small, has_direct_selector); if (instance_method_func(method->m_name.c_str(), method->m_types.c_str())) break; diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h index b8ba9dbb65f..9ef21c6e720 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AppleObjCClassDescriptorV2_h_ -#define liblldb_AppleObjCClassDescriptorV2_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCCLASSDESCRIPTORV2_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCCLASSDESCRIPTORV2_H #include @@ -133,7 +133,9 @@ private: }; struct method_list_t { - uint32_t m_entsize; + uint16_t m_entsize; + bool m_is_small; + bool m_has_direct_selector; uint32_t m_count; lldb::addr_t m_first_ptr; @@ -148,15 +150,19 @@ private: std::string m_name; std::string m_types; - static size_t GetSize(Process *process) { - size_t ptr_size = process->GetAddressByteSize(); + static size_t GetSize(Process *process, bool is_small) { + size_t field_size; + if (is_small) + field_size = 4; // uint32_t relative indirect fields + else + field_size = process->GetAddressByteSize(); - return ptr_size // SEL name; - + ptr_size // const char *types; - + ptr_size; // IMP imp; + return field_size // SEL name; + + field_size // const char *types; + + field_size; // IMP imp; } - bool Read(Process *process, lldb::addr_t addr); + bool Read(Process *process, lldb::addr_t addr, bool, bool); }; struct ivar_list_t { @@ -328,4 +334,4 @@ private: } // namespace lldb_private -#endif // liblldb_AppleObjCClassDescriptorV2_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCCLASSDESCRIPTORV2_H diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp index 73843063606..7b331307c0f 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp @@ -1,4 +1,4 @@ -//===-- AppleObjCDeclVendor.cpp ---------------------------------*- C++ -*-===// +//===-- AppleObjCDeclVendor.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,10 +8,10 @@ #include "AppleObjCDeclVendor.h" +#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" #include "lldb/Core/Module.h" -#include "lldb/Symbol/ClangASTMetadata.h" -#include "lldb/Symbol/ClangUtil.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/Log.h" @@ -30,17 +30,14 @@ public: bool FindExternalVisibleDeclsByName(const clang::DeclContext *decl_ctx, clang::DeclarationName name) override { - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; Log *log(GetLogIfAllCategoriesSet( LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel? if (log) { LLDB_LOGF(log, - "AppleObjCExternalASTSource::FindExternalVisibleDeclsByName[%" - "u] on (ASTContext*)%p Looking for %s in (%sDecl*)%p", - current_id, + "AppleObjCExternalASTSource::FindExternalVisibleDeclsByName" + " on (ASTContext*)%p Looking for %s in (%sDecl*)%p", static_cast(&decl_ctx->getParentASTContext()), name.getAsString().c_str(), decl_ctx->getDeclKindName(), static_cast(decl_ctx)); @@ -70,44 +67,37 @@ public: } void CompleteType(clang::TagDecl *tag_decl) override { - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; Log *log(GetLogIfAllCategoriesSet( LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel? LLDB_LOGF(log, - "AppleObjCExternalASTSource::CompleteType[%u] on " + "AppleObjCExternalASTSource::CompleteType on " "(ASTContext*)%p Completing (TagDecl*)%p named %s", - current_id, static_cast(&tag_decl->getASTContext()), + static_cast(&tag_decl->getASTContext()), static_cast(tag_decl), tag_decl->getName().str().c_str()); - LLDB_LOG(log, " AOEAS::CT[{0}] Before:\n{1}", current_id, - ClangUtil::DumpDecl(tag_decl)); + LLDB_LOG(log, " AOEAS::CT Before:\n{1}", ClangUtil::DumpDecl(tag_decl)); - LLDB_LOG(log, " AOEAS::CT[{1}] After:{1}", current_id, - ClangUtil::DumpDecl(tag_decl)); + LLDB_LOG(log, " AOEAS::CT After:{1}", ClangUtil::DumpDecl(tag_decl)); return; } void CompleteType(clang::ObjCInterfaceDecl *interface_decl) override { - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; Log *log(GetLogIfAllCategoriesSet( LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel? if (log) { LLDB_LOGF(log, - "AppleObjCExternalASTSource::CompleteType[%u] on " + "AppleObjCExternalASTSource::CompleteType on " "(ASTContext*)%p Completing (ObjCInterfaceDecl*)%p named %s", - current_id, static_cast(&interface_decl->getASTContext()), static_cast(interface_decl), interface_decl->getName().str().c_str()); - LLDB_LOGF(log, " AOEAS::CT[%u] Before:", current_id); + LLDB_LOGF(log, " AOEAS::CT Before:"); LLDB_LOG(log, " [CT] {0}", ClangUtil::DumpDecl(interface_decl)); } @@ -143,10 +133,9 @@ private: AppleObjCDeclVendor::AppleObjCDeclVendor(ObjCLanguageRuntime &runtime) : ClangDeclVendor(eAppleObjCDeclVendor), m_runtime(runtime), - m_ast_ctx(runtime.GetProcess() - ->GetTarget() - .GetArchitecture() - .GetTriple()), + m_ast_ctx( + "AppleObjCDeclVendor AST", + runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple()), m_type_realizer_sp(m_runtime.GetEncodingToType()) { m_external_source = new AppleObjCExternalASTSource(*this); llvm::IntrusiveRefCntPtr external_source_owning_ptr( @@ -309,7 +298,7 @@ public: } clang::ObjCMethodDecl * - BuildMethod(ClangASTContext &clang_ast_ctxt, + BuildMethod(TypeSystemClang &clang_ast_ctxt, clang::ObjCInterfaceDecl *interface_decl, const char *name, bool instance, ObjCLanguageRuntime::EncodingToTypeSP type_realizer_sp) { @@ -538,15 +527,13 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) { uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append, uint32_t max_matches, std::vector &decls) { - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; Log *log(GetLogIfAllCategoriesSet( LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel? - LLDB_LOGF(log, "AppleObjCDeclVendor::FindDecls [%u] ('%s', %s, %u, )", - current_id, (const char *)name.AsCString(), - append ? "true" : "false", max_matches); + LLDB_LOGF(log, "AppleObjCDeclVendor::FindDecls ('%s', %s, %u, )", + (const char *)name.AsCString(), append ? "true" : "false", + max_matches); if (!append) decls.clear(); @@ -579,24 +566,21 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append, isa_value = metadata->GetISAPtr(); LLDB_LOG(log, - "AOCTV::FT [%u] Found %s (isa 0x%" PRIx64 - ") in the ASTContext", - current_id, result_iface_type.getAsString(), isa_value); + "AOCTV::FT Found %s (isa 0x%" PRIx64 ") in the ASTContext", + result_iface_type.getAsString(), isa_value); } - decls.push_back(CompilerDecl(&m_ast_ctx, result_iface_decl)); + decls.push_back(m_ast_ctx.GetCompilerDecl(result_iface_decl)); ret++; break; } else { - LLDB_LOGF(log, - "AOCTV::FT [%u] There's something in the ASTContext, but " - "it's not something we know about", - current_id); + LLDB_LOGF(log, "AOCTV::FT There's something in the ASTContext, but " + "it's not something we know about"); break; } } else if (log) { - LLDB_LOGF(log, "AOCTV::FT [%u] Couldn't find %s in the ASTContext", - current_id, name.AsCString()); + LLDB_LOGF(log, "AOCTV::FT Couldn't find %s in the ASTContext", + name.AsCString()); } // It's not. If it exists, we have to put it into our ASTContext. @@ -604,7 +588,7 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append, ObjCLanguageRuntime::ObjCISA isa = m_runtime.GetISA(name); if (!isa) { - LLDB_LOGF(log, "AOCTV::FT [%u] Couldn't find the isa", current_id); + LLDB_LOGF(log, "AOCTV::FT Couldn't find the isa"); break; } @@ -613,9 +597,9 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append, if (!iface_decl) { LLDB_LOGF(log, - "AOCTV::FT [%u] Couldn't get the Objective-C interface for " + "AOCTV::FT Couldn't get the Objective-C interface for " "isa 0x%" PRIx64, - current_id, (uint64_t)isa); + (uint64_t)isa); break; } @@ -623,11 +607,11 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append, if (log) { clang::QualType new_iface_type = ast_ctx.getObjCInterfaceType(iface_decl); - LLDB_LOG(log, "AOCTV::FT [{0}] Created {1} (isa 0x{2:x})", current_id, + LLDB_LOG(log, "AOCTV::FT Created {1} (isa 0x{2:x})", new_iface_type.getAsString(), (uint64_t)isa); } - decls.push_back(CompilerDecl(&m_ast_ctx, iface_decl)); + decls.push_back(m_ast_ctx.GetCompilerDecl(iface_decl)); ret++; break; } while (false); diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h index f49ca3540c2..c1201b98581 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h @@ -6,14 +6,14 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AppleObjCDeclVendor_h_ -#define liblldb_AppleObjCDeclVendor_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCDECLVENDOR_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCDECLVENDOR_H -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/lldb-private.h" #include "Plugins/ExpressionParser/Clang/ClangDeclVendor.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" namespace lldb_private { @@ -37,7 +37,7 @@ private: bool FinishDecl(clang::ObjCInterfaceDecl *decl); ObjCLanguageRuntime &m_runtime; - ClangASTContext m_ast_ctx; + TypeSystemClang m_ast_ctx; ObjCLanguageRuntime::EncodingToTypeSP m_type_realizer_sp; AppleObjCExternalASTSource *m_external_source; @@ -50,4 +50,4 @@ private: } // namespace lldb_private -#endif // liblldb_AppleObjCDeclVendor_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCDECLVENDOR_H diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp index 7076959bee9..22ea83a57be 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp @@ -1,5 +1,4 @@ -//===-- AppleObjCRuntime.cpp -------------------------------------*- C++ -//-*-===// +//===-- AppleObjCRuntime.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,10 +7,12 @@ //===----------------------------------------------------------------------===// #include "AppleObjCRuntime.h" +#include "AppleObjCRuntimeV1.h" +#include "AppleObjCRuntimeV2.h" #include "AppleObjCTrampolineHandler.h" - -#include "clang/AST/Type.h" - +#include "Plugins/Language/ObjC/NSString.h" +#include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h" +#include "Plugins/Process/Utility/HistoryThread.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" @@ -22,7 +23,6 @@ #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/ExecutionContext.h" #include "lldb/Target/Process.h" @@ -35,16 +35,17 @@ #include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" +#include "clang/AST/Type.h" -#include "Plugins/Process/Utility/HistoryThread.h" -#include "Plugins/Language/ObjC/NSString.h" -#include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(AppleObjCRuntime) + char AppleObjCRuntime::ID = 0; AppleObjCRuntime::~AppleObjCRuntime() {} @@ -55,6 +56,16 @@ AppleObjCRuntime::AppleObjCRuntime(Process *process) ReadObjCLibraryIfNeeded(process->GetTarget().GetImages()); } +void AppleObjCRuntime::Initialize() { + AppleObjCRuntimeV2::Initialize(); + AppleObjCRuntimeV1::Initialize(); +} + +void AppleObjCRuntime::Terminate() { + AppleObjCRuntimeV2::Terminate(); + AppleObjCRuntimeV1::Terminate(); +} + bool AppleObjCRuntime::GetObjectDescription(Stream &str, ValueObject &valobj) { CompilerType compiler_type(valobj.GetCompilerType()); bool is_signed; @@ -105,13 +116,13 @@ bool AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value, Target *target = exe_ctx.GetTargetPtr(); CompilerType compiler_type = value.GetCompilerType(); if (compiler_type) { - if (!ClangASTContext::IsObjCObjectPointerType(compiler_type)) { + if (!TypeSystemClang::IsObjCObjectPointerType(compiler_type)) { strm.Printf("Value doesn't point to an ObjC object.\n"); return false; } } else { // If it is not a pointer, see if we can make it into a pointer. - ClangASTContext *ast_context = ClangASTContext::GetScratch(*target); + TypeSystemClang *ast_context = TypeSystemClang::GetScratch(*target); if (!ast_context) return false; @@ -126,7 +137,7 @@ bool AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value, arg_value_list.PushValue(value); // This is the return value: - ClangASTContext *ast_context = ClangASTContext::GetScratch(*target); + TypeSystemClang *ast_context = TypeSystemClang::GetScratch(*target); if (!ast_context) return false; @@ -239,7 +250,8 @@ Address *AppleObjCRuntime::GetPrintForDebuggerAddr() { contexts.GetContextAtIndex(0, context); - m_PrintForDebugger_addr.reset(new Address(context.symbol->GetAddress())); + m_PrintForDebugger_addr = + std::make_unique
(context.symbol->GetAddress()); } return m_PrintForDebugger_addr.get(); @@ -335,8 +347,8 @@ bool AppleObjCRuntime::ReadObjCLibrary(const ModuleSP &module_sp) { // Maybe check here and if we have a handler already, and the UUID of this // module is the same as the one in the current module, then we don't have to // reread it? - m_objc_trampoline_handler_up.reset( - new AppleObjCTrampolineHandler(m_process->shared_from_this(), module_sp)); + m_objc_trampoline_handler_up = std::make_unique( + m_process->shared_from_this(), module_sp); if (m_objc_trampoline_handler_up != nullptr) { m_read_objc_library = true; return true; @@ -479,7 +491,7 @@ ValueObjectSP AppleObjCRuntime::GetExceptionObjectForThread( auto descriptor = GetClassDescriptor(*cpp_exception); if (!descriptor || !descriptor->IsValid()) return ValueObjectSP(); - + while (descriptor) { ConstString class_name(descriptor->GetClassName()); if (class_name == "NSException") @@ -490,19 +502,32 @@ ValueObjectSP AppleObjCRuntime::GetExceptionObjectForThread( return ValueObjectSP(); } +/// Utility method for error handling in GetBacktraceThreadFromException. +/// \param msg The message to add to the log. +/// \return An invalid ThreadSP to be returned from +/// GetBacktraceThreadFromException. +LLVM_NODISCARD +static ThreadSP FailExceptionParsing(llvm::StringRef msg) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + LLDB_LOG(log, "Failed getting backtrace from exception: {0}", msg); + return ThreadSP(); +} + ThreadSP AppleObjCRuntime::GetBacktraceThreadFromException( lldb::ValueObjectSP exception_sp) { ValueObjectSP reserved_dict = exception_sp->GetChildMemberWithName(ConstString("reserved"), true); - if (!reserved_dict) return ThreadSP(); + if (!reserved_dict) + return FailExceptionParsing("Failed to get 'reserved' member."); reserved_dict = reserved_dict->GetSyntheticValue(); - if (!reserved_dict) return ThreadSP(); + if (!reserved_dict) + return FailExceptionParsing("Failed to get synthetic value."); - ClangASTContext *clang_ast_context = - ClangASTContext::GetScratch(*exception_sp->GetTargetSP()); + TypeSystemClang *clang_ast_context = + TypeSystemClang::GetScratch(*exception_sp->GetTargetSP()); if (!clang_ast_context) - return ThreadSP(); + return FailExceptionParsing("Failed to get scratch AST."); CompilerType objc_id = clang_ast_context->GetBasicType(lldb::eBasicTypeObjCID); ValueObjectSP return_addresses; @@ -527,8 +552,8 @@ ThreadSP AppleObjCRuntime::GetBacktraceThreadFromException( 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 dict_entry_key = data.GetAddress(&data_offset); + auto dict_entry_value = data.GetAddress(&data_offset); auto key_nsstring = objc_object_from_address(dict_entry_key, "key"); StreamString key_summary; @@ -543,15 +568,22 @@ ThreadSP AppleObjCRuntime::GetBacktraceThreadFromException( } } - if (!return_addresses) return ThreadSP(); + if (!return_addresses) + return FailExceptionParsing("Failed to get return addresses."); auto frames_value = return_addresses->GetChildMemberWithName(ConstString("_frames"), true); + if (!frames_value) + return FailExceptionParsing("Failed to get frames_value."); addr_t frames_addr = frames_value->GetValueAsUnsigned(0); auto count_value = return_addresses->GetChildMemberWithName(ConstString("_cnt"), true); + if (!count_value) + return FailExceptionParsing("Failed to get count_value."); size_t count = count_value->GetValueAsUnsigned(0); auto ignore_value = return_addresses->GetChildMemberWithName(ConstString("_ignore"), true); + if (!ignore_value) + return FailExceptionParsing("Failed to get ignore_value."); size_t ignore = ignore_value->GetValueAsUnsigned(0); size_t ptr_size = m_process->GetAddressByteSize(); @@ -563,7 +595,8 @@ ThreadSP AppleObjCRuntime::GetBacktraceThreadFromException( pcs.push_back(pc); } - if (pcs.empty()) return ThreadSP(); + if (pcs.empty()) + return FailExceptionParsing("Failed to get PC list."); ThreadSP new_thread_sp(new HistoryThread(*m_process, 0, pcs)); m_process->GetExtendedThreadList().AddThread(new_thread_sp); diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h index 79ac53e1e44..e9790871e8c 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AppleObjCRuntime_h_ -#define liblldb_AppleObjCRuntime_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIME_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIME_H #include "llvm/ADT/Optional.h" @@ -31,6 +31,10 @@ public: static char ID; + static void Initialize(); + + static void Terminate(); + bool isA(const void *ClassID) const override { return ClassID == &ID || ObjCLanguageRuntime::isA(ClassID); } @@ -84,7 +88,7 @@ public: bool ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) override; lldb::SearchFilterSP CreateExceptionSearchFilter() override; - + static std::tuple GetExceptionThrowLocation(); lldb::ValueObjectSP GetExceptionObjectForThread( @@ -97,7 +101,7 @@ public: virtual void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true, lldb::addr_t &cf_false); - + virtual bool IsTaggedPointer (lldb::addr_t addr) { return false; } protected: @@ -128,4 +132,4 @@ protected: } // namespace lldb_private -#endif // liblldb_AppleObjCRuntime_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIME_H diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp index 88bfe2ce020..8202686597a 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp @@ -1,5 +1,4 @@ -//===-- AppleObjCRuntimeV1.cpp --------------------------------------*- C++ -//-*-===// +//===-- AppleObjCRuntimeV1.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,12 +12,12 @@ #include "clang/AST/Type.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Expression/FunctionCaller.h" #include "lldb/Expression/UtilityFunction.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" @@ -106,8 +105,8 @@ ConstString AppleObjCRuntimeV1::GetPluginName() { uint32_t AppleObjCRuntimeV1::GetPluginVersion() { return 1; } BreakpointResolverSP -AppleObjCRuntimeV1::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, - bool throw_bp) { +AppleObjCRuntimeV1::CreateExceptionResolver(const BreakpointSP &bkpt, + bool catch_bp, bool throw_bp) { BreakpointResolverSP resolver_sp; if (throw_bp) @@ -363,7 +362,7 @@ void AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() { lldb::offset_t offset = addr_size; // Skip prototype const uint32_t count = data.GetU32(&offset); const uint32_t num_buckets = data.GetU32(&offset); - const addr_t buckets_ptr = data.GetPointer(&offset); + const addr_t buckets_ptr = data.GetAddress(&offset); if (m_hash_signature.NeedsUpdate(count, num_buckets, buckets_ptr)) { m_hash_signature.UpdateSignature(count, num_buckets, buckets_ptr); diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h index 6fdae63d412..d8725d0f57c 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AppleObjCRuntimeV1_h_ -#define liblldb_AppleObjCRuntimeV1_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV1_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV1_H #include "AppleObjCRuntime.h" #include "lldb/lldb-private.h" @@ -113,9 +113,9 @@ public: DeclVendor *GetDeclVendor() override; protected: - lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt, - bool catch_bp, - bool throw_bp) override; + lldb::BreakpointResolverSP + CreateExceptionResolver(const lldb::BreakpointSP &bkpt, + bool catch_bp, bool throw_bp) override; class HashTableSignature { public: @@ -153,4 +153,4 @@ private: } // namespace lldb_private -#endif // liblldb_AppleObjCRuntimeV1_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV1_H diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index 4015f10c496..ac9a0939402 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -1,4 +1,4 @@ -//===-- AppleObjCRuntimeV2.cpp ----------------------------------*- C++ -*-===// +//===-- AppleObjCRuntimeV2.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -15,12 +15,11 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" -#include "lldb/Core/ClangForward.h" #include "lldb/Host/OptionParser.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/lldb-enumerations.h" -#include "lldb/Core/ClangForward.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -35,7 +34,6 @@ #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Interpreter/OptionValueBoolean.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/TypeList.h" @@ -64,6 +62,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" +#include "clang/Basic/TargetInfo.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" @@ -582,8 +581,8 @@ protected: case 0: break; case 1: { - regex_up.reset(new RegularExpression( - llvm::StringRef::withNullAsEmpty(command.GetArgumentAtIndex(0)))); + regex_up = std::make_unique( + llvm::StringRef::withNullAsEmpty(command.GetArgumentAtIndex(0))); if (!regex_up->IsValid()) { result.AppendError( "invalid argument - please provide a valid regular expression"); @@ -826,8 +825,8 @@ lldb_private::ConstString AppleObjCRuntimeV2::GetPluginName() { uint32_t AppleObjCRuntimeV2::GetPluginVersion() { return 1; } BreakpointResolverSP -AppleObjCRuntimeV2::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, - bool throw_bp) { +AppleObjCRuntimeV2::CreateExceptionResolver(const BreakpointSP &bkpt, + bool catch_bp, bool throw_bp) { BreakpointResolverSP resolver_sp; if (throw_bp) @@ -897,12 +896,12 @@ size_t AppleObjCRuntimeV2::GetByteOffsetForIvar(CompilerType &parent_ast_type, const char *ivar_name) { uint32_t ivar_offset = LLDB_INVALID_IVAR_OFFSET; - const char *class_name = parent_ast_type.GetConstTypeName().AsCString(); - if (class_name && class_name[0] && ivar_name && ivar_name[0]) { + ConstString class_name = parent_ast_type.GetTypeName(); + if (!class_name.IsEmpty() && ivar_name && ivar_name[0]) { // Make the objective C V2 mangled name for the ivar offset from the class // name and ivar name std::string buffer("OBJC_IVAR_$_"); - buffer.append(class_name); + buffer.append(class_name.AsCString()); buffer.push_back('.'); buffer.append(ivar_name); ConstString ivar_const_str(buffer.c_str()); @@ -1176,6 +1175,28 @@ AppleObjCRuntimeV2::GetClassDescriptorFromISA(ObjCISA isa) { return class_descriptor_sp; } +static std::pair ObjCGetClassNameRaw( + AppleObjCRuntime::ObjCISA isa, + Process *process) { + StreamString expr_string; + std::string input = std::to_string(isa); + expr_string.Printf("(const char *)objc_debug_class_getNameRaw(%s)", + input.c_str()); + + ValueObjectSP result_sp; + EvaluateExpressionOptions eval_options; + eval_options.SetLanguage(lldb::eLanguageTypeObjC); + eval_options.SetResultIsInternal(true); + eval_options.SetGenerateDebugInfo(true); + eval_options.SetTimeout(process->GetUtilityExpressionTimeout()); + auto eval_result = process->GetTarget().EvaluateExpression( + expr_string.GetData(), + process->GetThreadList().GetSelectedThread()->GetSelectedFrame().get(), + result_sp, eval_options); + ConstString type_name(result_sp->GetSummaryAsCString()); + return std::make_pair(eval_result == eExpressionCompleted, type_name); +} + ObjCLanguageRuntime::ClassDescriptorSP AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) { ClassDescriptorSP objc_class_sp; @@ -1192,32 +1213,43 @@ AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) { // if we get an invalid VO (which might still happen when playing around with // pointers returned by the expression parser, don't consider this a valid // ObjC object) - if (valobj.GetCompilerType().IsValid()) { - addr_t isa_pointer = valobj.GetPointerValue(); + if (!valobj.GetCompilerType().IsValid()) + return objc_class_sp; + addr_t isa_pointer = valobj.GetPointerValue(); - // tagged pointer - if (IsTaggedPointer(isa_pointer)) { - return m_tagged_pointer_vendor_up->GetClassDescriptor(isa_pointer); - } else { - ExecutionContext exe_ctx(valobj.GetExecutionContextRef()); + // tagged pointer + if (IsTaggedPointer(isa_pointer)) + return m_tagged_pointer_vendor_up->GetClassDescriptor(isa_pointer); + ExecutionContext exe_ctx(valobj.GetExecutionContextRef()); - Process *process = exe_ctx.GetProcessPtr(); - if (process) { - Status error; - ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error); - if (isa != LLDB_INVALID_ADDRESS) { - objc_class_sp = GetClassDescriptorFromISA(isa); - if (isa && !objc_class_sp) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - LLDB_LOGF(log, - "0x%" PRIx64 - ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was " - "not in class descriptor cache 0x%" PRIx64, - isa_pointer, isa); - } - } - } - } + Process *process = exe_ctx.GetProcessPtr(); + if (!process) + return objc_class_sp; + + Status error; + ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error); + if (isa == LLDB_INVALID_ADDRESS) + return objc_class_sp; + + objc_class_sp = GetClassDescriptorFromISA(isa); + + if (objc_class_sp) + return objc_class_sp; + else { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | + LIBLLDB_LOG_TYPES)); + LLDB_LOGF(log, + "0x%" PRIx64 + ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was " + "not in class descriptor cache 0x%" PRIx64, + isa_pointer, isa); + } + + ClassDescriptorSP descriptor_sp(new ClassDescriptorV2(*this, isa, nullptr)); + auto resolved = ObjCGetClassNameRaw(isa, process); + if (resolved.first == true) { + AddClass(isa, descriptor_sp, resolved.second.AsCString()); + objc_class_sp = descriptor_sp; } return objc_class_sp; } @@ -1301,7 +1333,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic( return DescriptorMapUpdateResult::Fail(); thread_sp->CalculateExecutionContext(exe_ctx); - ClangASTContext *ast = ClangASTContext::GetScratch(process->GetTarget()); + TypeSystemClang *ast = TypeSystemClang::GetScratch(process->GetTarget()); if (!ast) return DescriptorMapUpdateResult::Fail(); @@ -1434,8 +1466,6 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic( Value return_value; return_value.SetValueType(Value::eValueTypeScalar); - // return_value.SetContext (Value::eContextTypeClangType, - // clang_uint32_t_type); return_value.SetCompilerType(clang_uint32_t_type); return_value.GetScalar() = 0; @@ -1499,7 +1529,7 @@ uint32_t AppleObjCRuntimeV2::ParseClassInfoArray(const DataExtractor &data, // Iterate through all ClassInfo structures lldb::offset_t offset = 0; for (uint32_t i = 0; i < num_class_infos; ++i) { - ObjCISA isa = data.GetPointer(&offset); + ObjCISA isa = data.GetAddress(&offset); if (isa == 0) { if (should_log) @@ -1563,7 +1593,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { return DescriptorMapUpdateResult::Fail(); thread_sp->CalculateExecutionContext(exe_ctx); - ClangASTContext *ast = ClangASTContext::GetScratch(process->GetTarget()); + TypeSystemClang *ast = TypeSystemClang::GetScratch(process->GetTarget()); if (!ast) return DescriptorMapUpdateResult::Fail(); @@ -1660,13 +1690,11 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { // Next make the function caller for our implementation utility function. Value value; value.SetValueType(Value::eValueTypeScalar); - // value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type); value.SetCompilerType(clang_void_pointer_type); arguments.PushValue(value); arguments.PushValue(value); value.SetValueType(Value::eValueTypeScalar); - // value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type); value.SetCompilerType(clang_uint32_t_type); arguments.PushValue(value); arguments.PushValue(value); @@ -1732,8 +1760,6 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { Value return_value; return_value.SetValueType(Value::eValueTypeScalar); - // return_value.SetContext (Value::eContextTypeClangType, - // clang_uint32_t_type); return_value.SetCompilerType(clang_uint32_t_type); return_value.GetScalar() = 0; @@ -1980,7 +2006,7 @@ void AppleObjCRuntimeV2::WarnIfNoClassesCached( DeclVendor *AppleObjCRuntimeV2::GetDeclVendor() { if (!m_decl_vendor_up) - m_decl_vendor_up.reset(new AppleObjCDeclVendor(*this)); + m_decl_vendor_up = std::make_unique(*this); return m_decl_vendor_up.get(); } @@ -2477,7 +2503,7 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA( ObjCISA isa, ObjCISA &ret_isa) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES)); - LLDB_LOGF(log, "AOCRT::NPI Evalulate(isa = 0x%" PRIx64 ")", (uint64_t)isa); + LLDB_LOGF(log, "AOCRT::NPI Evaluate(isa = 0x%" PRIx64 ")", (uint64_t)isa); if ((isa & ~m_objc_debug_isa_class_mask) == 0) return false; @@ -2550,7 +2576,7 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA( lldb::offset_t offset = 0; for (unsigned i = 0; i != num_new_classes; ++i) - m_indexed_isa_cache.push_back(data.GetPointer(&offset)); + m_indexed_isa_cache.push_back(data.GetAddress(&offset)); } } @@ -2558,7 +2584,7 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA( if (index > m_indexed_isa_cache.size()) return false; - LLDB_LOGF(log, "AOCRT::NPI Evalulate(ret_isa = 0x%" PRIx64 ")", + LLDB_LOGF(log, "AOCRT::NPI Evaluate(ret_isa = 0x%" PRIx64 ")", (uint64_t)m_indexed_isa_cache[index]); ret_isa = m_indexed_isa_cache[index]; @@ -2642,8 +2668,8 @@ class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame { const lldb::ABISP &abi = process_sp->GetABI(); if (!abi) return; - ClangASTContext *clang_ast_context = - ClangASTContext::GetScratch(process_sp->GetTarget()); + TypeSystemClang *clang_ast_context = + TypeSystemClang::GetScratch(process_sp->GetTarget()); if (!clang_ast_context) return; CompilerType voidstar = @@ -2668,6 +2694,8 @@ class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame { m_arguments = ValueObjectListSP(new ValueObjectList()); m_arguments->Append(exception); + + m_stop_desc = "hit Objective-C exception"; } ValueObjectSP exception; @@ -2689,8 +2717,10 @@ static void RegisterObjCExceptionRecognizer() { FileSpec module; ConstString function; std::tie(module, function) = AppleObjCRuntime::GetExceptionThrowLocation(); + std::vector symbols = {function}; StackFrameRecognizerManager::AddRecognizer( StackFrameRecognizerSP(new ObjCExceptionThrowFrameRecognizer()), - module.GetFilename(), function, /*first_instruction_only*/ true); + module.GetFilename(), symbols, + /*first_instruction_only*/ true); }); } diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h index 785bb3938d2..99264d556da 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AppleObjCRuntimeV2_h_ -#define liblldb_AppleObjCRuntimeV2_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV2_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV2_H #include #include @@ -103,9 +103,9 @@ public: static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDate = 6; protected: - lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt, - bool catch_bp, - bool throw_bp) override; + lldb::BreakpointResolverSP + CreateExceptionResolver(const lldb::BreakpointSP &bkpt, + bool catch_bp, bool throw_bp) override; private: class HashTableSignature { @@ -162,7 +162,8 @@ private: friend class AppleObjCRuntimeV2; - DISALLOW_COPY_AND_ASSIGN(NonPointerISACache); + NonPointerISACache(const NonPointerISACache &) = delete; + const NonPointerISACache &operator=(const NonPointerISACache &) = delete; }; class TaggedPointerVendorV2 @@ -181,7 +182,9 @@ private: : TaggedPointerVendor(), m_runtime(runtime) {} private: - DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorV2); + TaggedPointerVendorV2(const TaggedPointerVendorV2 &) = delete; + const TaggedPointerVendorV2 & + operator=(const TaggedPointerVendorV2 &) = delete; }; class TaggedPointerVendorRuntimeAssisted : public TaggedPointerVendorV2 { @@ -212,7 +215,10 @@ private: friend class AppleObjCRuntimeV2::TaggedPointerVendorV2; - DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorRuntimeAssisted); + TaggedPointerVendorRuntimeAssisted( + const TaggedPointerVendorRuntimeAssisted &) = delete; + const TaggedPointerVendorRuntimeAssisted & + operator=(const TaggedPointerVendorRuntimeAssisted &) = delete; }; class TaggedPointerVendorExtended @@ -250,7 +256,9 @@ private: friend class AppleObjCRuntimeV2::TaggedPointerVendorV2; - DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorExtended); + TaggedPointerVendorExtended(const TaggedPointerVendorExtended &) = delete; + const TaggedPointerVendorExtended & + operator=(const TaggedPointerVendorExtended &) = delete; }; class TaggedPointerVendorLegacy : public TaggedPointerVendorV2 { @@ -266,7 +274,9 @@ private: friend class AppleObjCRuntimeV2::TaggedPointerVendorV2; - DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorLegacy); + TaggedPointerVendorLegacy(const TaggedPointerVendorLegacy &) = delete; + const TaggedPointerVendorLegacy & + operator=(const TaggedPointerVendorLegacy &) = delete; }; struct DescriptorMapUpdateResult { @@ -337,4 +347,4 @@ private: } // namespace lldb_private -#endif // liblldb_AppleObjCRuntimeV2_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV2_H diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp index 36f95c063b8..c96768c9f58 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp @@ -1,5 +1,4 @@ -//===-- AppleObjCTrampolineHandler.cpp ----------------------------*- C++ -//-*-===// +//===-- AppleObjCTrampolineHandler.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,6 +9,7 @@ #include "AppleObjCTrampolineHandler.h" #include "AppleThreadPlanStepThroughObjCTrampoline.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" @@ -19,7 +19,6 @@ #include "lldb/Expression/FunctionCaller.h" #include "lldb/Expression/UserExpression.h" #include "lldb/Expression/UtilityFunction.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContext.h" @@ -319,7 +318,7 @@ void AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::SetUpRegion() { const uint16_t descriptor_size = data.GetU16(&offset); const size_t num_descriptors = data.GetU32(&offset); - m_next_region = data.GetPointer(&offset); + m_next_region = data.GetAddress(&offset); // If the header size is 0, that means we've come in too early before this // data is set up. @@ -521,8 +520,8 @@ bool AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines( Process *process = exe_ctx.GetProcessPtr(); const ABI *abi = process->GetABI().get(); - ClangASTContext *clang_ast_context = - ClangASTContext::GetScratch(process->GetTarget()); + TypeSystemClang *clang_ast_context = + TypeSystemClang::GetScratch(process->GetTarget()); if (!clang_ast_context) return false; @@ -548,7 +547,7 @@ bool AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines( error = argument_values.GetValueAtIndex(0)->GetValueAsData(&exe_ctx, data, nullptr); lldb::offset_t offset = 0; - lldb::addr_t region_addr = data.GetPointer(&offset); + lldb::addr_t region_addr = data.GetAddress(&offset); if (region_addr != 0) vtable_handler->ReadRegions(region_addr); @@ -657,6 +656,27 @@ const AppleObjCTrampolineHandler::DispatchFunction DispatchFunction::eFixUpFixed}, }; +// This is the table of ObjC "accelerated dispatch" functions. They are a set +// of objc methods that are "seldom overridden" and so the compiler replaces the +// objc_msgSend with a call to one of the dispatch functions. That will check +// whether the method has been overridden, and directly call the Foundation +// implementation if not. +// This table is supposed to be complete. If ones get added in the future, we +// will have to add them to the table. +const char *AppleObjCTrampolineHandler::g_opt_dispatch_names[] = { + "objc_alloc", + "objc_autorelease", + "objc_release", + "objc_retain", + "objc_alloc_init", + "objc_allocWithZone", + "objc_opt_class", + "objc_opt_isKindOfClass", + "objc_opt_new", + "objc_opt_respondsToSelector", + "objc_opt_self", +}; + AppleObjCTrampolineHandler::AppleObjCTrampolineHandler( const ProcessSP &process_sp, const ModuleSP &objc_module_sp) : m_process_wp(), m_objc_module_sp(objc_module_sp), @@ -751,9 +771,24 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler( m_msgSend_map.insert(std::pair(sym_addr, i)); } } + + // Similarly, cache the addresses of the "optimized dispatch" function. + for (size_t i = 0; i != llvm::array_lengthof(g_opt_dispatch_names); i++) { + ConstString name_const_str(g_opt_dispatch_names[i]); + const Symbol *msgSend_symbol = + m_objc_module_sp->FindFirstSymbolWithNameAndType(name_const_str, + eSymbolTypeCode); + if (msgSend_symbol && msgSend_symbol->ValueIsAddress()) { + lldb::addr_t sym_addr = + msgSend_symbol->GetAddressRef().GetOpcodeLoadAddress(target); + + m_opt_dispatch_map.emplace(sym_addr, i); + } + } // Build our vtable dispatch handler here: - m_vtables_up.reset(new AppleObjCVTables(process_sp, m_objc_module_sp)); + m_vtables_up = + std::make_unique(process_sp, m_objc_module_sp); if (m_vtables_up) m_vtables_up->ReadRegions(); } @@ -804,8 +839,8 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread, } // Next make the runner function for our implementation utility function. - ClangASTContext *clang_ast_context = - ClangASTContext::GetScratch(thread.GetProcess()->GetTarget()); + TypeSystemClang *clang_ast_context = + TypeSystemClang::GetScratch(thread.GetProcess()->GetTarget()); if (!clang_ast_context) return LLDB_INVALID_ADDRESS; @@ -846,45 +881,53 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread, return args_addr; } +const AppleObjCTrampolineHandler::DispatchFunction * +AppleObjCTrampolineHandler::FindDispatchFunction(lldb::addr_t addr) { + MsgsendMap::iterator pos; + pos = m_msgSend_map.find(addr); + if (pos != m_msgSend_map.end()) { + return &g_dispatch_functions[(*pos).second]; + } + return nullptr; +} + +void +AppleObjCTrampolineHandler::ForEachDispatchFunction( + std::function callback) { + for (auto elem : m_msgSend_map) { + callback(elem.first, g_dispatch_functions[elem.second]); + } +} + ThreadPlanSP AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, bool stop_others) { ThreadPlanSP ret_plan_sp; lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC(); - DispatchFunction this_dispatch; - bool found_it = false; + DispatchFunction vtable_dispatch + = {"vtable", 0, false, false, DispatchFunction::eFixUpFixed}; // First step is to look and see if we are in one of the known ObjC // dispatch functions. We've already compiled a table of same, so // consult it. - MsgsendMap::iterator pos; - pos = m_msgSend_map.find(curr_pc); - if (pos != m_msgSend_map.end()) { - this_dispatch = g_dispatch_functions[(*pos).second]; - found_it = true; - } - + const DispatchFunction *this_dispatch = FindDispatchFunction(curr_pc); + // Next check to see if we are in a vtable region: - if (!found_it) { + if (!this_dispatch && m_vtables_up) { uint32_t flags; - if (m_vtables_up) { - found_it = m_vtables_up->IsAddressInVTables(curr_pc, flags); - if (found_it) { - this_dispatch.name = "vtable"; - this_dispatch.stret_return = - (flags & AppleObjCVTables::eOBJC_TRAMPOLINE_STRET) == - AppleObjCVTables::eOBJC_TRAMPOLINE_STRET; - this_dispatch.is_super = false; - this_dispatch.is_super2 = false; - this_dispatch.fixedup = DispatchFunction::eFixUpFixed; - } + if (m_vtables_up->IsAddressInVTables(curr_pc, flags)) { + vtable_dispatch.stret_return = + (flags & AppleObjCVTables::eOBJC_TRAMPOLINE_STRET) == + AppleObjCVTables::eOBJC_TRAMPOLINE_STRET; + this_dispatch = &vtable_dispatch; } } - if (found_it) { + if (this_dispatch) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); // We are decoding a method dispatch. First job is to pull the @@ -901,7 +944,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, TargetSP target_sp(thread.CalculateTarget()); - ClangASTContext *clang_ast_context = ClangASTContext::GetScratch(*target_sp); + TypeSystemClang *clang_ast_context = TypeSystemClang::GetScratch(*target_sp); if (!clang_ast_context) return ret_plan_sp; @@ -921,7 +964,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, // the return struct pointer, and the object is the second, and // the selector is the third. Otherwise the object is the first // and the selector the second. - if (this_dispatch.stret_return) { + if (this_dispatch->stret_return) { obj_index = 1; sel_index = 2; argument_values.PushValue(void_ptr_value); @@ -963,8 +1006,8 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, // run-to-address plan directly. Otherwise we have to figure out // where the implementation lives. - if (this_dispatch.is_super) { - if (this_dispatch.is_super2) { + if (this_dispatch->is_super) { + if (this_dispatch->is_super2) { // In the objc_msgSendSuper2 case, we don't get the object // directly, we get a structure containing the object and the // class to which the super message is being sent. So we need @@ -1087,25 +1130,25 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, // flag_value.SetContext (Value::eContextTypeClangType, clang_int_type); flag_value.SetCompilerType(clang_int_type); - if (this_dispatch.stret_return) + if (this_dispatch->stret_return) flag_value.GetScalar() = 1; else flag_value.GetScalar() = 0; dispatch_values.PushValue(flag_value); - if (this_dispatch.is_super) + if (this_dispatch->is_super) flag_value.GetScalar() = 1; else flag_value.GetScalar() = 0; dispatch_values.PushValue(flag_value); - if (this_dispatch.is_super2) + if (this_dispatch->is_super2) flag_value.GetScalar() = 1; else flag_value.GetScalar() = 0; dispatch_values.PushValue(flag_value); - switch (this_dispatch.fixedup) { + switch (this_dispatch->fixedup) { case DispatchFunction::eFixUpNone: flag_value.GetScalar() = 0; dispatch_values.PushValue(flag_value); @@ -1135,7 +1178,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, // stop_others value passed in to us here: const bool trampoline_stop_others = false; ret_plan_sp = std::make_shared( - thread, this, dispatch_values, isa_addr, sel_addr, + thread, *this, dispatch_values, isa_addr, sel_addr, trampoline_stop_others); if (log) { StreamString s; @@ -1144,6 +1187,26 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, } } } + + // Finally, check if we have hit an "optimized dispatch" function. This will + // either directly call the base implementation or dispatch an objc_msgSend + // if the method has been overridden. So we just do a "step in/step out", + // setting a breakpoint on objc_msgSend, and if we hit the msgSend, we + // will automatically step in again. That's the job of the + // AppleThreadPlanStepThroughDirectDispatch. + if (!this_dispatch && !ret_plan_sp) { + MsgsendMap::iterator pos; + pos = m_opt_dispatch_map.find(curr_pc); + if (pos != m_opt_dispatch_map.end()) { + + const char *opt_name = g_opt_dispatch_names[(*pos).second]; + + bool trampoline_stop_others = false; + LazyBool step_in_should_stop = eLazyBoolCalculate; + ret_plan_sp = std::make_shared ( + thread, *this, opt_name, trampoline_stop_others, step_in_should_stop); + } + } return ret_plan_sp; } diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h index d120d671eeb..27aebd8594d 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_AppleObjCTrampolineHandler_h_ -#define lldb_AppleObjCTrampolineHandler_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTRAMPOLINEHANDLER_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTRAMPOLINEHANDLER_H #include #include @@ -47,6 +47,9 @@ public: lldb::addr_t SetupDispatchFunction(Thread &thread, ValueList &dispatch_values); + const DispatchFunction *FindDispatchFunction(lldb::addr_t addr); + void ForEachDispatchFunction(std::function); private: static const char *g_lookup_implementation_function_name; @@ -96,7 +99,6 @@ private: void Dump(Stream &s); - public: bool m_valid; AppleObjCVTables *m_owner; lldb::addr_t m_header_addr; @@ -136,11 +138,13 @@ private: }; static const DispatchFunction g_dispatch_functions[]; + static const char *g_opt_dispatch_names[]; - typedef std::map MsgsendMap; // This table maps an dispatch + using MsgsendMap = std::map; // This table maps an dispatch // fn address to the index in // g_dispatch_functions MsgsendMap m_msgSend_map; + MsgsendMap m_opt_dispatch_map; lldb::ProcessWP m_process_wp; lldb::ModuleSP m_objc_module_sp; const char *m_lookup_implementation_function_code; @@ -155,4 +159,4 @@ private: } // namespace lldb_private -#endif // lldb_AppleObjCTrampolineHandler_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTRAMPOLINEHANDLER_H diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp index 66f04bef6cb..b19d3d90d4b 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp @@ -1,4 +1,4 @@ -//===-- AppleObjCTypeEncodingParser.cpp -------------------------*- C++ -*-===// +//===-- AppleObjCTypeEncodingParser.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,13 +8,15 @@ #include "AppleObjCTypeEncodingParser.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangUtil.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/StringLexer.h" +#include "clang/Basic/TargetInfo.h" + #include using namespace lldb_private; @@ -23,17 +25,16 @@ AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser( ObjCLanguageRuntime &runtime) : ObjCLanguageRuntime::EncodingToType(), m_runtime(runtime) { if (!m_scratch_ast_ctx_up) - m_scratch_ast_ctx_up.reset(new ClangASTContext(runtime.GetProcess() - ->GetTarget() - .GetArchitecture() - .GetTriple())); + m_scratch_ast_ctx_up = std::make_unique( + "AppleObjCTypeEncodingParser ASTContext", + runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple()); } std::string AppleObjCTypeEncodingParser::ReadStructName(StringLexer &type) { StreamString buffer; while (type.HasAtLeast(1) && type.Peek() != '=') buffer.Printf("%c", type.Next()); - return buffer.GetString(); + return std::string(buffer.GetString()); } std::string AppleObjCTypeEncodingParser::ReadQuotedString(StringLexer &type) { @@ -43,7 +44,7 @@ std::string AppleObjCTypeEncodingParser::ReadQuotedString(StringLexer &type) { StringLexer::Character next = type.Next(); UNUSED_IF_ASSERT_DISABLED(next); assert(next == '"'); - return buffer.GetString(); + return std::string(buffer.GetString()); } uint32_t AppleObjCTypeEncodingParser::ReadNumber(StringLexer &type) { @@ -61,7 +62,7 @@ AppleObjCTypeEncodingParser::StructElement::StructElement() : name(""), type(clang::QualType()), bitfield(0) {} AppleObjCTypeEncodingParser::StructElement -AppleObjCTypeEncodingParser::ReadStructElement(ClangASTContext &ast_ctx, +AppleObjCTypeEncodingParser::ReadStructElement(TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) { StructElement retval; @@ -76,19 +77,19 @@ AppleObjCTypeEncodingParser::ReadStructElement(ClangASTContext &ast_ctx, } clang::QualType AppleObjCTypeEncodingParser::BuildStruct( - ClangASTContext &ast_ctx, StringLexer &type, bool for_expression) { + TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) { return BuildAggregate(ast_ctx, type, for_expression, '{', '}', clang::TTK_Struct); } clang::QualType AppleObjCTypeEncodingParser::BuildUnion( - ClangASTContext &ast_ctx, StringLexer &type, bool for_expression) { + TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) { return BuildAggregate(ast_ctx, type, for_expression, '(', ')', clang::TTK_Union); } clang::QualType AppleObjCTypeEncodingParser::BuildAggregate( - ClangASTContext &ast_ctx, StringLexer &type, bool for_expression, + TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression, char opener, char closer, uint32_t kind) { if (!type.NextIf(opener)) return clang::QualType(); @@ -123,29 +124,30 @@ clang::QualType AppleObjCTypeEncodingParser::BuildAggregate( return clang::QualType(); // This is where we bail out. Sorry! CompilerType union_type(ast_ctx.CreateRecordType( - nullptr, lldb::eAccessPublic, name, kind, lldb::eLanguageTypeC)); + nullptr, OptionalClangModuleID(), lldb::eAccessPublic, name, kind, + lldb::eLanguageTypeC)); if (union_type) { - ClangASTContext::StartTagDeclarationDefinition(union_type); + TypeSystemClang::StartTagDeclarationDefinition(union_type); unsigned int count = 0; for (auto element : elements) { if (element.name.empty()) { StreamString elem_name; elem_name.Printf("__unnamed_%u", count); - element.name = elem_name.GetString(); + element.name = std::string(elem_name.GetString()); } - ClangASTContext::AddFieldToRecordType( + TypeSystemClang::AddFieldToRecordType( union_type, element.name.c_str(), ast_ctx.GetType(element.type), lldb::eAccessPublic, element.bitfield); ++count; } - ClangASTContext::CompleteTagDeclarationDefinition(union_type); + TypeSystemClang::CompleteTagDeclarationDefinition(union_type); } return ClangUtil::GetQualType(union_type); } clang::QualType AppleObjCTypeEncodingParser::BuildArray( - ClangASTContext &ast_ctx, StringLexer &type, bool for_expression) { + TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) { if (!type.NextIf('[')) return clang::QualType(); uint32_t size = ReadNumber(type); @@ -163,7 +165,7 @@ clang::QualType AppleObjCTypeEncodingParser::BuildArray( // consume but ignore the type info and always return an 'id'; if anything, // dynamic typing will resolve things for us anyway clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType( - ClangASTContext &clang_ast_ctx, StringLexer &type, bool for_expression) { + TypeSystemClang &clang_ast_ctx, StringLexer &type, bool for_expression) { if (!type.NextIf('@')) return clang::QualType(); @@ -247,7 +249,7 @@ clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType( } clang::QualType -AppleObjCTypeEncodingParser::BuildType(ClangASTContext &clang_ast_ctx, +AppleObjCTypeEncodingParser::BuildType(TypeSystemClang &clang_ast_ctx, StringLexer &type, bool for_expression, uint32_t *bitfield_bit_size) { if (!type.HasAtLeast(1)) @@ -353,7 +355,7 @@ AppleObjCTypeEncodingParser::BuildType(ClangASTContext &clang_ast_ctx, } } -CompilerType AppleObjCTypeEncodingParser::RealizeType(ClangASTContext &ast_ctx, +CompilerType AppleObjCTypeEncodingParser::RealizeType(TypeSystemClang &ast_ctx, const char *name, bool for_expression) { if (name && name[0]) { diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h index e43711bf4ee..9a108967e1a 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AppleObjCTypeEncodingParser_h_ -#define liblldb_AppleObjCTypeEncodingParser_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTYPEENCODINGPARSER_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTYPEENCODINGPARSER_H #include "clang/AST/ASTContext.h" @@ -22,7 +22,7 @@ public: AppleObjCTypeEncodingParser(ObjCLanguageRuntime &runtime); ~AppleObjCTypeEncodingParser() override = default; - CompilerType RealizeType(ClangASTContext &ast_ctx, const char *name, + CompilerType RealizeType(TypeSystemClang &ast_ctx, const char *name, bool for_expression) override; private: @@ -35,29 +35,29 @@ private: ~StructElement() = default; }; - clang::QualType BuildType(ClangASTContext &clang_ast_ctx, StringLexer &type, + clang::QualType BuildType(TypeSystemClang &clang_ast_ctx, StringLexer &type, bool for_expression, uint32_t *bitfield_bit_size = nullptr); - clang::QualType BuildStruct(ClangASTContext &ast_ctx, StringLexer &type, + clang::QualType BuildStruct(TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression); - clang::QualType BuildAggregate(ClangASTContext &clang_ast_ctx, + clang::QualType BuildAggregate(TypeSystemClang &clang_ast_ctx, StringLexer &type, bool for_expression, char opener, char closer, uint32_t kind); - clang::QualType BuildUnion(ClangASTContext &ast_ctx, StringLexer &type, + clang::QualType BuildUnion(TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression); - clang::QualType BuildArray(ClangASTContext &ast_ctx, StringLexer &type, + clang::QualType BuildArray(TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression); std::string ReadStructName(StringLexer &type); - StructElement ReadStructElement(ClangASTContext &ast_ctx, StringLexer &type, + StructElement ReadStructElement(TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression); - clang::QualType BuildObjCObjectPointerType(ClangASTContext &clang_ast_ctx, + clang::QualType BuildObjCObjectPointerType(TypeSystemClang &clang_ast_ctx, StringLexer &type, bool for_expression); @@ -70,4 +70,4 @@ private: } // namespace lldb_private -#endif // liblldb_AppleObjCTypeEncodingParser_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTYPEENCODINGPARSER_H diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp index af630eee726..653e007c7b5 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp @@ -1,4 +1,4 @@ -//===-- AppleThreadPlanStepThroughObjCTrampoline.cpp +//===-- AppleThreadPlanStepThroughObjCTrampoline.cpp-----------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -29,7 +29,7 @@ using namespace lldb_private; // ThreadPlanStepThroughObjCTrampoline constructor AppleThreadPlanStepThroughObjCTrampoline:: AppleThreadPlanStepThroughObjCTrampoline( - Thread &thread, AppleObjCTrampolineHandler *trampoline_handler, + Thread &thread, AppleObjCTrampolineHandler &trampoline_handler, ValueList &input_values, lldb::addr_t isa_addr, lldb::addr_t sel_addr, bool stop_others) : ThreadPlan(ThreadPlan::eKindGeneric, @@ -48,31 +48,30 @@ void AppleThreadPlanStepThroughObjCTrampoline::DidPush() { // Setting up the memory space for the called function text might require // allocations, i.e. a nested function call. This needs to be done as a // PreResumeAction. - m_thread.GetProcess()->AddPreResumeAction(PreResumeInitializeFunctionCaller, - (void *)this); + m_process.AddPreResumeAction(PreResumeInitializeFunctionCaller, (void *)this); } bool AppleThreadPlanStepThroughObjCTrampoline::InitializeFunctionCaller() { if (!m_func_sp) { DiagnosticManager diagnostics; m_args_addr = - m_trampoline_handler->SetupDispatchFunction(m_thread, m_input_values); + m_trampoline_handler.SetupDispatchFunction(GetThread(), m_input_values); if (m_args_addr == LLDB_INVALID_ADDRESS) { return false; } m_impl_function = - m_trampoline_handler->GetLookupImplementationFunctionCaller(); + m_trampoline_handler.GetLookupImplementationFunctionCaller(); ExecutionContext exc_ctx; EvaluateExpressionOptions options; options.SetUnwindOnError(true); options.SetIgnoreBreakpoints(true); options.SetStopOthers(m_stop_others); - m_thread.CalculateExecutionContext(exc_ctx); + GetThread().CalculateExecutionContext(exc_ctx); m_func_sp = m_impl_function->GetThreadPlanToCallFunction( exc_ctx, m_args_addr, options, diagnostics); m_func_sp->SetOkayToDiscard(true); - m_thread.QueueThreadPlan(m_func_sp, false); + PushPlan(m_func_sp); } return true; } @@ -132,7 +131,7 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) { if (!m_run_to_sp) { Value target_addr_value; ExecutionContext exc_ctx; - m_thread.CalculateExecutionContext(exc_ctx); + GetThread().CalculateExecutionContext(exc_ctx); m_impl_function->FetchFunctionResults(exc_ctx, m_args_addr, target_addr_value); m_impl_function->DeallocateFunctionResults(exc_ctx, m_args_addr); @@ -145,19 +144,19 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) { SetPlanComplete(); return true; } - if (m_trampoline_handler->AddrIsMsgForward(target_addr)) { + if (m_trampoline_handler.AddrIsMsgForward(target_addr)) { LLDB_LOGF(log, "Implementation lookup returned msgForward function: 0x%" PRIx64 ", stopping.", target_addr); - SymbolContext sc = m_thread.GetStackFrameAtIndex(0)->GetSymbolContext( + SymbolContext sc = GetThread().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( + m_run_to_sp = GetThread().QueueThreadPlanForStepOutNoShouldStop( abort_other_plans, &sc, first_insn, m_stop_others, eVoteNoOpinion, eVoteNoOpinion, frame_idx, status); if (m_run_to_sp && status.Success()) @@ -180,11 +179,10 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) { // Extract the target address from the value: m_run_to_sp = std::make_shared( - m_thread, target_so_addr, m_stop_others); - m_thread.QueueThreadPlan(m_run_to_sp, false); - m_run_to_sp->SetPrivate(true); + GetThread(), target_so_addr, m_stop_others); + PushPlan(m_run_to_sp); return false; - } else if (m_thread.IsThreadPlanDone(m_run_to_sp.get())) { + } else if (GetThread().IsThreadPlanDone(m_run_to_sp.get())) { // Third stage, work the run to target plan. SetPlanComplete(); return true; @@ -199,3 +197,227 @@ bool AppleThreadPlanStepThroughObjCTrampoline::MischiefManaged() { } bool AppleThreadPlanStepThroughObjCTrampoline::WillStop() { return true; } + +// Objective-C uses optimized dispatch functions for some common and seldom +// overridden methods. For instance +// [object respondsToSelector:]; +// will get compiled to: +// objc_opt_respondsToSelector(object); +// This checks whether the selector has been overridden, directly calling the +// implementation if it hasn't and calling objc_msgSend if it has. +// +// We need to get into the overridden implementation. We'll do that by +// setting a breakpoint on objc_msgSend, and doing a "step out". If we stop +// at objc_msgSend, we can step through to the target of the send, and see if +// that's a place we want to stop. +// +// A couple of complexities. The checking code might call some other method, +// so we might see objc_msgSend more than once. Also, these optimized dispatch +// functions might dispatch more than one message at a time (e.g. alloc followed +// by init.) So we can't give up at the first objc_msgSend. +// That means among other things that we have to handle the "ShouldStopHere" - +// since we can't just return control to the plan that's controlling us on the +// first step. + +AppleThreadPlanStepThroughDirectDispatch :: + AppleThreadPlanStepThroughDirectDispatch( + Thread &thread, AppleObjCTrampolineHandler &handler, + llvm::StringRef dispatch_func_name, bool stop_others, + LazyBool step_in_avoids_code_without_debug_info) + : ThreadPlanStepOut(thread, nullptr, true /* first instruction */, + stop_others, eVoteNoOpinion, eVoteNoOpinion, + 0 /* Step out of zeroth frame */, + eLazyBoolNo /* Our parent plan will decide this + when we are done */ + , + true /* Run to branch for inline step out */, + false /* Don't gather the return value */), + m_trampoline_handler(handler), + m_dispatch_func_name(std::string(dispatch_func_name)), + m_at_msg_send(false), m_stop_others(stop_others) { + // Set breakpoints on the dispatch functions: + auto bkpt_callback = [&] (lldb::addr_t addr, + const AppleObjCTrampolineHandler + ::DispatchFunction &dispatch) { + m_msgSend_bkpts.push_back(GetTarget().CreateBreakpoint(addr, + true /* internal */, + false /* hard */)); + m_msgSend_bkpts.back()->SetThreadID(GetThread().GetID()); + }; + handler.ForEachDispatchFunction(bkpt_callback); + + // We'll set the step-out plan in the DidPush so it gets queued in the right + // order. + + bool avoid_nodebug = true; + + switch (step_in_avoids_code_without_debug_info) { + case eLazyBoolYes: + avoid_nodebug = true; + break; + case eLazyBoolNo: + avoid_nodebug = false; + break; + case eLazyBoolCalculate: + avoid_nodebug = GetThread().GetStepInAvoidsNoDebug(); + break; + } + if (avoid_nodebug) + GetFlags().Set(ThreadPlanShouldStopHere::eStepInAvoidNoDebug); + else + GetFlags().Clear(ThreadPlanShouldStopHere::eStepInAvoidNoDebug); + // We only care about step in. Our parent plan will figure out what to + // do when we've stepped out again. + GetFlags().Clear(ThreadPlanShouldStopHere::eStepOutAvoidNoDebug); +} + +AppleThreadPlanStepThroughDirectDispatch:: + ~AppleThreadPlanStepThroughDirectDispatch() { + for (BreakpointSP bkpt_sp : m_msgSend_bkpts) { + GetTarget().RemoveBreakpointByID(bkpt_sp->GetID()); + } +} + +void AppleThreadPlanStepThroughDirectDispatch::GetDescription( + Stream *s, lldb::DescriptionLevel level) { + switch (level) { + case lldb::eDescriptionLevelBrief: + s->PutCString("Step through ObjC direct dispatch function."); + break; + default: + s->Printf("Step through ObjC direct dispatch '%s' using breakpoints: ", + m_dispatch_func_name.c_str()); + bool first = true; + for (auto bkpt_sp : m_msgSend_bkpts) { + if (!first) { + s->PutCString(", "); + } + first = false; + s->Printf("%d", bkpt_sp->GetID()); + } + (*s) << "."; + break; + } +} + +bool +AppleThreadPlanStepThroughDirectDispatch::DoPlanExplainsStop(Event *event_ptr) { + if (ThreadPlanStepOut::DoPlanExplainsStop(event_ptr)) + return true; + + StopInfoSP stop_info_sp = GetPrivateStopInfo(); + + // Check if the breakpoint is one of ours msgSend dispatch breakpoints. + + StopReason stop_reason = eStopReasonNone; + if (stop_info_sp) + stop_reason = stop_info_sp->GetStopReason(); + + // See if this is one of our msgSend breakpoints: + if (stop_reason == eStopReasonBreakpoint) { + ProcessSP process_sp = GetThread().GetProcess(); + uint64_t break_site_id = stop_info_sp->GetValue(); + BreakpointSiteSP site_sp + = process_sp->GetBreakpointSiteList().FindByID(break_site_id); + // Some other plan might have deleted the site's last owner before this + // got to us. In which case, it wasn't our breakpoint... + if (!site_sp) + return false; + + for (BreakpointSP break_sp : m_msgSend_bkpts) { + if (site_sp->IsBreakpointAtThisSite(break_sp->GetID())) { + // If we aren't the only one with a breakpoint on this site, then we + // should just stop and return control to the user. + if (site_sp->GetNumberOfOwners() > 1) { + SetPlanComplete(true); + return false; + } + m_at_msg_send = true; + return true; + } + } + } + + // We're done here. If one of our sub-plans explained the stop, they + // would have already answered true to PlanExplainsStop, and if they were + // done, we'll get called to figure out what to do in ShouldStop... + return false; +} + +bool AppleThreadPlanStepThroughDirectDispatch + ::DoWillResume(lldb::StateType resume_state, bool current_plan) { + ThreadPlanStepOut::DoWillResume(resume_state, current_plan); + m_at_msg_send = false; + return true; +} + +bool AppleThreadPlanStepThroughDirectDispatch::ShouldStop(Event *event_ptr) { + // If step out plan finished, that means we didn't find our way into a method + // implementation. Either we went directly to the default implementation, + // of the overridden implementation didn't have debug info. + // So we should mark ourselves as done. + const bool step_out_should_stop = ThreadPlanStepOut::ShouldStop(event_ptr); + if (step_out_should_stop) { + SetPlanComplete(true); + return true; + } + + // If we have a step through plan, then w're in the process of getting + // through an ObjC msgSend. If we arrived at the target function, then + // check whether we have debug info, and if we do, stop. + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + + if (m_objc_step_through_sp && m_objc_step_through_sp->IsPlanComplete()) { + // If the plan failed for some reason, we should probably just let the + // step over plan get us out of here... We don't need to do anything about + // the step through plan, it is done and will get popped when we continue. + if (!m_objc_step_through_sp->PlanSucceeded()) { + LLDB_LOGF(log, "ObjC Step through plan failed. Stepping out."); + } + Status error; + if (InvokeShouldStopHereCallback(eFrameCompareYounger, error)) { + SetPlanComplete(true); + return true; + } + // If we didn't want to stop at this msgSend, there might be another so + // we should just continue on with the step out and see if our breakpoint + // triggers again. + m_objc_step_through_sp.reset(); + for (BreakpointSP bkpt_sp : m_msgSend_bkpts) { + bkpt_sp->SetEnabled(true); + } + return false; + } + + // If we hit an msgSend breakpoint, then we should queue the step through + // plan: + + if (m_at_msg_send) { + LanguageRuntime *objc_runtime + = GetThread().GetProcess()->GetLanguageRuntime(eLanguageTypeObjC); + // There's no way we could have gotten here without an ObjC language + // runtime. + assert(objc_runtime); + m_objc_step_through_sp + = objc_runtime->GetStepThroughTrampolinePlan(GetThread(), m_stop_others); + // If we failed to find the target for this dispatch, just keep going and + // let the step out complete. + if (!m_objc_step_through_sp) { + LLDB_LOG(log, "Couldn't find target for message dispatch, continuing."); + return false; + } + // Otherwise push the step through plan and continue. + GetThread().QueueThreadPlan(m_objc_step_through_sp, false); + for (BreakpointSP bkpt_sp : m_msgSend_bkpts) { + bkpt_sp->SetEnabled(false); + } + return false; + } + return true; +} + +bool AppleThreadPlanStepThroughDirectDispatch::MischiefManaged() { + if (IsPlanComplete()) + return true; + return ThreadPlanStepOut::MischiefManaged(); +} diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h index 96f37851a35..89aed89f1ab 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h @@ -6,12 +6,15 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_AppleThreadPlanStepThroughObjCTrampoline_h_ -#define lldb_AppleThreadPlanStepThroughObjCTrampoline_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLETHREADPLANSTEPTHROUGHOBJCTRAMPOLINE_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLETHREADPLANSTEPTHROUGHOBJCTRAMPOLINE_H #include "AppleObjCTrampolineHandler.h" #include "lldb/Core/Value.h" #include "lldb/Target/ThreadPlan.h" +#include "lldb/Target/ThreadPlanStepInRange.h" +#include "lldb/Target/ThreadPlanStepOut.h" +#include "lldb/Target/ThreadPlanShouldStopHere.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-types.h" @@ -20,7 +23,7 @@ namespace lldb_private { class AppleThreadPlanStepThroughObjCTrampoline : public ThreadPlan { public: AppleThreadPlanStepThroughObjCTrampoline( - Thread &thread, AppleObjCTrampolineHandler *trampoline_handler, + Thread &thread, AppleObjCTrampolineHandler &trampoline_handler, ValueList &values, lldb::addr_t isa_addr, lldb::addr_t sel_addr, bool stop_others); @@ -52,25 +55,62 @@ protected: private: bool InitializeFunctionCaller(); - AppleObjCTrampolineHandler *m_trampoline_handler; // FIXME - ensure this - // doesn't go away on us? - // SP maybe? - lldb::addr_t m_args_addr; // Stores the address for our step through function - // result structure. - // lldb::addr_t m_object_addr; // This is only for Description. + AppleObjCTrampolineHandler &m_trampoline_handler; /// The handler itself. + lldb::addr_t m_args_addr; /// Stores the address for our step through function + /// result structure. ValueList m_input_values; - lldb::addr_t m_isa_addr; // isa_addr and sel_addr are the keys we will use to - // cache the implementation. + lldb::addr_t m_isa_addr; /// isa_addr and sel_addr are the keys we will use to + /// cache the implementation. lldb::addr_t m_sel_addr; - lldb::ThreadPlanSP m_func_sp; // This is the function call plan. We fill it - // at start, then set it - // to NULL when this plan is done. That way we know to go to: - lldb::ThreadPlanSP m_run_to_sp; // The plan that runs to the target. - FunctionCaller *m_impl_function; // This is a pointer to a impl function that - // is owned by the client that pushes this plan. - bool m_stop_others; + lldb::ThreadPlanSP m_func_sp; /// This is the function call plan. We fill it + /// at start, then set it to NULL when this plan + /// is done. That way we know to go on to: + lldb::ThreadPlanSP m_run_to_sp; /// The plan that runs to the target. + FunctionCaller *m_impl_function; /// This is a pointer to a impl function that + /// is owned by the client that pushes this + /// plan. + bool m_stop_others; /// Whether we should stop other threads. +}; + +class AppleThreadPlanStepThroughDirectDispatch: public ThreadPlanStepOut { +public: + AppleThreadPlanStepThroughDirectDispatch( + Thread &thread, AppleObjCTrampolineHandler &handler, + llvm::StringRef dispatch_func_name, bool stop_others, + LazyBool step_in_avoids_code_without_debug_info); + + ~AppleThreadPlanStepThroughDirectDispatch() override; + + void GetDescription(Stream *s, lldb::DescriptionLevel level) override; + + bool ShouldStop(Event *event_ptr) override; + + bool StopOthers() override { return m_stop_others; } + + bool MischiefManaged() override; + + bool DoWillResume(lldb::StateType resume_state, bool current_plan) override; + + void SetFlagsToDefault() override { + GetFlags().Set(ThreadPlanStepInRange::GetDefaultFlagsValue()); + } + +protected: + bool DoPlanExplainsStop(Event *event_ptr) override; + + AppleObjCTrampolineHandler &m_trampoline_handler; + std::string m_dispatch_func_name; /// Which dispatch function we're stepping + /// through. + lldb::ThreadPlanSP m_objc_step_through_sp; /// When we hit an objc_msgSend, + /// we'll use this plan to get to + /// its target. + std::vector m_msgSend_bkpts; /// Breakpoints on the objc + /// dispatch functions. + bool m_at_msg_send; /// Are we currently handling an msg_send + bool m_stop_others; /// Whether we should stop other threads. + }; } // namespace lldb_private -#endif // lldb_AppleThreadPlanStepThroughObjCTrampoline_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLETHREADPLANSTEPTHROUGHOBJCTRAMPOLINE_H diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/CMakeLists.txt index bcf324023c2..3789f563259 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/CMakeLists.txt @@ -19,6 +19,7 @@ add_lldb_library(lldbPluginAppleObjCRuntime PLUGIN lldbUtility lldbPluginExpressionParserClang lldbPluginCPPRuntime + lldbPluginTypeSystemClang CLANG_LIBS clangAST LINK_COMPONENTS diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/CMakeLists.txt index 5b3ea2ff27f..d6de9dcc31b 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/CMakeLists.txt @@ -1,4 +1,4 @@ -add_lldb_library(lldbPluginObjCRuntime PLUGIN +add_lldb_library(lldbPluginObjCRuntime ObjCLanguageRuntime.cpp LINK_LIBS diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp index 9eb493f83c8..2ccf9b33f9d 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp @@ -1,4 +1,4 @@ -//===-- ObjCLanguageRuntime.cpp ---------------------------------*- C++ -*-===// +//===-- ObjCLanguageRuntime.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,11 +9,11 @@ #include "ObjCLanguageRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/MappedHash.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/ValueObject.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/Type.h" @@ -41,7 +41,7 @@ ObjCLanguageRuntime::ObjCLanguageRuntime(Process *process) m_isa_to_descriptor_stop_id(UINT32_MAX), m_complete_class_cache(), m_negative_complete_class_cache() {} -bool ObjCLanguageRuntime::IsWhitelistedRuntimeValue(ConstString name) { +bool ObjCLanguageRuntime::IsAllowedRuntimeValue(ConstString name) { static ConstString g_self = ConstString("self"); static ConstString g_cmd = ConstString("_cmd"); return name == g_self || name == g_cmd; @@ -127,9 +127,9 @@ ObjCLanguageRuntime::LookupInCompleteClassCache(ConstString &name) { for (uint32_t i = 0; i < types.GetSize(); ++i) { TypeSP type_sp(types.GetTypeAtIndex(i)); - if (ClangASTContext::IsObjCObjectOrInterfaceType( + if (TypeSystemClang::IsObjCObjectOrInterfaceType( type_sp->GetForwardCompilerType())) { - if (type_sp->IsCompleteObjCClass()) { + if (TypePayloadClang(type_sp->GetPayload()).IsCompleteObjCClass()) { m_complete_class_cache[name] = type_sp; return type_sp; } @@ -387,9 +387,9 @@ ObjCLanguageRuntime::GetRuntimeType(CompilerType base_type) { CompilerType class_type; bool is_pointer_type = false; - if (ClangASTContext::IsObjCObjectPointerType(base_type, &class_type)) + if (TypeSystemClang::IsObjCObjectPointerType(base_type, &class_type)) is_pointer_type = true; - else if (ClangASTContext::IsObjCObjectOrInterfaceType(base_type)) + else if (TypeSystemClang::IsObjCObjectOrInterfaceType(base_type)) class_type = base_type; else return llvm::None; @@ -397,7 +397,7 @@ ObjCLanguageRuntime::GetRuntimeType(CompilerType base_type) { if (!class_type) return llvm::None; - ConstString class_name(class_type.GetConstTypeName()); + ConstString class_name(class_type.GetTypeName()); if (!class_name) return llvm::None; diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h index b9a4d5dae08..c43acf54bbc 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ObjCLanguageRuntime_h_ -#define liblldb_ObjCLanguageRuntime_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_OBJCLANGUAGERUNTIME_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_OBJCLANGUAGERUNTIME_H #include #include @@ -17,7 +17,6 @@ #include "llvm/Support/Casting.h" #include "lldb/Breakpoint/BreakpointPrecondition.h" -#include "lldb/Core/ClangForward.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Core/ThreadSafeDenseMap.h" #include "lldb/Symbol/CompilerType.h" @@ -29,6 +28,7 @@ class CommandObjectObjC_ClassTable_Dump; namespace lldb_private { +class TypeSystemClang; class UtilityFunction; class ObjCLanguageRuntime : public LanguageRuntime { @@ -144,12 +144,12 @@ public: public: virtual ~EncodingToType(); - virtual CompilerType RealizeType(ClangASTContext &ast_ctx, const char *name, + virtual CompilerType RealizeType(TypeSystemClang &ast_ctx, const char *name, bool for_expression) = 0; virtual CompilerType RealizeType(const char *name, bool for_expression); protected: - std::unique_ptr m_scratch_ast_ctx_up; + std::unique_ptr m_scratch_ast_ctx_up; }; class ObjCExceptionPrecondition : public BreakpointPrecondition { @@ -186,7 +186,8 @@ public: TaggedPointerVendor() = default; private: - DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendor); + TaggedPointerVendor(const TaggedPointerVendor &) = delete; + const TaggedPointerVendor &operator=(const TaggedPointerVendor &) = delete; }; ~ObjCLanguageRuntime() override; @@ -299,7 +300,7 @@ public: /// Check whether the name is "self" or "_cmd" and should show up in /// "frame variable". - bool IsWhitelistedRuntimeValue(ConstString name) override; + bool IsAllowedRuntimeValue(ConstString name) override; protected: // Classes that inherit from ObjCLanguageRuntime can see and modify these @@ -417,9 +418,10 @@ protected: void ReadObjCLibraryIfNeeded(const ModuleList &module_list); - DISALLOW_COPY_AND_ASSIGN(ObjCLanguageRuntime); + ObjCLanguageRuntime(const ObjCLanguageRuntime &) = delete; + const ObjCLanguageRuntime &operator=(const ObjCLanguageRuntime &) = delete; }; } // namespace lldb_private -#endif // liblldb_ObjCLanguageRuntime_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_OBJCLANGUAGERUNTIME_H diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp index b396781e672..6858c7134d3 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp @@ -1,4 +1,4 @@ -//===-- RenderScriptExpressionOpts.cpp --------------------------*- C++ -*-===// +//===-- RenderScriptExpressionOpts.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -86,7 +86,7 @@ bool RenderScriptRuntimeModulePass::runOnModule(llvm::Module &module) { llvm::StringRef real_triple = m_process_ptr->GetTarget().GetArchitecture().GetTriple().getTriple(); const llvm::Target *target_info = - llvm::TargetRegistry::lookupTarget(real_triple, err); + llvm::TargetRegistry::lookupTarget(std::string(real_triple), err); if (!target_info) { if (log) log->Warning("couldn't determine real target architecture: '%s'", diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h index 3ec4e37b6db..52da677128e 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_RENDERSCRIPT_EXPROPTS_H -#define LLDB_RENDERSCRIPT_EXPROPTS_H +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTEXPRESSIONOPTS_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTEXPRESSIONOPTS_H #include "llvm/IR/Module.h" #include "llvm/Support/TargetRegistry.h" diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp index 4edb8dec608..dd9312234d8 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp @@ -1,4 +1,4 @@ -//===-- RenderScriptRuntime.cpp ---------------------------------*- C++ -*-===// +//===-- RenderScriptRuntime.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -46,6 +46,8 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_renderscript; +LLDB_PLUGIN_DEFINE(RenderScriptRuntime) + #define FMT_COORD "(%" PRIu32 ", %" PRIu32 ", %" PRIu32 ")" char RenderScriptRuntime::ID = 0; @@ -791,6 +793,9 @@ RenderScriptRuntime::CreateInstance(Process *process, Searcher::CallbackReturn RSBreakpointResolver::SearchCallback(SearchFilter &filter, SymbolContext &context, Address *) { + BreakpointSP breakpoint_sp = GetBreakpoint(); + assert(breakpoint_sp); + ModuleSP module = context.module_sp; if (!module || !IsRenderScriptScriptModule(module)) @@ -811,7 +816,7 @@ RSBreakpointResolver::SearchCallback(SearchFilter &filter, if (kernel_sym) { Address bp_addr = kernel_sym->GetAddress(); if (filter.AddressPasses(bp_addr)) - m_breakpoint->AddLocation(bp_addr); + breakpoint_sp->AddLocation(bp_addr); } return Searcher::eCallbackReturnContinue; @@ -821,6 +826,9 @@ Searcher::CallbackReturn RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter, lldb_private::SymbolContext &context, Address *) { + BreakpointSP breakpoint_sp = GetBreakpoint(); + assert(breakpoint_sp); + // We need to have access to the list of reductions currently parsed, as // reduce names don't actually exist as symbols in a module. They are only // identifiable by parsing the .rs.info packet, or finding the expand symbol. @@ -867,7 +875,7 @@ RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter, if (!SkipPrologue(module, address)) { LLDB_LOGF(log, "%s: Error trying to skip prologue", __FUNCTION__); } - m_breakpoint->AddLocation(address, &new_bp); + breakpoint_sp->AddLocation(address, &new_bp); LLDB_LOGF(log, "%s: %s reduction breakpoint on %s in %s", __FUNCTION__, new_bp ? "new" : "existing", kernel_name.GetCString(), @@ -882,7 +890,8 @@ RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter, Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback( SearchFilter &filter, SymbolContext &context, Address *addr) { - if (!m_breakpoint) + BreakpointSP breakpoint_sp = GetBreakpoint(); + if (!breakpoint_sp) return eCallbackReturnContinue; Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); @@ -892,7 +901,8 @@ Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback( return Searcher::eCallbackReturnContinue; std::vector names; - m_breakpoint->GetNames(names); + Breakpoint& breakpoint = *breakpoint_sp; + breakpoint.GetNames(names); if (names.empty()) return eCallbackReturnContinue; @@ -932,7 +942,7 @@ Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback( } bool new_bp; - m_breakpoint->AddLocation(address, &new_bp); + breakpoint.AddLocation(address, &new_bp); LLDB_LOGF(log, "%s: Placed %sbreakpoint on %s", __FUNCTION__, new_bp ? "new " : "", k.m_name.AsCString()); @@ -1029,8 +1039,8 @@ bool RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value) { } lldb::BreakpointResolverSP -RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bp, bool catch_bp, - bool throw_bp) { +RenderScriptRuntime::CreateExceptionResolver(const lldb::BreakpointSP &bp, + bool catch_bp, bool throw_bp) { BreakpointResolverSP resolver_sp; return resolver_sp; } @@ -1513,7 +1523,7 @@ void RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook, script->type = ScriptDetails::eScriptC; script->cache_dir = cache_dir; script->res_name = res_name; - script->shared_lib = strm.GetString(); + script->shared_lib = std::string(strm.GetString()); script->context = addr_t(args[eRsContext]); } @@ -3129,7 +3139,7 @@ void RenderScriptRuntime::DumpKernels(Stream &strm) const { strm.Printf("Resource '%s':", module->m_resname.c_str()); strm.EOL(); for (const auto &kernel : module->m_kernels) { - strm.Indent(kernel.m_name.AsCString()); + strm.Indent(kernel.m_name.GetStringRef()); strm.EOL(); } } @@ -3939,9 +3949,10 @@ void RSModuleDescriptor::Dump(Stream &strm) const { } void RSGlobalDescriptor::Dump(Stream &strm) const { - strm.Indent(m_name.AsCString()); + strm.Indent(m_name.GetStringRef()); VariableList var_list; - m_module->m_module->FindGlobalVariables(m_name, nullptr, 1U, var_list); + m_module->m_module->FindGlobalVariables(m_name, CompilerDeclContext(), 1U, + var_list); if (var_list.GetSize() == 1) { auto var = var_list.GetVariableAtIndex(0); auto type = var->GetType(); @@ -3964,12 +3975,12 @@ void RSGlobalDescriptor::Dump(Stream &strm) const { } void RSKernelDescriptor::Dump(Stream &strm) const { - strm.Indent(m_name.AsCString()); + strm.Indent(m_name.GetStringRef()); strm.EOL(); } void RSReductionDescriptor::Dump(lldb_private::Stream &stream) const { - stream.Indent(m_reduce_name.AsCString()); + stream.Indent(m_reduce_name.GetStringRef()); stream.IndentMore(); stream.EOL(); stream.Indent(); diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h index c3740ba55a1..5e372654836 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RenderScriptRuntime_h_ -#define liblldb_RenderScriptRuntime_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H #include #include @@ -24,6 +24,10 @@ #include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h" +namespace clang { +class TargetOptions; +} + namespace lldb_private { namespace lldb_renderscript { @@ -54,7 +58,7 @@ struct RSCoordinate { // for .expand kernels as a fallback. class RSBreakpointResolver : public BreakpointResolver { public: - RSBreakpointResolver(Breakpoint *bp, ConstString name) + RSBreakpointResolver(const lldb::BreakpointSP &bp, ConstString name) : BreakpointResolver(bp, BreakpointResolver::NameResolver), m_kernel_name(name) {} @@ -73,9 +77,9 @@ public: lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } lldb::BreakpointResolverSP - CopyForBreakpoint(Breakpoint &breakpoint) override { + CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override { lldb::BreakpointResolverSP ret_sp( - new RSBreakpointResolver(&breakpoint, m_kernel_name)); + new RSBreakpointResolver(breakpoint, m_kernel_name)); return ret_sp; } @@ -96,7 +100,7 @@ public: }; RSReduceBreakpointResolver( - Breakpoint *breakpoint, ConstString reduce_name, + const lldb::BreakpointSP &breakpoint, ConstString reduce_name, std::vector *rs_modules, int kernel_types = eKernelTypeAll) : BreakpointResolver(breakpoint, BreakpointResolver::NameResolver), @@ -123,9 +127,9 @@ public: lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } lldb::BreakpointResolverSP - CopyForBreakpoint(Breakpoint &breakpoint) override { + CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override { lldb::BreakpointResolverSP ret_sp(new RSReduceBreakpointResolver( - &breakpoint, m_reduce_name, m_rsmodules, m_kernel_types)); + breakpoint, m_reduce_name, m_rsmodules, m_kernel_types)); return ret_sp; } @@ -246,7 +250,8 @@ typedef std::vector RSScriptGroupList; class RSScriptGroupBreakpointResolver : public BreakpointResolver { public: - RSScriptGroupBreakpointResolver(Breakpoint *bp, ConstString name, + RSScriptGroupBreakpointResolver(const lldb::BreakpointSP &bp, + ConstString name, const RSScriptGroupList &groups, bool stop_on_all) : BreakpointResolver(bp, BreakpointResolver::NameResolver), @@ -268,9 +273,9 @@ public: lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } lldb::BreakpointResolverSP - CopyForBreakpoint(Breakpoint &breakpoint) override { + CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override { lldb::BreakpointResolverSP ret_sp(new RSScriptGroupBreakpointResolver( - &breakpoint, m_group_name, m_script_groups, m_stop_on_all)); + breakpoint, m_group_name, m_script_groups, m_stop_on_all)); return ret_sp; } @@ -343,9 +348,9 @@ public: bool CouldHaveDynamicValue(ValueObject &in_value) override; - lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bp, - bool catch_bp, - bool throw_bp) override; + lldb::BreakpointResolverSP + CreateExceptionResolver(const lldb::BreakpointSP &bp, + bool catch_bp, bool throw_bp) override; bool LoadModule(const lldb::ModuleSP &module_sp); @@ -402,6 +407,8 @@ public: return false; } + bool GetOverrideExprOptions(clang::TargetOptions &prototype); + // PluginInterface protocol lldb_private::ConstString GetPluginName() override; @@ -421,7 +428,8 @@ protected: void InitSearchFilter(lldb::TargetSP target) { if (!m_filtersp) - m_filtersp.reset(new SearchFilterForUnconstrainedSearches(target)); + m_filtersp = + std::make_shared(target); } void FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp); @@ -577,11 +585,9 @@ private: // any previous stored allocation which has the same address. AllocationDetails *CreateAllocation(lldb::addr_t address); - bool GetOverrideExprOptions(clang::TargetOptions &prototype) override; - bool GetIRPasses(LLVMUserExpression::IRPasses &passes) override; }; } // namespace lldb_private -#endif // liblldb_RenderScriptRuntime_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp index 45d0d028d04..b6f8b20c90c 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp @@ -1,4 +1,4 @@ -//===-- RenderScriptScriptGroup.cpp -----------------------------*- C++ -*-===// +//===-- RenderScriptScriptGroup.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h index c25e240f6d5..03d3a7823a9 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h @@ -6,12 +6,12 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RenderScriptScriptGroup_h_ -#define liblldb_RenderScriptScriptGroup_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTSCRIPTGROUP_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTSCRIPTGROUP_H #include "lldb/Interpreter/CommandInterpreter.h" lldb::CommandObjectSP NewCommandObjectRenderScriptScriptGroup( lldb_private::CommandInterpreter &interpreter); -#endif // liblldb_RenderScriptScriptGroup_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTSCRIPTGROUP_H diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp index 4ddff3ad9c4..f51190e0c82 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp @@ -1,4 +1,4 @@ -//===-- RenderScriptx86ABIFixups.cpp ----------------------------*- C++ -*-===// +//===-- RenderScriptx86ABIFixups.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,7 +10,6 @@ #include "llvm/ADT/StringRef.h" #include "llvm/IR/BasicBlock.h" -#include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/Instruction.h" @@ -158,12 +157,11 @@ bool fixupX86StructRetCalls(llvm::Module &module) { assert(new_func_type && "failed to clone functionType for Renderscript ABI fixup"); - llvm::CallSite call_site(call_inst); llvm::Function *func = call_inst->getCalledFunction(); assert(func && "cannot resolve function in RenderScriptRuntime"); // Copy the original call arguments - std::vector new_call_args(call_site.arg_begin(), - call_site.arg_end()); + std::vector new_call_args(call_inst->arg_begin(), + call_inst->arg_end()); // Allocate enough space to store the return value of the original function // we pass a pointer to this allocation as the StructRet param, and then @@ -189,15 +187,17 @@ bool fixupX86StructRetCalls(llvm::Module &module) { ->setName("new_func_ptr_load_cast"); // load the new function address ready for a jump llvm::LoadInst *new_func_addr_load = - new llvm::LoadInst(new_func_ptr, "load_func_pointer", call_inst); + new llvm::LoadInst(new_func_ptr->getType()->getPointerElementType(), + new_func_ptr, "load_func_pointer", call_inst); // and create a callinstruction from it llvm::CallInst *new_call_inst = llvm::CallInst::Create(new_func_type, new_func_addr_load, new_call_args, "new_func_call", call_inst); new_call_inst->setCallingConv(call_inst->getCallingConv()); new_call_inst->setTailCall(call_inst->isTailCall()); - llvm::LoadInst *lldb_save_result_address = - new llvm::LoadInst(return_value_alloc, "save_return_val", call_inst); + llvm::LoadInst *lldb_save_result_address = new llvm::LoadInst( + return_value_alloc->getType()->getPointerElementType(), + return_value_alloc, "save_return_val", call_inst); // Now remove the old broken call call_inst->replaceAllUsesWith(lldb_save_result_address); diff --git a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h index a5efc999aea..7836fff4a3a 100644 --- a/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h +++ b/gnu/llvm/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_RENDERSCRIPT_X86_H -#define LLDB_RENDERSCRIPT_X86_H +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTX86ABIFIXUPS_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTX86ABIFIXUPS_H #include "llvm/IR/Module.h" diff --git a/gnu/llvm/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp b/gnu/llvm/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp index e0d2c5d0eef..333113a0b17 100644 --- a/gnu/llvm/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp +++ b/gnu/llvm/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp @@ -1,4 +1,4 @@ -//===-- MemoryHistoryASan.cpp -----------------------------------*- C++ -*-===// +//===-- MemoryHistoryASan.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -28,6 +28,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(MemoryHistoryASan) + MemoryHistorySP MemoryHistoryASan::CreateInstance(const ProcessSP &process_sp) { if (!process_sp.get()) return nullptr; @@ -136,7 +138,12 @@ static void CreateHistoryThreadFromValueObject(ProcessSP process_sp, pcs.push_back(pc); } - HistoryThread *history_thread = new HistoryThread(*process_sp, tid, pcs); + // The ASAN runtime already massages the return addresses into call + // addresses, we don't want LLDB's unwinder to try to locate the previous + // instruction again as this might lead to us reporting a different line. + bool pcs_are_call_addresses = true; + HistoryThread *history_thread = + new HistoryThread(*process_sp, tid, pcs, pcs_are_call_addresses); ThreadSP new_thread_sp(history_thread); std::ostringstream thread_name_with_number; thread_name_with_number << thread_name << " Thread " << tid; diff --git a/gnu/llvm/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h b/gnu/llvm/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h index 266576b0cd9..e9fe37d344a 100644 --- a/gnu/llvm/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h +++ b/gnu/llvm/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_MemoryHistoryASan_h_ -#define liblldb_MemoryHistoryASan_h_ +#ifndef LLDB_SOURCE_PLUGINS_MEMORYHISTORY_ASAN_MEMORYHISTORYASAN_H +#define LLDB_SOURCE_PLUGINS_MEMORYHISTORY_ASAN_MEMORYHISTORYASAN_H #include "lldb/Target/ABI.h" #include "lldb/Target/MemoryHistory.h" @@ -45,4 +45,4 @@ private: } // namespace lldb_private -#endif // liblldb_MemoryHistoryASan_h_ +#endif // LLDB_SOURCE_PLUGINS_MEMORYHISTORY_ASAN_MEMORYHISTORYASAN_H diff --git a/gnu/llvm/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/gnu/llvm/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp index 512b5bebf07..83cf9f8bd26 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp +++ b/gnu/llvm/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp @@ -1,4 +1,4 @@ -//===-- ObjectContainerBSDArchive.cpp ---------------------------*- C++ -*-===// +//===-- ObjectContainerBSDArchive.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -40,6 +40,8 @@ typedef struct ar_hdr { using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(ObjectContainerBSDArchive) + ObjectContainerBSDArchive::Object::Object() : ar_name(), modification_time(0), uid(0), gid(0), mode(0), size(0), file_offset(0), file_size(0) {} @@ -86,7 +88,7 @@ ObjectContainerBSDArchive::Object::Extract(const DataExtractor &data, return LLDB_INVALID_OFFSET; str.assign((const char *)data.GetData(&offset, 16), 16); - if (str.find("#1/") == 0) { + if (llvm::StringRef(str).startswith("#1/")) { // If the name is longer than 16 bytes, or contains an embedded space then // it will use this format where the length of the name is here and the // name characters are after this header. diff --git a/gnu/llvm/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h b/gnu/llvm/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h index 5d9c01315a6..f6862afff8a 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h +++ b/gnu/llvm/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ObjectContainerBSDArchive_h_ -#define liblldb_ObjectContainerBSDArchive_h_ +#ifndef LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_BSD_ARCHIVE_OBJECTCONTAINERBSDARCHIVE_H +#define LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_BSD_ARCHIVE_OBJECTCONTAINERBSDARCHIVE_H #include "lldb/Core/UniqueCStringMap.h" #include "lldb/Symbol/ObjectContainer.h" @@ -174,4 +174,4 @@ protected: Archive::shared_ptr m_archive_sp; }; -#endif // liblldb_ObjectContainerBSDArchive_h_ +#endif // LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_BSD_ARCHIVE_OBJECTCONTAINERBSDARCHIVE_H diff --git a/gnu/llvm/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp b/gnu/llvm/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp index 839a71cfdc7..bb56379ed1e 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp +++ b/gnu/llvm/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp @@ -1,4 +1,4 @@ -//===-- ObjectContainerUniversalMachO.cpp -----------------------*- C++ -*-===// +//===-- ObjectContainerUniversalMachO.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -20,6 +20,9 @@ using namespace lldb; using namespace lldb_private; using namespace llvm::MachO; +LLDB_PLUGIN_DEFINE_ADV(ObjectContainerUniversalMachO, + ObjectContainerMachOArchive) + void ObjectContainerUniversalMachO::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, diff --git a/gnu/llvm/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h b/gnu/llvm/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h index 51304971034..a5eac0ad0ff 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h +++ b/gnu/llvm/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ObjectContainerUniversalMachO_h_ -#define liblldb_ObjectContainerUniversalMachO_h_ +#ifndef LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_UNIVERSAL_MACH_O_OBJECTCONTAINERUNIVERSALMACHO_H +#define LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_UNIVERSAL_MACH_O_OBJECTCONTAINERUNIVERSALMACHO_H #include "lldb/Host/SafeMachO.h" #include "lldb/Symbol/ObjectContainer.h" @@ -72,4 +72,4 @@ protected: std::vector &fat_archs); }; -#endif // liblldb_ObjectContainerUniversalMachO_h_ +#endif // LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_UNIVERSAL_MACH_O_OBJECTCONTAINERUNIVERSALMACHO_H diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp b/gnu/llvm/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp index b83b2efb492..bd8eeedce57 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp @@ -1,4 +1,4 @@ -//===-- BreakpadRecords.cpp ----------------------------------- -*- C++ -*-===// +//===-- BreakpadRecords.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -205,7 +205,7 @@ llvm::Optional InfoRecord::parse(llvm::StringRef Line) { // use this as the UUID. Otherwise, we should revert back to the module ID. UUID ID; if (Line.trim().empty()) { - if (Str.empty() || ID.SetFromStringRef(Str, Str.size() / 2) != Str.size()) + if (Str.empty() || !ID.SetFromStringRef(Str)) return llvm::None; } return InfoRecord(std::move(ID)); diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h b/gnu/llvm/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h index 27bef975125..1620a1210b8 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H -#define LLDB_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H +#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H +#define LLDB_SOURCE_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H #include "lldb/Utility/UUID.h" #include "lldb/lldb-types.h" @@ -183,4 +183,4 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StackWinRecord &R); } // namespace breakpad } // namespace lldb_private -#endif // LLDB_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H +#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp b/gnu/llvm/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp index 3b9e0e2092a..7a9163ddb88 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp @@ -1,4 +1,4 @@ -//===-- ObjectFileBreakpad.cpp -------------------------------- -*- C++ -*-===// +//===-- ObjectFileBreakpad.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -16,6 +16,8 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::breakpad; +LLDB_PLUGIN_DEFINE(ObjectFileBreakpad) + namespace { struct Header { ArchSpec arch; diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h b/gnu/llvm/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h index cb4bba01fb7..8724feaa422 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_OBJECTFILE_BREAKPAD_OBJECTFILEBREAKPAD_H -#define LLDB_PLUGINS_OBJECTFILE_BREAKPAD_OBJECTFILEBREAKPAD_H +#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_BREAKPAD_OBJECTFILEBREAKPAD_H +#define LLDB_SOURCE_PLUGINS_OBJECTFILE_BREAKPAD_OBJECTFILEBREAKPAD_H #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/ArchSpec.h" @@ -103,4 +103,4 @@ private: } // namespace breakpad } // namespace lldb_private -#endif // LLDB_PLUGINS_OBJECTFILE_BREAKPAD_OBJECTFILEBREAKPAD_H +#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_BREAKPAD_OBJECTFILEBREAKPAD_H diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/ObjectFile/CMakeLists.txt index 4edd667b972..76f6d7ad0d7 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/CMakeLists.txt @@ -3,3 +3,4 @@ add_subdirectory(ELF) add_subdirectory(Mach-O) add_subdirectory(PECOFF) add_subdirectory(JIT) +add_subdirectory(wasm) \ No newline at end of file diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp b/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp index aa9871071b0..f0496beba2e 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp @@ -1,4 +1,4 @@ -//===-- ELFHeader.cpp ----------------------------------------- -*- C++ -*-===// +//===-- ELFHeader.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h b/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h index bb228e269d4..963cc850736 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h @@ -17,8 +17,8 @@ /// reading both 32 and 64 bit instances of the object. //===----------------------------------------------------------------------===// -#ifndef liblldb_ELFHeader_h_ -#define liblldb_ELFHeader_h_ +#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H +#define LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H #include "llvm/BinaryFormat/ELF.h" @@ -391,4 +391,4 @@ struct ELFRela { } // End namespace elf. -#endif // #ifndef liblldb_ELFHeader_h_ +#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 5b4ee5d2212..bca575b7f88 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -1,4 +1,4 @@ -//===-- ObjectFileELF.cpp ------------------------------------- -*- C++ -*-===// +//===-- ObjectFileELF.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -51,6 +51,8 @@ using namespace lldb_private; using namespace elf; using namespace llvm::ELF; +LLDB_PLUGIN_DEFINE(ObjectFileELF) + namespace { // ELF note owner definitions @@ -206,7 +208,9 @@ unsigned ELFRelocation::RelocAddend64(const ELFRelocation &rel) { } // end anonymous namespace -static user_id_t SegmentID(size_t PHdrIndex) { return ~PHdrIndex; } +static user_id_t SegmentID(size_t PHdrIndex) { + return ~user_id_t(PHdrIndex); +} bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) { // Read all fields. @@ -537,7 +541,8 @@ size_t ObjectFileELF::GetModuleSpecifications( __FUNCTION__, file.GetPath().c_str()); } - data_sp = MapFileData(file, -1, file_offset); + if (data_sp->GetByteSize() < length) + data_sp = MapFileData(file, -1, file_offset); if (data_sp) data.SetData(data_sp); // In case there is header extension in the section #0, the header we @@ -576,8 +581,7 @@ size_t ObjectFileELF::GetModuleSpecifications( func_cat, "Calculating module crc32 %s with size %" PRIu64 " KiB", file.GetLastPathComponent().AsCString(), - (FileSystem::Instance().GetByteSize(file) - file_offset) / - 1024); + (length - file_offset) / 1024); // For core files - which usually don't happen to have a // gnu_debuglink, and are pretty bulky - calculating whole @@ -899,7 +903,7 @@ size_t ObjectFileELF::ParseDependentModules() { if (m_filespec_up) return m_filespec_up->GetSize(); - m_filespec_up.reset(new FileSpecList()); + m_filespec_up = std::make_unique(); if (!ParseSectionHeaders()) return 0; @@ -1235,7 +1239,7 @@ void ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length, lldb::offset_t Offset = 0; uint8_t FormatVersion = data.GetU8(&Offset); - if (FormatVersion != llvm::ARMBuildAttrs::Format_Version) + if (FormatVersion != llvm::ELFAttrs::Format_Version) return; Offset = Offset + sizeof(uint32_t); // Section Length @@ -1588,6 +1592,7 @@ static SectionType GetSectionTypeFromName(llvm::StringRef Name) { .Case("str.dwo", eSectionTypeDWARFDebugStrDwo) .Case("str_offsets", eSectionTypeDWARFDebugStrOffsets) .Case("str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo) + .Case("tu_index", eSectionTypeDWARFDebugTuIndex) .Case("types", eSectionTypeDWARFDebugTypes) .Case("types.dwo", eSectionTypeDWARFDebugTypesDwo) .Default(eSectionTypeOther); @@ -1696,7 +1701,7 @@ class VMAddressProvider { public: VMAddressProvider(ObjectFile::Type Type, llvm::StringRef SegmentName) - : ObjectType(Type), SegmentName(SegmentName) {} + : ObjectType(Type), SegmentName(std::string(SegmentName)) {} std::string GetNextSegmentName() const { return llvm::formatv("{0}[{1}]", SegmentName, SegmentCount).str(); @@ -2230,8 +2235,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id, if (!mangled_name.empty()) mangled.SetMangledName(ConstString((mangled_name + suffix).str())); - ConstString demangled = - mangled.GetDemangledName(lldb::eLanguageTypeUnknown); + ConstString demangled = mangled.GetDemangledName(); llvm::StringRef demangled_name = demangled.GetStringRef(); if (!demangled_name.empty()) mangled.SetDemangledName(ConstString((demangled_name + suffix).str())); @@ -2713,7 +2717,7 @@ Symtab *ObjectFileELF::GetSymtab() { Section *symtab = section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get(); if (symtab) { - m_symtab_up.reset(new Symtab(symtab->GetObjectFile())); + m_symtab_up = std::make_unique(symtab->GetObjectFile()); symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, symtab); } @@ -2730,7 +2734,7 @@ Symtab *ObjectFileELF::GetSymtab() { .get(); if (dynsym) { if (!m_symtab_up) - m_symtab_up.reset(new Symtab(dynsym->GetObjectFile())); + m_symtab_up = std::make_unique(dynsym->GetObjectFile()); symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, dynsym); } } @@ -2746,20 +2750,19 @@ Symtab *ObjectFileELF::GetSymtab() { // also be present. const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL); if (symbol) { - const ELFDynamic *pltrelsz = FindDynamicSymbol(DT_PLTRELSZ); - assert(pltrelsz != NULL); // Synthesize trampoline symbols to help navigate the PLT. addr_t addr = symbol->d_ptr; Section *reloc_section = section_list->FindSectionContainingFileAddress(addr).get(); - if (reloc_section && pltrelsz->d_val > 0) { + if (reloc_section) { user_id_t reloc_id = reloc_section->GetID(); const ELFSectionHeaderInfo *reloc_header = GetSectionHeaderByIndex(reloc_id); assert(reloc_header); if (m_symtab_up == nullptr) - m_symtab_up.reset(new Symtab(reloc_section->GetObjectFile())); + m_symtab_up = + std::make_unique(reloc_section->GetObjectFile()); ParseTrampolineSymbols(m_symtab_up.get(), symbol_id, reloc_header, reloc_id); @@ -2769,17 +2772,17 @@ Symtab *ObjectFileELF::GetSymtab() { if (DWARFCallFrameInfo *eh_frame = GetModule()->GetUnwindTable().GetEHFrameInfo()) { if (m_symtab_up == nullptr) - m_symtab_up.reset(new Symtab(this)); + m_symtab_up = std::make_unique(this); ParseUnwindSymbols(m_symtab_up.get(), eh_frame); } // If we still don't have any symtab then create an empty instance to avoid // do the section lookup next time. if (m_symtab_up == nullptr) - m_symtab_up.reset(new Symtab(this)); + m_symtab_up = std::make_unique(this); // In the event that there's no symbol entry for the entry point we'll - // artifically create one. We delegate to the symtab object the figuring + // artificially create one. We delegate to the symtab object the figuring // out of the proper size, this will usually make it span til the next // symbol it finds in the section. This means that if there are missing // symbols the entry point might span beyond its function definition. @@ -2876,7 +2879,7 @@ void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table, return; // First we save the new symbols into a separate list and add them to the - // symbol table after we colleced all symbols we want to add. This is + // symbol table after we collected all symbols we want to add. This is // neccessary because adding a new symbol invalidates the internal index of // the symtab what causing the next lookup to be slow because it have to // recalculate the index first. @@ -2955,7 +2958,8 @@ void ObjectFileELF::Dump(Stream *s) { s->EOL(); SectionList *section_list = GetSectionList(); if (section_list) - section_list->Dump(s, nullptr, true, UINT32_MAX); + section_list->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true, + UINT32_MAX); Symtab *symtab = GetSymtab(); if (symtab) symtab->Dump(s, nullptr, eSortOrderNone); diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index 3b273896cb5..062271f1caf 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ObjectFileELF_h_ -#define liblldb_ObjectFileELF_h_ +#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H +#define LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H #include @@ -328,9 +328,6 @@ private: /// section index 0 is never valid). lldb::user_id_t GetSectionIndexByName(const char *name); - // Returns the ID of the first section that has the given type. - lldb::user_id_t GetSectionIndexByType(unsigned type); - /// Returns the section header with the given id or NULL. const ELFSectionHeaderInfo *GetSectionHeaderByIndex(lldb::user_id_t id); @@ -397,4 +394,4 @@ private: std::shared_ptr GetGnuDebugDataObjectFile(); }; -#endif // liblldb_ObjectFileELF_h_ +#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/gnu/llvm/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp index c55b96d9110..93c2c9f945f 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp @@ -1,4 +1,4 @@ -//===-- ObjectFileJIT.cpp ---------------------------------------*- C++ -*-===// +//===-- ObjectFileJIT.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -39,6 +39,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(ObjectFileJIT) + char ObjectFileJIT::ID; void ObjectFileJIT::Initialize() { @@ -118,7 +120,7 @@ Symtab *ObjectFileJIT::GetSymtab() { if (module_sp) { std::lock_guard guard(module_sp->GetMutex()); if (m_symtab_up == nullptr) { - m_symtab_up.reset(new Symtab(this)); + m_symtab_up = std::make_unique(this); std::lock_guard symtab_guard( m_symtab_up->GetMutex()); ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock()); @@ -137,7 +139,7 @@ bool ObjectFileJIT::IsStripped() { void ObjectFileJIT::CreateSections(SectionList &unified_section_list) { if (!m_sections_up) { - m_sections_up.reset(new SectionList()); + m_sections_up = std::make_unique(); ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock()); if (delegate_sp) { delegate_sp->PopulateSectionList(this, *m_sections_up); @@ -161,7 +163,8 @@ void ObjectFileJIT::Dump(Stream *s) { SectionList *sections = GetSectionList(); if (sections) - sections->Dump(s, nullptr, true, UINT32_MAX); + sections->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true, + UINT32_MAX); if (m_symtab_up) m_symtab_up->Dump(s, nullptr, eSortOrderNone); diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/gnu/llvm/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h index c992683cfc3..a3a1acea916 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ObjectFileJIT_h_ -#define liblldb_ObjectFileJIT_h_ +#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_JIT_OBJECTFILEJIT_H +#define LLDB_SOURCE_PLUGINS_OBJECTFILE_JIT_OBJECTFILEJIT_H #include "lldb/Core/Address.h" #include "lldb/Symbol/ObjectFile.h" @@ -104,4 +104,4 @@ protected: lldb::ObjectFileJITDelegateWP m_delegate_wp; }; -#endif // liblldb_ObjectFileJIT_h_ +#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_JIT_OBJECTFILEJIT_H diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/gnu/llvm/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index 3f9b68aad89..2bb4b21adea 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -1,4 +1,4 @@ -//===-- ObjectFileMachO.cpp -------------------------------------*- C++ -*-===// +//===-- ObjectFileMachO.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -66,6 +66,8 @@ using namespace lldb; using namespace lldb_private; using namespace llvm::MachO; +LLDB_PLUGIN_DEFINE(ObjectFileMachO) + // Some structure definitions needed for parsing the dyld shared cache files // found on iOS devices. @@ -1148,6 +1150,7 @@ AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) { case eSectionTypeDWARFDebugStrDwo: case eSectionTypeDWARFDebugStrOffsets: case eSectionTypeDWARFDebugStrOffsetsDwo: + case eSectionTypeDWARFDebugTuIndex: case eSectionTypeDWARFDebugTypes: case eSectionTypeDWARFDebugTypesDwo: case eSectionTypeDWARFAppleNames: @@ -1250,7 +1253,7 @@ Symtab *ObjectFileMachO::GetSymtab() { if (module_sp) { std::lock_guard guard(module_sp->GetMutex()); if (m_symtab_up == nullptr) { - m_symtab_up.reset(new Symtab(this)); + m_symtab_up = std::make_unique(this); std::lock_guard symtab_guard( m_symtab_up->GetMutex()); ParseSymtab(); @@ -1817,7 +1820,7 @@ void ObjectFileMachO::CreateSections(SectionList &unified_section_list) { if (m_sections_up) return; - m_sections_up.reset(new SectionList()); + m_sections_up = std::make_unique(); lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); // bool dump_sections = false; @@ -1904,6 +1907,7 @@ protected: std::vector m_section_infos; }; +#define TRIE_SYMBOL_IS_THUMB (1ULL << 63) struct TrieEntry { void Dump() const { printf("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"", @@ -1917,7 +1921,9 @@ struct TrieEntry { } ConstString name; uint64_t address = LLDB_INVALID_ADDRESS; - uint64_t flags = 0; + uint64_t flags = + 0; // EXPORT_SYMBOL_FLAGS_REEXPORT, EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER, + // TRIE_SYMBOL_IS_THUMB uint64_t other = 0; ConstString import_name; }; @@ -1940,13 +1946,16 @@ struct TrieEntryWithOffset { }; static bool ParseTrieEntries(DataExtractor &data, lldb::offset_t offset, - const bool is_arm, + const bool is_arm, addr_t text_seg_base_addr, std::vector &nameSlices, std::set &resolver_addresses, - std::vector &output) { + std::vector &reexports, + std::vector &ext_symbols) { if (!data.ValidOffset(offset)) return true; + // Terminal node -- end of a branch, possibly add this to + // the symbol table or resolver table. const uint64_t terminalSize = data.GetULEB128(&offset); lldb::offset_t children_offset = offset + terminalSize; if (terminalSize != 0) { @@ -1959,6 +1968,8 @@ static bool ParseTrieEntries(DataExtractor &data, lldb::offset_t offset, import_name = data.GetCStr(&offset); } else { e.entry.address = data.GetULEB128(&offset); + if (text_seg_base_addr != LLDB_INVALID_ADDRESS) + e.entry.address += text_seg_base_addr; if (e.entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) { e.entry.other = data.GetULEB128(&offset); uint64_t resolver_addr = e.entry.other; @@ -1968,9 +1979,18 @@ static bool ParseTrieEntries(DataExtractor &data, lldb::offset_t offset, } else e.entry.other = 0; } - // Only add symbols that are reexport symbols with a valid import name - if (EXPORT_SYMBOL_FLAGS_REEXPORT & e.entry.flags && import_name && - import_name[0]) { + bool add_this_entry = false; + if (Flags(e.entry.flags).Test(EXPORT_SYMBOL_FLAGS_REEXPORT) && + import_name && import_name[0]) { + // add symbols that are reexport symbols with a valid import name. + add_this_entry = true; + } else if (e.entry.flags == 0 && + (import_name == nullptr || import_name[0] == '\0')) { + // add externally visible symbols, in case the nlist record has + // been stripped/omitted. + add_this_entry = true; + } + if (add_this_entry) { std::string name; if (!nameSlices.empty()) { for (auto name_slice : nameSlices) @@ -1984,7 +2004,15 @@ static bool ParseTrieEntries(DataExtractor &data, lldb::offset_t offset, // Skip the leading '_' e.entry.import_name.SetCString(import_name + 1); } - output.push_back(e); + if (Flags(e.entry.flags).Test(EXPORT_SYMBOL_FLAGS_REEXPORT)) { + reexports.push_back(e); + } else { + if (is_arm && (e.entry.address & 1)) { + e.entry.flags |= TRIE_SYMBOL_IS_THUMB; + e.entry.address &= THUMB_ADDRESS_BIT_MASK; + } + ext_symbols.push_back(e); + } } } @@ -1997,8 +2025,9 @@ static bool ParseTrieEntries(DataExtractor &data, lldb::offset_t offset, return false; // Corrupt data lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset); if (childNodeOffset) { - if (!ParseTrieEntries(data, childNodeOffset, is_arm, nameSlices, - resolver_addresses, output)) { + if (!ParseTrieEntries(data, childNodeOffset, is_arm, text_seg_base_addr, + nameSlices, resolver_addresses, reexports, + ext_symbols)) { return false; } } @@ -2007,6 +2036,66 @@ static bool ParseTrieEntries(DataExtractor &data, lldb::offset_t offset, return true; } +static SymbolType GetSymbolType(const char *&symbol_name, + bool &demangled_is_synthesized, + const SectionSP &text_section_sp, + const SectionSP &data_section_sp, + const SectionSP &data_dirty_section_sp, + const SectionSP &data_const_section_sp, + const SectionSP &symbol_section) { + SymbolType type = eSymbolTypeInvalid; + + const char *symbol_sect_name = symbol_section->GetName().AsCString(); + if (symbol_section->IsDescendant(text_section_sp.get())) { + if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS | + S_ATTR_SELF_MODIFYING_CODE | + S_ATTR_SOME_INSTRUCTIONS)) + type = eSymbolTypeData; + else + type = eSymbolTypeCode; + } else if (symbol_section->IsDescendant(data_section_sp.get()) || + symbol_section->IsDescendant(data_dirty_section_sp.get()) || + symbol_section->IsDescendant(data_const_section_sp.get())) { + if (symbol_sect_name && + ::strstr(symbol_sect_name, "__objc") == symbol_sect_name) { + type = eSymbolTypeRuntime; + + if (symbol_name) { + llvm::StringRef symbol_name_ref(symbol_name); + if (symbol_name_ref.startswith("OBJC_")) { + static const llvm::StringRef g_objc_v2_prefix_class("OBJC_CLASS_$_"); + static const llvm::StringRef g_objc_v2_prefix_metaclass( + "OBJC_METACLASS_$_"); + static const llvm::StringRef g_objc_v2_prefix_ivar("OBJC_IVAR_$_"); + if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) { + symbol_name = symbol_name + g_objc_v2_prefix_class.size(); + type = eSymbolTypeObjCClass; + demangled_is_synthesized = true; + } else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass)) { + symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size(); + type = eSymbolTypeObjCMetaClass; + demangled_is_synthesized = true; + } else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar)) { + symbol_name = symbol_name + g_objc_v2_prefix_ivar.size(); + type = eSymbolTypeObjCIVar; + demangled_is_synthesized = true; + } + } + } + } else if (symbol_sect_name && + ::strstr(symbol_sect_name, "__gcc_except_tab") == + symbol_sect_name) { + type = eSymbolTypeException; + } else { + type = eSymbolTypeData; + } + } else if (symbol_sect_name && + ::strstr(symbol_sect_name, "__IMPORT") == symbol_sect_name) { + type = eSymbolTypeTrampoline; + } + return type; +} + // Read the UUID out of a dyld_shared_cache file on-disk. UUID ObjectFileMachO::GetSharedCacheUUID(FileSpec dyld_shared_cache, const ByteOrder byte_order, @@ -2063,7 +2152,15 @@ size_t ObjectFileMachO::ParseSymtab() { struct symtab_command symtab_load_command = {0, 0, 0, 0, 0, 0}; struct linkedit_data_command function_starts_load_command = {0, 0, 0, 0}; struct dyld_info_command dyld_info = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + // The data element of type bool indicates that this entry is thumb + // code. typedef AddressDataArray FunctionStarts; + + // Record the address of every function/data that we add to the symtab. + // We add symbols to the table in the order of most information (nlist + // records) to least (function starts), and avoid duplicating symbols + // via this set. + std::set symbols_added; FunctionStarts function_starts; lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); uint32_t i; @@ -2088,29 +2185,6 @@ size_t ObjectFileMachO::ParseSymtab() { if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) == nullptr) // fill in symoff, nsyms, stroff, strsize fields return 0; - if (symtab_load_command.symoff == 0) { - if (log) - module_sp->LogMessage(log, "LC_SYMTAB.symoff == 0"); - return 0; - } - - if (symtab_load_command.stroff == 0) { - if (log) - module_sp->LogMessage(log, "LC_SYMTAB.stroff == 0"); - return 0; - } - - if (symtab_load_command.nsyms == 0) { - if (log) - module_sp->LogMessage(log, "LC_SYMTAB.nsyms == 0"); - return 0; - } - - if (symtab_load_command.strsize == 0) { - if (log) - module_sp->LogMessage(log, "LC_SYMTAB.strsize == 0"); - return 0; - } break; case LC_DYLD_INFO: @@ -2223,7 +2297,7 @@ size_t ObjectFileMachO::ParseSymtab() { #if defined(__APPLE__) && \ (defined(__arm__) || defined(__arm64__) || defined(__aarch64__)) - if (m_header.flags & 0x80000000u && + if (m_header.flags & MH_DYLIB_IN_CACHE && process->GetAddressByteSize() == sizeof(void *)) { // This mach-o memory file is in the dyld shared cache. If this // program is not remote and this is iOS, then this process will @@ -2305,7 +2379,7 @@ size_t ObjectFileMachO::ParseSymtab() { // problem. For binaries outside the shared cache, it's faster to // read the entire strtab at once instead of piece-by-piece as we // process the nlist records. - if ((m_header.flags & 0x80000000u) == 0) { + if ((m_header.flags & MH_DYLIB_IN_CACHE) == 0) { DataBufferSP strtab_data_sp( ReadMemory(process_sp, strtab_addr, strtab_data_byte_size)); if (strtab_data_sp) { @@ -2351,27 +2425,7 @@ size_t ObjectFileMachO::ParseSymtab() { } } - if (nlist_data.GetByteSize() == 0 && - memory_module_load_level == eMemoryModuleLoadLevelComplete) { - if (log) - module_sp->LogMessage(log, "failed to read nlist data"); - return 0; - } - const bool have_strtab_data = strtab_data.GetByteSize() > 0; - if (!have_strtab_data) { - if (process) { - if (strtab_addr == LLDB_INVALID_ADDRESS) { - if (log) - module_sp->LogMessage(log, "failed to locate the strtab in memory"); - return 0; - } - } else { - if (log) - module_sp->LogMessage(log, "failed to read strtab data"); - return 0; - } - } ConstString g_segment_name_TEXT = GetSegmentNameTEXT(); ConstString g_segment_name_DATA = GetSegmentNameDATA(); @@ -2398,6 +2452,7 @@ size_t ObjectFileMachO::ParseSymtab() { section_list->FindSectionByName(g_section_name_eh_frame); const bool is_arm = (m_header.cputype == llvm::MachO::CPU_TYPE_ARM); + const bool always_thumb = GetArchitecture().IsAlwaysThumbInstructions(); // lldb works best if it knows the start address of all functions in a // module. Linker symbols or debug info are normally the best source of @@ -2423,6 +2478,14 @@ size_t ObjectFileMachO::ParseSymtab() { 0) { // Now append the current entry function_start_entry.addr += delta; + if (is_arm) { + if (function_start_entry.addr & 1) { + function_start_entry.addr &= THUMB_ADDRESS_BIT_MASK; + function_start_entry.data = true; + } else if (always_thumb) { + function_start_entry.data = true; + } + } function_starts.Append(function_start_entry); } } else { @@ -2445,6 +2508,14 @@ size_t ObjectFileMachO::ParseSymtab() { if (func) { FunctionStarts::Entry function_start_entry; function_start_entry.addr = func->base - text_base_addr; + if (is_arm) { + if (function_start_entry.addr & 1) { + function_start_entry.addr &= THUMB_ADDRESS_BIT_MASK; + function_start_entry.data = true; + } else if (always_thumb) { + function_start_entry.data = true; + } + } function_starts.Append(function_start_entry); } } @@ -2505,32 +2576,27 @@ size_t ObjectFileMachO::ParseSymtab() { std::string memory_symbol_name; uint32_t unmapped_local_symbols_found = 0; - std::vector trie_entries; + std::vector reexport_trie_entries; + std::vector external_sym_trie_entries; std::set resolver_addresses; if (dyld_trie_data.GetByteSize() > 0) { - std::vector nameSlices; - ParseTrieEntries(dyld_trie_data, 0, is_arm, nameSlices, resolver_addresses, - trie_entries); - ConstString text_segment_name("__TEXT"); SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name); - if (text_segment_sp) { - const lldb::addr_t text_segment_file_addr = - text_segment_sp->GetFileAddress(); - if (text_segment_file_addr != LLDB_INVALID_ADDRESS) { - for (auto &e : trie_entries) - e.entry.address += text_segment_file_addr; - } - } + lldb::addr_t text_segment_file_addr = LLDB_INVALID_ADDRESS; + if (text_segment_sp) + text_segment_file_addr = text_segment_sp->GetFileAddress(); + std::vector nameSlices; + ParseTrieEntries(dyld_trie_data, 0, is_arm, text_segment_file_addr, + nameSlices, resolver_addresses, reexport_trie_entries, + external_sym_trie_entries); } typedef std::set IndirectSymbols; IndirectSymbols indirect_symbol_names; -#if defined(__APPLE__) && \ - (defined(__arm__) || defined(__arm64__) || defined(__aarch64__)) +#if defined(__APPLE__) && TARGET_OS_EMBEDDED // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been // optimized by moving LOCAL symbols out of the memory mapped portion of @@ -2542,7 +2608,7 @@ size_t ObjectFileMachO::ParseSymtab() { // to parse any DSC unmapped symbol information. If we find any, we set a // flag that tells the normal nlist parser to ignore all LOCAL symbols. - if (m_header.flags & 0x80000000u) { + if (m_header.flags & MH_DYLIB_IN_CACHE) { // Before we can start mapping the DSC, we need to make certain the // target process is actually using the cache we can find. @@ -3503,8 +3569,8 @@ size_t ObjectFileMachO::ParseSymtab() { N_FUN_addr_to_sym_idx.equal_range(nlist.n_value); if (range.first != range.second) { bool found_it = false; - for (const auto pos = range.first; - pos != range.second; ++pos) { + for (auto pos = range.first; pos != range.second; + ++pos) { if (sym[sym_idx].GetMangled().GetName( lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) == @@ -3548,8 +3614,8 @@ size_t ObjectFileMachO::ParseSymtab() { nlist.n_value); if (range.first != range.second) { bool found_it = false; - for (const auto pos = range.first; - pos != range.second; ++pos) { + for (auto pos = range.first; pos != range.second; + ++pos) { if (sym[sym_idx].GetMangled().GetName( lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) == @@ -3595,6 +3661,9 @@ size_t ObjectFileMachO::ParseSymtab() { symbol_section); sym[GSYM_sym_idx].GetAddressRef().SetOffset( symbol_value); + symbols_added.insert(sym[GSYM_sym_idx] + .GetAddress() + .GetFileAddress()); // We just need the flags from the linker // symbol, so put these flags // into the N_GSYM flags to avoid duplicate @@ -3614,6 +3683,8 @@ size_t ObjectFileMachO::ParseSymtab() { if (set_value) { sym[sym_idx].GetAddressRef().SetSection(symbol_section); sym[sym_idx].GetAddressRef().SetOffset(symbol_value); + symbols_added.insert( + sym[sym_idx].GetAddress().GetFileAddress()); } sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc); @@ -3902,10 +3973,7 @@ size_t ObjectFileMachO::ParseSymtab() { // filename, so here we combine it with the first one if we are // minimizing the symbol table const char *so_path = - sym[sym_idx - 1] - .GetMangled() - .GetDemangledName(lldb::eLanguageTypeUnknown) - .AsCString(); + sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString(); if (so_path && so_path[0]) { std::string full_so_path(so_path); const size_t double_slash_pos = full_so_path.find("//"); @@ -4297,11 +4365,10 @@ size_t ObjectFileMachO::ParseSymtab() { } if (is_gsym) { - const char *gsym_name = - sym[sym_idx] - .GetMangled() - .GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) - .GetCString(); + const char *gsym_name = sym[sym_idx] + .GetMangled() + .GetName(Mangled::ePreferMangled) + .GetCString(); if (gsym_name) N_GSYM_name_to_sym_idx[gsym_name] = sym_idx; } @@ -4365,10 +4432,9 @@ size_t ObjectFileMachO::ParseSymtab() { if (range.first != range.second) { for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos) { - if (sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, - Mangled::ePreferMangled) == + if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName( - lldb::eLanguageTypeUnknown, Mangled::ePreferMangled)) { + Mangled::ePreferMangled)) { m_nlist_idx_to_sym_idx[nlist_idx] = pos->second; // We just need the flags from the linker symbol, so put these // flags into the N_FUN flags to avoid duplicate symbols in the @@ -4401,10 +4467,9 @@ size_t ObjectFileMachO::ParseSymtab() { if (range.first != range.second) { for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos) { - if (sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, - Mangled::ePreferMangled) == + if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName( - lldb::eLanguageTypeUnknown, Mangled::ePreferMangled)) { + Mangled::ePreferMangled)) { m_nlist_idx_to_sym_idx[nlist_idx] = pos->second; // We just need the flags from the linker symbol, so put these // flags into the N_STSYM flags to avoid duplicate symbols in @@ -4419,8 +4484,7 @@ size_t ObjectFileMachO::ParseSymtab() { // Combine N_GSYM stab entries with the non stab symbol. const char *gsym_name = sym[sym_idx] .GetMangled() - .GetName(lldb::eLanguageTypeUnknown, - Mangled::ePreferMangled) + .GetName(Mangled::ePreferMangled) .GetCString(); if (gsym_name) { ConstNameToSymbolIndexMap::const_iterator pos = @@ -4432,6 +4496,8 @@ size_t ObjectFileMachO::ParseSymtab() { // invalid address of zero when the global is a common symbol. sym[GSYM_sym_idx].GetAddressRef().SetSection(symbol_section); sym[GSYM_sym_idx].GetAddressRef().SetOffset(symbol_value); + symbols_added.insert( + sym[GSYM_sym_idx].GetAddress().GetFileAddress()); // We just need the flags from the linker symbol, so put these // flags into the N_GSYM flags to avoid duplicate symbols in // the symbol table. @@ -4449,6 +4515,7 @@ size_t ObjectFileMachO::ParseSymtab() { if (set_value) { sym[sym_idx].GetAddressRef().SetSection(symbol_section); sym[sym_idx].GetAddressRef().SetOffset(symbol_value); + symbols_added.insert(sym[sym_idx].GetAddress().GetFileAddress()); } sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc); if (nlist.n_desc & N_WEAK_REF) @@ -4505,12 +4572,58 @@ size_t ObjectFileMachO::ParseSymtab() { } } + // Count how many trie symbols we'll add to the symbol table + int trie_symbol_table_augment_count = 0; + for (auto &e : external_sym_trie_entries) { + if (symbols_added.find(e.entry.address) == symbols_added.end()) + trie_symbol_table_augment_count++; + } + + if (num_syms < sym_idx + trie_symbol_table_augment_count) { + num_syms = sym_idx + trie_symbol_table_augment_count; + sym = symtab->Resize(num_syms); + } uint32_t synthetic_sym_id = symtab_load_command.nsyms; + // Add symbols from the trie to the symbol table. + for (auto &e : external_sym_trie_entries) { + if (symbols_added.find(e.entry.address) != symbols_added.end()) + continue; + + // Find the section that this trie address is in, use that to annotate + // symbol type as we add the trie address and name to the symbol table. + Address symbol_addr; + if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) { + SectionSP symbol_section(symbol_addr.GetSection()); + const char *symbol_name = e.entry.name.GetCString(); + bool demangled_is_synthesized = false; + SymbolType type = + GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp, + data_section_sp, data_dirty_section_sp, + data_const_section_sp, symbol_section); + + sym[sym_idx].SetType(type); + if (symbol_section) { + sym[sym_idx].SetID(synthetic_sym_id++); + sym[sym_idx].GetMangled().SetMangledName(ConstString(symbol_name)); + if (demangled_is_synthesized) + sym[sym_idx].SetDemangledNameIsSynthesized(true); + sym[sym_idx].SetIsSynthetic(true); + sym[sym_idx].SetExternal(true); + sym[sym_idx].GetAddressRef() = symbol_addr; + symbols_added.insert(symbol_addr.GetFileAddress()); + if (e.entry.flags & TRIE_SYMBOL_IS_THUMB) + sym[sym_idx].SetFlags(MACHO_NLIST_ARM_SYMBOL_IS_THUMB); + ++sym_idx; + } + } + } + if (function_starts_count > 0) { uint32_t num_synthetic_function_symbols = 0; for (i = 0; i < function_starts_count; ++i) { - if (!function_starts.GetEntryRef(i).data) + if (symbols_added.find(function_starts.GetEntryRef(i).addr) == + symbols_added.end()) ++num_synthetic_function_symbols; } @@ -4522,14 +4635,11 @@ size_t ObjectFileMachO::ParseSymtab() { for (i = 0; i < function_starts_count; ++i) { const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex(i); - if (!func_start_entry->data) { + if (symbols_added.find(func_start_entry->addr) == symbols_added.end()) { addr_t symbol_file_addr = func_start_entry->addr; uint32_t symbol_flags = 0; - if (is_arm) { - if (symbol_file_addr & 1) - symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB; - symbol_file_addr &= THUMB_ADDRESS_BIT_MASK; - } + if (func_start_entry->data) + symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB; Address symbol_addr; if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) { SectionSP symbol_section(symbol_addr.GetSection()); @@ -4556,6 +4666,7 @@ size_t ObjectFileMachO::ParseSymtab() { sym[sym_idx].SetType(eSymbolTypeCode); sym[sym_idx].SetIsSynthetic(true); sym[sym_idx].GetAddressRef() = symbol_addr; + symbols_added.insert(symbol_addr.GetFileAddress()); if (symbol_flags) sym[sym_idx].SetFlags(symbol_flags); if (symbol_byte_size) @@ -4656,6 +4767,7 @@ size_t ObjectFileMachO::ParseSymtab() { sym[sym_idx].SetType(eSymbolTypeResolver); sym[sym_idx].SetIsSynthetic(true); sym[sym_idx].GetAddressRef() = so_addr; + symbols_added.insert(so_addr.GetFileAddress()); sym[sym_idx].SetByteSize(symbol_stub_byte_size); ++sym_idx; } @@ -4673,8 +4785,8 @@ size_t ObjectFileMachO::ParseSymtab() { } } - if (!trie_entries.empty()) { - for (const auto &e : trie_entries) { + if (!reexport_trie_entries.empty()) { + for (const auto &e : reexport_trie_entries) { if (e.entry.import_name) { // Only add indirect symbols from the Trie entries if we didn't have // a N_INDR nlist entry for this already @@ -4740,7 +4852,8 @@ void ObjectFileMachO::Dump(Stream *s) { *s << "\n"; SectionList *sections = GetSectionList(); if (sections) - sections->Dump(s, nullptr, true, UINT32_MAX); + sections->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true, + UINT32_MAX); if (m_symtab_up) m_symtab_up->Dump(s, nullptr, eSortOrderNone); @@ -5085,10 +5198,10 @@ uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) { std::string loader_path("@loader_path"); std::string executable_path("@executable_path"); for (auto &rpath : rpath_paths) { - if (rpath.find(loader_path) == 0) { + if (llvm::StringRef(rpath).startswith(loader_path)) { rpath.erase(0, loader_path.size()); rpath.insert(0, this_file_spec.GetDirectory().GetCString()); - } else if (rpath.find(executable_path) == 0) { + } else if (llvm::StringRef(rpath).startswith(executable_path)) { rpath.erase(0, executable_path.size()); rpath.insert(0, this_file_spec.GetDirectory().GetCString()); } diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/gnu/llvm/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h index eb843298d07..979e637ef6f 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ObjectFileMachO_h_ -#define liblldb_ObjectFileMachO_h_ +#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_MACH_O_OBJECTFILEMACHO_H +#define LLDB_SOURCE_PLUGINS_OBJECTFILE_MACH_O_OBJECTFILEMACHO_H #include "lldb/Core/Address.h" #include "lldb/Core/FileSpecList.h" @@ -193,7 +193,7 @@ protected: size_t ParseSymtab(); - typedef lldb_private::RangeArray EncryptedFileRanges; + typedef lldb_private::RangeVector EncryptedFileRanges; EncryptedFileRanges GetEncryptedFileRanges(); struct SegmentParsingContext; @@ -230,4 +230,4 @@ protected: bool m_allow_assembly_emulation_unwind_plans; }; -#endif // liblldb_ObjectFileMachO_h_ +#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_MACH_O_OBJECTFILEMACHO_H diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp index 750bc77bdf7..dac2c496423 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp @@ -1,4 +1,4 @@ -//===-- ObjectFilePECOFF.cpp ------------------------------------*- C++ -*-===// +//===-- ObjectFilePECOFF.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -41,6 +41,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(ObjectFilePECOFF) + struct CVInfoPdb70 { // 16-byte GUID struct _Guid { @@ -53,15 +55,12 @@ struct CVInfoPdb70 { llvm::support::ulittle32_t Age; }; -static UUID GetCoffUUID(llvm::object::COFFObjectFile *coff_obj) { - if (!coff_obj) - return UUID(); - +static UUID GetCoffUUID(llvm::object::COFFObjectFile &coff_obj) { const llvm::codeview::DebugInfo *pdb_info = nullptr; llvm::StringRef pdb_file; // This part is similar with what has done in minidump parser. - if (!coff_obj->getDebugPDBInfo(pdb_info, pdb_file) && pdb_info) { + if (!coff_obj.getDebugPDBInfo(pdb_info, pdb_file) && pdb_info) { if (pdb_info->PDB70.CVSignature == llvm::OMF::Signature::PDB70) { using llvm::support::endian::read16be; using llvm::support::endian::read32be; @@ -170,7 +169,11 @@ size_t ObjectFilePECOFF::GetModuleSpecifications( Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); - auto binary = llvm::object::createBinary(file.GetPath()); + if (data_sp->GetByteSize() < length) + if (DataBufferSP full_sp = MapFileData(file, -1, file_offset)) + data_sp = std::move(full_sp); + auto binary = llvm::object::createBinary(llvm::MemoryBufferRef( + toStringRef(data_sp->GetData()), file.GetFilename().GetStringRef())); if (!binary) { LLDB_LOG_ERROR(log, binary.takeError(), @@ -178,18 +181,15 @@ size_t ObjectFilePECOFF::GetModuleSpecifications( return initial_count; } - if (!binary->getBinary()->isCOFF() && - !binary->getBinary()->isCOFFImportFile()) + auto *COFFObj = llvm::dyn_cast(binary->get()); + if (!COFFObj) return initial_count; - auto COFFObj = - llvm::cast(binary->getBinary()); - ModuleSpec module_spec(file); ArchSpec &spec = module_spec.GetArchitecture(); lldb_private::UUID &uuid = module_spec.GetUUID(); if (!uuid.IsValid()) - uuid = GetCoffUUID(COFFObj); + uuid = GetCoffUUID(*COFFObj); switch (COFFObj->getMachine()) { case MachineAmd64: @@ -242,12 +242,13 @@ lldb::SymbolType ObjectFilePECOFF::MapSymbolType(uint16_t coff_symbol_type) { } bool ObjectFilePECOFF::CreateBinary() { - if (m_owningbin) + if (m_binary) return true; Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); - auto binary = llvm::object::createBinary(m_file.GetPath()); + auto binary = llvm::object::createBinary(llvm::MemoryBufferRef( + toStringRef(m_data.GetData()), m_file.GetFilename().GetStringRef())); if (!binary) { LLDB_LOG_ERROR(log, binary.takeError(), "Failed to create binary for file ({1}): {0}", m_file); @@ -255,19 +256,14 @@ bool ObjectFilePECOFF::CreateBinary() { } // Make sure we only handle COFF format. - if (!binary->getBinary()->isCOFF() && - !binary->getBinary()->isCOFFImportFile()) + m_binary = + llvm::unique_dyn_cast(std::move(*binary)); + if (!m_binary) return false; - m_owningbin = OWNBINType(std::move(*binary)); - LLDB_LOGF(log, - "%p ObjectFilePECOFF::CreateBinary() module = %p (%s), file = " - "%s, binary = %p (Bin = %p)", - static_cast(this), static_cast(GetModule().get()), - GetModule()->GetSpecificationDescription().c_str(), - m_file ? m_file.GetPath().c_str() : "", - static_cast(m_owningbin.getPointer()), - static_cast(m_owningbin->getBinary())); + LLDB_LOG(log, "this = {0}, module = {1} ({2}), file = {3}, binary = {4}", + this, GetModule().get(), GetModule()->GetSpecificationDescription(), + m_file.GetPath(), m_binary.get()); return true; } @@ -279,7 +275,7 @@ ObjectFilePECOFF::ObjectFilePECOFF(const lldb::ModuleSP &module_sp, lldb::offset_t length) : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset), m_dos_header(), m_coff_header(), m_sect_headers(), - m_entry_point_address(), m_deps_filespec(), m_owningbin() { + m_entry_point_address(), m_deps_filespec() { ::memset(&m_dos_header, 0, sizeof(m_dos_header)); ::memset(&m_coff_header, 0, sizeof(m_coff_header)); } @@ -290,7 +286,7 @@ ObjectFilePECOFF::ObjectFilePECOFF(const lldb::ModuleSP &module_sp, addr_t header_addr) : ObjectFile(module_sp, process_sp, header_addr, header_data_sp), m_dos_header(), m_coff_header(), m_sect_headers(), - m_entry_point_address(), m_deps_filespec(), m_owningbin() { + m_entry_point_address(), m_deps_filespec() { ::memset(&m_dos_header, 0, sizeof(m_dos_header)); ::memset(&m_coff_header, 0, sizeof(m_coff_header)); } @@ -544,6 +540,9 @@ DataExtractor ObjectFilePECOFF::ReadImageData(uint32_t offset, size_t size) { if (!size) return {}; + if (m_data.ValidOffsetForDataOfSize(offset, size)) + return DataExtractor(m_data, offset, size); + if (m_file) { // A bit of a hack, but we intend to write to this buffer, so we can't // mmap it. @@ -567,13 +566,11 @@ DataExtractor ObjectFilePECOFF::ReadImageData(uint32_t offset, size_t size) { } DataExtractor ObjectFilePECOFF::ReadImageDataByRVA(uint32_t rva, size_t size) { - if (m_file) { - Address addr = GetAddress(rva); - SectionSP sect = addr.GetSection(); - if (!sect) - return {}; - rva = sect->GetFileOffset() + addr.GetOffset(); - } + Address addr = GetAddress(rva); + SectionSP sect = addr.GetSection(); + if (!sect) + return {}; + rva = sect->GetFileOffset() + addr.GetOffset(); return ReadImageData(rva, size); } @@ -638,7 +635,7 @@ Symtab *ObjectFilePECOFF::GetSymtab() { std::lock_guard guard(module_sp->GetMutex()); if (m_symtab_up == nullptr) { SectionList *sect_list = GetSectionList(); - m_symtab_up.reset(new Symtab(this)); + m_symtab_up = std::make_unique(this); std::lock_guard guard(m_symtab_up->GetMutex()); const uint32_t num_syms = m_coff_header.nsyms; @@ -659,7 +656,7 @@ Symtab *ObjectFilePECOFF::GetSymtab() { // because it is used as offset 0 to encode a NULL string. uint32_t *strtab_data_start = const_cast( reinterpret_cast(strtab_data.GetDataStart())); - strtab_data_start[0] = 0; + ::memset(&strtab_data_start[0], 0, sizeof(uint32_t)); offset = 0; std::string symbol_name; @@ -701,7 +698,7 @@ Symtab *ObjectFilePECOFF::GetSymtab() { if (symbol.naux > 0) { i += symbol.naux; - offset += symbol_size; + offset += symbol.naux * symbol_size; } } } @@ -866,7 +863,7 @@ SectionType ObjectFilePECOFF::GetSectionType(llvm::StringRef sect_name, void ObjectFilePECOFF::CreateSections(SectionList &unified_section_list) { if (m_sections_up) return; - m_sections_up.reset(new SectionList()); + m_sections_up = std::make_unique(); ModuleSP module_sp(GetModule()); if (module_sp) { @@ -929,10 +926,7 @@ UUID ObjectFilePECOFF::GetUUID() { if (!CreateBinary()) return UUID(); - auto COFFObj = - llvm::cast(m_owningbin->getBinary()); - - m_uuid = GetCoffUUID(COFFObj); + m_uuid = GetCoffUUID(*m_binary); return m_uuid; } @@ -950,30 +944,20 @@ uint32_t ObjectFilePECOFF::ParseDependentModules() { return 0; Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); - LLDB_LOGF(log, - "%p ObjectFilePECOFF::ParseDependentModules() module = %p " - "(%s), binary = %p (Bin = %p)", - static_cast(this), static_cast(module_sp.get()), - module_sp->GetSpecificationDescription().c_str(), - static_cast(m_owningbin.getPointer()), - static_cast(m_owningbin->getBinary())); - - auto COFFObj = - llvm::dyn_cast(m_owningbin->getBinary()); - if (!COFFObj) - return 0; + LLDB_LOG(log, "this = {0}, module = {1} ({2}), file = {3}, binary = {4}", + this, GetModule().get(), GetModule()->GetSpecificationDescription(), + m_file.GetPath(), m_binary.get()); m_deps_filespec = FileSpecList(); - for (const auto &entry : COFFObj->import_directories()) { + for (const auto &entry : m_binary->import_directories()) { llvm::StringRef dll_name; - auto ec = entry.getName(dll_name); // Report a bogus entry. - if (ec != std::error_code()) { + if (llvm::Error e = entry.getName(dll_name)) { LLDB_LOGF(log, "ObjectFilePECOFF::ParseDependentModules() - failed to get " "import directory entry name: %s", - ec.message().c_str()); + llvm::toString(std::move(e)).c_str()); continue; } @@ -1045,7 +1029,8 @@ void ObjectFilePECOFF::Dump(Stream *s) { SectionList *sections = GetSectionList(); if (sections) - sections->Dump(s, nullptr, true, UINT32_MAX); + sections->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true, + UINT32_MAX); if (m_symtab_up) m_symtab_up->Dump(s, nullptr, eSortOrderNone); @@ -1172,7 +1157,7 @@ void ObjectFilePECOFF::DumpOptCOFFHeader(Stream *s, // Dump a single ELF section header to the specified output stream void ObjectFilePECOFF::DumpSectionHeader(Stream *s, const section_header_t &sh) { - std::string name = GetSectionName(sh); + std::string name = std::string(GetSectionName(sh)); s->Printf("%-16s 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%4.4x " "0x%4.4x 0x%8.8x\n", name.c_str(), sh.vmaddr, sh.vmsize, sh.offset, sh.size, sh.reloff, diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h b/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h index c0efe702f57..fdcacbeab1e 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h @@ -6,13 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ObjectFilePECOFF_h_ -#define liblldb_ObjectFilePECOFF_h_ +#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_PECOFF_OBJECTFILEPECOFF_H +#define LLDB_SOURCE_PLUGINS_OBJECTFILE_PECOFF_OBJECTFILEPECOFF_H #include #include "lldb/Symbol/ObjectFile.h" -#include "llvm/Object/Binary.h" +#include "llvm/Object/COFF.h" class ObjectFilePECOFF : public lldb_private::ObjectFile { public: @@ -293,7 +293,6 @@ protected: private: bool CreateBinary(); -private: dos_header_t m_dos_header; coff_header_t m_coff_header; coff_opt_header_t m_coff_header_opt; @@ -301,9 +300,8 @@ private: lldb::addr_t m_image_base; lldb_private::Address m_entry_point_address; llvm::Optional m_deps_filespec; - typedef llvm::object::OwningBinary OWNBINType; - llvm::Optional m_owningbin; + std::unique_ptr m_binary; lldb_private::UUID m_uuid; }; -#endif // liblldb_ObjectFilePECOFF_h_ +#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_PECOFF_OBJECTFILEPECOFF_H diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/PECallFrameInfo.h b/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/PECallFrameInfo.h index b5932dc726a..7c2a479ecdd 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/PECallFrameInfo.h +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/PECallFrameInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PECallFrameInfo_h_ -#define liblldb_PECallFrameInfo_h_ +#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_PECOFF_PECALLFRAMEINFO_H +#define LLDB_SOURCE_PLUGINS_OBJECTFILE_PECOFF_PECALLFRAMEINFO_H #include "lldb/Symbol/CallFrameInfo.h" #include "lldb/Utility/DataExtractor.h" @@ -44,4 +44,4 @@ private: lldb_private::DataExtractor m_exception_dir; }; -#endif // liblldb_PECallFrameInfo_h_ +#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_PECOFF_PECALLFRAMEINFO_H diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp b/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp index d5da60b19bf..500af933e93 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp @@ -1,4 +1,4 @@ -//===-- WindowsMiniDump.cpp -------------------------------------*- C++ -*-===// +//===-- WindowsMiniDump.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.h b/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.h index 9aaed6908a1..04b93e22136 100644 --- a/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.h +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_WindowsMiniDump_h_ -#define liblldb_WindowsMiniDump_h_ +#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_PECOFF_WINDOWSMINIDUMP_H +#define LLDB_SOURCE_PLUGINS_OBJECTFILE_PECOFF_WINDOWSMINIDUMP_H #include "lldb/Target/Process.h" diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/wasm/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/ObjectFile/wasm/CMakeLists.txt new file mode 100644 index 00000000000..5069b6b19b9 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/wasm/CMakeLists.txt @@ -0,0 +1,11 @@ +add_lldb_library(lldbPluginObjectFileWasm PLUGIN + ObjectFileWasm.cpp + + LINK_LIBS + lldbCore + lldbHost + lldbSymbol + lldbUtility + LINK_COMPONENTS + Support + ) diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp b/gnu/llvm/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp new file mode 100644 index 00000000000..91150fa02eb --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp @@ -0,0 +1,466 @@ +//===-- ObjectFileWasm.cpp ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ObjectFileWasm.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Section.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/SectionLoadList.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/Log.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/Magic.h" +#include "llvm/BinaryFormat/Wasm.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Format.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::wasm; + +LLDB_PLUGIN_DEFINE(ObjectFileWasm) + +static const uint32_t kWasmHeaderSize = + sizeof(llvm::wasm::WasmMagic) + sizeof(llvm::wasm::WasmVersion); + +/// Checks whether the data buffer starts with a valid Wasm module header. +static bool ValidateModuleHeader(const DataBufferSP &data_sp) { + if (!data_sp || data_sp->GetByteSize() < kWasmHeaderSize) + return false; + + if (llvm::identify_magic(toStringRef(data_sp->GetData())) != + llvm::file_magic::wasm_object) + return false; + + uint8_t *Ptr = data_sp->GetBytes() + sizeof(llvm::wasm::WasmMagic); + + uint32_t version = llvm::support::endian::read32le(Ptr); + return version == llvm::wasm::WasmVersion; +} + +static llvm::Optional +GetWasmString(llvm::DataExtractor &data, llvm::DataExtractor::Cursor &c) { + // A Wasm string is encoded as a vector of UTF-8 codes. + // Vectors are encoded with their u32 length followed by the element + // sequence. + uint64_t len = data.getULEB128(c); + if (!c) { + consumeError(c.takeError()); + return llvm::None; + } + + if (len >= (uint64_t(1) << 32)) { + return llvm::None; + } + + llvm::SmallVector str_storage; + data.getU8(c, str_storage, len); + if (!c) { + consumeError(c.takeError()); + return llvm::None; + } + + llvm::StringRef str = toStringRef(makeArrayRef(str_storage)); + return ConstString(str); +} + +char ObjectFileWasm::ID; + +void ObjectFileWasm::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance, + CreateMemoryInstance, GetModuleSpecifications); +} + +void ObjectFileWasm::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +ConstString ObjectFileWasm::GetPluginNameStatic() { + static ConstString g_name("wasm"); + return g_name; +} + +ObjectFile * +ObjectFileWasm::CreateInstance(const ModuleSP &module_sp, DataBufferSP &data_sp, + offset_t data_offset, const FileSpec *file, + offset_t file_offset, offset_t length) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + + if (!data_sp) { + data_sp = MapFileData(*file, length, file_offset); + if (!data_sp) { + LLDB_LOGF(log, "Failed to create ObjectFileWasm instance for file %s", + file->GetPath().c_str()); + return nullptr; + } + data_offset = 0; + } + + assert(data_sp); + if (!ValidateModuleHeader(data_sp)) { + LLDB_LOGF(log, + "Failed to create ObjectFileWasm instance: invalid Wasm header"); + return nullptr; + } + + // Update the data to contain the entire file if it doesn't contain it + // already. + if (data_sp->GetByteSize() < length) { + data_sp = MapFileData(*file, length, file_offset); + if (!data_sp) { + LLDB_LOGF(log, + "Failed to create ObjectFileWasm instance: cannot read file %s", + file->GetPath().c_str()); + return nullptr; + } + data_offset = 0; + } + + std::unique_ptr objfile_up(new ObjectFileWasm( + module_sp, data_sp, data_offset, file, file_offset, length)); + ArchSpec spec = objfile_up->GetArchitecture(); + if (spec && objfile_up->SetModulesArchitecture(spec)) { + LLDB_LOGF(log, + "%p ObjectFileWasm::CreateInstance() module = %p (%s), file = %s", + static_cast(objfile_up.get()), + static_cast(objfile_up->GetModule().get()), + objfile_up->GetModule()->GetSpecificationDescription().c_str(), + file ? file->GetPath().c_str() : ""); + return objfile_up.release(); + } + + LLDB_LOGF(log, "Failed to create ObjectFileWasm instance"); + return nullptr; +} + +ObjectFile *ObjectFileWasm::CreateMemoryInstance(const ModuleSP &module_sp, + DataBufferSP &data_sp, + const ProcessSP &process_sp, + addr_t header_addr) { + if (!ValidateModuleHeader(data_sp)) + return nullptr; + + std::unique_ptr objfile_up( + new ObjectFileWasm(module_sp, data_sp, process_sp, header_addr)); + ArchSpec spec = objfile_up->GetArchitecture(); + if (spec && objfile_up->SetModulesArchitecture(spec)) + return objfile_up.release(); + return nullptr; +} + +bool ObjectFileWasm::DecodeNextSection(lldb::offset_t *offset_ptr) { + // Buffer sufficient to read a section header and find the pointer to the next + // section. + const uint32_t kBufferSize = 1024; + DataExtractor section_header_data = ReadImageData(*offset_ptr, kBufferSize); + + llvm::DataExtractor data = section_header_data.GetAsLLVM(); + llvm::DataExtractor::Cursor c(0); + + // Each section consists of: + // - a one-byte section id, + // - the u32 size of the contents, in bytes, + // - the actual contents. + uint8_t section_id = data.getU8(c); + uint64_t payload_len = data.getULEB128(c); + if (!c) + return !llvm::errorToBool(c.takeError()); + + if (payload_len >= (uint64_t(1) << 32)) + return false; + + if (section_id == llvm::wasm::WASM_SEC_CUSTOM) { + // Custom sections have the id 0. Their contents consist of a name + // identifying the custom section, followed by an uninterpreted sequence + // of bytes. + lldb::offset_t prev_offset = c.tell(); + llvm::Optional sect_name = GetWasmString(data, c); + if (!sect_name) + return false; + + if (payload_len < c.tell() - prev_offset) + return false; + + uint32_t section_length = payload_len - (c.tell() - prev_offset); + m_sect_infos.push_back(section_info{*offset_ptr + c.tell(), section_length, + section_id, *sect_name}); + *offset_ptr += (c.tell() + section_length); + } else if (section_id <= llvm::wasm::WASM_SEC_EVENT) { + m_sect_infos.push_back(section_info{*offset_ptr + c.tell(), + static_cast(payload_len), + section_id, ConstString()}); + *offset_ptr += (c.tell() + payload_len); + } else { + // Invalid section id. + return false; + } + return true; +} + +bool ObjectFileWasm::DecodeSections() { + lldb::offset_t offset = kWasmHeaderSize; + if (IsInMemory()) { + offset += m_memory_addr; + } + + while (DecodeNextSection(&offset)) + ; + return true; +} + +size_t ObjectFileWasm::GetModuleSpecifications( + const FileSpec &file, DataBufferSP &data_sp, offset_t data_offset, + offset_t file_offset, offset_t length, ModuleSpecList &specs) { + if (!ValidateModuleHeader(data_sp)) { + return 0; + } + + ModuleSpec spec(file, ArchSpec("wasm32-unknown-unknown-wasm")); + specs.Append(spec); + return 1; +} + +ObjectFileWasm::ObjectFileWasm(const ModuleSP &module_sp, DataBufferSP &data_sp, + offset_t data_offset, const FileSpec *file, + offset_t offset, offset_t length) + : ObjectFile(module_sp, file, offset, length, data_sp, data_offset), + m_arch("wasm32-unknown-unknown-wasm") { + m_data.SetAddressByteSize(4); +} + +ObjectFileWasm::ObjectFileWasm(const lldb::ModuleSP &module_sp, + lldb::DataBufferSP &header_data_sp, + const lldb::ProcessSP &process_sp, + lldb::addr_t header_addr) + : ObjectFile(module_sp, process_sp, header_addr, header_data_sp), + m_arch("wasm32-unknown-unknown-wasm") {} + +bool ObjectFileWasm::ParseHeader() { + // We already parsed the header during initialization. + return true; +} + +Symtab *ObjectFileWasm::GetSymtab() { return nullptr; } + +void ObjectFileWasm::CreateSections(SectionList &unified_section_list) { + if (m_sections_up) + return; + + m_sections_up = std::make_unique(); + + if (m_sect_infos.empty()) { + DecodeSections(); + } + + for (const section_info §_info : m_sect_infos) { + SectionType section_type = eSectionTypeOther; + ConstString section_name; + offset_t file_offset = sect_info.offset & 0xffffffff; + addr_t vm_addr = file_offset; + size_t vm_size = sect_info.size; + + if (llvm::wasm::WASM_SEC_CODE == sect_info.id) { + section_type = eSectionTypeCode; + section_name = ConstString("code"); + + // A code address in DWARF for WebAssembly is the offset of an + // instruction relative within the Code section of the WebAssembly file. + // For this reason Section::GetFileAddress() must return zero for the + // Code section. + vm_addr = 0; + } else { + section_type = + llvm::StringSwitch(sect_info.name.GetStringRef()) + .Case(".debug_abbrev", eSectionTypeDWARFDebugAbbrev) + .Case(".debug_addr", eSectionTypeDWARFDebugAddr) + .Case(".debug_aranges", eSectionTypeDWARFDebugAranges) + .Case(".debug_cu_index", eSectionTypeDWARFDebugCuIndex) + .Case(".debug_frame", eSectionTypeDWARFDebugFrame) + .Case(".debug_info", eSectionTypeDWARFDebugInfo) + .Case(".debug_line", eSectionTypeDWARFDebugLine) + .Case(".debug_line_str", eSectionTypeDWARFDebugLineStr) + .Case(".debug_loc", eSectionTypeDWARFDebugLoc) + .Case(".debug_loclists", eSectionTypeDWARFDebugLocLists) + .Case(".debug_macinfo", eSectionTypeDWARFDebugMacInfo) + .Case(".debug_macro", 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_offsets", eSectionTypeDWARFDebugStrOffsets) + .Case(".debug_types", eSectionTypeDWARFDebugTypes) + .Default(eSectionTypeOther); + if (section_type == eSectionTypeOther) + continue; + section_name = sect_info.name; + if (!IsInMemory()) { + vm_size = 0; + vm_addr = 0; + } + } + + 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. + section_type, // Section ID. + section_name, // Section name. + section_type, // Section type. + vm_addr, // VM address. + vm_size, // VM size in bytes of this section. + file_offset, // Offset of this section in the file. + sect_info.size, // Size of the section as found in the file. + 0, // Alignment of the section + 0, // Flags for this section. + 1)); // Number of host bytes per target byte + m_sections_up->AddSection(section_sp); + unified_section_list.AddSection(section_sp); + } +} + +bool ObjectFileWasm::SetLoadAddress(Target &target, lldb::addr_t load_address, + bool value_is_offset) { + /// In WebAssembly, linear memory is disjointed from code space. The VM can + /// load multiple instances of a module, which logically share the same code. + /// We represent a wasm32 code address with 64-bits, like: + /// 63 32 31 0 + /// +---------------+---------------+ + /// + module_id | offset | + /// +---------------+---------------+ + /// where the lower 32 bits represent a module offset (relative to the module + /// start not to the beginning of the code section) and the higher 32 bits + /// uniquely identify the module in the WebAssembly VM. + /// In other words, we assume that each WebAssembly module is loaded by the + /// engine at a 64-bit address that starts at the boundary of 4GB pages, like + /// 0x0000000400000000 for module_id == 4. + /// These 64-bit addresses will be used to request code ranges for a specific + /// module from the WebAssembly engine. + + assert(m_memory_addr == LLDB_INVALID_ADDRESS || + m_memory_addr == load_address); + + ModuleSP module_sp = GetModule(); + if (!module_sp) + return false; + + DecodeSections(); + + size_t num_loaded_sections = 0; + SectionList *section_list = GetSectionList(); + if (!section_list) + return false; + + const size_t num_sections = section_list->GetSize(); + for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) { + SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx)); + if (target.SetSectionLoadAddress( + section_sp, load_address | section_sp->GetFileOffset())) { + ++num_loaded_sections; + } + } + + return num_loaded_sections > 0; +} + +DataExtractor ObjectFileWasm::ReadImageData(offset_t offset, uint32_t size) { + DataExtractor data; + if (m_file) { + if (offset < GetByteSize()) { + size = std::min(static_cast(size), GetByteSize() - offset); + auto buffer_sp = MapFileData(m_file, size, offset); + return DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize()); + } + } else { + ProcessSP process_sp(m_process_wp.lock()); + if (process_sp) { + auto data_up = std::make_unique(size, 0); + Status readmem_error; + size_t bytes_read = process_sp->ReadMemory( + offset, data_up->GetBytes(), data_up->GetByteSize(), readmem_error); + if (bytes_read > 0) { + DataBufferSP buffer_sp(data_up.release()); + data.SetData(buffer_sp, 0, buffer_sp->GetByteSize()); + } + } + } + + data.SetByteOrder(GetByteOrder()); + return data; +} + +llvm::Optional ObjectFileWasm::GetExternalDebugInfoFileSpec() { + static ConstString g_sect_name_external_debug_info("external_debug_info"); + + for (const section_info §_info : m_sect_infos) { + if (g_sect_name_external_debug_info == sect_info.name) { + const uint32_t kBufferSize = 1024; + DataExtractor section_header_data = + ReadImageData(sect_info.offset, kBufferSize); + llvm::DataExtractor data = section_header_data.GetAsLLVM(); + llvm::DataExtractor::Cursor c(0); + llvm::Optional symbols_url = GetWasmString(data, c); + if (symbols_url) + return FileSpec(symbols_url->GetStringRef()); + } + } + return llvm::None; +} + +void ObjectFileWasm::Dump(Stream *s) { + ModuleSP module_sp(GetModule()); + if (!module_sp) + return; + + std::lock_guard guard(module_sp->GetMutex()); + + llvm::raw_ostream &ostream = s->AsRawOstream(); + ostream << static_cast(this) << ": "; + s->Indent(); + ostream << "ObjectFileWasm, file = '"; + m_file.Dump(ostream); + ostream << "', arch = "; + ostream << GetArchitecture().GetArchitectureName() << "\n"; + + SectionList *sections = GetSectionList(); + if (sections) { + sections->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true, + UINT32_MAX); + } + ostream << "\n"; + DumpSectionHeaders(ostream); + ostream << "\n"; +} + +void ObjectFileWasm::DumpSectionHeader(llvm::raw_ostream &ostream, + const section_info_t &sh) { + ostream << llvm::left_justify(sh.name.GetStringRef(), 16) << " " + << llvm::format_hex(sh.offset, 10) << " " + << llvm::format_hex(sh.size, 10) << " " << llvm::format_hex(sh.id, 6) + << "\n"; +} + +void ObjectFileWasm::DumpSectionHeaders(llvm::raw_ostream &ostream) { + ostream << "Section Headers\n"; + ostream << "IDX name addr size id\n"; + ostream << "==== ---------------- ---------- ---------- ------\n"; + + uint32_t idx = 0; + for (auto pos = m_sect_infos.begin(); pos != m_sect_infos.end(); + ++pos, ++idx) { + ostream << "[" << llvm::format_decimal(idx, 2) << "] "; + ObjectFileWasm::DumpSectionHeader(ostream, *pos); + } +} diff --git a/gnu/llvm/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h b/gnu/llvm/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h new file mode 100644 index 00000000000..b6e906a7b15 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h @@ -0,0 +1,151 @@ +//===-- ObjectFileWasm.h ----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_WASM_OBJECTFILEWASM_H +#define LLDB_SOURCE_PLUGINS_OBJECTFILE_WASM_OBJECTFILEWASM_H + +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Utility/ArchSpec.h" + +namespace lldb_private { +namespace wasm { + +/// Generic Wasm object file reader. +/// +/// This class provides a generic wasm32 reader plugin implementing the +/// ObjectFile protocol. +class ObjectFileWasm : public ObjectFile { +public: + static void Initialize(); + static void Terminate(); + + static ConstString GetPluginNameStatic(); + static const char *GetPluginDescriptionStatic() { + return "WebAssembly 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; } + /// \} + + /// LLVM RTTI support + /// \{ + static char ID; + bool isA(const void *ClassID) const override { + return ClassID == &ID || ObjectFile::isA(ClassID); + } + static bool classof(const ObjectFile *obj) { return obj->isA(&ID); } + /// \} + + /// 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 !!GetExternalDebugInfoFileSpec(); } + + void CreateSections(SectionList &unified_section_list) override; + + void Dump(Stream *s) override; + + ArchSpec GetArchitecture() override { return m_arch; } + + UUID GetUUID() override { return m_uuid; } + + uint32_t GetDependentModules(FileSpecList &files) override { return 0; } + + Type CalculateType() override { return eTypeSharedLibrary; } + + Strata CalculateStrata() override { return eStrataUser; } + + bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, + bool value_is_offset) override; + + lldb_private::Address GetBaseAddress() override { + return IsInMemory() ? Address(m_memory_addr) : Address(0); + } + /// \} + + /// A Wasm module that has external DWARF debug information should contain a + /// custom section named "external_debug_info", whose payload is an UTF-8 + /// encoded string that points to a Wasm module that contains the debug + /// information for this module. + llvm::Optional GetExternalDebugInfoFileSpec(); + +private: + ObjectFileWasm(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); + ObjectFileWasm(const lldb::ModuleSP &module_sp, + lldb::DataBufferSP &header_data_sp, + const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); + + /// Wasm section decoding routines. + /// \{ + bool DecodeNextSection(lldb::offset_t *offset_ptr); + bool DecodeSections(); + /// \} + + /// Read a range of bytes from the Wasm module. + DataExtractor ReadImageData(lldb::offset_t offset, uint32_t size); + + typedef struct section_info { + lldb::offset_t offset; + uint32_t size; + uint32_t id; + ConstString name; + } section_info_t; + + /// Wasm section header dump routines. + /// \{ + void DumpSectionHeader(llvm::raw_ostream &ostream, const section_info_t &sh); + void DumpSectionHeaders(llvm::raw_ostream &ostream); + /// \} + + std::vector m_sect_infos; + ArchSpec m_arch; + UUID m_uuid; +}; + +} // namespace wasm +} // namespace lldb_private +#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_WASM_OBJECTFILEWASM_H diff --git a/gnu/llvm/lldb/source/Plugins/OperatingSystem/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/OperatingSystem/CMakeLists.txt index 655007a0aab..06d909b862a 100644 --- a/gnu/llvm/lldb/source/Plugins/OperatingSystem/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/OperatingSystem/CMakeLists.txt @@ -1 +1,3 @@ -add_subdirectory(Python) +if (LLDB_ENABLE_PYTHON) + add_subdirectory(Python) +endif() diff --git a/gnu/llvm/lldb/source/Plugins/OperatingSystem/Python/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/OperatingSystem/Python/CMakeLists.txt index e8b0f31d373..91d7901011b 100644 --- a/gnu/llvm/lldb/source/Plugins/OperatingSystem/Python/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/OperatingSystem/Python/CMakeLists.txt @@ -1,4 +1,4 @@ -add_lldb_library(lldbPluginOSPython PLUGIN +add_lldb_library(lldbPluginOperatingSystemPython PLUGIN OperatingSystemPython.cpp LINK_LIBS diff --git a/gnu/llvm/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/gnu/llvm/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp index b04ac61c99a..417aa2e2143 100644 --- a/gnu/llvm/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp +++ b/gnu/llvm/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp @@ -1,4 +1,4 @@ -//===-- OperatingSystemPython.cpp --------------------------------*- C++-*-===// +//===-- OperatingSystemPython.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -39,6 +39,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(OperatingSystemPython) + void OperatingSystemPython::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, @@ -337,7 +339,7 @@ OperatingSystemPython::CreateRegisterContextForThread(Thread *thread, m_interpreter->OSPlugin_RegisterContextData(m_python_object_sp, thread->GetID()); if (reg_context_data) { - std::string value = reg_context_data->GetValue(); + std::string value = std::string(reg_context_data->GetValue()); DataBufferSP data_sp(new DataBufferHeap(value.c_str(), value.length())); if (data_sp->GetByteSize()) { RegisterContextMemory *reg_ctx_memory = new RegisterContextMemory( diff --git a/gnu/llvm/lldb/source/Plugins/Platform/Android/AdbClient.cpp b/gnu/llvm/lldb/source/Plugins/Platform/Android/AdbClient.cpp index eb3cf85fb66..ffccd6d628a 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/Android/AdbClient.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/Android/AdbClient.cpp @@ -1,4 +1,4 @@ -//===-- AdbClient.cpp -------------------------------------------*- C++ -*-===// +//===-- AdbClient.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -94,11 +94,7 @@ Status ReadAllBytes(Connection &conn, void *buffer, size_t size) { Status AdbClient::CreateByDeviceID(const std::string &device_id, AdbClient &adb) { - DeviceIDList connect_devices; - auto error = adb.GetDevices(connect_devices); - if (error.Fail()) - return error; - + Status error; std::string android_serial; if (!device_id.empty()) android_serial = device_id; @@ -106,18 +102,18 @@ Status AdbClient::CreateByDeviceID(const std::string &device_id, android_serial = env_serial; if (android_serial.empty()) { - if (connect_devices.size() != 1) + DeviceIDList connected_devices; + error = adb.GetDevices(connected_devices); + if (error.Fail()) + return error; + + if (connected_devices.size() != 1) return Status("Expected a single connected device, got instead %zu - try " "setting 'ANDROID_SERIAL'", - connect_devices.size()); - adb.SetDeviceID(connect_devices.front()); + connected_devices.size()); + adb.SetDeviceID(connected_devices.front()); } else { - auto find_it = std::find(connect_devices.begin(), connect_devices.end(), - android_serial); - if (find_it == connect_devices.end()) - return Status("Device \"%s\" not found", android_serial.c_str()); - - adb.SetDeviceID(*find_it); + adb.SetDeviceID(android_serial); } return error; } @@ -136,12 +132,12 @@ const std::string &AdbClient::GetDeviceID() const { return m_device_id; } Status AdbClient::Connect() { Status error; - m_conn.reset(new ConnectionFileDescriptor); + m_conn = std::make_unique(); std::string port = "5037"; if (const char *env_port = std::getenv("ANDROID_ADB_SERVER_PORT")) { port = env_port; } - std::string uri = "connect://localhost:" + port; + std::string uri = "connect://127.0.0.1:" + port; m_conn->Connect(uri.c_str(), &error); return error; @@ -166,7 +162,7 @@ Status AdbClient::GetDevices(DeviceIDList &device_list) { response.split(devices, "\n", -1, false); for (const auto &device : devices) - device_list.push_back(device.split('\t').first); + device_list.push_back(std::string(device.split('\t').first)); // Force disconnect since ADB closes connection after host:devices response // is sent. @@ -365,7 +361,7 @@ Status AdbClient::internalShell(const char *command, milliseconds timeout, StreamString adb_command; adb_command.Printf("shell:%s", command); - error = SendMessage(adb_command.GetString(), false); + error = SendMessage(std::string(adb_command.GetString()), false); if (error.Fail()) return error; diff --git a/gnu/llvm/lldb/source/Plugins/Platform/Android/AdbClient.h b/gnu/llvm/lldb/source/Plugins/Platform/Android/AdbClient.h index 035796b1cf9..04ad3819f57 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/Android/AdbClient.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/Android/AdbClient.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AdbClient_h_ -#define liblldb_AdbClient_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_ANDROID_ADBCLIENT_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_ANDROID_ADBCLIENT_H #include "lldb/Utility/Status.h" #include @@ -137,4 +137,4 @@ private: } // namespace platform_android } // namespace lldb_private -#endif // liblldb_AdbClient_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_ANDROID_ADBCLIENT_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp b/gnu/llvm/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp index 93fc87d6de0..9949fbf18fa 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp @@ -1,4 +1,4 @@ -//===-- PlatformAndroid.cpp -------------------------------------*- C++ -*-===// +//===-- PlatformAndroid.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -26,6 +26,8 @@ using namespace lldb_private; using namespace lldb_private::platform_android; using namespace std::chrono; +LLDB_PLUGIN_DEFINE(PlatformAndroid) + static uint32_t g_initialize_count = 0; static const unsigned int g_android_default_cache_size = 2048; // Fits inside 4k adb packet. @@ -170,7 +172,7 @@ Status PlatformAndroid::ConnectRemote(Args &args) { if (!UriParser::Parse(url, scheme, host, port, path)) return Status("Invalid URL: %s", url); if (host != "localhost") - m_device_id = host; + m_device_id = std::string(host); auto error = PlatformLinux::ConnectRemote(args); if (error.Success()) { diff --git a/gnu/llvm/lldb/source/Plugins/Platform/Android/PlatformAndroid.h b/gnu/llvm/lldb/source/Plugins/Platform/Android/PlatformAndroid.h index b710a7f46d0..2ea1c0f4618 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/Android/PlatformAndroid.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/Android/PlatformAndroid.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformAndroid_h_ -#define liblldb_PlatformAndroid_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_ANDROID_PLATFORMANDROID_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_ANDROID_PLATFORMANDROID_H #include #include @@ -77,10 +77,11 @@ private: std::string m_device_id; uint32_t m_sdk_version; - DISALLOW_COPY_AND_ASSIGN(PlatformAndroid); + PlatformAndroid(const PlatformAndroid &) = delete; + const PlatformAndroid &operator=(const PlatformAndroid &) = delete; }; } // namespace platofor_android } // namespace lldb_private -#endif // liblldb_PlatformAndroid_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_ANDROID_PLATFORMANDROID_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp b/gnu/llvm/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp index 64b6fdb9079..6dd5306a93e 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp @@ -1,4 +1,4 @@ -//===-- PlatformAndroidRemoteGDBServer.cpp ----------------------*- C++ -*-===// +//===-- PlatformAndroidRemoteGDBServer.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -117,7 +117,7 @@ Status PlatformAndroidRemoteGDBServer::ConnectRemote(Args &args) { if (!UriParser::Parse(url, scheme, host, remote_port, path)) return Status("Invalid URL: %s", url); if (host != "localhost") - m_device_id = host; + m_device_id = std::string(host); m_socket_namespace.reset(); if (scheme == ConnectionFileDescriptor::UNIX_CONNECT_SCHEME) @@ -188,7 +188,7 @@ Status PlatformAndroidRemoteGDBServer::MakeConnectURL( if (error.Success()) { m_port_forwards[pid] = local_port; std::ostringstream url_str; - url_str << "connect://localhost:" << local_port; + url_str << "connect://127.0.0.1:" << local_port; connect_url = url_str.str(); break; } diff --git a/gnu/llvm/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h b/gnu/llvm/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h index c4421a3f4a3..c3e0d0f66e8 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformAndroidRemoteGDBServer_h_ -#define liblldb_PlatformAndroidRemoteGDBServer_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_ANDROID_PLATFORMANDROIDREMOTEGDBSERVER_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_ANDROID_PLATFORMANDROIDREMOTEGDBSERVER_H #include #include @@ -54,10 +54,13 @@ protected: std::string &connect_url); private: - DISALLOW_COPY_AND_ASSIGN(PlatformAndroidRemoteGDBServer); + PlatformAndroidRemoteGDBServer(const PlatformAndroidRemoteGDBServer &) = + delete; + const PlatformAndroidRemoteGDBServer & + operator=(const PlatformAndroidRemoteGDBServer &) = delete; }; } // namespace platform_android } // namespace lldb_private -#endif // liblldb_PlatformAndroidRemoteGDBServer_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_ANDROID_PLATFORMANDROIDREMOTEGDBSERVER_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/gnu/llvm/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp index 261f44c230f..97c2f22b505 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp @@ -1,4 +1,4 @@ -//===-- PlatformFreeBSD.cpp -------------------------------------*- C++ -*-===// +//===-- PlatformFreeBSD.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -36,6 +36,8 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::platform_freebsd; +LLDB_PLUGIN_DEFINE(PlatformFreeBSD) + static uint32_t g_initialize_count = 0; diff --git a/gnu/llvm/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h b/gnu/llvm/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h index e3a3aa7145f..56f2f2771d1 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformFreeBSD_h_ -#define liblldb_PlatformFreeBSD_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_FREEBSD_PLATFORMFREEBSD_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_FREEBSD_PLATFORMFREEBSD_H #include "Plugins/Platform/POSIX/PlatformPOSIX.h" @@ -62,10 +62,11 @@ public: lldb::addr_t offset) override; private: - DISALLOW_COPY_AND_ASSIGN(PlatformFreeBSD); + PlatformFreeBSD(const PlatformFreeBSD &) = delete; + const PlatformFreeBSD &operator=(const PlatformFreeBSD &) = delete; }; } // namespace platform_freebsd } // namespace lldb_private -#endif // liblldb_PlatformFreeBSD_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_FREEBSD_PLATFORMFREEBSD_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp b/gnu/llvm/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp index 485ffbe0487..577aa77c2ec 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp @@ -1,4 +1,4 @@ -//===-- PlatformLinux.cpp ---------------------------------------*- C++ -*-===// +//===-- PlatformLinux.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -34,6 +34,8 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::platform_linux; +LLDB_PLUGIN_DEFINE(PlatformLinux) + static uint32_t g_initialize_count = 0; @@ -360,14 +362,14 @@ PlatformLinux::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, // Hook up process PTY if we have one (which we should for local debugging // with llgs). - int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor(); + int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor(); if (pty_fd != PseudoTerminal::invalid_fd) { process_sp->SetSTDIOFileDescriptor(pty_fd); LLDB_LOG(log, "hooked up STDIO pty to process"); } else LLDB_LOG(log, "not using process STDIO pty"); } else { - LLDB_LOG(log, "process launch failed: {0}", error); + LLDB_LOG(log, "{0}", error); // FIXME figure out appropriate cleanup here. Do we delete the target? Do // we delete the process? Does our caller do that? } diff --git a/gnu/llvm/lldb/source/Plugins/Platform/Linux/PlatformLinux.h b/gnu/llvm/lldb/source/Plugins/Platform/Linux/PlatformLinux.h index 67d211ac824..765a0a86a4e 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/Linux/PlatformLinux.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/Linux/PlatformLinux.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformLinux_h_ -#define liblldb_PlatformLinux_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_LINUX_PLATFORMLINUX_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_LINUX_PLATFORMLINUX_H #include "Plugins/Platform/POSIX/PlatformPOSIX.h" @@ -60,10 +60,11 @@ public: lldb::addr_t offset) override; private: - DISALLOW_COPY_AND_ASSIGN(PlatformLinux); + PlatformLinux(const PlatformLinux &) = delete; + const PlatformLinux &operator=(const PlatformLinux &) = delete; }; } // namespace platform_linux } // namespace lldb_private -#endif // liblldb_PlatformLinux_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_LINUX_PLATFORMLINUX_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt index d5a84d87fcd..44707971205 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt @@ -25,7 +25,6 @@ list(APPEND PLUGIN_PLATFORM_MACOSX_DARWIN_ONLY_SOURCES ) if(CMAKE_SYSTEM_NAME MATCHES "Darwin") - include_directories(${LIBXML2_INCLUDE_DIR}) add_subdirectory(objcxx) set(OBJC_LIBS "lldbPluginPlatformMacOSXObjCXX") list(APPEND PLUGIN_PLATFORM_MACOSX_SOURCES diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp index 12a63f0aacb..bd0a231303b 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp @@ -1,4 +1,4 @@ -//===-- PlatformAppleSimulator.cpp ------------------------------*- C++ -*-===// +//===-- PlatformAppleSimulator.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -15,6 +15,7 @@ #include #include #include "lldb/Host/PseudoTerminal.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Target/Process.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Status.h" @@ -34,9 +35,9 @@ void PlatformAppleSimulator::Initialize() { PlatformDarwin::Initialize(); } void PlatformAppleSimulator::Terminate() { PlatformDarwin::Terminate(); } /// Default Constructor -PlatformAppleSimulator::PlatformAppleSimulator() - : PlatformDarwin(true), m_core_sim_path_mutex(), - m_core_simulator_framework_path(), m_device() {} +PlatformAppleSimulator::PlatformAppleSimulator( + CoreSimulatorSupport::DeviceType::ProductFamilyID kind) + : PlatformDarwin(true), m_kind(kind) {} /// Destructor. /// @@ -77,9 +78,10 @@ void PlatformAppleSimulator::GetStatus(Stream &strm) { // simulator PlatformAppleSimulator::LoadCoreSimulator(); + std::string developer_dir = HostInfo::GetXcodeDeveloperDirectory().GetPath(); CoreSimulatorSupport::DeviceSet devices = CoreSimulatorSupport::DeviceSet::GetAvailableDevices( - GetDeveloperDirectory()); + developer_dir.c_str()); const size_t num_devices = devices.GetNumDevices(); if (num_devices) { strm.Printf("Available devices:\n"); @@ -123,9 +125,10 @@ Status PlatformAppleSimulator::ConnectRemote(Args &args) { const char *arg_cstr = args.GetArgumentAtIndex(0); if (arg_cstr) { std::string arg_str(arg_cstr); + std::string developer_dir = HostInfo::GetXcodeDeveloperDirectory().GetPath(); CoreSimulatorSupport::DeviceSet devices = CoreSimulatorSupport::DeviceSet::GetAvailableDevices( - GetDeveloperDirectory()); + developer_dir.c_str()); devices.ForEach( [this, &arg_str](const CoreSimulatorSupport::Device &device) -> bool { if (arg_str == device.GetUDID() || arg_str == device.GetName()) { @@ -191,10 +194,10 @@ lldb::ProcessSP PlatformAppleSimulator::DebugProcess( process_sp->SetShouldDetach(false); // If we didn't have any file actions, the pseudo terminal might have - // been used where the slave side was given as the file to open for - // stdin/out/err after we have already opened the master so we can + // been used where the secondary side was given as the file to open for + // stdin/out/err after we have already opened the primary so we can // read/write stdin/out/err. - int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor(); + int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor(); if (pty_fd != PseudoTerminal::invalid_fd) { process_sp->SetSTDIOFileDescriptor(pty_fd); } @@ -212,17 +215,11 @@ FileSpec PlatformAppleSimulator::GetCoreSimulatorPath() { #if defined(__APPLE__) std::lock_guard guard(m_core_sim_path_mutex); if (!m_core_simulator_framework_path.hasValue()) { - const char *developer_dir = GetDeveloperDirectory(); - if (developer_dir) { - StreamString cs_path; - cs_path.Printf( - "%s/Library/PrivateFrameworks/CoreSimulator.framework/CoreSimulator", - developer_dir); - m_core_simulator_framework_path = FileSpec(cs_path.GetData()); - FileSystem::Instance().Resolve(*m_core_simulator_framework_path); - } + m_core_simulator_framework_path = + FileSpec("/Library/Developer/PrivateFrameworks/CoreSimulator.framework/" + "CoreSimulator"); + FileSystem::Instance().Resolve(*m_core_simulator_framework_path); } - return m_core_simulator_framework_path.getValue(); #else return FileSpec(); @@ -243,10 +240,10 @@ void PlatformAppleSimulator::LoadCoreSimulator() { #if defined(__APPLE__) CoreSimulatorSupport::Device PlatformAppleSimulator::GetSimulatorDevice() { if (!m_device.hasValue()) { - const CoreSimulatorSupport::DeviceType::ProductFamilyID dev_id = - CoreSimulatorSupport::DeviceType::ProductFamilyID::iPhone; + const CoreSimulatorSupport::DeviceType::ProductFamilyID dev_id = m_kind; + std::string developer_dir = HostInfo::GetXcodeDeveloperDirectory().GetPath(); m_device = CoreSimulatorSupport::DeviceSet::GetAvailableDevices( - GetDeveloperDirectory()) + developer_dir.c_str()) .GetFanciest(dev_id); } diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h index ec5f157e6f6..8c0174f2946 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformAppleSimulator_h_ -#define liblldb_PlatformAppleSimulator_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMAPPLESIMULATOR_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMAPPLESIMULATOR_H #include @@ -25,7 +25,8 @@ public: static void Terminate(); // Class Methods - PlatformAppleSimulator(); + PlatformAppleSimulator( + CoreSimulatorSupport::DeviceType::ProductFamilyID kind); virtual ~PlatformAppleSimulator(); @@ -47,6 +48,7 @@ protected: std::mutex m_core_sim_path_mutex; llvm::Optional m_core_simulator_framework_path; llvm::Optional m_device; + CoreSimulatorSupport::DeviceType::ProductFamilyID m_kind; lldb_private::FileSpec GetCoreSimulatorPath(); @@ -57,7 +59,9 @@ protected: #endif private: - DISALLOW_COPY_AND_ASSIGN(PlatformAppleSimulator); + PlatformAppleSimulator(const PlatformAppleSimulator &) = delete; + const PlatformAppleSimulator & + operator=(const PlatformAppleSimulator &) = delete; }; -#endif // liblldb_PlatformAppleSimulator_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMAPPLESIMULATOR_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp index 40148e23a1b..cecffacf69f 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp @@ -1,4 +1,4 @@ -//===-- PlatformAppleTVSimulator.cpp ----------------------------*- C++ -*-===// +//===-- PlatformAppleTVSimulator.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -143,7 +143,8 @@ const char *PlatformAppleTVSimulator::GetDescriptionStatic() { /// Default Constructor PlatformAppleTVSimulator::PlatformAppleTVSimulator() - : PlatformDarwin(true), m_sdk_dir_mutex(), m_sdk_directory() {} + : PlatformAppleSimulator( + CoreSimulatorSupport::DeviceType::ProductFamilyID::appleTV) {} /// Destructor. /// @@ -153,9 +154,9 @@ PlatformAppleTVSimulator::~PlatformAppleTVSimulator() {} void PlatformAppleTVSimulator::GetStatus(Stream &strm) { Platform::GetStatus(strm); - const char *sdk_directory = GetSDKDirectoryAsCString(); - if (sdk_directory) - strm.Printf(" SDK Path: \"%s\"\n", sdk_directory); + llvm::StringRef sdk_directory = GetSDKDirectoryAsCString(); + if (!sdk_directory.empty()) + strm.Printf(" SDK Path: \"%s\"\n", sdk_directory.str().c_str()); else strm.PutCString(" SDK Path: error: unable to locate SDK\n"); } @@ -236,59 +237,12 @@ Status PlatformAppleTVSimulator::ResolveExecutable( return error; } -static FileSystem::EnumerateDirectoryResult -EnumerateDirectoryCallback(void *baton, llvm::sys::fs::file_type ft, - llvm::StringRef path) { - if (ft == llvm::sys::fs::file_type::directory_file) { - FileSpec file_spec(path); - const char *filename = file_spec.GetFilename().GetCString(); - if (filename && - strncmp(filename, "AppleTVSimulator", strlen("AppleTVSimulator")) == - 0) { - ::snprintf((char *)baton, PATH_MAX, "%s", filename); - return FileSystem::eEnumerateDirectoryResultQuit; - } - } - return FileSystem::eEnumerateDirectoryResultNext; -} - -const char *PlatformAppleTVSimulator::GetSDKDirectoryAsCString() { - std::lock_guard guard(m_sdk_dir_mutex); - if (m_sdk_directory.empty()) { - const char *developer_dir = GetDeveloperDirectory(); - if (developer_dir) { - char sdks_directory[PATH_MAX]; - char sdk_dirname[PATH_MAX]; - sdk_dirname[0] = '\0'; - snprintf(sdks_directory, sizeof(sdks_directory), - "%s/Platforms/AppleTVSimulator.platform/Developer/SDKs", - developer_dir); - FileSpec simulator_sdk_spec; - bool find_directories = true; - bool find_files = false; - bool find_other = false; - FileSystem::Instance().EnumerateDirectory( - sdks_directory, find_directories, find_files, find_other, - EnumerateDirectoryCallback, sdk_dirname); - - if (sdk_dirname[0]) { - m_sdk_directory = sdks_directory; - m_sdk_directory.append(1, '/'); - m_sdk_directory.append(sdk_dirname); - return m_sdk_directory.c_str(); - } - } - // Assign a single NULL character so we know we tried to find the device - // support directory and we don't keep trying to find it over and over. - m_sdk_directory.assign(1, '\0'); - } - - // We should have put a single NULL character into m_sdk_directory or it - // should have a valid path if the code gets here - assert(m_sdk_directory.empty() == false); - if (m_sdk_directory[0]) - return m_sdk_directory.c_str(); - return NULL; +llvm::StringRef PlatformAppleTVSimulator::GetSDKDirectoryAsCString() { + llvm::StringRef sdk; + sdk = HostInfo::GetXcodeSDKPath(XcodeSDK("AppleTVSimulator.Internal.sdk")); + if (sdk.empty()) + sdk = HostInfo::GetXcodeSDKPath(XcodeSDK("AppleTVSimulator.sdk")); + return sdk; } Status PlatformAppleTVSimulator::GetSymbolFile(const FileSpec &platform_file, @@ -299,10 +253,10 @@ Status PlatformAppleTVSimulator::GetSymbolFile(const FileSpec &platform_file, if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) { char resolved_path[PATH_MAX]; - const char *sdk_dir = GetSDKDirectoryAsCString(); - if (sdk_dir) { - ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", sdk_dir, - platform_file_path); + llvm::StringRef sdk_dir = GetSDKDirectoryAsCString(); + if (!sdk_dir.empty()) { + ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", + sdk_dir.str().c_str(), platform_file_path); // First try in the SDK and see if the file is in there local_file.SetFile(resolved_path, FileSpec::Style::native); @@ -328,7 +282,7 @@ Status PlatformAppleTVSimulator::GetSymbolFile(const FileSpec &platform_file, Status PlatformAppleTVSimulator::GetSharedModule( const ModuleSpec &module_spec, lldb_private::Process *process, ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, - ModuleSP *old_module_sp_ptr, bool *did_create_ptr) { + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { // For AppleTV, the SDK files are all cached locally on the host system. So // first we ask for the file in the cached SDK, then we attempt to get a // shared module for the right architecture with the right UUID. @@ -342,9 +296,9 @@ Status PlatformAppleTVSimulator::GetSharedModule( module_search_paths_ptr); } else { const bool always_create = false; - error = ModuleList::GetSharedModule( - module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, - did_create_ptr, always_create); + error = ModuleList::GetSharedModule(module_spec, module_sp, + module_search_paths_ptr, old_modules, + did_create_ptr, always_create); } if (module_sp) module_sp->SetPlatformFileSpec(platform_file); @@ -361,13 +315,12 @@ uint32_t PlatformAppleTVSimulator::FindProcesses( // Now we filter them down to only the TvOS triples for (uint32_t i = 0; i < n; ++i) { - const ProcessInstanceInfo &proc_info = - all_osx_process_infos.GetProcessInfoAtIndex(i); + const ProcessInstanceInfo &proc_info = all_osx_process_infos[i]; if (proc_info.GetArchitecture().GetTriple().getOS() == llvm::Triple::TvOS) { - process_infos.Append(proc_info); + process_infos.push_back(proc_info); } } - return process_infos.GetSize(); + return process_infos.size(); } bool PlatformAppleTVSimulator::GetSupportedArchitectureAtIndex(uint32_t idx, @@ -379,6 +332,7 @@ bool PlatformAppleTVSimulator::GetSupportedArchitectureAtIndex(uint32_t idx, arch = platform_arch; if (arch.IsValid()) { arch.GetTriple().setOS(llvm::Triple::TvOS); + arch.GetTriple().setEnvironment(llvm::Triple::Simulator); return true; } } diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h index 0005eab4e67..247cac06a32 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h @@ -6,12 +6,12 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformAppleTVSimulator_h_ -#define liblldb_PlatformAppleTVSimulator_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMAPPLETVSIMULATOR_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMAPPLETVSIMULATOR_H -#include "PlatformDarwin.h" +#include "PlatformAppleSimulator.h" -class PlatformAppleTVSimulator : public PlatformDarwin { +class PlatformAppleTVSimulator : public PlatformAppleSimulator { public: // Class Functions static lldb::PlatformSP CreateInstance(bool force, @@ -55,7 +55,7 @@ public: GetSharedModule(const lldb_private::ModuleSpec &module_spec, lldb_private::Process *process, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) override; uint32_t @@ -69,7 +69,7 @@ public: AddClangModuleCompilationOptions(lldb_private::Target *target, std::vector &options) override { return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType( - target, options, PlatformDarwin::SDKType::iPhoneSimulator); + target, options, lldb_private::XcodeSDK::Type::iPhoneSimulator); } protected: @@ -77,10 +77,12 @@ protected: std::string m_sdk_directory; std::string m_build_update; - const char *GetSDKDirectoryAsCString(); + llvm::StringRef GetSDKDirectoryAsCString(); private: - DISALLOW_COPY_AND_ASSIGN(PlatformAppleTVSimulator); + PlatformAppleTVSimulator(const PlatformAppleTVSimulator &) = delete; + const PlatformAppleTVSimulator & + operator=(const PlatformAppleTVSimulator &) = delete; }; -#endif // liblldb_PlatformAppleTVSimulator_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMAPPLETVSIMULATOR_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp index 0e21f3b96d9..372dd9de975 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp @@ -1,4 +1,4 @@ -//===-- PlatformAppleWatchSimulator.cpp -------------------------*- C++ -*-===// +//===-- PlatformAppleWatchSimulator.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -76,7 +76,8 @@ PlatformSP PlatformAppleWatchSimulator::CreateInstance(bool force, bool create = force; if (!create && arch && arch->IsValid()) { switch (arch->GetMachine()) { - case llvm::Triple::x86_64: { + case llvm::Triple::x86_64: + case llvm::Triple::x86: { const llvm::Triple &triple = arch->GetTriple(); switch (triple.getVendor()) { case llvm::Triple::Apple: @@ -143,7 +144,8 @@ const char *PlatformAppleWatchSimulator::GetDescriptionStatic() { /// Default Constructor PlatformAppleWatchSimulator::PlatformAppleWatchSimulator() - : PlatformDarwin(true), m_sdk_directory() {} + : PlatformAppleSimulator( + CoreSimulatorSupport::DeviceType::ProductFamilyID::appleWatch) {} /// Destructor. /// @@ -153,9 +155,9 @@ PlatformAppleWatchSimulator::~PlatformAppleWatchSimulator() {} void PlatformAppleWatchSimulator::GetStatus(Stream &strm) { Platform::GetStatus(strm); - const char *sdk_directory = GetSDKDirectoryAsCString(); - if (sdk_directory) - strm.Printf(" SDK Path: \"%s\"\n", sdk_directory); + llvm::StringRef sdk_directory = GetSDKDirectoryAsCString(); + if (!sdk_directory.empty()) + strm.Printf(" SDK Path: \"%s\"\n", sdk_directory.str().c_str()); else strm.PutCString(" SDK Path: error: unable to locate SDK\n"); } @@ -236,59 +238,12 @@ Status PlatformAppleWatchSimulator::ResolveExecutable( return error; } -static FileSystem::EnumerateDirectoryResult -EnumerateDirectoryCallback(void *baton, llvm::sys::fs::file_type ft, - llvm::StringRef path) { - if (ft == llvm::sys::fs::file_type::directory_file) { - FileSpec file_spec(path); - const char *filename = file_spec.GetFilename().GetCString(); - if (filename && - strncmp(filename, "AppleWatchSimulator", - strlen("AppleWatchSimulator")) == 0) { - ::snprintf((char *)baton, PATH_MAX, "%s", filename); - return FileSystem::eEnumerateDirectoryResultQuit; - } - } - return FileSystem::eEnumerateDirectoryResultNext; -} - -const char *PlatformAppleWatchSimulator::GetSDKDirectoryAsCString() { - std::lock_guard guard(m_sdk_dir_mutex); - if (m_sdk_directory.empty()) { - const char *developer_dir = GetDeveloperDirectory(); - if (developer_dir) { - char sdks_directory[PATH_MAX]; - char sdk_dirname[PATH_MAX]; - sdk_dirname[0] = '\0'; - snprintf(sdks_directory, sizeof(sdks_directory), - "%s/Platforms/AppleWatchSimulator.platform/Developer/SDKs", - developer_dir); - FileSpec simulator_sdk_spec; - bool find_directories = true; - bool find_files = false; - bool find_other = false; - FileSystem::Instance().EnumerateDirectory( - sdks_directory, find_directories, find_files, find_other, - EnumerateDirectoryCallback, sdk_dirname); - - if (sdk_dirname[0]) { - m_sdk_directory = sdks_directory; - m_sdk_directory.append(1, '/'); - m_sdk_directory.append(sdk_dirname); - return m_sdk_directory.c_str(); - } - } - // Assign a single NULL character so we know we tried to find the device - // support directory and we don't keep trying to find it over and over. - m_sdk_directory.assign(1, '\0'); - } - - // We should have put a single NULL character into m_sdk_directory or it - // should have a valid path if the code gets here - assert(m_sdk_directory.empty() == false); - if (m_sdk_directory[0]) - return m_sdk_directory.c_str(); - return NULL; +llvm::StringRef PlatformAppleWatchSimulator::GetSDKDirectoryAsCString() { + llvm::StringRef sdk; + sdk = HostInfo::GetXcodeSDKPath(XcodeSDK("WatchSimulator.Internal.sdk")); + if (sdk.empty()) + sdk = HostInfo::GetXcodeSDKPath(XcodeSDK("WatchSimulator.sdk")); + return sdk; } Status PlatformAppleWatchSimulator::GetSymbolFile(const FileSpec &platform_file, @@ -299,10 +254,10 @@ Status PlatformAppleWatchSimulator::GetSymbolFile(const FileSpec &platform_file, if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) { char resolved_path[PATH_MAX]; - const char *sdk_dir = GetSDKDirectoryAsCString(); - if (sdk_dir) { - ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", sdk_dir, - platform_file_path); + llvm::StringRef sdk_dir = GetSDKDirectoryAsCString(); + if (!sdk_dir.empty()) { + ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", + sdk_dir.str().c_str(), platform_file_path); // First try in the SDK and see if the file is in there local_file.SetFile(resolved_path, FileSpec::Style::native); @@ -328,7 +283,7 @@ Status PlatformAppleWatchSimulator::GetSymbolFile(const FileSpec &platform_file, Status PlatformAppleWatchSimulator::GetSharedModule( const ModuleSpec &module_spec, lldb_private::Process *process, ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, - ModuleSP *old_module_sp_ptr, bool *did_create_ptr) { + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { // For AppleWatch, the SDK files are all cached locally on the host system. // So first we ask for the file in the cached SDK, then we attempt to get a // shared module for the right architecture with the right UUID. @@ -342,9 +297,9 @@ Status PlatformAppleWatchSimulator::GetSharedModule( module_search_paths_ptr); } else { const bool always_create = false; - error = ModuleList::GetSharedModule( - module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, - did_create_ptr, always_create); + error = ModuleList::GetSharedModule(module_spec, module_sp, + module_search_paths_ptr, old_modules, + did_create_ptr, always_create); } if (module_sp) module_sp->SetPlatformFileSpec(platform_file); @@ -361,25 +316,31 @@ uint32_t PlatformAppleWatchSimulator::FindProcesses( // Now we filter them down to only the WatchOS triples for (uint32_t i = 0; i < n; ++i) { - const ProcessInstanceInfo &proc_info = - all_osx_process_infos.GetProcessInfoAtIndex(i); + const ProcessInstanceInfo &proc_info = all_osx_process_infos[i]; if (proc_info.GetArchitecture().GetTriple().getOS() == llvm::Triple::WatchOS) { - process_infos.Append(proc_info); + process_infos.push_back(proc_info); } } - return process_infos.GetSize(); + return process_infos.size(); } bool PlatformAppleWatchSimulator::GetSupportedArchitectureAtIndex( uint32_t idx, ArchSpec &arch) { - static const ArchSpec platform_arch( - HostInfo::GetArchitecture(HostInfo::eArchKind64)); - if (idx == 0) { - arch = platform_arch; + arch = HostInfo::GetArchitecture(HostInfo::eArchKind32); + if (arch.IsValid()) { + arch.GetTriple().setOS(llvm::Triple::WatchOS); + arch.GetTriple().setEnvironment(llvm::Triple::Simulator); + return true; + } + } + + if (idx == 1) { + arch = HostInfo::GetArchitecture(HostInfo::eArchKind64); if (arch.IsValid()) { arch.GetTriple().setOS(llvm::Triple::WatchOS); + arch.GetTriple().setEnvironment(llvm::Triple::Simulator); return true; } } diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h index d8ffa05343a..5becb8c0bf2 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h @@ -6,12 +6,12 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformAppleWatchSimulator_h_ -#define liblldb_PlatformAppleWatchSimulator_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMAPPLEWATCHSIMULATOR_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMAPPLEWATCHSIMULATOR_H -#include "PlatformDarwin.h" +#include "PlatformAppleSimulator.h" -class PlatformAppleWatchSimulator : public PlatformDarwin { +class PlatformAppleWatchSimulator : public PlatformAppleSimulator { public: // Class Functions static lldb::PlatformSP CreateInstance(bool force, @@ -55,7 +55,7 @@ public: GetSharedModule(const lldb_private::ModuleSpec &module_spec, lldb_private::Process *process, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) override; uint32_t @@ -69,7 +69,7 @@ public: AddClangModuleCompilationOptions(lldb_private::Target *target, std::vector &options) override { return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType( - target, options, PlatformDarwin::SDKType::iPhoneSimulator); + target, options, lldb_private::XcodeSDK::Type::iPhoneSimulator); } protected: @@ -77,10 +77,12 @@ protected: std::string m_sdk_directory; std::string m_build_update; - const char *GetSDKDirectoryAsCString(); + llvm::StringRef GetSDKDirectoryAsCString(); private: - DISALLOW_COPY_AND_ASSIGN(PlatformAppleWatchSimulator); + PlatformAppleWatchSimulator(const PlatformAppleWatchSimulator &) = delete; + const PlatformAppleWatchSimulator & + operator=(const PlatformAppleWatchSimulator &) = delete; }; -#endif // liblldb_PlatformAppleWatchSimulator_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMAPPLEWATCHSIMULATOR_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index ae9f20db43c..133eda93219 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -1,4 +1,4 @@ -//===-- PlatformDarwin.cpp --------------------------------------*- C++ -*-===// +//===-- PlatformDarwin.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -19,6 +19,7 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/Section.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/XML.h" @@ -47,9 +48,7 @@ using namespace lldb; using namespace lldb_private; /// Default Constructor -PlatformDarwin::PlatformDarwin(bool is_host) - : PlatformPOSIX(is_host), // This is the local host platform - m_developer_directory() {} +PlatformDarwin::PlatformDarwin(bool is_host) : PlatformPOSIX(is_host) {} /// Destructor. /// @@ -57,6 +56,17 @@ PlatformDarwin::PlatformDarwin(bool is_host) /// inherited from by the plug-in instance. PlatformDarwin::~PlatformDarwin() {} +lldb_private::Status +PlatformDarwin::PutFile(const lldb_private::FileSpec &source, + const lldb_private::FileSpec &destination, uint32_t uid, + uint32_t gid) { + // Unconditionally unlink the destination. If it is an executable, + // simply opening it and truncating its contents would invalidate + // its cached code signature. + Unlink(destination); + return PlatformPOSIX::PutFile(source, destination, uid, gid); +} + FileSpecList PlatformDarwin::LocateExecutableScriptingResources( Target *target, Module &module, Stream *feedback_stream) { FileSpecList file_list; @@ -211,7 +221,7 @@ BringInRemoteFile(Platform *platform, lldb_private::Status PlatformDarwin::GetSharedModuleWithLocalCache( const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr) { + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); LLDB_LOGF(log, @@ -228,7 +238,7 @@ lldb_private::Status PlatformDarwin::GetSharedModuleWithLocalCache( Status err; err = ModuleList::GetSharedModule(module_spec, module_sp, - module_search_paths_ptr, old_module_sp_ptr, + module_search_paths_ptr, old_modules, did_create_ptr); if (module_sp) return err; @@ -331,8 +341,8 @@ lldb_private::Status PlatformDarwin::GetSharedModuleWithLocalCache( Status PlatformDarwin::GetSharedModule( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr, - bool *did_create_ptr) { + const FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { Status error; module_sp.reset(); @@ -341,16 +351,16 @@ Status PlatformDarwin::GetSharedModule( // module first. if (m_remote_platform_sp) { error = m_remote_platform_sp->GetSharedModule( - module_spec, process, module_sp, module_search_paths_ptr, - old_module_sp_ptr, did_create_ptr); + module_spec, process, module_sp, module_search_paths_ptr, old_modules, + did_create_ptr); } } if (!module_sp) { // Fall back to the local platform and find the file locally error = Platform::GetSharedModule(module_spec, process, module_sp, - module_search_paths_ptr, - old_module_sp_ptr, did_create_ptr); + module_search_paths_ptr, old_modules, + did_create_ptr); const FileSpec &platform_file = module_spec.GetFileSpec(); if (!module_sp && module_search_paths_ptr && platform_file) { @@ -363,7 +373,7 @@ Status PlatformDarwin::GetSharedModule( new_module_spec.GetFileSpec() = bundle_directory; if (Host::ResolveExecutableInBundle(new_module_spec.GetFileSpec())) { Status new_error(Platform::GetSharedModule( - new_module_spec, process, module_sp, nullptr, old_module_sp_ptr, + new_module_spec, process, module_sp, nullptr, old_modules, did_create_ptr)); if (module_sp) @@ -390,8 +400,8 @@ Status PlatformDarwin::GetSharedModule( ModuleSpec new_module_spec(module_spec); new_module_spec.GetFileSpec() = new_file_spec; Status new_error(Platform::GetSharedModule( - new_module_spec, process, module_sp, nullptr, - old_module_sp_ptr, did_create_ptr)); + new_module_spec, process, module_sp, nullptr, old_modules, + did_create_ptr)); if (module_sp) { module_sp->SetPlatformFileSpec(new_file_spec); @@ -536,6 +546,8 @@ bool PlatformDarwin::ARMGetSupportedArchitectureAtIndex(uint32_t idx, #define OSNAME "watchos" #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 #define OSNAME "bridgeos" +#elif defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1 +#define OSNAME "macosx" #else #define OSNAME "ios" #endif @@ -1123,90 +1135,6 @@ static FileSpec GetXcodeSelectPath() { return g_xcode_select_filespec; } -// Return a directory path like /Applications/Xcode.app/Contents/Developer -const char *PlatformDarwin::GetDeveloperDirectory() { - std::lock_guard guard(m_mutex); - if (m_developer_directory.empty()) { - bool developer_dir_path_valid = false; - char developer_dir_path[PATH_MAX]; - - // Get the lldb framework's file path, and if it exists, truncate some - // components to only the developer directory path. - FileSpec temp_file_spec = HostInfo::GetShlibDir(); - if (temp_file_spec) { - if (temp_file_spec.GetPath(developer_dir_path, - sizeof(developer_dir_path))) { - // e.g. - // /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework - char *shared_frameworks = - strstr(developer_dir_path, "/SharedFrameworks/LLDB.framework"); - if (shared_frameworks) { - shared_frameworks[0] = '\0'; // truncate developer_dir_path at this point - strncat (developer_dir_path, "/Developer", sizeof (developer_dir_path) - 1); // add /Developer on - developer_dir_path_valid = true; - } else { - // e.g. - // /Applications/Xcode.app/Contents/Developer/Toolchains/iOS11.2.xctoolchain/System/Library/PrivateFrameworks/LLDB.framework - char *developer_toolchains = - strstr(developer_dir_path, "/Contents/Developer/Toolchains/"); - if (developer_toolchains) { - developer_toolchains += sizeof ("/Contents/Developer") - 1; - developer_toolchains[0] = '\0'; // truncate developer_dir_path at this point - developer_dir_path_valid = true; - } - } - } - } - - if (!developer_dir_path_valid) { - std::string xcode_dir_path; - const char *xcode_select_prefix_dir = getenv("XCODE_SELECT_PREFIX_DIR"); - if (xcode_select_prefix_dir) - xcode_dir_path.append(xcode_select_prefix_dir); - xcode_dir_path.append("/usr/share/xcode-select/xcode_dir_path"); - temp_file_spec.SetFile(xcode_dir_path, FileSpec::Style::native); - auto dir_buffer = - FileSystem::Instance().CreateDataBuffer(temp_file_spec.GetPath()); - if (dir_buffer && dir_buffer->GetByteSize() > 0) { - llvm::StringRef path_ref(dir_buffer->GetChars()); - // Trim tailing newlines and make sure there is enough room for a null - // terminator. - path_ref = - path_ref.rtrim("\r\n").take_front(sizeof(developer_dir_path) - 1); - ::memcpy(developer_dir_path, path_ref.data(), path_ref.size()); - developer_dir_path[path_ref.size()] = '\0'; - developer_dir_path_valid = true; - } - } - - if (!developer_dir_path_valid) { - FileSpec devel_dir = GetXcodeSelectPath(); - if (FileSystem::Instance().IsDirectory(devel_dir)) { - devel_dir.GetPath(&developer_dir_path[0], sizeof(developer_dir_path)); - developer_dir_path_valid = true; - } - } - - if (developer_dir_path_valid) { - temp_file_spec.SetFile(developer_dir_path, FileSpec::Style::native); - if (FileSystem::Instance().Exists(temp_file_spec)) { - m_developer_directory.assign(developer_dir_path); - return m_developer_directory.c_str(); - } - } - // Assign a single NULL character so we know we tried to find the device - // support directory and we don't keep trying to find it over and over. - m_developer_directory.assign(1, '\0'); - } - - // We should have put a single NULL character into m_developer_directory or - // it should have a valid path if the code gets here - assert(m_developer_directory.empty() == false); - if (m_developer_directory[0]) - return m_developer_directory.c_str(); - return nullptr; -} - BreakpointSP PlatformDarwin::SetThreadCreationBreakpoint(Target &target) { BreakpointSP bp_sp; static const char *g_bp_names[] = { @@ -1267,76 +1195,6 @@ void PlatformDarwin::CalculateTrapHandlerSymbolNames() { m_trap_handlers.push_back(ConstString("_sigtramp")); } -static const char *const sdk_strings[] = { - "MacOSX", "iPhoneSimulator", "iPhoneOS", -}; - -static FileSpec CheckPathForXcode(const FileSpec &fspec) { - if (FileSystem::Instance().Exists(fspec)) { - const char substr[] = ".app/Contents"; - - std::string path_to_shlib = fspec.GetPath(); - size_t pos = path_to_shlib.rfind(substr); - if (pos != std::string::npos) { - path_to_shlib.erase(pos + strlen(substr)); - FileSpec ret(path_to_shlib); - - FileSpec xcode_binary_path = ret; - xcode_binary_path.AppendPathComponent("MacOS"); - xcode_binary_path.AppendPathComponent("Xcode"); - - if (FileSystem::Instance().Exists(xcode_binary_path)) { - return ret; - } - } - } - return FileSpec(); -} - -static FileSpec GetXcodeContentsPath() { - static FileSpec g_xcode_filespec; - static llvm::once_flag g_once_flag; - llvm::call_once(g_once_flag, []() { - - FileSpec fspec; - - // First get the program file spec. If lldb.so or LLDB.framework is running - // in a program and that program is Xcode, the path returned with be the - // path to Xcode.app/Contents/MacOS/Xcode, so this will be the correct - // Xcode to use. - fspec = HostInfo::GetProgramFileSpec(); - - if (fspec) { - // Ignore the current binary if it is python. - std::string basename_lower = fspec.GetFilename().GetCString(); - std::transform(basename_lower.begin(), basename_lower.end(), - basename_lower.begin(), tolower); - if (basename_lower != "python") { - g_xcode_filespec = CheckPathForXcode(fspec); - } - } - - // Next check DEVELOPER_DIR environment variable - if (!g_xcode_filespec) { - const char *developer_dir_env_var = getenv("DEVELOPER_DIR"); - if (developer_dir_env_var && developer_dir_env_var[0]) { - FileSpec developer_dir_spec = FileSpec(developer_dir_env_var); - FileSystem::Instance().Resolve(developer_dir_spec); - g_xcode_filespec = CheckPathForXcode(developer_dir_spec); - } - - // Fall back to using "xcode-select" to find the selected Xcode - if (!g_xcode_filespec) { - FileSpec xcode_select_path(GetXcodeSelectPath()); - xcode_select_path.RemoveLastPathComponent(); - g_xcode_filespec = CheckPathForXcode(xcode_select_path); - } - } - }); - - return g_xcode_filespec; -} - static FileSpec GetCommandLineToolsLibraryPath() { static FileSpec g_command_line_tools_filespec; @@ -1351,47 +1209,12 @@ static FileSpec GetCommandLineToolsLibraryPath() { return g_command_line_tools_filespec; } -bool PlatformDarwin::SDKSupportsModules(SDKType sdk_type, - llvm::VersionTuple version) { - switch (sdk_type) { - case SDKType::MacOSX: - return version >= llvm::VersionTuple(10, 10); - case SDKType::iPhoneOS: - case SDKType::iPhoneSimulator: - return version >= llvm::VersionTuple(8); - } - - return false; -} - -bool PlatformDarwin::SDKSupportsModules(SDKType desired_type, - const FileSpec &sdk_path) { - ConstString last_path_component = sdk_path.GetLastPathComponent(); - - if (last_path_component) { - const llvm::StringRef sdk_name = last_path_component.GetStringRef(); - - if (!sdk_name.startswith(sdk_strings[desired_type])) - return false; - auto version_part = - sdk_name.drop_front(strlen(sdk_strings[desired_type])); - version_part.consume_back(".sdk"); - - llvm::VersionTuple version; - if (version.tryParse(version_part)) - return false; - return SDKSupportsModules(desired_type, version); - } - - return false; -} - FileSystem::EnumerateDirectoryResult PlatformDarwin::DirectoryEnumerator( void *baton, llvm::sys::fs::file_type file_type, llvm::StringRef path) { SDKEnumeratorInfo *enumerator_info = static_cast(baton); FileSpec spec(path); - if (SDKSupportsModules(enumerator_info->sdk_type, spec)) { + if (XcodeSDK::SDKSupportsModules(enumerator_info->sdk_type, spec)) { enumerator_info->found_path = spec; return FileSystem::EnumerateDirectoryResult::eEnumerateDirectoryResultNext; } @@ -1399,7 +1222,7 @@ FileSystem::EnumerateDirectoryResult PlatformDarwin::DirectoryEnumerator( return FileSystem::EnumerateDirectoryResult::eEnumerateDirectoryResultNext; } -FileSpec PlatformDarwin::FindSDKInXcodeForModules(SDKType sdk_type, +FileSpec PlatformDarwin::FindSDKInXcodeForModules(XcodeSDK::Type sdk_type, const FileSpec &sdks_spec) { // Look inside Xcode for the required installed iOS SDK version @@ -1425,38 +1248,33 @@ FileSpec PlatformDarwin::FindSDKInXcodeForModules(SDKType sdk_type, return FileSpec(); } -FileSpec PlatformDarwin::GetSDKDirectoryForModules(SDKType sdk_type) { - switch (sdk_type) { - case SDKType::MacOSX: - case SDKType::iPhoneSimulator: - case SDKType::iPhoneOS: - break; - } - - FileSpec sdks_spec = GetXcodeContentsPath(); +FileSpec PlatformDarwin::GetSDKDirectoryForModules(XcodeSDK::Type sdk_type) { + FileSpec sdks_spec = HostInfo::GetXcodeContentsDirectory(); sdks_spec.AppendPathComponent("Developer"); sdks_spec.AppendPathComponent("Platforms"); switch (sdk_type) { - case SDKType::MacOSX: + case XcodeSDK::Type::MacOSX: sdks_spec.AppendPathComponent("MacOSX.platform"); break; - case SDKType::iPhoneSimulator: + case XcodeSDK::Type::iPhoneSimulator: sdks_spec.AppendPathComponent("iPhoneSimulator.platform"); break; - case SDKType::iPhoneOS: + case XcodeSDK::Type::iPhoneOS: sdks_spec.AppendPathComponent("iPhoneOS.platform"); break; + default: + llvm_unreachable("unsupported sdk"); } sdks_spec.AppendPathComponent("Developer"); sdks_spec.AppendPathComponent("SDKs"); - if (sdk_type == SDKType::MacOSX) { + if (sdk_type == XcodeSDK::Type::MacOSX) { llvm::VersionTuple version = HostInfo::GetOSVersion(); if (!version.empty()) { - if (SDKSupportsModules(SDKType::MacOSX, version)) { + if (XcodeSDK::SDKSupportsModules(XcodeSDK::Type::MacOSX, version)) { // If the Xcode SDKs are not available then try to use the // Command Line Tools one which is only for MacOSX. if (!FileSystem::Instance().Exists(sdks_spec)) { @@ -1501,8 +1319,131 @@ PlatformDarwin::ParseVersionBuildDir(llvm::StringRef dir) { return std::make_tuple(version, build); } +llvm::Expected +PlatformDarwin::FetchExtendedCrashInformation(Process &process) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + + StructuredData::ArraySP annotations = ExtractCrashInfoAnnotations(process); + + if (!annotations || !annotations->GetSize()) { + LLDB_LOG(log, "Couldn't extract crash information annotations"); + return nullptr; + } + + StructuredData::DictionarySP extended_crash_info = + std::make_shared(); + + extended_crash_info->AddItem("crash-info annotations", annotations); + + return extended_crash_info; +} + +StructuredData::ArraySP +PlatformDarwin::ExtractCrashInfoAnnotations(Process &process) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + + ConstString section_name("__crash_info"); + Target &target = process.GetTarget(); + StructuredData::ArraySP array_sp = std::make_shared(); + + for (ModuleSP module : target.GetImages().Modules()) { + SectionList *sections = module->GetSectionList(); + + std::string module_name = module->GetSpecificationDescription(); + + // The DYDL module is skipped since it's always loaded when running the + // binary. + if (module_name == "/usr/lib/dyld") + continue; + + if (!sections) { + LLDB_LOG(log, "Module {0} doesn't have any section!", module_name); + continue; + } + + SectionSP crash_info = sections->FindSectionByName(section_name); + if (!crash_info) { + LLDB_LOG(log, "Module {0} doesn't have section {1}!", module_name, + section_name); + continue; + } + + addr_t load_addr = crash_info->GetLoadBaseAddress(&target); + + if (load_addr == LLDB_INVALID_ADDRESS) { + LLDB_LOG(log, "Module {0} has an invalid '{1}' section load address: {2}", + module_name, section_name, load_addr); + continue; + } + + Status error; + CrashInfoAnnotations annotations; + size_t expected_size = sizeof(CrashInfoAnnotations); + size_t bytes_read = process.ReadMemoryFromInferior(load_addr, &annotations, + expected_size, error); + + if (expected_size != bytes_read || error.Fail()) { + LLDB_LOG(log, "Failed to read {0} section from memory in module {1}: {2}", + section_name, module_name, error); + continue; + } + + // initial support added for version 5 + if (annotations.version < 5) { + LLDB_LOG(log, + "Annotation version lower than 5 unsupported! Module {0} has " + "version {1} instead.", + module_name, annotations.version); + continue; + } + + if (!annotations.message) { + LLDB_LOG(log, "No message available for module {0}.", module_name); + continue; + } + + std::string message; + bytes_read = + process.ReadCStringFromMemory(annotations.message, message, error); + + if (message.empty() || bytes_read != message.size() || error.Fail()) { + LLDB_LOG(log, "Failed to read the message from memory in module {0}: {1}", + module_name, error); + continue; + } + + // Remove trailing newline from message + if (message.back() == '\n') + message.pop_back(); + + if (!annotations.message2) + LLDB_LOG(log, "No message2 available for module {0}.", module_name); + + std::string message2; + bytes_read = + process.ReadCStringFromMemory(annotations.message2, message2, error); + + if (!message2.empty() && bytes_read == message2.size() && error.Success()) + if (message2.back() == '\n') + message2.pop_back(); + + StructuredData::DictionarySP entry_sp = + std::make_shared(); + + entry_sp->AddStringItem("image", module->GetFileSpec().GetPath(false)); + entry_sp->AddStringItem("uuid", module->GetUUID().GetAsString()); + entry_sp->AddStringItem("message", message); + entry_sp->AddStringItem("message2", message2); + entry_sp->AddIntegerItem("abort-cause", annotations.abort_cause); + + array_sp->AddItem(entry_sp); + } + + return array_sp; +} + void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType( - Target *target, std::vector &options, SDKType sdk_type) { + Target *target, std::vector &options, XcodeSDK::Type sdk_type) { const std::vector apple_arguments = { "-x", "objective-c++", "-fobjc-arc", "-fblocks", "-D_ISO646_H", "-D__ISO646_H", @@ -1513,7 +1454,7 @@ void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType( StreamString minimum_version_option; bool use_current_os_version = false; switch (sdk_type) { - case SDKType::iPhoneOS: + case XcodeSDK::Type::iPhoneOS: #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) use_current_os_version = true; #else @@ -1521,17 +1462,19 @@ void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType( #endif break; - case SDKType::iPhoneSimulator: + case XcodeSDK::Type::iPhoneSimulator: use_current_os_version = false; break; - case SDKType::MacOSX: + case XcodeSDK::Type::MacOSX: #if defined(__i386__) || defined(__x86_64__) use_current_os_version = true; #else use_current_os_version = false; #endif break; + default: + break; } llvm::VersionTuple version; @@ -1550,19 +1493,22 @@ void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType( // Only add the version-min options if we got a version from somewhere if (!version.empty()) { switch (sdk_type) { - case SDKType::iPhoneOS: + case XcodeSDK::Type::iPhoneOS: minimum_version_option.PutCString("-mios-version-min="); minimum_version_option.PutCString(version.getAsString()); break; - case SDKType::iPhoneSimulator: + case XcodeSDK::Type::iPhoneSimulator: minimum_version_option.PutCString("-mios-simulator-version-min="); minimum_version_option.PutCString(version.getAsString()); break; - case SDKType::MacOSX: + case XcodeSDK::Type::MacOSX: minimum_version_option.PutCString("-mmacosx-version-min="); minimum_version_option.PutCString(version.getAsString()); + break; + default: + llvm_unreachable("unsupported sdk"); } - options.push_back(minimum_version_option.GetString()); + options.push_back(std::string(minimum_version_option.GetString())); } FileSpec sysroot_spec; @@ -1620,8 +1566,7 @@ llvm::VersionTuple PlatformDarwin::GetOSVersion(Process *process) { lldb_private::FileSpec PlatformDarwin::LocateExecutable(const char *basename) { // A collection of SBFileSpec whose SBFileSpec.m_directory members are filled - // in with - // any executable directories that should be searched. + // in with any executable directories that should be searched. static std::vector g_executable_dirs; // Find the global list of directories that we will search for executables @@ -1630,7 +1575,7 @@ lldb_private::FileSpec PlatformDarwin::LocateExecutable(const char *basename) { llvm::call_once(g_once_flag, []() { // When locating executables, trust the DEVELOPER_DIR first if it is set - FileSpec xcode_contents_dir = GetXcodeContentsPath(); + FileSpec xcode_contents_dir = HostInfo::GetXcodeContentsDirectory(); if (xcode_contents_dir) { FileSpec xcode_lldb_resources = xcode_contents_dir; xcode_lldb_resources.AppendPathComponent("SharedFrameworks"); @@ -1692,12 +1637,10 @@ PlatformDarwin::LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) { return PlatformPOSIX::LaunchProcess(launch_info); } -lldb_private::Status -PlatformDarwin::FindBundleBinaryInExecSearchPaths (const ModuleSpec &module_spec, Process *process, - ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, - ModuleSP *old_module_sp_ptr, bool *did_create_ptr) -{ +lldb_private::Status PlatformDarwin::FindBundleBinaryInExecSearchPaths( + const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { const FileSpec &platform_file = module_spec.GetFileSpec(); // See if the file is present in any of the module_search_paths_ptr // directories. @@ -1754,9 +1697,9 @@ PlatformDarwin::FindBundleBinaryInExecSearchPaths (const ModuleSpec &module_spec if (FileSystem::Instance().Exists(path_to_try)) { ModuleSpec new_module_spec(module_spec); new_module_spec.GetFileSpec() = path_to_try; - Status new_error(Platform::GetSharedModule( - new_module_spec, process, module_sp, nullptr, old_module_sp_ptr, - did_create_ptr)); + Status new_error( + Platform::GetSharedModule(new_module_spec, process, module_sp, + nullptr, old_modules, did_create_ptr)); if (module_sp) { module_sp->SetPlatformFileSpec(path_to_try); @@ -1768,3 +1711,30 @@ PlatformDarwin::FindBundleBinaryInExecSearchPaths (const ModuleSpec &module_spec } return Status(); } + +std::string PlatformDarwin::FindComponentInPath(llvm::StringRef path, + llvm::StringRef component) { + auto begin = llvm::sys::path::begin(path); + auto end = llvm::sys::path::end(path); + for (auto it = begin; it != end; ++it) { + if (it->contains(component)) { + llvm::SmallString<128> buffer; + llvm::sys::path::append(buffer, begin, ++it, + llvm::sys::path::Style::posix); + return buffer.str().str(); + } + } + return {}; +} + +FileSpec PlatformDarwin::GetCurrentToolchainDirectory() { + if (FileSpec fspec = HostInfo::GetShlibDir()) + return FileSpec(FindComponentInPath(fspec.GetPath(), ".xctoolchain")); + return {}; +} + +FileSpec PlatformDarwin::GetCurrentCommandLineToolsDirectory() { + if (FileSpec fspec = HostInfo::GetShlibDir()) + return FileSpec(FindComponentInPath(fspec.GetPath(), "CommandLineTools")); + return {}; +} diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h index ccf6853cda7..4e9a9495893 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h @@ -6,13 +6,15 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformDarwin_h_ -#define liblldb_PlatformDarwin_h_ - +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMDARWIN_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMDARWIN_H #include "Plugins/Platform/POSIX/PlatformPOSIX.h" #include "lldb/Host/FileSystem.h" +#include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/StructuredData.h" +#include "lldb/Utility/XcodeSDK.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/FileSystem.h" @@ -25,6 +27,11 @@ public: ~PlatformDarwin() override; + lldb_private::Status PutFile(const lldb_private::FileSpec &source, + const lldb_private::FileSpec &destination, + uint32_t uid = UINT32_MAX, + uint32_t gid = UINT32_MAX) override; + // lldb_private::Platform functions lldb_private::Status ResolveSymbolFile(lldb_private::Target &target, @@ -39,7 +46,7 @@ public: GetSharedModule(const lldb_private::ModuleSpec &module_spec, lldb_private::Process *process, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) override; size_t GetSoftwareBreakpointTrapOpcode( @@ -79,13 +86,45 @@ public: static std::tuple ParseVersionBuildDir(llvm::StringRef str); - enum SDKType : unsigned { - MacOSX = 0, - iPhoneSimulator, - iPhoneOS, - }; + llvm::Expected + FetchExtendedCrashInformation(lldb_private::Process &process) override; + + /// Return the toolchain directory the current LLDB instance is located in. + static lldb_private::FileSpec GetCurrentToolchainDirectory(); + + /// Return the command line tools directory the current LLDB instance is + /// located in. + static lldb_private::FileSpec GetCurrentCommandLineToolsDirectory(); protected: + struct CrashInfoAnnotations { + uint64_t version; // unsigned long + uint64_t message; // char * + uint64_t signature_string; // char * + uint64_t backtrace; // char * + uint64_t message2; // char * + uint64_t thread; // uint64_t + uint64_t dialog_mode; // unsigned int + uint64_t abort_cause; // unsigned int + }; + + /// Extract the `__crash_info` annotations from each of of the target's + /// modules. + /// + /// If the platform have a crashed processes with a `__crash_info` section, + /// extract the section to gather the messages annotations and the abort + /// cause. + /// + /// \param[in] process + /// The crashed process. + /// + /// \return + /// A structured data array containing at each entry in each entry, the + /// module spec, its UUID, the crash messages and the abort cause. + /// \b nullptr if process has no crash information annotations. + lldb_private::StructuredData::ArraySP + ExtractCrashInfoAnnotations(lldb_private::Process &process); + void ReadLibdispatchOffsetsAddress(lldb_private::Process *process); void ReadLibdispatchOffsets(lldb_private::Process *process); @@ -93,16 +132,11 @@ protected: virtual lldb_private::Status GetSharedModuleWithLocalCache( const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr); - - static bool SDKSupportsModules(SDKType sdk_type, llvm::VersionTuple version); - - static bool SDKSupportsModules(SDKType desired_type, - const lldb_private::FileSpec &sdk_path); + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr); struct SDKEnumeratorInfo { lldb_private::FileSpec found_path; - SDKType sdk_type; + lldb_private::XcodeSDK::Type sdk_type; }; static lldb_private::FileSystem::EnumerateDirectoryResult @@ -110,29 +144,32 @@ protected: llvm::StringRef path); static lldb_private::FileSpec - FindSDKInXcodeForModules(SDKType sdk_type, + FindSDKInXcodeForModules(lldb_private::XcodeSDK::Type sdk_type, const lldb_private::FileSpec &sdks_spec); static lldb_private::FileSpec - GetSDKDirectoryForModules(PlatformDarwin::SDKType sdk_type); + GetSDKDirectoryForModules(lldb_private::XcodeSDK::Type sdk_type); - void - AddClangModuleCompilationOptionsForSDKType(lldb_private::Target *target, - std::vector &options, - SDKType sdk_type); + void AddClangModuleCompilationOptionsForSDKType( + lldb_private::Target *target, std::vector &options, + lldb_private::XcodeSDK::Type sdk_type); - const char *GetDeveloperDirectory(); + lldb_private::Status FindBundleBinaryInExecSearchPaths( + const lldb_private::ModuleSpec &module_spec, + lldb_private::Process *process, lldb::ModuleSP &module_sp, + const lldb_private::FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr); - lldb_private::Status - FindBundleBinaryInExecSearchPaths (const lldb_private::ModuleSpec &module_spec, lldb_private::Process *process, - lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr); + static std::string FindComponentInPath(llvm::StringRef path, + llvm::StringRef component); std::string m_developer_directory; - + llvm::StringMap m_sdk_path; + std::mutex m_sdk_path_mutex; private: - DISALLOW_COPY_AND_ASSIGN(PlatformDarwin); + PlatformDarwin(const PlatformDarwin &) = delete; + const PlatformDarwin &operator=(const PlatformDarwin &) = delete; }; -#endif // liblldb_PlatformDarwin_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMDARWIN_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp index 7ca5397595c..6d1cf804a0a 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp @@ -1,5 +1,4 @@ -//===-- PlatformDarwinKernel.cpp -----------------------------------*- C++ -//-*-===// +//===-- PlatformDarwinKernel.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,6 +17,7 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Interpreter/OptionValueFileSpecList.h" #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Interpreter/Property.h" @@ -328,7 +328,7 @@ void PlatformDarwinKernel::CollectKextAndKernelDirectories() { // DeveloperDirectory is something like // "/Applications/Xcode.app/Contents/Developer" - std::string developer_dir = GetDeveloperDirectory(); + std::string developer_dir = HostInfo::GetXcodeDeveloperDirectory().GetPath(); if (developer_dir.empty()) developer_dir = "/Applications/Xcode.app/Contents/Developer"; @@ -644,8 +644,8 @@ bool PlatformDarwinKernel::KernelHasdSYMSibling(const FileSpec &kernel_binary) { Status PlatformDarwinKernel::GetSharedModule( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr, - bool *did_create_ptr) { + const FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { Status error; module_sp.reset(); const FileSpec &platform_file = module_spec.GetFileSpec(); @@ -676,7 +676,7 @@ Status PlatformDarwinKernel::GetSharedModule( // framework on macOS systems, a chance. error = PlatformDarwin::GetSharedModule(module_spec, process, module_sp, module_search_paths_ptr, - old_module_sp_ptr, did_create_ptr); + old_modules, did_create_ptr); if (error.Success() && module_sp.get()) { return error; } @@ -730,7 +730,7 @@ Status PlatformDarwinKernel::GetSharedModule( // framework on macOS systems, a chance. error = PlatformDarwin::GetSharedModule(module_spec, process, module_sp, module_search_paths_ptr, - old_module_sp_ptr, did_create_ptr); + old_modules, did_create_ptr); if (error.Success() && module_sp.get()) { return error; } diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h index 31c13d2daa5..203bfb5e606 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformDarwinKernel_h_ -#define liblldb_PlatformDarwinKernel_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMDARWINKERNEL_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMDARWINKERNEL_H #include "lldb/Utility/ConstString.h" @@ -57,7 +57,7 @@ public: GetSharedModule(const lldb_private::ModuleSpec &module_spec, lldb_private::Process *process, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) override; bool GetSupportedArchitectureAtIndex(uint32_t idx, @@ -172,7 +172,8 @@ public: // dSYMs next to them lldb_private::LazyBool m_ios_debug_session; - DISALLOW_COPY_AND_ASSIGN(PlatformDarwinKernel); + PlatformDarwinKernel(const PlatformDarwinKernel &) = delete; + const PlatformDarwinKernel &operator=(const PlatformDarwinKernel &) = delete; }; #else // __APPLE__ @@ -196,4 +197,4 @@ public: #endif // __APPLE__ -#endif // liblldb_PlatformDarwinKernel_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMDARWINKERNEL_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp index 134a4c7c807..cbdd2cde662 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp @@ -1,4 +1,4 @@ -//===-- PlatformMacOSX.cpp --------------------------------------*- C++ -*-===// +//===-- PlatformMacOSX.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,16 +7,22 @@ //===----------------------------------------------------------------------===// #include "PlatformMacOSX.h" -#include "lldb/Host/Config.h" - - -#include - +#include "PlatformRemoteiOS.h" +#if defined(__APPLE__) +#include "PlatformAppleTVSimulator.h" +#include "PlatformAppleWatchSimulator.h" +#include "PlatformDarwinKernel.h" +#include "PlatformRemoteAppleBridge.h" +#include "PlatformRemoteAppleTV.h" +#include "PlatformRemoteAppleWatch.h" +#include "PlatformiOSSimulator.h" +#endif #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Host/Config.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Symbol/ObjectFile.h" @@ -28,13 +34,27 @@ #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" +#include + using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(PlatformMacOSX) + static uint32_t g_initialize_count = 0; void PlatformMacOSX::Initialize() { PlatformDarwin::Initialize(); + PlatformRemoteiOS::Initialize(); +#if defined(__APPLE__) + PlatformiOSSimulator::Initialize(); + PlatformDarwinKernel::Initialize(); + PlatformAppleTVSimulator::Initialize(); + PlatformAppleWatchSimulator::Initialize(); + PlatformRemoteAppleTV::Initialize(); + PlatformRemoteAppleWatch::Initialize(); + PlatformRemoteAppleBridge::Initialize(); +#endif if (g_initialize_count++ == 0) { #if defined(__APPLE__) @@ -55,6 +75,16 @@ void PlatformMacOSX::Terminate() { } } +#if defined(__APPLE__) + PlatformRemoteAppleBridge::Terminate(); + PlatformRemoteAppleWatch::Terminate(); + PlatformRemoteAppleTV::Terminate(); + PlatformAppleWatchSimulator::Terminate(); + PlatformAppleTVSimulator::Terminate(); + PlatformDarwinKernel::Terminate(); + PlatformiOSSimulator::Terminate(); +#endif + PlatformRemoteiOS::Terminate(); PlatformDarwin::Terminate(); } @@ -155,73 +185,37 @@ PlatformMacOSX::~PlatformMacOSX() {} ConstString PlatformMacOSX::GetSDKDirectory(lldb_private::Target &target) { ModuleSP exe_module_sp(target.GetExecutableModule()); - if (exe_module_sp) { - ObjectFile *objfile = exe_module_sp->GetObjectFile(); - if (objfile) { - std::string xcode_contents_path; - std::string default_xcode_sdk; - FileSpec fspec; - llvm::VersionTuple version = objfile->GetSDKVersion(); - if (!version.empty()) { - fspec = HostInfo::GetShlibDir(); - if (fspec) { - std::string path; - xcode_contents_path = fspec.GetPath(); - size_t pos = xcode_contents_path.find("/Xcode.app/Contents/"); - if (pos != std::string::npos) { - // LLDB.framework is inside an Xcode app bundle, we can locate the - // SDK from here - xcode_contents_path.erase(pos + strlen("/Xcode.app/Contents/")); - } else { - xcode_contents_path.clear(); - // Use the selected Xcode - int status = 0; - int signo = 0; - std::string output; - const char *command = "xcrun -sdk macosx --show-sdk-path"; - lldb_private::Status error = RunShellCommand( - command, // shell command to run - FileSpec(), // current working directory - &status, // Put the exit status of the process in here - &signo, // Put the signal that caused the process to exit in - // here - &output, // Get the output from the command and place it in this - // string - std::chrono::seconds(3)); - if (status == 0 && !output.empty()) { - size_t first_non_newline = output.find_last_not_of("\r\n"); - if (first_non_newline != std::string::npos) - output.erase(first_non_newline + 1); - default_xcode_sdk = output; - - pos = default_xcode_sdk.find("/Xcode.app/Contents/"); - if (pos != std::string::npos) - xcode_contents_path = default_xcode_sdk.substr( - 0, pos + strlen("/Xcode.app/Contents/")); - } - } - } - - if (!xcode_contents_path.empty()) { - StreamString sdk_path; - sdk_path.Printf("%sDeveloper/Platforms/MacOSX.platform/Developer/" - "SDKs/MacOSX%u.%u.sdk", - xcode_contents_path.c_str(), version.getMajor(), - version.getMinor().getValue()); - fspec.SetFile(sdk_path.GetString(), FileSpec::Style::native); - if (FileSystem::Instance().Exists(fspec)) - return ConstString(sdk_path.GetString()); - } + if (!exe_module_sp) + return {}; + + ObjectFile *objfile = exe_module_sp->GetObjectFile(); + if (!objfile) + return {}; + + llvm::VersionTuple version = objfile->GetSDKVersion(); + if (version.empty()) + return {}; + + // First try to find an SDK that matches the given SDK version. + if (FileSpec fspec = HostInfo::GetXcodeContentsDirectory()) { + StreamString sdk_path; + sdk_path.Printf("%s/Developer/Platforms/MacOSX.platform/Developer/" + "SDKs/MacOSX%u.%u.sdk", + fspec.GetPath().c_str(), version.getMajor(), + version.getMinor().getValue()); + if (FileSystem::Instance().Exists(fspec)) + return ConstString(sdk_path.GetString()); + } - if (!default_xcode_sdk.empty()) { - fspec.SetFile(default_xcode_sdk, FileSpec::Style::native); - if (FileSystem::Instance().Exists(fspec)) - return ConstString(default_xcode_sdk); - } - } - } + // Use the default SDK as a fallback. + FileSpec fspec( + HostInfo::GetXcodeSDKPath(lldb_private::XcodeSDK::GetAnyMacOS())); + if (fspec) { + if (FileSystem::Instance().Exists(fspec)) + return ConstString(fspec.GetPath()); } - return ConstString(); + + return {}; } Status PlatformMacOSX::GetSymbolFile(const FileSpec &platform_file, @@ -298,10 +292,10 @@ lldb_private::Status PlatformMacOSX::GetSharedModule( const lldb_private::ModuleSpec &module_spec, Process *process, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr) { - Status error = GetSharedModuleWithLocalCache( - module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, - did_create_ptr); + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { + Status error = GetSharedModuleWithLocalCache(module_spec, module_sp, + module_search_paths_ptr, + old_modules, did_create_ptr); if (module_sp) { if (module_spec.GetArchitecture().GetCore() == @@ -312,15 +306,16 @@ lldb_private::Status PlatformMacOSX::GetSharedModule( ModuleSpec module_spec_x86_64(module_spec); module_spec_x86_64.GetArchitecture() = ArchSpec("x86_64-apple-macosx"); lldb::ModuleSP x86_64_module_sp; - lldb::ModuleSP old_x86_64_module_sp; + llvm::SmallVector old_x86_64_modules; bool did_create = false; Status x86_64_error = GetSharedModuleWithLocalCache( module_spec_x86_64, x86_64_module_sp, module_search_paths_ptr, - &old_x86_64_module_sp, &did_create); + &old_x86_64_modules, &did_create); if (x86_64_module_sp && x86_64_module_sp->GetObjectFile()) { module_sp = x86_64_module_sp; - if (old_module_sp_ptr) - *old_module_sp_ptr = old_x86_64_module_sp; + if (old_modules) + old_modules->append(old_x86_64_modules.begin(), + old_x86_64_modules.end()); if (did_create_ptr) *did_create_ptr = did_create; return x86_64_error; @@ -330,7 +325,9 @@ lldb_private::Status PlatformMacOSX::GetSharedModule( } if (!module_sp) { - error = FindBundleBinaryInExecSearchPaths (module_spec, process, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr); + error = FindBundleBinaryInExecSearchPaths(module_spec, process, module_sp, + module_search_paths_ptr, + old_modules, did_create_ptr); } return error; } diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h index 5e942f090c9..deca3f06ab7 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformMacOSX_h_ -#define liblldb_PlatformMacOSX_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMMACOSX_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMMACOSX_H #include "PlatformDarwin.h" @@ -40,7 +40,7 @@ public: GetSharedModule(const lldb_private::ModuleSpec &module_spec, lldb_private::Process *process, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) override; const char *GetDescription() override { @@ -73,11 +73,12 @@ public: AddClangModuleCompilationOptions(lldb_private::Target *target, std::vector &options) override { return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType( - target, options, PlatformDarwin::SDKType::MacOSX); + target, options, lldb_private::XcodeSDK::Type::MacOSX); } private: - DISALLOW_COPY_AND_ASSIGN(PlatformMacOSX); + PlatformMacOSX(const PlatformMacOSX &) = delete; + const PlatformMacOSX &operator=(const PlatformMacOSX &) = delete; }; -#endif // liblldb_PlatformMacOSX_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMMACOSX_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.cpp b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.cpp index ca50ea2863b..eb25a061de4 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.cpp @@ -1,4 +1,4 @@ -//===-- PlatformRemoteAppleBridge.cpp -------------------------------*- C++ -*-===// +//===-- PlatformRemoteAppleBridge.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.h b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.h index 3ecd20f2ade..b255fa37ed1 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformRemoteAppleBridge_h_ -#define liblldb_PlatformRemoteAppleBridge_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMREMOTEAPPLEBRIDGE_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMREMOTEAPPLEBRIDGE_H #include @@ -58,7 +58,9 @@ protected: std::string GetPlatformName () override; private: - DISALLOW_COPY_AND_ASSIGN(PlatformRemoteAppleBridge); + PlatformRemoteAppleBridge(const PlatformRemoteAppleBridge &) = delete; + const PlatformRemoteAppleBridge & + operator=(const PlatformRemoteAppleBridge &) = delete; }; -#endif // liblldb_PlatformRemoteAppleBridge_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMREMOTEAPPLEBRIDGE_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp index 10adc700fd8..082ddcc0f56 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp @@ -1,4 +1,4 @@ -//===-- PlatformRemoteAppleTV.cpp -------------------------------*- C++ -*-===// +//===-- PlatformRemoteAppleTV.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h index ce2e164f6a9..f5b554d2f66 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformRemoteAppleTV_h_ -#define liblldb_PlatformRemoteAppleTV_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMREMOTEAPPLETV_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMREMOTEAPPLETV_H #include @@ -58,7 +58,9 @@ protected: std::string GetPlatformName () override; private: - DISALLOW_COPY_AND_ASSIGN(PlatformRemoteAppleTV); + PlatformRemoteAppleTV(const PlatformRemoteAppleTV &) = delete; + const PlatformRemoteAppleTV & + operator=(const PlatformRemoteAppleTV &) = delete; }; -#endif // liblldb_PlatformRemoteAppleTV_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMREMOTEAPPLETV_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp index fa190dbd10f..6b40393ba5b 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp @@ -1,4 +1,4 @@ -//===-- PlatformRemoteAppleWatch.cpp ----------------------------*- C++ -*-===// +//===-- PlatformRemoteAppleWatch.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h index 6cd470da722..712693f6c41 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformRemoteAppleWatch_h_ -#define liblldb_PlatformRemoteAppleWatch_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMREMOTEAPPLEWATCH_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMREMOTEAPPLEWATCH_H #include #include @@ -61,7 +61,9 @@ protected: std::string GetPlatformName () override; private: - DISALLOW_COPY_AND_ASSIGN(PlatformRemoteAppleWatch); + PlatformRemoteAppleWatch(const PlatformRemoteAppleWatch &) = delete; + const PlatformRemoteAppleWatch & + operator=(const PlatformRemoteAppleWatch &) = delete; }; -#endif // liblldb_PlatformRemoteAppleWatch_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMREMOTEAPPLEWATCH_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp index 0aa129c808d..065eefa48fe 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp @@ -1,4 +1,4 @@ -//===-- PlatformRemoteDarwinDevice.cpp -----------------------------------*- C++ -*-===// +//===-- PlatformRemoteDarwinDevice.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -15,6 +15,7 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" @@ -342,9 +343,8 @@ PlatformRemoteDarwinDevice::GetSDKDirectoryForLatestOSVersion() { const char *PlatformRemoteDarwinDevice::GetDeviceSupportDirectory() { std::string platform_dir = "/Platforms/" + GetPlatformName() + "/DeviceSupport"; if (m_device_support_directory.empty()) { - const char *device_support_dir = GetDeveloperDirectory(); - if (device_support_dir) { - m_device_support_directory.assign(device_support_dir); + if (FileSpec fspec = HostInfo::GetXcodeDeveloperDirectory()) { + m_device_support_directory = fspec.GetPath(); m_device_support_directory.append(platform_dir.c_str()); } else { // Assign a single NULL character so we know we tried to find the device @@ -504,8 +504,8 @@ Status PlatformRemoteDarwinDevice::GetSymbolFile(const FileSpec &platform_file, Status PlatformRemoteDarwinDevice::GetSharedModule( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr, - bool *did_create_ptr) { + const FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { // For iOS, the SDK files are all cached locally on the host system. So first // we ask for the file in the cached SDK, then we attempt to get a shared // module for the right architecture with the right UUID. @@ -608,24 +608,25 @@ Status PlatformRemoteDarwinDevice::GetSharedModule( // This may not be an SDK-related module. Try whether we can bring in the // thing to our local cache. error = GetSharedModuleWithLocalCache(module_spec, module_sp, - module_search_paths_ptr, - old_module_sp_ptr, did_create_ptr); + module_search_paths_ptr, old_modules, + did_create_ptr); if (error.Success()) return error; // See if the file is present in any of the module_search_paths_ptr // directories. if (!module_sp) - error = PlatformDarwin::FindBundleBinaryInExecSearchPaths (module_spec, process, module_sp, - module_search_paths_ptr, old_module_sp_ptr, did_create_ptr); + error = PlatformDarwin::FindBundleBinaryInExecSearchPaths( + module_spec, process, module_sp, module_search_paths_ptr, old_modules, + did_create_ptr); if (error.Success()) return error; const bool always_create = false; - error = ModuleList::GetSharedModule( - module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, - did_create_ptr, always_create); + error = ModuleList::GetSharedModule(module_spec, module_sp, + module_search_paths_ptr, old_modules, + did_create_ptr, always_create); if (module_sp) module_sp->SetPlatformFileSpec(platform_file); diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h index 5e0b7d92bbd..cc5f286f3b2 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformRemoteDarwinDevice_h_ -#define liblldb_PlatformRemoteDarwinDevice_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMREMOTEDARWINDEVICE_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMREMOTEDARWINDEVICE_H #include @@ -38,14 +38,14 @@ public: GetSharedModule(const lldb_private::ModuleSpec &module_spec, lldb_private::Process *process, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) override; void AddClangModuleCompilationOptions(lldb_private::Target *target, std::vector &options) override { return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType( - target, options, PlatformDarwin::SDKType::iPhoneOS); + target, options, lldb_private::XcodeSDK::Type::iPhoneOS); } protected: @@ -103,7 +103,9 @@ protected: virtual std::string GetPlatformName () = 0; private: - DISALLOW_COPY_AND_ASSIGN(PlatformRemoteDarwinDevice); + PlatformRemoteDarwinDevice(const PlatformRemoteDarwinDevice &) = delete; + const PlatformRemoteDarwinDevice & + operator=(const PlatformRemoteDarwinDevice &) = delete; }; -#endif // liblldb_PlatformRemoteDarwinDevice_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMREMOTEDARWINDEVICE_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp index 81d9fcfe83c..b37cdecd38c 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp @@ -1,4 +1,4 @@ -//===-- PlatformRemoteiOS.cpp -----------------------------------*- C++ -*-===// +//===-- PlatformRemoteiOS.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,6 +25,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(PlatformRemoteiOS) + // Static Variables static uint32_t g_initialize_count = 0; diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h index a0eb523fd1e..4f38128bfb0 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformRemoteiOS_h_ -#define liblldb_PlatformRemoteiOS_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMREMOTEIOS_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMREMOTEIOS_H #include @@ -57,7 +57,8 @@ protected: std::string GetPlatformName () override; private: - DISALLOW_COPY_AND_ASSIGN(PlatformRemoteiOS); + PlatformRemoteiOS(const PlatformRemoteiOS &) = delete; + const PlatformRemoteiOS &operator=(const PlatformRemoteiOS &) = delete; }; -#endif // liblldb_PlatformRemoteiOS_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMREMOTEIOS_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp index 6230962c2e2..e293bd5b644 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp @@ -1,5 +1,4 @@ -//===-- PlatformiOSSimulator.cpp -----------------------------------*- C++ -//-*-===// +//===-- PlatformiOSSimulator.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -148,8 +147,8 @@ const char *PlatformiOSSimulator::GetDescriptionStatic() { /// Default Constructor PlatformiOSSimulator::PlatformiOSSimulator() - : PlatformAppleSimulator(), m_sdk_dir_mutex(), m_sdk_directory(), - m_build_update() {} + : PlatformAppleSimulator( + CoreSimulatorSupport::DeviceType::ProductFamilyID::iPhone) {} /// Destructor. /// @@ -159,9 +158,9 @@ PlatformiOSSimulator::~PlatformiOSSimulator() {} void PlatformiOSSimulator::GetStatus(Stream &strm) { Platform::GetStatus(strm); - const char *sdk_directory = GetSDKDirectoryAsCString(); - if (sdk_directory) - strm.Printf(" SDK Path: \"%s\"\n", sdk_directory); + llvm::StringRef sdk_directory = GetSDKDirectoryAsCString(); + if (!sdk_directory.empty()) + strm.Printf(" SDK Path: \"%s\"\n", sdk_directory.str().c_str()); else strm.PutCString(" SDK Path: error: unable to locate SDK\n"); PlatformAppleSimulator::GetStatus(strm); @@ -243,58 +242,12 @@ Status PlatformiOSSimulator::ResolveExecutable( return error; } -static FileSystem::EnumerateDirectoryResult -EnumerateDirectoryCallback(void *baton, llvm::sys::fs::file_type ft, - llvm::StringRef path) { - if (ft == llvm::sys::fs::file_type::directory_file) { - FileSpec file_spec(path); - const char *filename = file_spec.GetFilename().GetCString(); - if (filename && - strncmp(filename, "iPhoneSimulator", strlen("iPhoneSimulator")) == 0) { - ::snprintf((char *)baton, PATH_MAX, "%s", filename); - return FileSystem::eEnumerateDirectoryResultQuit; - } - } - return FileSystem::eEnumerateDirectoryResultNext; -} - -const char *PlatformiOSSimulator::GetSDKDirectoryAsCString() { - std::lock_guard guard(m_sdk_dir_mutex); - if (m_sdk_directory.empty()) { - const char *developer_dir = GetDeveloperDirectory(); - if (developer_dir) { - char sdks_directory[PATH_MAX]; - char sdk_dirname[PATH_MAX]; - sdk_dirname[0] = '\0'; - snprintf(sdks_directory, sizeof(sdks_directory), - "%s/Platforms/iPhoneSimulator.platform/Developer/SDKs", - developer_dir); - FileSpec simulator_sdk_spec; - bool find_directories = true; - bool find_files = false; - bool find_other = false; - FileSystem::Instance().EnumerateDirectory( - sdks_directory, find_directories, find_files, find_other, - EnumerateDirectoryCallback, sdk_dirname); - - if (sdk_dirname[0]) { - m_sdk_directory = sdks_directory; - m_sdk_directory.append(1, '/'); - m_sdk_directory.append(sdk_dirname); - return m_sdk_directory.c_str(); - } - } - // Assign a single NULL character so we know we tried to find the device - // support directory and we don't keep trying to find it over and over. - m_sdk_directory.assign(1, '\0'); - } - - // We should have put a single NULL character into m_sdk_directory or it - // should have a valid path if the code gets here - assert(m_sdk_directory.empty() == false); - if (m_sdk_directory[0]) - return m_sdk_directory.c_str(); - return NULL; +llvm::StringRef PlatformiOSSimulator::GetSDKDirectoryAsCString() { + llvm::StringRef sdk; + sdk = HostInfo::GetXcodeSDKPath(XcodeSDK("iPhoneSimulator.Internal.sdk")); + if (sdk.empty()) + sdk = HostInfo::GetXcodeSDKPath(XcodeSDK("iPhoneSimulator.sdk")); + return sdk; } Status PlatformiOSSimulator::GetSymbolFile(const FileSpec &platform_file, @@ -305,10 +258,10 @@ Status PlatformiOSSimulator::GetSymbolFile(const FileSpec &platform_file, if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) { char resolved_path[PATH_MAX]; - const char *sdk_dir = GetSDKDirectoryAsCString(); - if (sdk_dir) { - ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", sdk_dir, - platform_file_path); + llvm::StringRef sdk_dir = GetSDKDirectoryAsCString(); + if (!sdk_dir.empty()) { + ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", + sdk_dir.str().c_str(), platform_file_path); // First try in the SDK and see if the file is in there local_file.SetFile(resolved_path, FileSpec::Style::native); @@ -333,8 +286,8 @@ Status PlatformiOSSimulator::GetSymbolFile(const FileSpec &platform_file, Status PlatformiOSSimulator::GetSharedModule( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr, - bool *did_create_ptr) { + const FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { // For iOS, the SDK files are all cached locally on the host system. So first // we ask for the file in the cached SDK, then we attempt to get a shared // module for the right architecture with the right UUID. @@ -348,9 +301,9 @@ Status PlatformiOSSimulator::GetSharedModule( module_search_paths_ptr); } else { const bool always_create = false; - error = ModuleList::GetSharedModule( - module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, - did_create_ptr, always_create); + error = ModuleList::GetSharedModule(module_spec, module_sp, + module_search_paths_ptr, old_modules, + did_create_ptr, always_create); } if (module_sp) module_sp->SetPlatformFileSpec(platform_file); @@ -367,13 +320,12 @@ PlatformiOSSimulator::FindProcesses(const ProcessInstanceInfoMatch &match_info, // Now we filter them down to only the iOS triples for (uint32_t i = 0; i < n; ++i) { - const ProcessInstanceInfo &proc_info = - all_osx_process_infos.GetProcessInfoAtIndex(i); + const ProcessInstanceInfo &proc_info = all_osx_process_infos[i]; if (proc_info.GetArchitecture().GetTriple().getOS() == llvm::Triple::IOS) { - process_infos.Append(proc_info); + process_infos.push_back(proc_info); } } - return process_infos.GetSize(); + return process_infos.size(); } bool PlatformiOSSimulator::GetSupportedArchitectureAtIndex(uint32_t idx, @@ -387,6 +339,7 @@ bool PlatformiOSSimulator::GetSupportedArchitectureAtIndex(uint32_t idx, arch = platform_arch; if (arch.IsValid()) { arch.GetTriple().setOS(llvm::Triple::IOS); + arch.GetTriple().setEnvironment(llvm::Triple::Simulator); return true; } } else { diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h index d766929b2b8..cc8e45a2be2 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformiOSSimulator_h_ -#define liblldb_PlatformiOSSimulator_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMIOSSIMULATOR_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMIOSSIMULATOR_H #include #include @@ -57,7 +57,7 @@ public: GetSharedModule(const lldb_private::ModuleSpec &module_spec, lldb_private::Process *process, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) override; uint32_t @@ -71,7 +71,7 @@ public: AddClangModuleCompilationOptions(lldb_private::Target *target, std::vector &options) override { return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType( - target, options, PlatformDarwin::SDKType::iPhoneSimulator); + target, options, lldb_private::XcodeSDK::Type::iPhoneSimulator); } protected: @@ -79,10 +79,11 @@ protected: std::string m_sdk_directory; std::string m_build_update; - const char *GetSDKDirectoryAsCString(); + llvm::StringRef GetSDKDirectoryAsCString(); private: - DISALLOW_COPY_AND_ASSIGN(PlatformiOSSimulator); + PlatformiOSSimulator(const PlatformiOSSimulator &) = delete; + const PlatformiOSSimulator &operator=(const PlatformiOSSimulator &) = delete; }; -#endif // liblldb_PlatformiOSSimulator_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_PLATFORMIOSSIMULATOR_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h index 0a75371288c..5104e488189 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformiOSSimulatorCoreSimulatorSupport_h_ -#define liblldb_PlatformiOSSimulatorCoreSimulatorSupport_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_OBJCXX_PLATFORMIOSSIMULATORCORESIMULATORSUPPORT_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_OBJCXX_PLATFORMIOSSIMULATORCORESIMULATORSUPPORT_H #include #include @@ -217,4 +217,4 @@ private: }; } -#endif // liblldb_PlatformiOSSimulatorCoreSimulatorSupport_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_MACOSX_OBJCXX_PLATFORMIOSSIMULATORCORESIMULATORSUPPORT_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm index 15ae82e9d93..8f36640a66a 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm +++ b/gnu/llvm/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm @@ -1,5 +1,4 @@ -//===-- PlatformiOSSimulatorCoreSimulatorSupport.cpp ---------------*- C++ -//-*-===// +//===-- PlatformiOSSimulatorCoreSimulatorSupport.cpp ----------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -51,10 +50,12 @@ using namespace lldb_private; - (NSUInteger)state; - (BOOL)shutdownWithError:(NSError **)error; - (NSUUID *)UDID; -- (pid_t)spawnWithPath:(NSString *)path - options:(NSDictionary *)options - terminationHandler:(void (^)(int status))terminationHandler - error:(NSError **)error; +- (BOOL)spawnWithPath:(NSString *)path + options:(nullable NSDictionary *)options + terminationQueue:(nullable dispatch_queue_t)terminationQueue + terminationHandler:(nullable void (^)(int status))terminationHandler + pid:(pid_t *_Nullable)pid + error:(NSError *__autoreleasing _Nullable *_Nullable)error; @end CoreSimulatorSupport::Process::Process(lldb::pid_t p) : m_pid(p), m_error() {} @@ -403,22 +404,25 @@ static Status HandleFileAction(ProcessLaunchInfo &launch_info, case FileAction::eFileActionOpen: { FileSpec file_spec = file_action->GetFileSpec(); if (file_spec) { - const int master_fd = launch_info.GetPTY().GetMasterFileDescriptor(); + const int master_fd = launch_info.GetPTY().GetPrimaryFileDescriptor(); if (master_fd != PseudoTerminal::invalid_fd) { - // Check in case our file action open wants to open the slave - const char *slave_path = launch_info.GetPTY().GetSlaveName(NULL, 0); - if (slave_path) { - FileSpec slave_spec(slave_path); - if (file_spec == slave_spec) { - int slave_fd = launch_info.GetPTY().GetSlaveFileDescriptor(); - if (slave_fd == PseudoTerminal::invalid_fd) - slave_fd = launch_info.GetPTY().OpenSlave(O_RDWR, nullptr, 0); - if (slave_fd == PseudoTerminal::invalid_fd) { - error.SetErrorStringWithFormat("unable to open slave pty '%s'", - slave_path); + // Check in case our file action open wants to open the secondary + const char *secondary_path = + launch_info.GetPTY().GetSecondaryName(NULL, 0); + if (secondary_path) { + FileSpec secondary_spec(secondary_path); + if (file_spec == secondary_spec) { + int secondary_fd = + launch_info.GetPTY().GetSecondaryFileDescriptor(); + if (secondary_fd == PseudoTerminal::invalid_fd) + secondary_fd = + launch_info.GetPTY().OpenSecondary(O_RDWR, nullptr, 0); + if (secondary_fd == PseudoTerminal::invalid_fd) { + error.SetErrorStringWithFormat( + "unable to open secondary pty '%s'", secondary_path); return error; // Failure } - [options setValue:[NSNumber numberWithInteger:slave_fd] + [options setValue:[NSNumber numberWithInteger:secondary_fd] forKey:key]; return error; // Success } @@ -465,9 +469,12 @@ CoreSimulatorSupport::Device::Spawn(ProcessLaunchInfo &launch_info) { provided, path will be argv[0] */ #define kSimDeviceSpawnWaitForDebugger \ @"wait_for_debugger" /* An NSNumber (bool) */ +#define kSimDeviceSpawnStandalone @"standalone" NSMutableDictionary *options = [[NSMutableDictionary alloc] init]; + options[kSimDeviceSpawnStandalone] = @(YES); + if (launch_info.GetFlags().Test(lldb::eLaunchFlagDebug)) [options setObject:@YES forKey:kSimDeviceSpawnWaitForDebugger]; @@ -524,16 +531,19 @@ CoreSimulatorSupport::Device::Spawn(ProcessLaunchInfo &launch_info) { NSError *nserror; - pid_t pid = [m_dev + pid_t pid; + BOOL success = [m_dev spawnWithPath:[NSString stringWithUTF8String:launch_info .GetExecutableFile() .GetPath() .c_str()] options:options + terminationQueue:nil terminationHandler:nil + pid:&pid error:&nserror]; - if (pid < 0) { + if (!success) { const char *nserror_string = [[nserror description] UTF8String]; error.SetErrorString(nserror_string ? nserror_string : "unable to launch"); } diff --git a/gnu/llvm/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp b/gnu/llvm/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp index 53f819e6a27..caebd79c853 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp @@ -1,4 +1,4 @@ -//===-- PlatformNetBSD.cpp -------------------------------------*- C++ -*-===// +//===-- PlatformNetBSD.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -34,6 +34,8 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::platform_netbsd; +LLDB_PLUGIN_DEFINE(PlatformNetBSD) + static uint32_t g_initialize_count = 0; @@ -329,14 +331,14 @@ PlatformNetBSD::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, // Hook up process PTY if we have one (which we should for local debugging // with llgs). - int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor(); + int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor(); if (pty_fd != PseudoTerminal::invalid_fd) { process_sp->SetSTDIOFileDescriptor(pty_fd); LLDB_LOG(log, "hooked up STDIO pty to process"); } else LLDB_LOG(log, "not using process STDIO pty"); } else { - LLDB_LOG(log, "process launch failed: {0}", error); + LLDB_LOG(log, "{0}", error); // FIXME figure out appropriate cleanup here. Do we delete the target? Do // we delete the process? Does our caller do that? } diff --git a/gnu/llvm/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h b/gnu/llvm/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h index 0584d92d6c9..d53e5841888 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformNetBSD_h_ -#define liblldb_PlatformNetBSD_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_NETBSD_PLATFORMNETBSD_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_NETBSD_PLATFORMNETBSD_H #include "Plugins/Platform/POSIX/PlatformPOSIX.h" @@ -60,10 +60,11 @@ public: lldb::addr_t offset) override; private: - DISALLOW_COPY_AND_ASSIGN(PlatformNetBSD); + PlatformNetBSD(const PlatformNetBSD &) = delete; + const PlatformNetBSD &operator=(const PlatformNetBSD &) = delete; }; } // namespace platform_netbsd } // namespace lldb_private -#endif // liblldb_PlatformNetBSD_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_NETBSD_PLATFORMNETBSD_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp b/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp index 73e766f3973..a743970990a 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp @@ -1,4 +1,4 @@ -//===-- PlatformOpenBSD.cpp -------------------------------------*- C++ -*-===// +//===-- PlatformOpenBSD.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -34,6 +34,8 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::platform_openbsd; +LLDB_PLUGIN_DEFINE(PlatformOpenBSD) + static uint32_t g_initialize_count = 0; @@ -91,7 +93,7 @@ ConstString PlatformOpenBSD::GetPluginName() { } void PlatformOpenBSD::Initialize() { - PlatformPOSIX::Initialize(); + Platform::Initialize(); if (g_initialize_count++ == 0) { #if defined(__OpenBSD__) @@ -190,128 +192,9 @@ void PlatformOpenBSD::GetStatus(Stream &strm) { #endif } +// OpenBSD processes cannot yet be launched by spawning and attaching. bool PlatformOpenBSD::CanDebugProcess() { - if (IsHost()) { - return true; - } else { - // If we're connected, we can debug. - return IsConnected(); - } -} - -// For local debugging, OpenBSD will override the debug logic to use llgs-launch -// rather than lldb-launch, llgs-attach. This differs from current lldb- -// launch, debugserver-attach approach on MacOSX. -lldb::ProcessSP -PlatformOpenBSD::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, - Target *target, // Can be NULL, if NULL create a new - // target, else use existing one - Status &error) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - LLDB_LOG(log, "target {0}", target); - - // If we're a remote host, use standard behavior from parent class. - if (!IsHost()) - return PlatformPOSIX::DebugProcess(launch_info, debugger, target, error); - - // - // For local debugging, we'll insist on having ProcessGDBRemote create the - // process. - // - - ProcessSP process_sp; - - // Make sure we stop at the entry point - launch_info.GetFlags().Set(eLaunchFlagDebug); - - // We always launch the process we are going to debug in a separate process - // group, since then we can handle ^C interrupts ourselves w/o having to - // worry about the target getting them as well. - launch_info.SetLaunchInSeparateProcessGroup(true); - - // Ensure we have a target. - if (target == nullptr) { - LLDB_LOG(log, "creating new target"); - TargetSP 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; - } - - target = new_target_sp.get(); - if (!target) { - error.SetErrorString("CreateTarget() returned nullptr"); - LLDB_LOG(log, "error: {0}", error); - return process_sp; - } - } - - // Mark target as currently selected target. - debugger.GetTargetList().SetSelectedTarget(target); - - // Now create the gdb-remote process. - LLDB_LOG(log, "having target create process with gdb-remote plugin"); - process_sp = target->CreateProcess( - launch_info.GetListener(), "gdb-remote", nullptr); - - if (!process_sp) { - error.SetErrorString("CreateProcess() failed for gdb-remote process"); - LLDB_LOG(log, "error: {0}", error); - return process_sp; - } - - LLDB_LOG(log, "successfully created process"); - // Adjust launch for a hijacker. - ListenerSP listener_sp; - if (!launch_info.GetHijackListener()) { - LLDB_LOG(log, "setting up hijacker"); - listener_sp = - Listener::MakeListener("lldb.PlatformOpenBSD.DebugProcess.hijack"); - launch_info.SetHijackListener(listener_sp); - process_sp->HijackProcessEvents(listener_sp); - } - - // Log file actions. - if (log) { - LLDB_LOG(log, "launching process with the following file actions:"); - StreamString stream; - size_t i = 0; - const FileAction *file_action; - while ((file_action = launch_info.GetFileActionAtIndex(i++)) != nullptr) { - file_action->Dump(stream); - LLDB_LOG(log, "{0}", stream.GetData()); - stream.Clear(); - } - } - - // Do the launch. - error = process_sp->Launch(launch_info); - if (error.Success()) { - // Handle the hijacking of process events. - if (listener_sp) { - const StateType state = process_sp->WaitForProcessToStop( - llvm::None, NULL, false, listener_sp); - - LLDB_LOG(log, "pid {0} state {0}", process_sp->GetID(), state); - } - - // Hook up process PTY if we have one (which we should for local debugging - // with llgs). - int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor(); - if (pty_fd != PseudoTerminal::invalid_fd) { - process_sp->SetSTDIOFileDescriptor(pty_fd); - LLDB_LOG(log, "hooked up STDIO pty to process"); - } else - LLDB_LOG(log, "not using process STDIO pty"); - } else { - LLDB_LOG(log, "process launch failed: {0}", error); - // FIXME figure out appropriate cleanup here. Do we delete the target? Do - // we delete the process? Does our caller do that? - } - - return process_sp; + return false; } void PlatformOpenBSD::CalculateTrapHandlerSymbolNames() { @@ -332,13 +215,3 @@ MmapArgList PlatformOpenBSD::GetMmapArgumentList(const ArchSpec &arch, MmapArgList args({addr, length, prot, flags_platform, fd, offset}); return args; } - -FileSpec PlatformOpenBSD::LocateExecutable(const char *basename) { - - std::string check = std::string("/usr/bin/") + basename; - if (access(check.c_str(), X_OK) == 0) { - return FileSpec(check); - } - - return FileSpec(); -} diff --git a/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h b/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h index bcd79af30cd..9cfe32c3720 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformOpenBSD_h_ -#define liblldb_PlatformOpenBSD_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_OPENBSD_PLATFORMOPENBSD_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_OPENBSD_PLATFORMOPENBSD_H #include "Plugins/Platform/POSIX/PlatformPOSIX.h" @@ -46,9 +46,6 @@ public: bool CanDebugProcess() override; - lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, - Target *target, Status &error) override; - void CalculateTrapHandlerSymbolNames() override; MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr, @@ -56,13 +53,12 @@ public: unsigned flags, lldb::addr_t fd, lldb::addr_t offset) override; - lldb_private::FileSpec LocateExecutable(const char *basename) override; - private: - DISALLOW_COPY_AND_ASSIGN(PlatformOpenBSD); + PlatformOpenBSD(const PlatformOpenBSD &) = delete; + const PlatformOpenBSD &operator=(const PlatformOpenBSD &) = delete; }; } // namespace platform_openbsd } // namespace lldb_private -#endif // liblldb_PlatformOpenBSD_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_OPENBSD_PLATFORMOPENBSD_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/POSIX/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Platform/POSIX/CMakeLists.txt index 749407d63d5..6f52deabc85 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/POSIX/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/Platform/POSIX/CMakeLists.txt @@ -1,4 +1,4 @@ -add_lldb_library(lldbPluginPlatformPOSIX PLUGIN +add_lldb_library(lldbPluginPlatformPOSIX PlatformPOSIX.cpp LINK_LIBS @@ -7,4 +7,5 @@ add_lldb_library(lldbPluginPlatformPOSIX PLUGIN lldbHost lldbInterpreter lldbTarget + lldbPluginTypeSystemClang ) diff --git a/gnu/llvm/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/gnu/llvm/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp index 2b64be63a62..180ea1d2cfd 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -1,4 +1,4 @@ -//===-- PlatformPOSIX.cpp ---------------------------------------*- C++ -*-===// +//===-- PlatformPOSIX.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,9 +8,9 @@ #include "PlatformPOSIX.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" -#include "lldb/Core/ModuleSpec.h" #include "lldb/Core/ValueObject.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/FunctionCaller.h" @@ -22,7 +22,6 @@ #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/ProcessLaunchInfo.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" @@ -64,148 +63,6 @@ lldb_private::OptionGroupOptions *PlatformPOSIX::GetConnectionOptions( return m_options.at(&interpreter).get(); } -Status -PlatformPOSIX::ResolveExecutable(const ModuleSpec &module_spec, - lldb::ModuleSP &exe_module_sp, - const FileSpecList *module_search_paths_ptr) { - Status error; - // Nothing special to do here, just use the actual file and architecture - - char exe_path[PATH_MAX]; - ModuleSpec resolved_module_spec(module_spec); - - if (IsHost()) { - // If we have "ls" as the exe_file, resolve the executable location based - // on the current path variables - 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, - FileSpec::Style::native); - FileSystem::Instance().Resolve(resolved_module_spec.GetFileSpec()); - } - - 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 (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) - error.Clear(); - else { - const uint32_t permissions = FileSystem::Instance().GetPermissions( - resolved_module_spec.GetFileSpec()); - if (permissions && (permissions & eFilePermissionsEveryoneR) == 0) - error.SetErrorStringWithFormat( - "executable '%s' is not readable", - resolved_module_spec.GetFileSpec().GetPath().c_str()); - else - error.SetErrorStringWithFormat( - "unable to find executable for '%s'", - resolved_module_spec.GetFileSpec().GetPath().c_str()); - } - } else { - if (m_remote_platform_sp) { - error = - GetCachedExecutable(resolved_module_spec, exe_module_sp, - module_search_paths_ptr, *m_remote_platform_sp); - } else { - // We may connect to a process and use the provided executable (Don't use - // local $PATH). - - // Resolve any executable within a bundle on MacOSX - Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec()); - - if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) - error.Clear(); - else - error.SetErrorStringWithFormat("the platform is not currently " - "connected, and '%s' doesn't exist in " - "the system root.", - exe_path); - } - } - - if (error.Success()) { - if (resolved_module_spec.GetArchitecture().IsValid()) { - error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, - module_search_paths_ptr, nullptr, nullptr); - if (error.Fail()) { - // If we failed, it may be because the vendor and os aren't known. If - // that is the case, try setting them to the host architecture and give - // it another try. - llvm::Triple &module_triple = - resolved_module_spec.GetArchitecture().GetTriple(); - bool is_vendor_specified = - (module_triple.getVendor() != llvm::Triple::UnknownVendor); - bool is_os_specified = - (module_triple.getOS() != llvm::Triple::UnknownOS); - if (!is_vendor_specified || !is_os_specified) { - const llvm::Triple &host_triple = - HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple(); - - if (!is_vendor_specified) - module_triple.setVendorName(host_triple.getVendorName()); - if (!is_os_specified) - module_triple.setOSName(host_triple.getOSName()); - - error = ModuleList::GetSharedModule(resolved_module_spec, - exe_module_sp, module_search_paths_ptr, nullptr, nullptr); - } - } - - // TODO find out why exe_module_sp might be NULL - if (error.Fail() || !exe_module_sp || !exe_module_sp->GetObjectFile()) { - exe_module_sp.reset(); - error.SetErrorStringWithFormat( - "'%s' doesn't contain the architecture %s", - resolved_module_spec.GetFileSpec().GetPath().c_str(), - resolved_module_spec.GetArchitecture().GetArchitectureName()); - } - } else { - // No valid architecture was specified, ask the platform for the - // architectures that we should be using (in the correct order) and see - // if we can find a match that way - StreamString arch_names; - for (uint32_t idx = 0; GetSupportedArchitectureAtIndex( - idx, resolved_module_spec.GetArchitecture()); - ++idx) { - error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, - module_search_paths_ptr, nullptr, nullptr); - // Did we find an executable using one of the - if (error.Success()) { - if (exe_module_sp && exe_module_sp->GetObjectFile()) - break; - else - error.SetErrorToGenericError(); - } - - if (idx > 0) - arch_names.PutCString(", "); - arch_names.PutCString( - resolved_module_spec.GetArchitecture().GetArchitectureName()); - } - - if (error.Fail() || !exe_module_sp) { - 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(), - GetPluginName().GetCString(), arch_names.GetData()); - } else { - error.SetErrorStringWithFormat( - "'%s' is not readable", - resolved_module_spec.GetFileSpec().GetPath().c_str()); - } - } - } - } - - return error; -} - static uint32_t chown_file(Platform *platform, const char *path, uint32_t uid = UINT32_MAX, uint32_t gid = UINT32_MAX) { @@ -429,7 +286,7 @@ std::string PlatformPOSIX::GetPlatformSpecificConnectionInformation() { if (GetLocalCacheDirectory() && *GetLocalCacheDirectory()) stream.Printf("cache dir: %s", GetLocalCacheDirectory()); if (stream.GetSize()) - return stream.GetString(); + return std::string(stream.GetString()); else return ""; } @@ -679,7 +536,7 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx, static const char *dlopen_wrapper_name = "__lldb_dlopen_wrapper"; Process *process = exe_ctx.GetProcessSP().get(); // Insert the dlopen shim defines into our generic expression: - std::string expr(GetLibdlFunctionDeclarations(process)); + std::string expr(std::string(GetLibdlFunctionDeclarations(process))); expr.append(dlopen_wrapper_code); Status utility_error; DiagnosticManager diagnostics; @@ -706,7 +563,7 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx, FunctionCaller *do_dlopen_function = nullptr; // Fetch the clang types we will need: - ClangASTContext *ast = ClangASTContext::GetScratch(process->GetTarget()); + TypeSystemClang *ast = TypeSystemClang::GetScratch(process->GetTarget()); if (!ast) return nullptr; @@ -950,9 +807,9 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process, Value return_value; // Fetch the clang types we will need: - ClangASTContext *ast = ClangASTContext::GetScratch(process->GetTarget()); + TypeSystemClang *ast = TypeSystemClang::GetScratch(process->GetTarget()); if (!ast) { - error.SetErrorString("dlopen error: Unable to get ClangASTContext"); + error.SetErrorString("dlopen error: Unable to get TypeSystemClang"); return LLDB_INVALID_IMAGE_TOKEN; } diff --git a/gnu/llvm/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h b/gnu/llvm/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h index 5858f99088e..72c54f4147c 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformPOSIX_h_ -#define liblldb_PlatformPOSIX_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_POSIX_PLATFORMPOSIX_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_POSIX_PLATFORMPOSIX_H #include #include @@ -37,10 +37,6 @@ public: const lldb::UnixSignalsSP &GetRemoteUnixSignals() override; - lldb_private::Status ResolveExecutable( - const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp, - const lldb_private::FileSpecList *module_search_paths_ptr) override; - lldb::ProcessSP Attach(lldb_private::ProcessAttachInfo &attach_info, lldb_private::Debugger &debugger, lldb_private::Target *target, // Can be nullptr, if @@ -105,7 +101,8 @@ protected: llvm::StringRef GetLibdlFunctionDeclarations(lldb_private::Process *process); private: - DISALLOW_COPY_AND_ASSIGN(PlatformPOSIX); + PlatformPOSIX(const PlatformPOSIX &) = delete; + const PlatformPOSIX &operator=(const PlatformPOSIX &) = delete; }; -#endif // liblldb_PlatformPOSIX_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_POSIX_PLATFORMPOSIX_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp b/gnu/llvm/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp index c18939faa8f..f7f5cf16619 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp @@ -1,4 +1,4 @@ -//===-- PlatformWindows.cpp -------------------------------------*- C++ -*-===// +//===-- PlatformWindows.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,7 +18,6 @@ #include "lldb/Breakpoint/BreakpointSite.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" -#include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Host/HostInfo.h" #include "lldb/Target/Process.h" @@ -27,6 +26,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(PlatformWindows) + static uint32_t g_initialize_count = 0; namespace { @@ -156,110 +157,6 @@ PlatformWindows::PlatformWindows(bool is_host) : RemoteAwarePlatform(is_host) {} /// inherited from by the plug-in instance. PlatformWindows::~PlatformWindows() = default; -Status PlatformWindows::ResolveExecutable( - const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp, - const FileSpecList *module_search_paths_ptr) { - Status error; - // Nothing special to do here, just use the actual file and architecture - - char exe_path[PATH_MAX]; - ModuleSpec resolved_module_spec(ms); - - if (IsHost()) { - // if we cant resolve the executable loation based on the current path - // variables - 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, - FileSpec::Style::native); - FileSystem::Instance().Resolve(resolved_module_spec.GetFileSpec()); - } - - if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) - FileSystem::Instance().ResolveExecutableLocation( - resolved_module_spec.GetFileSpec()); - - if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) - error.Clear(); - else { - ms.GetFileSpec().GetPath(exe_path, sizeof(exe_path)); - error.SetErrorStringWithFormat("unable to find executable for '%s'", - exe_path); - } - } else { - if (m_remote_platform_sp) { - error = - GetCachedExecutable(resolved_module_spec, exe_module_sp, - module_search_paths_ptr, *m_remote_platform_sp); - } else { - // We may connect to a process and use the provided executable (Don't use - // local $PATH). - if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) - error.Clear(); - else - error.SetErrorStringWithFormat("the platform is not currently " - "connected, and '%s' doesn't exist in " - "the system root.", - exe_path); - } - } - - if (error.Success()) { - if (resolved_module_spec.GetArchitecture().IsValid()) { - error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, - nullptr, nullptr, nullptr); - - if (!exe_module_sp || exe_module_sp->GetObjectFile() == nullptr) { - exe_module_sp.reset(); - error.SetErrorStringWithFormat( - "'%s' doesn't contain the architecture %s", - resolved_module_spec.GetFileSpec().GetPath().c_str(), - resolved_module_spec.GetArchitecture().GetArchitectureName()); - } - } else { - // No valid architecture was specified, ask the platform for the - // architectures that we should be using (in the correct order) and see - // if we can find a match that way - StreamString arch_names; - for (uint32_t idx = 0; GetSupportedArchitectureAtIndex( - idx, resolved_module_spec.GetArchitecture()); - ++idx) { - error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, - module_search_paths_ptr, nullptr, - nullptr); - // Did we find an executable using one of the - if (error.Success()) { - if (exe_module_sp && exe_module_sp->GetObjectFile()) - break; - else - error.SetErrorToGenericError(); - } - - if (idx > 0) - arch_names.PutCString(", "); - arch_names.PutCString( - resolved_module_spec.GetArchitecture().GetArchitectureName()); - } - - if (error.Fail() || !exe_module_sp) { - 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(), - GetPluginName().GetCString(), arch_names.GetData()); - } else { - error.SetErrorStringWithFormat( - "'%s' is not readable", - resolved_module_spec.GetFileSpec().GetPath().c_str()); - } - } - } - } - - return error; -} - Status PlatformWindows::ConnectRemote(Args &args) { Status error; if (IsHost()) { diff --git a/gnu/llvm/lldb/source/Plugins/Platform/Windows/PlatformWindows.h b/gnu/llvm/lldb/source/Plugins/Platform/Windows/PlatformWindows.h index 5740001f0e0..d8b2cd8a26a 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/Windows/PlatformWindows.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/Windows/PlatformWindows.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformWindows_h_ -#define liblldb_PlatformWindows_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_WINDOWS_PLATFORMWINDOWS_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_WINDOWS_PLATFORMWINDOWS_H #include "lldb/Target/RemoteAwarePlatform.h" @@ -36,11 +36,6 @@ public: uint32_t GetPluginVersion() override { return 1; } // lldb_private::Platform functions - Status - ResolveExecutable(const lldb_private::ModuleSpec &module_spec, - lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr) override; - const char *GetDescription() override { return GetPluginDescriptionStatic(IsHost()); } @@ -72,9 +67,10 @@ public: ConstString GetFullNameForDylib(ConstString basename) override; private: - DISALLOW_COPY_AND_ASSIGN(PlatformWindows); + PlatformWindows(const PlatformWindows &) = delete; + const PlatformWindows &operator=(const PlatformWindows &) = delete; }; } // namespace lldb_private -#endif // liblldb_PlatformWindows_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_WINDOWS_PLATFORMWINDOWS_H diff --git a/gnu/llvm/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/gnu/llvm/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp index 1e62ddfe94f..21bf7f4ac46 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ b/gnu/llvm/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -1,4 +1,4 @@ -//===-- PlatformRemoteGDBServer.cpp -----------------------------*- C++ -*-===// +//===-- PlatformRemoteGDBServer.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -35,6 +35,8 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::platform_gdb_server; +LLDB_PLUGIN_DEFINE_ADV(PlatformRemoteGDBServer, PlatformGDB) + static bool g_initialized = false; void PlatformRemoteGDBServer::Initialize() { @@ -286,40 +288,55 @@ Status PlatformRemoteGDBServer::ConnectRemote(Args &args) { "execute 'platform disconnect' to close the " "current connection", GetHostname()); + return error; + } + + if (args.GetArgumentCount() != 1) { + error.SetErrorString( + "\"platform connect\" takes a single argument: "); + return error; + } + + const char *url = args.GetArgumentAtIndex(0); + if (!url) + return Status("URL is null."); + + int port; + llvm::StringRef scheme, hostname, pathname; + if (!UriParser::Parse(url, scheme, hostname, port, pathname)) + return Status("Invalid URL: %s", url); + + // We're going to reuse the hostname when we connect to the debugserver. + m_platform_scheme = std::string(scheme); + m_platform_hostname = std::string(hostname); + + m_gdb_client.SetConnection(std::make_unique()); + if (repro::Reproducer::Instance().IsReplaying()) { + error = m_gdb_replay_server.Connect(m_gdb_client); + if (error.Success()) + m_gdb_replay_server.StartAsyncThread(); } else { - if (args.GetArgumentCount() == 1) { - m_gdb_client.SetConnection(new ConnectionFileDescriptor()); - // we're going to reuse the hostname when we connect to the debugserver - int port; - std::string path; - const char *url = args.GetArgumentAtIndex(0); - if (!url) - return Status("URL is null."); - llvm::StringRef scheme, hostname, pathname; - if (!UriParser::Parse(url, scheme, hostname, port, pathname)) - return Status("Invalid URL: %s", url); - m_platform_scheme = scheme; - m_platform_hostname = hostname; - path = pathname; - - const ConnectionStatus status = m_gdb_client.Connect(url, &error); - if (status == eConnectionStatusSuccess) { - if (m_gdb_client.HandshakeWithServer(&error)) { - m_gdb_client.GetHostInfo(); - // If a working directory was set prior to connecting, send it down - // now - if (m_working_dir) - m_gdb_client.SetWorkingDir(m_working_dir); - } else { - m_gdb_client.Disconnect(); - if (error.Success()) - error.SetErrorString("handshake failed"); - } - } - } else { - error.SetErrorString( - "\"platform connect\" takes a single argument: "); + if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) { + repro::GDBRemoteProvider &provider = + g->GetOrCreate(); + m_gdb_client.SetPacketRecorder(provider.GetNewPacketRecorder()); } + m_gdb_client.Connect(url, &error); + } + + if (error.Fail()) + return error; + + if (m_gdb_client.HandshakeWithServer(&error)) { + m_gdb_client.GetHostInfo(); + // If a working directory was set prior to connecting, send it down + // now. + if (m_working_dir) + m_gdb_client.SetWorkingDir(m_working_dir); + } else { + m_gdb_client.Disconnect(); + if (error.Success()) + error.SetErrorString("handshake failed"); } return error; } @@ -486,10 +503,10 @@ lldb::ProcessSP PlatformRemoteGDBServer::DebugProcess( "gdb-remote", nullptr); if (process_sp) { - error = process_sp->ConnectRemote(nullptr, connect_url.c_str()); + error = process_sp->ConnectRemote(connect_url.c_str()); // Retry the connect remote one time... if (error.Fail()) - error = process_sp->ConnectRemote(nullptr, connect_url.c_str()); + error = process_sp->ConnectRemote(connect_url.c_str()); if (error.Success()) error = process_sp->Launch(launch_info); else if (debugserver_pid != LLDB_INVALID_PROCESS_ID) { @@ -572,7 +589,7 @@ lldb::ProcessSP PlatformRemoteGDBServer::Attach( target->CreateProcess(attach_info.GetListenerForProcess(debugger), "gdb-remote", nullptr); if (process_sp) { - error = process_sp->ConnectRemote(nullptr, connect_url.c_str()); + error = process_sp->ConnectRemote(connect_url.c_str()); if (error.Success()) { ListenerSP listener_sp = attach_info.GetHijackListener(); if (listener_sp) @@ -725,7 +742,8 @@ const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() { response.GetResponseType() != response.eResponse) return m_remote_signals_sp; - auto object_sp = StructuredData::ParseJSON(response.GetStringRef()); + auto object_sp = + StructuredData::ParseJSON(std::string(response.GetStringRef())); if (!object_sp || !object_sp->IsValid()) return m_remote_signals_sp; @@ -772,7 +790,7 @@ const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() { std::string description{""}; object_sp = dict->GetValueForKey("description"); if (object_sp && object_sp->IsValid()) - description = object_sp->GetStringValue(); + description = std::string(object_sp->GetStringValue()); remote_signals_sp->AddSignal(signo, name.str().c_str(), suppress, stop, notify, description.c_str()); @@ -811,7 +829,7 @@ std::string PlatformRemoteGDBServer::MakeUrl(const char *scheme, result.Printf(":%u", port); if (path) result.Write(path, strlen(path)); - return result.GetString(); + return std::string(result.GetString()); } lldb::ProcessSP PlatformRemoteGDBServer::ConnectProcess( diff --git a/gnu/llvm/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/gnu/llvm/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h index 13edcbab9f5..0602be1fa37 100644 --- a/gnu/llvm/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h +++ b/gnu/llvm/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h @@ -7,13 +7,14 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_PlatformRemoteGDBServer_h_ -#define liblldb_PlatformRemoteGDBServer_h_ +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_GDB_SERVER_PLATFORMREMOTEGDBSERVER_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_GDB_SERVER_PLATFORMREMOTEGDBSERVER_H #include -#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" #include "Plugins/Process/Utility/GDBRemoteSignals.h" +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" +#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h" #include "lldb/Target/Platform.h" namespace lldb_private { @@ -164,6 +165,7 @@ public: protected: process_gdb_remote::GDBRemoteCommunicationClient m_gdb_client; + process_gdb_remote::GDBRemoteCommunicationReplayServer m_gdb_replay_server; std::string m_platform_description; // After we connect we can get a more // complete description of what we are // connected to @@ -192,10 +194,12 @@ private: llvm::Optional DoGetUserName(UserIDResolver::id_t uid) override; llvm::Optional DoGetGroupName(UserIDResolver::id_t uid) override; - DISALLOW_COPY_AND_ASSIGN(PlatformRemoteGDBServer); + PlatformRemoteGDBServer(const PlatformRemoteGDBServer &) = delete; + const PlatformRemoteGDBServer & + operator=(const PlatformRemoteGDBServer &) = delete; }; } // namespace platform_gdb_server } // namespace lldb_private -#endif // liblldb_PlatformRemoteGDBServer_h_ +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_GDB_SERVER_PLATFORMREMOTEGDBSERVER_H diff --git a/gnu/llvm/lldb/source/Plugins/Plugins.def.in b/gnu/llvm/lldb/source/Plugins/Plugins.def.in new file mode 100644 index 00000000000..bf54598fb2f --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/Plugins.def.in @@ -0,0 +1,37 @@ +/*===- lldb/source/Plugin/Plugins.def ---------------------------*- C++ -*-===*\ +|* *| +|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| +|* Exceptions. *| +|* See https://llvm.org/LICENSE.txt for license information. *| +|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This file enumerates all of the plugins supported by this build of LLDB. *| +|* Clients of this file should define the LLDB_PLUGIN macro to be a *| +|* function-like macro with a single parameter (the name of the plugin) *| +|* including this file will then enumerate all of the plugins. Script *| +|* interpreter plugins can be enumerated separately by defining *| +|* LLDB_SCRIPT_PLUGIN in which case they are not part of LLDB_PLUGIN. *| +|* *| +|* *| +|* The set of plugins supported by LLDB is generated at configuration *| +|* time, at which point this header is generated. Do not modify this *| +|* header directly. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#ifndef LLDB_PLUGIN +# error Please define the macro LLDB_PLUGIN(PluginName) +#endif + +#ifndef LLDB_SCRIPT_PLUGIN +#define LLDB_SCRIPT_PLUGIN(p) LLDB_PLUGIN(p) +#endif + +@LLDB_ENUM_PLUGINS@ +@LLDB_PROCESS_WINDOWS_PLUGIN@ +@LLDB_PROCESS_GDB_PLUGIN@ + +#undef LLDB_PLUGIN +#undef LLDB_SCRIPT_PLUGIN diff --git a/gnu/llvm/lldb/source/Plugins/Process/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Process/CMakeLists.txt index bc80f93a271..fdeb211fe7a 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/Process/CMakeLists.txt @@ -7,9 +7,6 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") elseif (CMAKE_SYSTEM_NAME MATCHES "NetBSD") add_subdirectory(NetBSD) add_subdirectory(POSIX) -elseif (CMAKE_SYSTEM_NAME MATCHES "OpenBSD") - add_subdirectory(OpenBSD) - add_subdirectory(POSIX) elseif (CMAKE_SYSTEM_NAME MATCHES "Windows") add_subdirectory(Windows/Common) elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin") diff --git a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp index 0a49f96f54a..48dbddb86cc 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp @@ -1,4 +1,4 @@ -//===-- FreeBSDThread.cpp ---------------------------------------*- C++ -*-===// +//===-- FreeBSDThread.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -14,9 +14,6 @@ #include #include -#include "lldb/Target/UnixSignals.h" -#include "lldb/Utility/State.h" - #include "FreeBSDThread.h" #include "POSIXStopInfo.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" @@ -26,7 +23,6 @@ #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h" #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h" #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" -#include "Plugins/Process/Utility/UnwindLLDB.h" #include "ProcessFreeBSD.h" #include "ProcessMonitor.h" #include "RegisterContextPOSIXProcessMonitor_arm.h" @@ -44,6 +40,8 @@ #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Target/UnixSignals.h" +#include "lldb/Target/Unwind.h" #include "lldb/Utility/State.h" #include "llvm/ADT/SmallString.h" @@ -166,7 +164,6 @@ lldb::RegisterContextSP FreeBSDThread::GetRegisterContext() { assert(target_arch.GetTriple().getOS() == llvm::Triple::FreeBSD); switch (target_arch.GetMachine()) { case llvm::Triple::aarch64: - reg_interface = new RegisterInfoPOSIX_arm64(target_arch); break; case llvm::Triple::arm: reg_interface = new RegisterInfoPOSIX_arm(target_arch); @@ -195,7 +192,8 @@ lldb::RegisterContextSP FreeBSDThread::GetRegisterContext() { switch (target_arch.GetMachine()) { case llvm::Triple::aarch64: { RegisterContextPOSIXProcessMonitor_arm64 *reg_ctx = - new RegisterContextPOSIXProcessMonitor_arm64(*this, 0, reg_interface); + new RegisterContextPOSIXProcessMonitor_arm64( + *this, std::make_unique(target_arch)); m_posix_thread = reg_ctx; m_reg_context_sp.reset(reg_ctx); break; @@ -254,8 +252,7 @@ FreeBSDThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame) { if (concrete_frame_idx == 0) reg_ctx_sp = GetRegisterContext(); else { - assert(GetUnwinder()); - reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame); + reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame); } return reg_ctx_sp; @@ -275,13 +272,6 @@ bool FreeBSDThread::CalculateStopInfo() { return true; } -Unwind *FreeBSDThread::GetUnwinder() { - if (!m_unwinder_up) - m_unwinder_up.reset(new UnwindLLDB(*this)); - - return m_unwinder_up.get(); -} - void FreeBSDThread::DidStop() { // Don't set the thread state to stopped unless we really stopped. } diff --git a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h index 6d3c253a519..774ffb511bc 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h +++ b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h @@ -102,8 +102,6 @@ protected: void ExitNotify(const ProcessMessage &message); void ExecNotify(const ProcessMessage &message); - lldb_private::Unwind *GetUnwinder() override; - // FreeBSDThread internal API. // POSIXThread override diff --git a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp index 71f012944a9..4e6f3afda0a 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp @@ -1,4 +1,4 @@ -//===-- POSIXStopInfo.cpp ---------------------------------------*- C++ -*-===// +//===-- POSIXStopInfo.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp index 32e3320150f..a44080640f6 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp @@ -1,5 +1,4 @@ -//===-- ProcessFreeBSD.cpp ----------------------------------------*- C++ -//-*-===// +//===-- ProcessFreeBSD.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -57,6 +56,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(ProcessFreeBSD) + namespace { UnixSignalsSP &GetFreeBSDSignals() { static UnixSignalsSP s_freebsd_signals_sp(new FreeBSDSignals()); @@ -379,7 +380,8 @@ 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)}; + const FileSpec dbg_pts_file_spec{ + launch_info.GetPTY().GetSecondaryName(NULL, 0)}; file_action = launch_info.GetFileActionForFD(STDIN_FILENO); stdin_file_spec = diff --git a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp index ff3fb0a75e2..6a9209d1214 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp @@ -1,4 +1,4 @@ -//===-- ProcessMonitor.cpp ------------------------------------ -*- C++ -*-===// +//===-- ProcessMonitor.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -855,7 +855,7 @@ bool ProcessMonitor::Launch(LaunchArgs *args) { // terminal has already dupped the tty descriptors to stdin/out/err. This // closes original fd from which they were copied (and avoids leaking // descriptors to the debugged process. - terminal.CloseSlaveFileDescriptor(); + terminal.CloseSecondaryFileDescriptor(); // Do not inherit setgid powers. if (setgid(getgid()) != 0) @@ -939,7 +939,7 @@ bool ProcessMonitor::Launch(LaunchArgs *args) { #endif // Release the master terminal descriptor and pass it off to the // ProcessMonitor instance. Similarly stash the inferior pid. - monitor->m_terminal_fd = terminal.ReleaseMasterFileDescriptor(); + monitor->m_terminal_fd = terminal.ReleasePrimaryFileDescriptor(); monitor->m_pid = pid; // Set the terminal fd to be in non blocking mode (it simplifies the diff --git a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp index f0c4526357c..4216f68faf5 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIXProcessMonitor_arm.cpp -----------*- C++ -*-===// +//===-- RegisterContextPOSIXProcessMonitor_arm.cpp ------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp index 147f4b56a80..d3eafae1e6d 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIXProcessMonitor_arm64.cpp -----------*- C++ -*-===// +//===-- RegisterContextPOSIXProcessMonitor_arm64.cpp ----------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -22,9 +22,9 @@ using namespace lldb_private; RegisterContextPOSIXProcessMonitor_arm64:: RegisterContextPOSIXProcessMonitor_arm64( - lldb_private::Thread &thread, uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info) - : RegisterContextPOSIX_arm64(thread, concrete_frame_idx, register_info) {} + lldb_private::Thread &thread, + std::unique_ptr register_info) + : RegisterContextPOSIX_arm64(thread, std::move(register_info)) {} ProcessMonitor &RegisterContextPOSIXProcessMonitor_arm64::GetMonitor() { lldb::ProcessSP base = CalculateProcess(); diff --git a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h index d54d34e89ca..f100d905e28 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h @@ -17,8 +17,8 @@ class RegisterContextPOSIXProcessMonitor_arm64 public POSIXBreakpointProtocol { public: RegisterContextPOSIXProcessMonitor_arm64( - lldb_private::Thread &thread, uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info); + lldb_private::Thread &thread, + std::unique_ptr register_info); protected: bool ReadGPR(); diff --git a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp index db9b5a6a038..23c76f234c8 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIXProcessMonitor_mips64.cpp -----------*- C++ -*-===// +//===-- RegisterContextPOSIXProcessMonitor_mips64.cpp ---------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp index 77694733fa3..f8342775a81 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIXProcessMonitor_powerpc.cpp ----------*- C++ -*-===// +//===-- RegisterContextPOSIXProcessMonitor_powerpc.cpp --------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp index 3046d97f153..b1739e1e3bd 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIXProcessMonitor_x86.cpp --------------*- C++ -*-===// +//===-- RegisterContextPOSIXProcessMonitor_x86.cpp ------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Linux/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Process/Linux/CMakeLists.txt index b4b4c401a27..dd2a88957f4 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Linux/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/Process/Linux/CMakeLists.txt @@ -1,4 +1,4 @@ -add_lldb_library(lldbPluginProcessLinux PLUGIN +add_lldb_library(lldbPluginProcessLinux NativeProcessLinux.cpp NativeRegisterContextLinux.cpp NativeRegisterContextLinux_arm.cpp diff --git a/gnu/llvm/lldb/source/Plugins/Process/Linux/LinuxPTraceDefines_arm64sve.h b/gnu/llvm/lldb/source/Plugins/Process/Linux/LinuxPTraceDefines_arm64sve.h new file mode 100644 index 00000000000..18ba39d55b1 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/Process/Linux/LinuxPTraceDefines_arm64sve.h @@ -0,0 +1,253 @@ +//===-- LinuxPTraceDefines_arm64sve.h ------------------------- -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_LinuxPTraceDefines_arm64sve_h +#define lldb_LinuxPTraceDefines_arm64sve_h + +#define SVE_MAGIC 0x53564501 + +struct sve_context { + struct _aarch64_ctx head; + __u16 vl; + __u16 __reserved[3]; +}; + +/* + * The SVE architecture leaves space for future expansion of the + * vector length beyond its initial architectural limit of 2048 bits + * (16 quadwords). + * + * See linux/Documentation/arm64/sve.txt for a description of the VL/VQ + * terminology. + */ +#define SVE_VQ_BYTES 16 /* number of bytes per quadword */ + +#define SVE_VQ_MIN 1 +#define SVE_VQ_MAX 512 + +#define SVE_VL_MIN (SVE_VQ_MIN * SVE_VQ_BYTES) +#define SVE_VL_MAX (SVE_VQ_MAX * SVE_VQ_BYTES) + +#define SVE_NUM_ZREGS 32 +#define SVE_NUM_PREGS 16 + +#define sve_vl_valid(vl) \ + ((vl) % SVE_VQ_BYTES == 0 && (vl) >= SVE_VL_MIN && (vl) <= SVE_VL_MAX) +#define sve_vq_from_vl(vl) ((vl) / SVE_VQ_BYTES) +#define sve_vl_from_vq(vq) ((vq)*SVE_VQ_BYTES) + +/* + * If the SVE registers are currently live for the thread at signal delivery, + * sve_context.head.size >= + * SVE_SIG_CONTEXT_SIZE(sve_vq_from_vl(sve_context.vl)) + * and the register data may be accessed using the SVE_SIG_*() macros. + * + * If sve_context.head.size < + * SVE_SIG_CONTEXT_SIZE(sve_vq_from_vl(sve_context.vl)), + * the SVE registers were not live for the thread and no register data + * is included: in this case, the SVE_SIG_*() macros should not be + * used except for this check. + * + * The same convention applies when returning from a signal: a caller + * will need to remove or resize the sve_context block if it wants to + * make the SVE registers live when they were previously non-live or + * vice-versa. This may require the the caller to allocate fresh + * memory and/or move other context blocks in the signal frame. + * + * Changing the vector length during signal return is not permitted: + * sve_context.vl must equal the thread's current vector length when + * doing a sigreturn. + * + * + * Note: for all these macros, the "vq" argument denotes the SVE + * vector length in quadwords (i.e., units of 128 bits). + * + * The correct way to obtain vq is to use sve_vq_from_vl(vl). The + * result is valid if and only if sve_vl_valid(vl) is true. This is + * guaranteed for a struct sve_context written by the kernel. + * + * + * Additional macros describe the contents and layout of the payload. + * For each, SVE_SIG_x_OFFSET(args) is the start offset relative to + * the start of struct sve_context, and SVE_SIG_x_SIZE(args) is the + * size in bytes: + * + * x type description + * - ---- ----------- + * REGS the entire SVE context + * + * ZREGS __uint128_t[SVE_NUM_ZREGS][vq] all Z-registers + * ZREG __uint128_t[vq] individual Z-register Zn + * + * PREGS uint16_t[SVE_NUM_PREGS][vq] all P-registers + * PREG uint16_t[vq] individual P-register Pn + * + * FFR uint16_t[vq] first-fault status register + * + * Additional data might be appended in the future. + */ + +#define SVE_SIG_ZREG_SIZE(vq) ((__u32)(vq)*SVE_VQ_BYTES) +#define SVE_SIG_PREG_SIZE(vq) ((__u32)(vq) * (SVE_VQ_BYTES / 8)) +#define SVE_SIG_FFR_SIZE(vq) SVE_SIG_PREG_SIZE(vq) + +#define SVE_SIG_REGS_OFFSET \ + ((sizeof(struct sve_context) + (SVE_VQ_BYTES - 1)) / SVE_VQ_BYTES * \ + SVE_VQ_BYTES) + +#define SVE_SIG_ZREGS_OFFSET SVE_SIG_REGS_OFFSET +#define SVE_SIG_ZREG_OFFSET(vq, n) \ + (SVE_SIG_ZREGS_OFFSET + SVE_SIG_ZREG_SIZE(vq) * (n)) +#define SVE_SIG_ZREGS_SIZE(vq) \ + (SVE_SIG_ZREG_OFFSET(vq, SVE_NUM_ZREGS) - SVE_SIG_ZREGS_OFFSET) + +#define SVE_SIG_PREGS_OFFSET(vq) (SVE_SIG_ZREGS_OFFSET + SVE_SIG_ZREGS_SIZE(vq)) +#define SVE_SIG_PREG_OFFSET(vq, n) \ + (SVE_SIG_PREGS_OFFSET(vq) + SVE_SIG_PREG_SIZE(vq) * (n)) +#define SVE_SIG_PREGS_SIZE(vq) \ + (SVE_SIG_PREG_OFFSET(vq, SVE_NUM_PREGS) - SVE_SIG_PREGS_OFFSET(vq)) + +#define SVE_SIG_FFR_OFFSET(vq) \ + (SVE_SIG_PREGS_OFFSET(vq) + SVE_SIG_PREGS_SIZE(vq)) + +#define SVE_SIG_REGS_SIZE(vq) \ + (SVE_SIG_FFR_OFFSET(vq) + SVE_SIG_FFR_SIZE(vq) - SVE_SIG_REGS_OFFSET) + +#define SVE_SIG_CONTEXT_SIZE(vq) (SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq)) + +/* SVE/FP/SIMD state (NT_ARM_SVE) */ + +struct user_sve_header { + __u32 size; /* total meaningful regset content in bytes */ + __u32 max_size; /* maxmium possible size for this thread */ + __u16 vl; /* current vector length */ + __u16 max_vl; /* maximum possible vector length */ + __u16 flags; + __u16 __reserved; +}; + +/* Definitions for user_sve_header.flags: */ +#define SVE_PT_REGS_MASK (1 << 0) + +#define SVE_PT_REGS_FPSIMD 0 +#define SVE_PT_REGS_SVE SVE_PT_REGS_MASK + +/* + * Common SVE_PT_* flags: + * These must be kept in sync with prctl interface in + */ +#define SVE_PT_VL_INHERIT (PR_SVE_VL_INHERIT >> 16) +#define SVE_PT_VL_ONEXEC (PR_SVE_SET_VL_ONEXEC >> 16) + +/* + * The remainder of the SVE state follows struct user_sve_header. The + * total size of the SVE state (including header) depends on the + * metadata in the header: SVE_PT_SIZE(vq, flags) gives the total size + * of the state in bytes, including the header. + * + * Refer to for details of how to pass the correct + * "vq" argument to these macros. + */ + +/* Offset from the start of struct user_sve_header to the register data */ +#define SVE_PT_REGS_OFFSET \ + ((sizeof(struct sve_context) + (SVE_VQ_BYTES - 1)) / SVE_VQ_BYTES * \ + SVE_VQ_BYTES) + +/* + * The register data content and layout depends on the value of the + * flags field. + */ + +/* + * (flags & SVE_PT_REGS_MASK) == SVE_PT_REGS_FPSIMD case: + * + * The payload starts at offset SVE_PT_FPSIMD_OFFSET, and is of type + * struct user_fpsimd_state. Additional data might be appended in the + * future: use SVE_PT_FPSIMD_SIZE(vq, flags) to compute the total size. + * SVE_PT_FPSIMD_SIZE(vq, flags) will never be less than + * sizeof(struct user_fpsimd_state). + */ + +#define SVE_PT_FPSIMD_OFFSET SVE_PT_REGS_OFFSET + +#define SVE_PT_FPSIMD_SIZE(vq, flags) (sizeof(struct user_fpsimd_state)) + +/* + * (flags & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE case: + * + * The payload starts at offset SVE_PT_SVE_OFFSET, and is of size + * SVE_PT_SVE_SIZE(vq, flags). + * + * Additional macros describe the contents and layout of the payload. + * For each, SVE_PT_SVE_x_OFFSET(args) is the start offset relative to + * the start of struct user_sve_header, and SVE_PT_SVE_x_SIZE(args) is + * the size in bytes: + * + * x type description + * - ---- ----------- + * ZREGS \ + * ZREG | + * PREGS | refer to + * PREG | + * FFR / + * + * FPSR uint32_t FPSR + * FPCR uint32_t FPCR + * + * Additional data might be appended in the future. + */ + +#define SVE_PT_SVE_ZREG_SIZE(vq) SVE_SIG_ZREG_SIZE(vq) +#define SVE_PT_SVE_PREG_SIZE(vq) SVE_SIG_PREG_SIZE(vq) +#define SVE_PT_SVE_FFR_SIZE(vq) SVE_SIG_FFR_SIZE(vq) +#define SVE_PT_SVE_FPSR_SIZE sizeof(__u32) +#define SVE_PT_SVE_FPCR_SIZE sizeof(__u32) + +#define __SVE_SIG_TO_PT(offset) \ + ((offset)-SVE_SIG_REGS_OFFSET + SVE_PT_REGS_OFFSET) + +#define SVE_PT_SVE_OFFSET SVE_PT_REGS_OFFSET + +#define SVE_PT_SVE_ZREGS_OFFSET __SVE_SIG_TO_PT(SVE_SIG_ZREGS_OFFSET) +#define SVE_PT_SVE_ZREG_OFFSET(vq, n) \ + __SVE_SIG_TO_PT(SVE_SIG_ZREG_OFFSET(vq, n)) +#define SVE_PT_SVE_ZREGS_SIZE(vq) \ + (SVE_PT_SVE_ZREG_OFFSET(vq, SVE_NUM_ZREGS) - SVE_PT_SVE_ZREGS_OFFSET) + +#define SVE_PT_SVE_PREGS_OFFSET(vq) __SVE_SIG_TO_PT(SVE_SIG_PREGS_OFFSET(vq)) +#define SVE_PT_SVE_PREG_OFFSET(vq, n) \ + __SVE_SIG_TO_PT(SVE_SIG_PREG_OFFSET(vq, n)) +#define SVE_PT_SVE_PREGS_SIZE(vq) \ + (SVE_PT_SVE_PREG_OFFSET(vq, SVE_NUM_PREGS) - SVE_PT_SVE_PREGS_OFFSET(vq)) + +#define SVE_PT_SVE_FFR_OFFSET(vq) __SVE_SIG_TO_PT(SVE_SIG_FFR_OFFSET(vq)) + +#define SVE_PT_SVE_FPSR_OFFSET(vq) \ + ((SVE_PT_SVE_FFR_OFFSET(vq) + SVE_PT_SVE_FFR_SIZE(vq) + \ + (SVE_VQ_BYTES - 1)) / \ + SVE_VQ_BYTES * SVE_VQ_BYTES) +#define SVE_PT_SVE_FPCR_OFFSET(vq) \ + (SVE_PT_SVE_FPSR_OFFSET(vq) + SVE_PT_SVE_FPSR_SIZE) + +/* + * Any future extension appended after FPCR must be aligned to the next + * 128-bit boundary. + */ + +#define SVE_PT_SVE_SIZE(vq, flags) \ + ((SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE - SVE_PT_SVE_OFFSET + \ + (SVE_VQ_BYTES - 1)) / \ + SVE_VQ_BYTES * SVE_VQ_BYTES) + +#define SVE_PT_SIZE(vq, flags) \ + (((flags)&SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE \ + ? SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, flags) \ + : SVE_PT_FPSIMD_OFFSET + SVE_PT_FPSIMD_SIZE(vq, flags)) + +#endif diff --git a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp index 32be0ca6091..79d803de158 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -1,4 +1,4 @@ -//===-- NativeProcessLinux.cpp -------------------------------- -*- C++ -*-===// +//===-- NativeProcessLinux.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -256,7 +256,7 @@ NativeProcessLinux::Factory::Launch(ProcessLaunchInfo &launch_info, } return std::unique_ptr(new NativeProcessLinux( - pid, launch_info.GetPTY().ReleaseMasterFileDescriptor(), native_delegate, + pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), native_delegate, Info.GetArchitecture(), mainloop, {pid})); } diff --git a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp index 3186b6cf39a..1b9e067639c 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextLinux.cpp --------------------------*- C++ -*-===// +//===-- NativeRegisterContextLinux.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h index 9a89a13f5f5..da7a762419f 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h @@ -55,7 +55,7 @@ protected: virtual void *GetGPRBuffer() = 0; - virtual size_t GetGPRSize() { + virtual size_t GetGPRSize() const { return GetRegisterInfoInterface().GetGPRSize(); } diff --git a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp index f9002cce251..a83491e6d89 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextLinux_arm.cpp --------------------*- C++ -*-===// +//===-- NativeRegisterContextLinux_arm.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -566,7 +566,7 @@ uint32_t NativeRegisterContextLinux_arm::SetHardwareWatchpoint( // Check 4-byte alignment for hardware watchpoint target address. Below is a // hack to recalculate address and size in order to make sure we can watch - // non 4-byte alligned addresses as well. + // non 4-byte aligned addresses as well. if (addr & 0x03) { uint8_t watch_mask = (addr & 0x03) + size; @@ -861,7 +861,7 @@ Status NativeRegisterContextLinux_arm::DoReadRegisterValue( // PTRACE_PEEKUSER don't work in the aarch64 linux kernel used on android // devices (always return "Bad address"). To avoid using PTRACE_PEEKUSER we // read out the full GPR register set instead. This approach is about 4 times - // slower but the performance overhead is negligible in comparision to + // slower but the performance overhead is negligible in comparison to // processing time in lldb-server. assert(offset % 4 == 0 && "Try to write a register with unaligned offset"); if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm)) @@ -881,7 +881,7 @@ Status NativeRegisterContextLinux_arm::DoWriteRegisterValue( // devices (always return "Bad address"). To avoid using PTRACE_POKEUSER we // read out the full GPR register set, modify the requested register and // write it back. This approach is about 4 times slower but the performance - // overhead is negligible in comparision to processing time in lldb-server. + // overhead is negligible in comparison to processing time in lldb-server. assert(offset % 4 == 0 && "Try to write a register with unaligned offset"); if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm)) return Status("Register isn't fit into the size of the GPR area"); diff --git a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp index ea7337b632e..beae3aef7c0 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextLinux_arm64.cpp --------------------*- C++ -*-===// +//===-- NativeRegisterContextLinux_arm64.cpp ------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -21,7 +21,6 @@ #include "Plugins/Process/Linux/NativeProcessLinux.h" #include "Plugins/Process/Linux/Procfs.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" -#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" // System includes - They have to be included after framework includes because // they define some macros which collide with variable names in other modules @@ -37,76 +36,6 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::process_linux; -// ARM64 general purpose registers. -static const uint32_t g_gpr_regnums_arm64[] = { - gpr_x0_arm64, gpr_x1_arm64, gpr_x2_arm64, gpr_x3_arm64, - gpr_x4_arm64, gpr_x5_arm64, gpr_x6_arm64, gpr_x7_arm64, - gpr_x8_arm64, gpr_x9_arm64, gpr_x10_arm64, gpr_x11_arm64, - gpr_x12_arm64, gpr_x13_arm64, gpr_x14_arm64, gpr_x15_arm64, - gpr_x16_arm64, gpr_x17_arm64, gpr_x18_arm64, gpr_x19_arm64, - gpr_x20_arm64, gpr_x21_arm64, gpr_x22_arm64, gpr_x23_arm64, - gpr_x24_arm64, gpr_x25_arm64, gpr_x26_arm64, gpr_x27_arm64, - gpr_x28_arm64, gpr_fp_arm64, gpr_lr_arm64, gpr_sp_arm64, - gpr_pc_arm64, gpr_cpsr_arm64, gpr_w0_arm64, gpr_w1_arm64, - gpr_w2_arm64, gpr_w3_arm64, gpr_w4_arm64, gpr_w5_arm64, - gpr_w6_arm64, gpr_w7_arm64, gpr_w8_arm64, gpr_w9_arm64, - gpr_w10_arm64, gpr_w11_arm64, gpr_w12_arm64, gpr_w13_arm64, - gpr_w14_arm64, gpr_w15_arm64, gpr_w16_arm64, gpr_w17_arm64, - gpr_w18_arm64, gpr_w19_arm64, gpr_w20_arm64, gpr_w21_arm64, - gpr_w22_arm64, gpr_w23_arm64, gpr_w24_arm64, gpr_w25_arm64, - gpr_w26_arm64, gpr_w27_arm64, gpr_w28_arm64, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; -static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) - - 1) == k_num_gpr_registers_arm64, - "g_gpr_regnums_arm64 has wrong number of register infos"); - -// ARM64 floating point registers. -static const uint32_t g_fpu_regnums_arm64[] = { - fpu_v0_arm64, fpu_v1_arm64, fpu_v2_arm64, fpu_v3_arm64, - fpu_v4_arm64, fpu_v5_arm64, fpu_v6_arm64, fpu_v7_arm64, - fpu_v8_arm64, fpu_v9_arm64, fpu_v10_arm64, fpu_v11_arm64, - fpu_v12_arm64, fpu_v13_arm64, fpu_v14_arm64, fpu_v15_arm64, - fpu_v16_arm64, fpu_v17_arm64, fpu_v18_arm64, fpu_v19_arm64, - fpu_v20_arm64, fpu_v21_arm64, fpu_v22_arm64, fpu_v23_arm64, - fpu_v24_arm64, fpu_v25_arm64, fpu_v26_arm64, fpu_v27_arm64, - fpu_v28_arm64, fpu_v29_arm64, fpu_v30_arm64, fpu_v31_arm64, - fpu_s0_arm64, fpu_s1_arm64, fpu_s2_arm64, fpu_s3_arm64, - fpu_s4_arm64, fpu_s5_arm64, fpu_s6_arm64, fpu_s7_arm64, - fpu_s8_arm64, fpu_s9_arm64, fpu_s10_arm64, fpu_s11_arm64, - fpu_s12_arm64, fpu_s13_arm64, fpu_s14_arm64, fpu_s15_arm64, - fpu_s16_arm64, fpu_s17_arm64, fpu_s18_arm64, fpu_s19_arm64, - fpu_s20_arm64, fpu_s21_arm64, fpu_s22_arm64, fpu_s23_arm64, - fpu_s24_arm64, fpu_s25_arm64, fpu_s26_arm64, fpu_s27_arm64, - fpu_s28_arm64, fpu_s29_arm64, fpu_s30_arm64, fpu_s31_arm64, - - fpu_d0_arm64, fpu_d1_arm64, fpu_d2_arm64, fpu_d3_arm64, - fpu_d4_arm64, fpu_d5_arm64, fpu_d6_arm64, fpu_d7_arm64, - fpu_d8_arm64, fpu_d9_arm64, fpu_d10_arm64, fpu_d11_arm64, - fpu_d12_arm64, fpu_d13_arm64, fpu_d14_arm64, fpu_d15_arm64, - fpu_d16_arm64, fpu_d17_arm64, fpu_d18_arm64, fpu_d19_arm64, - fpu_d20_arm64, fpu_d21_arm64, fpu_d22_arm64, fpu_d23_arm64, - fpu_d24_arm64, fpu_d25_arm64, fpu_d26_arm64, fpu_d27_arm64, - fpu_d28_arm64, fpu_d29_arm64, fpu_d30_arm64, fpu_d31_arm64, - fpu_fpsr_arm64, fpu_fpcr_arm64, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; -static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) - - 1) == k_num_fpr_registers_arm64, - "g_fpu_regnums_arm64 has wrong number of register infos"); - -namespace { -// Number of register sets provided by this context. -enum { k_num_register_sets = 2 }; -} - -// Register sets for ARM64. -static const RegisterSet g_reg_sets_arm64[k_num_register_sets] = { - {"General Purpose Registers", "gpr", k_num_gpr_registers_arm64, - g_gpr_regnums_arm64}, - {"Floating Point Registers", "fpu", k_num_fpr_registers_arm64, - g_fpu_regnums_arm64}}; - std::unique_ptr NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux( const ArchSpec &target_arch, NativeThreadProtocol &native_thread) { @@ -126,23 +55,6 @@ NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64( const ArchSpec &target_arch, NativeThreadProtocol &native_thread) : NativeRegisterContextLinux(native_thread, new RegisterInfoPOSIX_arm64(target_arch)) { - switch (target_arch.GetMachine()) { - case llvm::Triple::aarch64: - m_reg_info.num_registers = k_num_registers_arm64; - m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64; - m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64; - m_reg_info.last_gpr = k_last_gpr_arm64; - m_reg_info.first_fpr = k_first_fpr_arm64; - m_reg_info.last_fpr = k_last_fpr_arm64; - m_reg_info.first_fpr_v = fpu_v0_arm64; - m_reg_info.last_fpr_v = fpu_v31_arm64; - m_reg_info.gpr_flags = gpr_cpsr_arm64; - break; - default: - llvm_unreachable("Unhandled target architecture."); - break; - } - ::memset(&m_fpr, 0, sizeof(m_fpr)); ::memset(&m_gpr_arm64, 0, sizeof(m_gpr_arm64)); ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs)); @@ -157,22 +69,24 @@ NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64( m_fpu_is_valid = false; } +RegisterInfoPOSIX_arm64 & +NativeRegisterContextLinux_arm64::GetRegisterInfo() const { + return static_cast(*m_register_info_interface_up); +} + uint32_t NativeRegisterContextLinux_arm64::GetRegisterSetCount() const { - return k_num_register_sets; + return GetRegisterInfo().GetRegisterSetCount(); } const RegisterSet * NativeRegisterContextLinux_arm64::GetRegisterSet(uint32_t set_index) const { - if (set_index < k_num_register_sets) - return &g_reg_sets_arm64[set_index]; - - return nullptr; + return GetRegisterInfo().GetRegisterSet(set_index); } uint32_t NativeRegisterContextLinux_arm64::GetUserRegisterCount() const { uint32_t count = 0; - for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) - count += g_reg_sets_arm64[set_index].num_registers; + for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index) + count += GetRegisterSet(set_index)->num_registers; return count; } @@ -344,11 +258,17 @@ Status NativeRegisterContextLinux_arm64::WriteAllRegisterValues( } bool NativeRegisterContextLinux_arm64::IsGPR(unsigned reg) const { - return reg <= m_reg_info.last_gpr; // GPR's come first. + if (GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) == + RegisterInfoPOSIX_arm64::GPRegSet) + return true; + return false; } bool NativeRegisterContextLinux_arm64::IsFPR(unsigned reg) const { - return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr); + if (GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) == + RegisterInfoPOSIX_arm64::FPRegSet) + return true; + return false; } uint32_t NativeRegisterContextLinux_arm64::NumSupportedHardwareBreakpoints() { @@ -571,7 +491,7 @@ uint32_t NativeRegisterContextLinux_arm64::SetHardwareWatchpoint( // Check 8-byte alignment for hardware watchpoint target address. Below is a // hack to recalculate address and size in order to make sure we can watch - // non 8-byte alligned addresses as well. + // non 8-byte aligned addresses as well. if (addr & 0x07) { uint8_t watch_mask = (addr & 0x07) + size; @@ -900,8 +820,7 @@ void NativeRegisterContextLinux_arm64::InvalidateAllRegisters() { uint32_t NativeRegisterContextLinux_arm64::CalculateFprOffset( const RegisterInfo *reg_info) const { - return reg_info->byte_offset - - GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset; + return reg_info->byte_offset - GetGPRSize(); } #endif // defined (__arm64__) || defined (__aarch64__) diff --git a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h index f7c501a9fdf..0fbbea51d21 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h @@ -12,7 +12,7 @@ #define lldb_NativeRegisterContextLinux_arm64_h #include "Plugins/Process/Linux/NativeRegisterContextLinux.h" -#include "Plugins/Process/Utility/lldb-arm64-register-enums.h" +#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" namespace lldb_private { namespace process_linux { @@ -95,47 +95,13 @@ protected: size_t GetFPRSize() override { return sizeof(m_fpr); } private: - struct RegInfo { - uint32_t num_registers; - uint32_t num_gpr_registers; - uint32_t num_fpr_registers; - - uint32_t last_gpr; - uint32_t first_fpr; - uint32_t last_fpr; - - uint32_t first_fpr_v; - uint32_t last_fpr_v; - - uint32_t gpr_flags; - }; - - // based on RegisterContextDarwin_arm64.h - struct VReg { - uint8_t bytes[16]; - }; - - // based on RegisterContextDarwin_arm64.h - struct FPU { - VReg v[32]; - uint32_t fpsr; - uint32_t fpcr; - }; - - struct GPR { - uint64_t x[31]; - uint64_t sp; - uint64_t pc; - uint64_t pstate; - }; - bool m_gpr_is_valid; bool m_fpu_is_valid; - GPR m_gpr_arm64; // 64-bit general purpose registers. - RegInfo m_reg_info; - FPU m_fpr; // floating-point registers including extended register sets. + RegisterInfoPOSIX_arm64::GPR m_gpr_arm64; // 64-bit general purpose registers. + RegisterInfoPOSIX_arm64::FPU + m_fpr; // floating-point registers including extended register sets. // Debug register info for hardware breakpoints and watchpoints management. struct DREG { lldb::addr_t address; // Breakpoint/watchpoint address value. @@ -162,6 +128,8 @@ private: Status WriteHardwareDebugRegs(int hwbType); uint32_t CalculateFprOffset(const RegisterInfo *reg_info) const; + + RegisterInfoPOSIX_arm64 &GetRegisterInfo() const; }; } // namespace process_linux diff --git a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp index d456cbb0565..b0a4ad94ce0 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextLinux_mips64.cpp ---------------*- C++ -*-===// +//===-- NativeRegisterContextLinux_mips64.cpp -----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -679,7 +679,7 @@ static int GetVacantWatchIndex(struct pt_watch_regs *regs, lldb::addr_t addr, } if (vacant_watches > 1) { - // Split this watchpoint accross several registers + // Split this watchpoint across several registers struct pt_watch_regs regs_copy; regs_copy = *regs; lldb::addr_t break_addr; diff --git a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp index 2eb60cf1c16..6d1a15a0b70 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextLinux_ppc64le.cpp ------------------*- C++ -*-===// +//===-- NativeRegisterContextLinux_ppc64le.cpp ----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -552,7 +552,7 @@ uint32_t NativeRegisterContextLinux_ppc64le::SetHardwareWatchpoint( // Check 8-byte alignment for hardware watchpoint target address. Below is a // hack to recalculate address and size in order to make sure we can watch - // non 8-byte alligned addresses as well. + // non 8-byte aligned addresses as well. if (addr & 0x07) { addr_t begin = llvm::alignDown(addr, 8); diff --git a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp index 966147bf98e..c72b89a519f 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextLinux_s390x.cpp --------------------*- C++ -*-===// +//===-- NativeRegisterContextLinux_s390x.cpp ------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h index 69714e40011..5ed78810a18 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h @@ -76,7 +76,7 @@ protected: Status WriteFPR() override; void *GetGPRBuffer() override { return &m_regs; } - size_t GetGPRSize() override { return sizeof(m_regs); } + size_t GetGPRSize() const override { return sizeof(m_regs); } void *GetFPRBuffer() override { return &m_fp_regs; } size_t GetFPRSize() override { return sizeof(m_fp_regs); } diff --git a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp index 0818630db62..f9a3c221227 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextLinux_x86_64.cpp ---------------*- C++ -*-===// +//===-- NativeRegisterContextLinux_x86_64.cpp -----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp index b2730e60129..14eea2df381 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp @@ -1,4 +1,4 @@ -//===-- NativeThreadLinux.cpp --------------------------------- -*- C++ -*-===// +//===-- NativeThreadLinux.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -99,7 +99,7 @@ std::string NativeThreadLinux::GetName() { auto BufferOrError = getProcFile(process.GetID(), GetID(), "comm"); if (!BufferOrError) return ""; - return BufferOrError.get()->getBuffer().rtrim('\n'); + return std::string(BufferOrError.get()->getBuffer().rtrim('\n')); } lldb::StateType NativeThreadLinux::GetState() { return m_state; } diff --git a/gnu/llvm/lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp b/gnu/llvm/lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp index a7e8c00f0fe..4817ef2ac3e 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp @@ -1,4 +1,4 @@ -//===-- ProcessorTrace.cpp ------------------------------------ -*- C++ -*-===// +//===-- ProcessorTrace.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Linux/SingleStepCheck.cpp b/gnu/llvm/lldb/source/Plugins/Process/Linux/SingleStepCheck.cpp index a3b89c5013d..f0c6bdc6cf8 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Linux/SingleStepCheck.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Linux/SingleStepCheck.cpp @@ -1,4 +1,4 @@ -//===-- SingleStepCheck.cpp ----------------------------------- -*- C++ -*-===// +//===-- SingleStepCheck.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp index 5737efd1d6e..06190d0c036 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp @@ -1,4 +1,4 @@ -//===-- CommunicationKDP.cpp ------------------------------------*- C++ -*-===// +//===-- CommunicationKDP.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -77,11 +77,9 @@ bool CommunicationKDP::SendRequestAndGetReply( } std::lock_guard guard(m_sequence_mutex); -#ifdef LLDB_CONFIGURATION_DEBUG // NOTE: this only works for packets that are in native endian byte order assert(request_packet.GetSize() == *((const uint16_t *)(request_packet.GetData() + 2))); -#endif lldb::offset_t offset = 1; const uint32_t num_retries = 3; for (uint32_t i = 0; i < num_retries; ++i) { @@ -306,7 +304,7 @@ bool CommunicationKDP::CheckForPacket(const uint8_t *src, size_t src_len, if (length <= bytes_available) { // We have an entire packet ready, we need to copy the data bytes into // a buffer that will be owned by the packet and erase the bytes from - // our communcation buffer "m_bytes" + // our communication buffer "m_bytes" packet.SetData(DataBufferSP(new DataBufferHeap(&m_bytes[0], length))); m_bytes.erase(0, length); @@ -447,7 +445,7 @@ lldb_private::UUID CommunicationKDP::GetUUID() { if (uuid_str.size() < 32) return uuid; - if (uuid.SetFromStringRef(uuid_str) == 0) { + if (!uuid.SetFromStringRef(uuid_str)) { UUID invalid_uuid; return invalid_uuid; } @@ -788,7 +786,7 @@ void CommunicationKDP::DumpPacket(Stream &s, const DataExtractor &packet) { const uint32_t region_count = packet.GetU32(&offset); s.Printf(" (count = %u", region_count); for (uint32_t i = 0; i < region_count; ++i) { - const addr_t region_addr = packet.GetPointer(&offset); + const addr_t region_addr = packet.GetAddress(&offset); const uint32_t region_size = packet.GetU32(&offset); const uint32_t region_prot = packet.GetU32(&offset); s.Printf("\n\tregion[%" PRIu64 "] = { range = [0x%16.16" PRIx64 diff --git a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h index 47013c97209..d04765f9d86 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h +++ b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommunicationKDP_h_ -#define liblldb_CommunicationKDP_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_COMMUNICATIONKDP_H +#define LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_COMMUNICATIONKDP_H #include #include @@ -241,7 +241,8 @@ protected: lldb::addr_t m_last_read_memory_addr; // Last memory read address for logging private: // For CommunicationKDP only - DISALLOW_COPY_AND_ASSIGN(CommunicationKDP); + CommunicationKDP(const CommunicationKDP &) = delete; + const CommunicationKDP &operator=(const CommunicationKDP &) = delete; }; -#endif // liblldb_CommunicationKDP_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_COMMUNICATIONKDP_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp index 491c0b012b0..2f4a8917a78 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp @@ -1,4 +1,4 @@ -//===-- ProcessKDP.cpp ------------------------------------------*- C++ -*-===// +//===-- ProcessKDP.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -50,6 +50,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE_ADV(ProcessKDP, ProcessMacOSXKernel) + namespace { #define LLDB_PROPERTIES_processkdp @@ -215,7 +217,7 @@ bool ProcessKDP::GetHostArchitecture(ArchSpec &arch) { return false; } -Status ProcessKDP::DoConnectRemote(Stream *strm, llvm::StringRef remote_url) { +Status ProcessKDP::DoConnectRemote(llvm::StringRef remote_url) { Status error; // Don't let any JIT happen when doing KDP as we can't allocate memory and we @@ -248,7 +250,7 @@ Status ProcessKDP::DoConnectRemote(Stream *strm, llvm::StringRef remote_url) { const uint16_t reply_port = socket.GetLocalPortNumber(); if (reply_port != 0) { - m_comm.SetConnection(conn_up.release()); + m_comm.SetConnection(std::move(conn_up)); if (m_comm.SendRequestReattach(reply_port)) { if (m_comm.SendRequestConnect(reply_port, reply_port, diff --git a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h index a7f8466f984..52af5613440 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h +++ b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ProcessKDP_h_ -#define liblldb_ProcessKDP_h_ - +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_PROCESSKDP_H +#define LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_PROCESSKDP_H #include #include @@ -68,8 +67,7 @@ public: WillAttachToProcessWithName(const char *process_name, bool wait_for_launch) override; - lldb_private::Status DoConnectRemote(lldb_private::Stream *strm, - llvm::StringRef remote_url) override; + lldb_private::Status DoConnectRemote(llvm::StringRef remote_url) override; lldb_private::Status DoAttachToProcessWithID( lldb::pid_t pid, @@ -187,7 +185,8 @@ protected: private: // For ProcessKDP only - DISALLOW_COPY_AND_ASSIGN(ProcessKDP); + ProcessKDP(const ProcessKDP &) = delete; + const ProcessKDP &operator=(const ProcessKDP &) = delete; }; -#endif // liblldb_ProcessKDP_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_PROCESSKDP_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp index 96d2921747a..3b5f1157d54 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp @@ -1,4 +1,4 @@ -//===-- ProcessKDPLog.cpp ---------------------------------------*- C++ -*-===// +//===-- ProcessKDPLog.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h index c22dd980b6e..91b1b6e49b7 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h +++ b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ProcessKDPLog_h_ -#define liblldb_ProcessKDPLog_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_PROCESSKDPLOG_H +#define LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_PROCESSKDPLOG_H #include "lldb/Utility/Log.h" @@ -39,4 +39,4 @@ public: }; } -#endif // liblldb_ProcessKDPLog_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_PROCESSKDPLOG_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp index da6e0f5c504..81b602a2b7a 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextKDP_arm.cpp ------------------------------*- C++ -*-===// +//===-- RegisterContextKDP_arm.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h index e31da42121b..616aff8afda 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h +++ b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextKDP_arm_h_ -#define liblldb_RegisterContextKDP_arm_h_ - +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_REGISTERCONTEXTKDP_ARM_H +#define LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_REGISTERCONTEXTKDP_ARM_H #include "Plugins/Process/Utility/RegisterContextDarwin_arm.h" @@ -40,4 +39,4 @@ protected: ThreadKDP &m_kdp_thread; }; -#endif // liblldb_RegisterContextKDP_arm_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_REGISTERCONTEXTKDP_ARM_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp index f8349860612..c5e710968c3 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp @@ -1,5 +1,4 @@ -//===-- RegisterContextKDP_arm64.cpp ------------------------------*- C++ -//-*-===// +//===-- RegisterContextKDP_arm64.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h index 29dfc6789e8..998a78a6b8a 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h @@ -7,9 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextKDP_arm64_h_ -#define liblldb_RegisterContextKDP_arm64_h_ - +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_REGISTERCONTEXTKDP_ARM64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_REGISTERCONTEXTKDP_ARM64_H #include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h" @@ -41,4 +40,4 @@ protected: ThreadKDP &m_kdp_thread; }; -#endif // liblldb_RegisterContextKDP_arm64_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_REGISTERCONTEXTKDP_ARM64_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp index 7cb057d33f8..aa46e466804 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextKDP_i386.cpp -----------------------------*- C++ -*-===// +//===-- RegisterContextKDP_i386.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h index fd48fbd1948..f32c88e6cfc 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h +++ b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextKDP_i386_h_ -#define liblldb_RegisterContextKDP_i386_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_REGISTERCONTEXTKDP_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_REGISTERCONTEXTKDP_I386_H #include "Plugins/Process/Utility/RegisterContextDarwin_i386.h" @@ -35,4 +35,4 @@ protected: ThreadKDP &m_kdp_thread; }; -#endif // liblldb_RegisterContextKDP_i386_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_REGISTERCONTEXTKDP_I386_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp index 701c160dd95..565dd1c73f6 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextKDP_x86_64.cpp ---------------------------*- C++ -*-===// +//===-- RegisterContextKDP_x86_64.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h index 79623095b63..c4aad972ab5 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextKDP_x86_64_h_ -#define liblldb_RegisterContextKDP_x86_64_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_REGISTERCONTEXTKDP_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_REGISTERCONTEXTKDP_X86_64_H #include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h" @@ -35,4 +35,4 @@ protected: ThreadKDP &m_kdp_thread; }; -#endif // liblldb_RegisterContextKDP_x86_64_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_REGISTERCONTEXTKDP_X86_64_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp index 77361ef705f..a4af5e030ff 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp @@ -1,4 +1,4 @@ -//===-- ThreadKDP.cpp -------------------------------------*- C++ -*-===// +//===-- ThreadKDP.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -118,9 +118,7 @@ ThreadKDP::CreateRegisterContextForFrame(StackFrame *frame) { } } } else { - Unwind *unwinder = GetUnwinder(); - if (unwinder != nullptr) - reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame); + reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame); } return reg_ctx_sp; } diff --git a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h index 9971ea765a3..c75540a7730 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h +++ b/gnu/llvm/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadKDP_h_ -#define liblldb_ThreadKDP_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_THREADKDP_H +#define LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_THREADKDP_H #include @@ -69,4 +69,4 @@ protected: virtual bool CalculateStopInfo(); }; -#endif // liblldb_ThreadKDP_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_THREADKDP_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/NetBSD/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Process/NetBSD/CMakeLists.txt index 586725bb7a5..13f3790497b 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/NetBSD/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/Process/NetBSD/CMakeLists.txt @@ -1,4 +1,4 @@ -add_lldb_library(lldbPluginProcessNetBSD PLUGIN +add_lldb_library(lldbPluginProcessNetBSD NativeProcessNetBSD.cpp NativeRegisterContextNetBSD.cpp NativeRegisterContextNetBSD_x86_64.cpp diff --git a/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp index 4313d27e11e..5109022d80d 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp @@ -1,4 +1,4 @@ -//===-- NativeProcessNetBSD.cpp ------------------------------- -*- C++ -*-===// +//===-- NativeProcessNetBSD.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -95,7 +95,7 @@ NativeProcessNetBSD::Factory::Launch(ProcessLaunchInfo &launch_info, Info.GetArchitecture().GetArchitectureName()); std::unique_ptr process_up(new NativeProcessNetBSD( - pid, launch_info.GetPTY().ReleaseMasterFileDescriptor(), native_delegate, + pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), native_delegate, Info.GetArchitecture(), mainloop)); // Enable event reporting diff --git a/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp b/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp index a8afa0b2030..03b505c1989 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextNetBSD.cpp -------------------------*- C++ -*-===// +//===-- NativeRegisterContextNetBSD.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp index 05a35401da4..ca4706a6565 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextNetBSD_x86_64.cpp ---------------*- C++ -*-===// +//===-- NativeRegisterContextNetBSD_x86_64.cpp ----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#if defined(__x86_64__) +#if defined(__i386__) || defined(__x86_64__) #include "NativeRegisterContextNetBSD_x86_64.h" @@ -16,6 +16,7 @@ #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" +#include "Plugins/Process/Utility/RegisterContextNetBSD_i386.h" #include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h" // clang-format off @@ -135,9 +136,84 @@ static_assert((sizeof(g_dbr_regnums_x86_64) / sizeof(g_dbr_regnums_x86_64[0])) - k_num_dbr_registers_x86_64, "g_dbr_regnums_x86_64 has wrong number of register infos"); +// x86 32-bit general purpose registers. +const uint32_t g_gpr_regnums_i386[] = { + lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386, + lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386, + lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386, + lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386, + lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386, + lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386, + lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386, + lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) - + 1 == + k_num_gpr_registers_i386, + "g_gpr_regnums_i386 has wrong number of register infos"); + +// x86 32-bit floating point registers. +const uint32_t g_fpu_regnums_i386[] = { + lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386, + lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386, + lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386, + lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386, + lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386, + lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386, + lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386, + lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386, + lldb_xmm6_i386, lldb_xmm7_i386, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) - + 1 == + k_num_fpr_registers_i386, + "g_fpu_regnums_i386 has wrong number of register infos"); + +// x86 64-bit registers available via XState. +static const uint32_t g_xstate_regnums_i386[] = { + lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386, + lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386, + // Note: we currently do not provide them but this is needed to avoid + // unnamed groups in SBFrame::GetRegisterContext(). + lldb_bnd0_i386, lldb_bnd1_i386, lldb_bnd2_i386, + lldb_bnd3_i386, lldb_bndcfgu_i386, lldb_bndstatus_i386, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +static_assert((sizeof(g_xstate_regnums_i386) / sizeof(g_xstate_regnums_i386[0])) - + 1 == + k_num_avx_registers_i386 + k_num_mpx_registers_i386, + "g_xstate_regnums_i386 has wrong number of register infos"); + +// x86 debug registers. +static const uint32_t g_dbr_regnums_i386[] = { + lldb_dr0_i386, lldb_dr1_i386, lldb_dr2_i386, lldb_dr3_i386, + lldb_dr4_i386, lldb_dr5_i386, lldb_dr6_i386, lldb_dr7_i386, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +static_assert((sizeof(g_dbr_regnums_i386) / sizeof(g_dbr_regnums_i386[0])) - + 1 == + k_num_dbr_registers_i386, + "g_dbr_regnums_i386 has wrong number of register infos"); + + // Number of register sets provided by this context. enum { k_num_register_sets = 4 }; +// Register sets for x86 32-bit. +static const RegisterSet g_reg_sets_i386[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers_i386, + g_gpr_regnums_i386}, + {"Floating Point Registers", "fpu", k_num_fpr_registers_i386, + g_fpu_regnums_i386}, + {"Extended State Registers", "xstate", + k_num_avx_registers_i386 + k_num_mpx_registers_i386, + g_xstate_regnums_i386}, + {"Debug Registers", "dbr", k_num_dbr_registers_i386, + g_dbr_regnums_i386}, +}; + // Register sets for x86 64-bit. static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = { {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64, @@ -164,18 +240,23 @@ NativeRegisterContextNetBSD::CreateHostNativeRegisterContextNetBSD( static RegisterInfoInterface * CreateRegisterInfoInterface(const ArchSpec &target_arch) { - assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) && - "Register setting path assumes this is a 64-bit host"); - // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 - // register context. - return new RegisterContextNetBSD_x86_64(target_arch); + if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) { + // 32-bit hosts run with a RegisterContextNetBSD_i386 context. + return new RegisterContextNetBSD_i386(target_arch); + } else { + assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) && + "Register setting path assumes this is a 64-bit host"); + // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 + // register context. + return new RegisterContextNetBSD_x86_64(target_arch); + } } NativeRegisterContextNetBSD_x86_64::NativeRegisterContextNetBSD_x86_64( const ArchSpec &target_arch, NativeThreadProtocol &native_thread) : NativeRegisterContextNetBSD(native_thread, CreateRegisterInfoInterface(target_arch)), - m_gpr_x86_64(), m_fpr_x86_64(), m_dbr_x86_64() {} + m_gpr(), m_fpr(), m_dbr() {} // CONSIDER after local and llgs debugging are merged, register set support can // be moved into a base x86-64 class with IsRegisterSetAvailable made virtual. @@ -192,6 +273,8 @@ uint32_t NativeRegisterContextNetBSD_x86_64::GetRegisterSetCount() const { const RegisterSet * NativeRegisterContextNetBSD_x86_64::GetRegisterSet(uint32_t set_index) const { switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86: + return &g_reg_sets_i386[set_index]; case llvm::Triple::x86_64: return &g_reg_sets_x86_64[set_index]; default: @@ -202,36 +285,162 @@ NativeRegisterContextNetBSD_x86_64::GetRegisterSet(uint32_t set_index) const { return nullptr; } +static constexpr int RegNumX86ToX86_64(int regnum) { + switch (regnum) { + case lldb_eax_i386: + return lldb_rax_x86_64; + case lldb_ebx_i386: + return lldb_rbx_x86_64; + case lldb_ecx_i386: + return lldb_rcx_x86_64; + case lldb_edx_i386: + return lldb_rdx_x86_64; + case lldb_edi_i386: + return lldb_rdi_x86_64; + case lldb_esi_i386: + return lldb_rsi_x86_64; + case lldb_ebp_i386: + return lldb_rbp_x86_64; + case lldb_esp_i386: + return lldb_rsp_x86_64; + case lldb_eip_i386: + return lldb_rip_x86_64; + case lldb_eflags_i386: + return lldb_rflags_x86_64; + case lldb_cs_i386: + return lldb_cs_x86_64; + case lldb_fs_i386: + return lldb_fs_x86_64; + case lldb_gs_i386: + return lldb_gs_x86_64; + case lldb_ss_i386: + return lldb_ss_x86_64; + case lldb_ds_i386: + return lldb_ds_x86_64; + case lldb_es_i386: + return lldb_es_x86_64; + case lldb_fctrl_i386: + return lldb_fctrl_x86_64; + case lldb_fstat_i386: + return lldb_fstat_x86_64; + case lldb_ftag_i386: + return lldb_fstat_x86_64; + case lldb_fop_i386: + return lldb_fop_x86_64; + case lldb_fiseg_i386: + return lldb_fiseg_x86_64; + case lldb_fioff_i386: + return lldb_fioff_x86_64; + case lldb_foseg_i386: + return lldb_foseg_x86_64; + case lldb_fooff_i386: + return lldb_fooff_x86_64; + case lldb_mxcsr_i386: + return lldb_mxcsr_x86_64; + case lldb_mxcsrmask_i386: + return lldb_mxcsrmask_x86_64; + case lldb_st0_i386: + case lldb_st1_i386: + case lldb_st2_i386: + case lldb_st3_i386: + case lldb_st4_i386: + case lldb_st5_i386: + case lldb_st6_i386: + case lldb_st7_i386: + return lldb_st0_x86_64 + regnum - lldb_st0_i386; + case lldb_mm0_i386: + case lldb_mm1_i386: + case lldb_mm2_i386: + case lldb_mm3_i386: + case lldb_mm4_i386: + case lldb_mm5_i386: + case lldb_mm6_i386: + case lldb_mm7_i386: + return lldb_mm0_x86_64 + regnum - lldb_mm0_i386; + case lldb_xmm0_i386: + case lldb_xmm1_i386: + case lldb_xmm2_i386: + case lldb_xmm3_i386: + case lldb_xmm4_i386: + case lldb_xmm5_i386: + case lldb_xmm6_i386: + case lldb_xmm7_i386: + return lldb_xmm0_x86_64 + regnum - lldb_xmm0_i386; + case lldb_ymm0_i386: + case lldb_ymm1_i386: + case lldb_ymm2_i386: + case lldb_ymm3_i386: + case lldb_ymm4_i386: + case lldb_ymm5_i386: + case lldb_ymm6_i386: + case lldb_ymm7_i386: + return lldb_ymm0_x86_64 + regnum - lldb_ymm0_i386; + case lldb_dr0_i386: + case lldb_dr1_i386: + case lldb_dr2_i386: + case lldb_dr3_i386: + case lldb_dr4_i386: + case lldb_dr5_i386: + case lldb_dr6_i386: + case lldb_dr7_i386: + return lldb_dr0_x86_64 + regnum - lldb_dr0_i386; + default: + assert(false && "Unhandled i386 register."); + return 0; + } +} + int NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum( int reg_num) const { - if (reg_num <= k_last_gpr_x86_64) - return GPRegSet; - else if (reg_num <= k_last_fpr_x86_64) - return FPRegSet; - else if (reg_num <= k_last_avx_x86_64) - return XStateRegSet; // AVX - else if (reg_num <= k_last_mpxr_x86_64) - return -1; // MPXR - else if (reg_num <= k_last_mpxc_x86_64) - return -1; // MPXC - else if (reg_num <= lldb_dr7_x86_64) - return DBRegSet; // DBR - else + switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86: + if (reg_num <= k_last_gpr_i386) + return GPRegSet; + else if (reg_num <= k_last_fpr_i386) + return FPRegSet; + else if (reg_num <= k_last_avx_i386) + return XStateRegSet; // AVX + else if (reg_num <= lldb_dr7_i386) + return DBRegSet; // DBR + else + return -1; + case llvm::Triple::x86_64: + if (reg_num <= k_last_gpr_x86_64) + return GPRegSet; + else if (reg_num <= k_last_fpr_x86_64) + return FPRegSet; + else if (reg_num <= k_last_avx_x86_64) + return XStateRegSet; // AVX + else if (reg_num <= k_last_mpxr_x86_64) + return -1; // MPXR + else if (reg_num <= k_last_mpxc_x86_64) + return -1; // MPXC + else if (reg_num <= lldb_dr7_x86_64) + return DBRegSet; // DBR + else + return -1; + default: + assert(false && "Unhandled target architecture."); return -1; + } } Status NativeRegisterContextNetBSD_x86_64::ReadRegisterSet(uint32_t set) { switch (set) { case GPRegSet: - return DoRegisterSet(PT_GETREGS, &m_gpr_x86_64); + return DoRegisterSet(PT_GETREGS, &m_gpr); case FPRegSet: - return DoRegisterSet(PT_GETFPREGS, &m_fpr_x86_64); +#if defined(__x86_64__) + return DoRegisterSet(PT_GETFPREGS, &m_fpr); +#else + return DoRegisterSet(PT_GETXMMREGS, &m_fpr); +#endif case DBRegSet: - return DoRegisterSet(PT_GETDBREGS, &m_dbr_x86_64); + return DoRegisterSet(PT_GETDBREGS, &m_dbr); case XStateRegSet: #ifdef HAVE_XSTATE { - struct iovec iov = {&m_xstate_x86_64, sizeof(m_xstate_x86_64)}; + struct iovec iov = {&m_xstate, sizeof(m_xstate)}; return DoRegisterSet(PT_GETXSTATE, &iov); } #else @@ -244,15 +453,19 @@ Status NativeRegisterContextNetBSD_x86_64::ReadRegisterSet(uint32_t set) { Status NativeRegisterContextNetBSD_x86_64::WriteRegisterSet(uint32_t set) { switch (set) { case GPRegSet: - return DoRegisterSet(PT_SETREGS, &m_gpr_x86_64); + return DoRegisterSet(PT_SETREGS, &m_gpr); case FPRegSet: - return DoRegisterSet(PT_SETFPREGS, &m_fpr_x86_64); +#if defined(__x86_64__) + return DoRegisterSet(PT_SETFPREGS, &m_fpr); +#else + return DoRegisterSet(PT_SETXMMREGS, &m_fpr); +#endif case DBRegSet: - return DoRegisterSet(PT_SETDBREGS, &m_dbr_x86_64); + return DoRegisterSet(PT_SETDBREGS, &m_dbr); case XStateRegSet: #ifdef HAVE_XSTATE { - struct iovec iov = {&m_xstate_x86_64, sizeof(m_xstate_x86_64)}; + struct iovec iov = {&m_xstate, sizeof(m_xstate)}; return DoRegisterSet(PT_SETXSTATE, &iov); } #else @@ -272,7 +485,7 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info, return error; } - const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; + uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; if (reg == LLDB_INVALID_REGNUM) { // This is likely an internal register for lldb use only and should not be // directly queried. @@ -291,112 +504,175 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info, return error; } + switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86_64: + break; + case llvm::Triple::x86: + reg = RegNumX86ToX86_64(reg); + break; + default: + assert(false && "Unhandled target architecture."); + error.SetErrorString("Unhandled target architecture."); + return error; + } + error = ReadRegisterSet(set); if (error.Fail()) return error; switch (reg) { +#if defined(__x86_64__) case lldb_rax_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RAX]; + reg_value = (uint64_t)m_gpr.regs[_REG_RAX]; break; case lldb_rbx_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RBX]; + reg_value = (uint64_t)m_gpr.regs[_REG_RBX]; break; case lldb_rcx_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RCX]; + reg_value = (uint64_t)m_gpr.regs[_REG_RCX]; break; case lldb_rdx_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RDX]; + reg_value = (uint64_t)m_gpr.regs[_REG_RDX]; break; case lldb_rdi_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RDI]; + reg_value = (uint64_t)m_gpr.regs[_REG_RDI]; break; case lldb_rsi_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RSI]; + reg_value = (uint64_t)m_gpr.regs[_REG_RSI]; break; case lldb_rbp_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RBP]; + reg_value = (uint64_t)m_gpr.regs[_REG_RBP]; break; case lldb_rsp_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RSP]; + reg_value = (uint64_t)m_gpr.regs[_REG_RSP]; break; case lldb_r8_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R8]; + reg_value = (uint64_t)m_gpr.regs[_REG_R8]; break; case lldb_r9_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R9]; + reg_value = (uint64_t)m_gpr.regs[_REG_R9]; break; case lldb_r10_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R10]; + reg_value = (uint64_t)m_gpr.regs[_REG_R10]; break; case lldb_r11_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R11]; + reg_value = (uint64_t)m_gpr.regs[_REG_R11]; break; case lldb_r12_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R12]; + reg_value = (uint64_t)m_gpr.regs[_REG_R12]; break; case lldb_r13_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R13]; + reg_value = (uint64_t)m_gpr.regs[_REG_R13]; break; case lldb_r14_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R14]; + reg_value = (uint64_t)m_gpr.regs[_REG_R14]; break; case lldb_r15_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R15]; + reg_value = (uint64_t)m_gpr.regs[_REG_R15]; break; case lldb_rip_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RIP]; + reg_value = (uint64_t)m_gpr.regs[_REG_RIP]; break; case lldb_rflags_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RFLAGS]; + reg_value = (uint64_t)m_gpr.regs[_REG_RFLAGS]; break; case lldb_cs_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_CS]; + reg_value = (uint64_t)m_gpr.regs[_REG_CS]; break; case lldb_fs_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_FS]; + reg_value = (uint64_t)m_gpr.regs[_REG_FS]; break; case lldb_gs_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_GS]; + reg_value = (uint64_t)m_gpr.regs[_REG_GS]; break; case lldb_ss_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_SS]; + reg_value = (uint64_t)m_gpr.regs[_REG_SS]; break; case lldb_ds_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_DS]; + reg_value = (uint64_t)m_gpr.regs[_REG_DS]; break; case lldb_es_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_ES]; + reg_value = (uint64_t)m_gpr.regs[_REG_ES]; + break; +#else + case lldb_rax_x86_64: + reg_value = (uint32_t)m_gpr.r_eax; break; + case lldb_rbx_x86_64: + reg_value = (uint32_t)m_gpr.r_ebx; + break; + case lldb_rcx_x86_64: + reg_value = (uint32_t)m_gpr.r_ecx; + break; + case lldb_rdx_x86_64: + reg_value = (uint32_t)m_gpr.r_edx; + break; + case lldb_rdi_x86_64: + reg_value = (uint32_t)m_gpr.r_edi; + break; + case lldb_rsi_x86_64: + reg_value = (uint32_t)m_gpr.r_esi; + break; + case lldb_rsp_x86_64: + reg_value = (uint32_t)m_gpr.r_esp; + break; + case lldb_rbp_x86_64: + reg_value = (uint32_t)m_gpr.r_ebp; + break; + case lldb_rip_x86_64: + reg_value = (uint32_t)m_gpr.r_eip; + break; + case lldb_rflags_x86_64: + reg_value = (uint32_t)m_gpr.r_eflags; + break; + case lldb_cs_x86_64: + reg_value = (uint32_t)m_gpr.r_cs; + break; + case lldb_fs_x86_64: + reg_value = (uint32_t)m_gpr.r_fs; + break; + case lldb_gs_x86_64: + reg_value = (uint32_t)m_gpr.r_gs; + break; + case lldb_ss_x86_64: + reg_value = (uint32_t)m_gpr.r_ss; + break; + case lldb_ds_x86_64: + reg_value = (uint32_t)m_gpr.r_ds; + break; + case lldb_es_x86_64: + reg_value = (uint32_t)m_gpr.r_es; + break; +#endif case lldb_fctrl_x86_64: - reg_value = (uint16_t)m_fpr_x86_64.fxstate.fx_cw; + reg_value = (uint16_t)m_fpr.fxstate.fx_cw; break; case lldb_fstat_x86_64: - reg_value = (uint16_t)m_fpr_x86_64.fxstate.fx_sw; + reg_value = (uint16_t)m_fpr.fxstate.fx_sw; break; case lldb_ftag_x86_64: - reg_value = (uint8_t)m_fpr_x86_64.fxstate.fx_tw; + reg_value = (uint8_t)m_fpr.fxstate.fx_tw; break; case lldb_fop_x86_64: - reg_value = (uint64_t)m_fpr_x86_64.fxstate.fx_opcode; + reg_value = (uint64_t)m_fpr.fxstate.fx_opcode; break; case lldb_fiseg_x86_64: - reg_value = (uint64_t)m_fpr_x86_64.fxstate.fx_ip.fa_64; + reg_value = (uint64_t)m_fpr.fxstate.fx_ip.fa_64; break; case lldb_fioff_x86_64: - reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_ip.fa_32.fa_off; + reg_value = (uint32_t)m_fpr.fxstate.fx_ip.fa_32.fa_off; break; case lldb_foseg_x86_64: - reg_value = (uint64_t)m_fpr_x86_64.fxstate.fx_dp.fa_64; + reg_value = (uint64_t)m_fpr.fxstate.fx_dp.fa_64; break; case lldb_fooff_x86_64: - reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_dp.fa_32.fa_off; + reg_value = (uint32_t)m_fpr.fxstate.fx_dp.fa_32.fa_off; break; case lldb_mxcsr_x86_64: - reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_mxcsr; + reg_value = (uint32_t)m_fpr.fxstate.fx_mxcsr; break; case lldb_mxcsrmask_x86_64: - reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_mxcsr_mask; + reg_value = (uint32_t)m_fpr.fxstate.fx_mxcsr_mask; break; case lldb_st0_x86_64: case lldb_st1_x86_64: @@ -406,7 +682,7 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info, case lldb_st5_x86_64: case lldb_st6_x86_64: case lldb_st7_x86_64: - reg_value.SetBytes(&m_fpr_x86_64.fxstate.fx_87_ac[reg - lldb_st0_x86_64], + reg_value.SetBytes(&m_fpr.fxstate.fx_87_ac[reg - lldb_st0_x86_64], reg_info->byte_size, endian::InlHostByteOrder()); break; case lldb_mm0_x86_64: @@ -417,7 +693,7 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info, case lldb_mm5_x86_64: case lldb_mm6_x86_64: case lldb_mm7_x86_64: - reg_value.SetBytes(&m_fpr_x86_64.fxstate.fx_87_ac[reg - lldb_mm0_x86_64], + reg_value.SetBytes(&m_fpr.fxstate.fx_87_ac[reg - lldb_mm0_x86_64], reg_info->byte_size, endian::InlHostByteOrder()); break; case lldb_xmm0_x86_64: @@ -436,7 +712,7 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info, case lldb_xmm13_x86_64: case lldb_xmm14_x86_64: case lldb_xmm15_x86_64: - reg_value.SetBytes(&m_fpr_x86_64.fxstate.fx_xmm[reg - lldb_xmm0_x86_64], + reg_value.SetBytes(&m_fpr.fxstate.fx_xmm[reg - lldb_xmm0_x86_64], reg_info->byte_size, endian::InlHostByteOrder()); break; case lldb_ymm0_x86_64: @@ -456,15 +732,15 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info, case lldb_ymm14_x86_64: case lldb_ymm15_x86_64: #ifdef HAVE_XSTATE - if (!(m_xstate_x86_64.xs_rfbm & XCR0_SSE) || - !(m_xstate_x86_64.xs_rfbm & XCR0_YMM_Hi128)) { + if (!(m_xstate.xs_rfbm & XCR0_SSE) || + !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) { error.SetErrorStringWithFormat("register \"%s\" not supported by CPU/kernel", reg_info->name); } else { uint32_t reg_index = reg - lldb_ymm0_x86_64; YMMReg ymm = XStateToYMM( - m_xstate_x86_64.xs_fxsave.fx_xmm[reg_index].xmm_bytes, - m_xstate_x86_64.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes); + m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes, + m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes); reg_value.SetBytes(ymm.bytes, reg_info->byte_size, endian::InlHostByteOrder()); } @@ -480,7 +756,7 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info, case lldb_dr5_x86_64: case lldb_dr6_x86_64: case lldb_dr7_x86_64: - reg_value = (uint64_t)m_dbr_x86_64.dr[reg - lldb_dr0_x86_64]; + reg_value = (uint64_t)m_dbr.dr[reg - lldb_dr0_x86_64]; break; } @@ -497,7 +773,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister( return error; } - const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; + uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; if (reg == LLDB_INVALID_REGNUM) { // This is likely an internal register for lldb use only and should not be // directly queried. @@ -516,112 +792,175 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister( return error; } + switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86_64: + break; + case llvm::Triple::x86: + reg = RegNumX86ToX86_64(reg); + break; + default: + assert(false && "Unhandled target architecture."); + error.SetErrorString("Unhandled target architecture."); + return error; + } + error = ReadRegisterSet(set); if (error.Fail()) return error; switch (reg) { +#if defined(__x86_64__) case lldb_rax_x86_64: - m_gpr_x86_64.regs[_REG_RAX] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RAX] = reg_value.GetAsUInt64(); break; case lldb_rbx_x86_64: - m_gpr_x86_64.regs[_REG_RBX] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RBX] = reg_value.GetAsUInt64(); break; case lldb_rcx_x86_64: - m_gpr_x86_64.regs[_REG_RCX] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RCX] = reg_value.GetAsUInt64(); break; case lldb_rdx_x86_64: - m_gpr_x86_64.regs[_REG_RDX] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RDX] = reg_value.GetAsUInt64(); break; case lldb_rdi_x86_64: - m_gpr_x86_64.regs[_REG_RDI] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RDI] = reg_value.GetAsUInt64(); break; case lldb_rsi_x86_64: - m_gpr_x86_64.regs[_REG_RSI] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RSI] = reg_value.GetAsUInt64(); break; case lldb_rbp_x86_64: - m_gpr_x86_64.regs[_REG_RBP] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RBP] = reg_value.GetAsUInt64(); break; case lldb_rsp_x86_64: - m_gpr_x86_64.regs[_REG_RSP] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RSP] = reg_value.GetAsUInt64(); break; case lldb_r8_x86_64: - m_gpr_x86_64.regs[_REG_R8] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_R8] = reg_value.GetAsUInt64(); break; case lldb_r9_x86_64: - m_gpr_x86_64.regs[_REG_R9] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_R9] = reg_value.GetAsUInt64(); break; case lldb_r10_x86_64: - m_gpr_x86_64.regs[_REG_R10] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_R10] = reg_value.GetAsUInt64(); break; case lldb_r11_x86_64: - m_gpr_x86_64.regs[_REG_R11] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_R11] = reg_value.GetAsUInt64(); break; case lldb_r12_x86_64: - m_gpr_x86_64.regs[_REG_R12] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_R12] = reg_value.GetAsUInt64(); break; case lldb_r13_x86_64: - m_gpr_x86_64.regs[_REG_R13] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_R13] = reg_value.GetAsUInt64(); break; case lldb_r14_x86_64: - m_gpr_x86_64.regs[_REG_R14] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_R14] = reg_value.GetAsUInt64(); break; case lldb_r15_x86_64: - m_gpr_x86_64.regs[_REG_R15] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_R15] = reg_value.GetAsUInt64(); break; case lldb_rip_x86_64: - m_gpr_x86_64.regs[_REG_RIP] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RIP] = reg_value.GetAsUInt64(); break; case lldb_rflags_x86_64: - m_gpr_x86_64.regs[_REG_RFLAGS] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RFLAGS] = reg_value.GetAsUInt64(); break; case lldb_cs_x86_64: - m_gpr_x86_64.regs[_REG_CS] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_CS] = reg_value.GetAsUInt64(); break; case lldb_fs_x86_64: - m_gpr_x86_64.regs[_REG_FS] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_FS] = reg_value.GetAsUInt64(); break; case lldb_gs_x86_64: - m_gpr_x86_64.regs[_REG_GS] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_GS] = reg_value.GetAsUInt64(); break; case lldb_ss_x86_64: - m_gpr_x86_64.regs[_REG_SS] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_SS] = reg_value.GetAsUInt64(); break; case lldb_ds_x86_64: - m_gpr_x86_64.regs[_REG_DS] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_DS] = reg_value.GetAsUInt64(); break; case lldb_es_x86_64: - m_gpr_x86_64.regs[_REG_ES] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_ES] = reg_value.GetAsUInt64(); break; +#else + case lldb_rax_x86_64: + m_gpr.r_eax = reg_value.GetAsUInt32(); + break; + case lldb_rbx_x86_64: + m_gpr.r_ebx = reg_value.GetAsUInt32(); + break; + case lldb_rcx_x86_64: + m_gpr.r_ecx = reg_value.GetAsUInt32(); + break; + case lldb_rdx_x86_64: + m_gpr.r_edx = reg_value.GetAsUInt32(); + break; + case lldb_rdi_x86_64: + m_gpr.r_edi = reg_value.GetAsUInt32(); + break; + case lldb_rsi_x86_64: + m_gpr.r_esi = reg_value.GetAsUInt32(); + break; + case lldb_rsp_x86_64: + m_gpr.r_esp = reg_value.GetAsUInt32(); + break; + case lldb_rbp_x86_64: + m_gpr.r_ebp = reg_value.GetAsUInt32(); + break; + case lldb_rip_x86_64: + m_gpr.r_eip = reg_value.GetAsUInt32(); + break; + case lldb_rflags_x86_64: + m_gpr.r_eflags = reg_value.GetAsUInt32(); + break; + case lldb_cs_x86_64: + m_gpr.r_cs = reg_value.GetAsUInt32(); + break; + case lldb_fs_x86_64: + m_gpr.r_fs = reg_value.GetAsUInt32(); + break; + case lldb_gs_x86_64: + m_gpr.r_gs = reg_value.GetAsUInt32(); + break; + case lldb_ss_x86_64: + m_gpr.r_ss = reg_value.GetAsUInt32(); + break; + case lldb_ds_x86_64: + m_gpr.r_ds = reg_value.GetAsUInt32(); + break; + case lldb_es_x86_64: + m_gpr.r_es = reg_value.GetAsUInt32(); + break; +#endif case lldb_fctrl_x86_64: - m_fpr_x86_64.fxstate.fx_cw = reg_value.GetAsUInt16(); + m_fpr.fxstate.fx_cw = reg_value.GetAsUInt16(); break; case lldb_fstat_x86_64: - m_fpr_x86_64.fxstate.fx_sw = reg_value.GetAsUInt16(); + m_fpr.fxstate.fx_sw = reg_value.GetAsUInt16(); break; case lldb_ftag_x86_64: - m_fpr_x86_64.fxstate.fx_tw = reg_value.GetAsUInt8(); + m_fpr.fxstate.fx_tw = reg_value.GetAsUInt8(); break; case lldb_fop_x86_64: - m_fpr_x86_64.fxstate.fx_opcode = reg_value.GetAsUInt16(); + m_fpr.fxstate.fx_opcode = reg_value.GetAsUInt16(); break; case lldb_fiseg_x86_64: - m_fpr_x86_64.fxstate.fx_ip.fa_64 = reg_value.GetAsUInt64(); + m_fpr.fxstate.fx_ip.fa_64 = reg_value.GetAsUInt64(); break; case lldb_fioff_x86_64: - m_fpr_x86_64.fxstate.fx_ip.fa_32.fa_off = reg_value.GetAsUInt32(); + m_fpr.fxstate.fx_ip.fa_32.fa_off = reg_value.GetAsUInt32(); break; case lldb_foseg_x86_64: - m_fpr_x86_64.fxstate.fx_dp.fa_64 = reg_value.GetAsUInt64(); + m_fpr.fxstate.fx_dp.fa_64 = reg_value.GetAsUInt64(); break; case lldb_fooff_x86_64: - m_fpr_x86_64.fxstate.fx_dp.fa_32.fa_off = reg_value.GetAsUInt32(); + m_fpr.fxstate.fx_dp.fa_32.fa_off = reg_value.GetAsUInt32(); break; case lldb_mxcsr_x86_64: - m_fpr_x86_64.fxstate.fx_mxcsr = reg_value.GetAsUInt32(); + m_fpr.fxstate.fx_mxcsr = reg_value.GetAsUInt32(); break; case lldb_mxcsrmask_x86_64: - m_fpr_x86_64.fxstate.fx_mxcsr_mask = reg_value.GetAsUInt32(); + m_fpr.fxstate.fx_mxcsr_mask = reg_value.GetAsUInt32(); break; case lldb_st0_x86_64: case lldb_st1_x86_64: @@ -631,7 +970,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister( case lldb_st5_x86_64: case lldb_st6_x86_64: case lldb_st7_x86_64: - ::memcpy(&m_fpr_x86_64.fxstate.fx_87_ac[reg - lldb_st0_x86_64], + ::memcpy(&m_fpr.fxstate.fx_87_ac[reg - lldb_st0_x86_64], reg_value.GetBytes(), reg_value.GetByteSize()); break; case lldb_mm0_x86_64: @@ -642,7 +981,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister( case lldb_mm5_x86_64: case lldb_mm6_x86_64: case lldb_mm7_x86_64: - ::memcpy(&m_fpr_x86_64.fxstate.fx_87_ac[reg - lldb_mm0_x86_64], + ::memcpy(&m_fpr.fxstate.fx_87_ac[reg - lldb_mm0_x86_64], reg_value.GetBytes(), reg_value.GetByteSize()); break; case lldb_xmm0_x86_64: @@ -661,7 +1000,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister( case lldb_xmm13_x86_64: case lldb_xmm14_x86_64: case lldb_xmm15_x86_64: - ::memcpy(&m_fpr_x86_64.fxstate.fx_xmm[reg - lldb_xmm0_x86_64], + ::memcpy(&m_fpr.fxstate.fx_xmm[reg - lldb_xmm0_x86_64], reg_value.GetBytes(), reg_value.GetByteSize()); break; case lldb_ymm0_x86_64: @@ -681,8 +1020,8 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister( case lldb_ymm14_x86_64: case lldb_ymm15_x86_64: #ifdef HAVE_XSTATE - if (!(m_xstate_x86_64.xs_rfbm & XCR0_SSE) || - !(m_xstate_x86_64.xs_rfbm & XCR0_YMM_Hi128)) { + if (!(m_xstate.xs_rfbm & XCR0_SSE) || + !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) { error.SetErrorStringWithFormat("register \"%s\" not supported by CPU/kernel", reg_info->name); } else { @@ -690,8 +1029,8 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister( YMMReg ymm; ::memcpy(ymm.bytes, reg_value.GetBytes(), reg_value.GetByteSize()); YMMToXState(ymm, - m_xstate_x86_64.xs_fxsave.fx_xmm[reg_index].xmm_bytes, - m_xstate_x86_64.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes); + m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes, + m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes); } #else error.SetErrorString("XState not supported by the kernel"); @@ -705,7 +1044,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister( case lldb_dr5_x86_64: case lldb_dr6_x86_64: case lldb_dr7_x86_64: - m_dbr_x86_64.dr[reg - lldb_dr0_x86_64] = reg_value.GetAsUInt64(); + m_dbr.dr[reg - lldb_dr0_x86_64] = reg_value.GetAsUInt64(); break; } @@ -722,7 +1061,7 @@ Status NativeRegisterContextNetBSD_x86_64::ReadAllRegisterValues( return error; uint8_t *dst = data_sp->GetBytes(); - ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize()); + ::memcpy(dst, &m_gpr, GetRegisterInfoInterface().GetGPRSize()); dst += GetRegisterInfoInterface().GetGPRSize(); return error; @@ -742,7 +1081,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues( if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) { error.SetErrorStringWithFormat( "NativeRegisterContextNetBSD_x86_64::%s data_sp contained mismatched " - "data size, expected %" PRIu64 ", actual %" PRIu64, + "data size, expected %zu, actual %" PRIu64, __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize()); return error; } @@ -755,7 +1094,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues( __FUNCTION__); return error; } - ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize()); + ::memcpy(&m_gpr, src, GetRegisterInfoInterface().GetGPRSize()); error = WriteRegisterSet(GPRegSet); if (error.Fail()) @@ -765,13 +1104,25 @@ Status NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues( return error; } +int NativeRegisterContextNetBSD_x86_64::GetDR(int num) const { + assert(num >= 0 && num <= 7); + switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86: + return lldb_dr0_i386 + num; + case llvm::Triple::x86_64: + return lldb_dr0_x86_64 + num; + default: + return -1; + } +} + Status NativeRegisterContextNetBSD_x86_64::IsWatchpointHit(uint32_t wp_index, bool &is_hit) { if (wp_index >= NumSupportedHardwareWatchpoints()) return Status("Watchpoint index out of range"); RegisterValue reg_value; - const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(lldb_dr6_x86_64); + const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(GetDR(6)); Status error = ReadRegister(reg_info, reg_value); if (error.Fail()) { is_hit = false; @@ -808,7 +1159,7 @@ Status NativeRegisterContextNetBSD_x86_64::IsWatchpointVacant(uint32_t wp_index, return Status("Watchpoint index out of range"); RegisterValue reg_value; - const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(lldb_dr7_x86_64); + const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(GetDR(7)); Status error = ReadRegister(reg_info, reg_value); if (error.Fail()) { is_vacant = false; @@ -848,8 +1199,7 @@ Status NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpointWithIndex( if (!is_vacant) return Status("Watchpoint index not vacant"); - const RegisterInfo *const reg_info_dr7 = - GetRegisterInfoAtIndex(lldb_dr7_x86_64); + const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7)); RegisterValue dr7_value; error = ReadRegister(reg_info_dr7, dr7_value); if (error.Fail()) @@ -874,7 +1224,7 @@ Status NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpointWithIndex( control_bits |= enable_bit | rw_bits | size_bits; const RegisterInfo *const reg_info_drN = - GetRegisterInfoAtIndex(lldb_dr0_x86_64 + wp_index); + GetRegisterInfoAtIndex(GetDR(wp_index)); RegisterValue drN_value; error = ReadRegister(reg_info_drN, drN_value); if (error.Fail()) @@ -906,8 +1256,7 @@ bool NativeRegisterContextNetBSD_x86_64::ClearHardwareWatchpoint( // for watchpoints 0, 1, 2, or 3, respectively, clear bits 0-1, 2-3, 4-5 // or 6-7 of the debug control register (DR7) - const RegisterInfo *const reg_info_dr7 = - GetRegisterInfoAtIndex(lldb_dr7_x86_64); + const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7)); RegisterValue reg_value; Status error = ReadRegister(reg_info_dr7, reg_value); if (error.Fail()) @@ -924,8 +1273,7 @@ Status NativeRegisterContextNetBSD_x86_64::ClearWatchpointHit(uint32_t wp_index) // for watchpoints 0, 1, 2, or 3, respectively, check bits 0, 1, 2, or 3 of // the debug status register (DR6) - const RegisterInfo *const reg_info_dr6 = - GetRegisterInfoAtIndex(lldb_dr6_x86_64); + const RegisterInfo *const reg_info_dr6 = GetRegisterInfoAtIndex(GetDR(6)); RegisterValue reg_value; Status error = ReadRegister(reg_info_dr6, reg_value); if (error.Fail()) @@ -940,8 +1288,7 @@ Status NativeRegisterContextNetBSD_x86_64::ClearAllHardwareWatchpoints() { RegisterValue reg_value; // clear bits {0-4} of the debug status register (DR6) - const RegisterInfo *const reg_info_dr6 = - GetRegisterInfoAtIndex(lldb_dr6_x86_64); + const RegisterInfo *const reg_info_dr6 = GetRegisterInfoAtIndex(GetDR(6)); Status error = ReadRegister(reg_info_dr6, reg_value); if (error.Fail()) return error; @@ -952,8 +1299,7 @@ Status NativeRegisterContextNetBSD_x86_64::ClearAllHardwareWatchpoints() { return error; // clear bits {0-7,16-31} of the debug control register (DR7) - const RegisterInfo *const reg_info_dr7 = - GetRegisterInfoAtIndex(lldb_dr7_x86_64); + const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7)); error = ReadRegister(reg_info_dr7, reg_value); if (error.Fail()) return error; @@ -988,7 +1334,7 @@ NativeRegisterContextNetBSD_x86_64::GetWatchpointAddress(uint32_t wp_index) { return LLDB_INVALID_ADDRESS; RegisterValue reg_value; const RegisterInfo *const reg_info_drN = - GetRegisterInfoAtIndex(lldb_dr0_x86_64 + wp_index); + GetRegisterInfoAtIndex(GetDR(wp_index)); if (ReadRegister(reg_info_drN, reg_value).Fail()) return LLDB_INVALID_ADDRESS; return reg_value.GetAsUInt64(); @@ -1005,10 +1351,10 @@ Status NativeRegisterContextNetBSD_x86_64::CopyHardwareWatchpointsFrom( Status res = r_source.ReadRegisterSet(DBRegSet); if (!res.Fail()) { // copy dbregs only if any watchpoints were set - if ((r_source.m_dbr_x86_64.dr[7] & 0xFF) == 0) + if ((r_source.m_dbr.dr[7] & 0xFF) == 0) return res; - m_dbr_x86_64 = r_source.m_dbr_x86_64; + m_dbr = r_source.m_dbr; res = WriteRegisterSet(DBRegSet); } return res; diff --git a/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h b/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h index 54b8a806267..6c0632f3bce 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#if defined(__x86_64__) +#if defined(__i386__) || defined(__x86_64__) #ifndef lldb_NativeRegisterContextNetBSD_x86_64_h #define lldb_NativeRegisterContextNetBSD_x86_64_h @@ -81,14 +81,19 @@ private: enum { GPRegSet, FPRegSet, XStateRegSet, DBRegSet }; // Private member variables. - struct reg m_gpr_x86_64; - struct fpreg m_fpr_x86_64; - struct dbreg m_dbr_x86_64; + struct reg m_gpr; +#if defined(__x86_64__) + struct fpreg m_fpr; +#else + struct xmmregs m_fpr; +#endif + struct dbreg m_dbr; #ifdef HAVE_XSTATE - struct xstate m_xstate_x86_64; + struct xstate m_xstate; #endif int GetSetForNativeRegNum(int reg_num) const; + int GetDR(int num) const; Status ReadRegisterSet(uint32_t set); Status WriteRegisterSet(uint32_t set); diff --git a/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp b/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp index dd2745d9330..fe76fb40e0b 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp @@ -1,4 +1,4 @@ -//===-- NativeThreadNetBSD.cpp -------------------------------- -*- C++ -*-===// +//===-- NativeThreadNetBSD.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/POSIX/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Process/POSIX/CMakeLists.txt index fd74f816d1a..2db4e795b96 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/POSIX/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/Process/POSIX/CMakeLists.txt @@ -1,4 +1,4 @@ -add_lldb_library(lldbPluginProcessPOSIX PLUGIN +add_lldb_library(lldbPluginProcessPOSIX CrashReason.cpp NativeProcessELF.cpp ProcessMessage.cpp diff --git a/gnu/llvm/lldb/source/Plugins/Process/POSIX/CrashReason.cpp b/gnu/llvm/lldb/source/Plugins/Process/POSIX/CrashReason.cpp index b872269fdfe..579077b45bf 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/POSIX/CrashReason.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/POSIX/CrashReason.cpp @@ -1,4 +1,4 @@ -//===-- CrashReason.cpp -----------------------------------------*- C++ -*-===// +//===-- CrashReason.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp b/gnu/llvm/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp index 058dc5ae233..117d12101a0 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp @@ -1,4 +1,4 @@ -//===-- NativeProcessELF.cpp ---------------------------------- -*- C++ -*-===// +//===-- NativeProcessELF.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -107,6 +107,11 @@ lldb::addr_t NativeProcessELF::GetELFImageInfoAddress() { return LLDB_INVALID_ADDRESS; } +template lldb::addr_t NativeProcessELF::GetELFImageInfoAddress< + llvm::ELF::Elf32_Ehdr, llvm::ELF::Elf32_Phdr, llvm::ELF::Elf32_Dyn>(); +template lldb::addr_t NativeProcessELF::GetELFImageInfoAddress< + llvm::ELF::Elf64_Ehdr, llvm::ELF::Elf64_Phdr, llvm::ELF::Elf64_Dyn>(); + template llvm::Expected NativeProcessELF::ReadSVR4LibraryInfo(lldb::addr_t link_map_addr) { diff --git a/gnu/llvm/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h b/gnu/llvm/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h index 4fb513baebf..dcfa9290ff5 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h +++ b/gnu/llvm/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h @@ -48,6 +48,14 @@ protected: llvm::Optional m_shared_library_info_addr; }; +// Explicitly declare the two 32/64 bit templates that NativeProcessELF.cpp will +// define. This allows us to keep the template definition here and usable +// elsewhere. +extern template lldb::addr_t NativeProcessELF::GetELFImageInfoAddress< + llvm::ELF::Elf32_Ehdr, llvm::ELF::Elf32_Phdr, llvm::ELF::Elf32_Dyn>(); +extern template lldb::addr_t NativeProcessELF::GetELFImageInfoAddress< + llvm::ELF::Elf64_Ehdr, llvm::ELF::Elf64_Phdr, llvm::ELF::Elf64_Dyn>(); + } // namespace lldb_private -#endif \ No newline at end of file +#endif diff --git a/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp b/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp index 66286dd3d9e..4e8c6f1ba2d 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp @@ -1,4 +1,4 @@ -//===-- ProcessMessage.cpp --------------------------------------*- C++ -*-===// +//===-- ProcessMessage.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp b/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp index a17558bfe7c..f4d0803b264 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp @@ -1,5 +1,4 @@ -//===-- ProcessPOSIXLog.cpp ---------------------------------------*- C++ -//-*-===// +//===-- ProcessPOSIXLog.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/ARMDefines.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/ARMDefines.h index 1f7eb54d10e..fd3965fade1 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/ARMDefines.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/ARMDefines.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_ARMDefines_h_ -#define lldb_ARMDefines_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMDEFINES_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMDEFINES_H #include "llvm/Support/ErrorHandling.h" @@ -188,4 +188,4 @@ static inline bool ARMConditionPassed(const uint32_t condition, } // namespace lldb_private -#endif // lldb_ARMDefines_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMDEFINES_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/ARMUtils.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/ARMUtils.h index d860348818d..bbe4c9a35fa 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/ARMUtils.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/ARMUtils.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_ARMUtils_h_ -#define lldb_ARMUtils_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMUTILS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMUTILS_H #include "ARMDefines.h" #include "InstructionUtils.h" @@ -371,4 +371,4 @@ static inline bool BadReg(uint32_t n) { return n == 13 || n == 15; } } // namespace lldb_private -#endif // lldb_ARMUtils_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMUTILS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/AuxVector.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/AuxVector.cpp index 25a1d0b5af0..685d9d0824f 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/AuxVector.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/AuxVector.cpp @@ -1,4 +1,4 @@ -//===-- AuxVector.cpp -------------------------------------------*- C++ -*-===// +//===-- AuxVector.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/AuxVector.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/AuxVector.h index c16be68aedb..c8c8b124941 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/AuxVector.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/AuxVector.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AuxVector_H_ -#define liblldb_AuxVector_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_AUXVECTOR_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_AUXVECTOR_H #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Process/Utility/CMakeLists.txt index 77bb176a02e..76ffde5958b 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/CMakeLists.txt @@ -1,4 +1,4 @@ -add_lldb_library(lldbPluginProcessUtility PLUGIN +add_lldb_library(lldbPluginProcessUtility AuxVector.cpp DynamicRegisterInfo.cpp FreeBSDSignals.cpp @@ -11,7 +11,6 @@ add_lldb_library(lldbPluginProcessUtility PLUGIN MipsLinuxSignals.cpp NativeRegisterContextRegisterInfo.cpp NetBSDSignals.cpp - OpenBSDSignals.cpp RegisterContextDarwin_arm.cpp RegisterContextDarwin_arm64.cpp RegisterContextDarwin_i386.cpp @@ -27,12 +26,11 @@ add_lldb_library(lldbPluginProcessUtility PLUGIN RegisterContextLinux_mips64.cpp RegisterContextLinux_mips.cpp RegisterContextLinux_s390x.cpp - RegisterContextLLDB.cpp - RegisterContextMacOSXFrameBackchain.cpp RegisterContextMach_arm.cpp RegisterContextMach_i386.cpp RegisterContextMach_x86_64.cpp RegisterContextMemory.cpp + RegisterContextNetBSD_i386.cpp RegisterContextNetBSD_x86_64.cpp RegisterContextOpenBSD_i386.cpp RegisterContextOpenBSD_x86_64.cpp @@ -51,8 +49,6 @@ add_lldb_library(lldbPluginProcessUtility PLUGIN RegisterInfoPOSIX_ppc64le.cpp StopInfoMachException.cpp ThreadMemory.cpp - UnwindLLDB.cpp - UnwindMacOSXFrameBackchain.cpp LINK_LIBS lldbBreakpoint diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp index a86880af226..443638aa39f 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -1,4 +1,4 @@ -//===-- DynamicRegisterInfo.cpp ----------------------------*- C++ -*-===// +//===-- DynamicRegisterInfo.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -742,6 +742,8 @@ const lldb_private::RegisterInfo *DynamicRegisterInfo::GetRegisterInfo( for (auto ®_info : m_regs) { // We can use pointer comparison since we used a ConstString to set the // "name" member in AddRegister() + assert(ConstString(reg_info.name).GetCString() == reg_info.name && + "reg_info.name not from a ConstString?"); if (reg_info.name == reg_name.GetCString()) { return ®_info; } diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h index aacf547e187..48939375a50 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_DynamicRegisterInfo_h_ -#define lldb_DynamicRegisterInfo_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H #include #include @@ -90,4 +90,4 @@ protected: // all registers bool m_finalized = false; }; -#endif // lldb_DynamicRegisterInfo_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp index 9f63a594e05..0a4bdc72b36 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp @@ -1,4 +1,4 @@ -//===-- FreeBSDSignals.cpp --------------------------------------*- C++ -*-===// +//===-- FreeBSDSignals.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h index 75462f3c76f..c4c810e5498 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_FreeBSDSignals_H_ -#define liblldb_FreeBSDSignals_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_FREEBSDSIGNALS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_FREEBSDSIGNALS_H #include "lldb/Target/UnixSignals.h" @@ -24,4 +24,4 @@ private: } // namespace lldb_private -#endif // liblldb_FreeBSDSignals_H_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_FREEBSDSIGNALS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp index ed35273ce3f..427225c14d3 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteSignals.cpp ------------------------------------*- C++ -*-===// +//===-- GDBRemoteSignals.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h index a02dd0604e6..d37757ab60a 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteSignals_H_ -#define liblldb_GDBRemoteSignals_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_GDBREMOTESIGNALS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_GDBREMOTESIGNALS_H #include "lldb/Target/UnixSignals.h" @@ -26,4 +26,4 @@ private: } // namespace lldb_private -#endif // liblldb_GDBRemoteSignals_H_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_GDBREMOTESIGNALS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/HistoryThread.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/HistoryThread.cpp index 295c17e474f..d73b132539f 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/HistoryThread.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/HistoryThread.cpp @@ -1,4 +1,4 @@ -//===-- HistoryThread.cpp ---------------------------------------*- C++ -*-===// +//===-- HistoryThread.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,12 +25,14 @@ using namespace lldb_private; // Constructor HistoryThread::HistoryThread(lldb_private::Process &process, lldb::tid_t tid, - std::vector pcs) + std::vector pcs, + bool pcs_are_call_addresses) : Thread(process, tid, true), m_framelist_mutex(), m_framelist(), m_pcs(pcs), m_extended_unwind_token(LLDB_INVALID_ADDRESS), m_queue_name(), m_thread_name(), m_originating_unique_thread_id(tid), m_queue_id(LLDB_INVALID_QUEUE_ID) { - m_unwinder_up.reset(new HistoryUnwind(*this, pcs)); + m_unwinder_up = + std::make_unique(*this, pcs, pcs_are_call_addresses); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); LLDB_LOGF(log, "%p HistoryThread::HistoryThread", static_cast(this)); } diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/HistoryThread.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/HistoryThread.h index 1e265864017..a66e0f2d420 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/HistoryThread.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/HistoryThread.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_HistoryThread_h_ -#define liblldb_HistoryThread_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYTHREAD_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYTHREAD_H #include @@ -33,7 +33,8 @@ namespace lldb_private { class HistoryThread : public lldb_private::Thread { public: HistoryThread(lldb_private::Process &process, lldb::tid_t tid, - std::vector pcs); + std::vector pcs, + bool pcs_are_call_addresses = false); ~HistoryThread() override; @@ -88,4 +89,4 @@ protected: } // namespace lldb_private -#endif // liblldb_HistoryThread_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYTHREAD_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp index 83fdb011f5a..9b9522955de 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp @@ -1,4 +1,4 @@ -//===-- HistoryUnwind.cpp ---------------------------------------*- C++ -*-===// +//===-- HistoryUnwind.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -23,8 +23,10 @@ using namespace lldb_private; // Constructor -HistoryUnwind::HistoryUnwind(Thread &thread, std::vector pcs) - : Unwind(thread), m_pcs(pcs) {} +HistoryUnwind::HistoryUnwind(Thread &thread, std::vector pcs, + bool pcs_are_call_addresses) + : Unwind(thread), m_pcs(pcs), + m_pcs_are_call_addresses(pcs_are_call_addresses) {} // Destructor @@ -59,7 +61,10 @@ bool HistoryUnwind::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, if (frame_idx < m_pcs.size()) { cfa = frame_idx; pc = m_pcs[frame_idx]; - behaves_like_zeroth_frame = (frame_idx == 0); + if (m_pcs_are_call_addresses) + behaves_like_zeroth_frame = true; + else + behaves_like_zeroth_frame = (frame_idx == 0); return true; } return false; diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/HistoryUnwind.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/HistoryUnwind.h index 4d16608bd8c..cb72b5d0a17 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/HistoryUnwind.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/HistoryUnwind.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_HistoryUnwind_h_ -#define liblldb_HistoryUnwind_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYUNWIND_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYUNWIND_H #include @@ -18,7 +18,8 @@ namespace lldb_private { class HistoryUnwind : public lldb_private::Unwind { public: - HistoryUnwind(Thread &thread, std::vector pcs); + HistoryUnwind(Thread &thread, std::vector pcs, + bool pcs_are_call_addresses = false); ~HistoryUnwind() override; @@ -35,8 +36,11 @@ protected: private: std::vector m_pcs; + /// This boolean indicates that the PCs in the non-0 frames are call + /// addresses and not return addresses. + bool m_pcs_are_call_addresses; }; } // namespace lldb_private -#endif // liblldb_HistoryUnwind_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYUNWIND_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp index ee939b01d35..0f331933f2e 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp @@ -1,4 +1,4 @@ -//===-- InferiorCallPOSIX.cpp -----------------------------------*- C++ -*-===// +//===-- InferiorCallPOSIX.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h index 2008c5fe0b9..3623e10194f 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_InferiorCallPOSIX_h_ -#define lldb_InferiorCallPOSIX_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INFERIORCALLPOSIX_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INFERIORCALLPOSIX_H // Inferior execution of POSIX functions. @@ -32,4 +32,4 @@ bool InferiorCallMunmap(Process *proc, lldb::addr_t addr, lldb::addr_t length); } // namespace lldb_private -#endif // lldb_InferiorCallPOSIX_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INFERIORCALLPOSIX_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/InstructionUtils.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/InstructionUtils.h index f74933e691e..55b89440700 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/InstructionUtils.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/InstructionUtils.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_InstructionUtils_h_ -#define lldb_InstructionUtils_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INSTRUCTIONUTILS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INSTRUCTIONUTILS_H #include #include @@ -113,4 +113,4 @@ static inline int64_t SignedBits(const uint64_t value, const uint64_t msbit, } // namespace lldb_private -#endif // lldb_InstructionUtils_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INSTRUCTIONUTILS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp index 1ba432aa542..0c7d9ddc5ac 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp @@ -1,4 +1,4 @@ -//===-- LinuxProcMaps.cpp ---------------------------------------*- C++ -*-===// +//===-- LinuxProcMaps.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h index e1f0e48ac5c..363f248fd41 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_LinuxProcMaps_H_ -#define liblldb_LinuxProcMaps_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPROCMAPS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPROCMAPS_H #include "lldb/lldb-forward.h" #include "llvm/ADT/StringRef.h" @@ -24,4 +24,4 @@ void ParseLinuxMapRegions(llvm::StringRef linux_map, } // namespace lldb_private -#endif // liblldb_LinuxProcMaps_H_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPROCMAPS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp index bef47cd2630..4dd619e3bad 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp @@ -1,4 +1,4 @@ -//===-- LinuxSignals.cpp ----------------------------------------*- C++ -*-===// +//===-- LinuxSignals.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/LinuxSignals.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/LinuxSignals.h index 7ad8cfcbef6..32c4744a96d 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/LinuxSignals.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/LinuxSignals.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_LinuxSignals_H_ -#define liblldb_LinuxSignals_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXSIGNALS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXSIGNALS_H #include "lldb/Target/UnixSignals.h" @@ -24,4 +24,4 @@ private: } // namespace lldb_private -#endif // liblldb_LinuxSignals_H_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXSIGNALS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp index d8e5426ab5a..8f75844277c 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp @@ -1,5 +1,4 @@ -//===-- MipsLinuxSignals.cpp ----------------------------------------*- C++ -//-*-===// +//===-- MipsLinuxSignals.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h index b5e3ed86f56..6b78fc72a91 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_MipsLinuxSignals_H_ -#define liblldb_MipsLinuxSignals_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MIPSLINUXSIGNALS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MIPSLINUXSIGNALS_H #include "lldb/Target/UnixSignals.h" @@ -25,4 +25,4 @@ private: } // namespace lldb_private -#endif // liblldb_MipsLinuxSignals_H_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MIPSLINUXSIGNALS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp index be61cfdd737..3a875f7bb39 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextRegisterInfo.cpp -------------------*- C++ -*-===// +//===-- NativeRegisterContextRegisterInfo.cpp -----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h index b285c477cd9..0e96841fd90 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_PROCESS_UTIILTY_NATIVE_REGISTER_CONTEXT_REGISTER_INFO -#define LLDB_PLUGINS_PROCESS_UTIILTY_NATIVE_REGISTER_CONTEXT_REGISTER_INFO +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NATIVEREGISTERCONTEXTREGISTERINFO_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NATIVEREGISTERCONTEXTREGISTERINFO_H #include @@ -33,7 +33,7 @@ public: const RegisterInfoInterface &GetRegisterInfoInterface() const; -private: +protected: std::unique_ptr m_register_info_interface_up; }; } diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp index 29967deb7e9..ffdfd19b4ef 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp @@ -1,4 +1,4 @@ -//===-- NetBSDSignals.cpp --------------------------------------*- C++ -*-===// +//===-- NetBSDSignals.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/NetBSDSignals.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/NetBSDSignals.h index bf7399a8906..e6740a304a0 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/NetBSDSignals.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/NetBSDSignals.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_NetBSDSignals_H_ -#define liblldb_NetBSDSignals_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NETBSDSIGNALS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NETBSDSIGNALS_H #include "lldb/Target/UnixSignals.h" @@ -24,4 +24,4 @@ private: } // namespace lldb_private -#endif // liblldb_NetBSDSignals_H_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NETBSDSIGNALS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h index ef40162984f..21582df91fb 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_REGISTERCONTEXTDARWINCONSTANTS_H -#define LLDB_REGISTERCONTEXTDARWINCONSTANTS_H +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWINCONSTANTS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWINCONSTANTS_H namespace lldb_private { @@ -22,4 +22,4 @@ namespace lldb_private { } // namespace lldb_private -#endif // LLDB_REGISTERCONTEXTDARWINCONSTANTS_H +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWINCONSTANTS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp index 173e6690415..eef4541e7ed 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextDarwin_arm.cpp ---------------------------*- C++ -*-===// +//===-- RegisterContextDarwin_arm.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h index d7c1809a322..1bd60f75648 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextDarwin_arm_h_ -#define liblldb_RegisterContextDarwin_arm_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM_H #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" @@ -261,4 +261,4 @@ protected: static const lldb_private::RegisterInfo *GetRegisterInfos(); }; -#endif // liblldb_RegisterContextDarwin_arm_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp index fa5197cd6bf..9fc27527669 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp @@ -1,5 +1,4 @@ -//===-- RegisterContextDarwin_arm64.cpp ---------------------------*- C++ -//-*-===// +//===-- RegisterContextDarwin_arm64.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h index abb87e3c234..010e566be32 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextDarwin_arm64_h_ -#define liblldb_RegisterContextDarwin_arm64_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM64_H #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" @@ -228,4 +228,4 @@ protected: static const lldb_private::RegisterInfo *GetRegisterInfos(); }; -#endif // liblldb_RegisterContextDarwin_arm64_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM64_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp index 959b04700b1..c5ebddc56b6 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextDarwin_i386.cpp --------------------------*- C++ -*-===// +//===-- RegisterContextDarwin_i386.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h index e52f0fe6325..9c759c31cae 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextDarwin_i386_h_ -#define liblldb_RegisterContextDarwin_i386_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_I386_H #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" @@ -205,4 +205,4 @@ protected: static const lldb_private::RegisterInfo *GetRegisterInfos(); }; -#endif // liblldb_RegisterContextDarwin_i386_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_I386_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp index 22088a7d644..38cd00aea9c 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextDarwin_x86_64.cpp ------------------------*- C++ -*-===// +//===-- RegisterContextDarwin_x86_64.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h index 1a65a4f28b3..d9ba8d0b231 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextDarwin_x86_64_h_ -#define liblldb_RegisterContextDarwin_x86_64_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_X86_64_H #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" @@ -210,4 +210,4 @@ protected: static const lldb_private::RegisterInfo *GetRegisterInfos(); }; -#endif // liblldb_RegisterContextDarwin_x86_64_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_X86_64_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp index 6832b609593..4c2e291c62d 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp @@ -1,5 +1,4 @@ -//===-- RegisterContextDummy.cpp ---------------------------------*- C++ -//-*-===// +//===-- RegisterContextDummy.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h index bdaa2217d20..de98767693f 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_RegisterContextDummy_h_ -#define lldb_RegisterContextDummy_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDUMMY_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDUMMY_H #include @@ -56,9 +56,10 @@ private: lldb_private::RegisterSet m_reg_set0; // register set 0 (PC only) lldb_private::RegisterInfo m_pc_reg_info; - DISALLOW_COPY_AND_ASSIGN(RegisterContextDummy); + RegisterContextDummy(const RegisterContextDummy &) = delete; + const RegisterContextDummy &operator=(const RegisterContextDummy &) = delete; }; } // namespace lldb_private -#endif // lldb_RegisterContextDummy_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDUMMY_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp index b90b3810826..10d346a3cb7 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextFreeBSD_i386.cpp ------------------------*- C++ -*-===// +//===-- RegisterContextFreeBSD_i386.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h index 7aadf3a0a4c..5a3e5b0551d 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextFreeBSD_i386_H_ -#define liblldb_RegisterContextFreeBSD_i386_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_I386_H #include "RegisterInfoInterface.h" diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp index 4331ef5ad14..0c5d34f345d 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextFreeBSD_mips64.cpp ----------------------*- C++ -*-===// +//===-- RegisterContextFreeBSD_mips64.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h index 96f02b4440c..39968eacf47 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextFreeBSD_mips64_H_ -#define liblldb_RegisterContextFreeBSD_mips64_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_MIPS64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_MIPS64_H #include "RegisterInfoInterface.h" diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp index 4f869eb3b17..9fe6255d698 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextFreeBSD_powerpc.cpp ----------------------*- C++ -*-===// +//===-- RegisterContextFreeBSD_powerpc.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h index ba2751194d1..7e4c43ba908 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextFreeBSD_powerpc_h_ -#define liblldb_RegisterContextFreeBSD_powerpc_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_POWERPC_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_POWERPC_H #include "RegisterInfoInterface.h" @@ -49,4 +49,4 @@ public: uint32_t GetRegisterCount() const override; }; -#endif // liblldb_RegisterContextFreeBSD_powerpc_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_POWERPC_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp index bcf3951ee07..c1f390ade9b 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextFreeBSD_x86_64.cpp ----------------------*- C++ -*-===// +//===-- RegisterContextFreeBSD_x86_64.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h index c379e1a5cd7..d0f69fde181 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextFreeBSD_x86_64_H_ -#define liblldb_RegisterContextFreeBSD_x86_64_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_X86_64_H #include "RegisterInfoInterface.h" diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp index c19a2bfae66..57795873890 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp @@ -1,5 +1,4 @@ -//===-- RegisterContextHistory.cpp ---------------------------------*- C++ -//-*-===// +//===-- RegisterContextHistory.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h index 952e4263d95..407640d2bdb 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_RegisterContextHistory_h_ -#define lldb_RegisterContextHistory_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTHISTORY_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTHISTORY_H #include @@ -58,8 +58,10 @@ private: lldb::addr_t m_pc_value; - DISALLOW_COPY_AND_ASSIGN(RegisterContextHistory); + RegisterContextHistory(const RegisterContextHistory &) = delete; + const RegisterContextHistory & + operator=(const RegisterContextHistory &) = delete; }; } // namespace lldb_private -#endif // lldb_RegisterContextHistory_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTHISTORY_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp index 79979639dc7..518dc273faf 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextLinux_i386.cpp --------------------------*- C++ -*-===// +//===-- RegisterContextLinux_i386.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h index 5567a1ac42e..ef731a5a799 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextLinux_i386_H_ -#define liblldb_RegisterContextLinux_i386_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_I386_H #include "RegisterInfoInterface.h" diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp index fc60fea7917..837549e2a49 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextLinux_mips.cpp ------------------------*- C++ -*-===// +//===-- RegisterContextLinux_mips.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h index e637dfc15e4..9b59ab421ff 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextLinux_mips_H_ -#define liblldb_RegisterContextLinux_mips_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS_H #include "RegisterInfoInterface.h" #include "lldb/lldb-private.h" diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp index 3927883c47a..432a78129fd 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextLinux_mips64.cpp ------------------------*- C++ -*-===// +//===-- RegisterContextLinux_mips64.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h index ca0f0140a22..899f0a40e4a 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextLinux_mips64_H_ -#define liblldb_RegisterContextLinux_mips64_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS64_H #include "RegisterInfoInterface.h" #include "lldb/lldb-private.h" diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp index d6401d788ab..7a8989cd122 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextLinux_s390x.cpp --------------------------*- C++ -*-===// +//===-- RegisterContextLinux_s390x.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h index 10810c97af8..f381f38ecbf 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextLinux_s390x_h_ -#define liblldb_RegisterContextLinux_s390x_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_S390X_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_S390X_H #include "RegisterInfoInterface.h" diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp index 640d5bc0225..f9d4e23fcde 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextLinux_x86_64.cpp ------------------------*- C++ -*-===// +//===-- RegisterContextLinux_x86_64.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h index 02f273cb02c..ea21b913d5c 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextLinux_x86_64_H_ -#define liblldb_RegisterContextLinux_x86_64_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_X86_64_H #include "RegisterInfoInterface.h" diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp index c7042ab5137..1394cb7f00a 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextMach_arm.cpp -----------------------------*- C++ -*-===// +//===-- RegisterContextMach_arm.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h index 8b2425a193b..e7c180dbdd2 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextMach_arm_h_ -#define liblldb_RegisterContextMach_arm_h_ - +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_ARM_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_ARM_H #include "RegisterContextDarwin_arm.h" @@ -37,4 +36,4 @@ protected: int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg); }; -#endif // liblldb_RegisterContextMach_arm_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_ARM_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp index e631ab9bb26..b97166b6eeb 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextMach_i386.cpp ----------------------------*- C++ -*-===// +//===-- RegisterContextMach_i386.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h index b8835561e98..09966be60c9 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextMach_i386_h_ -#define liblldb_RegisterContextMach_i386_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_I386_H #include "RegisterContextDarwin_i386.h" @@ -32,4 +32,4 @@ protected: int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc); }; -#endif // liblldb_RegisterContextMach_i386_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_I386_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp index db17d7d8877..8933f136789 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextMach_x86_64.cpp --------------------------*- C++ -*-===// +//===-- RegisterContextMach_x86_64.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h index 688009aef8a..2a8a2cca2f8 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextMach_x86_64_h_ -#define liblldb_RegisterContextMach_x86_64_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_X86_64_H #include "RegisterContextDarwin_x86_64.h" @@ -33,4 +33,4 @@ protected: int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc); }; -#endif // liblldb_RegisterContextMach_x86_64_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_X86_64_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp index 946d4fa9f8e..f2d230b5405 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextMemory.cpp -------------------------------*- C++ -*-===// +//===-- RegisterContextMemory.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h index 68223eaeffd..764ee9b9721 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_RegisterContextMemory_h_ -#define lldb_RegisterContextMemory_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMEMORY_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMEMORY_H #include @@ -67,7 +67,9 @@ protected: // context that is stored in memmory private: - DISALLOW_COPY_AND_ASSIGN(RegisterContextMemory); + RegisterContextMemory(const RegisterContextMemory &) = delete; + const RegisterContextMemory & + operator=(const RegisterContextMemory &) = delete; }; -#endif // lldb_RegisterContextMemory_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMEMORY_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp new file mode 100644 index 00000000000..bd7830e42b4 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp @@ -0,0 +1,96 @@ +//===-- RegisterContextNetBSD_i386.cpp -------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#include "RegisterContextNetBSD_i386.h" +#include "RegisterContextPOSIX_x86.h" + +using namespace lldb_private; +using namespace lldb; + +// this needs to match 'struct reg' +struct GPR { + uint32_t eax; + uint32_t ecx; + uint32_t edx; + uint32_t ebx; + uint32_t esp; + uint32_t ebp; + uint32_t esi; + uint32_t edi; + uint32_t eip; + uint32_t eflags; + uint32_t cs; + uint32_t ss; + uint32_t ds; + uint32_t es; + uint32_t fs; + uint32_t gs; +}; + +struct FPR_i386 { + uint16_t fctrl; // FPU Control Word (fcw) + uint16_t fstat; // FPU Status Word (fsw) + uint16_t ftag; // FPU Tag Word (ftw) + uint16_t fop; // Last Instruction Opcode (fop) + union { + struct { + uint64_t fip; // Instruction Pointer + uint64_t fdp; // Data Pointer + } x86_64; + struct { + uint32_t fioff; // FPU IP Offset (fip) + uint32_t fiseg; // FPU IP Selector (fcs) + uint32_t fooff; // FPU Operand Pointer Offset (foo) + uint32_t foseg; // FPU Operand Pointer Selector (fos) + } i386_; // Added _ in the end to avoid error with gcc defining i386 in some + // cases + } ptr; + uint32_t mxcsr; // MXCSR Register State + uint32_t mxcsrmask; // MXCSR Mask + MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes + XMMReg xmm[8]; // 8*16 bytes for each XMM-reg = 128 bytes + uint32_t padding[56]; +}; + +struct UserArea { + GPR gpr; + FPR_i386 i387; + uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7). + uint32_t tlsbase; +}; + +#define DR_SIZE sizeof(((UserArea *)NULL)->u_debugreg[0]) +#define DR_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, u_debugreg[reg_index])) + +// Include RegisterInfos_i386 to declare our g_register_infos_i386 structure. +#define DECLARE_REGISTER_INFOS_I386_STRUCT +#include "RegisterInfos_i386.h" +#undef DECLARE_REGISTER_INFOS_I386_STRUCT + +RegisterContextNetBSD_i386::RegisterContextNetBSD_i386( + const ArchSpec &target_arch) + : RegisterInfoInterface(target_arch) {} + +size_t RegisterContextNetBSD_i386::GetGPRSize() const { return sizeof(GPR); } + +const RegisterInfo *RegisterContextNetBSD_i386::GetRegisterInfo() const { + switch (m_target_arch.GetMachine()) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: + return g_register_infos_i386; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +uint32_t RegisterContextNetBSD_i386::GetRegisterCount() const { + return static_cast(sizeof(g_register_infos_i386) / + sizeof(g_register_infos_i386[0])); +} diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.h new file mode 100644 index 00000000000..742bb18b830 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.h @@ -0,0 +1,25 @@ +//===-- RegisterContextNetBSD_i386.h ----------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTNETBSD_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTNETBSD_I386_H + +#include "RegisterInfoInterface.h" + +class RegisterContextNetBSD_i386 : public lldb_private::RegisterInfoInterface { +public: + RegisterContextNetBSD_i386(const lldb_private::ArchSpec &target_arch); + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; +}; + +#endif diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp index e620ff66c92..21aad92ecda 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextNetBSD_x86_64.cpp ------------------------*- C++ -*-===// +//===-- RegisterContextNetBSD_x86_64.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "RegisterContextNetBSD_x86_64.h" +#include "RegisterContextNetBSD_i386.h" #include "RegisterContextPOSIX_x86.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" @@ -83,9 +84,40 @@ struct UserArea { #include "RegisterInfos_x86_64.h" #undef DECLARE_REGISTER_INFOS_X86_64_STRUCT +static std::vector &GetPrivateRegisterInfoVector() { + static std::vector g_register_infos; + return g_register_infos; +} + +static const RegisterInfo * +GetRegisterInfo_i386(const lldb_private::ArchSpec &arch) { + std::vector &g_register_infos = + GetPrivateRegisterInfoVector(); + + // Allocate RegisterInfo only once + if (g_register_infos.empty()) { + // Copy the register information from base class + std::unique_ptr reg_interface( + new RegisterContextNetBSD_i386(arch)); + const RegisterInfo *base_info = reg_interface->GetRegisterInfo(); + g_register_infos.insert(g_register_infos.end(), &base_info[0], + &base_info[k_num_registers_i386]); + +// Include RegisterInfos_x86_64 to update the g_register_infos structure +// with x86_64 offsets. +#define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS +#include "RegisterInfos_x86_64.h" +#undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS + } + + return &g_register_infos[0]; +} + static const RegisterInfo * PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) { switch (target_arch.GetMachine()) { + case llvm::Triple::x86: + return GetRegisterInfo_i386(target_arch); case llvm::Triple::x86_64: return g_register_infos_x86_64; default: @@ -97,6 +129,11 @@ PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) { static uint32_t PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) { switch (target_arch.GetMachine()) { + case llvm::Triple::x86: { + assert(!GetPrivateRegisterInfoVector().empty() && + "i386 register info not yet filled."); + return static_cast(GetPrivateRegisterInfoVector().size()); + } case llvm::Triple::x86_64: return static_cast(sizeof(g_register_infos_x86_64) / sizeof(g_register_infos_x86_64[0])); @@ -106,11 +143,25 @@ PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) { } } +static uint32_t +PrivateGetUserRegisterCount(const lldb_private::ArchSpec &target_arch) { + switch (target_arch.GetMachine()) { + case llvm::Triple::x86: + return static_cast(k_num_user_registers_i386); + case llvm::Triple::x86_64: + return static_cast(k_num_user_registers_x86_64); + default: + assert(false && "Unhandled target architecture."); + return 0; + } +} + RegisterContextNetBSD_x86_64::RegisterContextNetBSD_x86_64( const ArchSpec &target_arch) : lldb_private::RegisterInfoInterface(target_arch), m_register_info_p(PrivateGetRegisterInfoPtr(target_arch)), - m_register_count(PrivateGetRegisterCount(target_arch)) {} + m_register_count(PrivateGetRegisterCount(target_arch)), + m_user_register_count(PrivateGetUserRegisterCount(target_arch)) {} size_t RegisterContextNetBSD_x86_64::GetGPRSize() const { return sizeof(GPR); } @@ -121,3 +172,7 @@ const RegisterInfo *RegisterContextNetBSD_x86_64::GetRegisterInfo() const { uint32_t RegisterContextNetBSD_x86_64::GetRegisterCount() const { return m_register_count; } + +uint32_t RegisterContextNetBSD_x86_64::GetUserRegisterCount() const { + return m_user_register_count; +} diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h index 4820ef8d17b..b7b8d33b7c3 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextNetBSD_x86_64_H_ -#define liblldb_RegisterContextNetBSD_x86_64_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTNETBSD_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTNETBSD_X86_64_H #include "RegisterInfoInterface.h" @@ -22,9 +22,12 @@ public: uint32_t GetRegisterCount() const override; + uint32_t GetUserRegisterCount() const override; + private: const lldb_private::RegisterInfo *m_register_info_p; const uint32_t m_register_count; + const uint32_t m_user_register_count; }; #endif diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp index 06eac6f7f99..7183ffcfd0f 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextOpenBSD_i386.cpp ------------------------*- C++ -*-===// +//===-- RegisterContextOpenBSD_i386.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h index 992ce0959fd..e6e24525b7f 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextOpenBSD_i386_H_ -#define liblldb_RegisterContextOpenBSD_i386_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTOPENBSD_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTOPENBSD_I386_H #include "RegisterInfoInterface.h" diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp index e210196d921..05c1f83efde 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextOpenBSD_x86_64.cpp ----------------------*- C++ -*-===// +//===-- RegisterContextOpenBSD_x86_64.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h index 9c76e721113..b399c721546 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextOpenBSD_x86_64_H_ -#define liblldb_RegisterContextOpenBSD_x86_64_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTOPENBSD_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTOPENBSD_X86_64_H #include "RegisterInfoInterface.h" diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp index 821e2aa73b5..617893b6b3b 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIX_arm.cpp --------------------------*- C++ -*-===// +//===-- RegisterContextPOSIX_arm.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -178,35 +178,6 @@ const char *RegisterContextPOSIX_arm::GetRegisterName(unsigned reg) { return GetRegisterInfo()[reg].name; } -lldb::ByteOrder RegisterContextPOSIX_arm::GetByteOrder() { - // Get the target process whose privileged thread was used for the register - // read. - lldb::ByteOrder byte_order = lldb::eByteOrderInvalid; - lldb_private::Process *process = CalculateProcess().get(); - - if (process) - byte_order = process->GetByteOrder(); - return byte_order; -} - bool RegisterContextPOSIX_arm::IsRegisterSetAvailable(size_t set_index) { return set_index < k_num_register_sets; } - -// Used when parsing DWARF and EH frame information and any other object file -// sections that contain register numbers in them. -uint32_t RegisterContextPOSIX_arm::ConvertRegisterKindToRegisterNumber( - lldb::RegisterKind kind, uint32_t num) { - const uint32_t num_regs = GetRegisterCount(); - - assert(kind < lldb::kNumRegisterKinds); - for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { - const lldb_private::RegisterInfo *reg_info = - GetRegisterInfoAtIndex(reg_idx); - - if (reg_info->kinds[kind] == num) - return reg_idx; - } - - return LLDB_INVALID_REGNUM; -} diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h index 603ba76430e..d6967f05ed4 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextPOSIX_arm_h_ -#define liblldb_RegisterContextPOSIX_arm_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM_H #include "RegisterInfoInterface.h" #include "lldb-arm-register-enums.h" @@ -44,9 +44,6 @@ public: const char *GetRegisterName(unsigned reg); - uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, - uint32_t num) override; - protected: struct RegInfo { uint32_t num_registers; @@ -95,12 +92,10 @@ protected: bool IsFPR(unsigned reg); - lldb::ByteOrder GetByteOrder(); - virtual bool ReadGPR() = 0; virtual bool ReadFPR() = 0; virtual bool WriteGPR() = 0; virtual bool WriteFPR() = 0; }; -#endif // liblldb_RegisterContextPOSIX_arm_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp index db1aa1b8b09..8ef587f13e3 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIX_arm64.cpp --------------------------*- C++ -*-===// +//===-- RegisterContextPOSIX_arm64.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,105 +25,25 @@ using namespace lldb; using namespace lldb_private; -// ARM64 general purpose registers. -const uint32_t g_gpr_regnums_arm64[] = { - gpr_x0_arm64, gpr_x1_arm64, gpr_x2_arm64, gpr_x3_arm64, - gpr_x4_arm64, gpr_x5_arm64, gpr_x6_arm64, gpr_x7_arm64, - gpr_x8_arm64, gpr_x9_arm64, gpr_x10_arm64, gpr_x11_arm64, - gpr_x12_arm64, gpr_x13_arm64, gpr_x14_arm64, gpr_x15_arm64, - gpr_x16_arm64, gpr_x17_arm64, gpr_x18_arm64, gpr_x19_arm64, - gpr_x20_arm64, gpr_x21_arm64, gpr_x22_arm64, gpr_x23_arm64, - gpr_x24_arm64, gpr_x25_arm64, gpr_x26_arm64, gpr_x27_arm64, - gpr_x28_arm64, gpr_fp_arm64, gpr_lr_arm64, gpr_sp_arm64, - gpr_pc_arm64, gpr_cpsr_arm64, gpr_w0_arm64, gpr_w1_arm64, - gpr_w2_arm64, gpr_w3_arm64, gpr_w4_arm64, gpr_w5_arm64, - gpr_w6_arm64, gpr_w7_arm64, gpr_w8_arm64, gpr_w9_arm64, - gpr_w10_arm64, gpr_w11_arm64, gpr_w12_arm64, gpr_w13_arm64, - gpr_w14_arm64, gpr_w15_arm64, gpr_w16_arm64, gpr_w17_arm64, - gpr_w18_arm64, gpr_w19_arm64, gpr_w20_arm64, gpr_w21_arm64, - gpr_w22_arm64, gpr_w23_arm64, gpr_w24_arm64, gpr_w25_arm64, - gpr_w26_arm64, gpr_w27_arm64, gpr_w28_arm64, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; -static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) - - 1) == k_num_gpr_registers_arm64, - "g_gpr_regnums_arm64 has wrong number of register infos"); - -// ARM64 floating point registers. -static const uint32_t g_fpu_regnums_arm64[] = { - fpu_v0_arm64, fpu_v1_arm64, fpu_v2_arm64, fpu_v3_arm64, - fpu_v4_arm64, fpu_v5_arm64, fpu_v6_arm64, fpu_v7_arm64, - fpu_v8_arm64, fpu_v9_arm64, fpu_v10_arm64, fpu_v11_arm64, - fpu_v12_arm64, fpu_v13_arm64, fpu_v14_arm64, fpu_v15_arm64, - fpu_v16_arm64, fpu_v17_arm64, fpu_v18_arm64, fpu_v19_arm64, - fpu_v20_arm64, fpu_v21_arm64, fpu_v22_arm64, fpu_v23_arm64, - fpu_v24_arm64, fpu_v25_arm64, fpu_v26_arm64, fpu_v27_arm64, - fpu_v28_arm64, fpu_v29_arm64, fpu_v30_arm64, fpu_v31_arm64, - fpu_s0_arm64, fpu_s1_arm64, fpu_s2_arm64, fpu_s3_arm64, - fpu_s4_arm64, fpu_s5_arm64, fpu_s6_arm64, fpu_s7_arm64, - fpu_s8_arm64, fpu_s9_arm64, fpu_s10_arm64, fpu_s11_arm64, - fpu_s12_arm64, fpu_s13_arm64, fpu_s14_arm64, fpu_s15_arm64, - fpu_s16_arm64, fpu_s17_arm64, fpu_s18_arm64, fpu_s19_arm64, - fpu_s20_arm64, fpu_s21_arm64, fpu_s22_arm64, fpu_s23_arm64, - fpu_s24_arm64, fpu_s25_arm64, fpu_s26_arm64, fpu_s27_arm64, - fpu_s28_arm64, fpu_s29_arm64, fpu_s30_arm64, fpu_s31_arm64, - - fpu_d0_arm64, fpu_d1_arm64, fpu_d2_arm64, fpu_d3_arm64, - fpu_d4_arm64, fpu_d5_arm64, fpu_d6_arm64, fpu_d7_arm64, - fpu_d8_arm64, fpu_d9_arm64, fpu_d10_arm64, fpu_d11_arm64, - fpu_d12_arm64, fpu_d13_arm64, fpu_d14_arm64, fpu_d15_arm64, - fpu_d16_arm64, fpu_d17_arm64, fpu_d18_arm64, fpu_d19_arm64, - fpu_d20_arm64, fpu_d21_arm64, fpu_d22_arm64, fpu_d23_arm64, - fpu_d24_arm64, fpu_d25_arm64, fpu_d26_arm64, fpu_d27_arm64, - fpu_d28_arm64, fpu_d29_arm64, fpu_d30_arm64, fpu_d31_arm64, - fpu_fpsr_arm64, fpu_fpcr_arm64, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; -static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) - - 1) == k_num_fpr_registers_arm64, - "g_fpu_regnums_arm64 has wrong number of register infos"); - -// Number of register sets provided by this context. -enum { k_num_register_sets = 2 }; - -// Register sets for ARM64. -static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets] = { - {"General Purpose Registers", "gpr", k_num_gpr_registers_arm64, - g_gpr_regnums_arm64}, - {"Floating Point Registers", "fpu", k_num_fpr_registers_arm64, - g_fpu_regnums_arm64}}; - bool RegisterContextPOSIX_arm64::IsGPR(unsigned reg) { - return reg <= m_reg_info.last_gpr; // GPR's come first. + if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) == + RegisterInfoPOSIX_arm64::GPRegSet) + return true; + return false; } bool RegisterContextPOSIX_arm64::IsFPR(unsigned reg) { - return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr); + if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) == + RegisterInfoPOSIX_arm64::FPRegSet) + return true; + return false; } RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64( - lldb_private::Thread &thread, uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info) - : lldb_private::RegisterContext(thread, concrete_frame_idx) { - m_register_info_up.reset(register_info); - - switch (register_info->m_target_arch.GetMachine()) { - case llvm::Triple::aarch64: - case llvm::Triple::aarch64_32: - m_reg_info.num_registers = k_num_registers_arm64; - m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64; - m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64; - m_reg_info.last_gpr = k_last_gpr_arm64; - m_reg_info.first_fpr = k_first_fpr_arm64; - m_reg_info.last_fpr = k_last_fpr_arm64; - m_reg_info.first_fpr_v = fpu_v0_arm64; - m_reg_info.last_fpr_v = fpu_v31_arm64; - m_reg_info.gpr_flags = gpr_cpsr_arm64; - break; - default: - assert(false && "Unhandled target architecture."); - break; - } + lldb_private::Thread &thread, + std::unique_ptr register_info) + : lldb_private::RegisterContext(thread, 0), + m_register_info_up(std::move(register_info)) { ::memset(&m_fpr, 0, sizeof m_fpr); } @@ -135,19 +55,15 @@ void RegisterContextPOSIX_arm64::Invalidate() {} void RegisterContextPOSIX_arm64::InvalidateAllRegisters() {} unsigned RegisterContextPOSIX_arm64::GetRegisterOffset(unsigned reg) { - assert(reg < m_reg_info.num_registers && "Invalid register number."); - return GetRegisterInfo()[reg].byte_offset; + return m_register_info_up->GetRegisterInfo()[reg].byte_offset; } unsigned RegisterContextPOSIX_arm64::GetRegisterSize(unsigned reg) { - assert(reg < m_reg_info.num_registers && "Invalid register number."); - return GetRegisterInfo()[reg].byte_size; + return m_register_info_up->GetRegisterInfo()[reg].byte_size; } size_t RegisterContextPOSIX_arm64::GetRegisterCount() { - size_t num_registers = - m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers; - return num_registers; + return m_register_info_up->GetRegisterCount(); } size_t RegisterContextPOSIX_arm64::GetGPRSize() { @@ -164,71 +80,23 @@ RegisterContextPOSIX_arm64::GetRegisterInfo() { const lldb_private::RegisterInfo * RegisterContextPOSIX_arm64::GetRegisterInfoAtIndex(size_t reg) { - if (reg < m_reg_info.num_registers) + if (reg < GetRegisterCount()) return &GetRegisterInfo()[reg]; else return nullptr; } size_t RegisterContextPOSIX_arm64::GetRegisterSetCount() { - size_t sets = 0; - for (size_t set = 0; set < k_num_register_sets; ++set) { - if (IsRegisterSetAvailable(set)) - ++sets; - } - - return sets; + return m_register_info_up->GetRegisterSetCount(); } const lldb_private::RegisterSet * RegisterContextPOSIX_arm64::GetRegisterSet(size_t set) { - if (IsRegisterSetAvailable(set)) { - switch (m_register_info_up->m_target_arch.GetMachine()) { - case llvm::Triple::aarch64: - case llvm::Triple::aarch64_32: - return &g_reg_sets_arm64[set]; - default: - assert(false && "Unhandled target architecture."); - return nullptr; - } - } - return nullptr; + return m_register_info_up->GetRegisterSet(set); } const char *RegisterContextPOSIX_arm64::GetRegisterName(unsigned reg) { - assert(reg < m_reg_info.num_registers && "Invalid register offset."); - return GetRegisterInfo()[reg].name; -} - -lldb::ByteOrder RegisterContextPOSIX_arm64::GetByteOrder() { - // Get the target process whose privileged thread was used for the register - // read. - lldb::ByteOrder byte_order = lldb::eByteOrderInvalid; - lldb_private::Process *process = CalculateProcess().get(); - - if (process) - byte_order = process->GetByteOrder(); - return byte_order; -} - -bool RegisterContextPOSIX_arm64::IsRegisterSetAvailable(size_t set_index) { - return set_index < k_num_register_sets; -} - -// Used when parsing DWARF and EH frame information and any other object file -// sections that contain register numbers in them. -uint32_t RegisterContextPOSIX_arm64::ConvertRegisterKindToRegisterNumber( - lldb::RegisterKind kind, uint32_t num) { - const uint32_t num_regs = GetRegisterCount(); - - assert(kind < lldb::kNumRegisterKinds); - for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { - const lldb_private::RegisterInfo *reg_info = - GetRegisterInfoAtIndex(reg_idx); - - if (reg_info->kinds[kind] == num) - return reg_idx; - } - - return LLDB_INVALID_REGNUM; + if (reg < GetRegisterCount()) + return GetRegisterInfo()[reg].name; + return nullptr; } diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h index 49a49b69da6..c2d5aee7f73 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h @@ -6,10 +6,11 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextPOSIX_arm64_h_ -#define liblldb_RegisterContextPOSIX_arm64_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM64_H #include "RegisterInfoInterface.h" +#include "RegisterInfoPOSIX_arm64.h" #include "lldb-arm64-register-enums.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/Log.h" @@ -19,8 +20,8 @@ class ProcessMonitor; class RegisterContextPOSIX_arm64 : public lldb_private::RegisterContext { public: RegisterContextPOSIX_arm64( - lldb_private::Thread &thread, uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info); + lldb_private::Thread &thread, + std::unique_ptr register_info); ~RegisterContextPOSIX_arm64() override; @@ -44,50 +45,15 @@ public: const char *GetRegisterName(unsigned reg); - uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, - uint32_t num) override; - protected: - struct RegInfo { - uint32_t num_registers; - uint32_t num_gpr_registers; - uint32_t num_fpr_registers; - - uint32_t last_gpr; - uint32_t first_fpr; - uint32_t last_fpr; - - uint32_t first_fpr_v; - uint32_t last_fpr_v; - - uint32_t gpr_flags; - }; - - // based on RegisterContextDarwin_arm64.h - struct VReg { - uint8_t bytes[16]; - }; - - // based on RegisterContextDarwin_arm64.h - struct FPU { - VReg v[32]; - uint32_t fpsr; - uint32_t fpcr; - }; - uint64_t m_gpr_arm64[lldb_private::k_num_gpr_registers_arm64]; // 64-bit // general // purpose // registers. - RegInfo m_reg_info; - struct RegisterContextPOSIX_arm64::FPU - m_fpr; // floating-point registers including extended register sets. - std::unique_ptr - m_register_info_up; // Register Info Interface (FreeBSD or Linux) - // Determines if an extended register set is supported on the processor - // running the inferior process. - virtual bool IsRegisterSetAvailable(size_t set_index); + struct RegisterInfoPOSIX_arm64::FPU + m_fpr; // floating-point registers including extended register sets. + std::unique_ptr m_register_info_up; virtual const lldb_private::RegisterInfo *GetRegisterInfo(); @@ -95,7 +61,7 @@ protected: bool IsFPR(unsigned reg); - lldb::ByteOrder GetByteOrder(); + size_t GetFPUSize() { return sizeof(RegisterInfoPOSIX_arm64::FPU); } virtual bool ReadGPR() = 0; virtual bool ReadFPR() = 0; @@ -103,4 +69,4 @@ protected: virtual bool WriteFPR() = 0; }; -#endif // liblldb_RegisterContextPOSIX_arm64_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM64_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp index f1fa3035b2e..c41c4bd7a7e 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIX_mips64.cpp -------------------------*- C++ -*-===// +//===-- RegisterContextPOSIX_mips64.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -149,17 +149,6 @@ const char *RegisterContextPOSIX_mips64::GetRegisterName(unsigned reg) { return GetRegisterInfo()[reg].name; } -lldb::ByteOrder RegisterContextPOSIX_mips64::GetByteOrder() { - // Get the target process whose privileged thread was used for the register - // read. - lldb::ByteOrder byte_order = eByteOrderInvalid; - Process *process = CalculateProcess().get(); - - if (process) - byte_order = process->GetByteOrder(); - return byte_order; -} - bool RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index) { size_t num_sets = GetRegisterSetCount(); diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h index c507e14bd5b..1843a2a6aff 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextPOSIX_mips64_h_ -#define liblldb_RegisterContextPOSIX_mips64_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_MIPS64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_MIPS64_H #include "RegisterContext_mips.h" #include "RegisterInfoInterface.h" @@ -73,12 +73,10 @@ protected: bool IsFPR(unsigned reg); - lldb::ByteOrder GetByteOrder(); - virtual bool ReadGPR() = 0; virtual bool ReadFPR() = 0; virtual bool WriteGPR() = 0; virtual bool WriteFPR() = 0; }; -#endif // liblldb_RegisterContextPOSIX_mips64_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_MIPS64_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp index a78e9ed3794..cd65b96d373 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp @@ -1,5 +1,4 @@ -//===-- RegisterContextPOSIX_powerpc.cpp -------------------------*- C++ -//-*-===// +//===-- RegisterContextPOSIX_powerpc.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -158,36 +157,8 @@ const char *RegisterContextPOSIX_powerpc::GetRegisterName(unsigned reg) { return GetRegisterInfo()[reg].name; } -lldb::ByteOrder RegisterContextPOSIX_powerpc::GetByteOrder() { - // Get the target process whose privileged thread was used for the register - // read. - lldb::ByteOrder byte_order = eByteOrderInvalid; - Process *process = CalculateProcess().get(); - - if (process) - byte_order = process->GetByteOrder(); - return byte_order; -} - bool RegisterContextPOSIX_powerpc::IsRegisterSetAvailable(size_t set_index) { size_t num_sets = k_num_register_sets; return (set_index < num_sets); } - -// Used when parsing DWARF and EH frame information and any other object file -// sections that contain register numbers in them. -uint32_t RegisterContextPOSIX_powerpc::ConvertRegisterKindToRegisterNumber( - lldb::RegisterKind kind, uint32_t num) { - const uint32_t num_regs = GetRegisterCount(); - - assert(kind < kNumRegisterKinds); - for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { - const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx); - - if (reg_info->kinds[kind] == num) - return reg_idx; - } - - return LLDB_INVALID_REGNUM; -} diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h index 1a21a717b22..e2c33461c8f 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextPOSIX_powerpc_h_ -#define liblldb_RegisterContextPOSIX_powerpc_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_POWERPC_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_POWERPC_H #include "RegisterContext_powerpc.h" #include "RegisterInfoInterface.h" @@ -165,9 +165,6 @@ public: const char *GetRegisterName(unsigned reg); - uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, - uint32_t num) override; - protected: uint64_t m_gpr_powerpc[k_num_gpr_registers_powerpc]; // general purpose registers. @@ -189,8 +186,6 @@ protected: bool IsVMX(unsigned reg); - lldb::ByteOrder GetByteOrder(); - virtual bool ReadGPR() = 0; virtual bool ReadFPR() = 0; virtual bool ReadVMX() = 0; @@ -199,4 +194,4 @@ protected: virtual bool WriteVMX() = 0; }; -#endif // liblldb_RegisterContextPOSIX_powerpc_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_POWERPC_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp index 02546c0ed16..f670be2ef3c 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIX_ppc64le.cpp -------------------------*- C++-*-===// +//===-- RegisterContextPOSIX_ppc64le.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -176,36 +176,8 @@ const char *RegisterContextPOSIX_ppc64le::GetRegisterName(unsigned reg) { return GetRegisterInfo()[reg].name; } -lldb::ByteOrder RegisterContextPOSIX_ppc64le::GetByteOrder() { - // Get the target process whose privileged thread was used for the register - // read. - lldb::ByteOrder byte_order = eByteOrderInvalid; - Process *process = CalculateProcess().get(); - - if (process) - byte_order = process->GetByteOrder(); - return byte_order; -} - bool RegisterContextPOSIX_ppc64le::IsRegisterSetAvailable(size_t set_index) { size_t num_sets = k_num_register_sets; return (set_index < num_sets); } - -// Used when parsing DWARF and EH frame information and any other object file -// sections that contain register numbers in them. -uint32_t RegisterContextPOSIX_ppc64le::ConvertRegisterKindToRegisterNumber( - lldb::RegisterKind kind, uint32_t num) { - const uint32_t num_regs = GetRegisterCount(); - - assert(kind < kNumRegisterKinds); - for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { - const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx); - - if (reg_info->kinds[kind] == num) - return reg_idx; - } - - return LLDB_INVALID_REGNUM; -} diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h index 37079775a3c..66794ec9e9c 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextPOSIX_ppc64le_h_ -#define liblldb_RegisterContextPOSIX_ppc64le_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_PPC64LE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_PPC64LE_H #include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h" #include "RegisterInfoInterface.h" @@ -39,9 +39,6 @@ public: const char *GetRegisterName(unsigned reg); - uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, - uint32_t num) override; - protected: // 64-bit general purpose registers. uint64_t m_gpr_ppc64le[k_num_gpr_registers_ppc64le]; @@ -71,7 +68,6 @@ protected: bool IsVSX(unsigned reg); - lldb::ByteOrder GetByteOrder(); }; -#endif // liblldb_RegisterContextPOSIX_ppc64le_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_PPC64LE_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp index e040e507572..e746ec642b3 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIX_s390x.cpp --------------------------*- C++ -*-===// +//===-- RegisterContextPOSIX_s390x.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -161,31 +161,3 @@ const RegisterSet *RegisterContextPOSIX_s390x::GetRegisterSet(size_t set) { } return nullptr; } - -lldb::ByteOrder RegisterContextPOSIX_s390x::GetByteOrder() { - // Get the target process whose privileged thread was used for the register - // read. - lldb::ByteOrder byte_order = eByteOrderInvalid; - Process *process = CalculateProcess().get(); - - if (process) - byte_order = process->GetByteOrder(); - return byte_order; -} - -// Used when parsing DWARF and EH frame information and any other object file -// sections that contain register numbers in them. -uint32_t RegisterContextPOSIX_s390x::ConvertRegisterKindToRegisterNumber( - lldb::RegisterKind kind, uint32_t num) { - const uint32_t num_regs = GetRegisterCount(); - - assert(kind < kNumRegisterKinds); - for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { - const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx); - - if (reg_info->kinds[kind] == num) - return reg_idx; - } - - return LLDB_INVALID_REGNUM; -} diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h index 54993ce6c3e..7df732d13ff 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextPOSIX_s390x_h_ -#define liblldb_RegisterContextPOSIX_s390x_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_S390X_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_S390X_H #include "RegisterContext_s390x.h" #include "RegisterInfoInterface.h" @@ -43,9 +43,6 @@ public: const char *GetRegisterName(unsigned reg); - uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, - uint32_t num) override; - protected: struct RegInfo { uint32_t num_registers; @@ -68,12 +65,10 @@ protected: bool IsFPR(unsigned reg); - lldb::ByteOrder GetByteOrder(); - virtual bool ReadGPR() = 0; virtual bool ReadFPR() = 0; virtual bool WriteGPR() = 0; virtual bool WriteFPR() = 0; }; -#endif // liblldb_RegisterContextPOSIX_s390x_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_S390X_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp index 4d5991f08f1..ac271a90d6a 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIX_x86.cpp ----------------------------*- C++ -*-===// +//===-- RegisterContextPOSIX_x86.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -456,17 +456,6 @@ const char *RegisterContextPOSIX_x86::GetRegisterName(unsigned reg) { return GetRegisterInfo()[reg].name; } -lldb::ByteOrder RegisterContextPOSIX_x86::GetByteOrder() { - // Get the target process whose privileged thread was used for the register - // read. - lldb::ByteOrder byte_order = eByteOrderInvalid; - Process *process = CalculateProcess().get(); - - if (process) - byte_order = process->GetByteOrder(); - return byte_order; -} - // Parse ymm registers and into xmm.bytes and ymmh.bytes. bool RegisterContextPOSIX_x86::CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order) { @@ -509,20 +498,3 @@ bool RegisterContextPOSIX_x86::IsRegisterSetAvailable(size_t set_index) { ++num_sets; return (set_index < num_sets); } - -// Used when parsing DWARF and EH frame information and any other object file -// sections that contain register numbers in them. -uint32_t RegisterContextPOSIX_x86::ConvertRegisterKindToRegisterNumber( - lldb::RegisterKind kind, uint32_t num) { - const uint32_t num_regs = GetRegisterCount(); - - assert(kind < kNumRegisterKinds); - for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { - const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx); - - if (reg_info->kinds[kind] == num) - return reg_idx; - } - - return LLDB_INVALID_REGNUM; -} diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h index 932f97bb567..c4886ae618a 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextPOSIX_x86_h_ -#define liblldb_RegisterContextPOSIX_x86_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_X86_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_X86_H #include "RegisterContext_x86.h" #include "RegisterInfoInterface.h" @@ -47,9 +47,6 @@ public: const char *GetRegisterName(unsigned reg); - uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, - uint32_t num) override; - // Note: prefer kernel definitions over user-land enum FPRType { eNotValid = 0, @@ -160,8 +157,6 @@ protected: bool IsAVX(unsigned reg); - lldb::ByteOrder GetByteOrder(); - bool CopyXSTATEtoYMM(uint32_t reg, lldb::ByteOrder byte_order); bool CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order); bool IsFPR(unsigned reg, FPRType fpr_type); @@ -173,4 +168,4 @@ protected: virtual bool WriteFPR() = 0; }; -#endif // liblldb_RegisterContextPOSIX_x86_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_X86_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp index bcf60cc7a33..31e2944084e 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextThreadMemory.cpp -------------------------*- C++ -*-===// +//===-- RegisterContextThreadMemory.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h index 09a679ab2c9..40688a502a6 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_RegisterContextThreadMemory_h_ -#define lldb_RegisterContextThreadMemory_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTTHREADMEMORY_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTTHREADMEMORY_H #include @@ -92,9 +92,11 @@ protected: uint32_t m_stop_id; private: - DISALLOW_COPY_AND_ASSIGN(RegisterContextThreadMemory); + RegisterContextThreadMemory(const RegisterContextThreadMemory &) = delete; + const RegisterContextThreadMemory & + operator=(const RegisterContextThreadMemory &) = delete; }; } // namespace lldb_private -#endif // lldb_RegisterContextThreadMemory_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTTHREADMEMORY_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp index 916d3233cde..11556e802e3 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextWindows_i386.cpp -------------------------*- C++ -*-===// +//===-- RegisterContextWindows_i386.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.h index 7779cc35752..6a5d3524300 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextWindows_i386_H_ -#define liblldb_RegisterContextWindows_i386_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTWINDOWS_I386_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTWINDOWS_I386_H #include "RegisterInfoInterface.h" diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp index e90584de1a4..4ffc4d25781 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextWindows_x86_64.cpp -----------------------*- C++ -*-===// +//===-- RegisterContextWindows_x86_64.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h index 18198b5b25b..c29acf28484 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextWindows_x86_64_H_ -#define liblldb_RegisterContextWindows_x86_64_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTWINDOWS_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTWINDOWS_X86_64_H #include "RegisterInfoInterface.h" diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContext_mips.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContext_mips.h index 7780be51baa..15081f974c6 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContext_mips.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContext_mips.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContext_mips64_H_ -#define liblldb_RegisterContext_mips64_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_MIPS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_MIPS_H #include #include @@ -371,4 +371,4 @@ struct UserArea { MSA_linux_mips msa; // MSA registers. }; -#endif // liblldb_RegisterContext_mips64_H_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_MIPS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h index 1ffcbeb5ec4..7407e2f402e 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContext_powerpc_H_ -#define liblldb_RegisterContext_powerpc_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_POWERPC_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_POWERPC_H // eh_frame and DWARF Register numbers (eRegisterKindEHFrame & // eRegisterKindDWARF) @@ -120,4 +120,4 @@ enum { dwarf_v31_powerpc, }; -#endif // liblldb_RegisterContext_powerpc_H_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_POWERPC_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h index 2cf39e9eb8e..248b3bd0bea 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContext_s390x_h_ -#define liblldb_RegisterContext_s390x_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_S390X_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_S390X_H // SystemZ ehframe, dwarf regnums diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h index 2b79f778aa5..27a1bad4d53 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContext_x86_H_ -#define liblldb_RegisterContext_x86_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_X86_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_X86_H #include #include diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoAndSetInterface.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoAndSetInterface.h new file mode 100644 index 00000000000..7e569dc9ba7 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoAndSetInterface.h @@ -0,0 +1,36 @@ +//===-- RegisterInfoAndSetInterface.h ---------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOANDSETINTERFACE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOANDSETINTERFACE_H + +#include "RegisterInfoInterface.h" + +#include "lldb/Utility/ArchSpec.h" +#include "lldb/lldb-private-types.h" +#include + +namespace lldb_private { + +class RegisterInfoAndSetInterface : public RegisterInfoInterface { +public: + RegisterInfoAndSetInterface(const lldb_private::ArchSpec &target_arch) + : RegisterInfoInterface(target_arch) {} + + virtual size_t GetFPRSize() const = 0; + + virtual const lldb_private::RegisterSet * + GetRegisterSet(size_t reg_set) const = 0; + + virtual size_t GetRegisterSetCount() const = 0; + + virtual size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const = 0; +}; +} // namespace lldb_private + +#endif diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h index 4b58e749adc..88c2ae7c501 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_RegisterInfoInterface_h -#define lldb_RegisterInfoInterface_h +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOINTERFACE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOINTERFACE_H #include "lldb/Utility/ArchSpec.h" #include "lldb/lldb-private-types.h" @@ -61,7 +61,6 @@ public: return nullptr; } -public: // FIXME make private. lldb_private::ArchSpec m_target_arch; }; diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp index d392d3be1c4..8fc4d5282b0 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp @@ -1,4 +1,4 @@ -//===-- RegisterInfoPOSIX_arm.cpp ------------------------------*- C++ -*-===// +//===-- RegisterInfoPOSIX_arm.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h index 39c2047600a..1cf896e3dec 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterInfoPOSIX_arm_h_ -#define liblldb_RegisterInfoPOSIX_arm_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM_H #include "RegisterInfoInterface.h" #include "lldb/Target/RegisterContext.h" @@ -58,4 +58,4 @@ private: uint32_t m_register_info_count; }; -#endif // liblldb_RegisterInfoPOSIX_arm_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp index 8b367bdc644..4537cee42ad 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterInfoPOSIX_arm64.cpp ----------------------------*- C++ -*-===// +//===-- RegisterInfoPOSIX_arm64.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -65,6 +65,82 @@ GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) { } } +// Number of register sets provided by this context. +enum { + k_num_gpr_registers = gpr_w28 - gpr_x0 + 1, + k_num_fpr_registers = fpu_fpcr - fpu_v0 + 1, + k_num_register_sets = 2 +}; + +// ARM64 general purpose registers. +static const uint32_t g_gpr_regnums_arm64[] = { + gpr_x0, gpr_x1, gpr_x2, gpr_x3, + gpr_x4, gpr_x5, gpr_x6, gpr_x7, + gpr_x8, gpr_x9, gpr_x10, gpr_x11, + gpr_x12, gpr_x13, gpr_x14, gpr_x15, + gpr_x16, gpr_x17, gpr_x18, gpr_x19, + gpr_x20, gpr_x21, gpr_x22, gpr_x23, + gpr_x24, gpr_x25, gpr_x26, gpr_x27, + gpr_x28, gpr_fp, gpr_lr, gpr_sp, + gpr_pc, gpr_cpsr, gpr_w0, gpr_w1, + gpr_w2, gpr_w3, gpr_w4, gpr_w5, + gpr_w6, gpr_w7, gpr_w8, gpr_w9, + gpr_w10, gpr_w11, gpr_w12, gpr_w13, + gpr_w14, gpr_w15, gpr_w16, gpr_w17, + gpr_w18, gpr_w19, gpr_w20, gpr_w21, + gpr_w22, gpr_w23, gpr_w24, gpr_w25, + gpr_w26, gpr_w27, gpr_w28, LLDB_INVALID_REGNUM}; + +static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) - + 1) == k_num_gpr_registers, + "g_gpr_regnums_arm64 has wrong number of register infos"); + +// ARM64 floating point registers. +static const uint32_t g_fpu_regnums_arm64[] = { + fpu_v0, fpu_v1, fpu_v2, + fpu_v3, fpu_v4, fpu_v5, + fpu_v6, fpu_v7, fpu_v8, + fpu_v9, fpu_v10, fpu_v11, + fpu_v12, fpu_v13, fpu_v14, + fpu_v15, fpu_v16, fpu_v17, + fpu_v18, fpu_v19, fpu_v20, + fpu_v21, fpu_v22, fpu_v23, + fpu_v24, fpu_v25, fpu_v26, + fpu_v27, fpu_v28, fpu_v29, + fpu_v30, fpu_v31, fpu_s0, + fpu_s1, fpu_s2, fpu_s3, + fpu_s4, fpu_s5, fpu_s6, + fpu_s7, fpu_s8, fpu_s9, + fpu_s10, fpu_s11, fpu_s12, + fpu_s13, fpu_s14, fpu_s15, + fpu_s16, fpu_s17, fpu_s18, + fpu_s19, fpu_s20, fpu_s21, + fpu_s22, fpu_s23, fpu_s24, + fpu_s25, fpu_s26, fpu_s27, + fpu_s28, fpu_s29, fpu_s30, + fpu_s31, fpu_d0, fpu_d1, + fpu_d2, fpu_d3, fpu_d4, + fpu_d5, fpu_d6, fpu_d7, + fpu_d8, fpu_d9, fpu_d10, + fpu_d11, fpu_d12, fpu_d13, + fpu_d14, fpu_d15, fpu_d16, + fpu_d17, fpu_d18, fpu_d19, + fpu_d20, fpu_d21, fpu_d22, + fpu_d23, fpu_d24, fpu_d25, + fpu_d26, fpu_d27, fpu_d28, + fpu_d29, fpu_d30, fpu_d31, + fpu_fpsr, fpu_fpcr, LLDB_INVALID_REGNUM}; +static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) - + 1) == k_num_fpr_registers, + "g_fpu_regnums_arm64 has wrong number of register infos"); +// clang-format on +// Register sets for ARM64. +static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers, + g_gpr_regnums_arm64}, + {"Floating Point Registers", "fpu", k_num_fpr_registers, + g_fpu_regnums_arm64}}; + static uint32_t GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) { switch (target_arch.GetMachine()) { @@ -80,19 +156,60 @@ GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) { RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64( const lldb_private::ArchSpec &target_arch) - : lldb_private::RegisterInfoInterface(target_arch), + : lldb_private::RegisterInfoAndSetInterface(target_arch), m_register_info_p(GetRegisterInfoPtr(target_arch)), - m_register_info_count(GetRegisterInfoCount(target_arch)) {} + m_register_info_count(GetRegisterInfoCount(target_arch)) { + + switch (target_arch.GetMachine()) { + case llvm::Triple::aarch64: + case llvm::Triple::aarch64_32: + num_registers = k_num_gpr_registers + k_num_fpr_registers; + num_gpr_registers = k_num_gpr_registers; + num_fpr_registers = k_num_fpr_registers; + last_gpr = gpr_w28; + first_fpr = fpu_v0; + last_fpr = fpu_fpcr; + break; + default: + assert(false && "Unhandled target architecture."); + break; + } +} + +uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const { + return num_gpr_registers + num_fpr_registers; +} size_t RegisterInfoPOSIX_arm64::GetGPRSize() const { return sizeof(struct RegisterInfoPOSIX_arm64::GPR); } +size_t RegisterInfoPOSIX_arm64::GetFPRSize() const { + return sizeof(struct RegisterInfoPOSIX_arm64::FPU); +} + const lldb_private::RegisterInfo * RegisterInfoPOSIX_arm64::GetRegisterInfo() const { return m_register_info_p; } -uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const { - return m_register_info_count; +size_t RegisterInfoPOSIX_arm64::GetRegisterSetCount() const { + return k_num_register_sets; +} + +size_t RegisterInfoPOSIX_arm64::GetRegisterSetFromRegisterIndex( + uint32_t reg_index) const { + if (reg_index <= last_gpr) + return GPRegSet; + else if (reg_index <= last_fpr) + return FPRegSet; + return LLDB_INVALID_REGNUM; +} + +const lldb_private::RegisterSet * +RegisterInfoPOSIX_arm64::GetRegisterSet(size_t set_index) const { + if (set_index < k_num_register_sets) + return &g_reg_sets_arm64[set_index]; + + return nullptr; } diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h index ace179a8181..2da6a531a6b 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h @@ -6,15 +6,18 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextLinux_arm64_H_ -#define liblldb_RegisterContextLinux_arm64_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM64_H -#include "RegisterInfoInterface.h" +#include "RegisterInfoAndSetInterface.h" #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" -class RegisterInfoPOSIX_arm64 : public lldb_private::RegisterInfoInterface { +class RegisterInfoPOSIX_arm64 + : public lldb_private::RegisterInfoAndSetInterface { public: + enum { GPRegSet = 0, FPRegSet }; + // based on RegisterContextDarwin_arm64.h struct GPR { uint64_t x[29]; // x0-x28 @@ -57,11 +60,28 @@ public: size_t GetGPRSize() const override; + size_t GetFPRSize() const override; + const lldb_private::RegisterInfo *GetRegisterInfo() const override; uint32_t GetRegisterCount() const override; + const lldb_private::RegisterSet * + GetRegisterSet(size_t reg_set) const override; + + size_t GetRegisterSetCount() const override; + + size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override; + private: + uint32_t num_registers; + uint32_t num_gpr_registers; + uint32_t num_fpr_registers; + + uint32_t last_gpr; + uint32_t first_fpr; + uint32_t last_fpr; + const lldb_private::RegisterInfo *m_register_info_p; uint32_t m_register_info_count; }; diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp index 35051a3ce09..3461d38a390 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp @@ -1,4 +1,4 @@ -//===-- RegisterInfoPOSIX_ppc64le.cpp --------------------------*- C++ -*-===// +//===-- RegisterInfoPOSIX_ppc64le.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h index c4d4d3b546e..98549ac0dda 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextLinux_ppc64le_H_ -#define liblldb_RegisterContextLinux_ppc64le_H_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_PPC64LE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_PPC64LE_H #include "RegisterInfoInterface.h" #include "lldb/Target/RegisterContext.h" diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h index 68c12aa6e52..4aee55e7afb 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h @@ -456,37 +456,26 @@ static uint32_t g_d29_invalidates[] = {fpu_v29, fpu_s29, LLDB_INVALID_REGNUM}; static uint32_t g_d30_invalidates[] = {fpu_v30, fpu_s30, LLDB_INVALID_REGNUM}; static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; -// Generates register kinds array for 64-bit general purpose registers -#define GPR64_KIND(reg, generic_kind) \ +// Generates register kinds array with DWARF, EH frame and generic kind +#define MISC_KIND(reg, type, generic_kind) \ { \ arm64_ehframe::reg, arm64_dwarf::reg, generic_kind, LLDB_INVALID_REGNUM, \ - gpr_##reg \ + type##_##reg \ } -// Generates register kinds array for registers with lldb kind -#define MISC_KIND(lldb_kind) \ +// Generates register kinds array for registers with only lldb kind +#define LLDB_KIND(lldb_kind) \ { \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_kind \ } // Generates register kinds array for vector registers -#define VREG_KIND(reg) \ - { \ - LLDB_INVALID_REGNUM, arm64_dwarf::reg, LLDB_INVALID_REGNUM, \ - LLDB_INVALID_REGNUM, fpu_##reg \ - } - -// Generates register kinds array for cpsr -#define CPSR_KIND(lldb_kind) \ - { \ - arm64_ehframe::cpsr, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, \ - LLDB_INVALID_REGNUM, lldb_kind \ - } - -#define MISC_GPR_KIND(lldb_kind) CPSR_KIND(lldb_kind) -#define MISC_FPU_KIND(lldb_kind) MISC_KIND(lldb_kind) -#define MISC_EXC_KIND(lldb_kind) MISC_KIND(lldb_kind) +#define GPR64_KIND(reg, generic_kind) MISC_KIND(reg, gpr, generic_kind) +#define VREG_KIND(reg) MISC_KIND(reg, fpu, LLDB_INVALID_REGNUM) +#define MISC_GPR_KIND(lldb_kind) MISC_KIND(cpsr, gpr, LLDB_REGNUM_GENERIC_FLAGS) +#define MISC_FPU_KIND(lldb_kind) LLDB_KIND(lldb_kind) +#define MISC_EXC_KIND(lldb_kind) LLDB_KIND(lldb_kind) // Defines a 64-bit general purpose register #define DEFINE_GPR64(reg, generic_kind) \ @@ -509,7 +498,7 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; { \ #wreg, nullptr, 4, \ GPR_OFFSET(gpr_##xreg) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, \ - lldb::eEncodingUint, lldb::eFormatHex, MISC_KIND(gpr_##wreg), \ + lldb::eEncodingUint, lldb::eFormatHex, LLDB_KIND(gpr_##wreg), \ g_contained_##xreg, g_##wreg##_invalidates, nullptr, 0 \ } @@ -521,11 +510,11 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; 0 \ } -// Defines S and D pseudo registers mapping over correspondig vector register +// Defines S and D pseudo registers mapping over corresponding vector register #define DEFINE_FPU_PSEUDO(reg, size, offset, vreg) \ { \ #reg, nullptr, size, FPU_OFFSET(fpu_##vreg - fpu_v0) + offset, \ - lldb::eEncodingIEEE754, lldb::eFormatFloat, MISC_KIND(fpu_##reg), \ + lldb::eEncodingIEEE754, lldb::eFormatFloat, LLDB_KIND(fpu_##reg), \ g_contained_##vreg, g_##reg##_invalidates, nullptr, 0 \ } diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h index 72ff904520a..343579cd265 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h @@ -145,7 +145,7 @@ DR_OFFSET(i), eEncodingUint, eFormatHex, \ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ - LLDB_INVALID_REGNUM }, \ + lldb_##reg##i##_i386 }, \ nullptr, nullptr, nullptr, 0 \ } diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp index 6d03bd534f3..2d8e8ef2161 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp @@ -1,4 +1,4 @@ -//===-- StopInfoMachException.cpp -------------------------------*- C++ -*-===// +//===-- StopInfoMachException.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,6 +8,7 @@ #include "StopInfoMachException.h" +#include "lldb/lldb-forward.h" #if defined(__APPLE__) // Needed for the EXC_RESOURCE interpretation macros @@ -289,10 +290,48 @@ const char *StopInfoMachException::GetDescription() { if (m_exc_data_count > 0) strm.PutChar(')'); - m_description = strm.GetString(); + m_description = std::string(strm.GetString()); return m_description.c_str(); } +static StopInfoSP GetStopInfoForHardwareBP(Thread &thread, Target *target, + uint32_t exc_data_count, + uint64_t exc_sub_code, + uint64_t exc_sub_sub_code) { + // Try hardware watchpoint. + if (target) { + // The exc_sub_code indicates the data break address. + lldb::WatchpointSP wp_sp = + target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code); + if (wp_sp && wp_sp->IsEnabled()) { + // Debugserver may piggyback the hardware index of the fired watchpoint + // in the exception data. Set the hardware index if that's the case. + if (exc_data_count >= 3) + wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code); + return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID()); + } + } + + // Try hardware breakpoint. + ProcessSP process_sp(thread.GetProcess()); + if (process_sp) { + // The exc_sub_code indicates the data break address. + lldb::BreakpointSiteSP bp_sp = + process_sp->GetBreakpointSiteList().FindByAddress( + (lldb::addr_t)exc_sub_code); + if (bp_sp && bp_sp->IsEnabled()) { + // Debugserver may piggyback the hardware index of the fired breakpoint + // in the exception data. Set the hardware index if that's the case. + if (exc_data_count >= 3) + bp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code); + return StopInfo::CreateStopReasonWithBreakpointSiteID(thread, + bp_sp->GetID()); + } + } + + return nullptr; +} + StopInfoSP StopInfoMachException::CreateStopReasonWithMachException( Thread &thread, uint32_t exc_type, uint32_t exc_data_count, uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code, @@ -350,22 +389,10 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException( is_actual_breakpoint = true; is_trace_if_actual_breakpoint_missing = true; } else { - - // It's a watchpoint, then. - // The exc_sub_code indicates the data break address. - lldb::WatchpointSP wp_sp; - if (target) - wp_sp = target->GetWatchpointList().FindByAddress( - (lldb::addr_t)exc_sub_code); - if (wp_sp && wp_sp->IsEnabled()) { - // Debugserver may piggyback the hardware index of the fired - // watchpoint in the exception data. Set the hardware index if - // that's the case. - if (exc_data_count >= 3) - wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code); - return StopInfo::CreateStopReasonWithWatchpointID(thread, - wp_sp->GetID()); - } + if (StopInfoSP stop_info = + GetStopInfoForHardwareBP(thread, target, exc_data_count, + exc_sub_code, exc_sub_sub_code)) + return stop_info; } } else if (exc_code == 2 || // EXC_I386_BPT exc_code == 3) // EXC_I386_BPTFLT diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/StopInfoMachException.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/StopInfoMachException.h index 74c05812ab0..d9c1886d709 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/StopInfoMachException.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/StopInfoMachException.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_StopInfoMachException_h_ -#define liblldb_StopInfoMachException_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_STOPINFOMACHEXCEPTION_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_STOPINFOMACHEXCEPTION_H #include @@ -48,4 +48,4 @@ protected: } // namespace lldb_private -#endif // liblldb_StopInfoMachException_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_STOPINFOMACHEXCEPTION_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp index 80b04bb14f7..7469e7633e7 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp @@ -1,5 +1,4 @@ -//===-- ThreadMemory.cpp ----------------------------------------------*- C++ -//-*-===// +//===-- ThreadMemory.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -30,7 +29,8 @@ ThreadMemory::ThreadMemory(Process &process, lldb::tid_t tid, llvm::StringRef name, llvm::StringRef queue, lldb::addr_t register_data_addr) : Thread(process, tid), m_backing_thread_sp(), m_thread_info_valobj_sp(), - m_name(name), m_queue(queue), m_register_data_addr(register_data_addr) {} + m_name(std::string(name)), m_queue(std::string(queue)), + m_register_data_addr(register_data_addr) {} ThreadMemory::~ThreadMemory() { DestroyThread(); } @@ -54,20 +54,14 @@ RegisterContextSP ThreadMemory::GetRegisterContext() { RegisterContextSP ThreadMemory::CreateRegisterContextForFrame(StackFrame *frame) { - RegisterContextSP reg_ctx_sp; uint32_t concrete_frame_idx = 0; if (frame) concrete_frame_idx = frame->GetConcreteFrameIndex(); - if (concrete_frame_idx == 0) { - reg_ctx_sp = GetRegisterContext(); - } else { - Unwind *unwinder = GetUnwinder(); - if (unwinder != nullptr) - reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame); - } - return reg_ctx_sp; + if (concrete_frame_idx == 0) + return GetRegisterContext(); + return GetUnwinder().CreateRegisterContextForFrame(frame); } bool ThreadMemory::CalculateStopInfo() { diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/ThreadMemory.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/ThreadMemory.h index 85bc1451e4a..d124f5780ea 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/ThreadMemory.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/ThreadMemory.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadMemory_h_ -#define liblldb_ThreadMemory_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H #include @@ -100,7 +100,8 @@ protected: lldb::addr_t m_register_data_addr; private: - DISALLOW_COPY_AND_ASSIGN(ThreadMemory); + ThreadMemory(const ThreadMemory &) = delete; + const ThreadMemory &operator=(const ThreadMemory &) = delete; }; -#endif // liblldb_ThreadMemory_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-arm-register-enums.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-arm-register-enums.h index 39cbf01ea9d..8f0eed4f02c 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-arm-register-enums.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-arm-register-enums.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_arm_register_enums_h -#define lldb_arm_register_enums_h +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM_REGISTER_ENUMS_H namespace lldb_private { // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) @@ -196,4 +196,4 @@ enum { }; } -#endif // #ifndef lldb_arm64_register_enums_h +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM_REGISTER_ENUMS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-arm64-register-enums.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-arm64-register-enums.h index cc414dcde3c..39d47b8801c 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-arm64-register-enums.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-arm64-register-enums.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_arm64_register_enums_h -#define lldb_arm64_register_enums_h +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM64_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM64_REGISTER_ENUMS_H namespace lldb_private { // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) @@ -261,4 +261,4 @@ enum { }; } -#endif // #ifndef lldb_arm64_register_enums_h +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM64_REGISTER_ENUMS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h index d97f7712242..e6a7efd00f6 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_mips_freebsd_register_enums_h -#define lldb_mips_freebsd_register_enums_h +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_FREEBSD_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_FREEBSD_REGISTER_ENUMS_H namespace lldb_private { // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) @@ -62,4 +62,4 @@ enum { k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1 }; } -#endif // #ifndef lldb_mips_freebsd_register_enums_h +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_FREEBSD_REGISTER_ENUMS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h index 2f68b8022c9..348af27d280 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_mips_linux_register_enums_h -#define lldb_mips_linux_register_enums_h +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_LINUX_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_LINUX_REGISTER_ENUMS_H namespace lldb_private { // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) @@ -357,4 +357,4 @@ enum { }; } -#endif // #ifndef lldb_mips_linux_register_enums_h +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_LINUX_REGISTER_ENUMS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h index 6edf7ee3864..40a75c006d8 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_ppc64_register_enums_h -#define lldb_ppc64_register_enums_h +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64_REGISTER_ENUMS_H // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) @@ -133,4 +133,4 @@ enum { k_num_vmx_registers_ppc64 = k_last_vmx_ppc64 - k_first_vmx_ppc64 + 1, }; -#endif // #ifndef lldb_ppc64_register_enums_h +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64_REGISTER_ENUMS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h index 0c381a5f391..a7b5bc5ad9e 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_ppc64le_register_enums_h -#define lldb_ppc64le_register_enums_h +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64LE_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64LE_REGISTER_ENUMS_H // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) @@ -204,4 +204,4 @@ enum { k_num_vsx_registers_ppc64le = k_last_vsx_ppc64le - k_first_vsx_ppc64le + 1, }; -#endif // #ifndef lldb_ppc64le_register_enums_h +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64LE_REGISTER_ENUMS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h index bd662610829..23c441e1c80 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_s390x_register_enums_h -#define lldb_s390x_register_enums_h +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_S390X_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_S390X_REGISTER_ENUMS_H namespace lldb_private { // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) @@ -87,4 +87,4 @@ enum { }; } -#endif // #ifndef lldb_s390x_register_enums_h +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_S390X_REGISTER_ENUMS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h b/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h index bfdd586d9de..35f1a4075d0 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_x86_register_enums_h -#define lldb_x86_register_enums_h +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_X86_REGISTER_ENUMS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_X86_REGISTER_ENUMS_H namespace lldb_private { // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) @@ -113,7 +113,8 @@ enum { lldb_bndstatus_i386, k_last_mpxc_i386 = lldb_bndstatus_i386, - lldb_dr0_i386, + k_first_dbr_i386, + lldb_dr0_i386 = k_first_dbr_i386, lldb_dr1_i386, lldb_dr2_i386, lldb_dr3_i386, @@ -121,6 +122,7 @@ enum { lldb_dr5_i386, lldb_dr6_i386, lldb_dr7_i386, + k_last_dbr_i386 = lldb_dr7_i386, k_num_registers_i386, k_num_gpr_registers_i386 = k_last_gpr_i386 - k_first_gpr_i386 + 1, @@ -131,6 +133,7 @@ enum { k_num_fpr_registers_i386 + k_num_avx_registers_i386 + k_num_mpx_registers_i386, + k_num_dbr_registers_i386 = k_last_dbr_i386 - k_first_dbr_i386 + 1, }; // Internal codes for all x86_64 registers. @@ -318,4 +321,4 @@ enum { }; } -#endif // #ifndef lldb_x86_register_enums_h +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_X86_REGISTER_ENUMS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/CMakeLists.txt index 876bc8cab96..e77c204fd61 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/CMakeLists.txt @@ -29,6 +29,7 @@ add_lldb_library(lldbPluginProcessWindowsCommon PLUGIN lldbTarget ws2_32 rpcrt4 + psapi LINK_COMPONENTS Support ) diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp index 59bcc2586f9..87c17d44c18 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp @@ -1,4 +1,4 @@ -//===-- DebuggerThread.cpp --------------------------------------*- C++ -*-===// +//===-- DebuggerThread.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -30,7 +30,7 @@ #include "llvm/Support/raw_ostream.h" #ifndef STATUS_WX86_BREAKPOINT -#define STATUS_WX86_BREAKPOINT 0x4000001FL // For WOW64 +#define STATUS_WX86_BREAKPOINT 0x4000001FL // For WOW64 #endif using namespace lldb; @@ -70,11 +70,11 @@ Status DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info) { Status result; DebugLaunchContext *context = new DebugLaunchContext(this, launch_info); - llvm::Expected slave_thread = ThreadLauncher::LaunchThread( - "lldb.plugin.process-windows.slave[?]", DebuggerThreadLaunchRoutine, - context); - if (!slave_thread) { - result = Status(slave_thread.takeError()); + llvm::Expected secondary_thread = + ThreadLauncher::LaunchThread("lldb.plugin.process-windows.secondary[?]", + DebuggerThreadLaunchRoutine, context); + if (!secondary_thread) { + result = Status(secondary_thread.takeError()); LLDB_LOG(log, "couldn't launch debugger thread. {0}", result); } @@ -89,11 +89,11 @@ Status DebuggerThread::DebugAttach(lldb::pid_t pid, Status result; DebugAttachContext *context = new DebugAttachContext(this, pid, attach_info); - llvm::Expected slave_thread = ThreadLauncher::LaunchThread( - "lldb.plugin.process-windows.slave[?]", DebuggerThreadAttachRoutine, - context); - if (!slave_thread) { - result = Status(slave_thread.takeError()); + llvm::Expected secondary_thread = + ThreadLauncher::LaunchThread("lldb.plugin.process-windows.secondary[?]", + DebuggerThreadAttachRoutine, context); + if (!secondary_thread) { + result = Status(secondary_thread.takeError()); LLDB_LOG(log, "couldn't attach to process '{0}'. {1}", pid, result); } @@ -411,7 +411,7 @@ DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info, std::string thread_name; llvm::raw_string_ostream name_stream(thread_name); - name_stream << "lldb.plugin.process-windows.slave[" << process_id << "]"; + name_stream << "lldb.plugin.process-windows.secondary[" << process_id << "]"; name_stream.flush(); llvm::set_thread_name(thread_name); diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp index 3bb00726f11..dfa1d76d35f 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp @@ -1,4 +1,4 @@ -//===-- LocalDebugDelegate.cpp ----------------------------------*- C++ -*-===// +//===-- LocalDebugDelegate.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp index f888d152caa..beee3f58678 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp @@ -1,4 +1,4 @@ -//===-- NativeProcessWindows.cpp --------------------------------*- C++ -*-===// +//===-- NativeProcessWindows.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -48,7 +48,7 @@ NativeProcessWindows::NativeProcessWindows(ProcessLaunchInfo &launch_info, NativeDelegate &delegate, llvm::Error &E) : NativeProcessProtocol(LLDB_INVALID_PROCESS_ID, - launch_info.GetPTY().ReleaseMasterFileDescriptor(), + launch_info.GetPTY().ReleasePrimaryFileDescriptor(), delegate), ProcessDebugger(), m_arch(launch_info.GetArchitecture()) { ErrorAsOutParameter EOut(&E); @@ -394,7 +394,7 @@ void NativeProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) { GetDebuggedProcessId(), image_base); // This is the earliest chance we can resolve the process ID and - // architecutre if we don't know them yet. + // architecture if we don't know them yet. if (GetID() == LLDB_INVALID_PROCESS_ID) SetID(GetDebuggedProcessId()); diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.cpp index fd82721bbcf..9128363eaa5 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.cpp @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextWindows.cpp ------------------------*- C++ -*-===// +//===-- NativeRegisterContextWindows.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_WoW64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_WoW64.cpp index a5a86f5e12c..d562c7df8bf 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_WoW64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_WoW64.cpp @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextWindows_WoW64.cpp ----- ------------*- C++ -*-===// +//===-- NativeRegisterContextWindows_WoW64.cpp ----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm.cpp index d25b08f7ecb..d2b1bc1a13c 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm.cpp @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextWindows_arm.cpp --------------------*- C++ -*-===// +//===-- NativeRegisterContextWindows_arm.cpp ------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp index b3b3abf6898..8205c8ec98d 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextWindows_arm64.cpp ------------------*- C++ -*-===// +//===-- NativeRegisterContextWindows_arm64.cpp ----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_i386.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_i386.cpp index 3ad721b60a1..45da4cd02ce 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_i386.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_i386.cpp @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextWindows_i386.cpp -------------------*- C++ -*-===// +//===-- NativeRegisterContextWindows_i386.cpp -----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_x86_64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_x86_64.cpp index fed64494664..819cd8eb383 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_x86_64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- NativeRegisterContextWindows_x86_64.cpp -----------------*- C++ -*-===// +//===-- NativeRegisterContextWindows_x86_64.cpp ---------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp index 45bdec40b40..16e67bb9f86 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp @@ -1,4 +1,4 @@ -//===-- NativeThreadWindows.cpp ---------------------------------*- C++ -*-===// +//===-- NativeThreadWindows.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp index cd780518fe2..8a85c8ba6f4 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp @@ -1,4 +1,4 @@ -//===-- ProcessDebugger.cpp -------------------------------------*- C++ -*-===// +//===-- ProcessDebugger.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -127,7 +127,7 @@ Status ProcessDebugger::LaunchProcess(ProcessLaunchInfo &launch_info, stream.Printf("ProcessDebugger unable to launch '%s'. ProcessDebugger can " "only be used for debug launches.", launch_info.GetExecutableFile().GetPath().c_str()); - std::string message = stream.GetString(); + std::string message = stream.GetString().str(); result.SetErrorString(message.c_str()); LLDB_LOG(log, "error: {0}", message); diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp index d4e60ec2b43..7b020f55e99 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp @@ -1,4 +1,4 @@ -//===-- ProcessWindows.cpp --------------------------------------*- C++ -*-===// +//===-- ProcessWindows.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -44,6 +44,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE_ADV(ProcessWindows, ProcessWindowsCommon) + namespace { std::string GetProcessExecutableName(HANDLE process_handle) { std::vector file_name; diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp index 8af9f39bb80..6f5e020e812 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp @@ -1,4 +1,4 @@ -//===-- ProcessWindowsLog.cpp -----------------------------------*- C++ -*-===// +//===-- ProcessWindowsLog.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp index c3cb45530f2..099bae6b0f6 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextWindows.cpp ------------------------------*- C++ -*-===// +//===-- RegisterContextWindows.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp index 86a302a87b8..6d608b2b6ce 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp @@ -1,4 +1,4 @@ -//===-- TargetThreadWindows.cpp----------------------------------*- C++ -*-===// +//===-- TargetThreadWindows.cpp--------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -11,11 +11,11 @@ #include "lldb/Host/windows/HostThreadWindows.h" #include "lldb/Host/windows/windows.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Unwind.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" #include "lldb/Utility/State.h" -#include "Plugins/Process/Utility/UnwindLLDB.h" #include "ProcessWindows.h" #include "ProcessWindowsLog.h" #include "TargetThreadWindows.h" @@ -113,9 +113,7 @@ TargetThreadWindows::CreateRegisterContextForFrame(StackFrame *frame) { } reg_ctx_sp = m_thread_reg_ctx_sp; } else { - Unwind *unwinder = GetUnwinder(); - if (unwinder != nullptr) - reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame); + reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame); } return reg_ctx_sp; @@ -126,14 +124,6 @@ bool TargetThreadWindows::CalculateStopInfo() { return true; } -Unwind *TargetThreadWindows::GetUnwinder() { - // FIXME: Implement an unwinder based on the Windows unwinder exposed through - // DIA SDK. - if (!m_unwinder_up) - m_unwinder_up.reset(new UnwindLLDB(*this)); - return m_unwinder_up.get(); -} - Status TargetThreadWindows::DoResume() { StateType resume_state = GetTemporaryResumeState(); StateType current_state = GetState(); diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/TargetThreadWindows.h b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/TargetThreadWindows.h index fc68cb73db9..2845847738f 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/TargetThreadWindows.h +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/TargetThreadWindows.h @@ -34,7 +34,6 @@ public: lldb::RegisterContextSP CreateRegisterContextForFrame(StackFrame *frame) override; bool CalculateStopInfo() override; - Unwind *GetUnwinder() override; Status DoResume(); diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/arm/RegisterContextWindows_arm.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/arm/RegisterContextWindows_arm.cpp index c8bcf71c7f6..ce4ad4a88b6 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/arm/RegisterContextWindows_arm.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/arm/RegisterContextWindows_arm.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextWindows_arm.cpp --------------------------*- C++ -*-===// +//===-- RegisterContextWindows_arm.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/arm64/RegisterContextWindows_arm64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/arm64/RegisterContextWindows_arm64.cpp index 4021ca1b188..809ec01f250 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/arm64/RegisterContextWindows_arm64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/arm64/RegisterContextWindows_arm64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextWindows_arm64.cpp ------------------------*- C++ -*-===// +//===-- RegisterContextWindows_arm64.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp index fc59d099d2d..0d5f0b8e45b 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextWindows_x64.cpp --------------------------*- C++ -*-===// +//===-- RegisterContextWindows_x64.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp index 2a271ac44e4..774823eb3ed 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextWindows_x86.cpp --------------------------*- C++ -*-===// +//===-- RegisterContextWindows_x86.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/gnu/llvm/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index ab23589ae9a..aa95e92607a 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -1,4 +1,4 @@ -//===-- ProcessElfCore.cpp --------------------------------------*- C++ -*-===// +//===-- ProcessElfCore.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -35,6 +35,8 @@ using namespace lldb_private; namespace ELF = llvm::ELF; +LLDB_PLUGIN_DEFINE(ProcessElfCore) + ConstString ProcessElfCore::GetPluginNameStatic() { static ConstString g_name("elf-core"); return g_name; diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/gnu/llvm/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h index 829fe9ac719..6f6309799f4 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h @@ -13,8 +13,8 @@ // space. //===----------------------------------------------------------------------===// -#ifndef liblldb_ProcessElfCore_h_ -#define liblldb_ProcessElfCore_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_PROCESSELFCORE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_PROCESSELFCORE_H #include #include @@ -125,7 +125,8 @@ private: lldb::ModuleSP m_core_module_sp; lldb_private::FileSpec m_core_file; std::string m_dyld_plugin_name; - DISALLOW_COPY_AND_ASSIGN(ProcessElfCore); + ProcessElfCore(const ProcessElfCore &) = delete; + const ProcessElfCore &operator=(const ProcessElfCore &) = delete; // True if m_thread_contexts contains valid entries bool m_thread_data_valid = false; @@ -165,4 +166,4 @@ private: llvm::Error parseLinuxNotes(llvm::ArrayRef notes); }; -#endif // liblldb_ProcessElfCore_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_PROCESSELFCORE_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp index fa05c457fc6..b76f26a584c 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIXCore_arm.cpp ------------------------*- C++ -*-===// +//===-- RegisterContextPOSIXCore_arm.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -44,10 +44,12 @@ bool RegisterContextCorePOSIX_arm::WriteFPR() { bool RegisterContextCorePOSIX_arm::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) { lldb::offset_t offset = reg_info->byte_offset; - uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); - if (offset == reg_info->byte_offset + reg_info->byte_size) { - value = v; - return true; + if (offset + reg_info->byte_size <= GetGPRSize()) { + uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); + if (offset == reg_info->byte_offset + reg_info->byte_size) { + value = v; + return true; + } } return false; } diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h index adda43ebccb..f9ec08ed35f 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextCorePOSIX_arm_h_ -#define liblldb_RegisterContextCorePOSIX_arm_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM_H +#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM_H #include "Plugins/Process/Utility/RegisterContextPOSIX_arm.h" #include "Plugins/Process/elf-core/RegisterUtilities.h" @@ -50,4 +50,4 @@ private: lldb_private::DataExtractor m_gpr; }; -#endif // liblldb_RegisterContextCorePOSIX_arm_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp index e477c438ba1..68556741698 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIXCore_arm64.cpp ----------------------*- C++ -*-===// +//===-- RegisterContextPOSIXCore_arm64.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -17,13 +17,16 @@ using namespace lldb_private; RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64( - Thread &thread, RegisterInfoInterface *register_info, + Thread &thread, std::unique_ptr register_info, const DataExtractor &gpregset, llvm::ArrayRef notes) - : RegisterContextPOSIX_arm64(thread, 0, register_info) { + : RegisterContextPOSIX_arm64(thread, std::move(register_info)) { m_gpr_buffer = std::make_shared(gpregset.GetDataStart(), gpregset.GetByteSize()); m_gpr.SetData(m_gpr_buffer); m_gpr.SetByteOrder(gpregset.GetByteOrder()); + + m_fpregset = getRegset( + notes, m_register_info_up->GetTargetArchitecture().GetTriple(), FPR_Desc); } RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64() {} @@ -45,11 +48,26 @@ bool RegisterContextCorePOSIX_arm64::WriteFPR() { bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) { lldb::offset_t offset = reg_info->byte_offset; - uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); - if (offset == reg_info->byte_offset + reg_info->byte_size) { - value = v; - return true; + if (offset + reg_info->byte_size <= GetGPRSize()) { + uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); + if (offset == reg_info->byte_offset + reg_info->byte_size) { + value = v; + return true; + } } + + const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; + if (reg == LLDB_INVALID_REGNUM) + return false; + + offset -= GetGPRSize(); + if (IsFPR(reg) && offset + reg_info->byte_size <= GetFPUSize()) { + Status error; + value.SetFromMemoryData(reg_info, m_fpregset.GetDataStart() + offset, + reg_info->byte_size, lldb::eByteOrderLittle, error); + return error.Success(); + } + return false; } diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h index de6d819c29c..830e0ff91e4 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextCorePOSIX_arm64_h_ -#define liblldb_RegisterContextCorePOSIX_arm64_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM64_H #include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h" #include "Plugins/Process/elf-core/RegisterUtilities.h" @@ -18,7 +18,7 @@ class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 { public: RegisterContextCorePOSIX_arm64( lldb_private::Thread &thread, - lldb_private::RegisterInfoInterface *register_info, + std::unique_ptr register_info, const lldb_private::DataExtractor &gpregset, llvm::ArrayRef notes); @@ -48,6 +48,7 @@ protected: private: lldb::DataBufferSP m_gpr_buffer; lldb_private::DataExtractor m_gpr; + lldb_private::DataExtractor m_fpregset; }; -#endif // liblldb_RegisterContextCorePOSIX_arm64_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM64_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp index 3601f3b3b21..b5b83d899a4 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIXCore_mips64.cpp ---------------------*- C++ -*-===// +//===-- RegisterContextPOSIXCore_mips64.cpp -------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h index 999c9451573..b42a76c082f 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextCorePOSIX_mips64_h_ -#define liblldb_RegisterContextCorePOSIX_mips64_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_MIPS64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_MIPS64_H #include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h" #include "Plugins/Process/elf-core/RegisterUtilities.h" @@ -52,4 +52,4 @@ private: lldb_private::DataExtractor m_fpr; }; -#endif // liblldb_RegisterContextCorePOSIX_mips64_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_MIPS64_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp index 6984bf4ee9b..e15cd47cd7d 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIXCore_powerpc.cpp --------------------*- C++ -*-===// +//===-- RegisterContextPOSIXCore_powerpc.cpp ------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h index 7684c0b3183..cf50b6e0bf7 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextCorePOSIX_powerpc_h_ -#define liblldb_RegisterContextCorePOSIX_powerpc_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_POWERPC_H +#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_POWERPC_H #include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h" #include "Plugins/Process/elf-core/RegisterUtilities.h" @@ -57,4 +57,4 @@ private: lldb_private::DataExtractor m_vec; }; -#endif // liblldb_RegisterContextCorePOSIX_powerpc_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_POWERPC_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp index 0eebf474f60..d44fb399e18 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIXCore_ppc64le.cpp --------------------*- C++ -*-===// +//===-- RegisterContextPOSIXCore_ppc64le.cpp ------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h index 6e01d23dd65..8de77a7e25b 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextCorePOSIX_ppc64le_h_ -#define liblldb_RegisterContextCorePOSIX_ppc64le_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_PPC64LE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_PPC64LE_H #include "Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h" #include "Plugins/Process/elf-core/RegisterUtilities.h" @@ -45,4 +45,4 @@ private: lldb_private::DataExtractor m_vsx; }; -#endif // liblldb_RegisterContextCorePOSIX_ppc64le_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_PPC64LE_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp index d84fc3e7439..c3aa92c9f86 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIXCore_s390x.cpp ----------------------*- C++ -*-===// +//===-- RegisterContextPOSIXCore_s390x.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h index 729617649c4..4560f062e06 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextCorePOSIX_s390x_h_ -#define liblldb_RegisterContextCorePOSIX_s390x_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_S390X_H +#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_S390X_H #include "Plugins/Process/Utility/RegisterContextPOSIX_s390x.h" #include "Plugins/Process/elf-core/RegisterUtilities.h" @@ -52,4 +52,4 @@ private: lldb_private::DataExtractor m_fpr; }; -#endif // liblldb_RegisterContextCorePOSIX_s390x_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_S390X_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp index 4454857e179..6eaad9f381d 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextPOSIXCore_x86_64.cpp ---------------------*- C++ -*-===// +//===-- RegisterContextPOSIXCore_x86_64.cpp -------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h index f41991c240d..9adfbf7e685 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextCorePOSIX_x86_64_h_ -#define liblldb_RegisterContextCorePOSIX_x86_64_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_X86_64_H #include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h" #include "Plugins/Process/elf-core/RegisterUtilities.h" @@ -46,4 +46,4 @@ private: std::unique_ptr m_fpregset; }; -#endif // liblldb_RegisterContextCorePOSIX_x86_64_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_X86_64_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp index c8829d612b3..0c21c0f50ab 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp @@ -1,4 +1,4 @@ -//===-- RegisterUtilities.cpp -----------------------------------*- C++ -*-===// +//===-- RegisterUtilities.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h index 49ad425db44..4e08aa28081 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_REGISTERUTILITIES_H -#define LLDB_REGISTERUTILITIES_H +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERUTILITIES_H +#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERUTILITIES_H #include "Plugins/ObjectFile/ELF/ObjectFileELF.h" #include "lldb/Utility/DataExtractor.h" @@ -118,4 +118,4 @@ constexpr RegsetDesc PPC_VSX_Desc[] = { } // namespace lldb_private -#endif // #ifndef LLDB_REGISTERUTILITIES_H +#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERUTILITIES_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/gnu/llvm/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 508c8a3108a..6b5acfa4bc1 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -1,4 +1,4 @@ -//===-- ThreadElfCore.cpp --------------------------------------*- C++ -*-===// +//===-- ThreadElfCore.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -82,7 +82,6 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { case llvm::Triple::FreeBSD: { switch (arch.GetMachine()) { case llvm::Triple::aarch64: - reg_interface = new RegisterInfoPOSIX_arm64(arch); break; case llvm::Triple::arm: reg_interface = new RegisterInfoPOSIX_arm(arch); @@ -111,7 +110,6 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { case llvm::Triple::NetBSD: { switch (arch.GetMachine()) { case llvm::Triple::aarch64: - reg_interface = new RegisterInfoPOSIX_arm64(arch); break; case llvm::Triple::x86_64: reg_interface = new RegisterContextNetBSD_x86_64(arch); @@ -128,7 +126,6 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { reg_interface = new RegisterInfoPOSIX_arm(arch); break; case llvm::Triple::aarch64: - reg_interface = new RegisterInfoPOSIX_arm64(arch); break; case llvm::Triple::mipsel: case llvm::Triple::mips: @@ -159,7 +156,6 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { case llvm::Triple::OpenBSD: { switch (arch.GetMachine()) { case llvm::Triple::aarch64: - reg_interface = new RegisterInfoPOSIX_arm64(arch); break; case llvm::Triple::arm: reg_interface = new RegisterInfoPOSIX_arm(arch); @@ -180,7 +176,7 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { break; } - if (!reg_interface) { + if (!reg_interface && arch.GetMachine() != llvm::Triple::aarch64) { LLDB_LOGF(log, "elf-core::%s:: Architecture(%d) or OS(%d) not supported", __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS()); assert(false && "Architecture or OS not supported"); @@ -189,7 +185,8 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { switch (arch.GetMachine()) { case llvm::Triple::aarch64: m_thread_reg_ctx_sp = std::make_shared( - *this, reg_interface, m_gpregset_data, m_notes); + *this, std::make_unique(arch), + m_gpregset_data, m_notes); break; case llvm::Triple::arm: m_thread_reg_ctx_sp = std::make_shared( @@ -229,9 +226,7 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { reg_ctx_sp = m_thread_reg_ctx_sp; } else { - Unwind *unwinder = GetUnwinder(); - if (unwinder != nullptr) - reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame); + reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame); } return reg_ctx_sp; } @@ -296,25 +291,25 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data, pr_cursig = data.GetU16(&offset); offset += 2; // pad - pr_sigpend = data.GetPointer(&offset); - pr_sighold = data.GetPointer(&offset); + pr_sigpend = data.GetAddress(&offset); + pr_sighold = data.GetAddress(&offset); pr_pid = data.GetU32(&offset); pr_ppid = data.GetU32(&offset); pr_pgrp = data.GetU32(&offset); pr_sid = data.GetU32(&offset); - pr_utime.tv_sec = data.GetPointer(&offset); - pr_utime.tv_usec = data.GetPointer(&offset); + pr_utime.tv_sec = data.GetAddress(&offset); + pr_utime.tv_usec = data.GetAddress(&offset); - pr_stime.tv_sec = data.GetPointer(&offset); - pr_stime.tv_usec = data.GetPointer(&offset); + pr_stime.tv_sec = data.GetAddress(&offset); + pr_stime.tv_usec = data.GetAddress(&offset); - pr_cutime.tv_sec = data.GetPointer(&offset); - pr_cutime.tv_usec = data.GetPointer(&offset); + pr_cutime.tv_sec = data.GetAddress(&offset); + pr_cutime.tv_usec = data.GetAddress(&offset); - pr_cstime.tv_sec = data.GetPointer(&offset); - pr_cstime.tv_usec = data.GetPointer(&offset); + pr_cstime.tv_sec = data.GetAddress(&offset); + pr_cstime.tv_usec = data.GetAddress(&offset); return error; } @@ -367,7 +362,7 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, offset += 4; } - pr_flag = data.GetPointer(&offset); + pr_flag = data.GetAddress(&offset); if (arch.IsMIPS()) { // The pr_uid and pr_gid is always 32 bit irrespective of platforms diff --git a/gnu/llvm/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h b/gnu/llvm/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h index ddcf35013b3..8d973bb840d 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h +++ b/gnu/llvm/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadElfCore_h_ -#define liblldb_ThreadElfCore_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H #include "Plugins/Process/elf-core/RegisterUtilities.h" #include "lldb/Target/Thread.h" @@ -173,4 +173,4 @@ protected: bool CalculateStopInfo() override; }; -#endif // liblldb_ThreadElfCore_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/CMakeLists.txt index 477f224b940..448d032b381 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/CMakeLists.txt @@ -6,10 +6,6 @@ lldb_tablegen(ProcessGDBRemotePropertiesEnum.inc -gen-lldb-property-enum-defs SOURCE ProcessGDBRemoteProperties.td TARGET LLDBPluginProcessGDBRemotePropertiesEnumGen) -if (CMAKE_SYSTEM_NAME MATCHES "Darwin") - include_directories(${LIBXML2_INCLUDE_DIR}) -endif() - set(LLDB_PLUGINS lldbPluginProcessUtility lldbPluginPlatformMacOSX diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp index 064bbde8442..fdaa60e2df4 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteClientBase.cpp ---------------------------------*- C++ -*-===// +//===-- GDBRemoteClientBase.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -41,7 +41,7 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse( { std::lock_guard lock(m_mutex); - m_continue_packet = payload; + m_continue_packet = std::string(payload); m_should_stop = false; } ContinueLock cont_lock(*this); diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h index ea294ffcef2..cd9f6ebd764 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteClientBase_h_ -#define liblldb_GDBRemoteClientBase_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECLIENTBASE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECLIENTBASE_H #include "GDBRemoteCommunication.h" @@ -149,4 +149,4 @@ private: } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_GDBRemoteCommunicationClient_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECLIENTBASE_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 0a98f6a15d7..bfacd41dc1a 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunication.cpp ------------------------------*- C++ -*-===// +//===-- GDBRemoteCommunication.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -125,7 +125,7 @@ GDBRemoteCommunication::SendPacketNoLock(llvm::StringRef payload) { packet.Write(payload.data(), payload.size()); packet.PutChar('#'); packet.PutHex8(CalculcateChecksum(payload)); - std::string packet_str = packet.GetString(); + std::string packet_str = std::string(packet.GetString()); return SendRawPacketNoLock(packet_str); } @@ -763,7 +763,7 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len, if (m_bytes[0] == '$' && total_length > 4) { for (size_t i = 0; !binary && i < total_length; ++i) { unsigned char c = m_bytes[i]; - if (isprint(c) == 0 && isspace(c) == 0) { + if (!llvm::isPrint(c) && !llvm::isSpace(c)) { binary = true; } } @@ -810,31 +810,9 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len, GDBRemotePacket::ePacketTypeRecv, total_length); // Copy the packet from m_bytes to packet_str expanding the run-length - // encoding in the process. Reserve enough byte for the most common case - // (no RLE used) - std ::string packet_str; - packet_str.reserve(m_bytes.length()); - for (std::string::const_iterator c = m_bytes.begin() + content_start; - c != m_bytes.begin() + content_end; ++c) { - if (*c == '*') { - // '*' indicates RLE. Next character will give us the repeat count - // and previous character is what is to be repeated. - char char_to_repeat = packet_str.back(); - // Number of time the previous character is repeated - int repeat_count = *++c + 3 - ' '; - // We have the char_to_repeat and repeat_count. Now push it in the - // packet. - for (int i = 0; i < repeat_count; ++i) - packet_str.push_back(char_to_repeat); - } else if (*c == 0x7d) { - // 0x7d is the escape character. The next character is to be XOR'd - // with 0x20. - char escapee = *++c ^ 0x20; - packet_str.push_back(escapee); - } else { - packet_str.push_back(*c); - } - } + // encoding in the process. + std ::string packet_str = + ExpandRLE(m_bytes.substr(content_start, content_end - content_start)); packet = StringExtractorGDBRemote(packet_str); if (m_bytes[0] == '$' || m_bytes[0] == '%') { @@ -891,7 +869,7 @@ Status GDBRemoteCommunication::StartListenThread(const char *hostname, else snprintf(listen_url, sizeof(listen_url), "listen://%i", port); m_listen_url = listen_url; - SetConnection(new ConnectionFileDescriptor()); + SetConnection(std::make_unique()); llvm::Expected listen_thread = ThreadLauncher::LaunchThread( listen_url, GDBRemoteCommunication::ListenThread, this); if (!listen_thread) @@ -1274,11 +1252,12 @@ GDBRemoteCommunication::ConnectLocally(GDBRemoteCommunication &client, return llvm::createStringError(llvm::inconvertibleErrorCode(), "Unable to connect: %s", status.AsCString()); - client.SetConnection(conn_up.release()); + client.SetConnection(std::move(conn_up)); if (llvm::Error error = accept_status.get().ToError()) return error; - server.SetConnection(new ConnectionFileDescriptor(accept_socket)); + server.SetConnection( + std::make_unique(accept_socket)); return llvm::Error::success(); } @@ -1382,3 +1361,30 @@ void llvm::format_provider::format( break; } } + +std::string GDBRemoteCommunication::ExpandRLE(std::string packet) { + // Reserve enough byte for the most common case (no RLE used). + std::string decoded; + decoded.reserve(packet.size()); + for (std::string::const_iterator c = packet.begin(); c != packet.end(); ++c) { + if (*c == '*') { + // '*' indicates RLE. Next character will give us the repeat count and + // previous character is what is to be repeated. + char char_to_repeat = decoded.back(); + // Number of time the previous character is repeated. + int repeat_count = *++c + 3 - ' '; + // We have the char_to_repeat and repeat_count. Now push it in the + // packet. + for (int i = 0; i < repeat_count; ++i) + decoded.push_back(char_to_repeat); + } else if (*c == 0x7d) { + // 0x7d is the escape character. The next character is to be XOR'd with + // 0x20. + char escapee = *++c ^ 0x20; + decoded.push_back(escapee); + } else { + decoded.push_back(*c); + } + } + return decoded; +} diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h index 0b670018bd6..b1e2075a64f 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteCommunication_h_ -#define liblldb_GDBRemoteCommunication_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATION_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATION_H #include "GDBRemoteCommunicationHistory.h" @@ -142,6 +142,9 @@ public: static llvm::Error ConnectLocally(GDBRemoteCommunication &client, GDBRemoteCommunication &server); + /// Expand GDB run-length encoding. + static std::string ExpandRLE(std::string); + protected: std::chrono::seconds m_packet_timeout; uint32_t m_echo_number; @@ -223,7 +226,9 @@ private: void *m_decompression_scratch = nullptr; #endif - DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunication); + GDBRemoteCommunication(const GDBRemoteCommunication &) = delete; + const GDBRemoteCommunication & + operator=(const GDBRemoteCommunication &) = delete; }; } // namespace process_gdb_remote @@ -239,4 +244,4 @@ struct format_provider< }; } // namespace llvm -#endif // liblldb_GDBRemoteCommunication_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATION_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index 4dafa1d494d..c75d5e106cd 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunicationClient.cpp ------------------------*- C++ -*-===// +//===-- GDBRemoteCommunicationClient.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -45,6 +45,13 @@ using namespace lldb_private::process_gdb_remote; using namespace lldb_private; using namespace std::chrono; +llvm::raw_ostream &process_gdb_remote::operator<<(llvm::raw_ostream &os, + const QOffsets &offsets) { + return os << llvm::formatv( + "QOffsets({0}, [{1:@[x]}])", offsets.segments, + llvm::make_range(offsets.offsets.begin(), offsets.offsets.end())); +} + // GDBRemoteCommunicationClient constructor GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() : GDBRemoteClientBase("gdb-remote.client", "gdb-remote.client.rx_packet"), @@ -573,7 +580,8 @@ StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() { if (response.IsUnsupportedResponse()) { m_supports_jThreadsInfo = false; } else if (!response.Empty()) { - object_sp = StructuredData::ParseJSON(response.GetStringRef()); + object_sp = + StructuredData::ParseJSON(std::string(response.GetStringRef())); } } } @@ -685,7 +693,7 @@ GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses( if (result != PacketResult::Success) return result; - const std::string &this_string = this_response.GetStringRef(); + const std::string &this_string = std::string(this_response.GetStringRef()); // Check for m or l as first character; l seems to mean this is the last // chunk @@ -757,7 +765,7 @@ bool GDBRemoteCommunicationClient::GetLaunchSuccess(std::string &error_str) { return true; if (response.GetChar() == 'E') { // A string the describes what failed when launching... - error_str = response.GetStringRef().substr(1); + error_str = std::string(response.GetStringRef().substr(1)); } else { error_str.assign("unknown error occurred launching process"); } @@ -833,7 +841,7 @@ int GDBRemoteCommunicationClient::SendEnvironmentPacket( bool send_hex_encoding = false; for (const char *p = name_equal_value; *p != '\0' && !send_hex_encoding; ++p) { - if (isprint(*p)) { + if (llvm::isPrint(*p)) { switch (*p) { case '$': case '#': @@ -1000,7 +1008,7 @@ bool GDBRemoteCommunicationClient::GetGDBServerVersion() { while (response.GetNameColonValue(name, value)) { if (name.equals("name")) { success = true; - m_gdb_server_name = value; + m_gdb_server_name = std::string(value); } else if (name.equals("version")) { llvm::StringRef major, minor; std::tie(major, minor) = value.split('.'); @@ -1123,6 +1131,20 @@ bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) { return true; } +static void ParseOSType(llvm::StringRef value, std::string &os_name, + std::string &environment) { + if (value.equals("iossimulator") || value.equals("tvossimulator") || + value.equals("watchossimulator")) { + environment = "simulator"; + os_name = value.drop_back(environment.size()).str(); + } else if (value.equals("maccatalyst")) { + os_name = "ios"; + environment = "macabi"; + } else { + os_name = value.str(); + } +} + bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS)); @@ -1158,7 +1180,7 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { if (!value.getAsInteger(0, sub)) ++num_keys_decoded; } else if (name.equals("arch")) { - arch_name = value; + arch_name = std::string(value); ++num_keys_decoded; } else if (name.equals("triple")) { StringExtractor extractor(value); @@ -1181,14 +1203,10 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { extractor.GetHexByteString(m_os_kernel); ++num_keys_decoded; } else if (name.equals("ostype")) { - if (value.equals("maccatalyst")) { - os_name = "ios"; - environment = "macabi"; - } else - os_name = value; + ParseOSType(value, os_name, environment); ++num_keys_decoded; } else if (name.equals("vendor")) { - vendor_name = value; + vendor_name = std::string(value); ++num_keys_decoded; } else if (name.equals("endian")) { byte_order = llvm::StringSwitch(value) @@ -1956,9 +1974,9 @@ bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse( } else if (name.equals("cpusubtype")) { value.getAsInteger(0, sub); } else if (name.equals("vendor")) { - vendor = value; + vendor = std::string(value); } else if (name.equals("ostype")) { - os_type = value; + os_type = std::string(value); } } @@ -2045,14 +2063,10 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { extractor.GetHexByteString(triple); ++num_keys_decoded; } else if (name.equals("ostype")) { - if (value.equals("maccatalyst")) { - os_name = "ios"; - environment = "macabi"; - } else - os_name = value; + ParseOSType(value, os_name, environment); ++num_keys_decoded; } else if (name.equals("vendor")) { - vendor_name = value; + vendor_name = std::string(value); ++num_keys_decoded; } else if (name.equals("endian")) { byte_order = llvm::StringSwitch(value) @@ -2069,7 +2083,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { if (!value.getAsInteger(16, pid)) ++num_keys_decoded; } else if (name.equals("elf_abi")) { - elf_abi = value; + elf_abi = std::string(value); ++num_keys_decoded; } } @@ -2140,7 +2154,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { uint32_t GDBRemoteCommunicationClient::FindProcesses( const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) { - process_infos.Clear(); + process_infos.clear(); if (m_supports_qfProcessInfo) { StreamString packet; @@ -2220,7 +2234,7 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses( ProcessInstanceInfo process_info; if (!DecodeProcessInfoResponse(response, process_info)) break; - process_infos.Append(process_info); + process_infos.push_back(process_info); response = StringExtractorGDBRemote(); } while (SendPacketAndWaitForResponse("qsProcessInfo", response, false) == PacketResult::Success); @@ -2229,7 +2243,7 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses( return 0; } } - return process_infos.GetSize(); + return process_infos.size(); } bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid, @@ -2536,7 +2550,7 @@ size_t GDBRemoteCommunicationClient::QueryGDBServer( return 0; StructuredData::ObjectSP data = - StructuredData::ParseJSON(response.GetStringRef()); + StructuredData::ParseJSON(std::string(response.GetStringRef())); if (!data) return 0; @@ -2557,7 +2571,7 @@ size_t GDBRemoteCommunicationClient::QueryGDBServer( std::string socket_name; if (StructuredData::ObjectSP socket_name_osp = element->GetValueForKey(llvm::StringRef("socket_name"))) - socket_name = socket_name_osp->GetStringValue(); + socket_name = std::string(socket_name_osp->GetStringValue()); if (port != 0 || !socket_name.empty()) connection_urls.emplace_back(port, socket_name); @@ -2783,12 +2797,10 @@ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs( thread_ids.push_back(1); } } else { -#if !defined(LLDB_CONFIGURATION_DEBUG) Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)); - LLDB_LOGF(log, "error: failed to get packet sequence mutex, not sending " - "packet 'qfThreadInfo'"); -#endif + LLDB_LOG(log, "error: failed to get packet sequence mutex, not sending " + "packet 'qfThreadInfo'"); sequence_mutex_unavailable = true; } return thread_ids.size(); @@ -3478,7 +3490,7 @@ GDBRemoteCommunicationClient::SendGetTraceConfigPacket(lldb::user_id_t uid, return error; } else options.setTraceParams( - static_pointer_cast( + std::static_pointer_cast( custom_params_sp)); } } else { @@ -3530,6 +3542,46 @@ Status GDBRemoteCommunicationClient::SendGetTraceDataPacket( return error; } +llvm::Optional GDBRemoteCommunicationClient::GetQOffsets() { + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse( + "qOffsets", response, /*send_async=*/false) != PacketResult::Success) + return llvm::None; + if (!response.IsNormalResponse()) + return llvm::None; + + QOffsets result; + llvm::StringRef ref = response.GetStringRef(); + const auto &GetOffset = [&] { + addr_t offset; + if (ref.consumeInteger(16, offset)) + return false; + result.offsets.push_back(offset); + return true; + }; + + if (ref.consume_front("Text=")) { + result.segments = false; + if (!GetOffset()) + return llvm::None; + if (!ref.consume_front(";Data=") || !GetOffset()) + return llvm::None; + if (ref.empty()) + return result; + if (ref.consume_front(";Bss=") && GetOffset() && ref.empty()) + return result; + } else if (ref.consume_front("TextSeg=")) { + result.segments = true; + if (!GetOffset()) + return llvm::None; + if (ref.empty()) + return result; + if (ref.consume_front(";DataSeg=") && GetOffset() && ref.empty()) + return result; + } + return llvm::None; +} + bool GDBRemoteCommunicationClient::GetModuleInfo( const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec, ModuleSpec &module_spec) { @@ -3571,7 +3623,7 @@ bool GDBRemoteCommunicationClient::GetModuleInfo( StringExtractor extractor(value); std::string uuid; extractor.GetHexByteString(uuid); - module_spec.GetUUID().SetFromStringRef(uuid, uuid.size() / 2); + module_spec.GetUUID().SetFromStringRef(uuid); } else if (name == "triple") { StringExtractor extractor(value); std::string triple; @@ -3607,8 +3659,7 @@ ParseModuleSpec(StructuredData::Dictionary *dict) { if (!dict->GetValueForKeyAsString("uuid", string)) return llvm::None; - if (result.GetUUID().SetFromStringRef(string, string.size() / 2) != - string.size()) + if (!result.GetUUID().SetFromStringRef(string)) return llvm::None; if (!dict->GetValueForKeyAsInteger("file_offset", integer)) @@ -3667,7 +3718,7 @@ GDBRemoteCommunicationClient::GetModulesInfo( } StructuredData::ObjectSP response_object_sp = - StructuredData::ParseJSON(response.GetStringRef()); + StructuredData::ParseJSON(std::string(response.GetStringRef())); if (!response_object_sp) return llvm::None; @@ -3722,7 +3773,7 @@ bool GDBRemoteCommunicationClient::ReadExtFeature( return false; } - const std::string &str = chunk.GetStringRef(); + const std::string &str = std::string(chunk.GetStringRef()); if (str.length() == 0) { // should have some data in chunk err.SetErrorString("Empty response from $qXfer packet"); @@ -3936,7 +3987,7 @@ GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() { if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response, send_async) == PacketResult::Success) { m_supported_async_json_packets_sp = - StructuredData::ParseJSON(response.GetStringRef()); + StructuredData::ParseJSON(std::string(response.GetStringRef())); if (m_supported_async_json_packets_sp && !m_supported_async_json_packets_sp->GetAsArray()) { // We were returned something other than a JSON array. This is @@ -4002,7 +4053,7 @@ Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData( // Build command: Configure{type_name}: serialized config data. StreamGDBRemote stream; stream.PutCString("QConfigure"); - stream.PutCString(type_name.AsCString()); + stream.PutCString(type_name.GetStringRef()); stream.PutChar(':'); if (config_sp) { // Gather the plain-text version of the configuration data. diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index 11fd40bce44..8df08cbde73 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteCommunicationClient_h_ -#define liblldb_GDBRemoteCommunicationClient_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONCLIENT_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONCLIENT_H #include "GDBRemoteClientBase.h" @@ -20,6 +20,7 @@ #include "lldb/Host/File.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/GDBRemote.h" +#include "lldb/Utility/ProcessInfo.h" #include "lldb/Utility/StructuredData.h" #if defined(_WIN32) #include "lldb/Host/windows/PosixApi.h" @@ -31,6 +32,22 @@ namespace lldb_private { namespace process_gdb_remote { +/// The offsets used by the target when relocating the executable. Decoded from +/// qOffsets packet response. +struct QOffsets { + /// If true, the offsets field describes segments. Otherwise, it describes + /// sections. + bool segments; + + /// The individual offsets. Section offsets have two or three members. + /// Segment offsets have either one of two. + std::vector offsets; +}; +inline bool operator==(const QOffsets &a, const QOffsets &b) { + return a.segments == b.segments && a.offsets == b.offsets; +} +llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const QOffsets &offsets); + class GDBRemoteCommunicationClient : public GDBRemoteClientBase { public: GDBRemoteCommunicationClient(); @@ -425,6 +442,11 @@ public: bool GetSharedCacheInfoSupported(); + /// Use qOffsets to query the offset used when relocating the target + /// executable. If successful, the returned structure will contain at least + /// one value in the offsets field. + llvm::Optional GetQOffsets(); + bool GetModuleInfo(const FileSpec &module_file_spec, const ArchSpec &arch_spec, ModuleSpec &module_spec); @@ -599,10 +621,12 @@ protected: LazyBool GetThreadPacketSupported(lldb::tid_t tid, llvm::StringRef packetStr); private: - DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationClient); + GDBRemoteCommunicationClient(const GDBRemoteCommunicationClient &) = delete; + const GDBRemoteCommunicationClient & + operator=(const GDBRemoteCommunicationClient &) = delete; }; } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_GDBRemoteCommunicationClient_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONCLIENT_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp index 9e5646985f8..3984a45c3da 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunicationHistory.cpp -----------------------*- C++ -*-===// +//===-- GDBRemoteCommunicationHistory.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h index ee265ef86df..e783e59c345 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteCommunicationHistory_h_ -#define liblldb_GDBRemoteCommunicationHistory_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONHISTORY_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONHISTORY_H #include #include @@ -83,4 +83,4 @@ private: } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_GDBRemoteCommunicationHistory_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONHISTORY_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp index 15c73e78bd4..920327e7d0a 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunicationReplayServer.cpp ------------------*- C++ -*-===// +//===-- GDBRemoteCommunicationReplayServer.cpp ----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -131,22 +131,26 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse( GDBRemotePacket entry = m_packet_history.back(); m_packet_history.pop_back(); + // Decode run-length encoding. + const std::string expanded_data = + GDBRemoteCommunication::ExpandRLE(entry.packet.data); + // We've handled the handshake implicitly before. Skip the packet and move // on. if (entry.packet.data == "+") continue; if (entry.type == GDBRemotePacket::ePacketTypeSend) { - if (unexpected(entry.packet.data, packet.GetStringRef())) { + if (unexpected(expanded_data, packet.GetStringRef())) { LLDB_LOG(log, "GDBRemoteCommunicationReplayServer expected packet: '{0}'", - entry.packet.data); + expanded_data); LLDB_LOG(log, "GDBRemoteCommunicationReplayServer actual packet: '{0}'", packet.GetStringRef()); #ifndef NDEBUG // This behaves like a regular assert, but prints the expected and // received packet before aborting. - printf("Reproducer expected packet: '%s'\n", entry.packet.data.c_str()); + printf("Reproducer expected packet: '%s'\n", expanded_data.c_str()); printf("Reproducer received packet: '%s'\n", packet.GetStringRef().data()); llvm::report_fatal_error("Encountered unexpected packet during replay"); @@ -155,7 +159,7 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse( } // Ignore QEnvironment packets as they're handled earlier. - if (entry.packet.data.find("QEnvironment") == 1) { + if (expanded_data.find("QEnvironment") == 1) { assert(m_packet_history.back().type == GDBRemotePacket::ePacketTypeRecv); m_packet_history.pop_back(); @@ -283,3 +287,28 @@ thread_result_t GDBRemoteCommunicationReplayServer::AsyncThread(void *arg) { return {}; } + +Status GDBRemoteCommunicationReplayServer::Connect( + process_gdb_remote::GDBRemoteCommunicationClient &client) { + repro::Loader *loader = repro::Reproducer::Instance().GetLoader(); + if (!loader) + return Status("No loader provided."); + + static std::unique_ptr> + multi_loader = repro::MultiLoader::Create( + repro::Reproducer::Instance().GetLoader()); + if (!multi_loader) + return Status("No gdb remote provider found."); + + llvm::Optional history_file = multi_loader->GetNextFile(); + if (!history_file) + return Status("No gdb remote packet log found."); + + if (auto error = LoadReplayHistory(FileSpec(*history_file))) + return Status("Unable to load replay history"); + + if (auto error = GDBRemoteCommunication::ConnectLocally(client, *this)) + return Status("Unable to connect to replay server"); + + return {}; +} diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h index 0b5e910f7c6..c13e5ee0bf9 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h @@ -6,11 +6,12 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteCommunicationReplayServer_h_ -#define liblldb_GDBRemoteCommunicationReplayServer_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONREPLAYSERVER_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONREPLAYSERVER_H // Other libraries and framework includes #include "GDBRemoteCommunication.h" +#include "GDBRemoteCommunicationClient.h" #include "GDBRemoteCommunicationHistory.h" // Project includes @@ -51,6 +52,8 @@ public: bool StartAsyncThread(); void StopAsyncThread(); + Status Connect(process_gdb_remote::GDBRemoteCommunicationClient &client); + protected: enum { eBroadcastBitAsyncContinue = (1 << 0), @@ -73,10 +76,13 @@ protected: bool m_skip_acks; private: - DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationReplayServer); + GDBRemoteCommunicationReplayServer( + const GDBRemoteCommunicationReplayServer &) = delete; + const GDBRemoteCommunicationReplayServer & + operator=(const GDBRemoteCommunicationReplayServer &) = delete; }; } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_GDBRemoteCommunicationReplayServer_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONREPLAYSERVER_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp index ac6ecffcf85..b78f0916b9b 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunicationServer.cpp ------------------------*- C++ -*-===// +//===-- GDBRemoteCommunicationServer.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h index 86f0abf45e0..a7c2ea47e3b 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteCommunicationServer_h_ -#define liblldb_GDBRemoteCommunicationServer_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVER_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVER_H #include #include @@ -74,7 +74,9 @@ protected: PacketResult SendOKResponse(); private: - DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServer); + GDBRemoteCommunicationServer(const GDBRemoteCommunicationServer &) = delete; + const GDBRemoteCommunicationServer & + operator=(const GDBRemoteCommunicationServer &) = delete; }; class PacketUnimplementedError @@ -92,4 +94,4 @@ public: } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_GDBRemoteCommunicationServer_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVER_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp index ae238a86ab5..08d48985179 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunicationServerCommon.cpp ------------------*- C++ -*-===// +//===-- GDBRemoteCommunicationServerCommon.cpp ----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -334,7 +334,7 @@ GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo( StringExtractorGDBRemote &packet) { m_proc_infos_index = 0; - m_proc_infos.Clear(); + m_proc_infos.clear(); ProcessInstanceInfoMatch match_info; packet.SetFilePos(::strlen("qfProcessInfo")); @@ -416,10 +416,9 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo( StringExtractorGDBRemote &packet) { - if (m_proc_infos_index < m_proc_infos.GetSize()) { + if (m_proc_infos_index < m_proc_infos.size()) { StreamString response; - CreateProcessInfoResponse( - m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response); + CreateProcessInfoResponse(m_proc_infos[m_proc_infos_index], response); ++m_proc_infos_index; return SendPacketNoLock(response.GetString()); } @@ -843,7 +842,8 @@ GDBRemoteCommunicationServerCommon::Handle_qSupported( response.PutCString(";QThreadSuffixSupported+"); response.PutCString(";QListThreadsInStopReply+"); response.PutCString(";qEcho+"); -#if defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) + response.PutCString(";qXfer:features:read+"); +#if defined(__linux__) || defined(__NetBSD__) response.PutCString(";QPassSignals+"); response.PutCString(";qXfer:auxv:read+"); response.PutCString(";qXfer:libraries-svr4:read+"); @@ -1228,7 +1228,7 @@ void GDBRemoteCommunicationServerCommon:: if (cpu_subtype != 0) response.Printf("cpusubtype:%" PRIx32 ";", cpu_subtype); - const std::string vendor = proc_triple.getVendorName(); + const std::string vendor = proc_triple.getVendorName().str(); if (!vendor.empty()) response.Printf("vendor:%s;", vendor.c_str()); #else @@ -1237,7 +1237,7 @@ void GDBRemoteCommunicationServerCommon:: response.PutStringAsRawHex8(proc_triple.getTriple()); response.PutChar(';'); #endif - std::string ostype = proc_triple.getOSName(); + std::string ostype = std::string(proc_triple.getOSName()); // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64. if (proc_triple.getVendor() == llvm::Triple::Apple) { switch (proc_triple.getArch()) { diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h index 52554631247..0f933c09cbd 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteCommunicationServerCommon_h_ -#define liblldb_GDBRemoteCommunicationServerCommon_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERCOMMON_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERCOMMON_H #include @@ -152,4 +152,4 @@ private: } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_GDBRemoteCommunicationServerCommon_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERCOMMON_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index f33f0ee6630..ae2f4bd041c 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunicationServerLLGS.cpp --------------------*- C++ -*-===// +//===-- GDBRemoteCommunicationServerLLGS.cpp ------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -377,6 +377,99 @@ static void AppendHexValue(StreamString &response, const uint8_t *buf, } } +static llvm::StringRef GetEncodingNameOrEmpty(const RegisterInfo ®_info) { + switch (reg_info.encoding) { + case eEncodingUint: + return "uint"; + case eEncodingSint: + return "sint"; + case eEncodingIEEE754: + return "ieee754"; + case eEncodingVector: + return "vector"; + default: + return ""; + } +} + +static llvm::StringRef GetFormatNameOrEmpty(const RegisterInfo ®_info) { + switch (reg_info.format) { + case eFormatBinary: + return "binary"; + case eFormatDecimal: + return "decimal"; + case eFormatHex: + return "hex"; + case eFormatFloat: + return "float"; + case eFormatVectorOfSInt8: + return "vector-sint8"; + case eFormatVectorOfUInt8: + return "vector-uint8"; + case eFormatVectorOfSInt16: + return "vector-sint16"; + case eFormatVectorOfUInt16: + return "vector-uint16"; + case eFormatVectorOfSInt32: + return "vector-sint32"; + case eFormatVectorOfUInt32: + return "vector-uint32"; + case eFormatVectorOfFloat32: + return "vector-float32"; + case eFormatVectorOfUInt64: + return "vector-uint64"; + case eFormatVectorOfUInt128: + return "vector-uint128"; + default: + return ""; + }; +} + +static llvm::StringRef GetKindGenericOrEmpty(const RegisterInfo ®_info) { + switch (reg_info.kinds[RegisterKind::eRegisterKindGeneric]) { + case LLDB_REGNUM_GENERIC_PC: + return "pc"; + case LLDB_REGNUM_GENERIC_SP: + return "sp"; + case LLDB_REGNUM_GENERIC_FP: + return "fp"; + case LLDB_REGNUM_GENERIC_RA: + return "ra"; + case LLDB_REGNUM_GENERIC_FLAGS: + return "flags"; + case LLDB_REGNUM_GENERIC_ARG1: + return "arg1"; + case LLDB_REGNUM_GENERIC_ARG2: + return "arg2"; + case LLDB_REGNUM_GENERIC_ARG3: + return "arg3"; + case LLDB_REGNUM_GENERIC_ARG4: + return "arg4"; + case LLDB_REGNUM_GENERIC_ARG5: + return "arg5"; + case LLDB_REGNUM_GENERIC_ARG6: + return "arg6"; + case LLDB_REGNUM_GENERIC_ARG7: + return "arg7"; + case LLDB_REGNUM_GENERIC_ARG8: + return "arg8"; + default: + return ""; + } +} + +static void CollectRegNums(const uint32_t *reg_num, StreamString &response, + bool usehex) { + for (int i = 0; *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) { + if (i > 0) + response.PutChar(','); + if (usehex) + response.Printf("%" PRIx32, *reg_num); + else + response.Printf("%" PRIu32, *reg_num); + } +} + static void WriteRegisterValueInHexFixedWidth( StreamString &response, NativeRegisterContext ®_ctx, const RegisterInfo ®_info, const RegisterValue *reg_value_p, @@ -922,9 +1015,9 @@ void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() { } Status GDBRemoteCommunicationServerLLGS::InitializeConnection( - std::unique_ptr &&connection) { + std::unique_ptr connection) { IOObjectSP read_object_sp = connection->GetReadObject(); - GDBRemoteCommunicationServer::SetConnection(connection.release()); + GDBRemoteCommunicationServer::SetConnection(std::move(connection)); Status error; m_network_handle_up = m_mainloop.RegisterReadObject( @@ -960,7 +1053,7 @@ Status GDBRemoteCommunicationServerLLGS::SetSTDIOFileDescriptor(int fd) { } m_stdio_communication.SetCloseOnEOF(false); - m_stdio_communication.SetConnection(conn_up.release()); + m_stdio_communication.SetConnection(std::move(conn_up)); if (!m_stdio_communication.IsConnected()) { error.SetErrorString( "failed to set connection for inferior I/O communication"); @@ -1072,7 +1165,7 @@ GDBRemoteCommunicationServerLLGS::Handle_jTraceStart( return SendIllFormedResponse(packet, "jTraceStart: Ill formed packet "); options.setTraceParams( - static_pointer_cast(custom_params_sp)); + std::static_pointer_cast(custom_params_sp)); if (buffersize == std::numeric_limits::max() || type != lldb::TraceType::eTraceTypeProcessorTrace) { @@ -1699,74 +1792,18 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo( response.Printf("bitsize:%" PRIu32 ";offset:%" PRIu32 ";", reg_info->byte_size * 8, reg_info->byte_offset); - switch (reg_info->encoding) { - case eEncodingUint: - response.PutCString("encoding:uint;"); - break; - case eEncodingSint: - response.PutCString("encoding:sint;"); - break; - case eEncodingIEEE754: - response.PutCString("encoding:ieee754;"); - break; - case eEncodingVector: - response.PutCString("encoding:vector;"); - break; - default: - break; - } + llvm::StringRef encoding = GetEncodingNameOrEmpty(*reg_info); + if (!encoding.empty()) + response << "encoding:" << encoding << ';'; - switch (reg_info->format) { - case eFormatBinary: - response.PutCString("format:binary;"); - break; - case eFormatDecimal: - response.PutCString("format:decimal;"); - break; - case eFormatHex: - response.PutCString("format:hex;"); - break; - case eFormatFloat: - response.PutCString("format:float;"); - break; - case eFormatVectorOfSInt8: - response.PutCString("format:vector-sint8;"); - break; - case eFormatVectorOfUInt8: - response.PutCString("format:vector-uint8;"); - break; - case eFormatVectorOfSInt16: - response.PutCString("format:vector-sint16;"); - break; - case eFormatVectorOfUInt16: - response.PutCString("format:vector-uint16;"); - break; - case eFormatVectorOfSInt32: - response.PutCString("format:vector-sint32;"); - break; - case eFormatVectorOfUInt32: - response.PutCString("format:vector-uint32;"); - break; - case eFormatVectorOfFloat32: - response.PutCString("format:vector-float32;"); - break; - case eFormatVectorOfUInt64: - response.PutCString("format:vector-uint64;"); - break; - case eFormatVectorOfUInt128: - response.PutCString("format:vector-uint128;"); - break; - default: - break; - }; + llvm::StringRef format = GetFormatNameOrEmpty(*reg_info); + if (!format.empty()) + response << "format:" << format << ';'; const char *const register_set_name = reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index); - if (register_set_name) { - response.PutCString("set:"); - response.PutCString(register_set_name); - response.PutChar(';'); - } + if (register_set_name) + response << "set:" << register_set_name << ';'; if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] != LLDB_INVALID_REGNUM) @@ -1777,71 +1814,19 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo( response.Printf("dwarf:%" PRIu32 ";", reg_info->kinds[RegisterKind::eRegisterKindDWARF]); - switch (reg_info->kinds[RegisterKind::eRegisterKindGeneric]) { - case LLDB_REGNUM_GENERIC_PC: - response.PutCString("generic:pc;"); - break; - case LLDB_REGNUM_GENERIC_SP: - response.PutCString("generic:sp;"); - break; - case LLDB_REGNUM_GENERIC_FP: - response.PutCString("generic:fp;"); - break; - case LLDB_REGNUM_GENERIC_RA: - response.PutCString("generic:ra;"); - break; - case LLDB_REGNUM_GENERIC_FLAGS: - response.PutCString("generic:flags;"); - break; - case LLDB_REGNUM_GENERIC_ARG1: - response.PutCString("generic:arg1;"); - break; - case LLDB_REGNUM_GENERIC_ARG2: - response.PutCString("generic:arg2;"); - break; - case LLDB_REGNUM_GENERIC_ARG3: - response.PutCString("generic:arg3;"); - break; - case LLDB_REGNUM_GENERIC_ARG4: - response.PutCString("generic:arg4;"); - break; - case LLDB_REGNUM_GENERIC_ARG5: - response.PutCString("generic:arg5;"); - break; - case LLDB_REGNUM_GENERIC_ARG6: - response.PutCString("generic:arg6;"); - break; - case LLDB_REGNUM_GENERIC_ARG7: - response.PutCString("generic:arg7;"); - break; - case LLDB_REGNUM_GENERIC_ARG8: - response.PutCString("generic:arg8;"); - break; - default: - break; - } + llvm::StringRef kind_generic = GetKindGenericOrEmpty(*reg_info); + if (!kind_generic.empty()) + response << "generic:" << kind_generic << ';'; if (reg_info->value_regs && reg_info->value_regs[0] != LLDB_INVALID_REGNUM) { response.PutCString("container-regs:"); - int i = 0; - for (const uint32_t *reg_num = reg_info->value_regs; - *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) { - if (i > 0) - response.PutChar(','); - response.Printf("%" PRIx32, *reg_num); - } + CollectRegNums(reg_info->value_regs, response, true); response.PutChar(';'); } if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) { response.PutCString("invalidate-regs:"); - int i = 0; - for (const uint32_t *reg_num = reg_info->invalidate_regs; - *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) { - if (i > 0) - response.PutChar(','); - response.Printf("%" PRIx32, *reg_num); - } + CollectRegNums(reg_info->invalidate_regs, response, true); response.PutChar(';'); } @@ -2055,7 +2040,7 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { packet, "P packet missing '=' char after register number"); // Parse out the value. - uint8_t reg_bytes[32]; // big enough to support up to 256 bit ymmN register + uint8_t reg_bytes[RegisterValue::kMaxRegisterByteSize]; size_t reg_size = packet.GetHexBytesAvail(reg_bytes); // Get the thread to use. @@ -2510,7 +2495,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo( ConstString name = region_info.GetName(); if (name) { response.PutCString("name:"); - response.PutStringAsRawHex8(name.AsCString()); + response.PutStringAsRawHex8(name.GetStringRef()); response.PutChar(';'); } } @@ -2750,17 +2735,119 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) { return PacketResult::Success; } +llvm::Expected> +GDBRemoteCommunicationServerLLGS::BuildTargetXml() { + // Ensure we have a thread. + NativeThreadProtocol *thread = m_debugged_process_up->GetThreadAtIndex(0); + if (!thread) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "No thread available"); + + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); + // Get the register context for the first thread. + NativeRegisterContext ®_context = thread->GetRegisterContext(); + + StreamString response; + + response.Printf(""); + response.Printf(""); + + response.Printf("%s", + m_debugged_process_up->GetArchitecture() + .GetTriple() + .getArchName() + .str() + .c_str()); + + response.Printf(""); + + const int registers_count = reg_context.GetUserRegisterCount(); + for (int reg_index = 0; reg_index < registers_count; reg_index++) { + const RegisterInfo *reg_info = + reg_context.GetRegisterInfoAtIndex(reg_index); + + if (!reg_info) { + LLDB_LOGF(log, + "%s failed to get register info for register index %" PRIu32, + "target.xml", reg_index); + continue; + } + + response.Printf("name, reg_info->byte_size * 8, + reg_info->byte_offset, reg_index); + + if (reg_info->alt_name && reg_info->alt_name[0]) + response.Printf("altname=\"%s\" ", reg_info->alt_name); + + llvm::StringRef encoding = GetEncodingNameOrEmpty(*reg_info); + if (!encoding.empty()) + response << "encoding=\"" << encoding << "\" "; + + llvm::StringRef format = GetFormatNameOrEmpty(*reg_info); + if (!format.empty()) + response << "format=\"" << format << "\" "; + + const char *const register_set_name = + reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index); + if (register_set_name) + response << "group=\"" << register_set_name << "\" "; + + if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] != + LLDB_INVALID_REGNUM) + response.Printf("ehframe_regnum=\"%" PRIu32 "\" ", + reg_info->kinds[RegisterKind::eRegisterKindEHFrame]); + + if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] != + LLDB_INVALID_REGNUM) + response.Printf("dwarf_regnum=\"%" PRIu32 "\" ", + reg_info->kinds[RegisterKind::eRegisterKindDWARF]); + + llvm::StringRef kind_generic = GetKindGenericOrEmpty(*reg_info); + if (!kind_generic.empty()) + response << "generic=\"" << kind_generic << "\" "; + + if (reg_info->value_regs && + reg_info->value_regs[0] != LLDB_INVALID_REGNUM) { + response.PutCString("value_regnums=\""); + CollectRegNums(reg_info->value_regs, response, false); + response.Printf("\" "); + } + + if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) { + response.PutCString("invalidate_regnums=\""); + CollectRegNums(reg_info->invalidate_regs, response, false); + response.Printf("\" "); + } + + if (reg_info->dynamic_size_dwarf_expr_bytes) { + const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len; + response.PutCString("dynamic_size_dwarf_expr_bytes=\""); + for (uint32_t i = 0; i < dwarf_opcode_len; ++i) + response.PutHex8(reg_info->dynamic_size_dwarf_expr_bytes[i]); + response.Printf("\" "); + } + + response.Printf("/>"); + } + + response.Printf(""); + response.Printf(""); + return MemoryBuffer::getMemBufferCopy(response.GetString(), "target.xml"); +} + llvm::Expected> GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object, llvm::StringRef annex) { - if (object == "auxv") { - // Make sure we have a valid process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "No process available"); - } + // Make sure we have a valid process. + if (!m_debugged_process_up || + (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "No process available"); + } + if (object == "auxv") { // Grab the auxv data. auto buffer_or_error = m_debugged_process_up->GetAuxvData(); if (!buffer_or_error) @@ -2786,6 +2873,9 @@ GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object, return MemoryBuffer::getMemBufferCopy(response.GetString(), __FUNCTION__); } + if (object == "features" && annex == "target.xml") + return BuildTargetXml(); + return llvm::make_error( "Xfer object not supported"); } diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h index 088ba92ad11..3ce285910c2 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteCommunicationServerLLGS_h_ -#define liblldb_GDBRemoteCommunicationServerLLGS_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERLLGS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERLLGS_H #include #include @@ -67,7 +67,7 @@ public: void DidExec(NativeProcessProtocol *process) override; - Status InitializeConnection(std::unique_ptr &&connection); + Status InitializeConnection(std::unique_ptr connection); protected: MainLoop &m_mainloop; @@ -199,6 +199,8 @@ protected: static std::string XMLEncodeAttributeValue(llvm::StringRef value); private: + llvm::Expected> BuildTargetXml(); + void HandleInferiorState_Exited(NativeProcessProtocol *process); void HandleInferiorState_Stopped(NativeProcessProtocol *process); @@ -222,10 +224,13 @@ private: void StopSTDIOForwarding(); // For GDBRemoteCommunicationServerLLGS only - DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServerLLGS); + GDBRemoteCommunicationServerLLGS(const GDBRemoteCommunicationServerLLGS &) = + delete; + const GDBRemoteCommunicationServerLLGS & + operator=(const GDBRemoteCommunicationServerLLGS &) = delete; }; } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_GDBRemoteCommunicationServerLLGS_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERLLGS_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp index 25cebbba8f7..d14b79a03d1 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunicationServerPlatform.cpp ----------------*- C++ -*-===// +//===-- GDBRemoteCommunicationServerPlatform.cpp --------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -173,7 +173,7 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer( uint16_t port = UINT16_MAX; while (packet.GetNameColonValue(name, value)) { if (name.equals("host")) - hostname = value; + hostname = std::string(value); else if (name.equals("port")) value.getAsInteger(0, port); } diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h index eacc99a012d..a8cacea7883 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteCommunicationServerPlatform_h_ -#define liblldb_GDBRemoteCommunicationServerPlatform_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERPLATFORM_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERPLATFORM_H #include #include @@ -100,10 +100,13 @@ private: static FileSpec GetDomainSocketPath(const char *prefix); - DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServerPlatform); + GDBRemoteCommunicationServerPlatform( + const GDBRemoteCommunicationServerPlatform &) = delete; + const GDBRemoteCommunicationServerPlatform & + operator=(const GDBRemoteCommunicationServerPlatform &) = delete; }; } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_GDBRemoteCommunicationServerPlatform_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERPLATFORM_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index ec1a54afd72..1f31b45d0fa 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteRegisterContext.cpp ----------------------------*- C++ -*-===// +//===-- GDBRemoteRegisterContext.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h index b42c87b5991..01586258710 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_GDBRemoteRegisterContext_h_ -#define lldb_GDBRemoteRegisterContext_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTEREGISTERCONTEXT_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTEREGISTERCONTEXT_H #include @@ -88,9 +88,7 @@ protected: void SetAllRegisterValid(bool b); bool GetRegisterIsValid(uint32_t reg) const { -#if defined(LLDB_CONFIGURATION_DEBUG) assert(reg < m_reg_valid.size()); -#endif if (reg < m_reg_valid.size()) return m_reg_valid[reg]; return false; @@ -103,9 +101,7 @@ protected: } void SetRegisterIsValid(uint32_t reg, bool valid) { -#if defined(LLDB_CONFIGURATION_DEBUG) assert(reg < m_reg_valid.size()); -#endif if (reg < m_reg_valid.size()) m_reg_valid[reg] = valid; } @@ -124,10 +120,12 @@ private: bool SetPrimordialRegister(const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm); - DISALLOW_COPY_AND_ASSIGN(GDBRemoteRegisterContext); + GDBRemoteRegisterContext(const GDBRemoteRegisterContext &) = delete; + const GDBRemoteRegisterContext & + operator=(const GDBRemoteRegisterContext &) = delete; }; } // namespace process_gdb_remote } // namespace lldb_private -#endif // lldb_GDBRemoteRegisterContext_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTEREGISTERCONTEXT_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index a49db5d9a93..1fed8e06426 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -1,4 +1,4 @@ -//===-- ProcessGDBRemote.cpp ------------------------------------*- C++ -*-===// +//===-- ProcessGDBRemote.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -17,6 +17,9 @@ #include #endif #include +#if defined(__APPLE__) +#include +#endif #include #include @@ -90,6 +93,8 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::process_gdb_remote; +LLDB_PLUGIN_DEFINE(ProcessGDBRemote) + namespace lldb { // Provide a function that can easily dump the packet history if we know a // ProcessGDBRemote * value (which we can get from logs or from debugging). We @@ -184,21 +189,6 @@ static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() { #define HIGH_PORT (49151u) #endif -#if defined(__APPLE__) && \ - (defined(__arm__) || defined(__arm64__) || defined(__aarch64__)) -static bool rand_initialized = false; - -static inline uint16_t get_random_port() { - if (!rand_initialized) { - time_t seed = time(NULL); - - rand_initialized = true; - srand(seed); - } - return (rand() % (HIGH_PORT - LOW_PORT)) + LOW_PORT; -} -#endif - ConstString ProcessGDBRemote::GetPluginNameStatic() { static ConstString g_name("gdb-remote"); return g_name; @@ -359,7 +349,8 @@ bool ProcessGDBRemote::ParsePythonTargetDefinition( StructuredData::ObjectSP triple_value = host_info_dict->GetValueForKey("triple"); if (auto triple_string_value = triple_value->GetAsString()) { - std::string triple_string = triple_string_value->GetValue(); + std::string triple_string = + std::string(triple_string_value->GetValue()); ArchSpec host_arch(triple_string.c_str()); if (!host_arch.IsCompatibleMatch(GetTarget().GetArchitecture())) { GetTarget().SetArchitecture(host_arch); @@ -638,15 +629,17 @@ Status ProcessGDBRemote::WillAttachToProcessWithName(const char *process_name, return WillLaunchOrAttach(); } -Status ProcessGDBRemote::DoConnectRemote(Stream *strm, - llvm::StringRef remote_url) { +Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); Status error(WillLaunchOrAttach()); if (error.Fail()) return error; - error = ConnectToDebugserver(remote_url); + if (repro::Reproducer::Instance().IsReplaying()) + error = ConnectToReplayServer(); + else + error = ConnectToDebugserver(remote_url); if (error.Fail()) return error; @@ -824,22 +817,23 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module, // since 'O' packets can really slow down debugging if the inferior // does a lot of output. if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) && - pty.OpenFirstAvailableMaster(O_RDWR | O_NOCTTY, nullptr, 0)) { - FileSpec slave_name{pty.GetSlaveName(nullptr, 0)}; + pty.OpenFirstAvailablePrimary(O_RDWR | O_NOCTTY, nullptr, 0)) { + FileSpec secondary_name{pty.GetSecondaryName(nullptr, 0)}; if (!stdin_file_spec) - stdin_file_spec = slave_name; + stdin_file_spec = secondary_name; if (!stdout_file_spec) - stdout_file_spec = slave_name; + stdout_file_spec = secondary_name; if (!stderr_file_spec) - stderr_file_spec = slave_name; + stderr_file_spec = secondary_name; } LLDB_LOGF( log, "ProcessGDBRemote::%s adjusted STDIO paths for local platform " - "(IsHost() is true) using slave: stdin=%s, stdout=%s, stderr=%s", + "(IsHost() is true) using secondary: stdin=%s, stdout=%s, " + "stderr=%s", __FUNCTION__, stdin_file_spec ? stdin_file_spec.GetCString() : "", stdout_file_spec ? stdout_file_spec.GetCString() : "", @@ -924,8 +918,8 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module, SetPrivateState(SetThreadStopInfo(response)); if (!disable_stdio) { - if (pty.GetMasterFileDescriptor() != PseudoTerminal::invalid_fd) - SetSTDIOFileDescriptor(pty.ReleaseMasterFileDescriptor()); + if (pty.GetPrimaryFileDescriptor() != PseudoTerminal::invalid_fd) + SetSTDIOFileDescriptor(pty.ReleasePrimaryFileDescriptor()); } } } else { @@ -957,7 +951,7 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) { uint32_t retry_count = 0; while (!m_gdb_comm.IsConnected()) { if (conn_up->Connect(connect_url, &error) == eConnectionStatusSuccess) { - m_gdb_comm.SetConnection(conn_up.release()); + m_gdb_comm.SetConnection(std::move(conn_up)); break; } else if (error.WasInterrupted()) { // If we were interrupted, don't keep retrying. @@ -1023,122 +1017,113 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) { void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - LLDB_LOGF(log, "ProcessGDBRemote::%s()", __FUNCTION__); - if (GetID() != LLDB_INVALID_PROCESS_ID) { - BuildDynamicRegisterInfo(false); + BuildDynamicRegisterInfo(false); - // See if the GDB server supports the qHostInfo information + // See if the GDB server supports qHostInfo or qProcessInfo packets. Prefer + // qProcessInfo as it will be more specific to our process. - // See if the GDB server supports the qProcessInfo packet, if so prefer - // that over the Host information as it will be more specific to our - // process. + const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture(); + if (remote_process_arch.IsValid()) { + process_arch = remote_process_arch; + LLDB_LOG(log, "gdb-remote had process architecture, using {0} {1}", + process_arch.GetArchitectureName(), + process_arch.GetTriple().getTriple()); + } else { + process_arch = m_gdb_comm.GetHostArchitecture(); + LLDB_LOG(log, + "gdb-remote did not have process architecture, using gdb-remote " + "host architecture {0} {1}", + process_arch.GetArchitectureName(), + process_arch.GetTriple().getTriple()); + } - const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture(); - if (remote_process_arch.IsValid()) { - process_arch = remote_process_arch; - LLDB_LOGF(log, - "ProcessGDBRemote::%s gdb-remote had process architecture, " - "using %s %s", - __FUNCTION__, - process_arch.GetArchitectureName() - ? process_arch.GetArchitectureName() - : "", - process_arch.GetTriple().getTriple().c_str() - ? process_arch.GetTriple().getTriple().c_str() - : ""); - } else { - process_arch = m_gdb_comm.GetHostArchitecture(); - LLDB_LOGF(log, - "ProcessGDBRemote::%s gdb-remote did not have process " - "architecture, using gdb-remote host architecture %s %s", - __FUNCTION__, - process_arch.GetArchitectureName() - ? process_arch.GetArchitectureName() - : "", - process_arch.GetTriple().getTriple().c_str() - ? process_arch.GetTriple().getTriple().c_str() - : ""); - } + if (process_arch.IsValid()) { + const ArchSpec &target_arch = GetTarget().GetArchitecture(); + if (target_arch.IsValid()) { + LLDB_LOG(log, "analyzing target arch, currently {0} {1}", + target_arch.GetArchitectureName(), + target_arch.GetTriple().getTriple()); + + // If the remote host is ARM and we have apple as the vendor, then + // ARM executables and shared libraries can have mixed ARM + // architectures. + // You can have an armv6 executable, and if the host is armv7, then the + // system will load the best possible architecture for all shared + // libraries it has, so we really need to take the remote host + // architecture as our defacto architecture in this case. + + if ((process_arch.GetMachine() == llvm::Triple::arm || + process_arch.GetMachine() == llvm::Triple::thumb) && + process_arch.GetTriple().getVendor() == llvm::Triple::Apple) { + GetTarget().SetArchitecture(process_arch); + LLDB_LOG(log, + "remote process is ARM/Apple, " + "setting target arch to {0} {1}", + process_arch.GetArchitectureName(), + process_arch.GetTriple().getTriple()); + } else { + // Fill in what is missing in the triple + const llvm::Triple &remote_triple = process_arch.GetTriple(); + llvm::Triple new_target_triple = target_arch.GetTriple(); + if (new_target_triple.getVendorName().size() == 0) { + new_target_triple.setVendor(remote_triple.getVendor()); - if (process_arch.IsValid()) { - const ArchSpec &target_arch = GetTarget().GetArchitecture(); - if (target_arch.IsValid()) { - LLDB_LOGF(log, - "ProcessGDBRemote::%s analyzing target arch, currently %s %s", - __FUNCTION__, - target_arch.GetArchitectureName() - ? target_arch.GetArchitectureName() - : "", - target_arch.GetTriple().getTriple().c_str() - ? target_arch.GetTriple().getTriple().c_str() - : ""); - - // If the remote host is ARM and we have apple as the vendor, then - // ARM executables and shared libraries can have mixed ARM - // architectures. - // You can have an armv6 executable, and if the host is armv7, then the - // system will load the best possible architecture for all shared - // libraries it has, so we really need to take the remote host - // architecture as our defacto architecture in this case. - - if ((process_arch.GetMachine() == llvm::Triple::arm || - process_arch.GetMachine() == llvm::Triple::thumb) && - process_arch.GetTriple().getVendor() == llvm::Triple::Apple) { - GetTarget().SetArchitecture(process_arch); - LLDB_LOGF(log, - "ProcessGDBRemote::%s remote process is ARM/Apple, " - "setting target arch to %s %s", - __FUNCTION__, - process_arch.GetArchitectureName() - ? process_arch.GetArchitectureName() - : "", - process_arch.GetTriple().getTriple().c_str() - ? process_arch.GetTriple().getTriple().c_str() - : ""); - } else { - // Fill in what is missing in the triple - const llvm::Triple &remote_triple = process_arch.GetTriple(); - llvm::Triple new_target_triple = target_arch.GetTriple(); - if (new_target_triple.getVendorName().size() == 0) { - new_target_triple.setVendor(remote_triple.getVendor()); - - if (new_target_triple.getOSName().size() == 0) { - new_target_triple.setOS(remote_triple.getOS()); - - if (new_target_triple.getEnvironmentName().size() == 0) - new_target_triple.setEnvironment( - remote_triple.getEnvironment()); - } + if (new_target_triple.getOSName().size() == 0) { + new_target_triple.setOS(remote_triple.getOS()); - ArchSpec new_target_arch = target_arch; - new_target_arch.SetTriple(new_target_triple); - GetTarget().SetArchitecture(new_target_arch); + if (new_target_triple.getEnvironmentName().size() == 0) + new_target_triple.setEnvironment(remote_triple.getEnvironment()); } - } - LLDB_LOGF(log, - "ProcessGDBRemote::%s final target arch after " - "adjustments for remote architecture: %s %s", - __FUNCTION__, - target_arch.GetArchitectureName() - ? target_arch.GetArchitectureName() - : "", - target_arch.GetTriple().getTriple().c_str() - ? target_arch.GetTriple().getTriple().c_str() - : ""); - } else { - // The target doesn't have a valid architecture yet, set it from the - // architecture we got from the remote GDB server - GetTarget().SetArchitecture(process_arch); + ArchSpec new_target_arch = target_arch; + new_target_arch.SetTriple(new_target_triple); + GetTarget().SetArchitecture(new_target_arch); + } } + + LLDB_LOG(log, + "final target arch after adjustments for remote architecture: " + "{0} {1}", + target_arch.GetArchitectureName(), + target_arch.GetTriple().getTriple()); + } else { + // The target doesn't have a valid architecture yet, set it from the + // architecture we got from the remote GDB server + GetTarget().SetArchitecture(process_arch); } + } + + MaybeLoadExecutableModule(); + + // Find out which StructuredDataPlugins are supported by the debug monitor. + // These plugins transmit data over async $J packets. + if (StructuredData::Array *supported_packets = + m_gdb_comm.GetSupportedStructuredDataPlugins()) + MapSupportedStructuredDataPlugins(*supported_packets); +} + +void ProcessGDBRemote::MaybeLoadExecutableModule() { + ModuleSP module_sp = GetTarget().GetExecutableModule(); + if (!module_sp) + return; + + llvm::Optional offsets = m_gdb_comm.GetQOffsets(); + if (!offsets) + return; - // Find out which StructuredDataPlugins are supported by the debug monitor. - // These plugins transmit data over async $J packets. - auto supported_packets_array = - m_gdb_comm.GetSupportedStructuredDataPlugins(); - if (supported_packets_array) - MapSupportedStructuredDataPlugins(*supported_packets_array); + bool is_uniform = + size_t(llvm::count(offsets->offsets, offsets->offsets[0])) == + offsets->offsets.size(); + if (!is_uniform) + return; // TODO: Handle non-uniform responses. + + bool changed = false; + module_sp->SetLoadAddress(GetTarget(), offsets->offsets[0], + /*value_is_offset=*/true, changed); + if (changed) { + ModuleList list; + list.Append(module_sp); + m_process->GetTarget().ModulesDidLoad(list); } } @@ -1576,7 +1561,8 @@ bool ProcessGDBRemote::UpdateThreadIDList() { for (int i = 0; i < nItems; i++) { // Get the thread stop info StringExtractorGDBRemote &stop_info = m_stop_packet_stack[i]; - const std::string &stop_info_str = stop_info.GetStringRef(); + const std::string &stop_info_str = + std::string(stop_info.GetStringRef()); m_thread_pcs.clear(); const size_t thread_pcs_pos = stop_info_str.find(";thread-pcs:"); @@ -2040,14 +2026,14 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) { }); } } else if (key == g_key_name) { - thread_name = object->GetStringValue(); + thread_name = std::string(object->GetStringValue()); } else if (key == g_key_qaddr) { thread_dispatch_qaddr = object->GetIntegerValue(LLDB_INVALID_ADDRESS); } else if (key == g_key_queue_name) { queue_vars_valid = true; - queue_name = object->GetStringValue(); + queue_name = std::string(object->GetStringValue()); } else if (key == g_key_queue_kind) { - std::string queue_kind_str = object->GetStringValue(); + std::string queue_kind_str = std::string(object->GetStringValue()); if (queue_kind_str == "serial") { queue_vars_valid = true; queue_kind = eQueueKindSerial; @@ -2071,9 +2057,9 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) { else associated_with_dispatch_queue = eLazyBoolNo; } else if (key == g_key_reason) { - reason = object->GetStringValue(); + reason = std::string(object->GetStringValue()); } else if (key == g_key_description) { - description = object->GetStringValue(); + description = std::string(object->GetStringValue()); } else if (key == g_key_registers) { StructuredData::Dictionary *registers_dict = object->GetAsDictionary(); @@ -2084,7 +2070,8 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) { const uint32_t reg = StringConvert::ToUInt32(key.GetCString(), UINT32_MAX, 10); if (reg != UINT32_MAX) - expedited_register_map[reg] = object->GetStringValue(); + expedited_register_map[reg] = + std::string(object->GetStringValue()); return true; // Keep iterating through all array items }); } @@ -2227,7 +2214,7 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { // Now convert the HEX bytes into a string value name_extractor.GetHexByteString(thread_name); } else if (key.compare("name") == 0) { - thread_name = value; + thread_name = std::string(value); } else if (key.compare("qaddr") == 0) { value.getAsInteger(16, thread_dispatch_qaddr); } else if (key.compare("dispatch_queue_t") == 0) { @@ -2248,7 +2235,7 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { if (!value.getAsInteger(0, queue_serial_number)) queue_vars_valid = true; } else if (key.compare("reason") == 0) { - reason = value; + reason = std::string(value); } else if (key.compare("description") == 0) { StringExtractor desc_extractor(value); // Now convert the HEX bytes into a string value @@ -2297,7 +2284,7 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { reason = "watchpoint"; StreamString ostr; ostr.Printf("%" PRIu64 " %" PRIu32, wp_addr, wp_index); - description = ostr.GetString(); + description = std::string(ostr.GetString()); } else if (key.compare("library") == 0) { auto error = LoadModules(); if (error) { @@ -2308,7 +2295,7 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { } else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) { uint32_t reg = UINT32_MAX; if (!key.getAsInteger(16, reg)) - expedited_register_map[reg] = std::move(value); + expedited_register_map[reg] = std::string(std::move(value)); } } @@ -2585,7 +2572,7 @@ Status ProcessGDBRemote::DoDestroy() { "to k packet: %s", response.GetStringRef().data()); exit_string.assign("got unexpected response to k packet: "); - exit_string.append(response.GetStringRef()); + exit_string.append(std::string(response.GetStringRef())); } } else { LLDB_LOGF(log, "ProcessGDBRemote::DoDestroy - failed to send k packet"); @@ -3127,7 +3114,7 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) { if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware)) { if (error_no != UINT8_MAX) error.SetErrorStringWithFormat( - "error: %d sending the breakpoint request", errno); + "error: %d sending the breakpoint request", error_no); else error.SetErrorString("error sending the breakpoint request"); return error; @@ -3356,30 +3343,10 @@ Status ProcessGDBRemote::DoSignal(int signo) { return error; } -Status ProcessGDBRemote::ConnectToReplayServer(repro::Loader *loader) { - if (!loader) - return Status("No loader provided."); - - static std::unique_ptr> - multi_loader = repro::MultiLoader::Create( - repro::Reproducer::Instance().GetLoader()); - - if (!multi_loader) - return Status("No gdb remote provider found."); - - llvm::Optional history_file = multi_loader->GetNextFile(); - if (!history_file) - return Status("No gdb remote packet log found."); - - // Load replay history. - if (auto error = - m_gdb_replay_server.LoadReplayHistory(FileSpec(*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"); +Status ProcessGDBRemote::ConnectToReplayServer() { + Status status = m_gdb_replay_server.Connect(m_gdb_comm); + if (status.Fail()) + return status; // Enable replay mode. m_replay_mode = true; @@ -3404,8 +3371,8 @@ 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); + if (repro::Reproducer::Instance().IsReplaying()) + return ConnectToReplayServer(); auto error = LaunchAndConnectToDebugserver(process_info); if (error.Fail()) { @@ -3452,6 +3419,23 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver( std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3, _4), false); debugserver_launch_info.SetUserID(process_info.GetUserID()); +#if defined(__APPLE__) + // On macOS 11, we need to support x86_64 applications translated to + // arm64. We check whether a binary is translated and spawn the correct + // debugserver accordingly. + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, + static_cast(process_info.GetProcessID()) }; + struct kinfo_proc processInfo; + size_t bufsize = sizeof(processInfo); + if (sysctl(mib, (unsigned)(sizeof(mib)/sizeof(int)), &processInfo, + &bufsize, NULL, 0) == 0 && bufsize > 0) { + if (processInfo.kp_proc.p_flag & P_TRANSLATED) { + FileSpec rosetta_debugserver("/Library/Apple/usr/libexec/oah/debugserver"); + debugserver_launch_info.SetExecutableFile(rosetta_debugserver, false); + } + } +#endif + int communication_fd = -1; #ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION // Use a socketpair on non-Windows systems for security and performance @@ -3486,7 +3470,8 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver( // Our process spawned correctly, we can now set our connection to use // our end of the socket pair cleanup_our.release(); - m_gdb_comm.SetConnection(new ConnectionFileDescriptor(our_socket, true)); + m_gdb_comm.SetConnection( + std::make_unique(our_socket, true)); #endif StartAsyncThread(); } @@ -3648,7 +3633,7 @@ void ProcessGDBRemote::StopAsyncThread() { bool ProcessGDBRemote::HandleNotifyPacket(StringExtractorGDBRemote &packet) { // get the packet at a string - const std::string &pkt = packet.GetStringRef(); + const std::string &pkt = std::string(packet.GetStringRef()); // skip %stop: StringExtractorGDBRemote stop_info(pkt.c_str() + 5); @@ -3794,7 +3779,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) { } // switch(stop_state) } // else // if in All-stop-mode } // if (continue_packet) - } // case eBroadcastBitAysncContinue + } // case eBroadcastBitAsyncContinue break; case eBroadcastBitAsyncThreadShouldExit: @@ -4030,7 +4015,8 @@ ProcessGDBRemote::GetExtendedInfoForThread(lldb::tid_t tid) { response.GetResponseType(); if (response_type == StringExtractorGDBRemote::eResponse) { if (!response.Empty()) { - object_sp = StructuredData::ParseJSON(response.GetStringRef()); + object_sp = + StructuredData::ParseJSON(std::string(response.GetStringRef())); } } } @@ -4102,7 +4088,8 @@ ProcessGDBRemote::GetLoadedDynamicLibrariesInfos_sender( response.GetResponseType(); if (response_type == StringExtractorGDBRemote::eResponse) { if (!response.Empty()) { - object_sp = StructuredData::ParseJSON(response.GetStringRef()); + object_sp = + StructuredData::ParseJSON(std::string(response.GetStringRef())); } } } @@ -4135,7 +4122,8 @@ StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() { response.GetResponseType(); if (response_type == StringExtractorGDBRemote::eResponse) { if (!response.Empty()) { - object_sp = StructuredData::ParseJSON(response.GetStringRef()); + object_sp = + StructuredData::ParseJSON(std::string(response.GetStringRef())); } } } @@ -4419,7 +4407,7 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, }); if (!gdb_type.empty() && !(encoding_set || format_set)) { - if (gdb_type.find("int") == 0) { + if (llvm::StringRef(gdb_type).startswith("int")) { reg_info.format = eFormatHex; reg_info.encoding = eEncodingUint; } else if (gdb_type == "data_ptr" || gdb_type == "code_ptr") { @@ -4682,7 +4670,7 @@ llvm::Expected ProcessGDBRemote::GetLoadedModuleList() { // value. module.set_base_is_offset(true); } else if (name == "l_ld") { - // the memory address of the libraries PT_DYAMIC section. + // the memory address of the libraries PT_DYNAMIC section. module.set_dynamic(StringConvert::ToUInt64( value.data(), LLDB_INVALID_ADDRESS, 0)); } @@ -5069,7 +5057,8 @@ ParseStructuredDataPacket(llvm::StringRef packet) { } // This is an asynchronous JSON packet, destined for a StructuredDataPlugin. - StructuredData::ObjectSP json_sp = StructuredData::ParseJSON(packet); + StructuredData::ObjectSP json_sp = + StructuredData::ParseJSON(std::string(packet)); if (log) { if (json_sp) { StreamString json_str; @@ -5276,7 +5265,7 @@ public: result.SetStatus(eReturnStatusSuccessFinishResult); Stream &output_strm = result.GetOutputStream(); output_strm.Printf(" packet: %s\n", packet_cstr); - std::string response_str = response.GetStringRef(); + std::string response_str = std::string(response.GetStringRef()); if (strstr(packet_cstr, "qGetProfileData") != nullptr) { response_str = process->HarmonizeThreadIdsForProfileData(response); @@ -5329,7 +5318,7 @@ public: [&output_strm](llvm::StringRef output) { output_strm << output; }); result.SetStatus(eReturnStatusSuccessFinishResult); output_strm.Printf(" packet: %s\n", packet.GetData()); - const std::string &response_str = response.GetStringRef(); + const std::string &response_str = std::string(response.GetStringRef()); if (response_str.empty()) output_strm.PutCString("response: \nerror: UNIMPLEMENTED\n"); diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 9ea3940103b..ba967727ae3 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ProcessGDBRemote_h_ -#define liblldb_ProcessGDBRemote_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTE_H #include #include @@ -85,7 +85,7 @@ public: Status WillAttachToProcessWithName(const char *process_name, bool wait_for_launch) override; - Status DoConnectRemote(Stream *strm, llvm::StringRef remote_url) override; + Status DoConnectRemote(llvm::StringRef remote_url) override; Status WillLaunchOrAttach(); @@ -312,7 +312,7 @@ protected: bool UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) override; - Status ConnectToReplayServer(repro::Loader *loader); + Status ConnectToReplayServer(); Status EstablishConnectionIfNeeded(const ProcessInfo &process_info); @@ -377,6 +377,7 @@ protected: bool UpdateThreadIDList(); void DidLaunchOrAttach(ArchSpec &process_arch); + void MaybeLoadExecutableModule(); Status ConnectToDebugserver(llvm::StringRef host_port); @@ -386,7 +387,7 @@ protected: DynamicLoader *GetDynamicLoader() override; bool GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_use, - std::string xml_filename, + std::string xml_filename, uint32_t &cur_reg_num, uint32_t ®_offset); @@ -449,10 +450,11 @@ private: llvm::DenseMap m_cached_module_specs; - DISALLOW_COPY_AND_ASSIGN(ProcessGDBRemote); + ProcessGDBRemote(const ProcessGDBRemote &) = delete; + const ProcessGDBRemote &operator=(const ProcessGDBRemote &) = delete; }; } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_ProcessGDBRemote_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTE_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp index 8cadc45824b..40990ef6649 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp @@ -1,4 +1,4 @@ -//===-- ProcessGDBRemoteLog.cpp ---------------------------------*- C++ -*-===// +//===-- ProcessGDBRemoteLog.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h index d9b8d4536af..bd3e993cf72 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ProcessGDBRemoteLog_h_ -#define liblldb_ProcessGDBRemoteLog_h_ - +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTELOG_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTELOG_H #include "lldb/Utility/Log.h" @@ -43,4 +42,4 @@ public: } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_ProcessGDBRemoteLog_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTELOG_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td index 9cbe3d40ca2..d4c3c8b94b7 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td @@ -11,8 +11,8 @@ let Definition = "processgdbremote" in { Desc<"The file that provides the description for remote target registers.">; def UseSVR4: Property<"use-libraries-svr4", "Boolean">, Global, - DefaultFalse, - Desc<"If true, the libraries-svr4 feature will be used to get a hold of the process's loaded modules.">; + DefaultTrue, + Desc<"If true, the libraries-svr4 feature will be used to get a hold of the process's loaded modules. This setting is only effective if lldb was build with xml support.">; def UseGPacketForReading: Property<"use-g-packet-for-reading", "Boolean">, Global, DefaultFalse, diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index 9da481979f7..6deabf8d5d7 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -1,4 +1,4 @@ -//===-- ThreadGDBRemote.cpp -------------------------------------*- C++ -*-===// +//===-- ThreadGDBRemote.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -311,9 +311,7 @@ ThreadGDBRemote::CreateRegisterContextForFrame(StackFrame *frame) { read_all_registers_at_once, write_all_registers_at_once); } } else { - Unwind *unwinder = GetUnwinder(); - if (unwinder != nullptr) - reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame); + reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame); } return reg_ctx_sp; } diff --git a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h index c74be169aba..5ad11170fec 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h +++ b/gnu/llvm/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadGDBRemote_h_ -#define liblldb_ThreadGDBRemote_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_THREADGDBREMOTE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_THREADGDBREMOTE_H #include @@ -116,4 +116,4 @@ protected: } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_ThreadGDBRemote_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_THREADGDBREMOTE_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/gnu/llvm/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp index 888044218a4..b78276d345e 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -1,5 +1,4 @@ -//===-- ProcessMachCore.cpp ------------------------------------------*- C++ -//-*-===// +//===-- ProcessMachCore.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -45,6 +44,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(ProcessMachCore) + ConstString ProcessMachCore::GetPluginNameStatic() { static ConstString g_name("mach-o-core"); return g_name; @@ -476,7 +477,7 @@ Status ProcessMachCore::DoLoadCore() { // segments are usually meaningless, they may be just "read", because we're // dealing with kernel coredumps or early startup coredumps and the dumper // is grabbing pages of memory without knowing what they are. If they - // aren't marked as "exeuctable", that can break the unwinder which will + // aren't marked as "executable", that can break the unwinder which will // check a pc value to see if it is in an executable segment and stop the // backtrace early if it is not ("executable" and "unknown" would both be // fine, but "not executable" will break the unwinder). diff --git a/gnu/llvm/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h b/gnu/llvm/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h index e6b1256b11a..30946410270 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h +++ b/gnu/llvm/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ProcessMachCore_h_ -#define liblldb_ProcessMachCore_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MACH_CORE_PROCESSMACHCORE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_MACH_CORE_PROCESSMACHCORE_H #include #include @@ -121,7 +121,8 @@ private: lldb::addr_t m_mach_kernel_addr; lldb_private::ConstString m_dyld_plugin_name; - DISALLOW_COPY_AND_ASSIGN(ProcessMachCore); + ProcessMachCore(const ProcessMachCore &) = delete; + const ProcessMachCore &operator=(const ProcessMachCore &) = delete; }; -#endif // liblldb_ProcessMachCore_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_MACH_CORE_PROCESSMACHCORE_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp b/gnu/llvm/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp index b71e48449b7..1950baea412 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp @@ -1,4 +1,4 @@ -//===-- ThreadMachCore.cpp --------------------------------------*- C++ -*-===// +//===-- ThreadMachCore.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -83,9 +83,7 @@ ThreadMachCore::CreateRegisterContextForFrame(StackFrame *frame) { } reg_ctx_sp = m_thread_reg_ctx_sp; } else { - Unwind *unwinder = GetUnwinder(); - if (unwinder != nullptr) - reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame); + reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame); } return reg_ctx_sp; } diff --git a/gnu/llvm/lldb/source/Plugins/Process/mach-core/ThreadMachCore.h b/gnu/llvm/lldb/source/Plugins/Process/mach-core/ThreadMachCore.h index ac5957e9020..da08a7c2fa9 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/mach-core/ThreadMachCore.h +++ b/gnu/llvm/lldb/source/Plugins/Process/mach-core/ThreadMachCore.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadMachCore_h_ -#define liblldb_ThreadMachCore_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MACH_CORE_THREADMACHCORE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_MACH_CORE_THREADMACHCORE_H #include @@ -62,4 +62,4 @@ protected: bool CalculateStopInfo() override; }; -#endif // liblldb_ThreadMachCore_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_MACH_CORE_THREADMACHCORE_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/gnu/llvm/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp index 3c0e1cb49d1..0c7f4cbbb85 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp @@ -1,4 +1,4 @@ -//===-- MinidumpParser.cpp ---------------------------------------*- C++ -*-===// +//===-- MinidumpParser.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/minidump/MinidumpParser.h b/gnu/llvm/lldb/source/Plugins/Process/minidump/MinidumpParser.h index 4bcb2b47d45..c4d7612b5f8 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/minidump/MinidumpParser.h +++ b/gnu/llvm/lldb/source/Plugins/Process/minidump/MinidumpParser.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_MinidumpParser_h_ -#define liblldb_MinidumpParser_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPPARSER_H +#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPPARSER_H #include "MinidumpTypes.h" @@ -100,7 +100,6 @@ private: MinidumpParser(lldb::DataBufferSP data_sp, std::unique_ptr file); -private: lldb::DataBufferSP m_data_sp; std::unique_ptr m_file; ArchSpec m_arch; @@ -108,4 +107,4 @@ private: } // end namespace minidump } // end namespace lldb_private -#endif // liblldb_MinidumpParser_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPPARSER_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp b/gnu/llvm/lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp index ed00b1cc07d..abddd79ad7d 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp @@ -1,4 +1,4 @@ -//===-- MinidumpTypes.cpp ---------------------------------------*- C++ -*-===// +//===-- MinidumpTypes.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/minidump/MinidumpTypes.h b/gnu/llvm/lldb/source/Plugins/Process/minidump/MinidumpTypes.h index a9c807930eb..a7ac65120e2 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/minidump/MinidumpTypes.h +++ b/gnu/llvm/lldb/source/Plugins/Process/minidump/MinidumpTypes.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_MinidumpTypes_h_ -#define liblldb_MinidumpTypes_h_ - +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPTYPES_H +#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPTYPES_H #include "lldb/Utility/Status.h" @@ -120,4 +119,4 @@ private: } // namespace minidump } // namespace lldb_private -#endif // liblldb_MinidumpTypes_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPTYPES_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/minidump/NtStructures.h b/gnu/llvm/lldb/source/Plugins/Process/minidump/NtStructures.h index fdb0cfb7981..1dafbe4a4f5 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/minidump/NtStructures.h +++ b/gnu/llvm/lldb/source/Plugins/Process/minidump/NtStructures.h @@ -1,3 +1,7 @@ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_NTSTRUCTURES_H + +#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_NTSTRUCTURES_H + //===-- NtStructures.h ------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -34,3 +38,5 @@ struct TEB64 { #endif // liblldb_Plugins_Process_Minidump_NtStructures_h_ } // namespace minidump } // namespace lldb_private + +#endif diff --git a/gnu/llvm/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/gnu/llvm/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp index 5c090dc6e12..1041f63aa2e 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -1,4 +1,4 @@ -//===-- ProcessMinidump.cpp -------------------------------------*- C++ -*-===// +//===-- ProcessMinidump.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -41,6 +41,8 @@ using namespace lldb; using namespace lldb_private; using namespace minidump; +LLDB_PLUGIN_DEFINE(ProcessMinidump) + namespace { /// A minimal ObjectFile implementation providing a dummy object file for the @@ -119,6 +121,72 @@ private: lldb::addr_t m_base; lldb::addr_t m_size; }; + +/// Duplicate the HashElfTextSection() from the breakpad sources. +/// +/// Breakpad, a Google crash log reporting tool suite, creates minidump files +/// for many different architectures. When using Breakpad to create ELF +/// minidumps, it will check for a GNU build ID when creating a minidump file +/// and if one doesn't exist in the file, it will say the UUID of the file is a +/// checksum of up to the first 4096 bytes of the .text section. Facebook also +/// uses breakpad and modified this hash to avoid collisions so we can +/// calculate and check for this as well. +/// +/// The breakpad code might end up hashing up to 15 bytes that immediately +/// follow the .text section in the file, so this code must do exactly what it +/// does so we can get an exact match for the UUID. +/// +/// \param[in] module_sp The module to grab the .text section from. +/// +/// \param[in/out] breakpad_uuid A vector that will receive the calculated +/// breakpad .text hash. +/// +/// \param[in/out] facebook_uuid A vector that will receive the calculated +/// facebook .text hash. +/// +void HashElfTextSection(ModuleSP module_sp, std::vector &breakpad_uuid, + std::vector &facebook_uuid) { + SectionList *sect_list = module_sp->GetSectionList(); + if (sect_list == nullptr) + return; + SectionSP sect_sp = sect_list->FindSectionByName(ConstString(".text")); + if (!sect_sp) + return; + constexpr size_t kMDGUIDSize = 16; + constexpr size_t kBreakpadPageSize = 4096; + // The breakpad code has a bug where it might access beyond the end of a + // .text section by up to 15 bytes, so we must ensure we round up to the + // next kMDGUIDSize byte boundary. + DataExtractor data; + const size_t text_size = sect_sp->GetFileSize(); + const size_t read_size = std::min( + llvm::alignTo(text_size, kMDGUIDSize), kBreakpadPageSize); + sect_sp->GetObjectFile()->GetData(sect_sp->GetFileOffset(), read_size, data); + + breakpad_uuid.assign(kMDGUIDSize, 0); + facebook_uuid.assign(kMDGUIDSize, 0); + + // The only difference between the breakpad hash and the facebook hash is the + // hashing of the text section size into the hash prior to hashing the .text + // contents. + for (size_t i = 0; i < kMDGUIDSize; i++) + facebook_uuid[i] ^= text_size % 255; + + // This code carefully duplicates how the hash was created in Breakpad + // sources, including the error where it might has an extra 15 bytes past the + // end of the .text section if the .text section is less than a page size in + // length. + const uint8_t *ptr = data.GetDataStart(); + const uint8_t *ptr_end = data.GetDataEnd(); + while (ptr < ptr_end) { + for (unsigned i = 0; i < kMDGUIDSize; i++) { + breakpad_uuid[i] ^= ptr[i]; + facebook_uuid[i] ^= ptr[i]; + } + ptr += kMDGUIDSize; + } +} + } // namespace ConstString ProcessMinidump::GetPluginNameStatic() { @@ -226,8 +294,10 @@ Status ProcessMinidump::DoLoadCore() { llvm::Optional pid = m_minidump_parser->GetPid(); if (!pid) { - error.SetErrorString("failed to parse PID"); - return error; + GetTarget().GetDebugger().GetAsyncErrorStream()->PutCString( + "Unable to retrieve process ID from minidump file, setting process ID " + "to 1.\n"); + pid = 1; } SetID(pid.getValue()); @@ -253,7 +323,7 @@ void ProcessMinidump::RefreshStateAfterStop() { // TODO: The definition and use of this "dump requested" constant // in Breakpad are actually Linux-specific, and for similar use - // cases on Mac/Windows it defines differnt constants, referring + // cases on Mac/Windows it defines different constants, referring // to them as "simulated" exceptions; consider moving this check // down to the OS-specific paths and checking each OS for its own // constant. @@ -440,6 +510,53 @@ bool ProcessMinidump::UpdateThreadList(ThreadList &old_thread_list, return new_thread_list.GetSize(false) > 0; } +ModuleSP ProcessMinidump::GetOrCreateModule(UUID minidump_uuid, + llvm::StringRef name, + ModuleSpec module_spec) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + Status error; + + ModuleSP module_sp = + GetTarget().GetOrCreateModule(module_spec, true /* notify */, &error); + if (!module_sp) + return module_sp; + // We consider the module to be a match if the minidump UUID is a + // prefix of the actual UUID, or if either of the UUIDs are empty. + const auto dmp_bytes = minidump_uuid.GetBytes(); + const auto mod_bytes = module_sp->GetUUID().GetBytes(); + const bool match = dmp_bytes.empty() || mod_bytes.empty() || + mod_bytes.take_front(dmp_bytes.size()) == dmp_bytes; + if (match) { + LLDB_LOG(log, "Partial uuid match for {0}.", name); + return module_sp; + } + + // Breakpad generates minindump files, and if there is no GNU build + // ID in the binary, it will calculate a UUID by hashing first 4096 + // bytes of the .text section and using that as the UUID for a module + // in the minidump. Facebook uses a modified breakpad client that + // uses a slightly modified this hash to avoid collisions. Check for + // UUIDs from the minindump that match these cases and accept the + // module we find if they do match. + std::vector breakpad_uuid; + std::vector facebook_uuid; + HashElfTextSection(module_sp, breakpad_uuid, facebook_uuid); + if (dmp_bytes == llvm::ArrayRef(breakpad_uuid)) { + LLDB_LOG(log, "Breakpad .text hash match for {0}.", name); + return module_sp; + } + if (dmp_bytes == llvm::ArrayRef(facebook_uuid)) { + LLDB_LOG(log, "Facebook .text hash match for {0}.", name); + return module_sp; + } + // The UUID wasn't a partial match and didn't match the .text hash + // so remove the module from the target, we will need to create a + // placeholder object file. + GetTarget().GetImages().Remove(module_sp); + module_sp.reset(); + return module_sp; +} + void ProcessMinidump::ReadModuleList() { std::vector filtered_modules = m_minidump_parser->GetFilteredModuleList(); @@ -469,30 +586,21 @@ void ProcessMinidump::ReadModuleList() { // add the module to the target if it finds one. lldb::ModuleSP module_sp = GetTarget().GetOrCreateModule(module_spec, true /* notify */, &error); - if (!module_sp) { - // Try and find a module without specifying the UUID and only looking for - // the file given a basename. We then will look for a partial UUID match - // if we find any matches. This function will add the module to the - // target if it finds one, so we need to remove the module from the target - // if the UUID doesn't match during our manual UUID verification. This - // allows the "target.exec-search-paths" setting to specify one or more - // directories that contain executables that can be searched for matches. - ModuleSpec basename_module_spec(module_spec); - basename_module_spec.GetUUID().Clear(); - basename_module_spec.GetFileSpec().GetDirectory().Clear(); - module_sp = GetTarget().GetOrCreateModule(basename_module_spec, - true /* notify */, &error); - if (module_sp) { - // We consider the module to be a match if the minidump UUID is a - // prefix of the actual UUID, or if either of the UUIDs are empty. - const auto dmp_bytes = uuid.GetBytes(); - const auto mod_bytes = module_sp->GetUUID().GetBytes(); - const bool match = dmp_bytes.empty() || mod_bytes.empty() || - mod_bytes.take_front(dmp_bytes.size()) == dmp_bytes; - if (!match) { - GetTarget().GetImages().Remove(module_sp); - module_sp.reset(); - } + if (module_sp) { + LLDB_LOG(log, "Full uuid match for {0}.", name); + } else { + // We couldn't find a module with an exactly-matching UUID. Sometimes + // a minidump UUID is only a partial match or is a hash. So try again + // without specifying the UUID, then again without specifying the + // directory if that fails. This will allow us to find modules with + // partial matches or hash UUIDs in user-provided sysroots or search + // directories (target.exec-search-paths). + ModuleSpec partial_module_spec = module_spec; + partial_module_spec.GetUUID().Clear(); + module_sp = GetOrCreateModule(uuid, name, partial_module_spec); + if (!module_sp) { + partial_module_spec.GetFileSpec().GetDirectory().Clear(); + module_sp = GetOrCreateModule(uuid, name, partial_module_spec); } } if (module_sp) { diff --git a/gnu/llvm/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/gnu/llvm/lldb/source/Plugins/Process/minidump/ProcessMinidump.h index 750164cf8aa..bfdace7ea33 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/minidump/ProcessMinidump.h +++ b/gnu/llvm/lldb/source/Plugins/Process/minidump/ProcessMinidump.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ProcessMinidump_h_ -#define liblldb_ProcessMinidump_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_PROCESSMINIDUMP_H +#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_PROCESSMINIDUMP_H #include "MinidumpParser.h" #include "MinidumpTypes.h" @@ -102,6 +102,10 @@ protected: void ReadModuleList(); + lldb::ModuleSP GetOrCreateModule(lldb_private::UUID minidump_uuid, + llvm::StringRef name, + lldb_private::ModuleSpec module_spec); + JITLoaderList &GetJITLoaders() override; private: @@ -119,4 +123,4 @@ private: } // namespace minidump } // namespace lldb_private -#endif // liblldb_ProcessMinidump_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_PROCESSMINIDUMP_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp index 72dead07dcb..eb48785263f 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextMinidump_ARM.cpp -------------------------*- C++ -*-===// +//===-- RegisterContextMinidump_ARM.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h b/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h index 7af3b98a6fe..857f9c0a376 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h +++ b/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextMinidump_ARM_h_ -#define liblldb_RegisterContextMinidump_ARM_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_ARM_H +#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_ARM_H #include "MinidumpTypes.h" @@ -95,4 +95,4 @@ protected: } // end namespace minidump } // end namespace lldb_private -#endif // liblldb_RegisterContextMinidump_ARM_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_ARM_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp b/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp index bbd0e14a326..c7809c5f19b 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextMinidump_ARM64.cpp -----------------------*- C++ -*-===// +//===-- RegisterContextMinidump_ARM64.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h b/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h index f9e7f39eea6..8ae751095c0 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextMinidump_ARM64_h_ -#define liblldb_RegisterContextMinidump_ARM64_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_ARM64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_ARM64_H #include "MinidumpTypes.h" @@ -79,4 +79,4 @@ protected: } // end namespace minidump } // end namespace lldb_private -#endif // liblldb_RegisterContextMinidump_ARM64_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_ARM64_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp b/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp index 8ac2abb2209..38d7de77e3b 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextMinidump_x86_32.cpp ----------------------*- C++ -*-===// +//===-- RegisterContextMinidump_x86_32.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h b/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h index d787f78ec7d..9592d335eff 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h +++ b/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextMinidump_x86_32_h_ -#define liblldb_RegisterContextMinidump_x86_32_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_X86_32_H +#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_X86_32_H #include "MinidumpTypes.h" @@ -132,4 +132,4 @@ enum class MinidumpContext_x86_32_Flags : uint32_t { } // end namespace minidump } // end namespace lldb_private -#endif // liblldb_RegisterContextMinidump_x86_32_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_X86_32_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp b/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp index 515ccf6b2c3..3c593f0db6e 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextMinidump_x86_64.cpp ----------------------*- C++ -*-===// +//===-- RegisterContextMinidump_x86_64.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h b/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h index 34ddd477a9d..d920ea9d823 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h +++ b/gnu/llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RegisterContextMinidump_h_ -#define liblldb_RegisterContextMinidump_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_X86_64_H #include "MinidumpTypes.h" @@ -177,4 +177,4 @@ enum class MinidumpContext_x86_64_Flags : uint32_t { } // end namespace minidump } // end namespace lldb_private -#endif // liblldb_RegisterContextMinidump_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_X86_64_H diff --git a/gnu/llvm/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp b/gnu/llvm/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp index 5262de5a94c..e146a1a1af9 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp +++ b/gnu/llvm/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp @@ -1,4 +1,4 @@ -//===-- ThreadMinidump.cpp --------------------------------------*- C++ -*-===// +//===-- ThreadMinidump.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/Process/minidump/ThreadMinidump.h b/gnu/llvm/lldb/source/Plugins/Process/minidump/ThreadMinidump.h index 44c41bc9f50..aed7cfbc1b1 100644 --- a/gnu/llvm/lldb/source/Plugins/Process/minidump/ThreadMinidump.h +++ b/gnu/llvm/lldb/source/Plugins/Process/minidump/ThreadMinidump.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadMinidump_h_ -#define liblldb_ThreadMinidump_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_THREADMINIDUMP_H +#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_THREADMINIDUMP_H #include "MinidumpTypes.h" @@ -42,4 +42,4 @@ protected: } // namespace minidump } // namespace lldb_private -#endif // liblldb_ThreadMinidump_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_THREADMINIDUMP_H diff --git a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp index ecee8cc674f..acd6128d84c 100644 --- a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp +++ b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp @@ -57,3 +57,35 @@ llvm::Error Lua::LoadModule(llvm::StringRef filename) { lua_setglobal(m_lua_state, module_name.GetCString()); return llvm::Error::success(); } + +llvm::Error Lua::ChangeIO(FILE *out, FILE *err) { + assert(out != nullptr); + assert(err != nullptr); + + lua_getglobal(m_lua_state, "io"); + + lua_getfield(m_lua_state, -1, "stdout"); + if (luaL_Stream *s = static_cast( + luaL_testudata(m_lua_state, -1, LUA_FILEHANDLE))) { + s->f = out; + lua_pop(m_lua_state, 1); + } else { + lua_pop(m_lua_state, 2); + return llvm::make_error("could not get stdout", + llvm::inconvertibleErrorCode()); + } + + lua_getfield(m_lua_state, -1, "stderr"); + if (luaL_Stream *s = static_cast( + luaL_testudata(m_lua_state, -1, LUA_FILEHANDLE))) { + s->f = out; + lua_pop(m_lua_state, 1); + } else { + lua_pop(m_lua_state, 2); + return llvm::make_error("could not get stderr", + llvm::inconvertibleErrorCode()); + } + + lua_pop(m_lua_state, 1); + return llvm::Error::success(); +} diff --git a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h index f2984a925df..300115aac8a 100644 --- a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h +++ b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h @@ -38,6 +38,7 @@ public: llvm::Error Run(llvm::StringRef buffer); llvm::Error LoadModule(llvm::StringRef filename); + llvm::Error ChangeIO(FILE *out, FILE *err); private: lua_State *m_lua_state; diff --git a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp index 701d68d1ec0..8cbeac4563c 100644 --- a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp +++ b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp @@ -1,4 +1,4 @@ -//===-- ScriptInterpreterLua.cpp --------------------------------*- C++ -*-===// +//===-- ScriptInterpreterLua.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -15,10 +15,13 @@ #include "lldb/Utility/Stream.h" #include "lldb/Utility/StringList.h" #include "lldb/Utility/Timer.h" +#include "llvm/Support/FormatAdapters.h" using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(ScriptInterpreterLua) + class IOHandlerLuaInterpreter : public IOHandlerDelegate, public IOHandlerEditline { public: @@ -28,15 +31,23 @@ public: ">>> ", "..> ", true, debugger.GetUseColor(), 0, *this, nullptr), m_script_interpreter(script_interpreter) { + llvm::cantFail(m_script_interpreter.GetLua().ChangeIO( + debugger.GetOutputFile().GetStream(), + debugger.GetErrorFile().GetStream())); llvm::cantFail(m_script_interpreter.EnterSession(debugger.GetID())); } - ~IOHandlerLuaInterpreter() { + ~IOHandlerLuaInterpreter() override { llvm::cantFail(m_script_interpreter.LeaveSession()); } void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override { + if (llvm::StringRef(data).rtrim() == "quit") { + io_handler.SetIsDone(true); + return; + } + if (llvm::Error error = m_script_interpreter.GetLua().Run(data)) { *GetOutputStreamFileSP() << llvm::toString(std::move(error)); } @@ -55,12 +66,43 @@ ScriptInterpreterLua::~ScriptInterpreterLua() {} bool ScriptInterpreterLua::ExecuteOneLine(llvm::StringRef command, CommandReturnObject *result, const ExecuteScriptOptions &options) { + if (command.empty()) { + if (result) + result->AppendError("empty command passed to lua\n"); + return false; + } + + llvm::Expected> + io_redirect_or_error = ScriptInterpreterIORedirect::Create( + options.GetEnableIO(), m_debugger, result); + if (!io_redirect_or_error) { + if (result) + result->AppendErrorWithFormatv( + "failed to redirect I/O: {0}\n", + llvm::fmt_consume(io_redirect_or_error.takeError())); + else + llvm::consumeError(io_redirect_or_error.takeError()); + return false; + } + + ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error; + + if (llvm::Error e = + m_lua->ChangeIO(io_redirect.GetOutputFile()->GetStream(), + io_redirect.GetErrorFile()->GetStream())) { + result->AppendErrorWithFormatv("lua failed to redirect I/O: {0}\n", + llvm::toString(std::move(e))); + return false; + } + if (llvm::Error e = m_lua->Run(command)) { result->AppendErrorWithFormatv( "lua failed attempting to evaluate '{0}': {1}\n", command, llvm::toString(std::move(e))); return false; } + + io_redirect.Flush(); return true; } @@ -68,25 +110,23 @@ void ScriptInterpreterLua::ExecuteInterpreterLoop() { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION); - Debugger &debugger = m_debugger; - // At the moment, the only time the debugger does not have an input file // handle is when this is called directly from lua, in which case it is // both dangerous and unnecessary (not to mention confusing) to try to embed // a running interpreter loop inside the already running lua interpreter // loop, so we won't do it. - - if (!debugger.GetInputFile().IsValid()) + if (!m_debugger.GetInputFile().IsValid()) return; - IOHandlerSP io_handler_sp(new IOHandlerLuaInterpreter(debugger, *this)); - debugger.PushIOHandler(io_handler_sp); + IOHandlerSP io_handler_sp(new IOHandlerLuaInterpreter(m_debugger, *this)); + m_debugger.RunIOHandlerAsync(io_handler_sp); } bool ScriptInterpreterLua::LoadScriptingModule( const char *filename, bool init_session, lldb_private::Status &error, StructuredData::ObjectSP *module_sp) { + FileSystem::Instance().Collect(filename); if (llvm::Error e = m_lua->LoadModule(filename)) { error.SetErrorStringWithFormatv("lua failed to import '{0}': {1}\n", filename, llvm::toString(std::move(e))); diff --git a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h index 4e922151385..bcc6ab24f6d 100644 --- a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h +++ b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h @@ -25,7 +25,7 @@ public: void ExecuteInterpreterLoop() override; - virtual bool + bool LoadScriptingModule(const char *filename, bool init_session, lldb_private::Status &error, StructuredData::ObjectSP *module_sp = nullptr) override; diff --git a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp index 3517f831970..d9c32cc132d 100644 --- a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp +++ b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp @@ -1,4 +1,4 @@ -//===-- ScriptInterpreterNone.cpp -------------------------------*- C++ -*-===// +//===-- ScriptInterpreterNone.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -20,6 +20,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(ScriptInterpreterNone) + ScriptInterpreterNone::ScriptInterpreterNone(Debugger &debugger) : ScriptInterpreter(debugger, eScriptLanguageNone) {} diff --git a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h index 242065cc23e..c438b6315c5 100644 --- a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h +++ b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ScriptInterpreterNone_h_ -#define liblldb_ScriptInterpreterNone_h_ +#ifndef LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_NONE_SCRIPTINTERPRETERNONE_H +#define LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_NONE_SCRIPTINTERPRETERNONE_H #include "lldb/Interpreter/ScriptInterpreter.h" @@ -44,4 +44,4 @@ public: } // namespace lldb_private -#endif // liblldb_ScriptInterpreterNone_h_ +#endif // LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_NONE_SCRIPTINTERPRETERNONE_H diff --git a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp index e5a67653e33..6f040fdef09 100644 --- a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp +++ b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp @@ -1,4 +1,4 @@ -//===-- PythonDataObjects.cpp -----------------------------------*- C++ -*-===// +//===-- PythonDataObjects.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -44,7 +44,15 @@ template <> Expected python::As(Expected &&obj) { if (!obj) return obj.takeError(); - return obj.get().AsLongLong(); + return obj->AsLongLong(); +} + +template <> +Expected +python::As(Expected &&obj) { + if (!obj) + return obj.takeError(); + return obj->AsUnsignedLongLong(); } template <> @@ -58,7 +66,56 @@ Expected python::As(Expected &&obj) { auto utf8 = str.AsUTF8(); if (!utf8) return utf8.takeError(); - return utf8.get(); + return std::string(utf8.get()); +} + +Expected PythonObject::AsLongLong() const { + if (!m_py_obj) + return nullDeref(); +#if PY_MAJOR_VERSION < 3 + if (!PyLong_Check(m_py_obj)) { + PythonInteger i(PyRefType::Borrowed, m_py_obj); + return i.AsLongLong(); + } +#endif + assert(!PyErr_Occurred()); + long long r = PyLong_AsLongLong(m_py_obj); + if (PyErr_Occurred()) + return exception(); + return r; +} + +Expected PythonObject::AsUnsignedLongLong() const { + if (!m_py_obj) + return nullDeref(); +#if PY_MAJOR_VERSION < 3 + if (!PyLong_Check(m_py_obj)) { + PythonInteger i(PyRefType::Borrowed, m_py_obj); + return i.AsUnsignedLongLong(); + } +#endif + assert(!PyErr_Occurred()); + long long r = PyLong_AsUnsignedLongLong(m_py_obj); + if (PyErr_Occurred()) + return exception(); + return r; +} + +// wraps on overflow, instead of raising an error. +Expected PythonObject::AsModuloUnsignedLongLong() const { + if (!m_py_obj) + return nullDeref(); +#if PY_MAJOR_VERSION < 3 + if (!PyLong_Check(m_py_obj)) { + PythonInteger i(PyRefType::Borrowed, m_py_obj); + return i.AsModuloUnsignedLongLong(); + } +#endif + assert(!PyErr_Occurred()); + unsigned long long r = PyLong_AsUnsignedLongLongMask(m_py_obj); + if (PyErr_Occurred()) + return exception(); + return r; } void StructuredPythonObject::Serialize(llvm::json::OStream &s) const { @@ -463,32 +520,22 @@ void PythonInteger::Convert(PyRefType &type, PyObject *&py_obj) { #endif } -int64_t PythonInteger::GetInteger() const { - if (m_py_obj) { - assert(PyLong_Check(m_py_obj) && - "PythonInteger::GetInteger has a PyObject that isn't a PyLong"); - - int overflow = 0; - int64_t result = PyLong_AsLongLongAndOverflow(m_py_obj, &overflow); - if (overflow != 0) { - // We got an integer that overflows, like 18446744072853913392L we can't - // use PyLong_AsLongLong() as it will return 0xffffffffffffffff. If we - // use the unsigned long long it will work as expected. - const uint64_t uval = PyLong_AsUnsignedLongLong(m_py_obj); - result = static_cast(uval); - } - return result; - } - return UINT64_MAX; -} - void PythonInteger::SetInteger(int64_t value) { *this = Take(PyLong_FromLongLong(value)); } StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const { StructuredData::IntegerSP result(new StructuredData::Integer); - result->SetValue(GetInteger()); + // FIXME this is really not ideal. Errors are silently converted to 0 + // and overflows are silently wrapped. But we'd need larger changes + // to StructuredData to fix it, so that's how it is for now. + llvm::Expected value = AsModuloUnsignedLongLong(); + if (!value) { + llvm::consumeError(value.takeError()); + result->SetValue(0); + } else { + result->SetValue(value.get()); + } return result; } @@ -1044,7 +1091,7 @@ std::string PythonException::ReadBacktrace() const { if (!backtrace) { std::string message = std::string(toCString()) + "\n" + - "Traceback unavailble, an error occurred while reading it:\n"; + "Traceback unavailable, an error occurred while reading it:\n"; return (message + llvm::toString(backtrace.takeError())); } diff --git a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h index b75045b239a..22f6c67eb7a 100644 --- a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h +++ b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h @@ -36,7 +36,7 @@ // can never fail to assert instead, such as the creation of // PythonString from a string literal. // -// * Elimintate Reset(), and make all non-default constructors private. +// * Eliminate Reset(), and make all non-default constructors private. // Python objects should be created with Retain<> or Take<>, and they // should be assigned with operator= // @@ -90,7 +90,9 @@ public: void Serialize(llvm::json::OStream &s) const override; private: - DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject); + StructuredPythonObject(const StructuredPythonObject &) = delete; + const StructuredPythonObject & + operator=(const StructuredPythonObject &) = delete; }; enum class PyObjectType { @@ -319,7 +321,6 @@ public: StructuredData::ObjectSP CreateStructuredObject() const; -public: template llvm::Expected CallMethod(const char *name, const T &... t) const { @@ -360,15 +361,12 @@ public: return !!r; } - llvm::Expected AsLongLong() { - if (!m_py_obj) - return nullDeref(); - assert(!PyErr_Occurred()); - long long r = PyLong_AsLongLong(m_py_obj); - if (PyErr_Occurred()) - return exception(); - return r; - } + llvm::Expected AsLongLong() const; + + llvm::Expected AsUnsignedLongLong() const; + + // wraps on overflow, instead of raising an error. + llvm::Expected AsModuloUnsignedLongLong() const; llvm::Expected IsInstance(const PythonObject &cls) { if (!m_py_obj || !cls.IsValid()) @@ -399,6 +397,10 @@ template <> llvm::Expected As(llvm::Expected &&obj); template <> llvm::Expected As(llvm::Expected &&obj); +template <> +llvm::Expected +As(llvm::Expected &&obj); + template <> llvm::Expected As(llvm::Expected &&obj); @@ -491,8 +493,6 @@ public: static bool Check(PyObject *py_obj); static void Convert(PyRefType &type, PyObject *&py_obj); - int64_t GetInteger() const; - void SetInteger(int64_t value); StructuredData::IntegerSP CreateStructuredInteger() const; @@ -595,7 +595,7 @@ public: // safe, returns invalid on error; static PythonModule ImportModule(llvm::StringRef name) { - std::string s = name; + std::string s = std::string(name); auto mod = Import(s.c_str()); if (!mod) { llvm::consumeError(mod.takeError()); diff --git a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index 06e0d5bfa63..9f56b4fa60a 100644 --- a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -1,4 +1,4 @@ -//===-- ScriptInterpreterPython.cpp -----------------------------*- C++ -*-===// +//===-- ScriptInterpreterPython.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -16,7 +16,6 @@ #include "PythonDataObjects.h" #include "PythonReadline.h" #include "ScriptInterpreterPythonImpl.h" - #include "lldb/API/SBFrame.h" #include "lldb/API/SBValue.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" @@ -26,7 +25,6 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" -#include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/Pipe.h" @@ -35,13 +33,9 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" #include "lldb/Utility/Timer.h" - -#if defined(_WIN32) -#include "lldb/Host/windows/ConnectionGenericFileWindows.h" -#endif - #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FormatAdapters.h" @@ -56,6 +50,8 @@ using namespace lldb_private; using namespace lldb_private::python; using llvm::Expected; +LLDB_PLUGIN_DEFINE(ScriptInterpreterPython) + // Defined in the SWIG source file #if PY_MAJOR_VERSION >= 3 extern "C" PyObject *PyInit__lldb(void); @@ -222,10 +218,6 @@ struct InitializePythonRAII { public: InitializePythonRAII() : m_gil_state(PyGILState_UNLOCKED), m_was_already_initialized(false) { - // Python will muck with STDIN terminal state, so save off any current TTY - // settings so we can restore them. - m_stdin_tty_state.Save(STDIN_FILENO, false); - InitializePythonHome(); #ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE @@ -269,20 +261,40 @@ public: // We initialized the threads in this function, just unlock the GIL. PyEval_SaveThread(); } - - m_stdin_tty_state.Restore(); } private: void InitializePythonHome() { -#if defined(LLDB_PYTHON_HOME) +#if LLDB_EMBED_PYTHON_HOME #if PY_MAJOR_VERSION >= 3 - size_t size = 0; - static wchar_t *g_python_home = Py_DecodeLocale(LLDB_PYTHON_HOME, &size); + typedef wchar_t* str_type; #else - static char g_python_home[] = LLDB_PYTHON_HOME; + typedef char* str_type; #endif - Py_SetPythonHome(g_python_home); + static str_type g_python_home = []() -> str_type { + const char *lldb_python_home = LLDB_PYTHON_HOME; + const char *absolute_python_home = nullptr; + llvm::SmallString<64> path; + if (llvm::sys::path::is_absolute(lldb_python_home)) { + absolute_python_home = lldb_python_home; + } else { + FileSpec spec = HostInfo::GetShlibDir(); + if (!spec) + return nullptr; + spec.GetPath(path); + llvm::sys::path::append(path, lldb_python_home); + absolute_python_home = path.c_str(); + } +#if PY_MAJOR_VERSION >= 3 + size_t size = 0; + return Py_DecodeLocale(absolute_python_home, &size); +#else + return strdup(absolute_python_home); +#endif + }(); + if (g_python_home != nullptr) { + Py_SetPythonHome(g_python_home); + } #else #if defined(__APPLE__) && PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION == 7 // For Darwin, the only Python version supported is the one shipped in the @@ -471,7 +483,7 @@ ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger) m_run_one_line_str_global(), m_dictionary_name(m_debugger.GetInstanceName().AsCString()), m_active_io_handler(eIOHandlerNone), m_session_is_active(false), - m_pty_slave_is_open(false), m_valid_session(true), m_lock_count(0), + m_pty_secondary_is_open(false), m_valid_session(true), m_lock_count(0), m_command_thread_state(nullptr) { InitializePrivate(); @@ -853,7 +865,7 @@ static std::string GenerateUniqueName(const char *base_name_wanted, else sstr.Printf("%s_%p", base_name_wanted, name_token); - return sstr.GetString(); + return std::string(sstr.GetString()); } bool ScriptInterpreterPythonImpl::GetEmbeddedInterpreterModuleObjects() { @@ -877,15 +889,6 @@ bool ScriptInterpreterPythonImpl::GetEmbeddedInterpreterModuleObjects() { return m_run_one_line_function.IsValid(); } -static void ReadThreadBytesReceived(void *baton, const void *src, - size_t src_len) { - if (src && src_len) { - Stream *strm = (Stream *)baton; - strm->Write(src, src_len); - strm->Flush(); - } -} - bool ScriptInterpreterPythonImpl::ExecuteOneLine( llvm::StringRef command, CommandReturnObject *result, const ExecuteScriptOptions &options) { @@ -901,77 +904,21 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine( // another string to pass to PyRun_SimpleString messes up the escaping. So // we use the following more complicated method to pass the command string // directly down to Python. - Debugger &debugger = m_debugger; - - FileSP input_file_sp; - StreamFileSP output_file_sp; - StreamFileSP error_file_sp; - Communication output_comm( - "lldb.ScriptInterpreterPythonImpl.ExecuteOneLine.comm"); - bool join_read_thread = false; - if (options.GetEnableIO()) { - if (result) { - input_file_sp = debugger.GetInputFileSP(); - // Set output to a temporary file so we can forward the results on to - // the result object - - Pipe pipe; - Status pipe_result = pipe.CreateNew(false); - if (pipe_result.Success()) { -#if defined(_WIN32) - lldb::file_t read_file = pipe.GetReadNativeHandle(); - pipe.ReleaseReadFileDescriptor(); - std::unique_ptr conn_up( - new ConnectionGenericFile(read_file, true)); -#else - std::unique_ptr conn_up( - new ConnectionFileDescriptor(pipe.ReleaseReadFileDescriptor(), - true)); -#endif - if (conn_up->IsConnected()) { - output_comm.SetConnection(conn_up.release()); - output_comm.SetReadThreadBytesReceivedCallback( - ReadThreadBytesReceived, &result->GetOutputStream()); - output_comm.StartReadThread(); - join_read_thread = true; - FILE *outfile_handle = - fdopen(pipe.ReleaseWriteFileDescriptor(), "w"); - output_file_sp = std::make_shared(outfile_handle, true); - error_file_sp = output_file_sp; - if (outfile_handle) - ::setbuf(outfile_handle, nullptr); - - result->SetImmediateOutputFile( - debugger.GetOutputStream().GetFileSP()); - result->SetImmediateErrorFile( - debugger.GetErrorStream().GetFileSP()); - } - } - } - if (!input_file_sp || !output_file_sp || !error_file_sp) - debugger.AdoptTopIOHandlerFilesIfInvalid(input_file_sp, output_file_sp, - error_file_sp); - } else { - auto nullin = FileSystem::Instance().Open( - FileSpec(FileSystem::DEV_NULL), - File::eOpenOptionRead); - auto nullout = FileSystem::Instance().Open( - FileSpec(FileSystem::DEV_NULL), - File::eOpenOptionWrite); - if (!nullin) { - result->AppendErrorWithFormatv("failed to open /dev/null: {0}\n", - llvm::fmt_consume(nullin.takeError())); - return false; - } - if (!nullout) { - result->AppendErrorWithFormatv("failed to open /dev/null: {0}\n", - llvm::fmt_consume(nullout.takeError())); - return false; - } - input_file_sp = std::move(nullin.get()); - error_file_sp = output_file_sp = std::make_shared(std::move(nullout.get())); + llvm::Expected> + io_redirect_or_error = ScriptInterpreterIORedirect::Create( + options.GetEnableIO(), m_debugger, result); + if (!io_redirect_or_error) { + if (result) + result->AppendErrorWithFormatv( + "failed to redirect I/O: {0}\n", + llvm::fmt_consume(io_redirect_or_error.takeError())); + else + llvm::consumeError(io_redirect_or_error.takeError()); + return false; } + ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error; + bool success = false; { // WARNING! It's imperative that this RAII scope be as tight as @@ -987,8 +934,9 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine( Locker::AcquireLock | Locker::InitSession | (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) | ((result && result->GetInteractive()) ? 0 : Locker::NoSTDIN), - Locker::FreeAcquiredLock | Locker::TearDownSession, input_file_sp, - output_file_sp->GetFileSP(), error_file_sp->GetFileSP()); + Locker::FreeAcquiredLock | Locker::TearDownSession, + io_redirect.GetInputFile(), io_redirect.GetOutputFile(), + io_redirect.GetErrorFile()); // Find the correct script interpreter dictionary in the main module. PythonDictionary &session_dict = GetSessionDictionary(); @@ -1014,21 +962,7 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine( } } - // Flush our output and error file handles - output_file_sp->Flush(); - error_file_sp->Flush(); - } - - if (join_read_thread) { - // Close the write end of the pipe since we are done with our one line - // script. This should cause the read thread that output_comm is using to - // exit - output_file_sp->GetFile().Close(); - // The close above should cause this thread to exit when it gets to the - // end of file, so let it get all its data - output_comm.JoinReadThread(); - // Now we can close the read end of the pipe - output_comm.Disconnect(); + io_redirect.Flush(); } if (success) @@ -1064,7 +998,7 @@ void ScriptInterpreterPythonImpl::ExecuteInterpreterLoop() { IOHandlerSP io_handler_sp(new IOHandlerPythonInterpreter(debugger, this)); if (io_handler_sp) { - debugger.PushIOHandler(io_handler_sp); + debugger.RunIOHandlerAsync(io_handler_sp); } } @@ -1343,8 +1277,8 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback( bp_options->SetCallback( ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp); return error; - } else - return error; + } + return error; } // Set a Python one-liner as the callback for the watchpoint. @@ -1970,8 +1904,7 @@ lldb::StateType ScriptInterpreterPythonImpl::ScriptedThreadPlanGetRunState( } if (should_step) return lldb::eStateStepping; - else - return lldb::eStateRunning; + return lldb::eStateRunning; } StructuredData::GenericSP @@ -2043,8 +1976,7 @@ ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchDepth( if (depth_as_int <= lldb::kLastSearchDepthKind) return (lldb::SearchDepth)depth_as_int; - else - return lldb::eSearchDepthModule; + return lldb::eSearchDepthModule; } StructuredData::ObjectSP @@ -2748,6 +2680,7 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule( { FileSpec target_file(pathname); FileSystem::Instance().Resolve(target_file); + FileSystem::Instance().Collect(target_file); std::string basename(target_file.GetFilename().GetCString()); StreamString command_stream; @@ -3010,39 +2943,42 @@ bool ScriptInterpreterPythonImpl::RunScriptBasedCommand( return ret_val; } -// in Python, a special attribute __doc__ contains the docstring for an object -// (function, method, class, ...) if any is defined Otherwise, the attribute's -// value is None +/// In Python, a special attribute __doc__ contains the docstring for an object +/// (function, method, class, ...) if any is defined Otherwise, the attribute's +/// value is None. bool ScriptInterpreterPythonImpl::GetDocumentationForItem(const char *item, std::string &dest) { dest.clear(); + if (!item || !*item) return false; + std::string command(item); command += ".__doc__"; - char *result_ptr = nullptr; // Python is going to point this to valid data if - // ExecuteOneLineWithReturn returns successfully + // Python is going to point this to valid data if ExecuteOneLineWithReturn + // returns successfully. + char *result_ptr = nullptr; if (ExecuteOneLineWithReturn( - command.c_str(), ScriptInterpreter::eScriptReturnTypeCharStrOrNone, + command, ScriptInterpreter::eScriptReturnTypeCharStrOrNone, &result_ptr, ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false))) { if (result_ptr) dest.assign(result_ptr); return true; - } else { - StreamString str_stream; - str_stream.Printf( - "Function %s was not found. Containing module might be missing.", item); - dest = str_stream.GetString(); - return false; } + + StreamString str_stream; + str_stream << "Function " << item + << " was not found. Containing module might be missing."; + dest = std::string(str_stream.GetString()); + + return false; } bool ScriptInterpreterPythonImpl::GetShortHelpForCommandObject( StructuredData::GenericSP cmd_obj_sp, std::string &dest) { - bool got_string = false; dest.clear(); Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); @@ -3076,12 +3012,12 @@ bool ScriptInterpreterPythonImpl::GetShortHelpForCommandObject( if (PyErr_Occurred()) PyErr_Clear(); - // right now we know this function exists and is callable.. + // Right now we know this function exists and is callable. PythonObject py_return( PyRefType::Owned, PyObject_CallMethod(implementor.get(), callee_name, nullptr)); - // if it fails, print the error but otherwise go on + // If it fails, print the error but otherwise go on. if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); @@ -3091,9 +3027,10 @@ bool ScriptInterpreterPythonImpl::GetShortHelpForCommandObject( PythonString py_string(PyRefType::Borrowed, py_return.get()); llvm::StringRef return_data(py_string.GetString()); dest.assign(return_data.data(), return_data.size()); - got_string = true; + return true; } - return got_string; + + return false; } uint32_t ScriptInterpreterPythonImpl::GetFlagsForCommandObject( @@ -3131,20 +3068,15 @@ uint32_t ScriptInterpreterPythonImpl::GetFlagsForCommandObject( if (PyErr_Occurred()) PyErr_Clear(); - // right now we know this function exists and is callable.. - PythonObject py_return( - PyRefType::Owned, - PyObject_CallMethod(implementor.get(), callee_name, nullptr)); + long long py_return = unwrapOrSetPythonException( + As(implementor.CallMethod(callee_name))); // if it fails, print the error but otherwise go on if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); - } - - if (py_return.IsAllocated() && PythonInteger::Check(py_return.get())) { - PythonInteger int_value(PyRefType::Borrowed, py_return.get()); - result = int_value.GetInteger(); + } else { + result = py_return; } return result; diff --git a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h index 1fa198b07e5..22b2c8152ea 100644 --- a/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h +++ b/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h @@ -395,7 +395,7 @@ public: std::string m_dictionary_name; ActiveIOHandler m_active_io_handler; bool m_session_is_active; - bool m_pty_slave_is_open; + bool m_pty_secondary_is_open; bool m_valid_session; uint32_t m_lock_count; PyThreadState *m_command_thread_state; diff --git a/gnu/llvm/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp b/gnu/llvm/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp index c6b234baa8c..5ceaf886b81 100644 --- a/gnu/llvm/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp +++ b/gnu/llvm/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp @@ -1,4 +1,4 @@ -//===-- StructuredDataDarwinLog.cpp -----------------------------*- C++ -*-===// +//===-- StructuredDataDarwinLog.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -36,6 +36,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(StructuredDataDarwinLog) + #pragma mark - #pragma mark Anonymous Namespace @@ -706,9 +708,9 @@ private: attribute_end_pos + 1, operation_end_pos - (attribute_end_pos + 1)); // add filter spec - auto rule_sp = - FilterRule::CreateRule(accept, attribute_index, ConstString(operation), - rule_text.substr(operation_end_pos + 1), error); + auto rule_sp = FilterRule::CreateRule( + accept, attribute_index, ConstString(operation), + std::string(rule_text.substr(operation_end_pos + 1)), error); if (rule_sp && error.Success()) m_filter_rules.push_back(rule_sp); @@ -979,7 +981,7 @@ EnableOptionsSP ParseAutoEnableOptions(Status &error, Debugger &debugger) { EnableOptionsSP options_sp(new EnableOptions()); options_sp->NotifyOptionParsingStarting(&exe_ctx); - CommandReturnObject result; + CommandReturnObject result(debugger.GetUseColor()); // Parse the arguments. auto options_property_sp = @@ -1034,7 +1036,7 @@ bool RunEnableCommand(CommandInterpreter &interpreter) { } // Run the command. - CommandReturnObject return_object; + CommandReturnObject return_object(interpreter.GetDebugger().GetUseColor()); interpreter.HandleCommand(command_stream.GetData(), eLazyBoolNo, return_object); return return_object.Succeeded(); diff --git a/gnu/llvm/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h b/gnu/llvm/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h index 8fa1eed66ef..caa94af1f30 100644 --- a/gnu/llvm/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h +++ b/gnu/llvm/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef StructuredDataDarwinLog_h -#define StructuredDataDarwinLog_h +#ifndef LLDB_SOURCE_PLUGINS_STRUCTUREDDATA_DARWINLOG_STRUCTUREDDATADARWINLOG_H +#define LLDB_SOURCE_PLUGINS_STRUCTUREDDATA_DARWINLOG_STRUCTUREDDATADARWINLOG_H #include "lldb/Target/StructuredDataPlugin.h" @@ -34,7 +34,7 @@ public: /// Return whether the DarwinLog functionality is enabled. /// - /// The DarwinLog functionality is enabled if the user expicitly enabled + /// The DarwinLog functionality is enabled if the user explicitly enabled /// it with the enable command, or if the user has the setting set /// that controls if we always enable it for newly created/attached /// processes. @@ -115,4 +115,4 @@ private: }; } -#endif /* StructuredDataPluginDarwinLog_hpp */ +#endif // LLDB_SOURCE_PLUGINS_STRUCTUREDDATA_DARWINLOG_STRUCTUREDDATADARWINLOG_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp index b2c4d088334..eeec7296747 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp @@ -1,4 +1,4 @@ -//===-- SymbolFileBreakpad.cpp ----------------------------------*- C++ -*-===// +//===-- SymbolFileBreakpad.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,6 +25,8 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::breakpad; +LLDB_PLUGIN_DEFINE(SymbolFileBreakpad) + char SymbolFileBreakpad::ID; class SymbolFileBreakpad::LineIterator { @@ -292,7 +294,7 @@ uint32_t SymbolFileBreakpad::ResolveSymbolContext( } void SymbolFileBreakpad::FindFunctions( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) { // TODO @@ -305,7 +307,7 @@ void SymbolFileBreakpad::FindFunctions(const RegularExpression ®ex, } void SymbolFileBreakpad::FindTypes( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) {} @@ -406,20 +408,25 @@ GetRule(llvm::StringRef &unwind_rules) { } static const RegisterInfo * -ResolveRegister(const SymbolFile::RegisterInfoResolver &resolver, +ResolveRegister(const llvm::Triple &triple, + const SymbolFile::RegisterInfoResolver &resolver, llvm::StringRef name) { - if (name.consume_front("$")) - return resolver.ResolveName(name); - - return nullptr; + if (triple.isX86() || triple.isMIPS()) { + // X86 and MIPS registers have '$' in front of their register names. Arm and + // AArch64 don't. + if (!name.consume_front("$")) + return nullptr; + } + return resolver.ResolveName(name); } static const RegisterInfo * -ResolveRegisterOrRA(const SymbolFile::RegisterInfoResolver &resolver, +ResolveRegisterOrRA(const llvm::Triple &triple, + const SymbolFile::RegisterInfoResolver &resolver, llvm::StringRef name) { if (name == ".ra") return resolver.ResolveNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); - return ResolveRegister(resolver, name); + return ResolveRegister(triple, resolver, name); } llvm::ArrayRef SymbolFileBreakpad::SaveAsDWARF(postfix::Node &node) { @@ -438,6 +445,7 @@ bool SymbolFileBreakpad::ParseCFIUnwindRow(llvm::StringRef unwind_rules, Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); llvm::BumpPtrAllocator node_alloc; + llvm::Triple triple = m_objfile_sp->GetArchitecture().GetTriple(); while (auto rule = GetRule(unwind_rules)) { node_alloc.Reset(); llvm::StringRef lhs = rule->first; @@ -453,7 +461,8 @@ bool SymbolFileBreakpad::ParseCFIUnwindRow(llvm::StringRef unwind_rules, if (name == ".cfa" && lhs != ".cfa") return postfix::MakeNode(node_alloc); - if (const RegisterInfo *info = ResolveRegister(resolver, name)) { + if (const RegisterInfo *info = + ResolveRegister(triple, resolver, name)) { return postfix::MakeNode( node_alloc, info->kinds[eRegisterKindLLDB]); } @@ -468,7 +477,8 @@ bool SymbolFileBreakpad::ParseCFIUnwindRow(llvm::StringRef unwind_rules, llvm::ArrayRef saved = SaveAsDWARF(*rhs); if (lhs == ".cfa") { row.GetCFAValue().SetIsDWARFExpression(saved.data(), saved.size()); - } else if (const RegisterInfo *info = ResolveRegisterOrRA(resolver, lhs)) { + } else if (const RegisterInfo *info = + ResolveRegisterOrRA(triple, resolver, lhs)) { UnwindPlan::Row::RegisterLocation loc; loc.SetIsDWARFExpression(saved.data(), saved.size()); row.SetRegisterInfo(info->kinds[eRegisterKindLLDB], loc); @@ -572,6 +582,7 @@ SymbolFileBreakpad::ParseWinUnwindPlan(const Bookmark &bookmark, return nullptr; } auto it = program.begin(); + llvm::Triple triple = m_objfile_sp->GetArchitecture().GetTriple(); const auto &symbol_resolver = [&](postfix::SymbolNode &symbol) -> postfix::Node * { llvm::StringRef name = symbol.GetName(); @@ -579,7 +590,7 @@ SymbolFileBreakpad::ParseWinUnwindPlan(const Bookmark &bookmark, if (rule.first == name) return rule.second; } - if (const RegisterInfo *info = ResolveRegister(resolver, name)) + if (const RegisterInfo *info = ResolveRegister(triple, resolver, name)) return postfix::MakeNode( node_alloc, info->kinds[eRegisterKindLLDB]); return nullptr; @@ -609,7 +620,7 @@ SymbolFileBreakpad::ParseWinUnwindPlan(const Bookmark &bookmark, // Now process the rest of the assignments. for (++it; it != program.end(); ++it) { - const RegisterInfo *info = ResolveRegister(resolver, it->first); + const RegisterInfo *info = ResolveRegister(triple, resolver, it->first); // It is not an error if the resolution fails because the program may // contain temporary variables. if (!info) @@ -694,18 +705,18 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu, "How did we create compile units without a base address?"); SupportFileMap map; - data.line_table_up = std::make_unique(&cu); - std::unique_ptr line_seq_up( - data.line_table_up->CreateLineSequenceContainer()); + std::vector> sequences; + std::unique_ptr line_seq_up = + LineTable::CreateLineSequenceContainer(); llvm::Optional next_addr; auto finish_sequence = [&]() { - data.line_table_up->AppendLineEntryToSequence( + LineTable::AppendLineEntryToSequence( line_seq_up.get(), *next_addr, /*line*/ 0, /*column*/ 0, /*file_idx*/ 0, /*is_start_of_statement*/ false, /*is_start_of_basic_block*/ false, /*is_prologue_end*/ false, /*is_epilogue_begin*/ false, /*is_terminal_entry*/ true); - data.line_table_up->InsertSequence(line_seq_up.get()); - line_seq_up->Clear(); + sequences.push_back(std::move(line_seq_up)); + line_seq_up = LineTable::CreateLineSequenceContainer(); }; LineIterator It(*m_objfile_sp, Record::Func, data.bookmark), @@ -722,7 +733,7 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu, // Discontiguous entries. Finish off the previous sequence and reset. finish_sequence(); } - data.line_table_up->AppendLineEntryToSequence( + LineTable::AppendLineEntryToSequence( line_seq_up.get(), record->Address, record->LineNum, /*column*/ 0, map[record->FileNum], /*is_start_of_statement*/ true, /*is_start_of_basic_block*/ false, /*is_prologue_end*/ false, @@ -731,6 +742,7 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu, } if (next_addr) finish_sequence(); + data.line_table_up = std::make_unique(&cu, std::move(sequences)); data.support_files = map.translate(cu.GetPrimaryFile(), *m_files); } diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h index de271224a65..90dbcc77627 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H -#define LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H #include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h" #include "lldb/Core/FileSpecList.h" @@ -82,7 +82,7 @@ public: size_t ParseBlocksRecursive(Function &func) override { return 0; } void FindGlobalVariables(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, VariableList &variables) override {} @@ -110,14 +110,14 @@ public: TypeList &type_list) override {} void FindFunctions(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, lldb::FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) override; void FindFunctions(const RegularExpression ®ex, bool include_inlines, SymbolContextList &sc_list) override; - void FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx, + void FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) override; @@ -135,7 +135,7 @@ public: CompilerDeclContext FindNamespace(ConstString name, - const CompilerDeclContext *parent_decl_ctx) override { + const CompilerDeclContext &parent_decl_ctx) override { return CompilerDeclContext(); } diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp index 0a5073b8cd9..33ab11a3ca4 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp @@ -1,4 +1,4 @@ -//===-- AppleDWARFIndex.cpp ------------------------------------*- C++ -*-===// +//===-- AppleDWARFIndex.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -52,54 +52,70 @@ std::unique_ptr AppleDWARFIndex::Create( return nullptr; } -void AppleDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) { - if (m_apple_names_up) - m_apple_names_up->FindByName(basename.GetStringRef(), offsets); +void AppleDWARFIndex::GetGlobalVariables( + ConstString basename, llvm::function_ref callback) { + if (!m_apple_names_up) + return; + m_apple_names_up->FindByName( + basename.GetStringRef(), + DIERefCallback(callback, basename.GetStringRef())); } -void AppleDWARFIndex::GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) { +void AppleDWARFIndex::GetGlobalVariables( + const RegularExpression ®ex, + llvm::function_ref callback) { if (!m_apple_names_up) return; DWARFMappedHash::DIEInfoArray hash_data; - if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data)) - DWARFMappedHash::ExtractDIEArray(hash_data, offsets); + m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data); + // This is not really the DIE name. + DWARFMappedHash::ExtractDIEArray(hash_data, + DIERefCallback(callback, regex.GetText())); } -void AppleDWARFIndex::GetGlobalVariables(const DWARFUnit &cu, - DIEArray &offsets) { +void AppleDWARFIndex::GetGlobalVariables( + const DWARFUnit &cu, llvm::function_ref callback) { if (!m_apple_names_up) return; DWARFMappedHash::DIEInfoArray hash_data; - if (m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(), - cu.GetNextUnitOffset(), hash_data)) - DWARFMappedHash::ExtractDIEArray(hash_data, offsets); + m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(), cu.GetNextUnitOffset(), + hash_data); + DWARFMappedHash::ExtractDIEArray(hash_data, DIERefCallback(callback)); } -void AppleDWARFIndex::GetObjCMethods(ConstString class_name, - DIEArray &offsets) { - if (m_apple_objc_up) - m_apple_objc_up->FindByName(class_name.GetStringRef(), offsets); +void AppleDWARFIndex::GetObjCMethods( + ConstString class_name, llvm::function_ref callback) { + if (!m_apple_objc_up) + return; + m_apple_objc_up->FindByName( + class_name.GetStringRef(), + DIERefCallback(callback, class_name.GetStringRef())); } -void AppleDWARFIndex::GetCompleteObjCClass(ConstString class_name, - bool must_be_implementation, - DIEArray &offsets) { - if (m_apple_types_up) { - m_apple_types_up->FindCompleteObjCClassByName( - class_name.GetStringRef(), offsets, must_be_implementation); - } +void AppleDWARFIndex::GetCompleteObjCClass( + ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) { + if (!m_apple_types_up) + return; + m_apple_types_up->FindCompleteObjCClassByName( + class_name.GetStringRef(), + DIERefCallback(callback, class_name.GetStringRef()), + must_be_implementation); } -void AppleDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) { - if (m_apple_types_up) - m_apple_types_up->FindByName(name.GetStringRef(), offsets); +void AppleDWARFIndex::GetTypes( + ConstString name, llvm::function_ref callback) { + if (!m_apple_types_up) + return; + m_apple_types_up->FindByName(name.GetStringRef(), + DIERefCallback(callback, name.GetStringRef())); } -void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context, - DIEArray &offsets) { +void AppleDWARFIndex::GetTypes( + const DWARFDeclContext &context, + llvm::function_ref callback) { if (!m_apple_types_up) return; @@ -119,7 +135,8 @@ void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context, if (log) m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()"); m_apple_types_up->FindByNameAndTagAndQualifiedNameHash( - type_name.GetStringRef(), tag, qualified_name_hash, offsets); + type_name.GetStringRef(), tag, qualified_name_hash, + DIERefCallback(callback, type_name.GetStringRef())); return; } @@ -133,54 +150,52 @@ void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context, if (!has_qualified_name_hash && (context.GetSize() > 1) && (context[1].tag == DW_TAG_class_type || context[1].tag == DW_TAG_structure_type)) { - DIEArray class_matches; - m_apple_types_up->FindByName(context[1].name, class_matches); - if (class_matches.empty()) + if (m_apple_types_up->FindByName(context[1].name, + [&](DIERef ref) { return false; })) return; } if (log) m_module.LogMessage(log, "FindByNameAndTag()"); - m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, offsets); + m_apple_types_up->FindByNameAndTag( + type_name.GetStringRef(), tag, + DIERefCallback(callback, type_name.GetStringRef())); return; } - m_apple_types_up->FindByName(type_name.GetStringRef(), offsets); + m_apple_types_up->FindByName( + type_name.GetStringRef(), + DIERefCallback(callback, type_name.GetStringRef())); } -void AppleDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) { - if (m_apple_namespaces_up) - m_apple_namespaces_up->FindByName(name.GetStringRef(), offsets); +void AppleDWARFIndex::GetNamespaces( + ConstString name, llvm::function_ref callback) { + if (!m_apple_namespaces_up) + return; + m_apple_namespaces_up->FindByName( + name.GetStringRef(), DIERefCallback(callback, name.GetStringRef())); } -void AppleDWARFIndex::GetFunctions(ConstString name, SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, - std::vector &dies) { - DIEArray offsets; - m_apple_names_up->FindByName(name.GetStringRef(), offsets); - for (const DIERef &die_ref : offsets) { - ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf, parent_decl_ctx, - name_type_mask, dies); - } +void AppleDWARFIndex::GetFunctions( + ConstString name, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, + llvm::function_ref callback) { + m_apple_names_up->FindByName(name.GetStringRef(), [&](DIERef die_ref) { + return ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf, + parent_decl_ctx, name_type_mask, callback); + }); } -void AppleDWARFIndex::GetFunctions(const RegularExpression ®ex, - DIEArray &offsets) { +void AppleDWARFIndex::GetFunctions( + const RegularExpression ®ex, + llvm::function_ref callback) { if (!m_apple_names_up) return; DWARFMappedHash::DIEInfoArray hash_data; - if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data)) - DWARFMappedHash::ExtractDIEArray(hash_data, offsets); -} - -void AppleDWARFIndex::ReportInvalidDIERef(const DIERef &ref, - llvm::StringRef name) { - m_module.ReportErrorIfModifyDetected( - "the DWARF debug information has been modified (accelerator table had " - "bad die 0x%8.8x for '%s')\n", - ref.die_offset(), name.str().c_str()); + m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data); + DWARFMappedHash::ExtractDIEArray(hash_data, + DIERefCallback(callback, regex.GetText())); } void AppleDWARFIndex::Dump(Stream &s) { diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h index d15d61e270b..a7032f50e59 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_APPLEDWARFINDEX_H -#define LLDB_APPLEDWARFINDEX_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_APPLEDWARFINDEX_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_APPLEDWARFINDEX_H #include "Plugins/SymbolFile/DWARF/DWARFIndex.h" #include "Plugins/SymbolFile/DWARF/HashedNameToDIE.h" @@ -32,23 +32,33 @@ public: void Preload() override {} - void GetGlobalVariables(ConstString basename, DIEArray &offsets) override; - void GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) override; - void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override; - void GetObjCMethods(ConstString class_name, DIEArray &offsets) override; - void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, - DIEArray &offsets) override; - void GetTypes(ConstString name, DIEArray &offsets) override; - void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override; - void GetNamespaces(ConstString name, DIEArray &offsets) override; + void + GetGlobalVariables(ConstString basename, + llvm::function_ref callback) override; + void + GetGlobalVariables(const RegularExpression ®ex, + llvm::function_ref callback) override; + void + GetGlobalVariables(const DWARFUnit &cu, + llvm::function_ref callback) override; + void GetObjCMethods(ConstString class_name, + llvm::function_ref callback) override; + void GetCompleteObjCClass( + ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) override; + void GetTypes(ConstString name, + llvm::function_ref callback) override; + void GetTypes(const DWARFDeclContext &context, + llvm::function_ref callback) override; + void GetNamespaces(ConstString name, + llvm::function_ref callback) override; void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, - std::vector &dies) override; - void GetFunctions(const RegularExpression ®ex, DIEArray &offsets) override; + llvm::function_ref callback) override; + void GetFunctions(const RegularExpression ®ex, + llvm::function_ref callback) override; - void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override; void Dump(Stream &s) override; private: @@ -59,4 +69,4 @@ private: }; } // namespace lldb_private -#endif // LLDB_APPLEDWARFINDEX_H +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_APPLEDWARFINDEX_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt index 4a3bc81afa7..550404314af 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt @@ -37,8 +37,6 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN NameToDIE.cpp SymbolFileDWARF.cpp SymbolFileDWARFDwo.cpp - SymbolFileDWARFDwoDwp.cpp - SymbolFileDWARFDwp.cpp SymbolFileDWARFDebugMap.cpp UniqueDWARFASTType.cpp @@ -53,6 +51,7 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN lldbPluginObjCLanguage lldbPluginCPlusPlusLanguage lldbPluginExpressionParserClang + lldbPluginTypeSystemClang CLANG_LIBS clangAST clangBasic diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp index f7f2a5bf006..7a8ab9c9bcf 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp @@ -1,4 +1,4 @@ -//===-- DIERef.cpp ----------------------------------------------*- C++ -*-===// +//===-- DIERef.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h index 5546bb7e8b8..f7e09ee1728 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DIERef_h_ -#define SymbolFileDWARF_DIERef_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H #include "lldb/Core/dwarf.h" #include "llvm/ADT/Optional.h" @@ -44,6 +44,16 @@ public: dw_offset_t die_offset() const { return m_die_offset; } + bool operator<(DIERef other) const { + if (m_dwo_num_valid != other.m_dwo_num_valid) + return m_dwo_num_valid < other.m_dwo_num_valid; + if (m_dwo_num_valid && (m_dwo_num != other.m_dwo_num)) + return m_dwo_num < other.m_dwo_num; + if (m_section != other.m_section) + return m_section < other.m_section; + return m_die_offset < other.m_die_offset; + } + private: uint32_t m_dwo_num : 30; uint32_t m_dwo_num_valid : 1; @@ -60,4 +70,4 @@ template<> struct format_provider { }; } // namespace llvm -#endif // SymbolFileDWARF_DIERef_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h index 7ee4727cde9..2e0a7fd3ecd 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFASTParser_h_ -#define SymbolFileDWARF_DWARFASTParser_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSER_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSER_H #include "DWARFDefines.h" #include "lldb/Core/PluginInterface.h" @@ -55,4 +55,4 @@ public: const lldb_private::ExecutionContext *exe_ctx = nullptr); }; -#endif // SymbolFileDWARF_DWARFASTParser_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSER_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 6166aa77bda..2d1db66e7fd 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1,4 +1,4 @@ -//===-- DWARFASTParserClang.cpp ---------------------------------*- C++ -*-===// +//===-- DWARFASTParserClang.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,17 +13,17 @@ #include "DWARFDeclContext.h" #include "DWARFDefines.h" #include "SymbolFileDWARF.h" -#include "SymbolFileDWARFDwo.h" #include "SymbolFileDWARFDebugMap.h" +#include "SymbolFileDWARFDwo.h" #include "UniqueDWARFASTType.h" +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" #include "lldb/Core/Module.h" #include "lldb/Core/Value.h" #include "lldb/Host/Host.h" -#include "lldb/Symbol/ClangASTImporter.h" -#include "lldb/Symbol/ClangASTMetadata.h" -#include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" @@ -35,6 +35,8 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" +#include "llvm/Demangle/Demangle.h" + #include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" @@ -55,7 +57,7 @@ using namespace lldb; using namespace lldb_private; -DWARFASTParserClang::DWARFASTParserClang(ClangASTContext &ast) +DWARFASTParserClang::DWARFASTParserClang(TypeSystemClang &ast) : m_ast(ast), m_die_to_decl_ctx(), m_decl_ctx_to_die() {} DWARFASTParserClang::~DWARFASTParserClang() {} @@ -88,7 +90,7 @@ static bool DeclKindIsCXXClass(clang::Decl::Kind decl_kind) { ClangASTImporter &DWARFASTParserClang::GetClangASTImporter() { if (!m_clang_ast_importer_up) { - m_clang_ast_importer_up.reset(new ClangASTImporter); + m_clang_ast_importer_up = std::make_unique(); } return *m_clang_ast_importer_up; } @@ -155,7 +157,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc, // The type in the Clang module must have the same language as the current CU. LanguageSet languages; - languages.Insert(die.GetCU()->GetLanguageType()); + languages.Insert(SymbolFileDWARF::GetLanguage(*die.GetCU())); llvm::DenseSet searched_symbol_files; clang_module_sp->GetSymbolFile()->FindTypes(decl_context, languages, searched_symbol_files, pcm_types); @@ -210,14 +212,15 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc, TypeSP type_sp(new Type( die.GetID(), dwarf, pcm_type_sp->GetName(), pcm_type_sp->GetByteSize(), nullptr, LLDB_INVALID_UID, Type::eEncodingInvalid, - &pcm_type_sp->GetDeclaration(), type, Type::ResolveState::Forward)); + &pcm_type_sp->GetDeclaration(), type, Type::ResolveState::Forward, + TypePayloadClang(GetOwningClangModule(die)))); dwarf->GetTypeList().Insert(type_sp); dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type); - if (tag_decl) + clang::TagDecl *tag_decl = TypeSystemClang::GetAsTagDecl(type); + if (tag_decl) { LinkDeclContextToDIE(tag_decl, die); - else { + } else { clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die); if (defn_decl_ctx) LinkDeclContextToDIE(defn_decl_ctx, die); @@ -226,7 +229,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc, return type_sp; } -static void CompleteExternalTagDeclType(ClangASTContext &ast, +static void CompleteExternalTagDeclType(TypeSystemClang &ast, ClangASTImporter &ast_importer, clang::DeclContext *decl_ctx, DWARFDIE die, @@ -248,8 +251,8 @@ static void CompleteExternalTagDeclType(ClangASTContext &ast, type_name_cstr ? type_name_cstr : "", die.GetOffset()); // We need to make the type look complete otherwise, we might crash in // Clang when adding children. - if (ClangASTContext::StartTagDeclarationDefinition(type)) - ClangASTContext::CompleteTagDeclarationDefinition(type); + if (TypeSystemClang::StartTagDeclarationDefinition(type)) + TypeSystemClang::CompleteTagDeclarationDefinition(type); } } @@ -504,7 +507,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc, DWARF_LOG_LOOKUPS)); SymbolFileDWARF *dwarf = die.GetDWARF(); const dw_tag_t tag = die.Tag(); - LanguageType cu_language = die.GetLanguage(); + LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU()); Type::ResolveState resolve_state = Type::ResolveState::Unresolved; Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID; TypeSP type_sp; @@ -706,7 +709,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc, type_sp = std::make_shared( die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, dwarf->GetUID(attrs.type.Reference()), encoding_data_type, &attrs.decl, - clang_type, resolve_state); + clang_type, resolve_state, TypePayloadClang(GetOwningClangModule(die))); dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); return type_sp; @@ -726,8 +729,7 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc, if (type_sp) return type_sp; - DWARFDeclContext die_decl_ctx; - die.GetDWARFDeclContext(die_decl_ctx); + DWARFDeclContext die_decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die); type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx); @@ -789,27 +791,28 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc, clang_type = m_ast.CreateEnumerationType( attrs.name.GetCString(), GetClangDeclContextContainingDIE(die, nullptr), - attrs.decl, enumerator_clang_type, attrs.is_scoped_enum); + GetOwningClangModule(die), attrs.decl, enumerator_clang_type, + attrs.is_scoped_enum); } else { - enumerator_clang_type = - m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType()); + enumerator_clang_type = m_ast.GetEnumerationIntegerType(clang_type); } - LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die); + LinkDeclContextToDIE(TypeSystemClang::GetDeclContextForType(clang_type), die); type_sp = std::make_shared( die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, dwarf->GetUID(attrs.type.Reference()), Type::eEncodingIsUID, &attrs.decl, - clang_type, Type::ResolveState::Forward); + clang_type, Type::ResolveState::Forward, + TypePayloadClang(GetOwningClangModule(die))); - if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) { + if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) { if (die.HasChildren()) { bool is_signed = false; enumerator_clang_type.IsIntegerType(is_signed); ParseChildEnumerators(clang_type, is_signed, type_sp->GetByteSize().getValueOr(0), die); } - ClangASTContext::CompleteTagDeclarationDefinition(clang_type); + TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); } else { dwarf->GetObjectFile()->GetModule()->ReportError( "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its " @@ -919,7 +922,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, if (complete_objc_class_type_sp) { CompilerType type_clang_forward_type = complete_objc_class_type_sp->GetForwardCompilerType(); - if (ClangASTContext::IsObjCObjectOrInterfaceType( + if (TypeSystemClang::IsObjCObjectOrInterfaceType( type_clang_forward_type)) class_opaque_type = type_clang_forward_type; } @@ -1024,7 +1027,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, } else { CompilerType class_opaque_type = class_type->GetForwardCompilerType(); - if (ClangASTContext::IsCXXClassType(class_opaque_type)) { + if (TypeSystemClang::IsCXXClassType(class_opaque_type)) { if (class_opaque_type.IsBeingDefined() || alternate_defn) { if (!is_static && !die.HasChildren()) { // We have a C++ member function with no children (this @@ -1169,27 +1172,38 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, } if (!function_decl) { + const char *name = attrs.name.GetCString(); + + // We currently generate function templates with template parameters in + // their name. In order to get closer to the AST that clang generates + // we want to strip these from the name when creating the AST. + if (attrs.mangled_name) { + llvm::ItaniumPartialDemangler D; + if (!D.partialDemangle(attrs.mangled_name)) + name = D.getFunctionBaseName(nullptr, nullptr); + } + // We just have a function that isn't part of a class function_decl = m_ast.CreateFunctionDeclaration( ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx, - attrs.name.GetCString(), clang_type, attrs.storage, + GetOwningClangModule(die), name, clang_type, attrs.storage, attrs.is_inline); if (has_template_params) { - ClangASTContext::TemplateParameterInfos template_param_infos; + TypeSystemClang::TemplateParameterInfos template_param_infos; ParseTemplateParameterInfos(die, template_param_infos); template_function_decl = m_ast.CreateFunctionDeclaration( ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx, - attrs.name.GetCString(), clang_type, attrs.storage, - attrs.is_inline); + GetOwningClangModule(die), attrs.name.GetCString(), clang_type, + attrs.storage, attrs.is_inline); clang::FunctionTemplateDecl *func_template_decl = m_ast.CreateFunctionTemplateDecl( - containing_decl_ctx, template_function_decl, - attrs.name.GetCString(), template_param_infos); + containing_decl_ctx, GetOwningClangModule(die), + template_function_decl, name, template_param_infos); m_ast.CreateFunctionTemplateSpecializationInfo( - function_decl, func_template_decl, template_param_infos); + template_function_decl, func_template_decl, template_param_infos); } lldbassert(function_decl); @@ -1249,44 +1263,7 @@ TypeSP DWARFASTParserClang::ParseArrayType(const DWARFDIE &die, if (attrs.byte_stride == 0 && attrs.bit_stride == 0) attrs.byte_stride = element_type->GetByteSize().getValueOr(0); CompilerType array_element_type = element_type->GetForwardCompilerType(); - - if (ClangASTContext::IsCXXClassType(array_element_type) && - !array_element_type.GetCompleteType()) { - ModuleSP module_sp = die.GetModule(); - if (module_sp) { - if (die.GetCU()->GetProducer() == eProducerClang) - module_sp->ReportError( - "DWARF DW_TAG_array_type DIE at 0x%8.8x has a " - "class/union/struct element type DIE 0x%8.8x that is a " - "forward declaration, not a complete definition.\nTry " - "compiling the source file with -fstandalone-debug or " - "disable -gmodules", - die.GetOffset(), type_die.GetOffset()); - else - module_sp->ReportError( - "DWARF DW_TAG_array_type DIE at 0x%8.8x has a " - "class/union/struct element type DIE 0x%8.8x that is a " - "forward declaration, not a complete definition.\nPlease " - "file a bug against the compiler and include the " - "preprocessed output for %s", - die.GetOffset(), type_die.GetOffset(), GetUnitName(die).c_str()); - } - - // We have no choice other than to pretend that the element class - // type is complete. If we don't do this, clang will crash when - // trying to layout the class. 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. - if (ClangASTContext::StartTagDeclarationDefinition(array_element_type)) { - ClangASTContext::CompleteTagDeclarationDefinition(array_element_type); - } else { - module_sp->ReportError("DWARF DIE at 0x%8.8x was not able to " - "start its definition.\nPlease file a " - "bug and attach the file at the start " - "of this error message", - type_die.GetOffset()); - } - } + CompleteType(array_element_type); uint64_t array_element_bit_stride = attrs.byte_stride * 8 + attrs.bit_stride; @@ -1328,7 +1305,7 @@ TypeSP DWARFASTParserClang::ParsePointerToMemberType( CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType(); CompilerType class_clang_type = class_type->GetLayoutCompilerType(); - CompilerType clang_type = ClangASTContext::CreateMemberPointerType( + CompilerType clang_type = TypeSystemClang::CreateMemberPointerType( class_clang_type, pointee_clang_type); if (llvm::Optional clang_type_size = @@ -1341,6 +1318,28 @@ TypeSP DWARFASTParserClang::ParsePointerToMemberType( return nullptr; } +void DWARFASTParserClang::CompleteType(CompilerType type) { + // Technically, enums can be incomplete too, but we don't handle those as they + // are emitted even under -flimit-debug-info. + if (!TypeSystemClang::IsCXXClassType(type)) + return; + + if (type.GetCompleteType()) + return; + + // No complete definition in this module. Mark the class as complete to + // satisfy local ast invariants, but make a note of the fact that + // it is not _really_ complete so we can later search for a definition in a + // different module. + // Since we provide layout assistance, layouts of types containing this class + // will be correct even if we are not able to find the definition elsewhere. + bool started = TypeSystemClang::StartTagDeclarationDefinition(type); + lldbassert(started && "Unable to start a class type definition."); + TypeSystemClang::CompleteTagDeclarationDefinition(type); + const clang::TagDecl *td = ClangUtil::GetAsTagDecl(type); + m_ast.GetMetadata(td)->SetIsForcefullyCompleted(); +} + TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType( const SymbolContext &sc, const DWARFDIE &die, TypeSP type_sp) { if (!type_sp) @@ -1383,7 +1382,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, CompilerType clang_type; const dw_tag_t tag = die.Tag(); SymbolFileDWARF *dwarf = die.GetDWARF(); - LanguageType cu_language = die.GetLanguage(); + LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU()); Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_TYPE_COMPLETION | DWARF_LOG_LOOKUPS); @@ -1515,8 +1514,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, if (type_sp) return type_sp; - DWARFDeclContext die_decl_ctx; - die.GetDWARFDeclContext(die_decl_ctx); + DWARFDeclContext die_decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die); // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, // type_name_const_str); @@ -1582,12 +1580,12 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die)); if (attrs.name.GetStringRef().contains('<')) { - ClangASTContext::TemplateParameterInfos template_param_infos; + TypeSystemClang::TemplateParameterInfos template_param_infos; if (ParseTemplateParameterInfos(die, template_param_infos)) { clang::ClassTemplateDecl *class_template_decl = - m_ast.ParseClassTemplateDecl(decl_ctx, attrs.accessibility, - attrs.name.GetCString(), tag_decl_kind, - template_param_infos); + m_ast.ParseClassTemplateDecl( + decl_ctx, GetOwningClangModule(die), attrs.accessibility, + attrs.name.GetCString(), tag_decl_kind, template_param_infos); if (!class_template_decl) { if (log) { dwarf->GetObjectFile()->GetModule()->LogMessage( @@ -1602,8 +1600,8 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, clang::ClassTemplateSpecializationDecl *class_specialization_decl = m_ast.CreateClassTemplateSpecializationDecl( - decl_ctx, class_template_decl, tag_decl_kind, - template_param_infos); + decl_ctx, GetOwningClangModule(die), class_template_decl, + tag_decl_kind, template_param_infos); clang_type = m_ast.CreateClassTemplateSpecializationType( class_specialization_decl); clang_type_was_created = true; @@ -1616,8 +1614,9 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, if (!clang_type_was_created) { clang_type_was_created = true; clang_type = m_ast.CreateRecordType( - decl_ctx, attrs.accessibility, attrs.name.GetCString(), tag_decl_kind, - attrs.class_language, &metadata, attrs.exports_symbols); + decl_ctx, GetOwningClangModule(die), attrs.accessibility, + attrs.name.GetCString(), tag_decl_kind, attrs.class_language, + &metadata, attrs.exports_symbols); } } @@ -1625,12 +1624,11 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, // parameters in any class methods need it for the clang types for // function prototypes. LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die); - type_sp = std::make_shared(die.GetID(), dwarf, attrs.name, - attrs.byte_size, nullptr, LLDB_INVALID_UID, - Type::eEncodingIsUID, &attrs.decl, - clang_type, Type::ResolveState::Forward); - - type_sp->SetIsCompleteObjCClass(attrs.is_complete_objc_class); + type_sp = std::make_shared( + die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, + LLDB_INVALID_UID, Type::eEncodingIsUID, &attrs.decl, clang_type, + Type::ResolveState::Forward, + TypePayloadClang(OptionalClangModuleID(), attrs.is_complete_objc_class)); // 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 @@ -1676,8 +1674,8 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, // these child definitions. if (!die.HasChildren()) { // No children for this struct/union/class, lets finish it - if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) { - ClangASTContext::CompleteTagDeclarationDefinition(clang_type); + if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) { + TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); } else { dwarf->GetObjectFile()->GetModule()->ReportError( "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its " @@ -1689,7 +1687,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, if (tag == DW_TAG_structure_type) // this only applies in C { clang::RecordDecl *record_decl = - ClangASTContext::GetAsRecordDecl(clang_type); + TypeSystemClang::GetAsRecordDecl(clang_type); if (record_decl) { GetClangASTImporter().SetRecordLayout( @@ -1707,7 +1705,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, if (attrs.class_language != eLanguageTypeObjC && attrs.class_language != eLanguageTypeObjC_plus_plus) - ClangASTContext::StartTagDeclarationDefinition(clang_type); + TypeSystemClang::StartTagDeclarationDefinition(clang_type); // Leave this as a forward declaration until we need to know the // details of the type. lldb_private::Type will automatically call @@ -1723,9 +1721,9 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, // binaries. dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] = clang_type.GetOpaqueQualType(); - dwarf->GetForwardDeclClangTypeToDie() - [ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] = - die.GetID(); + dwarf->GetForwardDeclClangTypeToDie().try_emplace( + ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType(), + *die.GetDIERef()); m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true); } } @@ -1770,7 +1768,7 @@ public: m_property_getter_name(property_getter_name), m_property_attributes(property_attributes) { if (metadata != nullptr) { - m_metadata_up.reset(new ClangASTMetadata()); + m_metadata_up = std::make_unique(); *m_metadata_up = *metadata; } } @@ -1790,14 +1788,14 @@ public: m_property_attributes = rhs.m_property_attributes; if (rhs.m_metadata_up) { - m_metadata_up.reset(new ClangASTMetadata()); + m_metadata_up = std::make_unique(); *m_metadata_up = *rhs.m_metadata_up; } return *this; } bool Finalize() { - return ClangASTContext::AddObjCClassProperty( + return TypeSystemClang::AddObjCClassProperty( m_class_opaque_type, m_property_name, m_property_opaque_type, m_ivar_decl, m_property_setter_name, m_property_getter_name, m_property_attributes, m_metadata_up.get()); @@ -1816,14 +1814,14 @@ private: bool DWARFASTParserClang::ParseTemplateDIE( const DWARFDIE &die, - ClangASTContext::TemplateParameterInfos &template_param_infos) { + TypeSystemClang::TemplateParameterInfos &template_param_infos) { const dw_tag_t tag = die.Tag(); bool is_template_template_argument = false; switch (tag) { case DW_TAG_GNU_template_parameter_pack: { - template_param_infos.packed_args.reset( - new ClangASTContext::TemplateParameterInfos); + template_param_infos.packed_args = + std::make_unique(); for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid(); child_die = child_die.GetSibling()) { if (!ParseTemplateDIE(child_die, *template_param_infos.packed_args)) @@ -1925,7 +1923,7 @@ bool DWARFASTParserClang::ParseTemplateDIE( bool DWARFASTParserClang::ParseTemplateParameterInfos( const DWARFDIE &parent_die, - ClangASTContext::TemplateParameterInfos &template_param_infos) { + TypeSystemClang::TemplateParameterInfos &template_param_infos) { if (!parent_die) return false; @@ -1959,141 +1957,102 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die, ClangASTImporter::LayoutInfo layout_info; - { - if (die.HasChildren()) { - LanguageType class_language = eLanguageTypeUnknown; - if (ClangASTContext::IsObjCObjectOrInterfaceType(clang_type)) { - class_language = eLanguageTypeObjC; - // For objective C we don't start the definition when the class is - // created. - ClangASTContext::StartTagDeclarationDefinition(clang_type); - } - - int tag_decl_kind = -1; - AccessType default_accessibility = eAccessNone; - if (tag == DW_TAG_structure_type) { - tag_decl_kind = clang::TTK_Struct; - default_accessibility = eAccessPublic; - } else if (tag == DW_TAG_union_type) { - tag_decl_kind = clang::TTK_Union; - default_accessibility = eAccessPublic; - } else if (tag == DW_TAG_class_type) { - tag_decl_kind = clang::TTK_Class; - default_accessibility = eAccessPrivate; - } - - std::vector> bases; - std::vector member_accessibilities; - bool is_a_class = false; - // Parse members and base classes first - std::vector member_function_dies; - - DelayedPropertyList delayed_properties; - ParseChildMembers(die, clang_type, class_language, bases, - member_accessibilities, member_function_dies, - delayed_properties, default_accessibility, is_a_class, - layout_info); - - // Now parse any methods if there were any... - for (const DWARFDIE &die : member_function_dies) - dwarf->ResolveType(die); - - if (class_language == eLanguageTypeObjC) { - ConstString class_name(clang_type.GetTypeName()); - if (class_name) { - DIEArray method_die_offsets; - dwarf->GetObjCMethodDIEOffsets(class_name, method_die_offsets); - - if (!method_die_offsets.empty()) { - DWARFDebugInfo *debug_info = dwarf->DebugInfo(); - - const size_t num_matches = method_die_offsets.size(); - for (size_t i = 0; i < num_matches; ++i) { - const DIERef &die_ref = method_die_offsets[i]; - DWARFDIE method_die = debug_info->GetDIE(die_ref); - - if (method_die) - method_die.ResolveType(); - } - } - - for (DelayedPropertyList::iterator pi = delayed_properties.begin(), - pe = delayed_properties.end(); - pi != pe; ++pi) - pi->Finalize(); - } - } + if (die.HasChildren()) { + const bool type_is_objc_object_or_interface = + TypeSystemClang::IsObjCObjectOrInterfaceType(clang_type); + if (type_is_objc_object_or_interface) { + // For objective C we don't start the definition when the class is + // created. + TypeSystemClang::StartTagDeclarationDefinition(clang_type); + } + + int tag_decl_kind = -1; + AccessType default_accessibility = eAccessNone; + if (tag == DW_TAG_structure_type) { + tag_decl_kind = clang::TTK_Struct; + default_accessibility = eAccessPublic; + } else if (tag == DW_TAG_union_type) { + tag_decl_kind = clang::TTK_Union; + default_accessibility = eAccessPublic; + } else if (tag == DW_TAG_class_type) { + tag_decl_kind = clang::TTK_Class; + default_accessibility = eAccessPrivate; + } + + std::vector> bases; + std::vector member_accessibilities; + bool is_a_class = false; + // Parse members and base classes first + std::vector member_function_dies; + + DelayedPropertyList delayed_properties; + ParseChildMembers(die, clang_type, bases, member_accessibilities, + member_function_dies, delayed_properties, + default_accessibility, is_a_class, layout_info); + + // Now parse any methods if there were any... + for (const DWARFDIE &die : member_function_dies) + dwarf->ResolveType(die); + + if (type_is_objc_object_or_interface) { + ConstString class_name(clang_type.GetTypeName()); + if (class_name) { + dwarf->GetObjCMethods(class_name, [&](DWARFDIE method_die) { + method_die.ResolveType(); + return true; + }); - // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we - // need to tell the clang type it is actually a class. - if (class_language != eLanguageTypeObjC) { - if (is_a_class && tag_decl_kind != clang::TTK_Class) - m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type), - clang::TTK_Class); + for (DelayedPropertyList::iterator pi = delayed_properties.begin(), + pe = delayed_properties.end(); + pi != pe; ++pi) + pi->Finalize(); } + } - // Since DW_TAG_structure_type gets used for both classes and - // structures, we may need to set any DW_TAG_member fields to have a - // "private" access if none was specified. When we parsed the child - // members we tracked that actual accessibility value for each - // DW_TAG_member in the "member_accessibilities" array. If the value - // for the member is zero, then it was set to the - // "default_accessibility" which for structs was "public". Below we - // correct this by setting any fields to "private" that weren't - // correctly set. - if (is_a_class && !member_accessibilities.empty()) { - // This is a class and all members that didn't have their access - // specified are private. - m_ast.SetDefaultAccessForRecordFields( - m_ast.GetAsRecordDecl(clang_type), eAccessPrivate, - &member_accessibilities.front(), member_accessibilities.size()); + // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we + // need to tell the clang type it is actually a class. + if (!type_is_objc_object_or_interface) { + if (is_a_class && tag_decl_kind != clang::TTK_Class) + m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type), + clang::TTK_Class); + } + + // Since DW_TAG_structure_type gets used for both classes and + // structures, we may need to set any DW_TAG_member fields to have a + // "private" access if none was specified. When we parsed the child + // members we tracked that actual accessibility value for each + // DW_TAG_member in the "member_accessibilities" array. If the value + // for the member is zero, then it was set to the + // "default_accessibility" which for structs was "public". Below we + // correct this by setting any fields to "private" that weren't + // correctly set. + if (is_a_class && !member_accessibilities.empty()) { + // This is a class and all members that didn't have their access + // specified are private. + m_ast.SetDefaultAccessForRecordFields( + m_ast.GetAsRecordDecl(clang_type), eAccessPrivate, + &member_accessibilities.front(), member_accessibilities.size()); + } + + 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.TransferBaseClasses() + for (const auto &base_class : bases) { + clang::TypeSourceInfo *type_source_info = + base_class->getTypeSourceInfo(); + if (type_source_info) + CompleteType(m_ast.GetType(type_source_info->getType())); } - 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.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.GetType(type_source_info->getType()); - 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.", - die.GetName(), - base_class_type.GetTypeName().GetCString()); - if (die.GetCU()->GetProducer() == eProducerClang) - module->ReportError(":: Try compiling the source file with " - "-fstandalone-debug."); - - // 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.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. - if (ClangASTContext::StartTagDeclarationDefinition( - base_class_type)) { - ClangASTContext::CompleteTagDeclarationDefinition( - base_class_type); - } - } - } - } - - m_ast.TransferBaseClasses(clang_type.GetOpaqueQualType(), - std::move(bases)); - } + m_ast.TransferBaseClasses(clang_type.GetOpaqueQualType(), + std::move(bases)); } } m_ast.AddMethodOverridesForCXXRecordType(clang_type.GetOpaqueQualType()); - ClangASTContext::BuildIndirectFields(clang_type); - ClangASTContext::CompleteTagDeclarationDefinition(clang_type); + TypeSystemClang::BuildIndirectFields(clang_type); + TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); if (!layout_info.field_offsets.empty() || !layout_info.base_offsets.empty() || !layout_info.vbase_offsets.empty()) { @@ -2115,14 +2074,14 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die, bool DWARFASTParserClang::CompleteEnumType(const DWARFDIE &die, lldb_private::Type *type, CompilerType &clang_type) { - if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) { + if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) { if (die.HasChildren()) { bool is_signed = false; clang_type.IsIntegerType(is_signed); ParseChildEnumerators(clang_type, is_signed, type->GetByteSize().getValueOr(0), die); } - ClangASTContext::CompleteTagDeclarationDefinition(clang_type); + TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); } return (bool)clang_type; } @@ -2182,7 +2141,7 @@ void DWARFASTParserClang::EnsureAllDIEsInDeclContextHaveBeenParsed( CompilerDecl DWARFASTParserClang::GetDeclForUIDFromDWARF(const DWARFDIE &die) { clang::Decl *clang_decl = GetClangDeclForDIE(die); if (clang_decl != nullptr) - return CompilerDecl(&m_ast, clang_decl); + return m_ast.GetCompilerDecl(clang_decl); return CompilerDecl(); } @@ -2311,9 +2270,11 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, func_name.SetValue(ConstString(mangled), true); else if ((die.GetParent().Tag() == DW_TAG_compile_unit || die.GetParent().Tag() == DW_TAG_partial_unit) && - Language::LanguageIsCPlusPlus(die.GetLanguage()) && - !Language::LanguageIsObjC(die.GetLanguage()) && name && - strcmp(name, "main") != 0) { + Language::LanguageIsCPlusPlus( + SymbolFileDWARF::GetLanguage(*die.GetCU())) && + !Language::LanguageIsObjC( + SymbolFileDWARF::GetLanguage(*die.GetCU())) && + name && strcmp(name, "main") != 0) { // If the mangled name is not present in the DWARF, generate the // demangled name using the decl context. We skip if the function is // "main" as its name is never mangled. @@ -2323,10 +2284,9 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, unsigned type_quals = 0; std::vector param_types; std::vector param_decls; - DWARFDeclContext decl_ctx; StreamString sstr; - die.GetDWARFDeclContext(decl_ctx); + DWARFDeclContext decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die); sstr << decl_ctx.GetQualifiedName(); clang::DeclContext *containing_decl_ctx = @@ -2353,8 +2313,8 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, FunctionSP func_sp; std::unique_ptr decl_up; if (decl_file != 0 || decl_line != 0 || decl_column != 0) - decl_up.reset(new Declaration(die.GetCU()->GetFile(decl_file), - decl_line, decl_column)); + decl_up = std::make_unique(die.GetCU()->GetFile(decl_file), + decl_line, decl_column); SymbolFileDWARF *dwarf = die.GetDWARF(); // Supply the type _only_ if it has already been parsed @@ -2384,10 +2344,9 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, void DWARFASTParserClang::ParseSingleMember( const DWARFDIE &die, const DWARFDIE &parent_die, - lldb_private::CompilerType &class_clang_type, - const lldb::LanguageType class_language, + const lldb_private::CompilerType &class_clang_type, std::vector &member_accessibilities, - lldb::AccessType &default_accessibility, + lldb::AccessType default_accessibility, DelayedPropertyList &delayed_properties, lldb_private::ClangASTImporter::LayoutInfo &layout_info, FieldInfo &last_field_info) { @@ -2401,426 +2360,400 @@ void DWARFASTParserClang::ParseSingleMember( DWARFAttributes attributes; const size_t num_attributes = die.GetAttributes(attributes); - if (num_attributes > 0) { - const char *name = nullptr; - const char *prop_name = nullptr; - const char *prop_getter_name = nullptr; - const char *prop_setter_name = nullptr; - uint32_t prop_attributes = 0; - - bool is_artificial = false; - DWARFFormValue encoding_form; - AccessType accessibility = eAccessNone; - uint32_t member_byte_offset = - (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX; - llvm::Optional byte_size; - int64_t bit_offset = 0; - uint64_t data_bit_offset = UINT64_MAX; - size_t bit_size = 0; - bool is_external = - false; // On DW_TAG_members, this means the member is static - uint32_t i; - for (i = 0; i < num_attributes && !is_artificial; ++i) { - const dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - // DW_AT_data_member_location indicates the byte offset of the - // word from the base address of the structure. - // - // DW_AT_bit_offset indicates how many bits into the word - // (according to the host endianness) the low-order bit of the - // field starts. AT_bit_offset can be negative. - // - // DW_AT_bit_size indicates the size of the field in bits. - switch (attr) { - case DW_AT_name: - name = form_value.AsCString(); - break; - case DW_AT_type: - encoding_form = form_value; - break; - case DW_AT_bit_offset: - bit_offset = form_value.Signed(); - break; - case DW_AT_bit_size: - bit_size = form_value.Unsigned(); - break; - case DW_AT_byte_size: - byte_size = form_value.Unsigned(); - break; - case DW_AT_data_bit_offset: - data_bit_offset = form_value.Unsigned(); - 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( - nullptr, // ExecutionContext * - nullptr, // RegisterContext * - module_sp, - DataExtractor(debug_info_data, block_offset, block_length), - die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr, - memberOffset, nullptr)) { - member_byte_offset = memberOffset.ResolveValue(nullptr).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(); + if (num_attributes == 0) + return; + + const char *name = nullptr; + const char *prop_name = nullptr; + const char *prop_getter_name = nullptr; + const char *prop_setter_name = nullptr; + uint32_t prop_attributes = 0; + + bool is_artificial = false; + DWARFFormValue encoding_form; + AccessType accessibility = eAccessNone; + uint32_t member_byte_offset = + (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX; + llvm::Optional byte_size; + int64_t bit_offset = 0; + uint64_t data_bit_offset = UINT64_MAX; + size_t bit_size = 0; + bool is_external = + false; // On DW_TAG_members, this means the member is static + uint32_t i; + for (i = 0; i < num_attributes && !is_artificial; ++i) { + const dw_attr_t attr = attributes.AttributeAtIndex(i); + DWARFFormValue form_value; + if (attributes.ExtractFormValueAtIndex(i, form_value)) { + // DW_AT_data_member_location indicates the byte offset of the + // word from the base address of the structure. + // + // DW_AT_bit_offset indicates how many bits into the word + // (according to the host endianness) the low-order bit of the + // field starts. AT_bit_offset can be negative. + // + // DW_AT_bit_size indicates the size of the field in bits. + switch (attr) { + case DW_AT_name: + name = form_value.AsCString(); + break; + case DW_AT_type: + encoding_form = form_value; + break; + case DW_AT_bit_offset: + bit_offset = form_value.Signed(); + break; + case DW_AT_bit_size: + bit_size = form_value.Unsigned(); + break; + case DW_AT_byte_size: + byte_size = form_value.Unsigned(); + break; + case DW_AT_data_bit_offset: + data_bit_offset = form_value.Unsigned(); + 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( + nullptr, // ExecutionContext * + nullptr, // RegisterContext * + module_sp, + DataExtractor(debug_info_data, block_offset, block_length), + die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr, + memberOffset, nullptr)) { + member_byte_offset = memberOffset.ResolveValue(nullptr).UInt(); } - break; + } 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; - case DW_AT_accessibility: - accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); - break; - case DW_AT_artificial: - is_artificial = form_value.Boolean(); - break; - case DW_AT_APPLE_property_name: - prop_name = form_value.AsCString(); - break; - case DW_AT_APPLE_property_getter: - prop_getter_name = form_value.AsCString(); - break; - case DW_AT_APPLE_property_setter: - prop_setter_name = form_value.AsCString(); - break; - case DW_AT_APPLE_property_attribute: - prop_attributes = form_value.Unsigned(); - break; - case DW_AT_external: - is_external = form_value.Boolean(); - break; + case DW_AT_accessibility: + accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); + break; + case DW_AT_artificial: + is_artificial = form_value.Boolean(); + break; + case DW_AT_APPLE_property_name: + prop_name = form_value.AsCString(); + break; + case DW_AT_APPLE_property_getter: + prop_getter_name = form_value.AsCString(); + break; + case DW_AT_APPLE_property_setter: + prop_setter_name = form_value.AsCString(); + break; + case DW_AT_APPLE_property_attribute: + prop_attributes = form_value.Unsigned(); + break; + case DW_AT_external: + is_external = form_value.Boolean(); + break; - default: - case DW_AT_declaration: - case DW_AT_description: - case DW_AT_mutable: - case DW_AT_visibility: - case DW_AT_sibling: - break; - } + default: + case DW_AT_declaration: + case DW_AT_description: + case DW_AT_mutable: + case DW_AT_visibility: + case DW_AT_sibling: + break; } } + } - if (prop_name) { - ConstString fixed_setter; + if (prop_name) { + ConstString fixed_setter; - // Check if the property getter/setter were provided as full names. - // We want basenames, so we extract them. + // Check if the property getter/setter were provided as full names. + // We want basenames, so we extract them. - if (prop_getter_name && prop_getter_name[0] == '-') { - ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true); - prop_getter_name = prop_getter_method.GetSelector().GetCString(); - } + if (prop_getter_name && prop_getter_name[0] == '-') { + ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true); + prop_getter_name = prop_getter_method.GetSelector().GetCString(); + } - if (prop_setter_name && prop_setter_name[0] == '-') { - ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true); - prop_setter_name = prop_setter_method.GetSelector().GetCString(); - } + if (prop_setter_name && prop_setter_name[0] == '-') { + ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true); + prop_setter_name = prop_setter_method.GetSelector().GetCString(); + } - // If the names haven't been provided, they need to be filled in. + // If the names haven't been provided, they need to be filled in. - if (!prop_getter_name) { - prop_getter_name = prop_name; - } - if (!prop_setter_name && prop_name[0] && - !(prop_attributes & DW_APPLE_PROPERTY_readonly)) { - StreamString ss; + if (!prop_getter_name) { + prop_getter_name = prop_name; + } + if (!prop_setter_name && prop_name[0] && + !(prop_attributes & DW_APPLE_PROPERTY_readonly)) { + StreamString ss; - ss.Printf("set%c%s:", toupper(prop_name[0]), &prop_name[1]); + ss.Printf("set%c%s:", toupper(prop_name[0]), &prop_name[1]); - fixed_setter.SetString(ss.GetString()); - prop_setter_name = fixed_setter.GetCString(); - } + fixed_setter.SetString(ss.GetString()); + prop_setter_name = fixed_setter.GetCString(); } + } - // Clang has a DWARF generation bug where sometimes it represents - // fields that are references with bad byte size and bit size/offset - // information such as: - // - // DW_AT_byte_size( 0x00 ) - // DW_AT_bit_size( 0x40 ) - // DW_AT_bit_offset( 0xffffffffffffffc0 ) - // - // So check the bit offset to make sure it is sane, and if the values - // are not sane, remove them. If we don't do this then we will end up - // with a crash if we try to use this type in an expression when clang - // becomes unhappy with its recycled debug info. + // Clang has a DWARF generation bug where sometimes it represents + // fields that are references with bad byte size and bit size/offset + // information such as: + // + // DW_AT_byte_size( 0x00 ) + // DW_AT_bit_size( 0x40 ) + // DW_AT_bit_offset( 0xffffffffffffffc0 ) + // + // So check the bit offset to make sure it is sane, and if the values + // are not sane, remove them. If we don't do this then we will end up + // with a crash if we try to use this type in an expression when clang + // becomes unhappy with its recycled debug info. - if (byte_size.getValueOr(0) == 0 && bit_offset < 0) { - bit_size = 0; - bit_offset = 0; - } + if (byte_size.getValueOr(0) == 0 && bit_offset < 0) { + bit_size = 0; + bit_offset = 0; + } - // FIXME: Make Clang ignore Objective-C accessibility for expressions - if (class_language == eLanguageTypeObjC || - class_language == eLanguageTypeObjC_plus_plus) - accessibility = eAccessNone; + const bool class_is_objc_object_or_interface = + TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type); - // Handle static members - if (is_external && member_byte_offset == UINT32_MAX) { - Type *var_type = die.ResolveTypeUID(encoding_form.Reference()); + // FIXME: Make Clang ignore Objective-C accessibility for expressions + if (class_is_objc_object_or_interface) + accessibility = eAccessNone; - if (var_type) { - if (accessibility == eAccessNone) - accessibility = eAccessPublic; - ClangASTContext::AddVariableToRecordType( - class_clang_type, name, var_type->GetLayoutCompilerType(), - accessibility); - } - return; + // Handle static members + if (is_external && member_byte_offset == UINT32_MAX) { + Type *var_type = die.ResolveTypeUID(encoding_form.Reference()); + + if (var_type) { + if (accessibility == eAccessNone) + accessibility = eAccessPublic; + TypeSystemClang::AddVariableToRecordType( + class_clang_type, name, var_type->GetLayoutCompilerType(), + accessibility); } + return; + } + + if (!is_artificial) { + Type *member_type = die.ResolveTypeUID(encoding_form.Reference()); - if (!is_artificial) { - Type *member_type = die.ResolveTypeUID(encoding_form.Reference()); + clang::FieldDecl *field_decl = nullptr; + const uint64_t character_width = 8; + const uint64_t word_width = 32; + if (tag == DW_TAG_member) { + if (member_type) { + CompilerType member_clang_type = member_type->GetLayoutCompilerType(); - clang::FieldDecl *field_decl = nullptr; - const uint64_t character_width = 8; - const uint64_t word_width = 32; - if (tag == DW_TAG_member) { - if (member_type) { - CompilerType member_clang_type = member_type->GetLayoutCompilerType(); + if (accessibility == eAccessNone) + accessibility = default_accessibility; + member_accessibilities.push_back(accessibility); - if (accessibility == eAccessNone) - accessibility = default_accessibility; - member_accessibilities.push_back(accessibility); + uint64_t field_bit_offset = + (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8)); - uint64_t field_bit_offset = - (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8)); + if (bit_size > 0) { + FieldInfo this_field_info; + this_field_info.bit_offset = field_bit_offset; + this_field_info.bit_size = bit_size; - if (bit_size > 0) { - FieldInfo this_field_info; - this_field_info.bit_offset = field_bit_offset; - this_field_info.bit_size = bit_size; + if (data_bit_offset != UINT64_MAX) { + this_field_info.bit_offset = data_bit_offset; + } else { + if (!byte_size) + byte_size = member_type->GetByteSize(); - if (data_bit_offset != UINT64_MAX) { - this_field_info.bit_offset = data_bit_offset; + ObjectFile *objfile = die.GetDWARF()->GetObjectFile(); + if (objfile->GetByteOrder() == eByteOrderLittle) { + this_field_info.bit_offset += byte_size.getValueOr(0) * 8; + this_field_info.bit_offset -= (bit_offset + bit_size); } else { - if (!byte_size) - byte_size = member_type->GetByteSize(); - - ObjectFile *objfile = die.GetDWARF()->GetObjectFile(); - if (objfile->GetByteOrder() == eByteOrderLittle) { - this_field_info.bit_offset += byte_size.getValueOr(0) * 8; - this_field_info.bit_offset -= (bit_offset + bit_size); - } else { - this_field_info.bit_offset += bit_offset; - } + this_field_info.bit_offset += bit_offset; } + } - if ((this_field_info.bit_offset >= parent_bit_size) || - (last_field_info.IsBitfield() && - !last_field_info.NextBitfieldOffsetIsValid( - this_field_info.bit_offset))) { - ObjectFile *objfile = die.GetDWARF()->GetObjectFile(); - objfile->GetModule()->ReportWarning( - "0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid " - "bit offset (0x%8.8" PRIx64 - ") member will be ignored. Please file a bug against the " - "compiler and include the preprocessed output for %s\n", - die.GetID(), DW_TAG_value_to_name(tag), name, - this_field_info.bit_offset, GetUnitName(parent_die).c_str()); - return; - } + if ((this_field_info.bit_offset >= parent_bit_size) || + (last_field_info.IsBitfield() && + !last_field_info.NextBitfieldOffsetIsValid( + this_field_info.bit_offset))) { + ObjectFile *objfile = die.GetDWARF()->GetObjectFile(); + objfile->GetModule()->ReportWarning( + "0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid " + "bit offset (0x%8.8" PRIx64 + ") member will be ignored. Please file a bug against the " + "compiler and include the preprocessed output for %s\n", + die.GetID(), DW_TAG_value_to_name(tag), name, + this_field_info.bit_offset, GetUnitName(parent_die).c_str()); + return; + } - // Update the field bit offset we will report for layout - field_bit_offset = this_field_info.bit_offset; - - // Objective-C has invalid DW_AT_bit_offset values in older - // versions of clang, so we have to be careful and only insert - // unnamed bitfields if we have a new enough clang. - bool detect_unnamed_bitfields = true; - - if (class_language == eLanguageTypeObjC || - class_language == eLanguageTypeObjC_plus_plus) - detect_unnamed_bitfields = - die.GetCU()->Supports_unnamed_objc_bitfields(); - - if (detect_unnamed_bitfields) { - clang::Optional unnamed_field_info; - uint64_t last_field_end = 0; - - last_field_end = - last_field_info.bit_offset + last_field_info.bit_size; - - if (!last_field_info.IsBitfield()) { - // The last field was not a bit-field... - // but if it did take up the entire word then we need to extend - // last_field_end so the bit-field does not step into the last - // fields padding. - if (last_field_end != 0 && ((last_field_end % word_width) != 0)) - last_field_end += word_width - (last_field_end % word_width); - } + // Update the field bit offset we will report for layout + field_bit_offset = this_field_info.bit_offset; - // If we have a gap between the last_field_end and the current - // field we have an unnamed bit-field - if (this_field_info.bit_offset != last_field_end && - !(this_field_info.bit_offset < last_field_end)) { - unnamed_field_info = FieldInfo{}; - unnamed_field_info->bit_size = - this_field_info.bit_offset - last_field_end; - unnamed_field_info->bit_offset = last_field_end; - } + // Objective-C has invalid DW_AT_bit_offset values in older + // versions of clang, so we have to be careful and only insert + // unnamed bitfields if we have a new enough clang. + bool detect_unnamed_bitfields = true; - if (unnamed_field_info) { - clang::FieldDecl *unnamed_bitfield_decl = - ClangASTContext::AddFieldToRecordType( - class_clang_type, llvm::StringRef(), - m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, - word_width), - accessibility, unnamed_field_info->bit_size); + if (class_is_objc_object_or_interface) + detect_unnamed_bitfields = + die.GetCU()->Supports_unnamed_objc_bitfields(); - layout_info.field_offsets.insert(std::make_pair( - unnamed_bitfield_decl, unnamed_field_info->bit_offset)); - } + if (detect_unnamed_bitfields) { + clang::Optional unnamed_field_info; + uint64_t last_field_end = 0; + + last_field_end = + last_field_info.bit_offset + last_field_info.bit_size; + + if (!last_field_info.IsBitfield()) { + // The last field was not a bit-field... + // but if it did take up the entire word then we need to extend + // last_field_end so the bit-field does not step into the last + // fields padding. + if (last_field_end != 0 && ((last_field_end % word_width) != 0)) + last_field_end += word_width - (last_field_end % word_width); } - last_field_info = this_field_info; - last_field_info.SetIsBitfield(true); - } else { - last_field_info.bit_offset = field_bit_offset; + // If we have a gap between the last_field_end and the current + // field we have an unnamed bit-field. + // If we have a base class, we assume there is no unnamed + // bit-field if this is the first field since the gap can be + // attributed to the members from the base class. This assumption + // is not correct if the first field of the derived class is + // indeed an unnamed bit-field. We currently do not have the + // machinary to track the offset of the last field of classes we + // have seen before, so we are not handling this case. + if (this_field_info.bit_offset != last_field_end && + this_field_info.bit_offset > last_field_end && + !(last_field_info.bit_offset == 0 && + last_field_info.bit_size == 0 && + layout_info.base_offsets.size() != 0)) { + unnamed_field_info = FieldInfo{}; + unnamed_field_info->bit_size = + this_field_info.bit_offset - last_field_end; + unnamed_field_info->bit_offset = last_field_end; + } - if (llvm::Optional clang_type_size = - member_clang_type.GetByteSize(nullptr)) { - last_field_info.bit_size = *clang_type_size * character_width; + if (unnamed_field_info) { + clang::FieldDecl *unnamed_bitfield_decl = + TypeSystemClang::AddFieldToRecordType( + class_clang_type, llvm::StringRef(), + m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, + word_width), + accessibility, unnamed_field_info->bit_size); + + layout_info.field_offsets.insert(std::make_pair( + unnamed_bitfield_decl, unnamed_field_info->bit_offset)); } + } + + last_field_info = this_field_info; + last_field_info.SetIsBitfield(true); + } else { + last_field_info.bit_offset = field_bit_offset; - last_field_info.SetIsBitfield(false); + if (llvm::Optional clang_type_size = + member_clang_type.GetByteSize(nullptr)) { + last_field_info.bit_size = *clang_type_size * character_width; } - if (!member_clang_type.IsCompleteType()) - member_clang_type.GetCompleteType(); - - { - // Older versions of clang emit array[0] and array[1] in the - // same way (). If the current field - // is at the end of the structure, then there is definitely no - // room for extra elements and we override the type to - // array[0]. - - CompilerType member_array_element_type; - uint64_t member_array_size; - bool member_array_is_incomplete; - - if (member_clang_type.IsArrayType(&member_array_element_type, - &member_array_size, - &member_array_is_incomplete) && - !member_array_is_incomplete) { - uint64_t parent_byte_size = - parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, - UINT64_MAX); - - if (member_byte_offset >= parent_byte_size) { - if (member_array_size != 1 && - (member_array_size != 0 || - member_byte_offset > parent_byte_size)) { - module_sp->ReportError( - "0x%8.8" PRIx64 - ": DW_TAG_member '%s' refers to type 0x%8.8x" - " which extends beyond the bounds of 0x%8.8" PRIx64, - die.GetID(), name, encoding_form.Reference().GetOffset(), - parent_die.GetID()); - } + last_field_info.SetIsBitfield(false); + } - member_clang_type = - m_ast.CreateArrayType(member_array_element_type, 0, false); + if (!member_clang_type.IsCompleteType()) + member_clang_type.GetCompleteType(); + + { + // Older versions of clang emit array[0] and array[1] in the + // same way (). If the current field + // is at the end of the structure, then there is definitely no + // room for extra elements and we override the type to + // array[0]. + + CompilerType member_array_element_type; + uint64_t member_array_size; + bool member_array_is_incomplete; + + if (member_clang_type.IsArrayType(&member_array_element_type, + &member_array_size, + &member_array_is_incomplete) && + !member_array_is_incomplete) { + uint64_t parent_byte_size = + parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, + UINT64_MAX); + + if (member_byte_offset >= parent_byte_size) { + if (member_array_size != 1 && + (member_array_size != 0 || + member_byte_offset > parent_byte_size)) { + module_sp->ReportError( + "0x%8.8" PRIx64 + ": DW_TAG_member '%s' refers to type 0x%8.8x" + " which extends beyond the bounds of 0x%8.8" PRIx64, + die.GetID(), name, encoding_form.Reference().GetOffset(), + parent_die.GetID()); } - } - } - if (ClangASTContext::IsCXXClassType(member_clang_type) && - !member_clang_type.GetCompleteType()) { - if (die.GetCU()->GetProducer() == eProducerClang) - module_sp->ReportError( - "DWARF DIE at 0x%8.8x (class %s) has a member variable " - "0x%8.8x (%s) whose type is a forward declaration, not a " - "complete definition.\nTry compiling the source file " - "with -fstandalone-debug", - parent_die.GetOffset(), parent_die.GetName(), die.GetOffset(), - name); - else - module_sp->ReportError( - "DWARF DIE at 0x%8.8x (class %s) has a member variable " - "0x%8.8x (%s) whose type is a forward declaration, not a " - "complete definition.\nPlease file a bug against the " - "compiler and include the preprocessed output for %s", - parent_die.GetOffset(), parent_die.GetName(), die.GetOffset(), - name, GetUnitName(parent_die).c_str()); - // We have no choice other than to pretend that the member - // class is complete. If we don't do this, clang will crash - // when trying to layout the class. 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. - if (ClangASTContext::StartTagDeclarationDefinition( - member_clang_type)) { - ClangASTContext::CompleteTagDeclarationDefinition( - member_clang_type); - } else { - module_sp->ReportError( - "DWARF DIE at 0x%8.8x (class %s) has a member variable " - "0x%8.8x (%s) whose type claims to be a C++ class but we " - "were not able to start its definition.\nPlease file a " - "bug and attach the file at the start of this error " - "message", - parent_die.GetOffset(), parent_die.GetName(), die.GetOffset(), - name); + member_clang_type = + m_ast.CreateArrayType(member_array_element_type, 0, false); } } + } - field_decl = ClangASTContext::AddFieldToRecordType( - class_clang_type, name, member_clang_type, accessibility, - bit_size); + CompleteType(member_clang_type); - m_ast.SetMetadataAsUserID(field_decl, die.GetID()); + field_decl = TypeSystemClang::AddFieldToRecordType( + class_clang_type, name, member_clang_type, accessibility, + bit_size); - layout_info.field_offsets.insert( - std::make_pair(field_decl, field_bit_offset)); - } else { - if (name) - module_sp->ReportError( - "0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8x" - " which was unable to be parsed", - die.GetID(), name, encoding_form.Reference().GetOffset()); - else - module_sp->ReportError( - "0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8x" - " which was unable to be parsed", - die.GetID(), encoding_form.Reference().GetOffset()); - } + m_ast.SetMetadataAsUserID(field_decl, die.GetID()); + + layout_info.field_offsets.insert( + std::make_pair(field_decl, field_bit_offset)); + } else { + if (name) + module_sp->ReportError( + "0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8x" + " which was unable to be parsed", + die.GetID(), name, encoding_form.Reference().GetOffset()); + else + module_sp->ReportError( + "0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8x" + " which was unable to be parsed", + die.GetID(), encoding_form.Reference().GetOffset()); } + } - if (prop_name != nullptr && member_type) { - clang::ObjCIvarDecl *ivar_decl = nullptr; + if (prop_name != nullptr && member_type) { + clang::ObjCIvarDecl *ivar_decl = nullptr; - if (field_decl) { - ivar_decl = clang::dyn_cast(field_decl); - assert(ivar_decl != nullptr); - } + if (field_decl) { + ivar_decl = clang::dyn_cast(field_decl); + assert(ivar_decl != nullptr); + } - ClangASTMetadata metadata; - metadata.SetUserID(die.GetID()); - delayed_properties.push_back(DelayedAddObjCClassProperty( - class_clang_type, prop_name, member_type->GetLayoutCompilerType(), - ivar_decl, prop_setter_name, prop_getter_name, prop_attributes, - &metadata)); + ClangASTMetadata metadata; + metadata.SetUserID(die.GetID()); + delayed_properties.push_back(DelayedAddObjCClassProperty( + class_clang_type, prop_name, member_type->GetLayoutCompilerType(), + ivar_decl, prop_setter_name, prop_getter_name, prop_attributes, + &metadata)); - if (ivar_decl) - m_ast.SetMetadataAsUserID(ivar_decl, die.GetID()); - } + if (ivar_decl) + m_ast.SetMetadataAsUserID(ivar_decl, die.GetID()); } } } bool DWARFASTParserClang::ParseChildMembers( const DWARFDIE &parent_die, CompilerType &class_clang_type, - const LanguageType class_language, std::vector> &base_classes, std::vector &member_accessibilities, std::vector &member_function_dies, @@ -2832,8 +2765,8 @@ bool DWARFASTParserClang::ParseChildMembers( FieldInfo last_field_info; ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule(); - ClangASTContext *ast = - llvm::dyn_cast_or_null(class_clang_type.GetTypeSystem()); + TypeSystemClang *ast = + llvm::dyn_cast_or_null(class_clang_type.GetTypeSystem()); if (ast == nullptr) return false; @@ -2844,7 +2777,7 @@ bool DWARFASTParserClang::ParseChildMembers( switch (tag) { case DW_TAG_member: case DW_TAG_APPLE_property: - ParseSingleMember(die, parent_die, class_clang_type, class_language, + ParseSingleMember(die, parent_die, class_clang_type, member_accessibilities, default_accessibility, delayed_properties, layout_info, last_field_info); break; @@ -2934,7 +2867,7 @@ bool DWARFASTParserClang::ParseChildMembers( CompilerType base_class_clang_type = base_class_type->GetFullCompilerType(); assert(base_class_clang_type); - if (class_language == eLanguageTypeObjC) { + if (TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type)) { ast->SetObjCSuperClass(class_clang_type, base_class_clang_type); } else { std::unique_ptr result = @@ -3065,9 +2998,9 @@ size_t DWARFASTParserClang::ParseChildParameters( function_param_types.push_back(type->GetForwardCompilerType()); clang::ParmVarDecl *param_var_decl = - m_ast.CreateParameterDeclaration(containing_decl_ctx, name, - type->GetForwardCompilerType(), - storage); + m_ast.CreateParameterDeclaration( + containing_decl_ctx, GetOwningClangModule(die), name, + type->GetForwardCompilerType(), storage); assert(param_var_decl); function_param_decls.push_back(param_var_decl); @@ -3262,10 +3195,10 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) { if (dwarf && type) { const char *name = die.GetName(); clang::DeclContext *decl_context = - ClangASTContext::DeclContextGetAsDeclContext( + TypeSystemClang::DeclContextGetAsDeclContext( dwarf->GetDeclContextContainingUID(die.GetID())); decl = m_ast.CreateVariableDeclaration( - decl_context, name, + decl_context, GetOwningClangModule(die), name, ClangUtil::GetQualType(type->GetForwardCompilerType())); } break; @@ -3274,16 +3207,16 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) { SymbolFileDWARF *dwarf = die.GetDWARF(); DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import); if (imported_uid) { - CompilerDecl imported_decl = imported_uid.GetDecl(); + CompilerDecl imported_decl = SymbolFileDWARF::GetDecl(imported_uid); if (imported_decl) { clang::DeclContext *decl_context = - ClangASTContext::DeclContextGetAsDeclContext( + TypeSystemClang::DeclContextGetAsDeclContext( dwarf->GetDeclContextContainingUID(die.GetID())); if (clang::NamedDecl *clang_imported_decl = llvm::dyn_cast( (clang::Decl *)imported_decl.GetOpaqueDecl())) - decl = - m_ast.CreateUsingDeclaration(decl_context, clang_imported_decl); + decl = m_ast.CreateUsingDeclaration( + decl_context, OptionalClangModuleID(), clang_imported_decl); } } break; @@ -3293,15 +3226,17 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) { DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import); if (imported_uid) { - CompilerDeclContext imported_decl_ctx = imported_uid.GetDeclContext(); + CompilerDeclContext imported_decl_ctx = + SymbolFileDWARF::GetDeclContext(imported_uid); if (imported_decl_ctx) { clang::DeclContext *decl_context = - ClangASTContext::DeclContextGetAsDeclContext( + TypeSystemClang::DeclContextGetAsDeclContext( dwarf->GetDeclContextContainingUID(die.GetID())); if (clang::NamespaceDecl *ns_decl = - ClangASTContext::DeclContextGetAsNamespaceDecl( + TypeSystemClang::DeclContextGetAsNamespaceDecl( imported_decl_ctx)) - decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl); + decl = m_ast.CreateUsingDirectiveDeclaration( + decl_context, OptionalClangModuleID(), ns_decl); } } break; @@ -3359,6 +3294,32 @@ DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) { return nullptr; } +OptionalClangModuleID +DWARFASTParserClang::GetOwningClangModule(const DWARFDIE &die) { + if (!die.IsValid()) + return {}; + + for (DWARFDIE parent = die.GetParent(); parent.IsValid(); + parent = parent.GetParent()) { + const dw_tag_t tag = parent.Tag(); + if (tag == DW_TAG_module) { + DWARFDIE module_die = parent; + auto it = m_die_to_module.find(module_die.GetDIE()); + if (it != m_die_to_module.end()) + return it->second; + const char *name = module_die.GetAttributeValueAsString(DW_AT_name, 0); + if (!name) + return {}; + + OptionalClangModuleID id = + m_ast.GetOrCreateClangModule(name, GetOwningClangModule(module_die)); + m_die_to_module.insert({module_die.GetDIE(), id}); + return id; + } + } + return {}; +} + static bool IsSubroutine(const DWARFDIE &die) { switch (die.Tag()) { case DW_TAG_subprogram: @@ -3431,7 +3392,8 @@ clang::BlockDecl *DWARFASTParserClang::ResolveBlockDIE(const DWARFDIE &die) { DWARFDIE decl_context_die; clang::DeclContext *decl_context = GetClangDeclContextContainingDIE(die, &decl_context_die); - decl = m_ast.CreateBlockDeclaration(decl_context); + decl = + m_ast.CreateBlockDeclaration(decl_context, GetOwningClangModule(die)); if (decl) LinkDeclContextToDIE((clang::DeclContext *)decl, die); @@ -3459,7 +3421,8 @@ DWARFASTParserClang::ResolveNamespaceDIE(const DWARFDIE &die) { die.GetAttributeValueAsUnsigned(DW_AT_export_symbols, 0) != 0; namespace_decl = m_ast.GetUniqueNamespaceDeclaration( - namespace_name, containing_decl_ctx, is_inline); + namespace_name, containing_decl_ctx, GetOwningClangModule(die), + is_inline); Log *log = nullptr; // (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); if (log) { @@ -3641,9 +3604,11 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( } DWARFASTParserClang *src_dwarf_ast_parser = - (DWARFASTParserClang *)src_die.GetDWARFParser(); + static_cast( + SymbolFileDWARF::GetDWARFParser(*src_die.GetCU())); DWARFASTParserClang *dst_dwarf_ast_parser = - (DWARFASTParserClang *)dst_die.GetDWARFParser(); + static_cast( + SymbolFileDWARF::GetDWARFParser(*dst_die.GetCU())); // Now do the work of linking the DeclContexts and Types. if (fast_path) { diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index 8a78299c8b1..2ef49abc1da 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFASTParserClang_h_ -#define SymbolFileDWARF_DWARFASTParserClang_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERCLANG_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERCLANG_H #include "clang/AST/CharUnits.h" #include "llvm/ADT/DenseMap.h" @@ -19,10 +19,10 @@ #include "DWARFDefines.h" #include "DWARFFormValue.h" #include "LogChannelDWARF.h" -#include "lldb/Core/ClangForward.h" #include "lldb/Core/PluginInterface.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangASTImporter.h" + +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include @@ -36,7 +36,7 @@ struct ParsedDWARFTypeAttributes; class DWARFASTParserClang : public DWARFASTParser { public: - DWARFASTParserClang(lldb_private::ClangASTContext &ast); + DWARFASTParserClang(lldb_private::TypeSystemClang &ast); ~DWARFASTParserClang() override; @@ -78,15 +78,19 @@ protected: DIEToDeclContextMap; typedef std::multimap DeclContextToDIEMap; + typedef llvm::DenseMap + DIEToModuleMap; typedef llvm::DenseMap DIEToDeclMap; typedef llvm::DenseMap DeclToDIEMap; - lldb_private::ClangASTContext &m_ast; + lldb_private::TypeSystemClang &m_ast; DIEToDeclMap m_die_to_decl; DeclToDIEMap m_decl_to_die; DIEToDeclContextMap m_die_to_decl_ctx; DeclContextToDIEMap m_decl_ctx_to_die; + DIEToModuleMap m_die_to_module; std::unique_ptr m_clang_ast_importer_up; /// @} @@ -97,16 +101,15 @@ protected: clang::NamespaceDecl *ResolveNamespaceDIE(const DWARFDIE &die); bool ParseTemplateDIE(const DWARFDIE &die, - lldb_private::ClangASTContext::TemplateParameterInfos + lldb_private::TypeSystemClang::TemplateParameterInfos &template_param_infos); bool ParseTemplateParameterInfos( const DWARFDIE &parent_die, - lldb_private::ClangASTContext::TemplateParameterInfos + lldb_private::TypeSystemClang::TemplateParameterInfos &template_param_infos); bool ParseChildMembers( const DWARFDIE &die, lldb_private::CompilerType &class_compiler_type, - const lldb::LanguageType class_language, std::vector> &base_classes, std::vector &member_accessibilities, std::vector &member_function_dies, @@ -140,6 +143,7 @@ protected: clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die, DWARFDIE *decl_ctx_die); + lldb_private::OptionalClangModuleID GetOwningClangModule(const DWARFDIE &die); bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die, const DWARFDIE &dst_class_die, @@ -189,10 +193,9 @@ private: void ParseSingleMember(const DWARFDIE &die, const DWARFDIE &parent_die, - lldb_private::CompilerType &class_clang_type, - const lldb::LanguageType class_language, + const lldb_private::CompilerType &class_clang_type, std::vector &member_accessibilities, - lldb::AccessType &default_accessibility, + lldb::AccessType default_accessibility, DelayedPropertyList &delayed_properties, lldb_private::ClangASTImporter::LayoutInfo &layout_info, FieldInfo &last_field_info); @@ -214,6 +217,12 @@ private: ParsedDWARFTypeAttributes &attrs); lldb::TypeSP ParsePointerToMemberType(const DWARFDIE &die, const ParsedDWARFTypeAttributes &attrs); + + /// Complete a type from debug info, or mark it as forcefully completed if + /// there is no of the type in the current Module. Call this function in + /// contexts where the usual C++ rules require a type to be complete (base + /// class, member, etc.). + void CompleteType(lldb_private::CompilerType type); }; /// Parsed form of all attributes that are relevant for type reconstruction. @@ -251,4 +260,4 @@ struct ParsedDWARFTypeAttributes { uint32_t encoding = 0; }; -#endif // SymbolFileDWARF_DWARFASTParserClang_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERCLANG_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp index 741669b0575..0e9370be15f 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp @@ -1,4 +1,4 @@ -//===-- DWARFAbbreviationDeclaration.cpp ------------------------*- C++ -*-===// +//===-- DWARFAbbreviationDeclaration.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h index c0cf8823a36..f70aa71a595 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFAbbreviationDeclaration_h_ -#define liblldb_DWARFAbbreviationDeclaration_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFABBREVIATIONDECLARATION_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFABBREVIATIONDECLARATION_H #include "DWARFAttribute.h" #include "DWARFDefines.h" @@ -62,4 +62,4 @@ protected: DWARFAttribute::collection m_attributes; }; -#endif // liblldb_DWARFAbbreviationDeclaration_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFABBREVIATIONDECLARATION_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp index b3594a45568..6c72d9e2622 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp @@ -1,4 +1,4 @@ -//===-- DWARFAttribute.cpp --------------------------------------*- C++ -*-===// +//===-- DWARFAttribute.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h index 58427b19100..9948969f108 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFAttribute_h_ -#define SymbolFileDWARF_DWARFAttribute_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFATTRIBUTE_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFATTRIBUTE_H #include "DWARFDefines.h" #include "DWARFFormValue.h" @@ -82,4 +82,4 @@ protected: collection m_infos; }; -#endif // SymbolFileDWARF_DWARFAttribute_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFATTRIBUTE_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp index 033105efdc5..fcb424029f5 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp @@ -1,4 +1,4 @@ -//===-- DWARFBaseDIE.cpp ---------------------------------------*- C++ -*-===// +//===-- DWARFBaseDIE.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -74,13 +74,6 @@ const char *DWARFBaseDIE::GetName() const { return nullptr; } -lldb::LanguageType DWARFBaseDIE::GetLanguage() const { - if (IsValid()) - return m_cu->GetLanguageType(); - else - return lldb::eLanguageTypeUnknown; -} - lldb::ModuleSP DWARFBaseDIE::GetModule() const { SymbolFileDWARF *dwarf = GetDWARF(); if (dwarf) @@ -103,24 +96,6 @@ SymbolFileDWARF *DWARFBaseDIE::GetDWARF() const { return nullptr; } -llvm::Expected DWARFBaseDIE::GetTypeSystem() const { - if (!m_cu) - return llvm::make_error( - "Unable to get TypeSystem, no compilation unit available", - llvm::inconvertibleErrorCode()); - return m_cu->GetTypeSystem(); -} - -DWARFASTParser *DWARFBaseDIE::GetDWARFParser() const { - auto type_system_or_err = GetTypeSystem(); - if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to get DWARFASTParser"); - return nullptr; - } - return type_system_or_err->GetDWARFParser(); -} - bool DWARFBaseDIE::HasChildren() const { return m_die && m_die->HasChildren(); } @@ -130,11 +105,10 @@ bool DWARFBaseDIE::Supports_DW_AT_APPLE_objc_complete_type() const { } size_t DWARFBaseDIE::GetAttributes(DWARFAttributes &attributes, - uint32_t depth) const { + Recurse recurse) const { if (IsValid()) - return m_die->GetAttributes(m_cu, attributes, depth); - if (depth == 0) - attributes.Clear(); + return m_die->GetAttributes(m_cu, attributes, recurse); + attributes.Clear(); return 0; } diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h index 9652d7946e8..059b84864be 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFBaseDIE_h_ -#define SymbolFileDWARF_DWARFBaseDIE_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFBASEDIE_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFBASEDIE_H #include "lldb/Core/dwarf.h" #include "lldb/lldb-types.h" @@ -57,10 +57,6 @@ public: llvm::Optional GetDIERef() const; - llvm::Expected GetTypeSystem() const; - - DWARFASTParser *GetDWARFParser() const; - void Set(DWARFUnit *cu, DWARFDebugInfoEntry *die) { if (cu && die) { m_cu = cu; @@ -98,8 +94,6 @@ public: const char *GetName() const; - lldb::LanguageType GetLanguage() const; - lldb::ModuleSP GetModule() const; // Getting attribute values from the DIE. @@ -116,7 +110,9 @@ public: uint64_t GetAttributeValueAsAddress(const dw_attr_t attr, uint64_t fail_value) const; - size_t GetAttributes(DWARFAttributes &attributes, uint32_t depth = 0) const; + enum class Recurse : bool { no, yes }; + size_t GetAttributes(DWARFAttributes &attributes, + Recurse recurse = Recurse::yes) const; protected: DWARFUnit *m_cu; @@ -126,4 +122,4 @@ protected: bool operator==(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs); bool operator!=(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs); -#endif // SymbolFileDWARF_DWARFBaseDIE_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFBASEDIE_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index 718f0537d6e..f54fe0662aa 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -1,4 +1,4 @@ -//===-- DWARFCompileUnit.cpp ------------------------------------*- C++ -*-===// +//===-- DWARFCompileUnit.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -33,41 +33,27 @@ void DWARFCompileUnit::BuildAddressRangeTable( size_t num_debug_aranges = debug_aranges->GetNumRanges(); - // First get the compile unit DIE only and check if it has a DW_AT_ranges + // First get the compile unit DIE only and check contains ranges information. const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); const dw_offset_t cu_offset = GetOffset(); if (die) { DWARFRangeList ranges; const size_t num_ranges = - die->GetAttributeAddressRanges(this, ranges, false); + die->GetAttributeAddressRanges(this, ranges, /*check_hi_lo_pc=*/true); if (num_ranges > 0) { - // This compile unit has DW_AT_ranges, assume this is correct if it is - // present since clang no longer makes .debug_aranges by default and it - // emits DW_AT_ranges for DW_TAG_compile_units. GCC also does this with - // recent GCC builds. for (size_t i = 0; i < num_ranges; ++i) { const DWARFRangeList::Entry &range = ranges.GetEntryRef(i); debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), range.GetRangeEnd()); } - return; // We got all of our ranges from the DW_AT_ranges attribute + return; } } - // We don't have a DW_AT_ranges attribute, so we need to parse the DWARF - - // If the DIEs weren't parsed, then we don't want all dies for all compile - // units to stay loaded when they weren't needed. So we can end up parsing - // the DWARF and then throwing them all away to keep memory usage down. - ScopedExtractDIEs clear_dies(ExtractDIEsScoped()); - - die = DIEPtr(); - if (die) - die->BuildAddressRangeTable(this, debug_aranges); if (debug_aranges->GetNumRanges() == num_debug_aranges) { - // We got nothing from the functions, maybe we have a line tables only + // We got nothing from the debug info, maybe we have a line tables only // situation. Check the line tables and build the arange table from this. SymbolContext sc; sc.comp_unit = m_dwarf.GetCompUnitForDWARFCompUnit(*this); diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h index 454637ef981..3ec161f7dd5 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFCompileUnit_h_ -#define SymbolFileDWARF_DWARFCompileUnit_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFCOMPILEUNIT_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFCOMPILEUNIT_H #include "DWARFUnit.h" #include "llvm/Support/Error.h" @@ -27,9 +27,10 @@ private: DIERef::Section section, bool is_dwo) : DWARFUnit(dwarf, uid, header, abbrevs, section, is_dwo) {} - DISALLOW_COPY_AND_ASSIGN(DWARFCompileUnit); + DWARFCompileUnit(const DWARFCompileUnit &) = delete; + const DWARFCompileUnit &operator=(const DWARFCompileUnit &) = delete; friend class DWARFUnit; }; -#endif // SymbolFileDWARF_DWARFCompileUnit_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFCOMPILEUNIT_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp index 5052b825fea..37e28a09f3c 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp @@ -1,4 +1,4 @@ -//===-- DWARFContext.cpp ----------------------------------------*- C++ -*-===// +//===-- DWARFContext.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -28,18 +28,28 @@ static DWARFDataExtractor LoadSection(SectionList *section_list, } const DWARFDataExtractor & -DWARFContext::LoadOrGetSection(SectionType main_section_type, +DWARFContext::LoadOrGetSection(llvm::Optional main_section_type, llvm::Optional dwo_section_type, SectionData &data) { llvm::call_once(data.flag, [&] { if (dwo_section_type && isDwo()) data.data = LoadSection(m_dwo_section_list, *dwo_section_type); - else - data.data = LoadSection(m_main_section_list, main_section_type); + else if (main_section_type) + data.data = LoadSection(m_main_section_list, *main_section_type); }); return data.data; } +const DWARFDataExtractor &DWARFContext::getOrLoadCuIndexData() { + return LoadOrGetSection(llvm::None, eSectionTypeDWARFDebugCuIndex, + m_data_debug_cu_index); +} + +const DWARFDataExtractor &DWARFContext::getOrLoadTuIndexData() { + return LoadOrGetSection(llvm::None, eSectionTypeDWARFDebugTuIndex, + m_data_debug_tu_index); +} + const DWARFDataExtractor &DWARFContext::getOrLoadAbbrevData() { return LoadOrGetSection(eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAbbrevDwo, m_data_debug_abbrev); @@ -117,32 +127,19 @@ llvm::DWARFContext &DWARFContext::GetAsLLVM() { if (!m_llvm_context) { llvm::StringMap> section_map; uint8_t addr_size = 0; - - auto AddSection = [&](Section §ion) { - DataExtractor section_data; - section.GetSectionData(section_data); - + auto AddSection = [&](llvm::StringRef name, DWARFDataExtractor data) { // Set the address size the first time we see it. if (addr_size == 0) - addr_size = section_data.GetByteSize(); + addr_size = data.GetAddressByteSize(); - llvm::StringRef data = llvm::toStringRef(section_data.GetData()); - llvm::StringRef name = section.GetName().GetStringRef(); - if (name.startswith(".")) - name = name.drop_front(); section_map.try_emplace( - name, llvm::MemoryBuffer::getMemBuffer(data, name, false)); + name, llvm::MemoryBuffer::getMemBuffer(toStringRef(data.GetData()), + name, false)); }; - if (m_main_section_list) { - for (auto §ion : *m_main_section_list) - AddSection(*section); - } - - if (m_dwo_section_list) { - for (auto §ion : *m_dwo_section_list) - AddSection(*section); - } + AddSection("debug_line_str", getOrLoadLineStrData()); + AddSection("debug_cu_index", getOrLoadCuIndexData()); + AddSection("debug_tu_index", getOrLoadTuIndexData()); m_llvm_context = llvm::DWARFContext::create(section_map, addr_size); } diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h index 8691001b1b7..92161a21d16 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILE_DWARF_DWARFCONTEXT_H -#define LLDB_PLUGINS_SYMBOLFILE_DWARF_DWARFCONTEXT_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFCONTEXT_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFCONTEXT_H #include "DWARFDataExtractor.h" #include "lldb/Core/Section.h" @@ -31,6 +31,7 @@ private: SectionData m_data_debug_abbrev; SectionData m_data_debug_addr; SectionData m_data_debug_aranges; + SectionData m_data_debug_cu_index; SectionData m_data_debug_info; SectionData m_data_debug_line; SectionData m_data_debug_line_str; @@ -41,13 +42,17 @@ private: SectionData m_data_debug_rnglists; SectionData m_data_debug_str; SectionData m_data_debug_str_offsets; + SectionData m_data_debug_tu_index; SectionData m_data_debug_types; const DWARFDataExtractor & - LoadOrGetSection(lldb::SectionType main_section_type, + LoadOrGetSection(llvm::Optional main_section_type, llvm::Optional dwo_section_type, SectionData &data); + const DWARFDataExtractor &getOrLoadCuIndexData(); + const DWARFDataExtractor &getOrLoadTuIndexData(); + public: explicit DWARFContext(SectionList *main_section_list, SectionList *dwo_section_list) diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp index c5411a17f27..8e995e62797 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDIE.cpp --------------------------------------------*- C++ -*-===// +//===-- DWARFDIE.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -32,7 +32,7 @@ class ElaboratingDIEIterator // Container sizes are optimized for the case of following DW_AT_specification // and DW_AT_abstract_origin just once. llvm::SmallVector m_worklist; - llvm::SmallSet m_seen; + llvm::SmallSet m_seen; void Next() { assert(!m_worklist.empty() && "Incrementing end iterator?"); @@ -44,7 +44,7 @@ class ElaboratingDIEIterator // And add back any items that elaborate it. for (dw_attr_t attr : {DW_AT_specification, DW_AT_abstract_origin}) { if (DWARFDIE d = die.GetReferencedDIE(attr)) - if (m_seen.insert(die.GetID()).second) + if (m_seen.insert(die.GetDIE()).second) m_worklist.push_back(d); } } @@ -140,25 +140,64 @@ DWARFDIE::GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const { } DWARFDIE -DWARFDIE::LookupDeepestBlock(lldb::addr_t file_addr) const { - if (IsValid()) { - SymbolFileDWARF *dwarf = GetDWARF(); - DWARFUnit *cu = GetCU(); - DWARFDebugInfoEntry *function_die = nullptr; - DWARFDebugInfoEntry *block_die = nullptr; - if (m_die->LookupAddress(file_addr, cu, &function_die, &block_die)) { - if (block_die && block_die != function_die) { - if (cu->ContainsDIEOffset(block_die->GetOffset())) - return DWARFDIE(cu, block_die); - else - return DWARFDIE(dwarf->DebugInfo()->GetUnit(DIERef( - cu->GetSymbolFileDWARF().GetDwoNum(), - cu->GetDebugSection(), block_die->GetOffset())), - block_die); +DWARFDIE::LookupDeepestBlock(lldb::addr_t address) const { + if (!IsValid()) + return DWARFDIE(); + + DWARFDIE result; + bool check_children = false; + bool match_addr_range = false; + switch (Tag()) { + case DW_TAG_class_type: + case DW_TAG_namespace: + case DW_TAG_structure_type: + case DW_TAG_common_block: + check_children = true; + break; + case DW_TAG_compile_unit: + case DW_TAG_module: + case DW_TAG_catch_block: + case DW_TAG_subprogram: + case DW_TAG_try_block: + case DW_TAG_partial_unit: + match_addr_range = true; + break; + case DW_TAG_lexical_block: + case DW_TAG_inlined_subroutine: + check_children = true; + match_addr_range = true; + break; + default: + break; + } + + if (match_addr_range) { + DWARFRangeList ranges; + if (m_die->GetAttributeAddressRanges(m_cu, ranges, + /*check_hi_lo_pc=*/true) && + ranges.FindEntryThatContains(address)) { + check_children = true; + switch (Tag()) { + default: + break; + + case DW_TAG_inlined_subroutine: // Inlined Function + case DW_TAG_lexical_block: // Block { } in code + result = *this; + break; } + } else { + check_children = false; } } - return DWARFDIE(); + + if (check_children) { + for (DWARFDIE child = GetFirstChild(); child; child = child.GetSibling()) { + if (DWARFDIE child_result = child.LookupDeepestBlock(address)) + return child_result; + } + } + return result; } const char *DWARFDIE::GetMangledName() const { @@ -333,15 +372,6 @@ std::vector DWARFDIE::GetDeclContextDIEs() const { return result; } -void DWARFDIE::GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const { - if (IsValid()) { - dwarf_decl_ctx.SetLanguage(GetLanguage()); - m_die->GetDWARFDeclContext(GetCU(), dwarf_decl_ctx); - } else { - dwarf_decl_ctx.Clear(); - } -} - void DWARFDIE::GetDeclContext( llvm::SmallVectorImpl &context) const { const dw_tag_t tag = Tag(); @@ -418,27 +448,3 @@ bool DWARFDIE::GetDIENamesAndRanges( } else return false; } - -CompilerDecl DWARFDIE::GetDecl() const { - DWARFASTParser *dwarf_ast = GetDWARFParser(); - if (dwarf_ast) - return dwarf_ast->GetDeclForUIDFromDWARF(*this); - else - return CompilerDecl(); -} - -CompilerDeclContext DWARFDIE::GetDeclContext() const { - DWARFASTParser *dwarf_ast = GetDWARFParser(); - if (dwarf_ast) - return dwarf_ast->GetDeclContextForUIDFromDWARF(*this); - else - return CompilerDeclContext(); -} - -CompilerDeclContext DWARFDIE::GetContainingDeclContext() const { - DWARFASTParser *dwarf_ast = GetDWARFParser(); - if (dwarf_ast) - return dwarf_ast->GetDeclContextContainingUIDFromDWARF(*this); - else - return CompilerDeclContext(); -} diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h index 87d52eee9dd..13737280926 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDIE_h_ -#define SymbolFileDWARF_DWARFDIE_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDIE_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDIE_H #include "DWARFBaseDIE.h" #include "llvm/ADT/SmallSet.h" @@ -70,8 +70,6 @@ public: // DeclContext related functions std::vector GetDeclContextDIEs() const; - void GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const; - /// Return this DIE's decl context as it is needed to look up types /// in Clang's -gmodules debug info format. void GetDeclContext( @@ -90,14 +88,6 @@ public: int &decl_line, int &decl_column, int &call_file, int &call_line, int &call_column, lldb_private::DWARFExpression *frame_base) const; - - // CompilerDecl related functions - - lldb_private::CompilerDecl GetDecl() const; - - lldb_private::CompilerDeclContext GetDeclContext() const; - - lldb_private::CompilerDeclContext GetContainingDeclContext() const; }; -#endif // SymbolFileDWARF_DWARFDIE_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDIE_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp index 1678b228137..cf483286a66 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDataExtractor.cpp ----------------------------------*- C++ -*-===// +//===-- DWARFDataExtractor.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -23,8 +23,7 @@ DWARFDataExtractor::GetDWARFOffset(lldb::offset_t *offset_ptr) const { llvm::DWARFDataExtractor DWARFDataExtractor::GetAsLLVM() const { return llvm::DWARFDataExtractor( - llvm::StringRef(reinterpret_cast(GetDataStart()), - GetByteSize()), + llvm::makeArrayRef(GetDataStart(), GetByteSize()), GetByteOrder() == lldb::eByteOrderLittle, GetAddressByteSize()); } } // namespace lldb_private diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h index 22db5e8c0b7..df92bd45d5c 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFDataExtractor_h_ -#define liblldb_DWARFDataExtractor_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDATAEXTRACTOR_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDATAEXTRACTOR_H #include "lldb/Core/dwarf.h" #include "lldb/Utility/DataExtractor.h" @@ -34,4 +34,4 @@ public: }; } -#endif // liblldb_DWARFDataExtractor_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDATAEXTRACTOR_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp index 26301566a8e..0f0f50a645d 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDebugAbbrev.cpp ------------------------------------*- C++ -*-===// +//===-- DWARFDebugAbbrev.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h index 9c472932608..555864f4496 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDebugAbbrev_h_ -#define SymbolFileDWARF_DWARFDebugAbbrev_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGABBREV_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGABBREV_H #include #include @@ -78,4 +78,4 @@ protected: mutable DWARFAbbreviationDeclarationCollMapConstIter m_prev_abbr_offset_pos; }; -#endif // SymbolFileDWARF_DWARFDebugAbbrev_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGABBREV_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp index 86ce3b329b2..728cefe620a 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDebugArangeSet.cpp ---------------------------------*- C++ -*-===// +//===-- DWARFDebugArangeSet.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -63,7 +63,8 @@ llvm::Error DWARFDebugArangeSet::extract(const DWARFDataExtractor &data, // 1 - the version looks good // 2 - the address byte size looks plausible // 3 - the length seems to make sense - // size looks plausible + // 4 - size looks plausible + // 5 - the arange tuples do not contain a segment field if (m_header.version < 2 || m_header.version > 5) return llvm::make_error( "Invalid arange header version"); @@ -81,6 +82,10 @@ llvm::Error DWARFDebugArangeSet::extract(const DWARFDataExtractor &data, return llvm::make_error( "Invalid arange header length"); + if (m_header.seg_size) + return llvm::make_error( + "segmented arange entries are not supported"); + // The first tuple following the header in each set begins at an offset // that is a multiple of the size of a single tuple (that is, twice the // size of an address). The header is padded, if necessary, to the diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h index db0cf22a3f4..6b5b69a70a8 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDebugArangeSet_h_ -#define SymbolFileDWARF_DWARFDebugArangeSet_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGESET_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGESET_H #include "lldb/Core/dwarf.h" #include @@ -59,4 +59,4 @@ protected: DescriptorColl m_arange_descriptors; }; -#endif // SymbolFileDWARF_DWARFDebugArangeSet_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGESET_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp index c8da2381353..7dc52c1e2df 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDebugAranges.cpp -----------------------------------*- C++ -*-===// +//===-- DWARFDebugAranges.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h index 74ba011b27a..96e82619f98 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDebugAranges_h_ -#define SymbolFileDWARF_DWARFDebugAranges_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGES_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGES_H #include "lldb/Core/dwarf.h" #include "lldb/Utility/RangeMap.h" @@ -52,4 +52,4 @@ protected: RangeToDIE m_aranges; }; -#endif // SymbolFileDWARF_DWARFDebugAranges_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGES_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp index 1e04baca2c5..874978bf139 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDebugInfo.cpp --------------------------------------*- C++ -*-===// +//===-- DWARFDebugInfo.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -72,10 +72,16 @@ void DWARFDebugInfo::ParseUnitsFor(DIERef::Section section) { DWARFDataExtractor data = section == DIERef::Section::DebugTypes ? m_context.getOrLoadDebugTypesData() : m_context.getOrLoadDebugInfoData(); + const llvm::DWARFUnitIndex *index = nullptr; + if (m_context.isDwo()) + index = &llvm::getDWARFUnitIndex(m_context.GetAsLLVM(), + section == DIERef::Section::DebugTypes + ? llvm::DW_SECT_EXT_TYPES + : llvm::DW_SECT_INFO); lldb::offset_t offset = 0; while (data.ValidOffset(offset)) { - llvm::Expected unit_sp = - DWARFUnit::extract(m_dwarf, m_units.size(), data, section, &offset); + llvm::Expected unit_sp = DWARFUnit::extract( + m_dwarf, m_units.size(), data, section, &offset, index); if (!unit_sp) { // FIXME: Propagate this error up. @@ -96,12 +102,11 @@ void DWARFDebugInfo::ParseUnitsFor(DIERef::Section section) { } void DWARFDebugInfo::ParseUnitHeadersIfNeeded() { - if (!m_units.empty()) - return; - - ParseUnitsFor(DIERef::Section::DebugInfo); - ParseUnitsFor(DIERef::Section::DebugTypes); - llvm::sort(m_type_hash_to_unit_index, llvm::less_first()); + llvm::call_once(m_units_once_flag, [&] { + ParseUnitsFor(DIERef::Section::DebugInfo); + ParseUnitsFor(DIERef::Section::DebugTypes); + llvm::sort(m_type_hash_to_unit_index, llvm::less_first()); + }); } size_t DWARFDebugInfo::GetNumUnits() { @@ -109,7 +114,7 @@ size_t DWARFDebugInfo::GetNumUnits() { return m_units.size(); } -DWARFUnit *DWARFDebugInfo::GetUnitAtIndex(user_id_t idx) { +DWARFUnit *DWARFDebugInfo::GetUnitAtIndex(size_t idx) { DWARFUnit *cu = nullptr; if (idx < GetNumUnits()) cu = m_units[idx].get(); @@ -191,7 +196,7 @@ DWARFDIE DWARFDebugInfo::GetDIE(const DIERef &die_ref) { DWARFUnit *cu = GetUnit(die_ref); if (cu) - return cu->GetDIE(die_ref.die_offset()); + return cu->GetNonSkeletonUnit().GetDIE(die_ref.die_offset()); return DWARFDIE(); // Not found } diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h index 056cf33a202..bdc718a5c2f 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDebugInfo_h_ -#define SymbolFileDWARF_DWARFDebugInfo_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFO_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFO_H #include #include @@ -35,7 +35,7 @@ public: lldb_private::DWARFContext &context); size_t GetNumUnits(); - DWARFUnit *GetUnitAtIndex(lldb::user_id_t idx); + DWARFUnit *GetUnitAtIndex(size_t idx); DWARFUnit *GetUnitAtOffset(DIERef::Section section, dw_offset_t cu_offset, uint32_t *idx_ptr = nullptr); DWARFUnit *GetUnitContainingDIEOffset(DIERef::Section section, @@ -61,7 +61,10 @@ protected: SymbolFileDWARF &m_dwarf; lldb_private::DWARFContext &m_context; + + llvm::once_flag m_units_once_flag; UnitColl m_units; + std::unique_ptr m_cu_aranges_up; // A quick address to compile unit table @@ -76,7 +79,8 @@ private: uint32_t FindUnitIndex(DIERef::Section section, dw_offset_t offset); - DISALLOW_COPY_AND_ASSIGN(DWARFDebugInfo); + DWARFDebugInfo(const DWARFDebugInfo &) = delete; + const DWARFDebugInfo &operator=(const DWARFDebugInfo &) = delete; }; -#endif // SymbolFileDWARF_DWARFDebugInfo_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFO_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index 320500fe608..f6425a889da 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===// +//===-- DWARFDebugInfoEntry.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -395,152 +395,14 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( return !ranges.IsEmpty(); } -// Dump -// -// Dumps a debug information entry and all of it's attributes to the specified -// stream. -void DWARFDebugInfoEntry::Dump(const DWARFUnit *cu, Stream &s, - uint32_t recurse_depth) const { - const DWARFDataExtractor &data = cu->GetData(); - lldb::offset_t offset = m_offset; - - if (data.ValidOffset(offset)) { - dw_uleb128_t abbrCode = data.GetULEB128(&offset); - - s.Printf("\n0x%8.8x: ", m_offset); - s.Indent(); - if (abbrCode != m_abbr_idx) { - s.Printf("error: DWARF has been modified\n"); - } else if (abbrCode) { - const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu); - if (abbrevDecl) { - s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag())); - s.Printf(" [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*' : ' '); - - // Dump all data in the .debug_info/.debug_types for the attributes - const uint32_t numAttributes = abbrevDecl->NumAttributes(); - for (uint32_t i = 0; i < numAttributes; ++i) { - DWARFFormValue form_value(cu); - dw_attr_t attr; - abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); - - DumpAttribute(cu, data, &offset, s, attr, form_value); - } - - const DWARFDebugInfoEntry *child = GetFirstChild(); - if (recurse_depth > 0 && child) { - s.IndentMore(); - - while (child) { - child->Dump(cu, s, recurse_depth - 1); - child = child->GetSibling(); - } - s.IndentLess(); - } - } else - s.Printf("Abbreviation code note found in 'debug_abbrev' class for " - "code: %u\n", - abbrCode); - } else { - s.Printf("NULL\n"); - } - } -} - -// DumpAttribute -// -// Dumps a debug information entry attribute along with it's form. Any special -// display of attributes is done (disassemble location lists, show enumeration -// values for attributes, etc). -void DWARFDebugInfoEntry::DumpAttribute( - const DWARFUnit *cu, const DWARFDataExtractor &data, - lldb::offset_t *offset_ptr, 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_value.Form())); - } - - if (!form_value.ExtractValue(data, offset_ptr)) - return; - - if (show_form) { - if (form_value.Form() == DW_FORM_indirect) { - s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form())); - } - - s.PutCString("] "); - } - - s.PutCString("( "); - - // Check to see if we have any special attribute formatters - switch (attr) { - case DW_AT_stmt_list: - s.Printf("0x%8.8" PRIx64, form_value.Unsigned()); - break; - - case DW_AT_language: - s.PutCString(DW_LANG_value_to_name(form_value.Unsigned())); - break; - - case DW_AT_encoding: - s.PutCString(DW_ATE_value_to_name(form_value.Unsigned())); - break; - - case DW_AT_frame_base: - case DW_AT_location: - case DW_AT_data_member_location: { - const uint8_t *blockData = form_value.BlockData(); - if (blockData) { - // Location description is inlined in data in the form value - DWARFDataExtractor locationData(data, - (*offset_ptr) - form_value.Unsigned(), - form_value.Unsigned()); - DWARFExpression::PrintDWARFExpression( - s, locationData, DWARFUnit::GetAddressByteSize(cu), 4, false); - } else { - // We have a location list offset as the value that is the offset into - // the .debug_loc section that describes the value over it's lifetime - uint64_t debug_loc_offset = form_value.Unsigned(); - DWARFExpression::PrintDWARFLocationList(s, cu, cu->GetLocationData(), - debug_loc_offset); - } - } break; - - case DW_AT_abstract_origin: - case DW_AT_specification: { - DWARFDIE abstract_die = form_value.Reference(); - form_value.Dump(s); - // *ostrm_ptr << HEX32 << abstract_die.GetOffset() << " ( "; - abstract_die.GetName(s); - } break; - - case DW_AT_type: { - DWARFDIE type_die = form_value.Reference(); - s.PutCString(" ( "); - type_die.AppendTypeName(s); - s.PutCString(" )"); - } break; - - default: - break; - } - - s.PutCString(" )\n"); -} - // Get all attribute values for a given DIE, including following any // specification or abstract origin attributes and including those in the // results. Any duplicate attributes will have the first instance take // precedence (this can happen for declaration attributes). -size_t DWARFDebugInfoEntry::GetAttributes( - const DWARFUnit *cu, DWARFAttributes &attributes, - uint32_t curr_depth) const { +size_t DWARFDebugInfoEntry::GetAttributes(const DWARFUnit *cu, + DWARFAttributes &attributes, + Recurse recurse, + uint32_t curr_depth) const { const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu); if (abbrevDecl) { const DWARFDataExtractor &data = cu->GetData(); @@ -571,11 +433,13 @@ size_t DWARFDebugInfoEntry::GetAttributes( break; } - if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) { + if (recurse == Recurse::yes && + ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))) { if (form_value.ExtractValue(data, &offset)) { DWARFDIE spec_die = form_value.Reference(); if (spec_die) - spec_die.GetAttributes(attributes, curr_depth + 1); + spec_die.GetDIE()->GetAttributes(spec_die.GetCU(), attributes, + recurse, curr_depth + 1); } } else { llvm::Optional fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu); @@ -819,34 +683,9 @@ const char *DWARFDebugInfoEntry::GetPubname(const DWARFUnit *cu) const { return name; } -// BuildAddressRangeTable -void DWARFDebugInfoEntry::BuildAddressRangeTable( - const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const { - if (m_tag) { - if (m_tag == DW_TAG_subprogram) { - dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; - dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; - if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) { - /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x - - /// 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc); - debug_aranges->AppendRange(cu->GetOffset(), lo_pc, hi_pc); - } - } - - const DWARFDebugInfoEntry *child = GetFirstChild(); - while (child) { - child->BuildAddressRangeTable(cu, debug_aranges); - child = child->GetSibling(); - } - } -} - -// BuildFunctionAddressRangeTable -// -// This function is very similar to the BuildAddressRangeTable function except -// that the actual DIE offset for the function is placed in the table instead -// of the compile unit offset (which is the way the standard .debug_aranges -// section does it). +/// This function is builds a table very similar to the standard .debug_aranges +/// table, except that the actual DIE offset for the function is placed in the +/// table instead of the compile unit offset. void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable( const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const { if (m_tag) { @@ -854,8 +693,6 @@ void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable( dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) { - // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " - - // 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY debug_aranges->AppendRange(GetOffset(), lo_pc, hi_pc); } } @@ -868,25 +705,34 @@ void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable( } } -void DWARFDebugInfoEntry::GetDWARFDeclContext( - DWARFUnit *cu, DWARFDeclContext &dwarf_decl_ctx) const { - const dw_tag_t tag = Tag(); - if (tag != DW_TAG_compile_unit && tag != DW_TAG_partial_unit) { - dwarf_decl_ctx.AppendDeclContext(tag, GetName(cu)); - DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(cu); - if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this) { - if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit && - parent_decl_ctx_die.Tag() != DW_TAG_partial_unit) - parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext( - parent_decl_ctx_die.GetCU(), dwarf_decl_ctx); - } +DWARFDeclContext +DWARFDebugInfoEntry::GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, + DWARFUnit *cu) { + DWARFDeclContext dwarf_decl_ctx; + for (;;) { + const dw_tag_t tag = die->Tag(); + if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit) + return dwarf_decl_ctx; + dwarf_decl_ctx.AppendDeclContext(tag, die->GetName(cu)); + DWARFDIE parent_decl_ctx_die = die->GetParentDeclContextDIE(cu); + if (!parent_decl_ctx_die || parent_decl_ctx_die.GetDIE() == die) + return dwarf_decl_ctx; + if (parent_decl_ctx_die.Tag() == DW_TAG_compile_unit || + parent_decl_ctx_die.Tag() == DW_TAG_partial_unit) + return dwarf_decl_ctx; + die = parent_decl_ctx_die.GetDIE(); + cu = parent_decl_ctx_die.GetCU(); } } +DWARFDeclContext DWARFDebugInfoEntry::GetDWARFDeclContext(DWARFUnit *cu) const { + return GetDWARFDeclContextStatic(this, cu); +} + DWARFDIE DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnit *cu) const { DWARFAttributes attributes; - GetAttributes(cu, attributes); + GetAttributes(cu, attributes, Recurse::yes); return GetParentDeclContextDIE(cu, attributes); } @@ -936,7 +782,7 @@ DWARFDebugInfoEntry::GetParentDeclContextDIE( const char *DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu, std::string &storage) const { DWARFAttributes attributes; - GetAttributes(cu, attributes); + GetAttributes(cu, attributes, Recurse::yes); return GetQualifiedName(cu, attributes, storage); } @@ -993,209 +839,6 @@ DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu, return storage.c_str(); } -bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, DWARFUnit *cu, - DWARFDebugInfoEntry **function_die, - DWARFDebugInfoEntry **block_die) { - bool found_address = false; - if (m_tag) { - bool check_children = false; - bool match_addr_range = false; - // printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset, - // DW_TAG_value_to_name(tag), address); - switch (m_tag) { - case DW_TAG_array_type: - break; - case DW_TAG_class_type: - check_children = true; - break; - case DW_TAG_entry_point: - case DW_TAG_enumeration_type: - case DW_TAG_formal_parameter: - case DW_TAG_imported_declaration: - case DW_TAG_label: - break; - case DW_TAG_lexical_block: - check_children = true; - match_addr_range = true; - break; - case DW_TAG_member: - case DW_TAG_pointer_type: - case DW_TAG_reference_type: - break; - case DW_TAG_compile_unit: - match_addr_range = true; - break; - case DW_TAG_string_type: - break; - case DW_TAG_structure_type: - check_children = true; - break; - case DW_TAG_subroutine_type: - case DW_TAG_typedef: - case DW_TAG_union_type: - case DW_TAG_unspecified_parameters: - case DW_TAG_variant: - break; - case DW_TAG_common_block: - check_children = true; - break; - case DW_TAG_common_inclusion: - case DW_TAG_inheritance: - break; - case DW_TAG_inlined_subroutine: - check_children = true; - match_addr_range = true; - break; - case DW_TAG_module: - match_addr_range = true; - break; - case DW_TAG_ptr_to_member_type: - case DW_TAG_set_type: - case DW_TAG_subrange_type: - case DW_TAG_with_stmt: - case DW_TAG_access_declaration: - case DW_TAG_base_type: - break; - case DW_TAG_catch_block: - match_addr_range = true; - break; - case DW_TAG_const_type: - case DW_TAG_constant: - case DW_TAG_enumerator: - case DW_TAG_file_type: - case DW_TAG_friend: - case DW_TAG_namelist: - case DW_TAG_namelist_item: - case DW_TAG_packed_type: - break; - case DW_TAG_subprogram: - match_addr_range = true; - break; - case DW_TAG_template_type_parameter: - case DW_TAG_template_value_parameter: - case DW_TAG_GNU_template_parameter_pack: - case DW_TAG_thrown_type: - break; - case DW_TAG_try_block: - match_addr_range = true; - break; - case DW_TAG_variant_part: - case DW_TAG_variable: - case DW_TAG_volatile_type: - case DW_TAG_dwarf_procedure: - case DW_TAG_restrict_type: - case DW_TAG_interface_type: - break; - case DW_TAG_namespace: - check_children = true; - break; - case DW_TAG_imported_module: - case DW_TAG_unspecified_type: - break; - case DW_TAG_partial_unit: - match_addr_range = true; - break; - case DW_TAG_imported_unit: - case DW_TAG_shared_type: - default: - break; - } - - if (match_addr_range) { - dw_addr_t lo_pc = - GetAttributeValueAsAddress(cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS); - if (lo_pc != LLDB_INVALID_ADDRESS) { - dw_addr_t hi_pc = GetAttributeHighPC(cu, lo_pc, LLDB_INVALID_ADDRESS); - if (hi_pc != LLDB_INVALID_ADDRESS) { - // printf("\n0x%8.8x: %30s: address = 0x%8.8x [0x%8.8x - 0x%8.8x) ", - // m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc); - if ((lo_pc <= address) && (address < hi_pc)) { - found_address = true; - // puts("***MATCH***"); - switch (m_tag) { - case DW_TAG_compile_unit: // File - case DW_TAG_partial_unit: // File - check_children = - ((function_die != nullptr) || (block_die != nullptr)); - break; - - case DW_TAG_subprogram: // Function - if (function_die) - *function_die = this; - check_children = (block_die != nullptr); - break; - - case DW_TAG_inlined_subroutine: // Inlined Function - case DW_TAG_lexical_block: // Block { } in code - if (block_die) { - *block_die = this; - check_children = true; - } - break; - - default: - check_children = true; - break; - } - } - } else { - // Compile units may not have a valid high/low pc when there - // are address gaps in subroutines so we must always search - // if there is no valid high and low PC. - check_children = - (m_tag == DW_TAG_compile_unit || m_tag == DW_TAG_partial_unit) && - ((function_die != nullptr) || (block_die != nullptr)); - } - } else { - DWARFRangeList ranges; - if (GetAttributeAddressRanges(cu, ranges, /*check_hi_lo_pc*/ false) && - ranges.FindEntryThatContains(address)) { - found_address = true; - // puts("***MATCH***"); - switch (m_tag) { - case DW_TAG_compile_unit: // File - case DW_TAG_partial_unit: // File - check_children = - ((function_die != nullptr) || (block_die != nullptr)); - break; - - case DW_TAG_subprogram: // Function - if (function_die) - *function_die = this; - check_children = (block_die != nullptr); - break; - - case DW_TAG_inlined_subroutine: // Inlined Function - case DW_TAG_lexical_block: // Block { } in code - if (block_die) { - *block_die = this; - check_children = true; - } - break; - - default: - check_children = true; - break; - } - } else { - check_children = false; - } - } - } - - if (check_children) { - // printf("checking children\n"); - DWARFDebugInfoEntry *child = GetFirstChild(); - while (child) { - if (child->LookupAddress(address, cu, function_die, block_die)) - return true; - child = child->GetSibling(); - } - } - } - return found_address; -} - lldb::offset_t DWARFDebugInfoEntry::GetFirstAttributeOffset() const { return GetOffset() + llvm::getULEB128Size(m_abbr_idx); } @@ -1210,6 +853,29 @@ DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const { return nullptr; } +bool DWARFDebugInfoEntry::IsGlobalOrStaticScopeVariable() const { + if (Tag() != DW_TAG_variable) + return false; + const DWARFDebugInfoEntry *parent_die = GetParent(); + while (parent_die != nullptr) { + switch (parent_die->Tag()) { + case DW_TAG_subprogram: + case DW_TAG_lexical_block: + case DW_TAG_inlined_subroutine: + return false; + + case DW_TAG_compile_unit: + case DW_TAG_partial_unit: + return true; + + default: + break; + } + parent_die = parent_die->GetParent(); + } + return false; +} + 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 && diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h index f35af6e7d49..3019e1767f1 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h @@ -6,13 +6,14 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDebugInfoEntry_h_ -#define SymbolFileDWARF_DWARFDebugInfoEntry_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H #include "SymbolFileDWARF.h" #include "llvm/ADT/SmallVector.h" #include "DWARFAbbreviationDeclaration.h" +#include "DWARFBaseDIE.h" #include "DWARFDebugAbbrev.h" #include "DWARFDebugRanges.h" #include @@ -41,23 +42,17 @@ public: bool operator==(const DWARFDebugInfoEntry &rhs) const; bool operator!=(const DWARFDebugInfoEntry &rhs) const; - void BuildAddressRangeTable(const DWARFUnit *cu, - DWARFDebugAranges *debug_aranges) const; - void BuildFunctionAddressRangeTable(const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const; bool Extract(const lldb_private::DWARFDataExtractor &data, const DWARFUnit *cu, lldb::offset_t *offset_ptr); - bool LookupAddress(const dw_addr_t address, DWARFUnit *cu, - DWARFDebugInfoEntry **function_die, - DWARFDebugInfoEntry **block_die); - - size_t GetAttributes(const DWARFUnit *cu, - DWARFAttributes &attrs, - uint32_t curr_depth = 0) - const; // "curr_depth" for internal use only, don't set this yourself!!! + using Recurse = DWARFBaseDIE::Recurse; + size_t GetAttributes(const DWARFUnit *cu, DWARFAttributes &attrs, + Recurse recurse = Recurse::yes) const { + return GetAttributes(cu, attrs, recurse, 0 /* curr_depth */); + } dw_offset_t GetAttributeValue(const DWARFUnit *cu, const dw_attr_t attr, @@ -106,15 +101,6 @@ public: const char *GetQualifiedName(DWARFUnit *cu, const DWARFAttributes &attributes, std::string &storage) const; - void Dump(const DWARFUnit *cu, lldb_private::Stream &s, - uint32_t recurse_depth) const; - - static void - DumpAttribute(const DWARFUnit *cu, - const lldb_private::DWARFDataExtractor &data, - lldb::offset_t *offset_ptr, lldb_private::Stream &s, - dw_attr_t attr, DWARFFormValue &form_value); - bool GetDIENamesAndRanges( DWARFUnit *cu, const char *&name, const char *&mangled, DWARFRangeList &rangeList, int &decl_file, int &decl_line, @@ -162,8 +148,7 @@ public: return HasChildren() ? this + 1 : nullptr; } - void GetDWARFDeclContext(DWARFUnit *cu, - DWARFDeclContext &dwarf_decl_ctx) const; + DWARFDeclContext GetDWARFDeclContext(DWARFUnit *cu) const; DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu) const; DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu, @@ -172,7 +157,15 @@ public: void SetSiblingIndex(uint32_t idx) { m_sibling_idx = idx; } void SetParentIndex(uint32_t idx) { m_parent_idx = idx; } + // This function returns true if the variable scope is either + // global or (file-static). It will return false for static variables + // that are local to a function, as they have local scope. + bool IsGlobalOrStaticScopeVariable() const; + protected: + static DWARFDeclContext + GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, DWARFUnit *cu); + dw_offset_t m_offset; // Offset within the .debug_info/.debug_types uint32_t m_parent_idx; // How many to subtract from "this" to get the parent. // If zero this die has no parent @@ -185,6 +178,10 @@ protected: /// A copy of the DW_TAG value so we don't have to go through the compile /// unit abbrev table dw_tag_t m_tag = llvm::dwarf::DW_TAG_null; + +private: + size_t GetAttributes(const DWARFUnit *cu, DWARFAttributes &attrs, + Recurse recurse, uint32_t curr_depth) const; }; -#endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp index 4238be7ec1c..278950a9f33 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDebugMacro.cpp -------------------------------------*- C++ -*-===// +//===-- DWARFDebugMacro.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h index c3a93a9f4d1..5c0338e950e 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDebugMacro_h_ -#define SymbolFileDWARF_DWARFDebugMacro_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGMACRO_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGMACRO_H #include @@ -58,4 +58,4 @@ public: lldb_private::DebugMacrosSP &debug_macros_sp); }; -#endif // SymbolFileDWARF_DWARFDebugMacro_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGMACRO_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp index 6c074002cb2..6a0f11d2a1c 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDebugRanges.cpp ------------------------------------*- C++ -*-===// +//===-- DWARFDebugRanges.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h index 1888a7760f2..b587845a67d 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDebugRanges_h_ -#define SymbolFileDWARF_DWARFDebugRanges_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGRANGES_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGRANGES_H #include "lldb/Core/dwarf.h" #include @@ -39,4 +39,4 @@ protected: range_map m_range_map; }; -#endif // SymbolFileDWARF_DWARFDebugRanges_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGRANGES_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp index a664314035e..f4c8c14cc8a 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDeclContext.cpp ------------------------------------*- C++ -*-===// +//===-- DWARFDeclContext.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h index 348b33464a5..9072b2dc011 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDeclContext_h_ -#define SymbolFileDWARF_DWARFDeclContext_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H #include #include @@ -48,6 +48,7 @@ public: } bool operator==(const DWARFDeclContext &rhs) const; + bool operator!=(const DWARFDeclContext &rhs) const { return !(*this == rhs); } uint32_t GetSize() const { return m_entries.size(); } @@ -85,4 +86,4 @@ protected: lldb::LanguageType m_language; }; -#endif // SymbolFileDWARF_DWARFDeclContext_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp index 2ae1bbc9f50..4e99a295ce5 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDefines.cpp ----------------------------------------*- C++ -*-===// +//===-- DWARFDefines.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -58,321 +58,6 @@ const char *DW_OP_value_to_name(uint32_t val) { return llvmstr.data(); } -DRC_class DW_OP_value_to_class(uint32_t val) { - // FIXME: If we just used llvm's DWARFExpression printer, we could delete - // all this code (and more in lldb's DWARFExpression.cpp). - switch (val) { - case 0x03: - return DRC_ONEOPERAND; - case 0x06: - return DRC_ZEROOPERANDS; - case 0x08: - return DRC_ONEOPERAND; - case 0x09: - return DRC_ONEOPERAND; - case 0x0a: - return DRC_ONEOPERAND; - case 0x0b: - return DRC_ONEOPERAND; - case 0x0c: - return DRC_ONEOPERAND; - case 0x0d: - return DRC_ONEOPERAND; - case 0x0e: - return DRC_ONEOPERAND; - case 0x0f: - return DRC_ONEOPERAND; - case 0x10: - return DRC_ONEOPERAND; - case 0x11: - return DRC_ONEOPERAND; - case 0x12: - return DRC_ZEROOPERANDS; - case 0x13: - return DRC_ZEROOPERANDS; - case 0x14: - return DRC_ZEROOPERANDS; - case 0x15: - return DRC_ONEOPERAND; - case 0x16: - return DRC_ZEROOPERANDS; - case 0x17: - return DRC_ZEROOPERANDS; - case 0x18: - return DRC_ZEROOPERANDS; - case 0x19: - return DRC_ZEROOPERANDS; - case 0x1a: - return DRC_ZEROOPERANDS; - case 0x1b: - return DRC_ZEROOPERANDS; - case 0x1c: - return DRC_ZEROOPERANDS; - case 0x1d: - return DRC_ZEROOPERANDS; - case 0x1e: - return DRC_ZEROOPERANDS; - case 0x1f: - return DRC_ZEROOPERANDS; - case 0x20: - return DRC_ZEROOPERANDS; - case 0x21: - return DRC_ZEROOPERANDS; - case 0x22: - return DRC_ZEROOPERANDS; - case 0x23: - return DRC_ONEOPERAND; - case 0x24: - return DRC_ZEROOPERANDS; - case 0x25: - return DRC_ZEROOPERANDS; - case 0x26: - return DRC_ZEROOPERANDS; - case 0x27: - return DRC_ZEROOPERANDS; - case 0x2f: - return DRC_ONEOPERAND; - case 0x28: - return DRC_ONEOPERAND; - case 0x29: - return DRC_ZEROOPERANDS; - case 0x2a: - return DRC_ZEROOPERANDS; - case 0x2b: - return DRC_ZEROOPERANDS; - case 0x2c: - return DRC_ZEROOPERANDS; - case 0x2d: - return DRC_ZEROOPERANDS; - case 0x2e: - return DRC_ZEROOPERANDS; - case 0x30: - return DRC_ZEROOPERANDS; - case 0x31: - return DRC_ZEROOPERANDS; - case 0x32: - return DRC_ZEROOPERANDS; - case 0x33: - return DRC_ZEROOPERANDS; - case 0x34: - return DRC_ZEROOPERANDS; - case 0x35: - return DRC_ZEROOPERANDS; - case 0x36: - return DRC_ZEROOPERANDS; - case 0x37: - return DRC_ZEROOPERANDS; - case 0x38: - return DRC_ZEROOPERANDS; - case 0x39: - return DRC_ZEROOPERANDS; - case 0x3a: - return DRC_ZEROOPERANDS; - case 0x3b: - return DRC_ZEROOPERANDS; - case 0x3c: - return DRC_ZEROOPERANDS; - case 0x3d: - return DRC_ZEROOPERANDS; - case 0x3e: - return DRC_ZEROOPERANDS; - case 0x3f: - return DRC_ZEROOPERANDS; - case 0x40: - return DRC_ZEROOPERANDS; - case 0x41: - return DRC_ZEROOPERANDS; - case 0x42: - return DRC_ZEROOPERANDS; - case 0x43: - return DRC_ZEROOPERANDS; - case 0x44: - return DRC_ZEROOPERANDS; - case 0x45: - return DRC_ZEROOPERANDS; - case 0x46: - return DRC_ZEROOPERANDS; - case 0x47: - return DRC_ZEROOPERANDS; - case 0x48: - return DRC_ZEROOPERANDS; - case 0x49: - return DRC_ZEROOPERANDS; - case 0x4a: - return DRC_ZEROOPERANDS; - case 0x4b: - return DRC_ZEROOPERANDS; - case 0x4c: - return DRC_ZEROOPERANDS; - case 0x4d: - return DRC_ZEROOPERANDS; - case 0x4e: - return DRC_ZEROOPERANDS; - case 0x4f: - return DRC_ZEROOPERANDS; - case 0x50: - return DRC_ZEROOPERANDS; - case 0x51: - return DRC_ZEROOPERANDS; - case 0x52: - return DRC_ZEROOPERANDS; - case 0x53: - return DRC_ZEROOPERANDS; - case 0x54: - return DRC_ZEROOPERANDS; - case 0x55: - return DRC_ZEROOPERANDS; - case 0x56: - return DRC_ZEROOPERANDS; - case 0x57: - return DRC_ZEROOPERANDS; - case 0x58: - return DRC_ZEROOPERANDS; - case 0x59: - return DRC_ZEROOPERANDS; - case 0x5a: - return DRC_ZEROOPERANDS; - case 0x5b: - return DRC_ZEROOPERANDS; - case 0x5c: - return DRC_ZEROOPERANDS; - case 0x5d: - return DRC_ZEROOPERANDS; - case 0x5e: - return DRC_ZEROOPERANDS; - case 0x5f: - return DRC_ZEROOPERANDS; - case 0x60: - return DRC_ZEROOPERANDS; - case 0x61: - return DRC_ZEROOPERANDS; - case 0x62: - return DRC_ZEROOPERANDS; - case 0x63: - return DRC_ZEROOPERANDS; - case 0x64: - return DRC_ZEROOPERANDS; - case 0x65: - return DRC_ZEROOPERANDS; - case 0x66: - return DRC_ZEROOPERANDS; - case 0x67: - return DRC_ZEROOPERANDS; - case 0x68: - return DRC_ZEROOPERANDS; - case 0x69: - return DRC_ZEROOPERANDS; - case 0x6a: - return DRC_ZEROOPERANDS; - case 0x6b: - return DRC_ZEROOPERANDS; - case 0x6c: - return DRC_ZEROOPERANDS; - case 0x6d: - return DRC_ZEROOPERANDS; - case 0x6e: - return DRC_ZEROOPERANDS; - case 0x6f: - return DRC_ZEROOPERANDS; - case 0x70: - return DRC_ONEOPERAND; - case 0x71: - return DRC_ONEOPERAND; - case 0x72: - return DRC_ONEOPERAND; - case 0x73: - return DRC_ONEOPERAND; - case 0x74: - return DRC_ONEOPERAND; - case 0x75: - return DRC_ONEOPERAND; - case 0x76: - return DRC_ONEOPERAND; - case 0x77: - return DRC_ONEOPERAND; - case 0x78: - return DRC_ONEOPERAND; - case 0x79: - return DRC_ONEOPERAND; - case 0x7a: - return DRC_ONEOPERAND; - case 0x7b: - return DRC_ONEOPERAND; - case 0x7c: - return DRC_ONEOPERAND; - case 0x7d: - return DRC_ONEOPERAND; - case 0x7e: - return DRC_ONEOPERAND; - case 0x7f: - return DRC_ONEOPERAND; - case 0x80: - return DRC_ONEOPERAND; - case 0x81: - return DRC_ONEOPERAND; - case 0x82: - return DRC_ONEOPERAND; - case 0x83: - return DRC_ONEOPERAND; - case 0x84: - return DRC_ONEOPERAND; - case 0x85: - return DRC_ONEOPERAND; - case 0x86: - return DRC_ONEOPERAND; - case 0x87: - return DRC_ONEOPERAND; - case 0x88: - return DRC_ONEOPERAND; - case 0x89: - return DRC_ONEOPERAND; - case 0x8a: - return DRC_ONEOPERAND; - case 0x8b: - return DRC_ONEOPERAND; - case 0x8c: - return DRC_ONEOPERAND; - case 0x8d: - return DRC_ONEOPERAND; - case 0x8e: - return DRC_ONEOPERAND; - case 0x8f: - return DRC_ONEOPERAND; - case 0x90: - return DRC_ONEOPERAND; - case 0x91: - return DRC_ONEOPERAND; - case 0x92: - return DRC_TWOOPERANDS; - case 0x93: - return DRC_ONEOPERAND; - case 0x94: - return DRC_ONEOPERAND; - case 0x95: - return DRC_ONEOPERAND; - case 0x96: - return DRC_ZEROOPERANDS; - case 0x97: - return DRC_DWARFv3 | DRC_ZEROOPERANDS; - case 0x98: - return DRC_DWARFv3 | DRC_ONEOPERAND; - case 0x99: - return DRC_DWARFv3 | DRC_ONEOPERAND; - case 0x9a: - return DRC_DWARFv3 | DRC_ONEOPERAND; - case 0xa3: /* DW_OP_entry_value */ - return DRC_TWOOPERANDS; - case 0xf0: - return DRC_ZEROOPERANDS; /* DW_OP_APPLE_uninit */ - case 0xe0: - return 0; - case 0xff: - return 0; - default: - return 0; - } -} - const char *DW_ATE_value_to_name(uint32_t val) { static char invalid[100]; llvm::StringRef llvmstr = llvm::dwarf::AttributeEncodingString(val); diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h index d16cb07baf8..1b7102cd7e3 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFDefines_h_ -#define SymbolFileDWARF_DWARFDefines_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEFINES_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEFINES_H #include "lldb/Core/dwarf.h" #include @@ -26,52 +26,12 @@ const char *DW_FORM_value_to_name(uint32_t val); const char *DW_OP_value_to_name(uint32_t val); -DRC_class DW_OP_value_to_class(uint32_t val); - const char *DW_ATE_value_to_name(uint32_t val); const char *DW_LANG_value_to_name(uint32_t val); const char *DW_LNS_value_to_name(uint32_t val); -/* These DRC are entirely our own construction, - although they are derived from various comments in the DWARF standard. - Most of these are not useful to the parser, but the DW_AT and DW_FORM - classes should prove to be usable in some fashion. */ - -#define DRC_0x65 0x1 -#define DRC_ADDRESS 0x2 -#define DRC_BLOCK 0x4 -#define DRC_CONSTANT 0x8 -#define DRC_DWARFv3 0x10 -#define DRC_FLAG 0x20 -#define DRC_INDIRECT_SPECIAL 0x40 -#define DRC_LINEPTR 0x80 -#define DRC_LOCEXPR 0x100 -#define DRC_LOCLISTPTR 0x200 -#define DRC_MACPTR 0x400 -#define DRC_ONEOPERAND 0x800 -#define DRC_OPERANDONE_1BYTE_DELTA 0x1000 -#define DRC_OPERANDONE_2BYTE_DELTA 0x2000 -#define DRC_OPERANDONE_4BYTE_DELTA 0x4000 -#define DRC_OPERANDONE_ADDRESS 0x8000 -#define DRC_OPERANDONE_BLOCK 0x10000 -#define DRC_OPERANDONE_SLEB128_OFFSET 0x20000 -#define DRC_OPERANDONE_ULEB128_OFFSET 0x40000 -#define DRC_OPERANDONE_ULEB128_REGISTER 0x80000 -#define DRC_OPERANDTWO_BLOCK 0x100000 -#define DRC_OPERANDTWO_SLEB128_OFFSET 0x200000 -#define DRC_OPERANDTWO_ULEB128_OFFSET 0x400000 -#define DRC_OPERANDTWO_ULEB128_REGISTER 0x800000 -#define DRC_OPERNADONE_ULEB128_REGISTER 0x1000000 -#define DRC_RANGELISTPTR 0x2000000 -#define DRC_REFERENCE 0x4000000 -#define DRC_STRING 0x8000000 -#define DRC_TWOOPERANDS 0x10000000 -#define DRC_VENDOR_GNU 0x20000000 -#define DRC_VENDOR_MIPS 0x40000000 -#define DRC_ZEROOPERANDS 0x80000000 - } // namespace lldb_private -#endif // SymbolFileDWARF_DWARFDefines_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEFINES_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index f660cc32b3f..305f1cbd282 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -1,4 +1,4 @@ -//===-- DWARFFormValue.cpp --------------------------------------*- C++ -*-===// +//===-- DWARFFormValue.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -454,40 +454,26 @@ void DWARFFormValue::Dump(Stream &s) const { } const char *DWARFFormValue::AsCString() const { - SymbolFileDWARF &symbol_file = m_unit->GetSymbolFileDWARF(); + DWARFContext &context = m_unit->GetSymbolFileDWARF().GetDWARFContext(); - if (m_form == DW_FORM_string) { + if (m_form == DW_FORM_string) return m_value.value.cstr; - } else if (m_form == DW_FORM_strp) { - return symbol_file.GetDWARFContext().getOrLoadStrData().PeekCStr( - m_value.value.uval); - } else if (m_form == DW_FORM_GNU_str_index) { - uint32_t index_size = 4; - lldb::offset_t offset = m_value.value.uval * index_size; - dw_offset_t str_offset = - symbol_file.GetDWARFContext().getOrLoadStrOffsetsData().GetMaxU64( - &offset, index_size); - return symbol_file.GetDWARFContext().getOrLoadStrData().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. - uint32_t indexSize = 4; - lldb::offset_t offset = - m_unit->GetStrOffsetsBase() + m_value.value.uval * indexSize; - dw_offset_t strOffset = - symbol_file.GetDWARFContext().getOrLoadStrOffsetsData().GetMaxU64( - &offset, indexSize); - return symbol_file.GetDWARFContext().getOrLoadStrData().PeekCStr(strOffset); + if (m_form == DW_FORM_strp) + return context.getOrLoadStrData().PeekCStr(m_value.value.uval); + + if (m_form == DW_FORM_GNU_str_index || 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) { + + llvm::Optional offset = + m_unit->GetStringOffsetSectionItem(m_value.value.uval); + if (!offset) + return nullptr; + return context.getOrLoadStrData().PeekCStr(*offset); } if (m_form == DW_FORM_line_strp) - return symbol_file.GetDWARFContext().getOrLoadLineStrData().PeekCStr( - m_value.value.uval); + return context.getOrLoadLineStrData().PeekCStr(m_value.value.uval); return nullptr; } @@ -531,7 +517,7 @@ DWARFDIE DWARFFormValue::Reference() const { case DW_FORM_ref_addr: { DWARFUnit *ref_cu = - m_unit->GetSymbolFileDWARF().DebugInfo()->GetUnitContainingDIEOffset( + m_unit->GetSymbolFileDWARF().DebugInfo().GetUnitContainingDIEOffset( DIERef::Section::DebugInfo, value); if (!ref_cu) { m_unit->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( @@ -544,7 +530,7 @@ DWARFDIE DWARFFormValue::Reference() const { case DW_FORM_ref_sig8: { DWARFTypeUnit *tu = - m_unit->GetSymbolFileDWARF().DebugInfo()->GetTypeUnitForHash(value); + m_unit->GetSymbolFileDWARF().DebugInfo().GetTypeUnitForHash(value); if (!tu) return {}; return tu->GetDIE(tu->GetTypeOffset()); diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h index 848db2990de..b401352c693 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFFormValue_h_ -#define SymbolFileDWARF_DWARFFormValue_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFFORMVALUE_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFFORMVALUE_H #include "DWARFDataExtractor.h" #include @@ -86,4 +86,4 @@ protected: ValueType m_value; // Contains all data for the form }; -#endif // SymbolFileDWARF_DWARFFormValue_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFFORMVALUE_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp index c122f756e81..683033d0ee4 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp @@ -1,4 +1,4 @@ -//===-- DWARFIndex.cpp -----------------------------------------*- C++ -*-===// +//===-- DWARFIndex.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -11,20 +11,21 @@ #include "Plugins/SymbolFile/DWARF/DWARFDIE.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" +#include "lldb/Core/Module.h" + using namespace lldb_private; using namespace lldb; DWARFIndex::~DWARFIndex() = default; -void DWARFIndex::ProcessFunctionDIE(llvm::StringRef name, DIERef ref, - SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, - std::vector &dies) { +bool DWARFIndex::ProcessFunctionDIE( + llvm::StringRef name, DIERef ref, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, + llvm::function_ref callback) { DWARFDIE die = dwarf.GetDIE(ref); if (!die) { ReportInvalidDIERef(ref, name); - return; + return true; } // Exit early if we're searching exclusively for methods or selectors and @@ -32,26 +33,22 @@ void DWARFIndex::ProcessFunctionDIE(llvm::StringRef name, DIERef ref, uint32_t looking_for_nonmethods = name_type_mask & ~(eFunctionNameTypeMethod | eFunctionNameTypeSelector); if (!looking_for_nonmethods && parent_decl_ctx.IsValid()) - return; + return true; // Otherwise, we need to also check that the context matches. If it does not // match, we do nothing. - if (!SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die)) - return; + if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die)) + return true; // In case of a full match, we just insert everything we find. - if (name_type_mask & eFunctionNameTypeFull) { - dies.push_back(die); - return; - } + if (name_type_mask & eFunctionNameTypeFull) + return callback(die); // If looking for ObjC selectors, we need to also check if the name is a // possible selector. if (name_type_mask & eFunctionNameTypeSelector && - ObjCLanguage::IsPossibleObjCMethodName(die.GetName())) { - dies.push_back(die); - return; - } + ObjCLanguage::IsPossibleObjCMethodName(die.GetName())) + return callback(die); bool looking_for_methods = name_type_mask & lldb::eFunctionNameTypeMethod; bool looking_for_functions = name_type_mask & lldb::eFunctionNameTypeBase; @@ -61,6 +58,29 @@ void DWARFIndex::ProcessFunctionDIE(llvm::StringRef name, DIERef ref, // searching for. if ((looking_for_methods && looking_for_functions) || looking_for_methods == die.IsMethod()) - dies.push_back(die); + return callback(die); } + + return true; +} + +DWARFIndex::DIERefCallbackImpl::DIERefCallbackImpl( + const DWARFIndex &index, llvm::function_ref callback, + llvm::StringRef name) + : m_index(index), + m_dwarf(*llvm::cast(index.m_module.GetSymbolFile())), + m_callback(callback), m_name(name) {} + +bool DWARFIndex::DIERefCallbackImpl::operator()(DIERef ref) const { + if (DWARFDIE die = m_dwarf.GetDIE(ref)) + return m_callback(die); + m_index.ReportInvalidDIERef(ref, m_name); + return true; +} + +void DWARFIndex::ReportInvalidDIERef(DIERef ref, llvm::StringRef name) const { + m_module.ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (accelerator table had " + "bad die 0x%8.8x for '%s')\n", + ref.die_offset(), name.str().c_str()); } diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h index e3c7c5e63ac..ecf82a910b6 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_DWARFINDEX_H -#define LLDB_DWARFINDEX_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFINDEX_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFINDEX_H #include "Plugins/SymbolFile/DWARF/DIERef.h" #include "Plugins/SymbolFile/DWARF/DWARFDIE.h" @@ -27,26 +27,38 @@ public: /// Finds global variables with the given base name. Any additional filtering /// (e.g., to only retrieve variables from a given context) should be done by /// the consumer. - virtual void GetGlobalVariables(ConstString basename, DIEArray &offsets) = 0; + virtual void + GetGlobalVariables(ConstString basename, + llvm::function_ref callback) = 0; - virtual void GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) = 0; - virtual void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) = 0; - virtual void GetObjCMethods(ConstString class_name, DIEArray &offsets) = 0; - virtual void GetCompleteObjCClass(ConstString class_name, - bool must_be_implementation, - DIEArray &offsets) = 0; - virtual void GetTypes(ConstString name, DIEArray &offsets) = 0; - virtual void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) = 0; - virtual void GetNamespaces(ConstString name, DIEArray &offsets) = 0; - virtual void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, - std::vector &dies) = 0; - virtual void GetFunctions(const RegularExpression ®ex, - DIEArray &offsets) = 0; + virtual void + GetGlobalVariables(const RegularExpression ®ex, + llvm::function_ref callback) = 0; + virtual void + GetGlobalVariables(const DWARFUnit &cu, + llvm::function_ref callback) = 0; + virtual void + GetObjCMethods(ConstString class_name, + llvm::function_ref callback) = 0; + virtual void + GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) = 0; + virtual void GetTypes(ConstString name, + llvm::function_ref callback) = 0; + virtual void GetTypes(const DWARFDeclContext &context, + llvm::function_ref callback) = 0; + virtual void + GetNamespaces(ConstString name, + llvm::function_ref callback) = 0; + virtual void + GetFunctions(ConstString name, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, + uint32_t name_type_mask, + llvm::function_ref callback) = 0; + virtual void + GetFunctions(const RegularExpression ®ex, + llvm::function_ref callback) = 0; - virtual void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) = 0; virtual void Dump(Stream &s) = 0; protected: @@ -56,11 +68,33 @@ protected: /// the function given by "ref" matches search criteria given by /// "parent_decl_ctx" and "name_type_mask", it is inserted into the "dies" /// vector. - void ProcessFunctionDIE(llvm::StringRef name, DIERef ref, + bool ProcessFunctionDIE(llvm::StringRef name, DIERef ref, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, std::vector &dies); + uint32_t name_type_mask, + llvm::function_ref callback); + + class DIERefCallbackImpl { + public: + DIERefCallbackImpl(const DWARFIndex &index, + llvm::function_ref callback, + llvm::StringRef name); + bool operator()(DIERef ref) const; + + private: + const DWARFIndex &m_index; + SymbolFileDWARF &m_dwarf; + const llvm::function_ref m_callback; + const llvm::StringRef m_name; + }; + DIERefCallbackImpl + DIERefCallback(llvm::function_ref callback, + llvm::StringRef name = {}) const { + return DIERefCallbackImpl(*this, callback, name); + } + + void ReportInvalidDIERef(DIERef ref, llvm::StringRef name) const; }; } // namespace lldb_private -#endif // LLDB_DWARFINDEX_H +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFINDEX_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp index fcc031bf1ea..48d578977c5 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp @@ -1,4 +1,4 @@ -//===-- DWARFTypeUnit.cpp ---------------------------------------*- C++ -*-===// +//===-- DWARFTypeUnit.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h index 8967509c081..5e4d48ab285 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFTypeUnit_h_ -#define SymbolFileDWARF_DWARFTypeUnit_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFTYPEUNIT_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFTYPEUNIT_H #include "DWARFUnit.h" #include "llvm/Support/Error.h" @@ -34,4 +34,4 @@ private: friend class DWARFUnit; }; -#endif // SymbolFileDWARF_DWARFTypeUnit_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFTYPEUNIT_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 22e3e40dac9..dfa40759a7f 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -1,4 +1,4 @@ -//===-- DWARFUnit.cpp -------------------------------------------*- C++ -*-===// +//===-- DWARFUnit.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -188,7 +188,7 @@ void DWARFUnit::ExtractDIEsRWLocked() { // simultaneously. We also don't need to do that as the dwo file will // contain a superset of information. So, we don't even attempt to parse // any remaining DIEs. - if (m_dwo_symbol_file) { + if (m_dwo) { m_die_array.front().SetHasChildren(false); break; } @@ -249,10 +249,8 @@ void DWARFUnit::ExtractDIEsRWLocked() { m_die_array.shrink_to_fit(); - if (m_dwo_symbol_file) { - DWARFUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit(); - dwo_cu->ExtractDIEsIfNeeded(); - } + if (m_dwo) + m_dwo->ExtractDIEsIfNeeded(); } // This is used when a split dwarf is enabled. @@ -261,23 +259,33 @@ void DWARFUnit::ExtractDIEsRWLocked() { // .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) { +void DWARFUnit::SetDwoStrOffsetsBase() { lldb::offset_t baseOffset = 0; - const DWARFDataExtractor &strOffsets = - dwo_cu->GetSymbolFileDWARF().GetDWARFContext().getOrLoadStrOffsetsData(); - uint64_t length = strOffsets.GetU32(&baseOffset); - if (length == 0xffffffff) - length = strOffsets.GetU64(&baseOffset); + if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) { + if (const auto *contribution = + entry->getContribution(llvm::DW_SECT_STR_OFFSETS)) + baseOffset = contribution->Offset; + else + return; + } - // Check version. - if (strOffsets.GetU16(&baseOffset) < 5) - return; + if (GetVersion() >= 5) { + const DWARFDataExtractor &strOffsets = + GetSymbolFileDWARF().GetDWARFContext().getOrLoadStrOffsetsData(); + uint64_t length = strOffsets.GetU32(&baseOffset); + if (length == 0xffffffff) + length = strOffsets.GetU64(&baseOffset); - // Skip padding. - baseOffset += 2; + // Check version. + if (strOffsets.GetU16(&baseOffset) < 5) + return; + + // Skip padding. + baseOffset += 2; + } - dwo_cu->SetStrOffsetsBase(baseOffset); + SetStrOffsetsBase(baseOffset); } // m_die_array_mutex must be already held as read/write. @@ -336,32 +344,27 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { } } - if (m_is_dwo) + if (m_is_dwo) { + SetDwoStrOffsetsBase(); return; + } - std::unique_ptr dwo_symbol_file = + std::shared_ptr dwo_symbol_file = m_dwarf.GetDwoSymbolFileForCompileUnit(*this, cu_die); if (!dwo_symbol_file) return; - DWARFUnit *dwo_cu = dwo_symbol_file->GetCompileUnit(); + uint64_t main_dwo_id = + cu_die.GetAttributeValueAsUnsigned(this, DW_AT_GNU_dwo_id, 0); + DWARFUnit *dwo_cu = dwo_symbol_file->GetDWOCompileUnitForHash(main_dwo_id); if (!dwo_cu) return; // Can't fetch the compile unit from the dwo file. + dwo_cu->SetUserData(this); DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly(); if (!dwo_cu_die.IsValid()) return; // Can't fetch the compile unit DIE from the dwo file. - uint64_t main_dwo_id = - cu_die.GetAttributeValueAsUnsigned(this, DW_AT_GNU_dwo_id, 0); - uint64_t sub_dwo_id = - dwo_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0); - if (main_dwo_id != sub_dwo_id) - return; // The 2 dwo ID isn't match. Don't use the dwo file as it belongs to - // a differectn compilation. - - m_dwo_symbol_file = std::move(dwo_symbol_file); - // 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_* @@ -375,21 +378,18 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { if (GetVersion() <= 4 && gnu_ranges_base) dwo_cu->SetRangesBase(*gnu_ranges_base); - else if (m_dwo_symbol_file->GetDWARFContext() + else if (dwo_symbol_file->GetDWARFContext() .getOrLoadRngListsData() .GetByteSize() > 0) dwo_cu->SetRangesBase(llvm::DWARFListTableHeader::getHeaderSize(DWARF32)); - if (GetVersion() >= 5 && m_dwo_symbol_file->GetDWARFContext() - .getOrLoadLocListsData() - .GetByteSize() > 0) + if (GetVersion() >= 5 && + dwo_symbol_file->GetDWARFContext().getOrLoadLocListsData().GetByteSize() > + 0) dwo_cu->SetLoclistsBase(llvm::DWARFListTableHeader::getHeaderSize(DWARF32)); dwo_cu->SetBaseAddress(GetBaseAddress()); - for (size_t i = 0; i < m_dwo_symbol_file->DebugInfo()->GetNumUnits(); ++i) { - DWARFUnit *unit = m_dwo_symbol_file->DebugInfo()->GetUnitAtIndex(i); - SetDwoStrOffsetsBase(unit); - } + m_dwo = std::shared_ptr(std::move(dwo_symbol_file), dwo_cu); } DWARFDIE DWARFUnit::LookupAddress(const dw_addr_t address) { @@ -467,18 +467,25 @@ void DWARFUnit::SetLoclistsBase(dw_addr_t loclists_base) { std::unique_ptr DWARFUnit::GetLocationTable(const DataExtractor &data) const { llvm::DWARFDataExtractor llvm_data( - toStringRef(data.GetData()), - data.GetByteOrder() == lldb::eByteOrderLittle, data.GetAddressByteSize()); + data.GetData(), data.GetByteOrder() == lldb::eByteOrderLittle, + data.GetAddressByteSize()); if (m_is_dwo || GetVersion() >= 5) return std::make_unique(llvm_data, GetVersion()); return std::make_unique(llvm_data); } -const DWARFDataExtractor &DWARFUnit::GetLocationData() const { +DWARFDataExtractor DWARFUnit::GetLocationData() const { DWARFContext &Ctx = GetSymbolFileDWARF().GetDWARFContext(); - return GetVersion() >= 5 ? Ctx.getOrLoadLocListsData() - : Ctx.getOrLoadLocData(); + const DWARFDataExtractor &data = + GetVersion() >= 5 ? Ctx.getOrLoadLocListsData() : Ctx.getOrLoadLocData(); + if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) { + if (const auto *contribution = entry->getContribution(llvm::DW_SECT_EXT_LOC)) + return DWARFDataExtractor(data, contribution->Offset, + contribution->Length); + return DWARFDataExtractor(); + } + return data; } void DWARFUnit::SetRangesBase(dw_addr_t ranges_base) { @@ -506,18 +513,14 @@ void DWARFUnit::ClearDIEsRWLocked() { m_die_array.clear(); m_die_array.shrink_to_fit(); - if (m_dwo_symbol_file) - m_dwo_symbol_file->GetCompileUnit()->ClearDIEsRWLocked(); + if (m_dwo) + m_dwo->ClearDIEsRWLocked(); } lldb::ByteOrder DWARFUnit::GetByteOrder() const { return m_dwarf.GetObjectFile()->GetByteOrder(); } -llvm::Expected DWARFUnit::GetTypeSystem() { - return m_dwarf.GetTypeSystemForLanguage(GetLanguageType()); -} - void DWARFUnit::SetBaseAddress(dw_addr_t base_addr) { m_base_addr = base_addr; } // Compare function DWARFDebugAranges::Range structures @@ -534,9 +537,6 @@ static bool CompareDIEOffset(const DWARFDebugInfoEntry &die, DWARFDIE DWARFUnit::GetDIE(dw_offset_t die_offset) { if (die_offset != DW_INVALID_OFFSET) { - if (GetDwoSymbolFile()) - return GetDwoSymbolFile()->GetCompileUnit()->GetDIE(die_offset); - if (ContainsDIEOffset(die_offset)) { ExtractDIEsIfNeeded(); DWARFDebugInfoEntry::const_iterator end = m_die_array.cend(); @@ -555,8 +555,9 @@ DWARFUnit::GetDIE(dw_offset_t die_offset) { } DWARFUnit &DWARFUnit::GetNonSkeletonUnit() { - if (SymbolFileDWARFDwo *dwo = GetDwoSymbolFile()) - return *dwo->GetCompileUnit(); + ExtractUnitDIEIfNeeded(); + if (m_dwo) + return *m_dwo; return *this; } @@ -570,11 +571,7 @@ uint8_t DWARFUnit::GetDefaultAddressSize() { return 4; } void *DWARFUnit::GetUserData() const { return m_user_data; } -void DWARFUnit::SetUserData(void *d) { - m_user_data = d; - if (m_dwo_symbol_file) - m_dwo_symbol_file->GetCompileUnit()->SetUserData(d); -} +void DWARFUnit::SetUserData(void *d) { m_user_data = d; } bool DWARFUnit::Supports_DW_AT_APPLE_objc_complete_type() { return GetProducer() != eProducerLLVMGCC; @@ -658,28 +655,17 @@ uint32_t DWARFUnit::GetProducerVersionUpdate() { ParseProducerInfo(); return m_producer_version_update; } -LanguageType DWARFUnit::LanguageTypeFromDWARF(uint64_t val) { - // Note: user languages between lo_user and hi_user must be handled - // explicitly here. - switch (val) { - case DW_LANG_Mips_Assembler: - return eLanguageTypeMipsAssembler; - case DW_LANG_GOOGLE_RenderScript: - return eLanguageTypeExtRenderScript; - default: - return static_cast(val); - } -} -LanguageType DWARFUnit::GetLanguageType() { - if (m_language_type != eLanguageTypeUnknown) - return m_language_type; +uint64_t DWARFUnit::GetDWARFLanguageType() { + if (m_language_type) + return *m_language_type; const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); - if (die) - m_language_type = LanguageTypeFromDWARF( - die->GetAttributeValueAsUnsigned(this, DW_AT_language, 0)); - return m_language_type; + if (!die) + m_language_type = 0; + else + m_language_type = die->GetAttributeValueAsUnsigned(this, DW_AT_language, 0); + return *m_language_type; } bool DWARFUnit::GetIsOptimized() { @@ -738,25 +724,6 @@ removeHostnameFromPathname(llvm::StringRef path_from_dwarf) { return path; } -static FileSpec resolveCompDir(const FileSpec &path) { - bool is_symlink = SymbolFileDWARF::GetSymlinkPaths().FindFileIndex( - 0, path, /*full*/ true) != UINT32_MAX; - - if (!is_symlink) - return path; - - namespace fs = llvm::sys::fs; - if (fs::get_file_type(path.GetPath(), false) != fs::file_type::symlink_file) - return path; - - FileSpec resolved_symlink; - const auto error = FileSystem::Instance().Readlink(path, resolved_symlink); - if (error.Success()) - return resolved_symlink; - - return path; -} - void DWARFUnit::ComputeCompDirAndGuessPathStyle() { m_comp_dir = FileSpec(); const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); @@ -768,7 +735,7 @@ void DWARFUnit::ComputeCompDirAndGuessPathStyle() { if (!comp_dir.empty()) { FileSpec::Style comp_dir_style = FileSpec::GuessPathStyle(comp_dir).getValueOr(FileSpec::Style::native); - m_comp_dir = resolveCompDir(FileSpec(comp_dir, comp_dir_style)); + m_comp_dir = FileSpec(comp_dir, comp_dir_style); } else { // Try to detect the style based on the DW_AT_name attribute, but just store // the detected style in the m_comp_dir field. @@ -795,21 +762,22 @@ void DWARFUnit::ComputeAbsolutePath() { SymbolFileDWARFDwo *DWARFUnit::GetDwoSymbolFile() { ExtractUnitDIEIfNeeded(); - return m_dwo_symbol_file.get(); + if (m_dwo) + return &llvm::cast(m_dwo->GetSymbolFileDWARF()); + return nullptr; } const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() { if (m_func_aranges_up == nullptr) { - m_func_aranges_up.reset(new DWARFDebugAranges()); + m_func_aranges_up = std::make_unique(); const DWARFDebugInfoEntry *die = DIEPtr(); if (die) die->BuildFunctionAddressRangeTable(this, m_func_aranges_up.get()); - if (m_dwo_symbol_file) { - DWARFUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit(); - const DWARFDebugInfoEntry *dwo_die = dwo_cu->DIEPtr(); + if (m_dwo) { + const DWARFDebugInfoEntry *dwo_die = m_dwo->DIEPtr(); if (dwo_die) - dwo_die->BuildFunctionAddressRangeTable(dwo_cu, + dwo_die->BuildFunctionAddressRangeTable(m_dwo.get(), m_func_aranges_up.get()); } @@ -820,10 +788,13 @@ const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() { } llvm::Expected -DWARFUnitHeader::extract(const DWARFDataExtractor &data, DIERef::Section section, - lldb::offset_t *offset_ptr) { +DWARFUnitHeader::extract(const DWARFDataExtractor &data, + DIERef::Section section, lldb::offset_t *offset_ptr, + const llvm::DWARFUnitIndex *index) { DWARFUnitHeader header; header.m_offset = *offset_ptr; + if (index) + header.m_index_entry = index->getFromOffset(*offset_ptr); header.m_length = data.GetDWARFInitialLength(offset_ptr); header.m_version = data.GetU16(offset_ptr); if (header.m_version == 5) { @@ -839,6 +810,26 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data, DIERef::Section section section == DIERef::Section::DebugTypes ? DW_UT_type : DW_UT_compile; } + if (header.m_index_entry) { + if (header.m_abbr_offset) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Package unit with a non-zero abbreviation offset"); + } + auto *unit_contrib = header.m_index_entry->getContribution(); + if (!unit_contrib || unit_contrib->Length != header.m_length + 4) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Inconsistent DWARF package unit index"); + } + auto *abbr_entry = + header.m_index_entry->getContribution(llvm::DW_SECT_ABBREV); + if (!abbr_entry) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "DWARF package index missing abbreviation column"); + } + header.m_abbr_offset = abbr_entry->Offset; + } if (header.IsTypeUnit()) { header.m_type_hash = data.GetU64(offset_ptr); header.m_type_offset = data.GetDWARFOffset(offset_ptr); @@ -869,11 +860,12 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data, DIERef::Section section llvm::Expected DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid, const DWARFDataExtractor &debug_info, - DIERef::Section section, lldb::offset_t *offset_ptr) { + DIERef::Section section, lldb::offset_t *offset_ptr, + const llvm::DWARFUnitIndex *index) { assert(debug_info.ValidOffset(*offset_ptr)); auto expected_header = - DWARFUnitHeader::extract(debug_info, section, offset_ptr); + DWARFUnitHeader::extract(debug_info, section, offset_ptr, index); if (!expected_header) return expected_header.takeError(); @@ -924,6 +916,12 @@ uint32_t DWARFUnit::GetHeaderByteSize() const { llvm_unreachable("invalid UnitType."); } +llvm::Optional +DWARFUnit::GetStringOffsetSectionItem(uint32_t index) const { + offset_t offset = GetStrOffsetsBase() + index * 4; + return m_dwarf.GetDWARFContext().getOrLoadStrOffsetsData().GetU32(&offset); +} + llvm::Expected DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) { if (GetVersion() <= 4) { diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index 217f9bb89ac..affad286a49 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -6,12 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_DWARFUnit_h_ -#define SymbolFileDWARF_DWARFUnit_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFUNIT_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFUNIT_H #include "DWARFDIE.h" #include "DWARFDebugInfoEntry.h" #include "lldb/lldb-enumerations.h" +#include "lldb/Utility/XcodeSDK.h" #include "llvm/Support/RWMutex.h" #include @@ -39,6 +40,9 @@ class DWARFUnitHeader { dw_offset_t m_length = 0; uint16_t m_version = 0; dw_offset_t m_abbr_offset = 0; + + const llvm::DWARFUnitIndex::Entry *m_index_entry = nullptr; + uint8_t m_unit_type = 0; uint8_t m_addr_size = 0; @@ -56,6 +60,9 @@ public: dw_offset_t GetLength() const { return m_length; } dw_offset_t GetAbbrOffset() const { return m_abbr_offset; } uint8_t GetUnitType() const { return m_unit_type; } + const llvm::DWARFUnitIndex::Entry *GetIndexEntry() const { + return m_index_entry; + } uint64_t GetTypeHash() const { return m_type_hash; } dw_offset_t GetTypeOffset() const { return m_type_offset; } bool IsTypeUnit() const { @@ -65,7 +72,7 @@ public: static llvm::Expected extract(const lldb_private::DWARFDataExtractor &data, DIERef::Section section, - lldb::offset_t *offset_ptr); + lldb::offset_t *offset_ptr, const llvm::DWARFUnitIndex *index); }; class DWARFUnit : public lldb_private::UserID { @@ -76,9 +83,12 @@ public: static llvm::Expected extract(SymbolFileDWARF &dwarf2Data, lldb::user_id_t uid, const lldb_private::DWARFDataExtractor &debug_info, - DIERef::Section section, lldb::offset_t *offset_ptr); + DIERef::Section section, lldb::offset_t *offset_ptr, + const llvm::DWARFUnitIndex *index); virtual ~DWARFUnit(); + bool IsDWOUnit() { return m_is_dwo; } + void ExtractUnitDIEIfNeeded(); void ExtractDIEsIfNeeded(); @@ -88,7 +98,8 @@ public: bool m_clear_dies = false; ScopedExtractDIEs(DWARFUnit &cu); ~ScopedExtractDIEs(); - DISALLOW_COPY_AND_ASSIGN(ScopedExtractDIEs); + ScopedExtractDIEs(const ScopedExtractDIEs &) = delete; + const ScopedExtractDIEs &operator=(const ScopedExtractDIEs &) = delete; ScopedExtractDIEs(ScopedExtractDIEs &&rhs); ScopedExtractDIEs &operator=(ScopedExtractDIEs &&rhs); }; @@ -152,8 +163,6 @@ public: lldb::ByteOrder GetByteOrder() const; - llvm::Expected GetTypeSystem(); - const DWARFDebugAranges &GetFunctionAranges(); void SetBaseAddress(dw_addr_t base_addr); @@ -190,9 +199,7 @@ public: uint32_t GetProducerVersionUpdate(); - static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val); - - lldb::LanguageType GetLanguageType(); + uint64_t GetDWARFLanguageType(); bool GetIsOptimized(); @@ -213,6 +220,8 @@ public: uint8_t GetUnitType() const { return m_header.GetUnitType(); } bool IsTypeUnit() const { return m_header.IsTypeUnit(); } + llvm::Optional GetStringOffsetSectionItem(uint32_t index) const; + /// Return a list of address ranges resulting from a (possibly encoded) /// range list starting at a given offset in the appropriate ranges section. llvm::Expected FindRnglistFromOffset(dw_offset_t offset); @@ -248,7 +257,7 @@ public: std::unique_ptr GetLocationTable(const lldb_private::DataExtractor &data) const; - const lldb_private::DWARFDataExtractor &GetLocationData() const; + lldb_private::DWARFDataExtractor GetLocationData() const; protected: DWARFUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid, @@ -279,7 +288,7 @@ protected: } SymbolFileDWARF &m_dwarf; - std::unique_ptr m_dwo_symbol_file; + std::shared_ptr m_dwo; DWARFUnitHeader m_header; const DWARFAbbreviationDeclarationSet *m_abbrevs = nullptr; void *m_user_data = nullptr; @@ -304,7 +313,7 @@ protected: uint32_t m_producer_version_major = 0; uint32_t m_producer_version_minor = 0; uint32_t m_producer_version_update = 0; - lldb::LanguageType m_language_type = lldb::eLanguageTypeUnknown; + llvm::Optional m_language_type; lldb_private::LazyBool m_is_optimized = lldb_private::eLazyBoolCalculate; llvm::Optional m_comp_dir; llvm::Optional m_file_spec; @@ -329,11 +338,13 @@ private: void ClearDIEsRWLocked(); void AddUnitDIE(const DWARFDebugInfoEntry &cu_die); + void SetDwoStrOffsetsBase(); void ComputeCompDirAndGuessPathStyle(); void ComputeAbsolutePath(); - DISALLOW_COPY_AND_ASSIGN(DWARFUnit); + DWARFUnit(const DWARFUnit &) = delete; + const DWARFUnit &operator=(const DWARFUnit &) = delete; }; -#endif // SymbolFileDWARF_DWARFUnit_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFUNIT_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp index 007ef2e05e5..cb3e662a6cd 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -1,4 +1,4 @@ -//===-- DebugNamesDWARFIndex.cpp -------------------------------*- C++ -*-===// +//===-- DebugNamesDWARFIndex.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,6 +10,7 @@ #include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h" #include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h" +#include "lldb/Core/Module.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Stream.h" @@ -19,18 +20,14 @@ using namespace lldb; llvm::Expected> DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names, DWARFDataExtractor debug_str, - DWARFDebugInfo *debug_info) { - if (!debug_info) { - return llvm::make_error("debug info null", - llvm::inconvertibleErrorCode()); - } + SymbolFileDWARF &dwarf) { auto index_up = std::make_unique(debug_names.GetAsLLVM(), debug_str.GetAsLLVM()); if (llvm::Error E = index_up->extract()) return std::move(E); return std::unique_ptr(new DebugNamesDWARFIndex( - module, std::move(index_up), debug_names, debug_str, *debug_info)); + module, std::move(index_up), debug_names, debug_str, dwarf)); } llvm::DenseSet @@ -53,12 +50,7 @@ DebugNamesDWARFIndex::ToDIERef(const DebugNames::Entry &entry) { if (!cu) return llvm::None; - // This initializes the DWO symbol file. It's not possible for - // GetDwoSymbolFile to call this automatically because of mutual recursion - // between this and DWARFDebugInfoEntry::GetAttributeValue. - cu->ExtractUnitDIEIfNeeded(); cu = &cu->GetNonSkeletonUnit(); - if (llvm::Optional die_offset = entry.getDIEUnitOffset()) return DIERef(cu->GetSymbolFileDWARF().GetDwoNum(), DIERef::Section::DebugInfo, cu->GetOffset() + *die_offset); @@ -66,10 +58,18 @@ DebugNamesDWARFIndex::ToDIERef(const DebugNames::Entry &entry) { return llvm::None; } -void DebugNamesDWARFIndex::Append(const DebugNames::Entry &entry, - DIEArray &offsets) { - if (llvm::Optional ref = ToDIERef(entry)) - offsets.push_back(*ref); +bool DebugNamesDWARFIndex::ProcessEntry( + const DebugNames::Entry &entry, + llvm::function_ref callback, llvm::StringRef name) { + llvm::Optional ref = ToDIERef(entry); + if (!ref) + return true; + SymbolFileDWARF &dwarf = + *llvm::cast(m_module.GetSymbolFile()); + DWARFDIE die = dwarf.GetDIE(*ref); + if (!die) + return true; + return callback(die); } void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error, @@ -83,23 +83,23 @@ void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error, ni.getUnitOffset(), name); } -void DebugNamesDWARFIndex::GetGlobalVariables(ConstString basename, - DIEArray &offsets) { - m_fallback.GetGlobalVariables(basename, offsets); - +void DebugNamesDWARFIndex::GetGlobalVariables( + ConstString basename, llvm::function_ref callback) { for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(basename.GetStringRef())) { if (entry.tag() != DW_TAG_variable) continue; - Append(entry, offsets); + if (!ProcessEntry(entry, callback, basename.GetStringRef())) + return; } -} -void DebugNamesDWARFIndex::GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) { - m_fallback.GetGlobalVariables(regex, offsets); + m_fallback.GetGlobalVariables(basename, callback); +} +void DebugNamesDWARFIndex::GetGlobalVariables( + const RegularExpression ®ex, + llvm::function_ref callback) { for (const DebugNames::NameIndex &ni: *m_debug_names_up) { for (DebugNames::NameTableEntry nte: ni) { if (!regex.Execute(nte.getString())) @@ -111,17 +111,19 @@ void DebugNamesDWARFIndex::GetGlobalVariables(const RegularExpression ®ex, if (entry_or->tag() != DW_TAG_variable) continue; - Append(*entry_or, offsets); + if (!ProcessEntry(*entry_or, callback, + llvm::StringRef(nte.getString()))) + return; } MaybeLogLookupError(entry_or.takeError(), ni, nte.getString()); } } -} -void DebugNamesDWARFIndex::GetGlobalVariables(const DWARFUnit &cu, - DIEArray &offsets) { - m_fallback.GetGlobalVariables(cu, offsets); + m_fallback.GetGlobalVariables(regex, callback); +} +void DebugNamesDWARFIndex::GetGlobalVariables( + const DWARFUnit &cu, llvm::function_ref callback) { uint64_t cu_offset = cu.GetOffset(); for (const DebugNames::NameIndex &ni: *m_debug_names_up) { for (DebugNames::NameTableEntry nte: ni) { @@ -133,18 +135,20 @@ void DebugNamesDWARFIndex::GetGlobalVariables(const DWARFUnit &cu, if (entry_or->getCUOffset() != cu_offset) continue; - Append(*entry_or, offsets); + if (!ProcessEntry(*entry_or, callback, + llvm::StringRef(nte.getString()))) + return; } MaybeLogLookupError(entry_or.takeError(), ni, nte.getString()); } } -} -void DebugNamesDWARFIndex::GetCompleteObjCClass(ConstString class_name, - bool must_be_implementation, - DIEArray &offsets) { - m_fallback.GetCompleteObjCClass(class_name, must_be_implementation, offsets); + m_fallback.GetGlobalVariables(cu, callback); +} +void DebugNamesDWARFIndex::GetCompleteObjCClass( + ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) { // Keep a list of incomplete types as fallback for when we don't find the // complete type. DIEArray incomplete_types; @@ -165,84 +169,98 @@ void DebugNamesDWARFIndex::GetCompleteObjCClass(ConstString class_name, continue; } - // FIXME: We should return DWARFDIEs so we don't have to resolve it twice. DWARFDIE die = m_debug_info.GetDIE(*ref); - if (!die) + if (!die) { + ReportInvalidDIERef(*ref, class_name.GetStringRef()); continue; + } if (die.GetAttributeValueAsUnsigned(DW_AT_APPLE_objc_complete_type, 0)) { // If we find the complete version we're done. - offsets.push_back(*ref); + callback(die); return; - } else { - incomplete_types.push_back(*ref); } + incomplete_types.push_back(*ref); } - offsets.insert(offsets.end(), incomplete_types.begin(), - incomplete_types.end()); -} + auto dierefcallback = DIERefCallback(callback, class_name.GetStringRef()); + for (DIERef ref : incomplete_types) + if (!dierefcallback(ref)) + return; -void DebugNamesDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) { - m_fallback.GetTypes(name, offsets); + m_fallback.GetCompleteObjCClass(class_name, must_be_implementation, callback); +} +void DebugNamesDWARFIndex::GetTypes( + ConstString name, llvm::function_ref callback) { for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name.GetStringRef())) { - if (isType(entry.tag())) - Append(entry, offsets); + if (isType(entry.tag())) { + if (!ProcessEntry(entry, callback, name.GetStringRef())) + return; + } } -} -void DebugNamesDWARFIndex::GetTypes(const DWARFDeclContext &context, - DIEArray &offsets) { - m_fallback.GetTypes(context, offsets); + m_fallback.GetTypes(name, callback); +} - for (const DebugNames::Entry &entry : - m_debug_names_up->equal_range(context[0].name)) { - if (entry.tag() == context[0].tag) - Append(entry, offsets); +void DebugNamesDWARFIndex::GetTypes( + const DWARFDeclContext &context, + llvm::function_ref callback) { + auto name = context[0].name; + for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name)) { + if (entry.tag() == context[0].tag) { + if (!ProcessEntry(entry, callback, name)) + return; + } } -} -void DebugNamesDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) { - m_fallback.GetNamespaces(name, offsets); + m_fallback.GetTypes(context, callback); +} +void DebugNamesDWARFIndex::GetNamespaces( + ConstString name, llvm::function_ref callback) { for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name.GetStringRef())) { - if (entry.tag() == DW_TAG_namespace) - Append(entry, offsets); + if (entry.tag() == DW_TAG_namespace) { + if (!ProcessEntry(entry, callback, name.GetStringRef())) + return; + } } + + m_fallback.GetNamespaces(name, callback); } void DebugNamesDWARFIndex::GetFunctions( ConstString name, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, - std::vector &dies) { - - std::vector v; - m_fallback.GetFunctions(name, dwarf, parent_decl_ctx, name_type_mask, v); + llvm::function_ref callback) { + std::set seen; for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name.GetStringRef())) { Tag tag = entry.tag(); if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine) continue; - if (llvm::Optional ref = ToDIERef(entry)) - ProcessFunctionDIE(name.GetStringRef(), *ref, dwarf, parent_decl_ctx, - name_type_mask, v); + if (llvm::Optional ref = ToDIERef(entry)) { + if (!ProcessFunctionDIE(name.GetStringRef(), *ref, dwarf, parent_decl_ctx, + name_type_mask, [&](DWARFDIE die) { + if (!seen.insert(die.GetDIE()).second) + return true; + return callback(die); + })) + return; + } } - std::set seen; - for (DWARFDIE die : v) - if (seen.insert(die.GetDIE()).second) - dies.push_back(die); + m_fallback.GetFunctions(name, dwarf, parent_decl_ctx, name_type_mask, + callback); } -void DebugNamesDWARFIndex::GetFunctions(const RegularExpression ®ex, - DIEArray &offsets) { - m_fallback.GetFunctions(regex, offsets); - +void DebugNamesDWARFIndex::GetFunctions( + const RegularExpression ®ex, + llvm::function_ref callback) { for (const DebugNames::NameIndex &ni: *m_debug_names_up) { for (DebugNames::NameTableEntry nte: ni) { if (!regex.Execute(nte.getString())) @@ -255,11 +273,15 @@ void DebugNamesDWARFIndex::GetFunctions(const RegularExpression ®ex, if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine) continue; - Append(*entry_or, offsets); + if (!ProcessEntry(*entry_or, callback, + llvm::StringRef(nte.getString()))) + return; } MaybeLogLookupError(entry_or.takeError(), ni, nte.getString()); } } + + m_fallback.GetFunctions(regex, callback); } void DebugNamesDWARFIndex::Dump(Stream &s) { diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h index dca25496373..5d041c36c8f 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h @@ -6,12 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_DEBUGNAMESDWARFINDEX_H -#define LLDB_DEBUGNAMESDWARFINDEX_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DEBUGNAMESDWARFINDEX_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DEBUGNAMESDWARFINDEX_H #include "Plugins/SymbolFile/DWARF/DWARFIndex.h" #include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h" #include "Plugins/SymbolFile/DWARF/ManualDWARFIndex.h" +#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" #include "lldb/Utility/ConstString.h" #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" @@ -20,28 +21,38 @@ class DebugNamesDWARFIndex : public DWARFIndex { public: static llvm::Expected> Create(Module &module, DWARFDataExtractor debug_names, - DWARFDataExtractor debug_str, DWARFDebugInfo *debug_info); + DWARFDataExtractor debug_str, SymbolFileDWARF &dwarf); void Preload() override { m_fallback.Preload(); } - void GetGlobalVariables(ConstString basename, DIEArray &offsets) override; - void GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) override; - void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override; - void GetObjCMethods(ConstString class_name, DIEArray &offsets) override {} - void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, - DIEArray &offsets) override; - void GetTypes(ConstString name, DIEArray &offsets) override; - void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override; - void GetNamespaces(ConstString name, DIEArray &offsets) override; + void + GetGlobalVariables(ConstString basename, + llvm::function_ref callback) override; + void + GetGlobalVariables(const RegularExpression ®ex, + llvm::function_ref callback) override; + void + GetGlobalVariables(const DWARFUnit &cu, + llvm::function_ref callback) override; + void + GetObjCMethods(ConstString class_name, + llvm::function_ref callback) override {} + void GetCompleteObjCClass( + ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) override; + void GetTypes(ConstString name, + llvm::function_ref callback) override; + void GetTypes(const DWARFDeclContext &context, + llvm::function_ref callback) override; + void GetNamespaces(ConstString name, + llvm::function_ref callback) override; void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, - std::vector &dies) override; + llvm::function_ref callback) override; void GetFunctions(const RegularExpression ®ex, - DIEArray &offsets) override; + llvm::function_ref callback) override; - void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override {} void Dump(Stream &s) override; private: @@ -49,11 +60,11 @@ private: std::unique_ptr debug_names_up, DWARFDataExtractor debug_names_data, DWARFDataExtractor debug_str_data, - DWARFDebugInfo &debug_info) - : DWARFIndex(module), m_debug_info(debug_info), + SymbolFileDWARF &dwarf) + : DWARFIndex(module), m_debug_info(dwarf.DebugInfo()), m_debug_names_data(debug_names_data), m_debug_str_data(debug_str_data), m_debug_names_up(std::move(debug_names_up)), - m_fallback(module, &debug_info, GetUnits(*m_debug_names_up)) {} + m_fallback(module, dwarf, GetUnits(*m_debug_names_up)) {} DWARFDebugInfo &m_debug_info; @@ -67,7 +78,9 @@ private: ManualDWARFIndex m_fallback; llvm::Optional ToDIERef(const DebugNames::Entry &entry); - void Append(const DebugNames::Entry &entry, DIEArray &offsets); + bool ProcessEntry(const DebugNames::Entry &entry, + llvm::function_ref callback, + llvm::StringRef name); static void MaybeLogLookupError(llvm::Error error, const DebugNames::NameIndex &ni, @@ -78,4 +91,4 @@ private: } // namespace lldb_private -#endif // LLDB_DEBUGNAMESDWARFINDEX_H +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DEBUGNAMESDWARFINDEX_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp index 88a29f4a267..d36f2a8bccf 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp @@ -1,4 +1,4 @@ -//===-- HashedNameToDIE.cpp -------------------------------------*- C++ -*-===// +//===-- HashedNameToDIE.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,91 +9,99 @@ #include "HashedNameToDIE.h" #include "llvm/ADT/StringRef.h" -void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array, - DIEArray &die_offsets) { +bool DWARFMappedHash::ExtractDIEArray( + const DIEInfoArray &die_info_array, + llvm::function_ref callback) { const size_t count = die_info_array.size(); for (size_t i = 0; i < count; ++i) - die_offsets.emplace_back(die_info_array[i]); + if (!callback(DIERef(die_info_array[i]))) + return false; + return true; } -void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array, - const dw_tag_t tag, - DIEArray &die_offsets) { +void DWARFMappedHash::ExtractDIEArray( + const DIEInfoArray &die_info_array, const dw_tag_t tag, + llvm::function_ref callback) { if (tag == 0) { - ExtractDIEArray(die_info_array, die_offsets); - } else { - const size_t count = die_info_array.size(); - for (size_t i = 0; i < count; ++i) { - const dw_tag_t die_tag = die_info_array[i].tag; - bool tag_matches = die_tag == 0 || tag == die_tag; - if (!tag_matches) { - if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type) - tag_matches = - tag == DW_TAG_structure_type || tag == DW_TAG_class_type; - } - if (tag_matches) - die_offsets.emplace_back(die_info_array[i]); + ExtractDIEArray(die_info_array, callback); + return; + } + + const size_t count = die_info_array.size(); + for (size_t i = 0; i < count; ++i) { + const dw_tag_t die_tag = die_info_array[i].tag; + bool tag_matches = die_tag == 0 || tag == die_tag; + if (!tag_matches) { + if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type) + tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type; + } + if (tag_matches) { + if (!callback(DIERef(die_info_array[i]))) + return; } } } -void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array, - const dw_tag_t tag, - const uint32_t qualified_name_hash, - DIEArray &die_offsets) { +void DWARFMappedHash::ExtractDIEArray( + const DIEInfoArray &die_info_array, const dw_tag_t tag, + const uint32_t qualified_name_hash, + llvm::function_ref callback) { if (tag == 0) { - ExtractDIEArray(die_info_array, die_offsets); - } else { - const size_t count = die_info_array.size(); - for (size_t i = 0; i < count; ++i) { - if (qualified_name_hash != die_info_array[i].qualified_name_hash) - continue; - const dw_tag_t die_tag = die_info_array[i].tag; - bool tag_matches = die_tag == 0 || tag == die_tag; - if (!tag_matches) { - if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type) - tag_matches = - tag == DW_TAG_structure_type || tag == DW_TAG_class_type; - } - if (tag_matches) - die_offsets.emplace_back(die_info_array[i]); + ExtractDIEArray(die_info_array, callback); + return; + } + + const size_t count = die_info_array.size(); + for (size_t i = 0; i < count; ++i) { + if (qualified_name_hash != die_info_array[i].qualified_name_hash) + continue; + const dw_tag_t die_tag = die_info_array[i].tag; + bool tag_matches = die_tag == 0 || tag == die_tag; + if (!tag_matches) { + if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type) + tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type; + } + if (tag_matches) { + if (!callback(DIERef(die_info_array[i]))) + return; } } } void DWARFMappedHash::ExtractClassOrStructDIEArray( const DIEInfoArray &die_info_array, - bool return_implementation_only_if_available, DIEArray &die_offsets) { + bool return_implementation_only_if_available, + llvm::function_ref callback) { const size_t count = die_info_array.size(); for (size_t i = 0; i < count; ++i) { const dw_tag_t die_tag = die_info_array[i].tag; - if (die_tag == 0 || die_tag == DW_TAG_class_type || - die_tag == DW_TAG_structure_type) { - if (die_info_array[i].type_flags & eTypeFlagClassIsImplementation) { - if (return_implementation_only_if_available) { - // We found the one true definition for this class, so only return - // that - die_offsets.clear(); - die_offsets.emplace_back(die_info_array[i]); - return; - } else { - // Put the one true definition as the first entry so it matches first - die_offsets.emplace(die_offsets.begin(), die_info_array[i]); - } - } else { - die_offsets.emplace_back(die_info_array[i]); - } + if (!(die_tag == 0 || die_tag == DW_TAG_class_type || + die_tag == DW_TAG_structure_type)) + continue; + bool is_implementation = + (die_info_array[i].type_flags & eTypeFlagClassIsImplementation) != 0; + if (is_implementation != return_implementation_only_if_available) + continue; + if (return_implementation_only_if_available) { + // We found the one true definition for this class, so only return + // that + callback(DIERef(die_info_array[i])); + return; } + if (!callback(DIERef(die_info_array[i]))) + return; } } void DWARFMappedHash::ExtractTypesFromDIEArray( const DIEInfoArray &die_info_array, uint32_t type_flag_mask, - uint32_t type_flag_value, DIEArray &die_offsets) { + uint32_t type_flag_value, llvm::function_ref callback) { const size_t count = die_info_array.size(); for (size_t i = 0; i < count; ++i) { - if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value) - die_offsets.emplace_back(die_info_array[i]); + if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value) { + if (!callback(DIERef(die_info_array[i]))) + return; + } } } @@ -453,7 +461,7 @@ DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression( } } -size_t DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex( +void DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex( const lldb_private::RegularExpression ®ex, DIEInfoArray &die_info_array) const { const uint32_t hash_count = m_header.hashes_count; @@ -482,10 +490,9 @@ size_t DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex( } } die_info_array.swap(pair.value); - return die_info_array.size(); } -size_t DWARFMappedHash::MemoryTable::AppendAllDIEsInRange( +void DWARFMappedHash::MemoryTable::AppendAllDIEsInRange( const uint32_t die_offset_start, const uint32_t die_offset_end, DIEInfoArray &die_info_array) const { const uint32_t hash_count = m_header.hashes_count; @@ -512,73 +519,74 @@ size_t DWARFMappedHash::MemoryTable::AppendAllDIEsInRange( } } } - return die_info_array.size(); } -size_t DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name, - DIEArray &die_offsets) { +bool DWARFMappedHash::MemoryTable::FindByName( + llvm::StringRef name, llvm::function_ref callback) { if (name.empty()) - return 0; + return true; DIEInfoArray die_info_array; - if (FindByName(name, die_info_array)) - DWARFMappedHash::ExtractDIEArray(die_info_array, die_offsets); - return die_info_array.size(); + FindByName(name, die_info_array); + return DWARFMappedHash::ExtractDIEArray(die_info_array, callback); } -size_t DWARFMappedHash::MemoryTable::FindByNameAndTag(llvm::StringRef name, - const dw_tag_t tag, - DIEArray &die_offsets) { +void DWARFMappedHash::MemoryTable::FindByNameAndTag( + llvm::StringRef name, const dw_tag_t tag, + llvm::function_ref callback) { DIEInfoArray die_info_array; - if (FindByName(name, die_info_array)) - DWARFMappedHash::ExtractDIEArray(die_info_array, tag, die_offsets); - return die_info_array.size(); + FindByName(name, die_info_array); + DWARFMappedHash::ExtractDIEArray(die_info_array, tag, callback); } -size_t DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash( +void DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash( llvm::StringRef name, const dw_tag_t tag, - const uint32_t qualified_name_hash, DIEArray &die_offsets) { + const uint32_t qualified_name_hash, + llvm::function_ref callback) { DIEInfoArray die_info_array; - if (FindByName(name, die_info_array)) - DWARFMappedHash::ExtractDIEArray(die_info_array, tag, qualified_name_hash, - die_offsets); - return die_info_array.size(); + FindByName(name, die_info_array); + DWARFMappedHash::ExtractDIEArray(die_info_array, tag, qualified_name_hash, + callback); } -size_t DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName( - llvm::StringRef name, DIEArray &die_offsets, bool must_be_implementation) { +void DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName( + llvm::StringRef name, llvm::function_ref callback, + bool must_be_implementation) { DIEInfoArray die_info_array; - if (FindByName(name, die_info_array)) { - if (must_be_implementation && - GetHeader().header_data.ContainsAtom(eAtomTypeTypeFlags)) { - // If we have two atoms, then we have the DIE offset and the type flags - // so we can find the objective C class efficiently. - DWARFMappedHash::ExtractTypesFromDIEArray(die_info_array, UINT32_MAX, - eTypeFlagClassIsImplementation, - die_offsets); - } else { - // We don't only want the one true definition, so try and see what we can - // find, and only return class or struct DIEs. If we do have the full - // implementation, then return it alone, else return all possible - // matches. - const bool return_implementation_only_if_available = true; - DWARFMappedHash::ExtractClassOrStructDIEArray( - die_info_array, return_implementation_only_if_available, die_offsets); - } + FindByName(name, die_info_array); + if (must_be_implementation && + GetHeader().header_data.ContainsAtom(eAtomTypeTypeFlags)) { + // If we have two atoms, then we have the DIE offset and the type flags + // so we can find the objective C class efficiently. + DWARFMappedHash::ExtractTypesFromDIEArray( + die_info_array, UINT32_MAX, eTypeFlagClassIsImplementation, callback); + return; } - return die_offsets.size(); + // We don't only want the one true definition, so try and see what we can + // find, and only return class or struct DIEs. If we do have the full + // implementation, then return it alone, else return all possible + // matches. + bool found_implementation = false; + DWARFMappedHash::ExtractClassOrStructDIEArray( + die_info_array, true /*return_implementation_only_if_available*/, + [&](DIERef ref) { + found_implementation = true; + // Here the return value does not matter as we are called at most once. + return callback(ref); + }); + if (found_implementation) + return; + DWARFMappedHash::ExtractClassOrStructDIEArray( + die_info_array, false /*return_implementation_only_if_available*/, + callback); } -size_t DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name, - DIEInfoArray &die_info_array) { +void DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name, + DIEInfoArray &die_info_array) { if (name.empty()) - return 0; + return; Pair kv_pair; - size_t old_size = die_info_array.size(); - if (Find(name, kv_pair)) { + if (Find(name, kv_pair)) die_info_array.swap(kv_pair.value); - return die_info_array.size() - old_size; - } - return 0; } diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h index 56d9bc54887..ad178fc6a98 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_HashedNameToDIE_h_ -#define SymbolFileDWARF_HashedNameToDIE_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H #include @@ -132,33 +132,36 @@ public: bool ReadHashData(uint32_t hash_data_offset, HashData &hash_data) const override; - size_t + void AppendAllDIEsThatMatchingRegex(const lldb_private::RegularExpression ®ex, DIEInfoArray &die_info_array) const; - size_t AppendAllDIEsInRange(const uint32_t die_offset_start, - const uint32_t die_offset_end, - DIEInfoArray &die_info_array) const; + void AppendAllDIEsInRange(const uint32_t die_offset_start, + const uint32_t die_offset_end, + DIEInfoArray &die_info_array) const; - size_t FindByName(llvm::StringRef name, DIEArray &die_offsets); + bool FindByName(llvm::StringRef name, + llvm::function_ref callback); - size_t FindByNameAndTag(llvm::StringRef name, const dw_tag_t tag, - DIEArray &die_offsets); + void FindByNameAndTag(llvm::StringRef name, const dw_tag_t tag, + llvm::function_ref callback); - size_t FindByNameAndTagAndQualifiedNameHash( + void FindByNameAndTagAndQualifiedNameHash( llvm::StringRef name, const dw_tag_t tag, - const uint32_t qualified_name_hash, DIEArray &die_offsets); + const uint32_t qualified_name_hash, + llvm::function_ref callback); - size_t FindCompleteObjCClassByName(llvm::StringRef name, - DIEArray &die_offsets, - bool must_be_implementation); + void + FindCompleteObjCClassByName(llvm::StringRef name, + llvm::function_ref callback, + bool must_be_implementation); protected: Result AppendHashDataForRegularExpression( const lldb_private::RegularExpression ®ex, lldb::offset_t *hash_data_offset_ptr, Pair &pair) const; - size_t FindByName(llvm::StringRef name, DIEInfoArray &die_info_array); + void FindByName(llvm::StringRef name, DIEInfoArray &die_info_array); Result GetHashDataForName(llvm::StringRef name, lldb::offset_t *hash_data_offset_ptr, @@ -169,29 +172,30 @@ public: std::string m_name; }; - static void ExtractDIEArray(const DIEInfoArray &die_info_array, - DIEArray &die_offsets); + static bool ExtractDIEArray(const DIEInfoArray &die_info_array, + llvm::function_ref callback); protected: static void ExtractDIEArray(const DIEInfoArray &die_info_array, - const dw_tag_t tag, DIEArray &die_offsets); + const dw_tag_t tag, + llvm::function_ref callback); static void ExtractDIEArray(const DIEInfoArray &die_info_array, const dw_tag_t tag, const uint32_t qualified_name_hash, - DIEArray &die_offsets); + llvm::function_ref callback); static void ExtractClassOrStructDIEArray(const DIEInfoArray &die_info_array, bool return_implementation_only_if_available, - DIEArray &die_offsets); + llvm::function_ref callback); - static void ExtractTypesFromDIEArray(const DIEInfoArray &die_info_array, - uint32_t type_flag_mask, - uint32_t type_flag_value, - DIEArray &die_offsets); + static void + ExtractTypesFromDIEArray(const DIEInfoArray &die_info_array, + uint32_t type_flag_mask, uint32_t type_flag_value, + llvm::function_ref callback); static const char *GetAtomTypeName(uint16_t atom); }; -#endif // SymbolFileDWARF_HashedNameToDIE_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp index 8495016d428..3f1d6677bac 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp @@ -1,4 +1,4 @@ -//===-- LogChannelDWARF.cpp ------------------------------------*- C++ -*-===// +//===-- LogChannelDWARF.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h index a89c686735d..2fc23563ef9 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_LogChannelDWARF_h_ -#define SymbolFileDWARF_LogChannelDWARF_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_LOGCHANNELDWARF_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_LOGCHANNELDWARF_H #include "lldb/Utility/Log.h" @@ -32,4 +32,4 @@ public: }; } -#endif // SymbolFileDWARF_LogChannelDWARF_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_LOGCHANNELDWARF_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp index 1e5927bd14f..7bf4b52bc78 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -1,4 +1,4 @@ -//===-- ManualDWARFIndex.cpp -----------------------------------*- C++ -*-===// +//===-- ManualDWARFIndex.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,31 +13,47 @@ #include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h" #include "lldb/Core/Module.h" -#include "lldb/Host/TaskPool.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/Timer.h" +#include "llvm/Support/ThreadPool.h" using namespace lldb_private; using namespace lldb; void ManualDWARFIndex::Index() { - if (!m_debug_info) + if (!m_dwarf) return; - DWARFDebugInfo &debug_info = *m_debug_info; - m_debug_info = nullptr; + SymbolFileDWARF &main_dwarf = *m_dwarf; + m_dwarf = nullptr; static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); - Timer scoped_timer(func_cat, "%p", static_cast(&debug_info)); + Timer scoped_timer(func_cat, "%p", static_cast(&main_dwarf)); + + DWARFDebugInfo &main_info = main_dwarf.DebugInfo(); + SymbolFileDWARFDwo *dwp_dwarf = main_dwarf.GetDwpSymbolFile().get(); + DWARFDebugInfo *dwp_info = dwp_dwarf ? &dwp_dwarf->DebugInfo() : nullptr; std::vector units_to_index; - units_to_index.reserve(debug_info.GetNumUnits()); - for (size_t U = 0; U < debug_info.GetNumUnits(); ++U) { - DWARFUnit *unit = debug_info.GetUnitAtIndex(U); + units_to_index.reserve(main_info.GetNumUnits() + + (dwp_info ? dwp_info->GetNumUnits() : 0)); + + // Process all units in the main file, as well as any type units in the dwp + // file. Type units in dwo files are handled when we reach the dwo file in + // IndexUnit. + for (size_t U = 0; U < main_info.GetNumUnits(); ++U) { + DWARFUnit *unit = main_info.GetUnitAtIndex(U); if (unit && m_units_to_avoid.count(unit->GetOffset()) == 0) units_to_index.push_back(unit); } + if (dwp_info && dwp_info->ContainsTypeUnits()) { + for (size_t U = 0; U < dwp_info->GetNumUnits(); ++U) { + if (auto *tu = llvm::dyn_cast(dwp_info->GetUnitAtIndex(U))) + units_to_index.push_back(tu); + } + } + if (units_to_index.empty()) return; @@ -48,27 +64,34 @@ void ManualDWARFIndex::Index() { std::vector> clear_cu_dies( units_to_index.size()); auto parser_fn = [&](size_t cu_idx) { - IndexUnit(*units_to_index[cu_idx], sets[cu_idx]); + IndexUnit(*units_to_index[cu_idx], dwp_dwarf, sets[cu_idx]); }; auto extract_fn = [&units_to_index, &clear_cu_dies](size_t cu_idx) { clear_cu_dies[cu_idx] = units_to_index[cu_idx]->ExtractDIEsScoped(); }; + // Share one thread pool across operations to avoid the overhead of + // recreating the threads. + llvm::ThreadPool pool; + // Create a task runner that extracts dies for each DWARF unit in a - // separate thread + // separate thread. // First figure out which units didn't have their DIEs already // parsed and remember this. If no DIEs were parsed prior to this index // function call, we are going to want to clear the CU dies after we are // done indexing to make sure we don't pull in all DWARF dies, but we need // to wait until all units have been indexed in case a DIE in one // unit refers to another and the indexes accesses those DIEs. - TaskMapOverInt(0, units_to_index.size(), extract_fn); + for (size_t i = 0; i < units_to_index.size(); ++i) + pool.async(extract_fn, i); + pool.wait(); // Now create a task runner that can index each DWARF unit in a // separate thread so we can index quickly. - - TaskMapOverInt(0, units_to_index.size(), parser_fn); + for (size_t i = 0; i < units_to_index.size(); ++i) + pool.async(parser_fn, i); + pool.wait(); auto finalize_fn = [this, &sets](NameToDIE(IndexSet::*index)) { NameToDIE &result = m_set.*index; @@ -77,21 +100,19 @@ void ManualDWARFIndex::Index() { result.Finalize(); }; - TaskPool::RunTasks([&]() { finalize_fn(&IndexSet::function_basenames); }, - [&]() { finalize_fn(&IndexSet::function_fullnames); }, - [&]() { finalize_fn(&IndexSet::function_methods); }, - [&]() { finalize_fn(&IndexSet::function_selectors); }, - [&]() { finalize_fn(&IndexSet::objc_class_selectors); }, - [&]() { finalize_fn(&IndexSet::globals); }, - [&]() { finalize_fn(&IndexSet::types); }, - [&]() { finalize_fn(&IndexSet::namespaces); }); + pool.async(finalize_fn, &IndexSet::function_basenames); + pool.async(finalize_fn, &IndexSet::function_fullnames); + pool.async(finalize_fn, &IndexSet::function_methods); + pool.async(finalize_fn, &IndexSet::function_selectors); + pool.async(finalize_fn, &IndexSet::objc_class_selectors); + pool.async(finalize_fn, &IndexSet::globals); + pool.async(finalize_fn, &IndexSet::types); + pool.async(finalize_fn, &IndexSet::namespaces); + pool.wait(); } -void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, IndexSet &set) { - assert( - !unit.GetSymbolFileDWARF().GetBaseCompileUnit() && - "DWARFUnit associated with .dwo or .dwp should not be indexed directly"); - +void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp, + IndexSet &set) { Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS); if (log) { @@ -100,14 +121,21 @@ void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, IndexSet &set) { unit.GetOffset()); } - const LanguageType cu_language = unit.GetLanguageType(); + const LanguageType cu_language = SymbolFileDWARF::GetLanguage(unit); IndexUnitImpl(unit, cu_language, set); if (SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile()) { - DWARFDebugInfo &dwo_info = *dwo_symbol_file->DebugInfo(); - for (size_t i = 0; i < dwo_info.GetNumUnits(); ++i) - IndexUnitImpl(*dwo_info.GetUnitAtIndex(i), cu_language, set); + // Type units in a dwp file are indexed separately, so we just need to + // process the split unit here. However, if the split unit is in a dwo file, + // then we need to process type units here. + if (dwo_symbol_file == dwp) { + IndexUnitImpl(unit.GetNonSkeletonUnit(), cu_language, set); + } else { + DWARFDebugInfo &dwo_info = dwo_symbol_file->DebugInfo(); + for (size_t i = 0; i < dwo_info.GetNumUnits(); ++i) + IndexUnitImpl(*dwo_info.GetUnitAtIndex(i), cu_language, set); + } } } @@ -165,12 +193,6 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit, is_declaration = form_value.Unsigned() != 0; break; - // case DW_AT_artificial: - // if (attributes.ExtractFormValueAtIndex(i, - // form_value)) - // is_artificial = form_value.Unsigned() != 0; - // break; - case DW_AT_MIPS_linkage_name: case DW_AT_linkage_name: if (attributes.ExtractFormValueAtIndex(i, form_value)) @@ -190,49 +212,8 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit, case DW_AT_location: case DW_AT_const_value: has_location_or_const_value = true; - if (tag == DW_TAG_variable) { - const DWARFDebugInfoEntry *parent_die = die.GetParent(); - while (parent_die != nullptr) { - switch (parent_die->Tag()) { - case DW_TAG_subprogram: - case DW_TAG_lexical_block: - case DW_TAG_inlined_subroutine: - // Even if this is a function level static, we don't add it. We - // could theoretically add these if we wanted to by - // introspecting into the DW_AT_location and seeing if the - // location describes a hard coded address, but we don't want - // the performance penalty of that right now. - is_global_or_static_variable = false; - // if (attributes.ExtractFormValueAtIndex(dwarf, i, - // form_value)) { - // // If we have valid block data, then we have location - // // expression bytesthat are fixed (not a location list). - // const uint8_t *block_data = form_value.BlockData(); - // if (block_data) { - // uint32_t block_length = form_value.Unsigned(); - // if (block_length == 1 + - // attributes.UnitAtIndex(i)->GetAddressByteSize()) { - // if (block_data[0] == DW_OP_addr) - // add_die = true; - // } - // } - // } - parent_die = nullptr; // Terminate the while loop. - break; - - case DW_TAG_compile_unit: - case DW_TAG_partial_unit: - is_global_or_static_variable = true; - parent_die = nullptr; // Terminate the while loop. - break; - - default: - parent_die = - parent_die->GetParent(); // Keep going in the while loop. - break; - } - } - } + is_global_or_static_variable = die.IsGlobalOrStaticScopeVariable(); + break; case DW_AT_specification: @@ -347,108 +328,118 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit, } } -void ManualDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) { +void ManualDWARFIndex::GetGlobalVariables( + ConstString basename, llvm::function_ref callback) { Index(); - m_set.globals.Find(basename, offsets); + m_set.globals.Find(basename, + DIERefCallback(callback, basename.GetStringRef())); } -void ManualDWARFIndex::GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) { +void ManualDWARFIndex::GetGlobalVariables( + const RegularExpression ®ex, + llvm::function_ref callback) { Index(); - m_set.globals.Find(regex, offsets); + m_set.globals.Find(regex, DIERefCallback(callback, regex.GetText())); } -void ManualDWARFIndex::GetGlobalVariables(const DWARFUnit &unit, - DIEArray &offsets) { +void ManualDWARFIndex::GetGlobalVariables( + const DWARFUnit &unit, llvm::function_ref callback) { Index(); - m_set.globals.FindAllEntriesForUnit(unit, offsets); + m_set.globals.FindAllEntriesForUnit(unit, DIERefCallback(callback)); } -void ManualDWARFIndex::GetObjCMethods(ConstString class_name, - DIEArray &offsets) { +void ManualDWARFIndex::GetObjCMethods( + ConstString class_name, llvm::function_ref callback) { Index(); - m_set.objc_class_selectors.Find(class_name, offsets); + m_set.objc_class_selectors.Find( + class_name, DIERefCallback(callback, class_name.GetStringRef())); } -void ManualDWARFIndex::GetCompleteObjCClass(ConstString class_name, - bool must_be_implementation, - DIEArray &offsets) { +void ManualDWARFIndex::GetCompleteObjCClass( + ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) { Index(); - m_set.types.Find(class_name, offsets); + m_set.types.Find(class_name, + DIERefCallback(callback, class_name.GetStringRef())); } -void ManualDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) { +void ManualDWARFIndex::GetTypes( + ConstString name, llvm::function_ref callback) { Index(); - m_set.types.Find(name, offsets); + m_set.types.Find(name, DIERefCallback(callback, name.GetStringRef())); } -void ManualDWARFIndex::GetTypes(const DWARFDeclContext &context, - DIEArray &offsets) { +void ManualDWARFIndex::GetTypes( + const DWARFDeclContext &context, + llvm::function_ref callback) { Index(); - m_set.types.Find(ConstString(context[0].name), offsets); + auto name = context[0].name; + m_set.types.Find(ConstString(name), + DIERefCallback(callback, llvm::StringRef(name))); } -void ManualDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) { +void ManualDWARFIndex::GetNamespaces( + ConstString name, llvm::function_ref callback) { Index(); - m_set.namespaces.Find(name, offsets); + m_set.namespaces.Find(name, DIERefCallback(callback, name.GetStringRef())); } -void ManualDWARFIndex::GetFunctions(ConstString name, SymbolFileDWARF &dwarf, - const CompilerDeclContext &parent_decl_ctx, - uint32_t name_type_mask, - std::vector &dies) { +void ManualDWARFIndex::GetFunctions( + ConstString name, SymbolFileDWARF &dwarf, + const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, + llvm::function_ref callback) { Index(); if (name_type_mask & eFunctionNameTypeFull) { - DIEArray offsets; - m_set.function_fullnames.Find(name, offsets); - for (const DIERef &die_ref: offsets) { - DWARFDIE die = dwarf.GetDIE(die_ref); - if (!die) - continue; - if (SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die)) - dies.push_back(die); - } + if (!m_set.function_fullnames.Find( + name, DIERefCallback( + [&](DWARFDIE die) { + if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, + die)) + return true; + return callback(die); + }, + name.GetStringRef()))) + return; } if (name_type_mask & eFunctionNameTypeBase) { - DIEArray offsets; - m_set.function_basenames.Find(name, offsets); - for (const DIERef &die_ref: offsets) { - DWARFDIE die = dwarf.GetDIE(die_ref); - if (!die) - continue; - if (SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die)) - dies.push_back(die); - } - offsets.clear(); + if (!m_set.function_basenames.Find( + name, DIERefCallback( + [&](DWARFDIE die) { + if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, + die)) + return true; + return callback(die); + }, + name.GetStringRef()))) + return; } if (name_type_mask & eFunctionNameTypeMethod && !parent_decl_ctx.IsValid()) { - DIEArray offsets; - m_set.function_methods.Find(name, offsets); - for (const DIERef &die_ref: offsets) { - if (DWARFDIE die = dwarf.GetDIE(die_ref)) - dies.push_back(die); - } + if (!m_set.function_methods.Find( + name, DIERefCallback(callback, name.GetStringRef()))) + return; } if (name_type_mask & eFunctionNameTypeSelector && !parent_decl_ctx.IsValid()) { - DIEArray offsets; - m_set.function_selectors.Find(name, offsets); - for (const DIERef &die_ref: offsets) { - if (DWARFDIE die = dwarf.GetDIE(die_ref)) - dies.push_back(die); - } + if (!m_set.function_selectors.Find( + name, DIERefCallback(callback, name.GetStringRef()))) + return; } } -void ManualDWARFIndex::GetFunctions(const RegularExpression ®ex, - DIEArray &offsets) { +void ManualDWARFIndex::GetFunctions( + const RegularExpression ®ex, + llvm::function_ref callback) { Index(); - m_set.function_basenames.Find(regex, offsets); - m_set.function_fullnames.Find(regex, offsets); + if (!m_set.function_basenames.Find(regex, + DIERefCallback(callback, regex.GetText()))) + return; + if (!m_set.function_fullnames.Find(regex, + DIERefCallback(callback, regex.GetText()))) + return; } void ManualDWARFIndex::Dump(Stream &s) { diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h index dd03b103c93..baff989eecc 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h @@ -6,42 +6,53 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_MANUALDWARFINDEX_H -#define LLDB_MANUALDWARFINDEX_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEX_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEX_H #include "Plugins/SymbolFile/DWARF/DWARFIndex.h" #include "Plugins/SymbolFile/DWARF/NameToDIE.h" #include "llvm/ADT/DenseSet.h" class DWARFDebugInfo; +class SymbolFileDWARFDwo; namespace lldb_private { class ManualDWARFIndex : public DWARFIndex { public: - ManualDWARFIndex(Module &module, DWARFDebugInfo *debug_info, + ManualDWARFIndex(Module &module, SymbolFileDWARF &dwarf, llvm::DenseSet units_to_avoid = {}) - : DWARFIndex(module), m_debug_info(debug_info), + : DWARFIndex(module), m_dwarf(&dwarf), m_units_to_avoid(std::move(units_to_avoid)) {} void Preload() override { Index(); } - void GetGlobalVariables(ConstString basename, DIEArray &offsets) override; - void GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) override; - void GetGlobalVariables(const DWARFUnit &unit, DIEArray &offsets) override; - void GetObjCMethods(ConstString class_name, DIEArray &offsets) override; - void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, - DIEArray &offsets) override; - void GetTypes(ConstString name, DIEArray &offsets) override; - void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override; - void GetNamespaces(ConstString name, DIEArray &offsets) override; + void + GetGlobalVariables(ConstString basename, + llvm::function_ref callback) override; + void + GetGlobalVariables(const RegularExpression ®ex, + llvm::function_ref callback) override; + void + GetGlobalVariables(const DWARFUnit &unit, + llvm::function_ref callback) override; + void GetObjCMethods(ConstString class_name, + llvm::function_ref callback) override; + void GetCompleteObjCClass( + ConstString class_name, bool must_be_implementation, + llvm::function_ref callback) override; + void GetTypes(ConstString name, + llvm::function_ref callback) override; + void GetTypes(const DWARFDeclContext &context, + llvm::function_ref callback) override; + void GetNamespaces(ConstString name, + llvm::function_ref callback) override; void GetFunctions(ConstString name, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, - std::vector &dies) override; - void GetFunctions(const RegularExpression ®ex, DIEArray &offsets) override; + llvm::function_ref callback) override; + void GetFunctions(const RegularExpression ®ex, + llvm::function_ref callback) override; - void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override {} void Dump(Stream &s) override; private: @@ -56,14 +67,15 @@ private: NameToDIE namespaces; }; void Index(); - void IndexUnit(DWARFUnit &unit, IndexSet &set); + void IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp, IndexSet &set); static void IndexUnitImpl(DWARFUnit &unit, const lldb::LanguageType cu_language, IndexSet &set); - /// Non-null value means we haven't built the index yet. - DWARFDebugInfo *m_debug_info; + /// The DWARF file which we are indexing. Set to nullptr after the index is + /// built. + SymbolFileDWARF *m_dwarf; /// Which dwarf units should we skip while building the index. llvm::DenseSet m_units_to_avoid; @@ -71,4 +83,4 @@ private: }; } // namespace lldb_private -#endif // LLDB_MANUALDWARFINDEX_H +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEX_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp index 7d81afb1b22..42e96af84a9 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp @@ -1,4 +1,4 @@ -//===-- NameToDIE.cpp -------------------------------------------*- C++ -*-===// +//===-- NameToDIE.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -26,28 +26,38 @@ void NameToDIE::Insert(ConstString name, const DIERef &die_ref) { m_map.Append(name, die_ref); } -size_t NameToDIE::Find(ConstString name, DIEArray &info_array) const { - return m_map.GetValues(name, info_array); +bool NameToDIE::Find(ConstString name, + llvm::function_ref callback) const { + for (const auto &entry : m_map.equal_range(name)) + if (!callback(entry.value)) + return false; + return true; } -size_t NameToDIE::Find(const RegularExpression ®ex, - DIEArray &info_array) const { - return m_map.GetValues(regex, info_array); +bool NameToDIE::Find(const RegularExpression ®ex, + llvm::function_ref callback) const { + for (const auto &entry : m_map) + if (regex.Execute(entry.cstring.GetCString())) { + if (!callback(entry.value)) + return false; + } + return true; } -size_t NameToDIE::FindAllEntriesForUnit(const DWARFUnit &unit, - DIEArray &info_array) const { - const size_t initial_size = info_array.size(); +void NameToDIE::FindAllEntriesForUnit( + const DWARFUnit &unit, + llvm::function_ref callback) const { const uint32_t size = m_map.GetSize(); for (uint32_t i = 0; i < size; ++i) { const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i); if (unit.GetSymbolFileDWARF().GetDwoNum() == die_ref.dwo_num() && unit.GetDebugSection() == die_ref.section() && unit.GetOffset() <= die_ref.die_offset() && - die_ref.die_offset() < unit.GetNextUnitOffset()) - info_array.push_back(die_ref); + die_ref.die_offset() < unit.GetNextUnitOffset()) { + if (!callback(die_ref)) + return; + } } - return info_array.size() - initial_size; } void NameToDIE::Dump(Stream *s) { diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h index b504f45e81b..5aa841cf3d1 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_NameToDIE_h_ -#define SymbolFileDWARF_NameToDIE_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_NAMETODIE_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_NAMETODIE_H #include @@ -32,14 +32,15 @@ public: void Finalize(); - size_t Find(lldb_private::ConstString name, - DIEArray &info_array) const; + bool Find(lldb_private::ConstString name, + llvm::function_ref callback) const; - size_t Find(const lldb_private::RegularExpression ®ex, - DIEArray &info_array) const; + bool Find(const lldb_private::RegularExpression ®ex, + llvm::function_ref callback) const; - size_t FindAllEntriesForUnit(const DWARFUnit &unit, - DIEArray &info_array) const; + void + FindAllEntriesForUnit(const DWARFUnit &unit, + llvm::function_ref callback) const; void ForEach(std::function m_map; }; -#endif // SymbolFileDWARF_NameToDIE_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_NAMETODIE_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index d45a8b56efe..0b7e31ae2d1 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1,4 +1,4 @@ -//===-- SymbolFileDWARF.cpp ------------------------------------*- C++ -*-===// +//===-- SymbolFileDWARF.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -34,9 +34,9 @@ #include "lldb/Interpreter/OptionValueFileSpecList.h" #include "lldb/Interpreter/OptionValueProperties.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Symbol/Block.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" @@ -70,7 +70,6 @@ #include "ManualDWARFIndex.h" #include "SymbolFileDWARFDebugMap.h" #include "SymbolFileDWARFDwo.h" -#include "SymbolFileDWARFDwp.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/Support/FileSystem.h" @@ -94,6 +93,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(SymbolFileDWARF) + char SymbolFileDWARF::ID; // static inline bool @@ -135,14 +136,6 @@ public: m_collection_sp->Initialize(g_symbolfiledwarf_properties); } - FileSpecList GetSymLinkPaths() { - const OptionValueFileSpecList *option_value = - m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList( - nullptr, true, ePropertySymLinkPaths); - assert(option_value); - return option_value->GetCurrentValue(); - } - bool IgnoreFileIndexes() const { return m_collection_sp->GetPropertyAtIndexAsBoolean( nullptr, ePropertyIgnoreIndexes, false); @@ -169,18 +162,46 @@ ParseLLVMLineTable(lldb_private::DWARFContext &context, llvm::Expected line_table = line.getOrParseLineTable( data, line_offset, ctx, nullptr, [&](llvm::Error e) { - LLDB_LOG_ERROR(log, std::move(e), - "SymbolFileDWARF::ParseLineTable failed to parse"); + LLDB_LOG_ERROR( + log, std::move(e), + "SymbolFileDWARF::ParseLineTable failed to parse: {0}"); }); if (!line_table) { LLDB_LOG_ERROR(log, line_table.takeError(), - "SymbolFileDWARF::ParseLineTable failed to parse"); + "SymbolFileDWARF::ParseLineTable failed to parse: {0}"); return nullptr; } return *line_table; } +static bool ParseLLVMLineTablePrologue(lldb_private::DWARFContext &context, + llvm::DWARFDebugLine::Prologue &prologue, + dw_offset_t line_offset, + dw_offset_t unit_offset) { + Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); + bool success = true; + llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVM(); + llvm::DWARFContext &ctx = context.GetAsLLVM(); + uint64_t offset = line_offset; + llvm::Error error = prologue.parse( + data, &offset, + [&](llvm::Error e) { + success = false; + LLDB_LOG_ERROR(log, std::move(e), + "SymbolFileDWARF::ParseSupportFiles failed to parse " + "line table prologue: {0}"); + }, + ctx, nullptr); + if (error) { + LLDB_LOG_ERROR(log, std::move(error), + "SymbolFileDWARF::ParseSupportFiles failed to parse line " + "table prologue: {0}"); + return false; + } + return success; +} + static llvm::Optional GetFileByIndex(const llvm::DWARFDebugLine::Prologue &prologue, size_t idx, llvm::StringRef compile_dir, FileSpec::Style style) { @@ -192,7 +213,7 @@ GetFileByIndex(const llvm::DWARFDebugLine::Prologue &prologue, size_t idx, // Otherwise ask for a relative path. std::string rel_path; - auto relative = llvm::DILineInfoSpecifier::FileLineInfoKind::Default; + auto relative = llvm::DILineInfoSpecifier::FileLineInfoKind::RawValue; if (!prologue.getFileNameByIndex(idx, compile_dir, relative, rel_path, style)) return {}; return std::move(rel_path); @@ -227,15 +248,12 @@ ParseSupportFilesFromPrologue(const lldb::ModuleSP &module, return support_files; } -FileSpecList SymbolFileDWARF::GetSymlinkPaths() { - return GetGlobalPluginProperties()->GetSymLinkPaths(); -} - void SymbolFileDWARF::Initialize() { LogChannelDWARF::Initialize(); PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, DebuggerInitialize); + SymbolFileDWARFDebugMap::Initialize(); } void SymbolFileDWARF::DebuggerInitialize(Debugger &debugger) { @@ -250,6 +268,7 @@ void SymbolFileDWARF::DebuggerInitialize(Debugger &debugger) { } void SymbolFileDWARF::Terminate() { + SymbolFileDWARFDebugMap::Terminate(); PluginManager::UnregisterPlugin(CreateInstance); LogChannelDWARF::Terminate(); } @@ -333,10 +352,8 @@ void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset, if (add_type) { const bool assert_not_being_parsed = true; Type *type = ResolveTypeUID(die, assert_not_being_parsed); - if (type) { - if (type_set.find(type) == type_set.end()) - type_set.insert(type); - } + if (type) + type_set.insert(type); } } @@ -366,15 +383,12 @@ void SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope, GetTypes(dwarf_cu->DIE(), dwarf_cu->GetOffset(), dwarf_cu->GetNextUnitOffset(), type_mask, type_set); } else { - DWARFDebugInfo *info = DebugInfo(); - if (info) { - const size_t num_cus = info->GetNumUnits(); - for (size_t cu_idx = 0; cu_idx < num_cus; ++cu_idx) { - dwarf_cu = info->GetUnitAtIndex(cu_idx); - if (dwarf_cu) { - GetTypes(dwarf_cu->DIE(), 0, UINT32_MAX, type_mask, type_set); - } - } + DWARFDebugInfo &info = DebugInfo(); + const size_t num_cus = info.GetNumUnits(); + for (size_t cu_idx = 0; cu_idx < num_cus; ++cu_idx) { + dwarf_cu = info.GetUnitAtIndex(cu_idx); + if (dwarf_cu) + GetTypes(dwarf_cu->DIE(), 0, UINT32_MAX, type_mask, type_set); } } @@ -418,9 +432,8 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp, // contain the .o file index/ID m_debug_map_module_wp(), m_debug_map_symfile(nullptr), m_context(m_objfile_sp->GetModule()->GetSectionList(), dwo_section_list), - m_data_debug_loc(), m_abbr(), m_info(), m_fetched_external_modules(false), - m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate), - m_unique_ast_type_map() {} + m_fetched_external_modules(false), + m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {} SymbolFileDWARF::~SymbolFileDWARF() {} @@ -471,9 +484,9 @@ void SymbolFileDWARF::InitializeObject() { LoadSectionData(eSectionTypeDWARFDebugNames, debug_names); if (debug_names.GetByteSize() > 0) { llvm::Expected> index_or = - DebugNamesDWARFIndex::Create( - *GetObjectFile()->GetModule(), debug_names, - m_context.getOrLoadStrData(), DebugInfo()); + DebugNamesDWARFIndex::Create(*GetObjectFile()->GetModule(), + debug_names, + m_context.getOrLoadStrData(), *this); if (index_or) { m_index = std::move(*index_or); return; @@ -483,8 +496,8 @@ void SymbolFileDWARF::InitializeObject() { } } - m_index = std::make_unique(*GetObjectFile()->GetModule(), - DebugInfo()); + m_index = + std::make_unique(*GetObjectFile()->GetModule(), *this); } bool SymbolFileDWARF::SupportedVersion(uint16_t version) { @@ -573,15 +586,6 @@ uint32_t SymbolFileDWARF::CalculateAbilities() { return abilities; } -const DWARFDataExtractor & -SymbolFileDWARF::GetCachedSectionData(lldb::SectionType sect_type, - DWARFDataSegment &data_segment) { - llvm::call_once(data_segment.m_flag, [this, sect_type, &data_segment] { - this->LoadSectionData(sect_type, std::ref(data_segment.m_data)); - }); - return data_segment.m_data; -} - void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type, DWARFDataExtractor &data) { ModuleSP module_sp(m_objfile_sp->GetModule()); @@ -618,23 +622,14 @@ DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() { return m_abbr.get(); } -const DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() const { - return m_abbr.get(); -} - -DWARFDebugInfo *SymbolFileDWARF::DebugInfo() { - if (m_info == nullptr) { +DWARFDebugInfo &SymbolFileDWARF::DebugInfo() { + llvm::call_once(m_info_once_flag, [&] { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION, static_cast(this)); - if (m_context.getOrLoadDebugInfoData().GetByteSize() > 0) - m_info = std::make_unique(*this, m_context); - } - return m_info.get(); -} - -const DWARFDebugInfo *SymbolFileDWARF::DebugInfo() const { - return m_info.get(); + m_info = std::make_unique(*this, m_context); + }); + return *m_info; } DWARFUnit * @@ -642,15 +637,11 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) { if (!comp_unit) return nullptr; - DWARFDebugInfo *info = DebugInfo(); - if (info) { - // The compile unit ID is the index of the DWARF unit. - DWARFUnit *dwarf_cu = info->GetUnitAtIndex(comp_unit->GetID()); - if (dwarf_cu && dwarf_cu->GetUserData() == nullptr) - dwarf_cu->SetUserData(comp_unit); - return dwarf_cu; - } - return nullptr; + // The compile unit ID is the index of the DWARF unit. + DWARFUnit *dwarf_cu = DebugInfo().GetUnitAtIndex(comp_unit->GetID()); + if (dwarf_cu && dwarf_cu->GetUserData() == nullptr) + dwarf_cu->SetUserData(comp_unit); + return dwarf_cu; } DWARFDebugRanges *SymbolFileDWARF::GetDebugRanges() { @@ -660,7 +651,7 @@ DWARFDebugRanges *SymbolFileDWARF::GetDebugRanges() { static_cast(this)); if (m_context.getOrLoadRangesData().GetByteSize() > 0) - m_ranges.reset(new DWARFDebugRanges()); + m_ranges = std::make_unique(); if (m_ranges) m_ranges->Extract(m_context); @@ -668,6 +659,22 @@ DWARFDebugRanges *SymbolFileDWARF::GetDebugRanges() { return m_ranges.get(); } +/// Make an absolute path out of \p file_spec and remap it using the +/// module's source remapping dictionary. +static void MakeAbsoluteAndRemap(FileSpec &file_spec, DWARFUnit &dwarf_cu, + const ModuleSP &module_sp) { + if (!file_spec) + return; + // 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 + // files are NFS mounted. + file_spec.MakeAbsolute(dwarf_cu.GetCompilationDirectory()); + + std::string remapped_file; + if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file)) + file_spec.SetFile(remapped_file, FileSpec::Style::native); +} + lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { CompUnitSP cu_sp; CompileUnit *comp_unit = (CompileUnit *)dwarf_cu.GetUserData(); @@ -675,9 +682,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { // We already parsed this compile unit, had out a shared pointer to it cu_sp = comp_unit->shared_from_this(); } else { - if (&dwarf_cu.GetSymbolFileDWARF() != this) { - return dwarf_cu.GetSymbolFileDWARF().ParseCompileUnit(dwarf_cu); - } else if (dwarf_cu.GetOffset() == 0 && GetDebugMapSymfile()) { + if (dwarf_cu.GetOffset() == 0 && GetDebugMapSymfile()) { // Let the debug map create the compile unit cu_sp = m_debug_map_symfile->GetCompileUnit(this); dwarf_cu.SetUserData(cu_sp.get()); @@ -688,19 +693,9 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { dwarf_cu.GetNonSkeletonUnit().GetUnitDIEOnly(); if (cu_die) { FileSpec cu_file_spec(cu_die.GetName(), dwarf_cu.GetPathStyle()); - 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 - // files are NFS mounted. - cu_file_spec.MakeAbsolute(dwarf_cu.GetCompilationDirectory()); - - std::string remapped_file; - if (module_sp->RemapSourceFile(cu_file_spec.GetPath(), - remapped_file)) - cu_file_spec.SetFile(remapped_file, FileSpec::Style::native); - } + MakeAbsoluteAndRemap(cu_file_spec, dwarf_cu, module_sp); - LanguageType cu_language = DWARFUnit::LanguageTypeFromDWARF( + LanguageType cu_language = SymbolFileDWARF::LanguageTypeFromDWARF( cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0)); bool is_optimized = dwarf_cu.GetNonSkeletonUnit().GetIsOptimized(); @@ -724,16 +719,13 @@ void SymbolFileDWARF::BuildCuTranslationTable() { if (!m_lldb_cu_to_dwarf_unit.empty()) return; - DWARFDebugInfo *info = DebugInfo(); - if (!info) - return; - - if (!info->ContainsTypeUnits()) { + DWARFDebugInfo &info = DebugInfo(); + if (!info.ContainsTypeUnits()) { // We can use a 1-to-1 mapping. No need to build a translation table. return; } - for (uint32_t i = 0, num = info->GetNumUnits(); i < num; ++i) { - if (auto *cu = llvm::dyn_cast(info->GetUnitAtIndex(i))) { + for (uint32_t i = 0, num = info.GetNumUnits(); i < num; ++i) { + if (auto *cu = llvm::dyn_cast(info.GetUnitAtIndex(i))) { cu->SetID(m_lldb_cu_to_dwarf_unit.size()); m_lldb_cu_to_dwarf_unit.push_back(i); } @@ -750,23 +742,16 @@ llvm::Optional SymbolFileDWARF::GetDWARFUnitIndex(uint32_t cu_idx) { } uint32_t SymbolFileDWARF::CalculateNumCompileUnits() { - DWARFDebugInfo *info = DebugInfo(); - if (!info) - return 0; BuildCuTranslationTable(); - return m_lldb_cu_to_dwarf_unit.empty() ? info->GetNumUnits() + return m_lldb_cu_to_dwarf_unit.empty() ? DebugInfo().GetNumUnits() : m_lldb_cu_to_dwarf_unit.size(); } CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) { ASSERT_MODULE_LOCK(this); - DWARFDebugInfo *info = DebugInfo(); - if (!info) - return {}; - if (llvm::Optional dwarf_idx = GetDWARFUnitIndex(cu_idx)) { if (auto *dwarf_cu = llvm::cast_or_null( - info->GetUnitAtIndex(*dwarf_idx))) + DebugInfo().GetUnitAtIndex(*dwarf_idx))) return ParseCompileUnit(*dwarf_cu); } return {}; @@ -778,8 +763,7 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit, if (!die.IsValid()) return nullptr; - auto type_system_or_err = - GetTypeSystemForLanguage(die.GetCU()->GetLanguageType()); + auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU())); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), std::move(err), "Unable to parse function"); @@ -792,6 +776,13 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit, return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die); } +lldb::addr_t SymbolFileDWARF::FixupAddress(lldb::addr_t file_addr) { + SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); + if (debug_map_symfile) + return debug_map_symfile->LinkOSOFileAddress(this, file_addr); + return file_addr; +} + bool SymbolFileDWARF::FixupAddress(Address &addr) { SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); if (debug_map_symfile) { @@ -804,11 +795,39 @@ lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) { std::lock_guard guard(GetModuleMutex()); DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu) - return dwarf_cu->GetLanguageType(); + return GetLanguage(*dwarf_cu); else return eLanguageTypeUnknown; } +XcodeSDK SymbolFileDWARF::ParseXcodeSDK(CompileUnit &comp_unit) { + std::lock_guard guard(GetModuleMutex()); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); + if (!dwarf_cu) + return {}; + const DWARFBaseDIE cu_die = dwarf_cu->GetNonSkeletonUnit().GetUnitDIEOnly(); + if (!cu_die) + return {}; + const char *sdk = cu_die.GetAttributeValueAsString(DW_AT_APPLE_sdk, nullptr); + if (!sdk) + return {}; + const char *sysroot = + cu_die.GetAttributeValueAsString(DW_AT_LLVM_sysroot, ""); + // Register the sysroot path remapping with the module belonging to + // the CU as well as the one belonging to the symbol file. The two + // would be different if this is an OSO object and module is the + // corresponding debug map, in which case both should be updated. + ModuleSP module_sp = comp_unit.GetModule(); + if (module_sp) + module_sp->RegisterXcodeSDK(sdk, sysroot); + + ModuleSP local_module_sp = m_objfile_sp->GetModule(); + if (local_module_sp && local_module_sp != module_sp) + local_module_sp->RegisterXcodeSDK(sdk, sysroot); + + return {sdk}; +} + size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "SymbolFileDWARF::ParseFunctions"); @@ -863,8 +882,24 @@ bool SymbolFileDWARF::ForEachExternalModule( bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit, FileSpecList &support_files) { - if (!comp_unit.GetLineTable()) - ParseLineTable(comp_unit); + std::lock_guard guard(GetModuleMutex()); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); + if (!dwarf_cu) + return false; + + dw_offset_t offset = dwarf_cu->GetLineTableOffset(); + if (offset == DW_INVALID_OFFSET) + return false; + + llvm::DWARFDebugLine::Prologue prologue; + if (!ParseLLVMLineTablePrologue(m_context, prologue, offset, + dwarf_cu->GetOffset())) + return false; + + comp_unit.SetSupportFiles(ParseSupportFilesFromPrologue( + comp_unit.GetModule(), prologue, dwarf_cu->GetPathStyle(), + dwarf_cu->GetCompilationDirectory().GetCString())); + return true; } @@ -898,12 +933,15 @@ SymbolFileDWARF::GetTypeUnitSupportFiles(DWARFTypeUnit &tu) { llvm::DWARFDataExtractor data = m_context.getOrLoadLineData().GetAsLLVM(); llvm::DWARFContext &ctx = m_context.GetAsLLVM(); llvm::DWARFDebugLine::Prologue prologue; - llvm::Error error = prologue.parse(data, &line_table_offset, ctx); - if (error) { + auto report = [](llvm::Error error) { Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); LLDB_LOG_ERROR(log, std::move(error), "SymbolFileDWARF::GetTypeUnitSupportFiles failed to parse " "the line table prologue"); + }; + llvm::Error error = prologue.parse(data, &line_table_offset, report, ctx); + if (error) { + report(std::move(error)); } else { list = ParseSupportFilesFromPrologue(GetObjectFile()->GetModule(), prologue, tu.GetPathStyle()); @@ -961,9 +999,12 @@ bool SymbolFileDWARF::ParseImportedModules( } std::reverse(module.path.begin(), module.path.end()); if (const char *include_path = module_die.GetAttributeValueAsString( - DW_AT_LLVM_include_path, nullptr)) - module.search_path = ConstString(include_path); - if (const char *sysroot = module_die.GetAttributeValueAsString( + DW_AT_LLVM_include_path, nullptr)) { + FileSpec include_spec(include_path, dwarf_cu->GetPathStyle()); + MakeAbsoluteAndRemap(include_spec, *dwarf_cu, m_objfile_sp->GetModule()); + module.search_path = ConstString(include_spec.GetPath()); + } + if (const char *sysroot = dwarf_cu->DIE().GetAttributeValueAsString( DW_AT_LLVM_sysroot, nullptr)) module.sysroot = ConstString(sysroot); imported_modules.push_back(module); @@ -981,18 +1022,13 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { if (!dwarf_cu) return false; - const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly(); - if (!dwarf_cu_die) - return false; - - const dw_offset_t cu_line_offset = dwarf_cu_die.GetAttributeValueAsUnsigned( - DW_AT_stmt_list, DW_INVALID_OFFSET); - if (cu_line_offset == DW_INVALID_OFFSET) + dw_offset_t offset = dwarf_cu->GetLineTableOffset(); + if (offset == DW_INVALID_OFFSET) return false; llvm::DWARFDebugLine line; - const llvm::DWARFDebugLine::LineTable *line_table = ParseLLVMLineTable( - m_context, line, cu_line_offset, dwarf_cu->GetOffset()); + const llvm::DWARFDebugLine::LineTable *line_table = + ParseLLVMLineTable(m_context, line, offset, dwarf_cu->GetOffset()); if (!line_table) return false; @@ -1000,20 +1036,25 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { // FIXME: Rather than parsing the whole line table and then copying it over // into LLDB, we should explore using a callback to populate the line table // while we parse to reduce memory usage. - std::unique_ptr line_table_up = - std::make_unique(&comp_unit); - LineSequence *sequence = line_table_up->CreateLineSequenceContainer(); - for (auto &row : line_table->Rows) { - line_table_up->AppendLineEntryToSequence( - sequence, row.Address.Address, row.Line, row.Column, row.File, - row.IsStmt, row.BasicBlock, row.PrologueEnd, row.EpilogueBegin, - row.EndSequence); - if (row.EndSequence) { - line_table_up->InsertSequence(sequence); - sequence = line_table_up->CreateLineSequenceContainer(); + std::vector> sequences; + // The Sequences view contains only valid line sequences. Don't iterate over + // the Rows directly. + for (const llvm::DWARFDebugLine::Sequence &seq : line_table->Sequences) { + std::unique_ptr sequence = + LineTable::CreateLineSequenceContainer(); + for (unsigned idx = seq.FirstRowIndex; idx < seq.LastRowIndex; ++idx) { + const llvm::DWARFDebugLine::Row &row = line_table->Rows[idx]; + LineTable::AppendLineEntryToSequence( + sequence.get(), row.Address.Address, row.Line, row.Column, row.File, + row.IsStmt, row.BasicBlock, row.PrologueEnd, row.EpilogueBegin, + row.EndSequence); } + sequences.push_back(std::move(sequence)); } + std::unique_ptr line_table_up = + std::make_unique(&comp_unit, std::move(sequences)); + if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile()) { // 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 @@ -1024,10 +1065,6 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { comp_unit.SetLineTable(line_table_up.release()); } - comp_unit.SetSupportFiles(ParseSupportFilesFromPrologue( - comp_unit.GetModule(), line_table->Prologue, dwarf_cu->GetPathStyle(), - dwarf_cu->GetCompilationDirectory().GetCString())); - return true; } @@ -1157,15 +1194,15 @@ size_t SymbolFileDWARF::ParseBlocksRecursive( (name != nullptr || mangled_name != nullptr)) { std::unique_ptr decl_up; if (decl_file != 0 || decl_line != 0 || decl_column != 0) - decl_up.reset(new Declaration( + decl_up = std::make_unique( comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file), - decl_line, decl_column)); + decl_line, decl_column); std::unique_ptr call_up; if (call_file != 0 || call_line != 0 || call_column != 0) - call_up.reset(new Declaration( + call_up = std::make_unique( comp_unit.GetSupportFiles().GetFileSpecAtIndex(call_file), - call_line, call_column)); + call_line, call_column); block->SetInlinedFunctionInfo(name, mangled_name, decl_up.get(), call_up.get()); @@ -1289,7 +1326,7 @@ CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) { // SymbolFileDWARF::GetDIE(). See comments inside the // SymbolFileDWARF::GetDIE() for details. if (DWARFDIE die = GetDIE(type_uid)) - return die.GetDecl(); + return GetDecl(die); return CompilerDecl(); } @@ -1302,7 +1339,7 @@ SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) { // SymbolFileDWARF::GetDIE(). See comments inside the // SymbolFileDWARF::GetDIE() for details. if (DWARFDIE die = GetDIE(type_uid)) - return die.GetDeclContext(); + return GetDeclContext(die); return CompilerDeclContext(); } @@ -1313,7 +1350,7 @@ SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) { // SymbolFileDWARF::GetDIE(). See comments inside the // SymbolFileDWARF::GetDIE() for details. if (DWARFDIE die = GetDIE(type_uid)) - return die.GetContainingDeclContext(); + return GetContainingDeclContext(die); return CompilerDeclContext(); } @@ -1394,8 +1431,8 @@ bool SymbolFileDWARF::HasForwardDeclForClangType( } TypeSystem *type_system = compiler_type.GetTypeSystem(); - ClangASTContext *clang_type_system = - llvm::dyn_cast_or_null(type_system); + TypeSystemClang *clang_type_system = + llvm::dyn_cast_or_null(type_system); if (!clang_type_system) return false; DWARFASTParserClang *ast_parser = @@ -1406,8 +1443,8 @@ bool SymbolFileDWARF::HasForwardDeclForClangType( bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) { std::lock_guard guard(GetModuleMutex()); - ClangASTContext *clang_type_system = - llvm::dyn_cast_or_null(compiler_type.GetTypeSystem()); + TypeSystemClang *clang_type_system = + llvm::dyn_cast_or_null(compiler_type.GetTypeSystem()); if (clang_type_system) { DWARFASTParserClang *ast_parser = static_cast(clang_type_system->GetDWARFParser()); @@ -1444,8 +1481,7 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) { dwarf_die.GetID(), dwarf_die.GetTagAsCString(), type->GetName().AsCString()); assert(compiler_type); - DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser(); - if (dwarf_ast) + if (DWARFASTParser *dwarf_ast = GetDWARFParser(*dwarf_die.GetCU())) return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type, compiler_type); } return false; @@ -1473,20 +1509,25 @@ Type *SymbolFileDWARF::ResolveType(const DWARFDIE &die, CompileUnit * SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu) { + if (dwarf_cu.IsDWOUnit()) { + DWARFCompileUnit *non_dwo_cu = + static_cast(dwarf_cu.GetUserData()); + assert(non_dwo_cu); + return non_dwo_cu->GetSymbolFileDWARF().GetCompUnitForDWARFCompUnit( + *non_dwo_cu); + } // Check if the symbol vendor already knows about this compile unit? if (dwarf_cu.GetUserData() == nullptr) { // The symbol vendor doesn't know about this compile unit, we need to parse // and add it to the symbol vendor object. return ParseCompileUnit(dwarf_cu).get(); } - return (CompileUnit *)dwarf_cu.GetUserData(); + return static_cast(dwarf_cu.GetUserData()); } -size_t SymbolFileDWARF::GetObjCMethodDIEOffsets(ConstString class_name, - DIEArray &method_die_offsets) { - method_die_offsets.clear(); - m_index->GetObjCMethods(class_name, method_die_offsets); - return method_die_offsets.size(); +void SymbolFileDWARF::GetObjCMethods( + ConstString class_name, llvm::function_ref callback) { + m_index->GetObjCMethods(class_name, callback); } bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) { @@ -1522,17 +1563,15 @@ lldb::ModuleSP SymbolFileDWARF::GetExternalModule(ConstString name) { DWARFDIE SymbolFileDWARF::GetDIE(const DIERef &die_ref) { if (die_ref.dwo_num()) { - return DebugInfo() - ->GetUnitAtIndex(*die_ref.dwo_num()) - ->GetDwoSymbolFile() - ->GetDIE(die_ref); + SymbolFileDWARF *dwarf = *die_ref.dwo_num() == 0x3fffffff + ? m_dwp_symfile.get() + : this->DebugInfo() + .GetUnitAtIndex(*die_ref.dwo_num()) + ->GetDwoSymbolFile(); + return dwarf->DebugInfo().GetDIE(die_ref); } - DWARFDebugInfo *debug_info = DebugInfo(); - if (debug_info) - return debug_info->GetDIE(die_ref); - else - return DWARFDIE(); + return DebugInfo().GetDIE(die_ref); } /// Return the DW_AT_(GNU_)dwo_name. @@ -1569,7 +1608,7 @@ llvm::Optional SymbolFileDWARF::GetDWOId() { return {}; } -std::unique_ptr +std::shared_ptr SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( DWARFUnit &unit, const DWARFDebugInfoEntry &cu_die) { // If this is a Darwin-style debug map (non-.dSYM) symbol file, @@ -1589,14 +1628,8 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( if (!dwo_name) return nullptr; - SymbolFileDWARFDwp *dwp_symfile = GetDwpSymbolFile(); - if (dwp_symfile) { - uint64_t dwo_id = ::GetDWOId(*dwarf_cu, cu_die); - std::unique_ptr dwo_symfile = - dwp_symfile->GetSymbolFileForDwoId(*dwarf_cu, dwo_id); - if (dwo_symfile) - return dwo_symfile; - } + if (std::shared_ptr dwp_sp = GetDwpSymbolFile()) + return dwp_sp; FileSpec dwo_file(dwo_name); FileSystem::Instance().Resolve(dwo_file); @@ -1624,20 +1657,21 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( if (dwo_obj_file == nullptr) return nullptr; - return std::make_unique(dwo_obj_file, *dwarf_cu); + return std::make_shared(*this, dwo_obj_file, + dwarf_cu->GetID()); } void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { if (m_fetched_external_modules) return; m_fetched_external_modules = true; - DWARFDebugInfo *debug_info = DebugInfo(); + DWARFDebugInfo &debug_info = DebugInfo(); // Follow DWO skeleton unit breadcrumbs. const uint32_t num_compile_units = GetNumCompileUnits(); for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { auto *dwarf_cu = - llvm::dyn_cast(debug_info->GetUnitAtIndex(cu_idx)); + llvm::dyn_cast(debug_info.GetUnitAtIndex(cu_idx)); if (!dwarf_cu) continue; @@ -1731,7 +1765,7 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() { if (!m_global_aranges_up) { - m_global_aranges_up.reset(new GlobalVariableMap()); + m_global_aranges_up = std::make_unique(); ModuleSP module_sp = GetObjectFile()->GetModule(); if (module_sp) { @@ -1773,6 +1807,32 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() { return *m_global_aranges_up; } +void SymbolFileDWARF::ResolveFunctionAndBlock(lldb::addr_t file_vm_addr, + bool lookup_block, + SymbolContext &sc) { + assert(sc.comp_unit); + DWARFUnit &cu = GetDWARFCompileUnit(sc.comp_unit)->GetNonSkeletonUnit(); + DWARFDIE function_die = cu.LookupAddress(file_vm_addr); + DWARFDIE block_die; + if (function_die) { + sc.function = sc.comp_unit->FindFunctionByUID(function_die.GetID()).get(); + if (sc.function == nullptr) + sc.function = ParseFunction(*sc.comp_unit, function_die); + + if (sc.function && lookup_block) + block_die = function_die.LookupDeepestBlock(file_vm_addr); + } + + if (!sc.function || ! lookup_block) + return; + + Block &block = sc.function->GetBlock(true); + if (block_die) + sc.block = block.FindBlockByID(block_die.GetID()); + else + sc.block = block.FindBlockByID(function_die.GetID()); +} + uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, SymbolContextItem resolve_scope, SymbolContext &sc) { @@ -1791,123 +1851,99 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, eSymbolContextLineEntry | eSymbolContextVariable)) { lldb::addr_t file_vm_addr = so_addr.GetFileAddress(); - DWARFDebugInfo *debug_info = DebugInfo(); - if (debug_info) { - llvm::Expected aranges = - debug_info->GetCompileUnitAranges(); - if (!aranges) { - Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); - LLDB_LOG_ERROR(log, aranges.takeError(), - "SymbolFileDWARF::ResolveSymbolContext failed to get cu " - "aranges. {0}"); - return 0; - } + DWARFDebugInfo &debug_info = DebugInfo(); + llvm::Expected aranges = + debug_info.GetCompileUnitAranges(); + if (!aranges) { + Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); + LLDB_LOG_ERROR(log, aranges.takeError(), + "SymbolFileDWARF::ResolveSymbolContext failed to get cu " + "aranges. {0}"); + return 0; + } - const dw_offset_t cu_offset = aranges->FindAddress(file_vm_addr); - if (cu_offset == DW_INVALID_OFFSET) { - // Global variables are not in the compile unit address ranges. The - // only way to currently find global variables is to iterate over the - // .debug_pubnames or the __apple_names table and find all items in - // there that point to DW_TAG_variable DIEs and then find the address - // that matches. - if (resolve_scope & eSymbolContextVariable) { - GlobalVariableMap &map = GetGlobalAranges(); - const GlobalVariableMap::Entry *entry = - map.FindEntryThatContains(file_vm_addr); - if (entry && entry->data) { - Variable *variable = entry->data; - SymbolContextScope *scc = variable->GetSymbolContextScope(); - if (scc) { - scc->CalculateSymbolContext(&sc); - sc.variable = variable; - } - return sc.GetResolvedMask(); + const dw_offset_t cu_offset = aranges->FindAddress(file_vm_addr); + if (cu_offset == DW_INVALID_OFFSET) { + // Global variables are not in the compile unit address ranges. The only + // way to currently find global variables is to iterate over the + // .debug_pubnames or the __apple_names table and find all items in there + // that point to DW_TAG_variable DIEs and then find the address that + // matches. + if (resolve_scope & eSymbolContextVariable) { + GlobalVariableMap &map = GetGlobalAranges(); + const GlobalVariableMap::Entry *entry = + map.FindEntryThatContains(file_vm_addr); + if (entry && entry->data) { + Variable *variable = entry->data; + SymbolContextScope *scc = variable->GetSymbolContextScope(); + if (scc) { + scc->CalculateSymbolContext(&sc); + sc.variable = variable; } + return sc.GetResolvedMask(); } - } else { - uint32_t cu_idx = DW_INVALID_INDEX; - if (auto *dwarf_cu = llvm::dyn_cast_or_null( - debug_info->GetUnitAtOffset(DIERef::Section::DebugInfo, - cu_offset, &cu_idx))) { - sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); - if (sc.comp_unit) { - resolved |= eSymbolContextCompUnit; - - bool force_check_line_table = false; - if (resolve_scope & - (eSymbolContextFunction | eSymbolContextBlock)) { - DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr); - DWARFDIE block_die; - if (function_die) { - sc.function = - sc.comp_unit->FindFunctionByUID(function_die.GetID()).get(); - if (sc.function == nullptr) - sc.function = ParseFunction(*sc.comp_unit, function_die); - - if (sc.function && (resolve_scope & eSymbolContextBlock)) - block_die = function_die.LookupDeepestBlock(file_vm_addr); - } else { - // We might have had a compile unit that had discontiguous - // address ranges where the gaps are symbols that don't have - // any debug info. Discontiguous compile unit address ranges - // should only happen when there aren't other functions from - // other compile units in these gaps. This helps keep the size - // of the aranges down. - force_check_line_table = true; - } - - if (sc.function != nullptr) { - resolved |= eSymbolContextFunction; - - if (resolve_scope & eSymbolContextBlock) { - Block &block = sc.function->GetBlock(true); - - if (block_die) - sc.block = block.FindBlockByID(block_die.GetID()); - else - sc.block = block.FindBlockByID(function_die.GetID()); - if (sc.block) - resolved |= eSymbolContextBlock; - } - } + } + } else { + uint32_t cu_idx = DW_INVALID_INDEX; + if (auto *dwarf_cu = llvm::dyn_cast_or_null( + debug_info.GetUnitAtOffset(DIERef::Section::DebugInfo, cu_offset, + &cu_idx))) { + sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); + if (sc.comp_unit) { + resolved |= eSymbolContextCompUnit; + + bool force_check_line_table = false; + if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) { + ResolveFunctionAndBlock(file_vm_addr, + resolve_scope & eSymbolContextBlock, sc); + if (sc.function) + resolved |= eSymbolContextFunction; + else { + // We might have had a compile unit that had discontiguous address + // ranges where the gaps are symbols that don't have any debug + // info. Discontiguous compile unit address ranges should only + // happen when there aren't other functions from other compile + // units in these gaps. This helps keep the size of the aranges + // down. + force_check_line_table = true; } + if (sc.block) + resolved |= eSymbolContextBlock; + } - if ((resolve_scope & eSymbolContextLineEntry) || - force_check_line_table) { - LineTable *line_table = sc.comp_unit->GetLineTable(); - if (line_table != nullptr) { - // And address that makes it into this function should be in - // terms of this debug file if there is no debug map, or it - // will be an address in the .o file which needs to be fixed up - // to be in terms of the debug map executable. Either way, - // calling FixupAddress() will work for us. - Address exe_so_addr(so_addr); - if (FixupAddress(exe_so_addr)) { - if (line_table->FindLineEntryByAddress(exe_so_addr, - sc.line_entry)) { - resolved |= eSymbolContextLineEntry; - } + if ((resolve_scope & eSymbolContextLineEntry) || + force_check_line_table) { + LineTable *line_table = sc.comp_unit->GetLineTable(); + if (line_table != nullptr) { + // And address that makes it into this function should be in terms + // of this debug file if there is no debug map, or it will be an + // address in the .o file which needs to be fixed up to be in + // terms of the debug map executable. Either way, calling + // FixupAddress() will work for us. + Address exe_so_addr(so_addr); + if (FixupAddress(exe_so_addr)) { + if (line_table->FindLineEntryByAddress(exe_so_addr, + sc.line_entry)) { + resolved |= eSymbolContextLineEntry; } } } + } - if (force_check_line_table && - !(resolved & eSymbolContextLineEntry)) { - // We might have had a compile unit that had discontiguous - // address ranges where the gaps are symbols that don't have any - // debug info. Discontiguous compile unit address ranges should - // only happen when there aren't other functions from other - // compile units in these gaps. This helps keep the size of the - // aranges down. - sc.comp_unit = nullptr; - resolved &= ~eSymbolContextCompUnit; - } - } else { - GetObjectFile()->GetModule()->ReportWarning( - "0x%8.8x: compile unit %u failed to create a valid " - "lldb_private::CompileUnit class.", - cu_offset, cu_idx); + if (force_check_line_table && !(resolved & eSymbolContextLineEntry)) { + // We might have had a compile unit that had discontiguous address + // ranges where the gaps are symbols that don't have any debug info. + // Discontiguous compile unit address ranges should only happen when + // there aren't other functions from other compile units in these + // gaps. This helps keep the size of the aranges down. + sc.comp_unit = nullptr; + resolved &= ~eSymbolContextCompUnit; } + } else { + GetObjectFile()->GetModule()->ReportWarning( + "0x%8.8x: compile unit %u failed to create a valid " + "lldb_private::CompileUnit class.", + cu_offset, cu_idx); } } } @@ -1969,30 +2005,8 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec, const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress(); if (file_vm_addr != LLDB_INVALID_ADDRESS) { - DWARFDIE function_die = - GetDWARFCompileUnit(dc_cu)->LookupAddress(file_vm_addr); - DWARFDIE block_die; - if (function_die) { - sc.function = - sc.comp_unit->FindFunctionByUID(function_die.GetID()) - .get(); - if (sc.function == nullptr) - sc.function = - ParseFunction(*sc.comp_unit, function_die); - - if (sc.function && (resolve_scope & eSymbolContextBlock)) - block_die = - function_die.LookupDeepestBlock(file_vm_addr); - } - - if (sc.function != nullptr) { - Block &block = sc.function->GetBlock(true); - - if (block_die) - sc.block = block.FindBlockByID(block_die.GetID()); - else if (function_die) - sc.block = block.FindBlockByID(function_die.GetID()); - } + ResolveFunctionAndBlock( + file_vm_addr, resolve_scope & eSymbolContextBlock, sc); } } @@ -2035,15 +2049,15 @@ std::recursive_mutex &SymbolFileDWARF::GetModuleMutex() const { } bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile( - const lldb_private::CompilerDeclContext *decl_ctx) { - if (decl_ctx == nullptr || !decl_ctx->IsValid()) { + const lldb_private::CompilerDeclContext &decl_ctx) { + if (!decl_ctx.IsValid()) { // Invalid namespace decl which means we aren't matching only things in // this symbol file, so return true to indicate it matches this symbol // file. return true; } - TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem(); + TypeSystem *decl_ctx_type_system = decl_ctx.GetTypeSystem(); auto type_system_or_err = GetTypeSystemForLanguage( decl_ctx_type_system->GetMinimumLanguage(nullptr)); if (auto err = type_system_or_err.takeError()) { @@ -2067,7 +2081,7 @@ bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile( } void SymbolFileDWARF::FindGlobalVariables( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, VariableList &variables) { std::lock_guard guard(GetModuleMutex()); Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); @@ -2077,16 +2091,12 @@ void SymbolFileDWARF::FindGlobalVariables( log, "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", " "parent_decl_ctx=%p, max_matches=%u, variables)", - name.GetCString(), static_cast(parent_decl_ctx), + name.GetCString(), static_cast(&parent_decl_ctx), max_matches); if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) return; - DWARFDebugInfo *info = DebugInfo(); - if (!info) - return; - // Remember how many variables are in the list before we search. const uint32_t original_size = variables.GetSize(); @@ -2098,69 +2108,46 @@ void SymbolFileDWARF::FindGlobalVariables( context, basename)) basename = name.GetStringRef(); - DIEArray die_offsets; - m_index->GetGlobalVariables(ConstString(basename), die_offsets); - const size_t num_die_matches = die_offsets.size(); - if (num_die_matches) { - SymbolContext sc; - sc.module_sp = m_objfile_sp->GetModule(); - assert(sc.module_sp); - - // Loop invariant: Variables up to this index have been checked for context - // matches. - uint32_t pruned_idx = original_size; + // Loop invariant: Variables up to this index have been checked for context + // matches. + uint32_t pruned_idx = original_size; - bool done = false; - for (size_t i = 0; i < num_die_matches && !done; ++i) { - const DIERef &die_ref = die_offsets[i]; - DWARFDIE die = GetDIE(die_ref); - - if (die) { - switch (die.Tag()) { - default: - case DW_TAG_subprogram: - case DW_TAG_inlined_subroutine: - case DW_TAG_try_block: - case DW_TAG_catch_block: - break; + SymbolContext sc; + m_index->GetGlobalVariables(ConstString(basename), [&](DWARFDIE die) { + if (!sc.module_sp) + sc.module_sp = m_objfile_sp->GetModule(); + assert(sc.module_sp); - case DW_TAG_variable: { - auto *dwarf_cu = llvm::dyn_cast(die.GetCU()); - if (!dwarf_cu) - continue; - sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); - - if (parent_decl_ctx) { - DWARFASTParser *dwarf_ast = die.GetDWARFParser(); - if (dwarf_ast) { - CompilerDeclContext actual_parent_decl_ctx = - dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); - if (!actual_parent_decl_ctx || - actual_parent_decl_ctx != *parent_decl_ctx) - continue; - } - } + if (die.Tag() != DW_TAG_variable) + return true; - ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, - &variables); - while (pruned_idx < variables.GetSize()) { - VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx); - if (name_is_mangled || - var_sp->GetName().GetStringRef().contains(name.GetStringRef())) - ++pruned_idx; - else - variables.RemoveVariableAtIndex(pruned_idx); - } + auto *dwarf_cu = llvm::dyn_cast(die.GetCU()); + if (!dwarf_cu) + return true; + sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); - if (variables.GetSize() - original_size >= max_matches) - done = true; - } break; - } - } else { - m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); + if (parent_decl_ctx) { + if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) { + CompilerDeclContext actual_parent_decl_ctx = + dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); + if (!actual_parent_decl_ctx || + actual_parent_decl_ctx != parent_decl_ctx) + return true; } } - } + + ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); + while (pruned_idx < variables.GetSize()) { + VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx); + if (name_is_mangled || + var_sp->GetName().GetStringRef().contains(name.GetStringRef())) + ++pruned_idx; + else + variables.RemoveVariableAtIndex(pruned_idx); + } + + return variables.GetSize() - original_size < max_matches; + }); // Return the number of variable that were appended to the list const uint32_t num_matches = variables.GetSize() - original_size; @@ -2169,7 +2156,7 @@ void SymbolFileDWARF::FindGlobalVariables( log, "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", " "parent_decl_ctx=%p, max_matches=%u, variables) => %u", - name.GetCString(), static_cast(parent_decl_ctx), + name.GetCString(), static_cast(&parent_decl_ctx), max_matches, num_matches); } } @@ -2188,41 +2175,24 @@ void SymbolFileDWARF::FindGlobalVariables(const RegularExpression ®ex, regex.GetText().str().c_str(), max_matches); } - DWARFDebugInfo *info = DebugInfo(); - if (!info) - return; - // Remember how many variables are in the list before we search. const uint32_t original_size = variables.GetSize(); - DIEArray die_offsets; - m_index->GetGlobalVariables(regex, die_offsets); - SymbolContext sc; - sc.module_sp = m_objfile_sp->GetModule(); - assert(sc.module_sp); - - const size_t num_matches = die_offsets.size(); - if (num_matches) { - for (size_t i = 0; i < num_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; - DWARFDIE die = GetDIE(die_ref); + m_index->GetGlobalVariables(regex, [&](DWARFDIE die) { + if (!sc.module_sp) + sc.module_sp = m_objfile_sp->GetModule(); + assert(sc.module_sp); - if (die) { - DWARFCompileUnit *dwarf_cu = - llvm::dyn_cast(die.GetCU()); - if (!dwarf_cu) - continue; - sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); + DWARFCompileUnit *dwarf_cu = llvm::dyn_cast(die.GetCU()); + if (!dwarf_cu) + return true; + sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); - ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); + ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); - if (variables.GetSize() - original_size >= max_matches) - break; - } else - m_index->ReportInvalidDIERef(die_ref, regex.GetText()); - } - } + return variables.GetSize() - original_size < max_matches; + }); } bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die, @@ -2281,28 +2251,26 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die, return false; } -bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx, +bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext &decl_ctx, const DWARFDIE &die) { // If we have no parent decl context to match this DIE matches, and if the // parent decl context isn't valid, we aren't trying to look for any // particular decl context so any die matches. - if (decl_ctx == nullptr || !decl_ctx->IsValid()) + if (!decl_ctx.IsValid()) return true; if (die) { - DWARFASTParser *dwarf_ast = die.GetDWARFParser(); - if (dwarf_ast) { - CompilerDeclContext actual_decl_ctx = - dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); - if (actual_decl_ctx) - return decl_ctx->IsContainedInLookup(actual_decl_ctx); + if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) { + if (CompilerDeclContext actual_decl_ctx = + dwarf_ast->GetDeclContextContainingUIDFromDWARF(die)) + return decl_ctx.IsContainedInLookup(actual_decl_ctx); } } return false; } void SymbolFileDWARF::FindFunctions(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) { @@ -2337,17 +2305,13 @@ void SymbolFileDWARF::FindFunctions(ConstString name, const uint32_t original_size = sc_list.GetSize(); llvm::DenseSet resolved_dies; - DIEArray offsets; - CompilerDeclContext empty_decl_ctx; - if (!parent_decl_ctx) - parent_decl_ctx = &empty_decl_ctx; - - std::vector dies; - m_index->GetFunctions(name, *this, *parent_decl_ctx, name_type_mask, dies); - for (const DWARFDIE &die : dies) { - if (resolved_dies.insert(die.GetDIE()).second) - ResolveFunction(die, include_inlines, sc_list); - } + + m_index->GetFunctions(name, *this, parent_decl_ctx, name_type_mask, + [&](DWARFDIE die) { + if (resolved_dies.insert(die.GetDIE()).second) + ResolveFunction(die, include_inlines, sc_list); + return true; + }); // Return the number of variable that were appended to the list const uint32_t num_matches = sc_list.GetSize() - original_size; @@ -2378,35 +2342,21 @@ void SymbolFileDWARF::FindFunctions(const RegularExpression ®ex, regex.GetText().str().c_str()); } - DWARFDebugInfo *info = DebugInfo(); - if (!info) - return; - - DIEArray offsets; - m_index->GetFunctions(regex, offsets); - llvm::DenseSet resolved_dies; - for (DIERef ref : offsets) { - DWARFDIE die = info->GetDIE(ref); - if (!die) { - m_index->ReportInvalidDIERef(ref, regex.GetText()); - continue; - } + m_index->GetFunctions(regex, [&](DWARFDIE die) { if (resolved_dies.insert(die.GetDIE()).second) ResolveFunction(die, include_inlines, sc_list); - } + return true; + }); } void SymbolFileDWARF::GetMangledNamesForFunction( const std::string &scope_qualified_name, std::vector &mangled_names) { - DWARFDebugInfo *info = DebugInfo(); - uint32_t num_comp_units = 0; - if (info) - num_comp_units = info->GetNumUnits(); - + DWARFDebugInfo &info = DebugInfo(); + uint32_t num_comp_units = info.GetNumUnits(); for (uint32_t i = 0; i < num_comp_units; i++) { - DWARFUnit *cu = info->GetUnitAtIndex(i); + DWARFUnit *cu = info.GetUnitAtIndex(i); if (cu == nullptr) continue; @@ -2415,15 +2365,15 @@ void SymbolFileDWARF::GetMangledNamesForFunction( dwo->GetMangledNamesForFunction(scope_qualified_name, mangled_names); } - for (lldb::user_id_t uid : + for (DIERef die_ref : m_function_scope_qualified_name_map.lookup(scope_qualified_name)) { - DWARFDIE die = GetDIE(uid); + DWARFDIE die = GetDIE(die_ref); mangled_names.push_back(ConstString(die.GetMangledName())); } } void SymbolFileDWARF::FindTypes( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) { @@ -2432,10 +2382,6 @@ void SymbolFileDWARF::FindTypes( if (!searched_symbol_files.insert(this).second) return; - DWARFDebugInfo *info = DebugInfo(); - if (!info) - return; - Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); if (log) { @@ -2444,8 +2390,8 @@ void SymbolFileDWARF::FindTypes( log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = " "%p (\"%s\"), max_matches=%u, type_list)", - name.GetCString(), static_cast(parent_decl_ctx), - parent_decl_ctx->GetName().AsCString(""), max_matches); + name.GetCString(), static_cast(&parent_decl_ctx), + parent_decl_ctx.GetName().AsCString(""), max_matches); else GetObjectFile()->GetModule()->LogMessage( log, @@ -2457,38 +2403,28 @@ void SymbolFileDWARF::FindTypes( if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) return; - DIEArray die_offsets; - m_index->GetTypes(name, die_offsets); - const size_t num_die_matches = die_offsets.size(); + m_index->GetTypes(name, [&](DWARFDIE die) { + if (!DIEInDeclContext(parent_decl_ctx, die)) + return true; // The containing decl contexts don't match - for (size_t i = 0; i < num_die_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; - DWARFDIE die = GetDIE(die_ref); - if (die) { - if (!DIEInDeclContext(parent_decl_ctx, die)) - continue; // The containing decl contexts don't match - - Type *matching_type = ResolveType(die, true, true); - if (matching_type) { - // We found a type pointer, now find the shared pointer form our type - // list - types.InsertUnique(matching_type->shared_from_this()); - if (types.GetSize() >= max_matches) - break; - } - } else { - m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); - } - } + Type *matching_type = ResolveType(die, true, true); + if (!matching_type) + return true; + + // We found a type pointer, now find the shared pointer form our type + // list + types.InsertUnique(matching_type->shared_from_this()); + return types.GetSize() < max_matches; + }); // Next search through the reachable Clang modules. This only applies for // DWARF objects compiled with -gmodules that haven't been processed by // dsymutil. - if (num_die_matches < max_matches) { + if (types.GetSize() < max_matches) { UpdateExternalModuleListIfNeeded(); for (const auto &pair : m_external_type_modules) - if (ModuleSP external_module_sp = pair.second) + if (ModuleSP external_module_sp = pair.second) if (SymbolFile *sym_file = external_module_sp->GetSymbolFile()) sym_file->FindTypes(name, parent_decl_ctx, max_matches, searched_symbol_files, types); @@ -2500,8 +2436,8 @@ void SymbolFileDWARF::FindTypes( log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx " "= %p (\"%s\"), max_matches=%u, type_list) => %u", - name.GetCString(), static_cast(parent_decl_ctx), - parent_decl_ctx->GetName().AsCString(""), max_matches, + name.GetCString(), static_cast(&parent_decl_ctx), + parent_decl_ctx.GetName().AsCString(""), max_matches, types.GetSize()); } else { GetObjectFile()->GetModule()->LogMessage( @@ -2529,32 +2465,22 @@ void SymbolFileDWARF::FindTypes( if (!name) return; - DIEArray die_offsets; - m_index->GetTypes(name, die_offsets); - const size_t num_die_matches = die_offsets.size(); - - for (size_t i = 0; i < num_die_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; - DWARFDIE die = GetDIE(die_ref); - - if (!die) { - m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); - continue; - } - if (!languages[die.GetCU()->GetLanguageType()]) - continue; + m_index->GetTypes(name, [&](DWARFDIE die) { + if (!languages[GetLanguage(*die.GetCU())]) + return true; llvm::SmallVector die_context; die.GetDeclContext(die_context); if (!contextMatches(die_context, pattern)) - continue; + return true; if (Type *matching_type = ResolveType(die, true, true)) { // We found a type pointer, now find the shared pointer form our type // list. types.InsertUnique(matching_type->shared_from_this()); } - } + return true; + }); // Next search through the reachable Clang modules. This only applies for // DWARF objects compiled with -gmodules that haven't been processed by @@ -2569,7 +2495,7 @@ void SymbolFileDWARF::FindTypes( CompilerDeclContext SymbolFileDWARF::FindNamespace(ConstString name, - const CompilerDeclContext *parent_decl_ctx) { + const CompilerDeclContext &parent_decl_ctx) { std::lock_guard guard(GetModuleMutex()); Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); @@ -2584,32 +2510,18 @@ SymbolFileDWARF::FindNamespace(ConstString name, if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) return namespace_decl_ctx; - DWARFDebugInfo *info = DebugInfo(); - if (info) { - DIEArray die_offsets; - m_index->GetNamespaces(name, die_offsets); - const size_t num_matches = die_offsets.size(); - if (num_matches) { - for (size_t i = 0; i < num_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; - DWARFDIE die = GetDIE(die_ref); - - if (die) { - if (!DIEInDeclContext(parent_decl_ctx, die)) - continue; // The containing decl contexts don't match - - DWARFASTParser *dwarf_ast = die.GetDWARFParser(); - if (dwarf_ast) { - namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF(die); - if (namespace_decl_ctx) - break; - } - } else { - m_index->ReportInvalidDIERef(die_ref, name.GetStringRef()); - } - } - } - } + m_index->GetNamespaces(name, [&](DWARFDIE die) { + if (!DIEInDeclContext(parent_decl_ctx, die)) + return true; // The containing decl contexts don't match + + DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()); + if (!dwarf_ast) + return true; + + namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF(die); + return !namespace_decl_ctx.IsValid(); + }); + if (log && namespace_decl_ctx) { GetObjectFile()->GetModule()->LogMessage( log, @@ -2735,10 +2647,10 @@ bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu) { if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type()) m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; else { - DWARFDebugInfo *debug_info = DebugInfo(); + DWARFDebugInfo &debug_info = DebugInfo(); const uint32_t num_compile_units = GetNumCompileUnits(); for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { - DWARFUnit *dwarf_cu = debug_info->GetUnitAtIndex(cu_idx); + DWARFUnit *dwarf_cu = debug_info.GetUnitAtIndex(cu_idx); if (dwarf_cu != cu && dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type()) { m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; @@ -2763,17 +2675,8 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE( if (!type_name || (must_be_implementation && !GetObjCClassSymbol(type_name))) return type_sp; - DIEArray die_offsets; - m_index->GetCompleteObjCClass(type_name, must_be_implementation, die_offsets); - - const size_t num_matches = die_offsets.size(); - - if (num_matches) { - for (size_t i = 0; i < num_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; - DWARFDIE type_die = GetDIE(die_ref); - - if (type_die) { + m_index->GetCompleteObjCClass( + type_name, must_be_implementation, [&](DWARFDIE type_die) { bool try_resolving_type = false; // Don't try and resolve the DIE we are looking for with the DIE @@ -2788,35 +2691,32 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE( break; } } + if (!try_resolving_type) + return true; - if (try_resolving_type) { - if (must_be_implementation && - type_die.Supports_DW_AT_APPLE_objc_complete_type()) - try_resolving_type = type_die.GetAttributeValueAsUnsigned( - DW_AT_APPLE_objc_complete_type, 0); - - if (try_resolving_type) { - Type *resolved_type = ResolveType(type_die, false, true); - if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) { - DEBUG_PRINTF("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 - " (cu 0x%8.8" PRIx64 ")\n", - die.GetID(), - m_objfile_sp->GetFileSpec().GetFilename().AsCString( - ""), - type_die.GetID(), type_cu->GetID()); - - if (die) - GetDIEToType()[die.GetDIE()] = resolved_type; - type_sp = resolved_type->shared_from_this(); - break; - } - } - } - } else { - m_index->ReportInvalidDIERef(die_ref, type_name.GetStringRef()); - } - } - } + if (must_be_implementation && + type_die.Supports_DW_AT_APPLE_objc_complete_type()) + try_resolving_type = type_die.GetAttributeValueAsUnsigned( + DW_AT_APPLE_objc_complete_type, 0); + if (!try_resolving_type) + return true; + + Type *resolved_type = ResolveType(type_die, false, true); + if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED) + return true; + + DEBUG_PRINTF( + "resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 + " (cu 0x%8.8" PRIx64 ")\n", + die.GetID(), + m_objfile_sp->GetFileSpec().GetFilename().AsCString(""), + type_die.GetID(), type_cu->GetID()); + + if (die) + GetDIEToType()[die.GetDIE()] = resolved_type; + type_sp = resolved_type->shared_from_this(); + return false; + }); return type_sp; } @@ -2930,10 +2830,6 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext( dwarf_decl_ctx.GetQualifiedName()); } - DIEArray die_offsets; - m_index->GetTypes(dwarf_decl_ctx, die_offsets); - const size_t num_matches = die_offsets.size(); - // Get the type system that we are looking to find a type for. We will // use this to ensure any matches we find are in a language that this // type system supports @@ -2950,91 +2846,85 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext( type_system = &type_system_or_err.get(); } } - if (num_matches) { - for (size_t i = 0; i < num_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; - DWARFDIE type_die = GetDIE(die_ref); - - if (type_die) { - // Make sure type_die's langauge matches the type system we are - // looking for. We don't want to find a "Foo" type from Java if we - // are looking for a "Foo" type for C, C++, ObjC, or ObjC++. - if (type_system && - !type_system->SupportsLanguage(type_die.GetLanguage())) - continue; - bool try_resolving_type = false; - - // Don't try and resolve the DIE we are looking for with the DIE - // itself! - const dw_tag_t type_tag = type_die.Tag(); - // Make sure the tags match - if (type_tag == tag) { - // The tags match, lets try resolving this type - try_resolving_type = true; - } else { - // The tags don't match, but we need to watch our for a forward - // declaration for a struct and ("struct foo") ends up being a - // class ("class foo { ... };") or vice versa. - switch (type_tag) { - case DW_TAG_class_type: - // We had a "class foo", see if we ended up with a "struct foo - // { ... };" - try_resolving_type = (tag == DW_TAG_structure_type); - break; - case DW_TAG_structure_type: - // We had a "struct foo", see if we ended up with a "class foo - // { ... };" - try_resolving_type = (tag == DW_TAG_class_type); - break; - default: - // Tags don't match, don't event try to resolve using this type - // whose name matches.... - break; - } - } - if (try_resolving_type) { - DWARFDeclContext type_dwarf_decl_ctx; - type_die.GetDWARFDeclContext(type_dwarf_decl_ctx); - - if (log) { - GetObjectFile()->GetModule()->LogMessage( - log, - "SymbolFileDWARF::" - "FindDefinitionTypeForDWARFDeclContext(tag=%s, " - "qualified-name='%s') trying die=0x%8.8x (%s)", - DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), - dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(), - type_dwarf_decl_ctx.GetQualifiedName()); - } + m_index->GetTypes(dwarf_decl_ctx, [&](DWARFDIE type_die) { + // Make sure type_die's langauge matches the type system we are + // looking for. We don't want to find a "Foo" type from Java if we + // are looking for a "Foo" type for C, C++, ObjC, or ObjC++. + if (type_system && + !type_system->SupportsLanguage(GetLanguage(*type_die.GetCU()))) + return true; + bool try_resolving_type = false; - // Make sure the decl contexts match all the way up - if (dwarf_decl_ctx == type_dwarf_decl_ctx) { - Type *resolved_type = ResolveType(type_die, false); - if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) { - type_sp = resolved_type->shared_from_this(); - break; - } - } - } else { - if (log) { - std::string qualified_name; - type_die.GetQualifiedName(qualified_name); - GetObjectFile()->GetModule()->LogMessage( - log, - "SymbolFileDWARF::" - "FindDefinitionTypeForDWARFDeclContext(tag=%s, " - "qualified-name='%s') ignoring die=0x%8.8x (%s)", - DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), - dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(), - qualified_name.c_str()); - } - } - } else { - m_index->ReportInvalidDIERef(die_ref, type_name.GetStringRef()); + // Don't try and resolve the DIE we are looking for with the DIE + // itself! + const dw_tag_t type_tag = type_die.Tag(); + // Make sure the tags match + if (type_tag == tag) { + // The tags match, lets try resolving this type + try_resolving_type = true; + } else { + // The tags don't match, but we need to watch our for a forward + // declaration for a struct and ("struct foo") ends up being a + // class ("class foo { ... };") or vice versa. + switch (type_tag) { + case DW_TAG_class_type: + // We had a "class foo", see if we ended up with a "struct foo + // { ... };" + try_resolving_type = (tag == DW_TAG_structure_type); + break; + case DW_TAG_structure_type: + // We had a "struct foo", see if we ended up with a "class foo + // { ... };" + try_resolving_type = (tag == DW_TAG_class_type); + break; + default: + // Tags don't match, don't event try to resolve using this type + // whose name matches.... + break; } } - } + + if (!try_resolving_type) { + if (log) { + std::string qualified_name; + type_die.GetQualifiedName(qualified_name); + GetObjectFile()->GetModule()->LogMessage( + log, + "SymbolFileDWARF::" + "FindDefinitionTypeForDWARFDeclContext(tag=%s, " + "qualified-name='%s') ignoring die=0x%8.8x (%s)", + DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), + dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(), + qualified_name.c_str()); + } + return true; + } + + DWARFDeclContext type_dwarf_decl_ctx = GetDWARFDeclContext(type_die); + + if (log) { + GetObjectFile()->GetModule()->LogMessage( + log, + "SymbolFileDWARF::" + "FindDefinitionTypeForDWARFDeclContext(tag=%s, " + "qualified-name='%s') trying die=0x%8.8x (%s)", + DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), + dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(), + type_dwarf_decl_ctx.GetQualifiedName()); + } + + // Make sure the decl contexts match all the way up + if (dwarf_decl_ctx != type_dwarf_decl_ctx) + return true; + + Type *resolved_type = ResolveType(type_die, false); + if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED) + return true; + + type_sp = resolved_type->shared_from_this(); + return false; + }); } } return type_sp; @@ -3045,8 +2935,7 @@ TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die, if (!die) return {}; - auto type_system_or_err = - GetTypeSystemForLanguage(die.GetCU()->GetLanguageType()); + auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU())); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), std::move(err), "Unable to parse type"); @@ -3067,7 +2956,7 @@ TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die, .AsCString("")); if (scope_qualified_name.size()) { m_function_scope_qualified_name_map[scope_qualified_name].insert( - die.GetID()); + *die.GetDIERef()); } } } @@ -3124,7 +3013,8 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) { size_t functions_added = 0; const dw_offset_t function_die_offset = func.GetID(); - DWARFDIE function_die = dwarf_cu->GetDIE(function_die_offset); + DWARFDIE function_die = + dwarf_cu->GetNonSkeletonUnit().GetDIE(function_die_offset); if (function_die) { ParseBlocksRecursive(*comp_unit, &func.GetBlock(false), function_die, LLDB_INVALID_ADDRESS, 0); @@ -3152,10 +3042,6 @@ size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) { size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { std::lock_guard guard(GetModuleMutex()); if (sc.comp_unit != nullptr) { - DWARFDebugInfo *info = DebugInfo(); - if (info == nullptr) - return 0; - if (sc.function) { DWARFDIE function_die = GetDIE(sc.function->GetID()); @@ -3170,7 +3056,7 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { return num_variables; } } else if (sc.comp_unit) { - DWARFUnit *dwarf_cu = info->GetUnitAtIndex(sc.comp_unit->GetID()); + DWARFUnit *dwarf_cu = DebugInfo().GetUnitAtIndex(sc.comp_unit->GetID()); if (dwarf_cu == nullptr) return 0; @@ -3182,25 +3068,16 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { variables = std::make_shared(); sc.comp_unit->SetVariableList(variables); - DIEArray die_offsets; - m_index->GetGlobalVariables(dwarf_cu->GetNonSkeletonUnit(), - die_offsets); - const size_t num_matches = die_offsets.size(); - if (num_matches) { - for (size_t i = 0; i < num_matches; ++i) { - const DIERef &die_ref = die_offsets[i]; - DWARFDIE die = GetDIE(die_ref); - if (die) { + m_index->GetGlobalVariables( + dwarf_cu->GetNonSkeletonUnit(), [&](DWARFDIE die) { VariableSP var_sp( ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS)); if (var_sp) { variables->AddVariableIfUnique(var_sp); ++vars_added; } - } else - m_index->ReportInvalidDIERef(die_ref, ""); - } - } + return true; + }); } return vars_added; } @@ -3412,12 +3289,10 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, // declaration context. if ((parent_tag == DW_TAG_compile_unit || parent_tag == DW_TAG_partial_unit) && - Language::LanguageIsCPlusPlus(die.GetLanguage())) { - DWARFDeclContext decl_ctx; - - die.GetDWARFDeclContext(decl_ctx); - mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString(); - } + Language::LanguageIsCPlusPlus(GetLanguage(*die.GetCU()))) + mangled = GetDWARFDeclContext(die) + .GetQualifiedNameAsConstString() + .GetCString(); } if (tag == DW_TAG_formal_parameter) @@ -3524,7 +3399,8 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, } } } else { - if (location_is_const_value_data) + if (location_is_const_value_data && + die.GetDIE()->IsGlobalOrStaticScopeVariable()) scope = eValueTypeVariableStatic; else { scope = eValueTypeVariableLocal; @@ -3603,7 +3479,7 @@ SymbolFileDWARF::FindBlockContainingSpecification( // Give the concrete function die specified by "func_die_offset", find the // concrete block whose DW_AT_specification or DW_AT_abstract_origin points // to "spec_block_die_offset" - return FindBlockContainingSpecification(DebugInfo()->GetDIE(func_die_ref), + return FindBlockContainingSpecification(DebugInfo().GetDIE(func_die_ref), spec_block_die_offset); } @@ -3762,7 +3638,8 @@ CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) { CallSiteParameterArray parameters; for (DWARFDIE child = call_site_die.GetFirstChild(); child.IsValid(); child = child.GetSibling()) { - if (child.Tag() != DW_TAG_call_site_parameter) + if (child.Tag() != DW_TAG_call_site_parameter && + child.Tag() != DW_TAG_GNU_call_site_parameter) continue; llvm::Optional LocationInCallee; @@ -3792,7 +3669,7 @@ CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) { dw_attr_t attr = attributes.AttributeAtIndex(i); if (attr == DW_AT_location) LocationInCallee = parse_simple_location(i); - if (attr == DW_AT_call_value) + if (attr == DW_AT_call_value || attr == DW_AT_GNU_call_site_value) LocationInCaller = parse_simple_location(i); } @@ -3805,12 +3682,13 @@ CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) { } /// Collect call graph edges present in a function DIE. -static std::vector> -CollectCallEdges(ModuleSP module, DWARFDIE function_die) { +std::vector> +SymbolFileDWARF::CollectCallEdges(ModuleSP module, 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); + bool has_call_edges = + function_die.GetAttributeValueAsUnsigned(DW_AT_call_all_calls, 0) || + function_die.GetAttributeValueAsUnsigned(DW_AT_GNU_all_call_sites, 0); if (!has_call_edges) return {}; @@ -3826,15 +3704,22 @@ CollectCallEdges(ModuleSP module, DWARFDIE function_die) { std::vector> call_edges; for (DWARFDIE child = function_die.GetFirstChild(); child.IsValid(); child = child.GetSibling()) { - if (child.Tag() != DW_TAG_call_site) + if (child.Tag() != DW_TAG_call_site && child.Tag() != DW_TAG_GNU_call_site) continue; llvm::Optional call_origin; llvm::Optional call_target; addr_t return_pc = LLDB_INVALID_ADDRESS; + addr_t call_inst_pc = LLDB_INVALID_ADDRESS; + addr_t low_pc = LLDB_INVALID_ADDRESS; + bool tail_call = false; + // Second DW_AT_low_pc may come from DW_TAG_subprogram referenced by + // DW_TAG_GNU_call_site's DW_AT_abstract_origin overwriting our 'low_pc'. + // So do not inherit attributes from DW_AT_abstract_origin. DWARFAttributes attributes; - const size_t num_attributes = child.GetAttributes(attributes); + const size_t num_attributes = + child.GetAttributes(attributes, DWARFDIE::Recurse::no); for (size_t i = 0; i < num_attributes; ++i) { DWARFFormValue form_value; if (!attributes.ExtractFormValueAtIndex(i, form_value)) { @@ -3844,8 +3729,11 @@ CollectCallEdges(ModuleSP module, DWARFDIE function_die) { dw_attr_t attr = attributes.AttributeAtIndex(i); + if (attr == DW_AT_call_tail_call || attr == DW_AT_GNU_tail_call) + tail_call = form_value.Boolean(); + // Extract DW_AT_call_origin (the call target's DIE). - if (attr == DW_AT_call_origin) { + if (attr == DW_AT_call_origin || attr == DW_AT_abstract_origin) { call_origin = form_value.Reference(); if (!call_origin->IsValid()) { LLDB_LOG(log, "CollectCallEdges: Invalid call origin in {0}", @@ -3854,15 +3742,24 @@ CollectCallEdges(ModuleSP module, DWARFDIE function_die) { } } + if (attr == DW_AT_low_pc) + low_pc = form_value.Address(); + // 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. if (attr == DW_AT_call_return_pc) return_pc = form_value.Address(); + // Extract DW_AT_call_pc (the PC at the call/branch instruction). It + // should only ever be unavailable for non-tail calls, in which case use + // LLDB_INVALID_ADDRESS. + if (attr == DW_AT_call_pc) + call_inst_pc = form_value.Address(); + // Extract DW_AT_call_target (the location of the address of the indirect // call). - if (attr == DW_AT_call_target) { + if (attr == DW_AT_call_target || attr == DW_AT_GNU_call_site_target) { if (!DWARFFormValue::IsBlockForm(form_value.Form())) { LLDB_LOG(log, "CollectCallEdges: AT_call_target does not have block form"); @@ -3882,16 +3779,39 @@ CollectCallEdges(ModuleSP module, DWARFDIE function_die) { continue; } + addr_t caller_address; + CallEdge::AddrType caller_address_type; + if (return_pc != LLDB_INVALID_ADDRESS) { + caller_address = return_pc; + caller_address_type = CallEdge::AddrType::AfterCall; + } else if (low_pc != LLDB_INVALID_ADDRESS) { + caller_address = low_pc; + caller_address_type = CallEdge::AddrType::AfterCall; + } else if (call_inst_pc != LLDB_INVALID_ADDRESS) { + caller_address = call_inst_pc; + caller_address_type = CallEdge::AddrType::Call; + } else { + LLDB_LOG(log, "CollectCallEdges: No caller address"); + continue; + } + // Adjust any PC forms. It needs to be fixed up if the main executable + // contains a debug map (i.e. pointers to object files), because we need a + // file address relative to the executable's text section. + caller_address = FixupAddress(caller_address); + // Extract call site parameters. CallSiteParameterArray parameters = CollectCallSiteParameters(module, child); std::unique_ptr edge; if (call_origin) { - LLDB_LOG(log, "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x})", - call_origin->GetPubname(), return_pc); - edge = std::make_unique(call_origin->GetMangledName(), - return_pc, std::move(parameters)); + LLDB_LOG(log, + "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x}) " + "(call-PC: {2:x})", + call_origin->GetPubname(), return_pc, call_inst_pc); + edge = std::make_unique( + call_origin->GetMangledName(), caller_address_type, caller_address, + tail_call, std::move(parameters)); } else { if (log) { StreamString call_target_desc; @@ -3900,8 +3820,9 @@ CollectCallEdges(ModuleSP module, DWARFDIE function_die) { LLDB_LOG(log, "CollectCallEdges: Found indirect call target: {0}", call_target_desc.GetString()); } - edge = std::make_unique(*call_target, return_pc, - std::move(parameters)); + edge = std::make_unique( + *call_target, caller_address_type, caller_address, tail_call, + std::move(parameters)); } if (log && parameters.size()) { @@ -3925,6 +3846,11 @@ CollectCallEdges(ModuleSP module, DWARFDIE function_die) { std::vector> SymbolFileDWARF::ParseCallEdgesInFunction(UserID func_id) { + // ParseCallEdgesInFunction must be called at the behest of an exclusively + // locked lldb::Function instance. Storage for parsed call edges is owned by + // the lldb::Function instance: locking at the SymbolFile level would be too + // late, because the act of storing results from ParseCallEdgesInFunction + // would be racy. DWARFDIE func_die = GetDIE(func_id.GetID()); if (func_die.IsValid()) return CollectCallEdges(GetObjectFile()->GetModule(), func_die); @@ -3945,8 +3871,8 @@ void SymbolFileDWARF::DumpClangAST(Stream &s) { auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus); if (!ts_or_err) return; - ClangASTContext *clang = - llvm::dyn_cast_or_null(&ts_or_err.get()); + TypeSystemClang *clang = + llvm::dyn_cast_or_null(&ts_or_err.get()); if (!clang) return; clang->Dump(s); @@ -3957,26 +3883,93 @@ SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() { lldb::ModuleSP module_sp(m_debug_map_module_wp.lock()); if (module_sp) { m_debug_map_symfile = - (SymbolFileDWARFDebugMap *)module_sp->GetSymbolFile(); + static_cast(module_sp->GetSymbolFile()); } } return m_debug_map_symfile; } -SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() { +const std::shared_ptr &SymbolFileDWARF::GetDwpSymbolFile() { llvm::call_once(m_dwp_symfile_once_flag, [this]() { ModuleSpec module_spec; module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec(); module_spec.GetSymbolFileSpec() = - FileSpec(m_objfile_sp->GetFileSpec().GetPath() + ".dwp"); + FileSpec(m_objfile_sp->GetModule()->GetFileSpec().GetPath() + ".dwp"); FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); FileSpec dwp_filespec = Symbols::LocateExecutableSymbolFile(module_spec, search_paths); if (FileSystem::Instance().Exists(dwp_filespec)) { - m_dwp_symfile = SymbolFileDWARFDwp::Create(GetObjectFile()->GetModule(), - dwp_filespec); + DataBufferSP dwp_file_data_sp; + lldb::offset_t dwp_file_data_offset = 0; + ObjectFileSP dwp_obj_file = ObjectFile::FindPlugin( + GetObjectFile()->GetModule(), &dwp_filespec, 0, + FileSystem::Instance().GetByteSize(dwp_filespec), dwp_file_data_sp, + dwp_file_data_offset); + if (!dwp_obj_file) + return; + m_dwp_symfile = + std::make_shared(*this, dwp_obj_file, 0x3fffffff); } }); - return m_dwp_symfile.get(); + return m_dwp_symfile; +} + +llvm::Expected SymbolFileDWARF::GetTypeSystem(DWARFUnit &unit) { + return unit.GetSymbolFileDWARF().GetTypeSystemForLanguage(GetLanguage(unit)); +} + +DWARFASTParser *SymbolFileDWARF::GetDWARFParser(DWARFUnit &unit) { + auto type_system_or_err = GetTypeSystem(unit); + if (auto err = type_system_or_err.takeError()) { + LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), + std::move(err), "Unable to get DWARFASTParser"); + return nullptr; + } + return type_system_or_err->GetDWARFParser(); +} + +CompilerDecl SymbolFileDWARF::GetDecl(const DWARFDIE &die) { + if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) + return dwarf_ast->GetDeclForUIDFromDWARF(die); + return CompilerDecl(); +} + +CompilerDeclContext SymbolFileDWARF::GetDeclContext(const DWARFDIE &die) { + if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) + return dwarf_ast->GetDeclContextForUIDFromDWARF(die); + return CompilerDeclContext(); +} + +CompilerDeclContext +SymbolFileDWARF::GetContainingDeclContext(const DWARFDIE &die) { + if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) + return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); + return CompilerDeclContext(); +} + +DWARFDeclContext SymbolFileDWARF::GetDWARFDeclContext(const DWARFDIE &die) { + if (!die.IsValid()) + return {}; + DWARFDeclContext dwarf_decl_ctx = + die.GetDIE()->GetDWARFDeclContext(die.GetCU()); + dwarf_decl_ctx.SetLanguage(GetLanguage(*die.GetCU())); + return dwarf_decl_ctx; +} + +LanguageType SymbolFileDWARF::LanguageTypeFromDWARF(uint64_t val) { + // Note: user languages between lo_user and hi_user must be handled + // explicitly here. + switch (val) { + case DW_LANG_Mips_Assembler: + return eLanguageTypeMipsAssembler; + case DW_LANG_GOOGLE_RenderScript: + return eLanguageTypeExtRenderScript; + default: + return static_cast(val); + } +} + +LanguageType SymbolFileDWARF::GetLanguage(DWARFUnit &unit) { + return LanguageTypeFromDWARF(unit.GetDWARFLanguageType()); } diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 23e26732453..76ceb279c71 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -6,17 +6,17 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_SymbolFileDWARF_h_ -#define SymbolFileDWARF_SymbolFileDWARF_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H #include #include #include -#include #include #include #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SetVector.h" #include "llvm/Support/Threading.h" #include "lldb/Core/UniqueCStringMap.h" @@ -90,8 +90,6 @@ public: static lldb_private::SymbolFile * CreateInstance(lldb::ObjectFileSP objfile_sp); - static lldb_private::FileSpecList GetSymlinkPaths(); - // Constructors and Destructors SymbolFileDWARF(lldb::ObjectFileSP objfile_sp, @@ -108,6 +106,9 @@ public: lldb::LanguageType ParseLanguage(lldb_private::CompileUnit &comp_unit) override; + lldb_private::XcodeSDK + ParseXcodeSDK(lldb_private::CompileUnit &comp_unit) override; + size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override; bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override; @@ -168,7 +169,7 @@ public: void FindGlobalVariables(lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, lldb_private::VariableList &variables) override; @@ -177,7 +178,7 @@ public: lldb_private::VariableList &variables) override; void FindFunctions(lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, lldb::FunctionNameType name_type_mask, bool include_inlines, lldb_private::SymbolContextList &sc_list) override; @@ -192,7 +193,7 @@ public: void FindTypes(lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, lldb_private::TypeMap &types) override; @@ -211,7 +212,7 @@ public: lldb_private::CompilerDeclContext FindNamespace( lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx) override; + const lldb_private::CompilerDeclContext &parent_decl_ctx) override; void PreloadSymbols() override; @@ -224,11 +225,7 @@ public: DWARFDebugAbbrev *DebugAbbrev(); - const DWARFDebugAbbrev *DebugAbbrev() const; - - DWARFDebugInfo *DebugInfo(); - - const DWARFDebugInfo *DebugInfo() const; + DWARFDebugInfo &DebugInfo(); DWARFDebugRanges *GetDebugRanges(); @@ -243,8 +240,8 @@ public: lldb_private::CompileUnit * GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu); - virtual size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name, - DIEArray &method_die_offsets); + virtual void GetObjCMethods(lldb_private::ConstString class_name, + llvm::function_ref callback); bool Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu); @@ -252,8 +249,6 @@ public: static DWARFDIE GetParentSymbolContextDIE(const DWARFDIE &die); - virtual lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu); - lldb::ModuleSP GetExternalModule(lldb_private::ConstString name); typedef std::map @@ -278,22 +273,17 @@ public: lldb::user_id_t GetUID(DIERef ref); - std::unique_ptr + std::shared_ptr GetDwoSymbolFileForCompileUnit(DWARFUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die); - // For regular SymbolFileDWARF instances the method returns nullptr, - // for the instances of the subclass SymbolFileDWARFDwo - // the method returns a pointer to the base compile unit. - virtual DWARFCompileUnit *GetBaseCompileUnit() { return nullptr; } - virtual llvm::Optional GetDwoNum() { return llvm::None; } /// If this is a DWARF object with a single CU, return its DW_AT_dwo_id. llvm::Optional GetDWOId(); static bool - DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx, + DIEInDeclContext(const lldb_private::CompilerDeclContext &parent_decl_ctx, const DWARFDIE &die); std::vector> @@ -305,8 +295,30 @@ public: lldb_private::DWARFContext &GetDWARFContext() { return m_context; } + const std::shared_ptr &GetDwpSymbolFile(); + lldb_private::FileSpec GetFile(DWARFUnit &unit, size_t file_idx); + static llvm::Expected + GetTypeSystem(DWARFUnit &unit); + + static DWARFASTParser *GetDWARFParser(DWARFUnit &unit); + + // CompilerDecl related functions + + static lldb_private::CompilerDecl GetDecl(const DWARFDIE &die); + + static lldb_private::CompilerDeclContext GetDeclContext(const DWARFDIE &die); + + static lldb_private::CompilerDeclContext + GetContainingDeclContext(const DWARFDIE &die); + + static DWARFDeclContext GetDWARFDeclContext(const DWARFDIE &die); + + static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val); + + static lldb::LanguageType GetLanguage(DWARFUnit &unit); + protected: typedef llvm::DenseMap DIEToTypePtr; @@ -315,25 +327,16 @@ protected: typedef llvm::DenseMap DIEToClangType; - typedef llvm::DenseMap - ClangTypeToDIE; + typedef llvm::DenseMap ClangTypeToDIE; - struct DWARFDataSegment { - llvm::once_flag m_flag; - lldb_private::DWARFDataExtractor m_data; - }; - - DISALLOW_COPY_AND_ASSIGN(SymbolFileDWARF); - - const lldb_private::DWARFDataExtractor & - GetCachedSectionData(lldb::SectionType sect_type, - DWARFDataSegment &data_segment); + SymbolFileDWARF(const SymbolFileDWARF &) = delete; + const SymbolFileDWARF &operator=(const SymbolFileDWARF &) = delete; virtual void LoadSectionData(lldb::SectionType sect_type, lldb_private::DWARFDataExtractor &data); bool DeclContextMatchesThisSymbolFile( - const lldb_private::CompilerDeclContext *decl_ctx); + const lldb_private::CompilerDeclContext &decl_ctx); uint32_t CalculateNumCompileUnits() override; @@ -341,6 +344,8 @@ protected: lldb_private::TypeList &GetTypeList() override; + lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu); + virtual DWARFUnit * GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit); @@ -383,6 +388,13 @@ protected: bool ResolveFunction(const DWARFDIE &die, bool include_inlines, lldb_private::SymbolContextList &sc_list); + /// Resolve functions and (possibly) blocks for the given file address and a + /// compile unit. The compile unit comes from the sc argument and it must be + /// set. The results of the lookup (if any) are written back to the symbol + /// context. + void ResolveFunctionAndBlock(lldb::addr_t file_vm_addr, bool lookup_block, + lldb_private::SymbolContext &sc); + virtual lldb::TypeSP FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx); @@ -417,9 +429,21 @@ protected: bool ClassContainsSelector(const DWARFDIE &class_die, lldb_private::ConstString selector); + /// Parse call site entries (DW_TAG_call_site), including any nested call site + /// parameters (DW_TAG_call_site_parameter). + std::vector> + CollectCallEdges(lldb::ModuleSP module, DWARFDIE function_die); + + /// If this symbol file is linked to by a debug map (see + /// SymbolFileDWARFDebugMap), and \p file_addr is a file address relative to + /// an object file, adjust \p file_addr so that it is relative to the main + /// binary. Returns the adjusted address, or \p file_addr if no adjustment is + /// needed, on success and LLDB_INVALID_ADDRESS otherwise. + lldb::addr_t FixupAddress(lldb::addr_t file_addr); + bool FixupAddress(lldb_private::Address &addr); - typedef std::set TypeSet; + typedef llvm::SetVector TypeSet; void GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset, dw_offset_t max_die_offset, uint32_t type_mask, @@ -454,7 +478,7 @@ protected: }; llvm::Optional DecodeUID(lldb::user_id_t uid); - SymbolFileDWARFDwp *GetDwpSymbolFile(); + void FindDwpSymbolFile(); const lldb_private::FileSpecList &GetTypeUnitSupportFiles(DWARFTypeUnit &tu); @@ -462,17 +486,14 @@ protected: SymbolFileDWARFDebugMap *m_debug_map_symfile; llvm::once_flag m_dwp_symfile_once_flag; - std::unique_ptr m_dwp_symfile; + std::shared_ptr m_dwp_symfile; lldb_private::DWARFContext m_context; - DWARFDataSegment m_data_debug_loc; - DWARFDataSegment m_data_debug_loclists; + llvm::once_flag m_info_once_flag; + std::unique_ptr m_info; - // The unique pointer items below are generated on demand if and when someone - // accesses them through a non const version of this class. std::unique_ptr m_abbr; - std::unique_ptr m_info; std::unique_ptr m_global_aranges_up; typedef std::unordered_map @@ -484,7 +505,7 @@ protected: bool m_fetched_external_modules : 1; lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type; - typedef std::set DIERefSet; + typedef std::set DIERefSet; typedef llvm::StringMap NameToOffsetMap; NameToOffsetMap m_function_scope_qualified_name_map; std::unique_ptr m_ranges; @@ -498,4 +519,4 @@ protected: std::vector m_lldb_cu_to_dwarf_unit; }; -#endif // SymbolFileDWARF_SymbolFileDWARF_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index cce666a222d..6515d78b8f2 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -1,4 +1,4 @@ -//===-- SymbolFileDWARFDebugMap.cpp -----------------------------*- C++ -*-===// +//===-- SymbolFileDWARFDebugMap.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -108,8 +108,7 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap( // First we find the original symbol in the .o file's symbol table Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType( - exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, - Mangled::ePreferMangled), + exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny); if (oso_fun_symbol) { // Add the inverse OSO file address to debug map entry mapping @@ -139,8 +138,7 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap( // in the .o file Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType( - exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, - Mangled::ePreferMangled), + exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), eSymbolTypeData, Symtab::eDebugNo, Symtab::eVisibilityAny); if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() && oso_gsym_symbol->ValueIsAddress()) { @@ -416,6 +414,7 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo( FileSpec oso_file(oso_path); ConstString oso_object; if (FileSystem::Instance().Exists(oso_file)) { + FileSystem::Instance().Collect(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( @@ -531,7 +530,7 @@ SymbolFileDWARF * SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file) { if (sym_file && sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic()) - return (SymbolFileDWARF *)sym_file; + return static_cast(sym_file); return nullptr; } @@ -630,6 +629,14 @@ SymbolFileDWARFDebugMap::ParseLanguage(CompileUnit &comp_unit) { return eLanguageTypeUnknown; } +XcodeSDK SymbolFileDWARFDebugMap::ParseXcodeSDK(CompileUnit &comp_unit) { + std::lock_guard guard(GetModuleMutex()); + SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); + if (oso_dwarf) + return oso_dwarf->ParseXcodeSDK(comp_unit); + return {}; +} + size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) { std::lock_guard guard(GetModuleMutex()); SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); @@ -826,7 +833,7 @@ uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext( } void SymbolFileDWARFDebugMap::PrivateFindGlobalVariables( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + 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) { @@ -848,7 +855,7 @@ void SymbolFileDWARFDebugMap::PrivateFindGlobalVariables( } void SymbolFileDWARFDebugMap::FindGlobalVariables( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, VariableList &variables) { std::lock_guard guard(GetModuleMutex()); uint32_t total_matches = 0; @@ -1002,7 +1009,7 @@ static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp, } void SymbolFileDWARFDebugMap::FindFunctions( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) { std::lock_guard guard(GetModuleMutex()); @@ -1172,7 +1179,7 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE( } void SymbolFileDWARFDebugMap::FindTypes( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) { @@ -1209,7 +1216,7 @@ void SymbolFileDWARFDebugMap::FindTypes( CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace( lldb_private::ConstString name, - const CompilerDeclContext *parent_decl_ctx) { + const CompilerDeclContext &parent_decl_ctx) { std::lock_guard guard(GetModuleMutex()); CompilerDeclContext matching_namespace; @@ -1225,6 +1232,9 @@ CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace( void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s) { ForEachSymbolFile([&s](SymbolFileDWARF *oso_dwarf) -> bool { oso_dwarf->DumpClangAST(s); + // The underlying assumption is that DumpClangAST(...) will obtain the + // AST from the underlying TypeSystem and therefore we only need to do + // this once and can stop after the first iteration hence we return true. return true; }); } diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h index 035a902498b..06f0d48c04c 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_ -#define SymbolFileDWARF_SymbolFileDWARFDebugMap_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H #include "lldb/Symbol/SymbolFile.h" #include "lldb/Utility/RangeMap.h" @@ -57,11 +57,10 @@ public: // Compile Unit function calls lldb::LanguageType ParseLanguage(lldb_private::CompileUnit &comp_unit) override; - + lldb_private::XcodeSDK + ParseXcodeSDK(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 ForEachExternalModule( @@ -105,14 +104,14 @@ public: lldb_private::SymbolContextList &sc_list) override; void FindGlobalVariables(lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, lldb_private::VariableList &variables) override; void FindGlobalVariables(const lldb_private::RegularExpression ®ex, uint32_t max_matches, lldb_private::VariableList &variables) override; void FindFunctions(lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, lldb::FunctionNameType name_type_mask, bool include_inlines, lldb_private::SymbolContextList &sc_list) override; @@ -121,7 +120,7 @@ public: lldb_private::SymbolContextList &sc_list) override; void FindTypes(lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, lldb_private::TypeMap &types) override; @@ -132,7 +131,7 @@ public: lldb_private::TypeMap &types) override; lldb_private::CompilerDeclContext FindNamespace( lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx) override; + const lldb_private::CompilerDeclContext &parent_decl_ctx) override; void GetTypes(lldb_private::SymbolContextScope *sc_scope, lldb::TypeClass type_mask, lldb_private::TypeList &type_list) override; @@ -254,7 +253,7 @@ protected: void PrivateFindGlobalVariables( lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, const std::vector &name_symbol_indexes, uint32_t max_matches, lldb_private::VariableList &variables); @@ -379,4 +378,4 @@ protected: DWARFDebugAranges *debug_aranges); }; -#endif // #ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp index f75f06f31e2..3aaa7d330b8 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp @@ -1,4 +1,4 @@ -//===-- SymbolFileDWARFDwo.cpp ----------------------------------*- C++ -*-===// +//===-- SymbolFileDWARFDwo.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -23,62 +23,52 @@ using namespace lldb_private; char SymbolFileDWARFDwo::ID; -SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile, - DWARFCompileUnit &dwarf_cu) +SymbolFileDWARFDwo::SymbolFileDWARFDwo(SymbolFileDWARF &base_symbol_file, + ObjectFileSP objfile, uint32_t id) : SymbolFileDWARF(objfile, objfile->GetSectionList( /*update_module_section_list*/ false)), - m_base_dwarf_cu(dwarf_cu) { - SetID(((lldb::user_id_t)dwarf_cu.GetID()) << 32); -} - -void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type, - DWARFDataExtractor &data) { - const SectionList *section_list = - m_objfile_sp->GetSectionList(false /* update_module_section_list */); - if (section_list) { - SectionSP section_sp(section_list->FindSectionByType(sect_type, true)); - if (section_sp) { + m_base_symbol_file(base_symbol_file) { + SetID(user_id_t(id) << 32); - if (m_objfile_sp->ReadSectionData(section_sp.get(), data) != 0) - return; + // Parsing of the dwarf unit index is not thread-safe, so we need to prime it + // to enable subsequent concurrent lookups. + m_context.GetAsLLVM().getCUIndex(); +} - data.Clear(); +DWARFCompileUnit *SymbolFileDWARFDwo::GetDWOCompileUnitForHash(uint64_t hash) { + if (const llvm::DWARFUnitIndex &index = m_context.GetAsLLVM().getCUIndex()) { + if (const llvm::DWARFUnitIndex::Entry *entry = index.getFromHash(hash)) { + if (auto *unit_contrib = entry->getContribution()) + return llvm::dyn_cast_or_null( + DebugInfo().GetUnitAtOffset(DIERef::Section::DebugInfo, + unit_contrib->Offset)); } + return nullptr; } - SymbolFileDWARF::LoadSectionData(sect_type, data); -} - -lldb::CompUnitSP -SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { - assert(GetCompileUnit() == &dwarf_cu && - "SymbolFileDWARFDwo::ParseCompileUnit called with incompatible " - "compile unit"); - return GetBaseSymbolFile().ParseCompileUnit(m_base_dwarf_cu); -} - -DWARFCompileUnit *SymbolFileDWARFDwo::GetCompileUnit() { - if (!m_cu) - m_cu = ComputeCompileUnit(); - return m_cu; + DWARFCompileUnit *cu = FindSingleCompileUnit(); + if (!cu) + return nullptr; + if (hash != + cu->GetUnitDIEOnly().GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0)) + return nullptr; + return cu; } -DWARFCompileUnit *SymbolFileDWARFDwo::ComputeCompileUnit() { - DWARFDebugInfo *debug_info = DebugInfo(); - if (!debug_info) - return nullptr; +DWARFCompileUnit *SymbolFileDWARFDwo::FindSingleCompileUnit() { + DWARFDebugInfo &debug_info = DebugInfo(); // Right now we only support dwo files with one compile unit. If we don't have // type units, we can just check for the unit count. - if (!debug_info->ContainsTypeUnits() && debug_info->GetNumUnits() == 1) - return llvm::cast(debug_info->GetUnitAtIndex(0)); + if (!debug_info.ContainsTypeUnits() && debug_info.GetNumUnits() == 1) + return llvm::cast(debug_info.GetUnitAtIndex(0)); // Otherwise, we have to run through all units, and find the compile unit that // way. DWARFCompileUnit *cu = nullptr; - for (size_t i = 0; i < debug_info->GetNumUnits(); ++i) { + for (size_t i = 0; i < debug_info.GetNumUnits(); ++i) { if (auto *candidate = - llvm::dyn_cast(debug_info->GetUnitAtIndex(i))) { + llvm::dyn_cast(debug_info.GetUnitAtIndex(i))) { if (cu) return nullptr; // More that one CU found. cu = candidate; @@ -87,11 +77,6 @@ DWARFCompileUnit *SymbolFileDWARFDwo::ComputeCompileUnit() { return cu; } -DWARFUnit * -SymbolFileDWARFDwo::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) { - return GetCompileUnit(); -} - SymbolFileDWARF::DIEToTypePtr &SymbolFileDWARFDwo::GetDIEToType() { return GetBaseSymbolFile().GetDIEToType(); } @@ -110,10 +95,10 @@ SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie() { return GetBaseSymbolFile().GetForwardDeclClangTypeToDie(); } -size_t SymbolFileDWARFDwo::GetObjCMethodDIEOffsets( - lldb_private::ConstString class_name, DIEArray &method_die_offsets) { - return GetBaseSymbolFile().GetObjCMethodDIEOffsets(class_name, - method_die_offsets); +void SymbolFileDWARFDwo::GetObjCMethods( + lldb_private::ConstString class_name, + llvm::function_ref callback) { + GetBaseSymbolFile().GetObjCMethods(class_name, callback); } UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() { @@ -133,10 +118,6 @@ lldb::TypeSP SymbolFileDWARFDwo::FindCompleteObjCDefinitionTypeForDIE( die, type_name, must_be_implementation); } -SymbolFileDWARF &SymbolFileDWARFDwo::GetBaseSymbolFile() { - return m_base_dwarf_cu.GetSymbolFileDWARF(); -} - llvm::Expected SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) { return GetBaseSymbolFile().GetTypeSystemForLanguage(language); @@ -144,7 +125,7 @@ SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) { DWARFDIE SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) { - if (*die_ref.dwo_num() == GetDwoNum()) - return DebugInfo()->GetDIE(die_ref); + if (die_ref.dwo_num() == GetDwoNum()) + return DebugInfo().GetDIE(die_ref); return GetBaseSymbolFile().GetDIE(die_ref); } diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h index 0855dba044e..93538aac3c5 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_ -#define SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDWO_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDWO_H #include "SymbolFileDWARF.h" @@ -24,19 +24,15 @@ public: static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} - SymbolFileDWARFDwo(lldb::ObjectFileSP objfile, DWARFCompileUnit &dwarf_cu); + SymbolFileDWARFDwo(SymbolFileDWARF &m_base_symbol_file, + lldb::ObjectFileSP objfile, uint32_t id); ~SymbolFileDWARFDwo() override = default; - lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu) override; + DWARFCompileUnit *GetDWOCompileUnitForHash(uint64_t hash); - DWARFCompileUnit *GetCompileUnit(); - - DWARFUnit * - GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) override; - - size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name, - DIEArray &method_die_offsets) override; + void GetObjCMethods(lldb_private::ConstString class_name, + llvm::function_ref callback) override; llvm::Expected GetTypeSystemForLanguage(lldb::LanguageType language) override; @@ -44,14 +40,9 @@ public: DWARFDIE GetDIE(const DIERef &die_ref) override; - DWARFCompileUnit *GetBaseCompileUnit() override { return &m_base_dwarf_cu; } - llvm::Optional GetDwoNum() override { return GetID() >> 32; } protected: - void LoadSectionData(lldb::SectionType sect_type, - lldb_private::DWARFDataExtractor &data) override; - DIEToTypePtr &GetDIEToType() override; DIEToVariableSP &GetDIEToVariable() override; @@ -69,12 +60,13 @@ protected: const DWARFDIE &die, lldb_private::ConstString type_name, bool must_be_implementation) override; - SymbolFileDWARF &GetBaseSymbolFile(); + SymbolFileDWARF &GetBaseSymbolFile() { return m_base_symbol_file; } - DWARFCompileUnit *ComputeCompileUnit(); + /// If this file contains exactly one compile unit, this function will return + /// it. Otherwise it returns nullptr. + DWARFCompileUnit *FindSingleCompileUnit(); - DWARFCompileUnit &m_base_dwarf_cu; - DWARFCompileUnit *m_cu = nullptr; + SymbolFileDWARF &m_base_symbol_file; }; -#endif // SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDWO_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td index ef6ae349858..2f1ce88808b 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td @@ -1,10 +1,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td" let Definition = "symbolfiledwarf" in { - def SymLinkPaths: Property<"comp-dir-symlink-paths", "FileSpecList">, - Global, - DefaultStringValue<"">, - Desc<"If the DW_AT_comp_dir matches any of these paths the symbolic links will be resolved at DWARF parse time.">; def IgnoreIndexes: Property<"ignore-file-indexes", "Boolean">, Global, DefaultFalse, diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp index 4862fea8d07..2181989cd37 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp @@ -1,4 +1,4 @@ -//===-- UniqueDWARFASTType.cpp ----------------------------------*- C++ -*-===// +//===-- UniqueDWARFASTType.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h index 1269dbac712..a1b1a300978 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_UniqueDWARFASTType_h_ -#define lldb_UniqueDWARFASTType_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_UNIQUEDWARFASTTYPE_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_UNIQUEDWARFASTTYPE_H #include @@ -100,4 +100,4 @@ protected: collection m_collection; }; -#endif // lldb_UniqueDWARFASTType_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_UNIQUEDWARFASTTYPE_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt index aaecec4765f..7dab9370e51 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt @@ -1,4 +1,4 @@ -add_lldb_library(lldbPluginSymbolFileNativePDB PLUGIN +add_lldb_library(lldbPluginSymbolFileNativePDB CodeViewRegisterMapping.cpp CompileUnitIndex.cpp DWARFLocationExpression.cpp @@ -14,6 +14,7 @@ add_lldb_library(lldbPluginSymbolFileNativePDB PLUGIN lldbCore lldbSymbol lldbUtility + lldbPluginTypeSystemClang CLANG_LIBS clangAST clangLex diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp index 3834165c71c..ca9ddcec287 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp @@ -1,4 +1,4 @@ -//===-- CodeViewRegisterMapping.cpp -----------------------------*- C++ -*-===// +//===-- CodeViewRegisterMapping.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h index b1c31e0c178..02c7495565b 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Plugins_SymbolFile_PDB_CodeViewRegisterMapping_h_ -#define lldb_Plugins_SymbolFile_PDB_CodeViewRegisterMapping_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_CODEVIEWREGISTERMAPPING_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_CODEVIEWREGISTERMAPPING_H #include "llvm/ADT/Triple.h" #include "llvm/DebugInfo/CodeView/CodeView.h" diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp index 830d78f8167..f25dc84fb34 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp @@ -1,4 +1,4 @@ -//===-- CompileUnitIndex.cpp ------------------------------------*- C++ -*-===// +//===-- CompileUnitIndex.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -154,7 +154,7 @@ CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) { // 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(); + std::string s = std::string(main_file.str()); llvm::sys::path::native(main_file); uint32_t file_count = modules.getSourceFileCount(modi); diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h index 44a1c8cdd9c..088de970cbf 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_COMPILEUNITINDEX_H -#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_COMPILEUNITINDEX_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_COMPILEUNITINDEX_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_COMPILEUNITINDEX_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp index 6aaff06cc13..d0672352a58 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp @@ -1,4 +1,4 @@ -//===-- DWARFLocationExpression.cpp -----------------------------*- C++ -*-===// +//===-- DWARFLocationExpression.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h index c37d715babd..99da09b70fe 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h @@ -6,14 +6,15 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H -#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H #include "lldb/lldb-forward.h" #include "llvm/DebugInfo/CodeView/CodeView.h" namespace llvm { class APSInt; +class StringRef; namespace codeview { class TypeIndex; } diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp index 4588c80aa1b..0acc77d7c67 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -14,11 +14,11 @@ #include "llvm/DebugInfo/PDB/Native/TpiStream.h" #include "llvm/Demangle/MicrosoftDemangle.h" +#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Module.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangASTMetadata.h" -#include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/LLDBAssert.h" @@ -178,7 +178,7 @@ GetNestedTagDefinition(const NestedTypeRecord &Record, // 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(); + std::string qname = std::string(parent.asTag().getUniqueName()); if (qname.size() < 4 || child.asTag().getUniqueName().size() < 4) return llvm::None; @@ -202,7 +202,7 @@ static bool IsAnonymousNamespaceName(llvm::StringRef name) { return name == "`anonymous namespace'" || name == "`anonymous-namespace'"; } -PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index, ClangASTContext &clang) +PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index, TypeSystemClang &clang) : m_index(index), m_clang(clang) { BuildParentMap(); } @@ -221,7 +221,7 @@ PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) { 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}; + return {m_clang.GetTranslationUnitDecl(), std::string(record.UniqueName)}; llvm::ms_demangle::IdentifierNode *idn = ttn->QualifiedName->getUnqualifiedIdentifier(); @@ -248,7 +248,7 @@ PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) { // 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}; + return {context, std::string(record.Name)}; for (llvm::ms_demangle::Node *scope : scopes) { auto *nii = static_cast(scope); @@ -507,7 +507,7 @@ PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) { llvm::StringRef uname = specs.back().GetBaseName(); specs = specs.drop_back(); if (specs.empty()) - return {context, name}; + return {context, std::string(name)}; llvm::StringRef scope_name = specs.back().GetFullName(); @@ -517,7 +517,7 @@ PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) { clang::QualType qt = GetOrCreateType(types.back()); clang::TagDecl *tag = qt->getAsTagDecl(); if (tag) - return {clang::TagDecl::castToDeclContext(tag), uname}; + return {clang::TagDecl::castToDeclContext(tag), std::string(uname)}; types.pop_back(); } @@ -526,7 +526,7 @@ PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) { std::string ns_name = spec.GetBaseName().str(); context = GetOrCreateNamespaceDecl(ns_name.c_str(), *context); } - return {context, uname}; + return {context, std::string(uname)}; } clang::DeclContext * @@ -656,7 +656,7 @@ bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) { lldbassert(IsTagRecord(type_id, m_index.tpi())); clang::QualType tag_qt = m_clang.getASTContext().getTypeDeclType(&tag); - ClangASTContext::SetHasExternalStorage(tag_qt.getAsOpaquePtr(), false); + TypeSystemClang::SetHasExternalStorage(tag_qt.getAsOpaquePtr(), false); TypeIndex tag_ti = type_id.index; CVType cvt = m_index.tpi().getType(tag_ti); @@ -681,7 +681,7 @@ bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) { // 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()); + UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index); auto error = llvm::codeview::visitMemberRecordStream(field_list_cvt.data(), completer); completer.complete(); @@ -776,12 +776,13 @@ clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id, metadata.SetUserID(toOpaqueUid(id)); metadata.SetIsDynamicCXXType(false); - CompilerType ct = m_clang.CreateRecordType( - context, access, uname, ttk, lldb::eLanguageTypeC_plus_plus, &metadata); + CompilerType ct = + m_clang.CreateRecordType(context, OptionalClangModuleID(), access, uname, + ttk, lldb::eLanguageTypeC_plus_plus, &metadata); lldbassert(ct.IsValid()); - ClangASTContext::StartTagDeclarationDefinition(ct); + TypeSystemClang::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 @@ -789,7 +790,7 @@ clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id, clang::QualType result = clang::QualType::getFromOpaquePtr(ct.GetOpaqueQualType()); - ClangASTContext::SetHasExternalStorage(result.getAsOpaquePtr(), true); + TypeSystemClang::SetHasExternalStorage(result.getAsOpaquePtr(), true); return result; } @@ -804,7 +805,8 @@ clang::NamespaceDecl * PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name, clang::DeclContext &context) { return m_clang.GetUniqueNamespaceDeclaration( - IsAnonymousNamespaceName(name) ? nullptr : name, &context); + IsAnonymousNamespaceName(name) ? nullptr : name, &context, + OptionalClangModuleID()); } clang::BlockDecl * @@ -814,7 +816,8 @@ PdbAstBuilder::GetOrCreateBlockDecl(PdbCompilandSymId block_id) { clang::DeclContext *scope = GetParentDeclContext(block_id); - clang::BlockDecl *block_decl = m_clang.CreateBlockDeclaration(scope); + clang::BlockDecl *block_decl = + m_clang.CreateBlockDeclaration(scope, OptionalClangModuleID()); m_uid_to_decl.insert({toOpaqueUid(block_id), block_decl}); DeclStatus status; @@ -831,7 +834,7 @@ clang::VarDecl *PdbAstBuilder::CreateVariableDecl(PdbSymUid uid, CVSymbol sym, clang::QualType qt = GetOrCreateType(var_info.type); clang::VarDecl *var_decl = m_clang.CreateVariableDeclaration( - &scope, var_info.name.str().c_str(), qt); + &scope, OptionalClangModuleID(), var_info.name.str().c_str(), qt); m_uid_to_decl[toOpaqueUid(uid)] = var_decl; DeclStatus status; @@ -876,10 +879,10 @@ PdbAstBuilder::GetOrCreateTypedefDecl(PdbGlobalSymId id) { PdbTypeSymId real_type_id{udt.Type, false}; clang::QualType qt = GetOrCreateType(real_type_id); - std::string uname = DropNameScope(udt.Name); + std::string uname = std::string(DropNameScope(udt.Name)); CompilerType ct = m_clang.CreateTypedefType(ToCompilerType(qt), uname.c_str(), - ToCompilerDeclContext(*scope)); + ToCompilerDeclContext(*scope), 0); clang::TypedefNameDecl *tnd = m_clang.GetAsTypedefDecl(ct); DeclStatus status; status.resolved = true; @@ -1012,7 +1015,8 @@ PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) { proc_name.consume_front("::"); clang::FunctionDecl *function_decl = m_clang.CreateFunctionDeclaration( - parent, proc_name.str().c_str(), func_ct, storage, false); + parent, OptionalClangModuleID(), 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; @@ -1080,8 +1084,8 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id, CompilerType param_type_ct = m_clang.GetType(qt); clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration( - &function_decl, param_name.str().c_str(), param_type_ct, - clang::SC_None, true); + &function_decl, OptionalClangModuleID(), param_name.str().c_str(), + param_type_ct, clang::SC_None, true); lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0); m_uid_to_decl[toOpaqueUid(param_uid)] = param; @@ -1102,11 +1106,11 @@ clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id, Declaration declaration; CompilerType enum_ct = m_clang.CreateEnumerationType( - uname.c_str(), decl_context, declaration, ToCompilerType(underlying_type), - er.isScoped()); + uname.c_str(), decl_context, OptionalClangModuleID(), declaration, + ToCompilerType(underlying_type), er.isScoped()); - ClangASTContext::StartTagDeclarationDefinition(enum_ct); - ClangASTContext::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true); + TypeSystemClang::StartTagDeclarationDefinition(enum_ct); + TypeSystemClang::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true); return clang::QualType::getFromOpaquePtr(enum_ct.GetOpaqueQualType()); } @@ -1334,7 +1338,7 @@ void PdbAstBuilder::ParseDeclsForContext(clang::DeclContext &context) { } CompilerDecl PdbAstBuilder::ToCompilerDecl(clang::Decl &decl) { - return {&m_clang, &decl}; + return m_clang.GetCompilerDecl(&decl); } CompilerType PdbAstBuilder::ToCompilerType(clang::QualType qt) { @@ -1347,7 +1351,7 @@ PdbAstBuilder::ToCompilerDeclContext(clang::DeclContext &context) { } clang::Decl * PdbAstBuilder::FromCompilerDecl(CompilerDecl decl) { - return static_cast(decl.GetOpaqueDecl()); + return ClangUtil::GetDecl(decl); } clang::DeclContext * diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h index a4242e90810..7bb2584d19a 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h @@ -6,13 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H -#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringRef.h" -#include "lldb/Symbol/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" #include "PdbIndex.h" #include "PdbSymUid.h" @@ -51,7 +51,7 @@ struct DeclStatus { class PdbAstBuilder { public: // Constructors and Destructors - PdbAstBuilder(ObjectFile &obj, PdbIndex &index, ClangASTContext &clang); + PdbAstBuilder(ObjectFile &obj, PdbIndex &index, TypeSystemClang &clang); lldb_private::CompilerDeclContext GetTranslationUnitDecl(); @@ -80,7 +80,7 @@ public: clang::Decl *FromCompilerDecl(CompilerDecl decl); clang::DeclContext *FromCompilerDeclContext(CompilerDeclContext context); - ClangASTContext &clang() { return m_clang; } + TypeSystemClang &clang() { return m_clang; } ClangASTImporter &importer() { return m_importer; } void Dump(Stream &stream); @@ -129,7 +129,7 @@ private: clang::QualType CreateSimpleType(TypeIndex ti); PdbIndex &m_index; - ClangASTContext &m_clang; + TypeSystemClang &m_clang; ClangASTImporter m_importer; @@ -142,4 +142,4 @@ private: } // namespace npdb } // namespace lldb_private -#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp index a7bc2351971..ecae767e446 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp @@ -1,4 +1,4 @@ -//===-- PdbFPOProgramToDWARFExpression.cpp ----------------------*- C++ -*-===// +//===-- PdbFPOProgramToDWARFExpression.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h index 107e26fb04c..fb979b87714 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Plugins_SymbolFile_PDB_PDBFPOProgramToDWARFExpression_h_ -#define lldb_Plugins_SymbolFile_PDB_PDBFPOProgramToDWARFExpression_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBFPOPROGRAMTODWARFEXPRESSION_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBFPOPROGRAMTODWARFEXPRESSION_H #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp index ba9a95b16e1..6ac6cc2da29 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp @@ -1,4 +1,4 @@ -//===-- PdbIndex.cpp --------------------------------------------*- C++ -*-===// +//===-- PdbIndex.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h index b30e7870bbd..ccc3cc2f453 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBINDEX_H -#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBINDEX_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBINDEX_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBINDEX_H #include "lldb/lldb-types.h" #include "llvm/ADT/IntervalMap.h" diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp index e5ad23f813e..67397d70711 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp @@ -1,4 +1,4 @@ -//===-- PdbSymUid.cpp -------------------------------------------*- C++ -*-===// +//===-- PdbSymUid.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h index 7252d63c1ab..3accd38d710 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h @@ -14,8 +14,8 @@ // access to the compile unit's information. //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBSYMUID_H -#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBSYMUID_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBSYMUID_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBSYMUID_H #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp index fc047e25a2f..b5a16447d9c 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp @@ -1,4 +1,4 @@ -//===-- PdbUtil.cpp ---------------------------------------------*- C++ -*-===// +//===-- PdbUtil.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h index 6f675b56dca..c309c5c8ea1 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H -#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBUTIL_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBUTIL_H #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/Variable.h" diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index 370c339fb74..cce06473d92 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -1,4 +1,4 @@ -//===-- SymbolFileNativePDB.cpp ---------------------------------*- C++ -*-===// +//===-- SymbolFileNativePDB.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -14,13 +14,13 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/Type.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.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/ClangUtil.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/LineTable.h" #include "lldb/Symbol/ObjectFile.h" @@ -129,17 +129,18 @@ loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) { // If it doesn't have a debug directory, fail. llvm::StringRef pdb_file; - auto ec = obj->getDebugPDBInfo(pdb_info, pdb_file); - if (ec) + if (llvm::Error e = obj->getDebugPDBInfo(pdb_info, pdb_file)) { + consumeError(std::move(e)); 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); + auto ec = llvm::identify_magic(pdb_file, magic); if (ec || magic != llvm::file_magic::pdb) return nullptr; - std::unique_ptr pdb = loadPDBFile(pdb_file, allocator); + std::unique_ptr pdb = loadPDBFile(std::string(pdb_file), allocator); if (!pdb) return nullptr; @@ -331,7 +332,7 @@ void SymbolFileNativePDB::InitializeObject() { std::move(err), "Failed to initialize"); } else { ts_or_err->SetSymbolFile(this); - auto *clang = llvm::cast_or_null(&ts_or_err.get()); + auto *clang = llvm::cast_or_null(&ts_or_err.get()); lldbassert(clang); m_ast = std::make_unique(*m_objfile_sp, *m_index, *clang); } @@ -452,7 +453,7 @@ lldb::TypeSP SymbolFileNativePDB::CreateModifierType(PdbTypeSymId type_id, std::string name; if (mr.ModifiedType.isSimple()) - name = GetSimpleTypeName(mr.ModifiedType.getSimpleKind()); + name = std::string(GetSimpleTypeName(mr.ModifiedType.getSimpleKind())); else name = computeTypeName(stream.typeCollection(), mr.ModifiedType); Declaration decl; @@ -532,14 +533,14 @@ static std::string GetUnqualifiedTypeName(const TagRecord &record) { MSVCUndecoratedNameParser parser(record.Name); llvm::ArrayRef specs = parser.GetSpecifiers(); - return specs.back().GetBaseName(); + return std::string(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; + return std::string(record.Name); llvm::ms_demangle::IdentifierNode *idn = ttn->QualifiedName->getUnqualifiedIdentifier(); @@ -1171,7 +1172,7 @@ size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) { void SymbolFileNativePDB::DumpClangAST(Stream &s) { m_ast->Dump(s); } void SymbolFileNativePDB::FindGlobalVariables( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, VariableList &variables) { std::lock_guard guard(GetModuleMutex()); using SymbolAndOffset = std::pair; @@ -1198,7 +1199,7 @@ void SymbolFileNativePDB::FindGlobalVariables( } void SymbolFileNativePDB::FindFunctions( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) { std::lock_guard guard(GetModuleMutex()); @@ -1236,7 +1237,7 @@ void SymbolFileNativePDB::FindFunctions(const RegularExpression ®ex, SymbolContextList &sc_list) {} void SymbolFileNativePDB::FindTypes( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) { std::lock_guard guard(GetModuleMutex()); @@ -1563,7 +1564,7 @@ void SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, CompilerDeclContext SymbolFileNativePDB::FindNamespace(ConstString name, - const CompilerDeclContext *parent_decl_ctx) { + const CompilerDeclContext &parent_decl_ctx) { return {}; } diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h index a37de0f58ef..bf5718e11a1 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H -#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H #include "lldb/Symbol/SymbolFile.h" @@ -100,7 +100,7 @@ public: size_t ParseBlocksRecursive(Function &func) override; void FindGlobalVariables(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, VariableList &variables) override; @@ -129,14 +129,14 @@ public: TypeList &type_list) override; void FindFunctions(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, lldb::FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) override; void FindFunctions(const RegularExpression ®ex, bool include_inlines, SymbolContextList &sc_list) override; - void FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx, + void FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) override; @@ -150,7 +150,7 @@ public: CompilerDeclContext FindNamespace(ConstString name, - const CompilerDeclContext *parent_decl_ctx) override; + const CompilerDeclContext &parent_decl_ctx) override; ConstString GetPluginName() override; @@ -246,4 +246,4 @@ private: } // namespace npdb } // namespace lldb_private -#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp index 7221144407c..c8fb46c7503 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp @@ -5,15 +5,18 @@ #include "PdbSymUid.h" #include "PdbUtil.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.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/SymbolDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h" #include "llvm/DebugInfo/PDB/Native/TpiStream.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" @@ -29,10 +32,10 @@ UdtRecordCompleter::UdtRecordCompleter(PdbTypeSymId id, CompilerType &derived_ct, clang::TagDecl &tag_decl, PdbAstBuilder &ast_builder, - TpiStream &tpi) + PdbIndex &index) : 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); + m_ast_builder(ast_builder), m_index(index) { + CVType cvt = m_index.tpi().getType(m_id.index); switch (cvt.kind()) { case LF_ENUM: llvm::cantFail(TypeDeserializer::deserializeAs(cvt, m_cvr.er)); @@ -55,7 +58,7 @@ clang::QualType UdtRecordCompleter::AddBaseClassForTypeIndex( PdbTypeSymId type_id(ti); clang::QualType qt = m_ast_builder.GetOrCreateType(type_id); - CVType udt_cvt = m_tpi.getType(ti); + CVType udt_cvt = m_index.tpi().getType(ti); std::unique_ptr base_spec = m_ast_builder.clang().CreateBaseClassSpecifier( @@ -128,9 +131,70 @@ Error UdtRecordCompleter::visitKnownMember( lldb::AccessType access = TranslateMemberAccess(static_data_member.getAccess()); - ClangASTContext::AddVariableToRecordType( + auto decl = TypeSystemClang::AddVariableToRecordType( m_derived_ct, static_data_member.Name, member_ct, access); + // Static constant members may be a const[expr] declaration. + // Query the symbol's value as the variable initializer if valid. + if (member_ct.IsConst()) { + std::string qual_name = decl->getQualifiedNameAsString(); + + auto results = + m_index.globals().findRecordsByName(qual_name, m_index.symrecords()); + + for (const auto &result : results) { + if (result.second.kind() == SymbolKind::S_CONSTANT) { + ConstantSym constant(SymbolRecordKind::ConstantSym); + cantFail(SymbolDeserializer::deserializeAs(result.second, + constant)); + + clang::QualType qual_type = decl->getType(); + unsigned type_width = decl->getASTContext().getIntWidth(qual_type); + unsigned constant_width = constant.Value.getBitWidth(); + + if (qual_type->isIntegralOrEnumerationType()) { + if (type_width >= constant_width) { + TypeSystemClang::SetIntegerInitializerForVariable( + decl, constant.Value.extOrTrunc(type_width)); + } else { + LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST), + "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " + "which resolves to a wider constant value ({4} bits). " + "Ignoring constant.", + m_derived_ct.GetTypeName(), static_data_member.Name, + member_ct.GetTypeName(), type_width, constant_width); + } + } else { + lldb::BasicType basic_type_enum = member_ct.GetBasicTypeEnumeration(); + switch (basic_type_enum) { + case lldb::eBasicTypeFloat: + case lldb::eBasicTypeDouble: + case lldb::eBasicTypeLongDouble: + if (type_width == constant_width) { + TypeSystemClang::SetFloatingInitializerForVariable( + decl, basic_type_enum == lldb::eBasicTypeFloat + ? llvm::APFloat(constant.Value.bitsToFloat()) + : llvm::APFloat(constant.Value.bitsToDouble())); + decl->setConstexpr(true); + } else { + LLDB_LOG( + GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST), + "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " + "which resolves to a constant value of mismatched width " + "({4} bits). Ignoring constant.", + m_derived_ct.GetTypeName(), static_data_member.Name, + member_ct.GetTypeName(), type_width, constant_width); + } + break; + default: + break; + } + } + break; + } + } + } + // FIXME: Add a PdbSymUid namespace for field list members and update // the m_uid_to_decl map with this decl. return Error::success(); @@ -149,7 +213,7 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, TypeIndex ti(data_member.Type); if (!ti.isSimple()) { - CVType cvt = m_tpi.getType(ti); + CVType cvt = m_index.tpi().getType(ti); if (cvt.kind() == LF_BITFIELD) { BitFieldRecord bfr; llvm::cantFail(TypeDeserializer::deserializeAs(cvt, bfr)); @@ -164,7 +228,7 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, lldb::AccessType access = TranslateMemberAccess(data_member.getAccess()); - clang::FieldDecl *decl = ClangASTContext::AddFieldToRecordType( + clang::FieldDecl *decl = TypeSystemClang::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 @@ -187,7 +251,7 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, OverloadedMethodRecord &overloaded) { TypeIndex method_list_idx = overloaded.MethodList; - CVType method_list_type = m_tpi.getType(method_list_idx); + CVType method_list_type = m_index.tpi().getType(method_list_idx); assert(method_list_type.kind() == LF_METHODLIST); MethodOverloadListRecord method_list; @@ -223,12 +287,12 @@ void UdtRecordCompleter::complete() { for (auto &ib : m_bases) bases.push_back(std::move(ib.second)); - ClangASTContext &clang = m_ast_builder.clang(); + TypeSystemClang &clang = m_ast_builder.clang(); clang.TransferBaseClasses(m_derived_ct.GetOpaqueQualType(), std::move(bases)); clang.AddMethodOverridesForCXXRecordType(m_derived_ct.GetOpaqueQualType()); - ClangASTContext::BuildIndirectFields(m_derived_ct); - ClangASTContext::CompleteTagDeclarationDefinition(m_derived_ct); + TypeSystemClang::BuildIndirectFields(m_derived_ct); + TypeSystemClang::CompleteTagDeclarationDefinition(m_derived_ct); if (auto *record_decl = llvm::dyn_cast(&m_tag_decl)) { m_ast_builder.importer().SetRecordLayout(record_decl, m_layout); diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h index 55397582209..ae7e47c82fe 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h @@ -6,10 +6,10 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H -#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H -#include "lldb/Symbol/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" #include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" @@ -25,6 +25,7 @@ class TagDecl; namespace llvm { namespace pdb { class TpiStream; +class GlobalsStream; } } // namespace llvm @@ -33,6 +34,7 @@ class Type; class CompilerType; namespace npdb { class PdbAstBuilder; +class PdbIndex; class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks { using IndexedBase = @@ -49,14 +51,14 @@ class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks { CompilerType &m_derived_ct; clang::TagDecl &m_tag_decl; PdbAstBuilder &m_ast_builder; - llvm::pdb::TpiStream &m_tpi; + PdbIndex &m_index; 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); + PdbIndex &index); #define MEMBER_RECORD(EnumName, EnumVal, Name) \ llvm::Error visitKnownMember(llvm::codeview::CVMemberRecord &CVR, \ @@ -79,4 +81,4 @@ private: } // namespace npdb } // namespace lldb_private -#endif // LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/CMakeLists.txt index 79bdce4277c..ceeb173a99e 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/CMakeLists.txt @@ -8,6 +8,7 @@ add_lldb_library(lldbPluginSymbolFilePDB PLUGIN lldbPluginSymbolFileNativePDB lldbSymbol lldbUtility + lldbPluginTypeSystemClang CLANG_LIBS clangAST clangLex diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp index 6b2dbd9e1e5..d87926a6588 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -1,4 +1,4 @@ -//===-- PDBASTParser.cpp ----------------------------------------*- C++ -*-===// +//===-- PDBASTParser.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -14,10 +14,10 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" +#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Module.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangASTMetadata.h" -#include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/Declaration.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/TypeMap.h" @@ -100,7 +100,7 @@ static lldb::Encoding TranslateEnumEncoding(PDB_VariantType type) { } static CompilerType -GetBuiltinTypeForPDBEncodingAndBitSize(ClangASTContext &clang_ast, +GetBuiltinTypeForPDBEncodingAndBitSize(TypeSystemClang &clang_ast, const PDBSymbolTypeBuiltin &pdb_type, Encoding encoding, uint32_t width) { clang::ASTContext &ast = clang_ast.getASTContext(); @@ -353,7 +353,7 @@ static clang::CallingConv TranslateCallingConvention(PDB_CallingConv pdb_cc) { } } -PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast) {} +PDBASTParser::PDBASTParser(lldb_private::TypeSystemClang &ast) : m_ast(ast) {} PDBASTParser::~PDBASTParser() {} @@ -386,7 +386,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { return nullptr; // Ignore unnamed-tag UDTs. - std::string name = MSVCUndecoratedNameParser::DropScope(udt->getName()); + std::string name = + std::string(MSVCUndecoratedNameParser::DropScope(udt->getName())); if (name.empty()) return nullptr; @@ -408,9 +409,9 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { metadata.SetUserID(type.getSymIndexId()); metadata.SetIsDynamicCXXType(false); - clang_type = - m_ast.CreateRecordType(decl_context, access, name, tag_type_kind, - lldb::eLanguageTypeC_plus_plus, &metadata); + clang_type = m_ast.CreateRecordType( + decl_context, OptionalClangModuleID(), access, name, tag_type_kind, + lldb::eLanguageTypeC_plus_plus, &metadata); assert(clang_type.IsValid()); auto record_decl = @@ -422,15 +423,15 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { m_ast.getASTContext(), GetMSInheritance(*udt)); record_decl->addAttr(inheritance_attr); - ClangASTContext::StartTagDeclarationDefinition(clang_type); + TypeSystemClang::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); + TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); - ClangASTContext::SetHasExternalStorage(clang_type.GetOpaqueQualType(), + TypeSystemClang::SetHasExternalStorage(clang_type.GetOpaqueQualType(), false); type_resolve_state = Type::ResolveState::Full; @@ -439,7 +440,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { // an endless recursion in CompleteTypeFromUdt function. m_forward_decl_to_uid[record_decl] = type.getSymIndexId(); - ClangASTContext::SetHasExternalStorage(clang_type.GetOpaqueQualType(), + TypeSystemClang::SetHasExternalStorage(clang_type.GetOpaqueQualType(), true); type_resolve_state = Type::ResolveState::Forward; @@ -465,7 +466,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { assert(enum_type); std::string name = - MSVCUndecoratedNameParser::DropScope(enum_type->getName()); + std::string(MSVCUndecoratedNameParser::DropScope(enum_type->getName())); auto decl_context = GetDeclContextContainingSymbol(type); uint64_t bytes = enum_type->getLength(); @@ -496,10 +497,11 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { // Class). Set it false for now. bool isScoped = false; - ast_enum = m_ast.CreateEnumerationType(name.c_str(), decl_context, decl, + ast_enum = m_ast.CreateEnumerationType(name.c_str(), decl_context, + OptionalClangModuleID(), decl, builtin_type, isScoped); - auto enum_decl = ClangASTContext::GetAsEnumDecl(ast_enum); + auto enum_decl = TypeSystemClang::GetAsEnumDecl(ast_enum); assert(enum_decl); m_uid_to_decl[type.getSymIndexId()] = enum_decl; @@ -512,8 +514,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { } } - if (ClangASTContext::StartTagDeclarationDefinition(ast_enum)) - ClangASTContext::CompleteTagDeclarationDefinition(ast_enum); + if (TypeSystemClang::StartTagDeclarationDefinition(ast_enum)) + TypeSystemClang::CompleteTagDeclarationDefinition(ast_enum); } if (enum_type->isConstType()) @@ -538,7 +540,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { return nullptr; std::string name = - MSVCUndecoratedNameParser::DropScope(type_def->getName()); + std::string(MSVCUndecoratedNameParser::DropScope(type_def->getName())); auto decl_ctx = GetDeclContextContainingSymbol(type); // Check if such a typedef already exists in the current context @@ -549,11 +551,11 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { CompilerType target_ast_type = target_type->GetFullCompilerType(); ast_typedef = m_ast.CreateTypedefType( - target_ast_type, name.c_str(), m_ast.CreateDeclContext(decl_ctx)); + target_ast_type, name.c_str(), m_ast.CreateDeclContext(decl_ctx), 0); if (!ast_typedef) return nullptr; - auto typedef_decl = ClangASTContext::GetAsTypedefDecl(ast_typedef); + auto typedef_decl = TypeSystemClang::GetAsTypedefDecl(ast_typedef); assert(typedef_decl); m_uid_to_decl[type.getSymIndexId()] = typedef_decl; } @@ -587,7 +589,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { return nullptr; func_sig = sig.release(); // Function type is named. - name = MSVCUndecoratedNameParser::DropScope(pdb_func->getName()); + name = std::string( + MSVCUndecoratedNameParser::DropScope(pdb_func->getName())); } else if (auto pdb_func_sig = llvm::dyn_cast(&type)) { func_sig = const_cast(pdb_func_sig); @@ -660,10 +663,10 @@ 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) && + if (TypeSystemClang::IsCXXClassType(element_ast_type) && !element_ast_type.GetCompleteType()) { - if (ClangASTContext::StartTagDeclarationDefinition(element_ast_type)) { - ClangASTContext::CompleteTagDeclarationDefinition(element_ast_type); + if (TypeSystemClang::StartTagDeclarationDefinition(element_ast_type)) { + TypeSystemClang::CompleteTagDeclarationDefinition(element_ast_type); } else { // We are not able to start defintion. return nullptr; @@ -721,7 +724,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { assert(class_parent_type); CompilerType pointer_ast_type; - pointer_ast_type = ClangASTContext::CreateMemberPointerType( + pointer_ast_type = TypeSystemClang::CreateMemberPointerType( class_parent_type->GetLayoutCompilerType(), pointee_type->GetForwardCompilerType()); assert(pointer_ast_type); @@ -787,7 +790,7 @@ bool PDBASTParser::CompleteTypeFromPDB( m_forward_decl_to_uid.erase(uid_it); - ClangASTContext::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), + TypeSystemClang::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), false); switch (symbol->getSymTag()) { @@ -887,7 +890,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) { if (auto parent_decl = llvm::dyn_cast_or_null(decl_context)) m_ast.GetCompleteDecl(parent_decl); - std::string name = MSVCUndecoratedNameParser::DropScope(data->getName()); + std::string name = + std::string(MSVCUndecoratedNameParser::DropScope(data->getName())); // Check if the current context already contains the symbol with the name. clang::Decl *decl = @@ -898,7 +902,7 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) { return nullptr; decl = m_ast.CreateVariableDeclaration( - decl_context, name.c_str(), + decl_context, OptionalClangModuleID(), name.c_str(), ClangUtil::GetQualType(type->GetLayoutCompilerType())); } @@ -913,7 +917,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) { auto decl_context = GetDeclContextContainingSymbol(symbol); assert(decl_context); - std::string name = MSVCUndecoratedNameParser::DropScope(func->getName()); + std::string name = + std::string(MSVCUndecoratedNameParser::DropScope(func->getName())); Type *type = symbol_file->ResolveTypeUID(sym_id); if (!type) @@ -923,8 +928,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) { : clang::StorageClass::SC_None; auto decl = m_ast.CreateFunctionDeclaration( - decl_context, name.c_str(), type->GetForwardCompilerType(), storage, - func->hasInlineAttribute()); + decl_context, OptionalClangModuleID(), name.c_str(), + type->GetForwardCompilerType(), storage, func->hasInlineAttribute()); std::vector params; if (std::unique_ptr sig = func->getSignature()) { @@ -937,8 +942,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) { continue; clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration( - decl, nullptr, arg_type->GetForwardCompilerType(), - clang::SC_None, true); + decl, OptionalClangModuleID(), nullptr, + arg_type->GetForwardCompilerType(), clang::SC_None, true); if (param) params.push_back(param); } @@ -1047,13 +1052,13 @@ clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol( // 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(); + std::string namespace_name = std::string(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_ast.GetUniqueNamespaceDeclaration( + namespace_name_c_str, curr_context, OptionalClangModuleID()); m_parent_to_namespaces[curr_context].insert(namespace_decl); m_namespaces.insert(namespace_decl); @@ -1119,7 +1124,8 @@ bool PDBASTParser::AddEnumValue(CompilerType enum_type, const PDBSymbolData &enum_value) { Declaration decl; Variant v = enum_value.getValue(); - std::string name = MSVCUndecoratedNameParser::DropScope(enum_value.getName()); + std::string name = + std::string(MSVCUndecoratedNameParser::DropScope(enum_value.getName())); int64_t raw_value; switch (v.Type) { case PDB_VariantType::Int8: @@ -1149,8 +1155,7 @@ bool PDBASTParser::AddEnumValue(CompilerType enum_type, default: return false; } - CompilerType underlying_type = - m_ast.GetEnumerationIntegerType(enum_type.GetOpaqueQualType()); + CompilerType underlying_type = m_ast.GetEnumerationIntegerType(enum_type); uint32_t byte_size = m_ast.getASTContext().getTypeSize( ClangUtil::GetQualType(underlying_type)); auto enum_constant_decl = m_ast.AddEnumerationValueToEnumerationType( @@ -1190,8 +1195,8 @@ bool PDBASTParser::CompleteTypeFromUDT( AddRecordMethods(symbol_file, compiler_type, *methods_enum); m_ast.AddMethodOverridesForCXXRecordType(compiler_type.GetOpaqueQualType()); - ClangASTContext::BuildIndirectFields(compiler_type); - ClangASTContext::CompleteTagDeclarationDefinition(compiler_type); + TypeSystemClang::BuildIndirectFields(compiler_type); + TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type); clang::CXXRecordDecl *record_decl = m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType()); @@ -1225,8 +1230,8 @@ void PDBASTParser::AddRecordMembers( "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); + if (TypeSystemClang::StartTagDeclarationDefinition(member_comp_type)) + TypeSystemClang::CompleteTagDeclarationDefinition(member_comp_type); } auto access = TranslateMemberAccess(member->getAccess()); @@ -1239,7 +1244,7 @@ void PDBASTParser::AddRecordMembers( if (location_type == PDB_LocType::ThisRel) bit_size *= 8; - auto decl = ClangASTContext::AddFieldToRecordType( + auto decl = TypeSystemClang::AddFieldToRecordType( record_type, member_name.c_str(), member_comp_type, access, bit_size); if (!decl) continue; @@ -1255,11 +1260,57 @@ void PDBASTParser::AddRecordMembers( break; } case PDB_DataKind::StaticMember: { - auto decl = ClangASTContext::AddVariableToRecordType( + auto decl = TypeSystemClang::AddVariableToRecordType( record_type, member_name.c_str(), member_comp_type, access); if (!decl) continue; + // Static constant members may be a const[expr] declaration. + // Query the symbol's value as the variable initializer if valid. + if (member_comp_type.IsConst()) { + auto value = member->getValue(); + clang::QualType qual_type = decl->getType(); + unsigned type_width = m_ast.getASTContext().getIntWidth(qual_type); + unsigned constant_width = value.getBitWidth(); + + if (qual_type->isIntegralOrEnumerationType()) { + if (type_width >= constant_width) { + TypeSystemClang::SetIntegerInitializerForVariable( + decl, value.toAPSInt().extOrTrunc(type_width)); + } else { + LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST), + "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " + "which resolves to a wider constant value ({4} bits). " + "Ignoring constant.", + record_type.GetTypeName(), member_name, + member_comp_type.GetTypeName(), type_width, + constant_width); + } + } else { + switch (member_comp_type.GetBasicTypeEnumeration()) { + case lldb::eBasicTypeFloat: + case lldb::eBasicTypeDouble: + case lldb::eBasicTypeLongDouble: + if (type_width == constant_width) { + TypeSystemClang::SetFloatingInitializerForVariable( + decl, value.toAPFloat()); + decl->setConstexpr(true); + } else { + LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST), + "Class '{0}' has a member '{1}' of type '{2}' ({3} " + "bits) which resolves to a constant value of mismatched " + "width ({4} bits). Ignoring constant.", + record_type.GetTypeName(), member_name, + member_comp_type.GetTypeName(), type_width, + constant_width); + } + break; + default: + break; + } + } + } + m_uid_to_decl[member->getSymIndexId()] = decl; break; @@ -1289,8 +1340,8 @@ void PDBASTParser::AddRecordBases( "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); + if (TypeSystemClang::StartTagDeclarationDefinition(base_comp_type)) + TypeSystemClang::CompleteTagDeclarationDefinition(base_comp_type); } auto access = TranslateMemberAccess(base->getAccess()); @@ -1333,7 +1384,8 @@ 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()); + std::string name = + std::string(MSVCUndecoratedNameParser::DropScope(method.getName())); Type *method_type = symbol_file.ResolveTypeUID(method.getSymIndexId()); // MSVC specific __vecDelDtor. @@ -1346,8 +1398,8 @@ PDBASTParser::AddRecordMethod(lldb_private::SymbolFile &symbol_file, ":: 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); + if (TypeSystemClang::StartTagDeclarationDefinition(method_comp_type)) + TypeSystemClang::CompleteTagDeclarationDefinition(method_comp_type); } AccessType access = TranslateMemberAccess(method.getAccess()); diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h index 9221d42b202..06f317f4c4d 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h @@ -6,12 +6,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H -#define LLDB_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H #include "lldb/lldb-forward.h" -#include "lldb/Symbol/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" class SymbolFilePDB; @@ -23,7 +23,7 @@ class RecordDecl; } // namespace clang namespace lldb_private { -class ClangASTContext; +class TypeSystemClang; class CompilerType; } // namespace lldb_private @@ -42,7 +42,7 @@ class PDBSymbolTypeUDT; class PDBASTParser { public: - PDBASTParser(lldb_private::ClangASTContext &ast); + PDBASTParser(lldb_private::TypeSystemClang &ast); ~PDBASTParser(); lldb::TypeSP CreateLLDBTypeFromPDBType(const llvm::pdb::PDBSymbol &type); @@ -103,7 +103,7 @@ private: lldb_private::CompilerType &record_type, const llvm::pdb::PDBSymbolFunc &method) const; - lldb_private::ClangASTContext &m_ast; + lldb_private::TypeSystemClang &m_ast; lldb_private::ClangASTImporter m_ast_importer; CXXRecordDeclToUidMap m_forward_decl_to_uid; @@ -113,4 +113,4 @@ private: DeclContextToUidMap m_decl_context_to_uid; }; -#endif // LLDB_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp index 42bf1b34c95..330188e29f0 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp @@ -1,4 +1,4 @@ -//===-- PDBLocationToDWARFExpression.cpp ------------------------*- C++ -*-===// +//===-- PDBLocationToDWARFExpression.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h index 2e9d1386d53..fd0fef03e2c 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Plugins_SymbolFile_PDB_PDBLocationToDWARFExpression_h_ -#define lldb_Plugins_SymbolFile_PDB_PDBLocationToDWARFExpression_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_PDBLOCATIONTODWARFEXPRESSION_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_PDBLOCATIONTODWARFEXPRESSION_H #include "lldb/Core/Module.h" #include "lldb/Symbol/Variable.h" diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 917ab68af41..1001514eded 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -1,4 +1,4 @@ -//===-- SymbolFilePDB.cpp ---------------------------------------*- C++ -*-===// +//===-- SymbolFilePDB.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,9 +13,9 @@ #include "clang/Lex/Lexer.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/LineTable.h" #include "lldb/Symbol/ObjectFile.h" @@ -58,6 +58,8 @@ using namespace lldb; using namespace lldb_private; using namespace llvm::pdb; +LLDB_PLUGIN_DEFINE(SymbolFilePDB) + char SymbolFilePDB::ID; namespace { @@ -310,8 +312,8 @@ SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func, return nullptr; } - ClangASTContext *clang_type_system = - llvm::dyn_cast_or_null(&type_system_or_err.get()); + TypeSystemClang *clang_type_system = + llvm::dyn_cast_or_null(&type_system_or_err.get()); if (!clang_type_system) return nullptr; clang_type_system->GetPDBParser()->GetDeclForSymbol(pdb_func); @@ -560,8 +562,8 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) { return nullptr; } - ClangASTContext *clang_type_system = - llvm::dyn_cast_or_null(&type_system_or_err.get()); + TypeSystemClang *clang_type_system = + llvm::dyn_cast_or_null(&type_system_or_err.get()); if (!clang_type_system) return nullptr; PDBASTParser *pdb = clang_type_system->GetPDBParser(); @@ -597,8 +599,8 @@ bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) { return false; } - ClangASTContext *clang_ast_ctx = - llvm::dyn_cast_or_null(&type_system_or_err.get()); + TypeSystemClang *clang_ast_ctx = + llvm::dyn_cast_or_null(&type_system_or_err.get()); if (!clang_ast_ctx) return false; @@ -619,8 +621,8 @@ lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) { return CompilerDecl(); } - ClangASTContext *clang_ast_ctx = - llvm::dyn_cast_or_null(&type_system_or_err.get()); + TypeSystemClang *clang_ast_ctx = + llvm::dyn_cast_or_null(&type_system_or_err.get()); if (!clang_ast_ctx) return CompilerDecl(); @@ -636,7 +638,7 @@ lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) { if (!decl) return CompilerDecl(); - return CompilerDecl(clang_ast_ctx, decl); + return clang_ast_ctx->GetCompilerDecl(decl); } lldb_private::CompilerDeclContext @@ -649,8 +651,8 @@ SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) { return CompilerDeclContext(); } - ClangASTContext *clang_ast_ctx = - llvm::dyn_cast_or_null(&type_system_or_err.get()); + TypeSystemClang *clang_ast_ctx = + llvm::dyn_cast_or_null(&type_system_or_err.get()); if (!clang_ast_ctx) return CompilerDeclContext(); @@ -679,8 +681,8 @@ SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) { return CompilerDeclContext(); } - ClangASTContext *clang_ast_ctx = - llvm::dyn_cast_or_null(&type_system_or_err.get()); + TypeSystemClang *clang_ast_ctx = + llvm::dyn_cast_or_null(&type_system_or_err.get()); if (!clang_ast_ctx) return CompilerDeclContext(); @@ -708,8 +710,8 @@ void SymbolFilePDB::ParseDeclsForContext( return; } - ClangASTContext *clang_ast_ctx = - llvm::dyn_cast_or_null(&type_system_or_err.get()); + TypeSystemClang *clang_ast_ctx = + llvm::dyn_cast_or_null(&type_system_or_err.get()); if (!clang_ast_ctx) return; @@ -1096,8 +1098,7 @@ SymbolFilePDB::ParseVariables(const lldb_private::SymbolContext &sc, } void SymbolFilePDB::FindGlobalVariables( - lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + lldb_private::ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, lldb_private::VariableList &variables) { std::lock_guard guard(GetModuleMutex()); if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) @@ -1129,8 +1130,8 @@ void SymbolFilePDB::FindGlobalVariables( if (sc.comp_unit == nullptr) continue; - if (parent_decl_ctx && GetDeclContextContainingUID( - result->getSymIndexId()) != *parent_decl_ctx) + if (parent_decl_ctx.IsValid() && + GetDeclContextContainingUID(result->getSymIndexId()) != parent_decl_ctx) continue; ParseVariables(sc, *pdb_data, &variables); @@ -1225,7 +1226,7 @@ void SymbolFilePDB::CacheFunctionNames() { // 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 + // not have information of this, we extract base names and cache them // by our own effort. llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name); if (!basename.empty()) @@ -1294,7 +1295,7 @@ void SymbolFilePDB::CacheFunctionNames() { void SymbolFilePDB::FindFunctions( lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, FunctionNameType name_type_mask, bool include_inlines, lldb_private::SymbolContextList &sc_list) { std::lock_guard guard(GetModuleMutex()); @@ -1323,8 +1324,8 @@ void SymbolFilePDB::FindFunctions( if (resolved_ids.find(id) != resolved_ids.end()) continue; - if (parent_decl_ctx && - GetDeclContextContainingUID(id) != *parent_decl_ctx) + if (parent_decl_ctx.IsValid() && + GetDeclContextContainingUID(id) != parent_decl_ctx) continue; if (ResolveFunction(id, include_inlines, sc_list)) @@ -1422,8 +1423,7 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) { } void SymbolFilePDB::FindTypes( - lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + lldb_private::ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, lldb_private::TypeMap &types) { @@ -1450,7 +1450,7 @@ void SymbolFilePDB::DumpClangAST(Stream &s) { } auto *clang_type_system = - llvm::dyn_cast_or_null(&type_system_or_err.get()); + llvm::dyn_cast_or_null(&type_system_or_err.get()); if (!clang_type_system) return; clang_type_system->Dump(s); @@ -1513,7 +1513,7 @@ void SymbolFilePDB::FindTypesByRegex( void SymbolFilePDB::FindTypesByName( llvm::StringRef name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, lldb_private::TypeMap &types) { std::unique_ptr results; if (name.empty()) @@ -1548,8 +1548,8 @@ void SymbolFilePDB::FindTypesByName( if (!ResolveTypeUID(result->getSymIndexId())) continue; - if (parent_decl_ctx && GetDeclContextContainingUID( - result->getSymIndexId()) != *parent_decl_ctx) + if (parent_decl_ctx.IsValid() && + GetDeclContextContainingUID(result->getSymIndexId()) != parent_decl_ctx) continue; auto iter = m_types.find(result->getSymIndexId()); @@ -1663,17 +1663,16 @@ PDBASTParser *SymbolFilePDB::GetPDBAstParser() { } auto *clang_type_system = - llvm::dyn_cast_or_null(&type_system_or_err.get()); + llvm::dyn_cast_or_null(&type_system_or_err.get()); if (!clang_type_system) return nullptr; return clang_type_system->GetPDBParser(); } - -lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace( - lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx) { +lldb_private::CompilerDeclContext +SymbolFilePDB::FindNamespace(lldb_private::ConstString name, + const CompilerDeclContext &parent_decl_ctx) { std::lock_guard guard(GetModuleMutex()); auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); @@ -1685,7 +1684,7 @@ lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace( } auto *clang_type_system = - llvm::dyn_cast_or_null(&type_system_or_err.get()); + llvm::dyn_cast_or_null(&type_system_or_err.get()); if (!clang_type_system) return CompilerDeclContext(); @@ -1696,7 +1695,7 @@ lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace( clang::DeclContext *decl_context = nullptr; if (parent_decl_ctx) decl_context = static_cast( - parent_decl_ctx->GetOpaqueDeclContext()); + parent_decl_ctx.GetOpaqueDeclContext()); auto namespace_decl = pdb->FindNamespaceDecl(decl_context, name.GetStringRef()); @@ -1817,7 +1816,7 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(CompileUnit &comp_unit, prev_source_idx, false, false, false, false, true); line_table->InsertSequence(sequence.release()); - sequence.reset(line_table->CreateLineSequenceContainer()); + sequence = line_table->CreateLineSequenceContainer(); } if (ShouldAddLine(match_line, lno, length)) { @@ -1854,7 +1853,7 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(CompileUnit &comp_unit, prev_source_idx, false, false, false, false, true); } - line_table->InsertSequence(sequence.release()); + line_table->InsertSequence(sequence.get()); } if (line_table->GetSize()) { @@ -1940,18 +1939,17 @@ SymbolFilePDB::GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func) { mangled.SetMangledName(ConstString(func_decorated_name)); // For MSVC, format of C funciton's decorated name depends on calling - // conventon. Unfortunately none of the format is recognized by current + // convention. Unfortunately none of the format is recognized by current // LLDB. For example, `_purecall` is a __cdecl C function. From PDB, // `__purecall` is retrieved as both its decorated and undecorated name // (using PDBSymbolFunc::getUndecoratedName method). However `__purecall` // string is not treated as mangled in LLDB (neither `?` nor `_Z` prefix). // Mangled::GetDemangledName method will fail internally and caches an - // empty string as its undecorated name. So we will face a contradition + // empty string as its undecorated name. So we will face a contradiction // here for the same symbol: // non-empty undecorated name from PDB // empty undecorated name from LLDB - if (!func_undecorated_name.empty() && - mangled.GetDemangledName(mangled.GuessLanguage()).IsEmpty()) + if (!func_undecorated_name.empty() && mangled.GetDemangledName().IsEmpty()) mangled.SetDemangledName(ConstString(func_undecorated_name)); // LLDB uses several flags to control how a C++ decorated name is @@ -1960,8 +1958,7 @@ SymbolFilePDB::GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func) { // PDB source unless we also apply same flags in getting undecorated // name through PDBSymbolFunc::getUndecoratedNameEx method. if (!func_undecorated_name.empty() && - mangled.GetDemangledName(mangled.GuessLanguage()) != - ConstString(func_undecorated_name)) + mangled.GetDemangledName() != ConstString(func_undecorated_name)) mangled.SetDemangledName(ConstString(func_undecorated_name)); } else if (!func_undecorated_name.empty()) { mangled.SetDemangledName(ConstString(func_undecorated_name)); @@ -1972,11 +1969,11 @@ SymbolFilePDB::GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func) { } bool SymbolFilePDB::DeclContextMatchesThisSymbolFile( - const lldb_private::CompilerDeclContext *decl_ctx) { - if (decl_ctx == nullptr || !decl_ctx->IsValid()) + const lldb_private::CompilerDeclContext &decl_ctx) { + if (!decl_ctx.IsValid()) return true; - TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem(); + TypeSystem *decl_ctx_type_system = decl_ctx.GetTypeSystem(); if (!decl_ctx_type_system) return false; auto type_system_or_err = GetTypeSystemForLanguage( diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h index 7a4eee48771..928cbffc5f6 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ -#define lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_SYMBOLFILEPDB_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_SYMBOLFILEPDB_H #include "lldb/Core/UniqueCStringMap.h" #include "lldb/Symbol/SymbolFile.h" @@ -112,7 +112,7 @@ public: void FindGlobalVariables(lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, lldb_private::VariableList &variables) override; @@ -121,7 +121,7 @@ public: lldb_private::VariableList &variables) override; void FindFunctions(lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, lldb::FunctionNameType name_type_mask, bool include_inlines, lldb_private::SymbolContextList &sc_list) override; @@ -138,7 +138,7 @@ public: void FindTypes(lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, lldb_private::TypeMap &types) override; @@ -160,7 +160,7 @@ public: lldb_private::CompilerDeclContext FindNamespace( lldb_private::ConstString name, - const lldb_private::CompilerDeclContext *parent_decl_ctx) override; + const lldb_private::CompilerDeclContext &parent_decl_ctx) override; lldb_private::ConstString GetPluginName() override; @@ -195,7 +195,7 @@ private: llvm::DenseMap &index_map) const; void FindTypesByName(llvm::StringRef name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, + const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, lldb_private::TypeMap &types); std::string GetMangledForPDBData(const llvm::pdb::PDBSymbolData &pdb_data); @@ -242,7 +242,7 @@ private: void CacheFunctionNames(); bool DeclContextMatchesThisSymbolFile( - const lldb_private::CompilerDeclContext *decl_ctx); + const lldb_private::CompilerDeclContext &decl_ctx); uint32_t GetCompilandId(const llvm::pdb::PDBSymbolData &data); @@ -262,4 +262,4 @@ private: lldb_private::UniqueCStringMap m_func_method_names; }; -#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_SYMBOLFILEPDB_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/gnu/llvm/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp index 305efea1afa..c4a0e609aa2 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp @@ -1,4 +1,4 @@ -//===-- SymbolFileSymtab.cpp ------------------------------------*- C++ -*-===// +//===-- SymbolFileSymtab.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,6 +25,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(SymbolFileSymtab) + char SymbolFileSymtab::ID; void SymbolFileSymtab::Initialize() { diff --git a/gnu/llvm/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/gnu/llvm/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h index 1fff8188433..9557ebbcb27 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SymbolFileSymtab_h_ -#define liblldb_SymbolFileSymtab_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_SYMTAB_SYMBOLFILESYMTAB_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_SYMTAB_SYMBOLFILESYMTAB_H #include #include @@ -106,7 +106,8 @@ protected: TypeMap m_objc_class_types; private: - DISALLOW_COPY_AND_ASSIGN(SymbolFileSymtab); + SymbolFileSymtab(const SymbolFileSymtab &) = delete; + const SymbolFileSymtab &operator=(const SymbolFileSymtab &) = delete; }; -#endif // liblldb_SymbolFileSymtab_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_SYMTAB_SYMBOLFILESYMTAB_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolVendor/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/SymbolVendor/CMakeLists.txt index 94862d58872..695b9a019ae 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolVendor/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/SymbolVendor/CMakeLists.txt @@ -3,3 +3,4 @@ if (CMAKE_SYSTEM_NAME MATCHES "Darwin") endif() add_subdirectory(ELF) +add_subdirectory(wasm) diff --git a/gnu/llvm/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp b/gnu/llvm/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp index d4d7a8937c1..2e6fd436502 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp @@ -1,4 +1,4 @@ -//===-- SymbolVendorELF.cpp ----------------------------------*- C++ -*-===// +//===-- SymbolVendorELF.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,6 +25,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(SymbolVendorELF) + // SymbolVendorELF constructor SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp) : SymbolVendor(module_sp) {} diff --git a/gnu/llvm/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h b/gnu/llvm/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h index 0cd740da5ce..824906c0495 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SymbolVendorELF_h_ -#define liblldb_SymbolVendorELF_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_ELF_SYMBOLVENDORELF_H +#define LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_ELF_SYMBOLVENDORELF_H #include "lldb/Symbol/SymbolVendor.h" #include "lldb/lldb-private.h" @@ -38,7 +38,8 @@ public: uint32_t GetPluginVersion() override; private: - DISALLOW_COPY_AND_ASSIGN(SymbolVendorELF); + SymbolVendorELF(const SymbolVendorELF &) = delete; + const SymbolVendorELF &operator=(const SymbolVendorELF &) = delete; }; -#endif // liblldb_SymbolVendorELF_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_ELF_SYMBOLVENDORELF_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolVendor/MacOSX/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/SymbolVendor/MacOSX/CMakeLists.txt index 8e82eae1513..2cf18513123 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolVendor/MacOSX/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/SymbolVendor/MacOSX/CMakeLists.txt @@ -1,5 +1,3 @@ -include_directories(${LIBXML2_INCLUDE_DIR}) - add_lldb_library(lldbPluginSymbolVendorMacOSX PLUGIN SymbolVendorMacOSX.cpp diff --git a/gnu/llvm/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp b/gnu/llvm/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp index bb37d777906..fc426d1c9c3 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp +++ b/gnu/llvm/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp @@ -1,4 +1,4 @@ -//===-- SymbolVendorMacOSX.cpp ----------------------------------*- C++ -*-===// +//===-- SymbolVendorMacOSX.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -20,12 +20,15 @@ #include "lldb/Symbol/LocateSymbolFile.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/Reproducer.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(SymbolVendorMacOSX) + // SymbolVendorMacOSX constructor SymbolVendorMacOSX::SymbolVendorMacOSX(const lldb::ModuleSP &module_sp) : SymbolVendor(module_sp) {} @@ -143,6 +146,11 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp, } if (dsym_fspec) { + // Compute dSYM root. + std::string dsym_root = dsym_fspec.GetPath(); + const size_t pos = dsym_root.find("/Contents/Resources/"); + dsym_root = pos != std::string::npos ? dsym_root.substr(0, pos) : ""; + DataBufferSP dsym_file_data_sp; lldb::offset_t dsym_file_data_offset = 0; dsym_objfile_sp = @@ -152,136 +160,132 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp, if (UUIDsMatch(module_sp.get(), dsym_objfile_sp.get(), feedback_strm)) { // We need a XML parser if we hope to parse a plist... if (XMLDocument::XMLEnabled()) { - char dsym_path[PATH_MAX]; - if (module_sp->GetSourceMappingList().IsEmpty() && - dsym_fspec.GetPath(dsym_path, sizeof(dsym_path))) { + if (module_sp->GetSourceMappingList().IsEmpty()) { lldb_private::UUID dsym_uuid = dsym_objfile_sp->GetUUID(); if (dsym_uuid) { std::string uuid_str = dsym_uuid.GetAsString(); - if (!uuid_str.empty()) { - char *resources = strstr(dsym_path, "/Contents/Resources/"); - if (resources) { - char dsym_uuid_plist_path[PATH_MAX]; - resources[strlen("/Contents/Resources/")] = '\0'; - snprintf(dsym_uuid_plist_path, sizeof(dsym_uuid_plist_path), - "%s%s.plist", dsym_path, uuid_str.c_str()); - FileSpec dsym_uuid_plist_spec(dsym_uuid_plist_path); - if (FileSystem::Instance().Exists(dsym_uuid_plist_spec)) { - ApplePropertyList plist(dsym_uuid_plist_path); - if (plist) { - std::string DBGBuildSourcePath; - std::string DBGSourcePath; - - // DBGSourcePathRemapping is a dictionary in the plist - // with keys which are DBGBuildSourcePath file paths and - // values which are DBGSourcePath file paths - - StructuredData::ObjectSP plist_sp = - plist.GetStructuredData(); - if (plist_sp.get() && plist_sp->GetAsDictionary() && - plist_sp->GetAsDictionary()->HasKey( - "DBGSourcePathRemapping") && - plist_sp->GetAsDictionary() - ->GetValueForKey("DBGSourcePathRemapping") - ->GetAsDictionary()) { - - // If DBGVersion 1 or DBGVersion missing, ignore DBGSourcePathRemapping. - // If DBGVersion 2, strip last two components of path remappings from - // entries to fix an issue with a specific set of - // DBGSourcePathRemapping entries that lldb worked - // with. - // If DBGVersion 3, trust & use the source path remappings as-is. - // - - bool new_style_source_remapping_dictionary = false; - bool do_truncate_remapping_names = false; - std::string original_DBGSourcePath_value = - DBGSourcePath; - if (plist_sp->GetAsDictionary()->HasKey("DBGVersion")) { - std::string version_string = - plist_sp->GetAsDictionary() - ->GetValueForKey("DBGVersion") - ->GetStringValue(""); - if (!version_string.empty() && - isdigit(version_string[0])) { - int version_number = atoi(version_string.c_str()); - if (version_number > 1) { - new_style_source_remapping_dictionary = true; - } - if (version_number == 2) { - do_truncate_remapping_names = true; - } + if (!uuid_str.empty() && !dsym_root.empty()) { + char dsym_uuid_plist_path[PATH_MAX]; + snprintf(dsym_uuid_plist_path, sizeof(dsym_uuid_plist_path), + "%s/Contents/Resources/%s.plist", dsym_root.c_str(), + uuid_str.c_str()); + FileSpec dsym_uuid_plist_spec(dsym_uuid_plist_path); + if (FileSystem::Instance().Exists(dsym_uuid_plist_spec)) { + ApplePropertyList plist(dsym_uuid_plist_path); + if (plist) { + std::string DBGBuildSourcePath; + std::string DBGSourcePath; + + // DBGSourcePathRemapping is a dictionary in the plist + // with keys which are DBGBuildSourcePath file paths and + // values which are DBGSourcePath file paths + + StructuredData::ObjectSP plist_sp = + plist.GetStructuredData(); + if (plist_sp.get() && plist_sp->GetAsDictionary() && + plist_sp->GetAsDictionary()->HasKey( + "DBGSourcePathRemapping") && + plist_sp->GetAsDictionary() + ->GetValueForKey("DBGSourcePathRemapping") + ->GetAsDictionary()) { + + // If DBGVersion 1 or DBGVersion missing, ignore + // DBGSourcePathRemapping. If DBGVersion 2, strip last two + // components of path remappings from + // entries to fix an issue with a + // specific set of DBGSourcePathRemapping + // entries that lldb worked with. + // If DBGVersion 3, trust & use the source path remappings + // as-is. + // + + bool new_style_source_remapping_dictionary = false; + bool do_truncate_remapping_names = false; + std::string original_DBGSourcePath_value = DBGSourcePath; + if (plist_sp->GetAsDictionary()->HasKey("DBGVersion")) { + std::string version_string = + std::string(plist_sp->GetAsDictionary() + ->GetValueForKey("DBGVersion") + ->GetStringValue("")); + if (!version_string.empty() && + isdigit(version_string[0])) { + int version_number = atoi(version_string.c_str()); + if (version_number > 1) { + new_style_source_remapping_dictionary = true; + } + if (version_number == 2) { + do_truncate_remapping_names = true; } } + } - StructuredData::Dictionary *remappings_dict = - plist_sp->GetAsDictionary() - ->GetValueForKey("DBGSourcePathRemapping") - ->GetAsDictionary(); - remappings_dict->ForEach( - [&module_sp, new_style_source_remapping_dictionary, - original_DBGSourcePath_value, do_truncate_remapping_names]( - ConstString key, - StructuredData::Object *object) -> bool { - if (object && object->GetAsString()) { - - // key is DBGBuildSourcePath - // object is DBGSourcePath - std::string DBGSourcePath = - object->GetStringValue(); - if (!new_style_source_remapping_dictionary && - !original_DBGSourcePath_value.empty()) { - DBGSourcePath = original_DBGSourcePath_value; - } - if (DBGSourcePath[0] == '~') { - FileSpec resolved_source_path( - DBGSourcePath.c_str()); - FileSystem::Instance().Resolve( - resolved_source_path); - DBGSourcePath = - resolved_source_path.GetPath(); - } + StructuredData::Dictionary *remappings_dict = + plist_sp->GetAsDictionary() + ->GetValueForKey("DBGSourcePathRemapping") + ->GetAsDictionary(); + remappings_dict->ForEach( + [&module_sp, new_style_source_remapping_dictionary, + original_DBGSourcePath_value, + do_truncate_remapping_names]( + ConstString key, + StructuredData::Object *object) -> bool { + if (object && object->GetAsString()) { + + // key is DBGBuildSourcePath + // object is DBGSourcePath + std::string DBGSourcePath = + std::string(object->GetStringValue()); + if (!new_style_source_remapping_dictionary && + !original_DBGSourcePath_value.empty()) { + DBGSourcePath = original_DBGSourcePath_value; + } + if (DBGSourcePath[0] == '~') { + FileSpec resolved_source_path( + DBGSourcePath.c_str()); + FileSystem::Instance().Resolve( + resolved_source_path); + DBGSourcePath = resolved_source_path.GetPath(); + } + module_sp->GetSourceMappingList().Append( + key, ConstString(DBGSourcePath), true); + // With version 2 of DBGSourcePathRemapping, we + // can chop off the last two filename parts + // from the source remapping and get a more + // general source remapping that still works. + // Add this as another option in addition to + // the full source path remap. + if (do_truncate_remapping_names) { + FileSpec build_path(key.AsCString()); + FileSpec source_path(DBGSourcePath.c_str()); + build_path.RemoveLastPathComponent(); + build_path.RemoveLastPathComponent(); + source_path.RemoveLastPathComponent(); + source_path.RemoveLastPathComponent(); module_sp->GetSourceMappingList().Append( - key, ConstString(DBGSourcePath), true); - // With version 2 of DBGSourcePathRemapping, we - // can chop off the last two filename parts - // from the source remapping and get a more - // general source remapping that still works. - // Add this as another option in addition to - // the full source path remap. - if (do_truncate_remapping_names) { - FileSpec build_path(key.AsCString()); - FileSpec source_path(DBGSourcePath.c_str()); - build_path.RemoveLastPathComponent(); - build_path.RemoveLastPathComponent(); - source_path.RemoveLastPathComponent(); - source_path.RemoveLastPathComponent(); - module_sp->GetSourceMappingList().Append( - ConstString(build_path.GetPath().c_str()), - ConstString(source_path.GetPath().c_str()), true); - } + ConstString(build_path.GetPath().c_str()), + ConstString(source_path.GetPath().c_str()), + true); } - return true; - }); - } + } + return true; + }); + } - // If we have a DBGBuildSourcePath + DBGSourcePath pair, - // append those to the source path remappings. - - plist.GetValueAsString("DBGBuildSourcePath", - DBGBuildSourcePath); - plist.GetValueAsString("DBGSourcePath", DBGSourcePath); - if (!DBGBuildSourcePath.empty() && - !DBGSourcePath.empty()) { - if (DBGSourcePath[0] == '~') { - FileSpec resolved_source_path(DBGSourcePath.c_str()); - FileSystem::Instance().Resolve(resolved_source_path); - DBGSourcePath = resolved_source_path.GetPath(); - } - module_sp->GetSourceMappingList().Append( - ConstString(DBGBuildSourcePath), - ConstString(DBGSourcePath), true); + // If we have a DBGBuildSourcePath + DBGSourcePath pair, + // append those to the source path remappings. + + plist.GetValueAsString("DBGBuildSourcePath", + DBGBuildSourcePath); + plist.GetValueAsString("DBGSourcePath", DBGSourcePath); + if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) { + if (DBGSourcePath[0] == '~') { + FileSpec resolved_source_path(DBGSourcePath.c_str()); + FileSystem::Instance().Resolve(resolved_source_path); + DBGSourcePath = resolved_source_path.GetPath(); } + module_sp->GetSourceMappingList().Append( + ConstString(DBGBuildSourcePath), + ConstString(DBGSourcePath), true); } } } @@ -291,6 +295,13 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp, } symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp); + if (!dsym_root.empty()) { + if (repro::Generator *g = + repro::Reproducer::Instance().GetGenerator()) { + repro::FileProvider &fp = g->GetOrCreate(); + fp.recordInterestingDirectory(dsym_root); + } + } return symbol_vendor; } } diff --git a/gnu/llvm/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h b/gnu/llvm/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h index 01e33ffcce6..7d2de4ac29a 100644 --- a/gnu/llvm/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h +++ b/gnu/llvm/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SymbolVendorMacOSX_h_ -#define liblldb_SymbolVendorMacOSX_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_MACOSX_SYMBOLVENDORMACOSX_H +#define LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_MACOSX_SYMBOLVENDORMACOSX_H #include "lldb/Symbol/SymbolVendor.h" #include "lldb/lldb-private.h" @@ -38,7 +38,8 @@ public: virtual uint32_t GetPluginVersion(); private: - DISALLOW_COPY_AND_ASSIGN(SymbolVendorMacOSX); + SymbolVendorMacOSX(const SymbolVendorMacOSX &) = delete; + const SymbolVendorMacOSX &operator=(const SymbolVendorMacOSX &) = delete; }; -#endif // liblldb_SymbolVendorMacOSX_h_ +#endif // LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_MACOSX_SYMBOLVENDORMACOSX_H diff --git a/gnu/llvm/lldb/source/Plugins/SymbolVendor/wasm/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/SymbolVendor/wasm/CMakeLists.txt new file mode 100644 index 00000000000..49f6012c7bc --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/SymbolVendor/wasm/CMakeLists.txt @@ -0,0 +1,9 @@ +add_lldb_library(lldbPluginSymbolVendorWasm PLUGIN + SymbolVendorWasm.cpp + + LINK_LIBS + lldbCore + lldbHost + lldbSymbol + lldbPluginObjectFileWasm + ) diff --git a/gnu/llvm/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp b/gnu/llvm/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp new file mode 100644 index 00000000000..1c09dabc562 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp @@ -0,0 +1,147 @@ +//===-- SymbolVendorWasm.cpp ----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "SymbolVendorWasm.h" + +#include + +#include "Plugins/ObjectFile/wasm/ObjectFileWasm.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Section.h" +#include "lldb/Host/Host.h" +#include "lldb/Symbol/LocateSymbolFile.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/Timer.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::wasm; + +LLDB_PLUGIN_DEFINE(SymbolVendorWasm) + +// SymbolVendorWasm constructor +SymbolVendorWasm::SymbolVendorWasm(const lldb::ModuleSP &module_sp) + : SymbolVendor(module_sp) {} + +void SymbolVendorWasm::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance); +} + +void SymbolVendorWasm::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString SymbolVendorWasm::GetPluginNameStatic() { + static ConstString g_name("WASM"); + return g_name; +} + +const char *SymbolVendorWasm::GetPluginDescriptionStatic() { + return "Symbol vendor for WASM that looks for dwo files that match " + "executables."; +} + +// CreateInstance +// +// Platforms can register a callback to use when creating symbol vendors to +// allow for complex debug information file setups, and to also allow for +// finding separate debug information files. +SymbolVendor * +SymbolVendorWasm::CreateInstance(const lldb::ModuleSP &module_sp, + lldb_private::Stream *feedback_strm) { + if (!module_sp) + return nullptr; + + ObjectFileWasm *obj_file = + llvm::dyn_cast_or_null(module_sp->GetObjectFile()); + if (!obj_file) + return nullptr; + + // If the main object file already contains debug info, then we are done. + if (obj_file->GetSectionList()->FindSectionByType( + lldb::eSectionTypeDWARFDebugInfo, true)) + return nullptr; + + static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); + Timer scoped_timer(func_cat, "SymbolVendorWasm::CreateInstance (module = %s)", + module_sp->GetFileSpec().GetPath().c_str()); + + ModuleSpec module_spec; + module_spec.GetFileSpec() = obj_file->GetFileSpec(); + FileSystem::Instance().Resolve(module_spec.GetFileSpec()); + module_spec.GetUUID() = obj_file->GetUUID(); + + // A Wasm module may have a custom section named "external_debug_info" whose + // content is the absolute or relative path of the Wasm module that contains + // debug symbols for this module. + llvm::Optional symbol_file_spec = + obj_file->GetExternalDebugInfoFileSpec(); + if (!symbol_file_spec) + return nullptr; + module_spec.GetSymbolFileSpec() = *symbol_file_spec; + + FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); + FileSpec sym_fspec = + Symbols::LocateExecutableSymbolFile(module_spec, search_paths); + if (!sym_fspec) + return nullptr; + + DataBufferSP sym_file_data_sp; + lldb::offset_t sym_file_data_offset = 0; + ObjectFileSP sym_objfile_sp = ObjectFile::FindPlugin( + module_sp, &sym_fspec, 0, FileSystem::Instance().GetByteSize(sym_fspec), + sym_file_data_sp, sym_file_data_offset); + if (!sym_objfile_sp) + return nullptr; + + // This objfile is for debugging purposes. + sym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo); + + SymbolVendorWasm *symbol_vendor = new SymbolVendorWasm(module_sp); + + // Get the module unified section list and add our debug sections to + // that. + SectionList *module_section_list = module_sp->GetSectionList(); + SectionList *objfile_section_list = sym_objfile_sp->GetSectionList(); + + static const SectionType g_sections[] = { + eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr, + eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugCuIndex, + eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo, + eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLineStr, + eSectionTypeDWARFDebugLoc, eSectionTypeDWARFDebugLocLists, + eSectionTypeDWARFDebugMacInfo, eSectionTypeDWARFDebugMacro, + eSectionTypeDWARFDebugPubNames, eSectionTypeDWARFDebugPubTypes, + eSectionTypeDWARFDebugRanges, eSectionTypeDWARFDebugRngLists, + eSectionTypeDWARFDebugStr, eSectionTypeDWARFDebugStrOffsets, + eSectionTypeDWARFDebugTypes}; + for (SectionType section_type : g_sections) { + if (SectionSP section_sp = + objfile_section_list->FindSectionByType(section_type, true)) { + if (SectionSP module_section_sp = + module_section_list->FindSectionByType(section_type, true)) + module_section_list->ReplaceSection(module_section_sp->GetID(), + section_sp); + else + module_section_list->AddSection(section_sp); + } + } + + symbol_vendor->AddSymbolFileRepresentation(sym_objfile_sp); + return symbol_vendor; +} + +// PluginInterface protocol +ConstString SymbolVendorWasm::GetPluginName() { return GetPluginNameStatic(); } + +uint32_t SymbolVendorWasm::GetPluginVersion() { return 1; } diff --git a/gnu/llvm/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h b/gnu/llvm/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h new file mode 100644 index 00000000000..96e737b1be9 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h @@ -0,0 +1,45 @@ +//===-- SymbolVendorWasm.h --------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_WASM_SYMBOLVENDORWASM_H +#define LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_WASM_SYMBOLVENDORWASM_H + +#include "lldb/Symbol/SymbolVendor.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { +namespace wasm { + +class SymbolVendorWasm : public lldb_private::SymbolVendor { +public: + SymbolVendorWasm(const lldb::ModuleSP &module_sp); + + static void Initialize(); + static void Terminate(); + static lldb_private::ConstString GetPluginNameStatic(); + static const char *GetPluginDescriptionStatic(); + + static lldb_private::SymbolVendor * + CreateInstance(const lldb::ModuleSP &module_sp, + lldb_private::Stream *feedback_strm); + + /// PluginInterface protocol. + /// \{ + lldb_private::ConstString GetPluginName() override; + uint32_t GetPluginVersion() override; + /// \} + +private: + SymbolVendorWasm(const SymbolVendorWasm &) = delete; + const SymbolVendorWasm &operator=(const SymbolVendorWasm &) = delete; +}; + +} // namespace wasm +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_WASM_SYMBOLVENDORWASM_H diff --git a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp index 571e1d8486b..7dfa759a7fb 100644 --- a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp +++ b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp @@ -1,5 +1,4 @@ -//===-- AppleGetItemInfoHandler.cpp -------------------------------*- C++ -//-*-===// +//===-- AppleGetItemInfoHandler.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,13 +8,12 @@ #include "AppleGetItemInfoHandler.h" - +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Module.h" #include "lldb/Core/Value.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/FunctionCaller.h" #include "lldb/Expression/UtilityFunction.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" @@ -108,7 +106,7 @@ void AppleGetItemInfoHandler::Detach() { m_get_item_info_return_buffer_addr != LLDB_INVALID_ADDRESS) { std::unique_lock lock(m_get_item_info_retbuffer_mutex, std::defer_lock); - lock.try_lock(); // Even if we don't get the lock, deallocate the buffer + (void)lock.try_lock(); // Even if we don't get the lock, deallocate the buffer m_process->DeallocateMemory(m_get_item_info_return_buffer_addr); } } @@ -229,7 +227,7 @@ AppleGetItemInfoHandler::GetItemInfo(Thread &thread, uint64_t item, lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0); ProcessSP process_sp(thread.CalculateProcess()); TargetSP target_sp(thread.CalculateTarget()); - ClangASTContext *clang_ast_context = ClangASTContext::GetScratch(*target_sp); + TypeSystemClang *clang_ast_context = TypeSystemClang::GetScratch(*target_sp); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME)); GetItemInfoReturnInfo return_value; diff --git a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h index 318d674d286..f1119a9562e 100644 --- a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h +++ b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_AppleGetItemInfoHandler_h_ -#define lldb_AppleGetItemInfoHandler_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYSTEMRUNTIME_MACOSX_APPLEGETITEMINFOHANDLER_H +#define LLDB_SOURCE_PLUGINS_SYSTEMRUNTIME_MACOSX_APPLEGETITEMINFOHANDLER_H #include #include @@ -109,4 +109,4 @@ private: } // using namespace lldb_private -#endif // lldb_AppleGetItemInfoHandler_h_ +#endif // LLDB_SOURCE_PLUGINS_SYSTEMRUNTIME_MACOSX_APPLEGETITEMINFOHANDLER_H diff --git a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp index be1b100cad3..ff57aa2afc9 100644 --- a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp +++ b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp @@ -1,5 +1,4 @@ -//===-- AppleGetPendingItemsHandler.cpp -------------------------------*- C++ -//-*-===// +//===-- AppleGetPendingItemsHandler.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,13 +8,12 @@ #include "AppleGetPendingItemsHandler.h" - +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Module.h" #include "lldb/Core/Value.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/FunctionCaller.h" #include "lldb/Expression/UtilityFunction.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" @@ -111,7 +109,7 @@ void AppleGetPendingItemsHandler::Detach() { m_get_pending_items_return_buffer_addr != LLDB_INVALID_ADDRESS) { std::unique_lock lock(m_get_pending_items_retbuffer_mutex, std::defer_lock); - lock.try_lock(); // Even if we don't get the lock, deallocate the buffer + (void)lock.try_lock(); // Even if we don't get the lock, deallocate the buffer m_process->DeallocateMemory(m_get_pending_items_return_buffer_addr); } } @@ -176,8 +174,8 @@ lldb::addr_t AppleGetPendingItemsHandler::SetupGetPendingItemsFunction( // Next make the runner function for our implementation utility function. Status error; - ClangASTContext *clang_ast_context = - ClangASTContext::GetScratch(thread.GetProcess()->GetTarget()); + TypeSystemClang *clang_ast_context = + TypeSystemClang::GetScratch(thread.GetProcess()->GetTarget()); CompilerType get_pending_items_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); get_pending_items_caller = @@ -228,7 +226,7 @@ AppleGetPendingItemsHandler::GetPendingItems(Thread &thread, addr_t queue, lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0); ProcessSP process_sp(thread.CalculateProcess()); TargetSP target_sp(thread.CalculateTarget()); - ClangASTContext *clang_ast_context = ClangASTContext::GetScratch(*target_sp); + TypeSystemClang *clang_ast_context = TypeSystemClang::GetScratch(*target_sp); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME)); GetPendingItemsReturnInfo return_value; diff --git a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h index 0780e3ca555..20895ca146c 100644 --- a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h +++ b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_AppleGetPendingItemsHandler_h_ -#define lldb_AppleGetPendingItemsHandler_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYSTEMRUNTIME_MACOSX_APPLEGETPENDINGITEMSHANDLER_H +#define LLDB_SOURCE_PLUGINS_SYSTEMRUNTIME_MACOSX_APPLEGETPENDINGITEMSHANDLER_H #include #include @@ -114,4 +114,4 @@ private: } // using namespace lldb_private -#endif // lldb_AppleGetPendingItemsHandler_h_ +#endif // LLDB_SOURCE_PLUGINS_SYSTEMRUNTIME_MACOSX_APPLEGETPENDINGITEMSHANDLER_H diff --git a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp index 338d63d631f..632f18d6ea8 100644 --- a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp +++ b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp @@ -1,4 +1,4 @@ -//===-- AppleGetQueuesHandler.cpp -------------------------------*- C++ -*-===// +//===-- AppleGetQueuesHandler.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,12 +8,12 @@ #include "AppleGetQueuesHandler.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Module.h" #include "lldb/Core/Value.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/FunctionCaller.h" #include "lldb/Expression/UtilityFunction.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" @@ -107,7 +107,7 @@ void AppleGetQueuesHandler::Detach() { m_get_queues_return_buffer_addr != LLDB_INVALID_ADDRESS) { std::unique_lock lock(m_get_queues_retbuffer_mutex, std::defer_lock); - lock.try_lock(); // Even if we don't get the lock, deallocate the buffer + (void)lock.try_lock(); // Even if we don't get the lock, deallocate the buffer m_process->DeallocateMemory(m_get_queues_return_buffer_addr); } } @@ -190,8 +190,8 @@ AppleGetQueuesHandler::SetupGetQueuesFunction(Thread &thread, } // Next make the runner function for our implementation utility function. - ClangASTContext *clang_ast_context = - ClangASTContext::GetScratch(thread.GetProcess()->GetTarget()); + TypeSystemClang *clang_ast_context = + TypeSystemClang::GetScratch(thread.GetProcess()->GetTarget()); CompilerType get_queues_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); Status error; @@ -231,7 +231,7 @@ AppleGetQueuesHandler::GetCurrentQueues(Thread &thread, addr_t page_to_free, lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0); ProcessSP process_sp(thread.CalculateProcess()); TargetSP target_sp(thread.CalculateTarget()); - ClangASTContext *clang_ast_context = ClangASTContext::GetScratch(*target_sp); + TypeSystemClang *clang_ast_context = TypeSystemClang::GetScratch(*target_sp); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME)); GetQueuesReturnInfo return_value; diff --git a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h index bd314f940a3..0c828d782a1 100644 --- a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h +++ b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_AppleGetQueuesHandler_h_ -#define lldb_AppleGetQueuesHandler_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYSTEMRUNTIME_MACOSX_APPLEGETQUEUESHANDLER_H +#define LLDB_SOURCE_PLUGINS_SYSTEMRUNTIME_MACOSX_APPLEGETQUEUESHANDLER_H #include #include @@ -106,4 +106,4 @@ private: } // using namespace lldb_private -#endif // lldb_AppleGetQueuesHandler_h_ +#endif // LLDB_SOURCE_PLUGINS_SYSTEMRUNTIME_MACOSX_APPLEGETQUEUESHANDLER_H diff --git a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp index 22beda87b47..6bfdbaca27d 100644 --- a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp +++ b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp @@ -1,5 +1,4 @@ -//===-- AppleGetThreadItemInfoHandler.cpp -------------------------------*- C++ -//-*-===// +//===-- AppleGetThreadItemInfoHandler.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,14 +8,13 @@ #include "AppleGetThreadItemInfoHandler.h" - +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Module.h" #include "lldb/Core/Value.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/Expression.h" #include "lldb/Expression/FunctionCaller.h" #include "lldb/Expression/UtilityFunction.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" @@ -117,7 +115,7 @@ void AppleGetThreadItemInfoHandler::Detach() { m_get_thread_item_info_return_buffer_addr != LLDB_INVALID_ADDRESS) { std::unique_lock lock(m_get_thread_item_info_retbuffer_mutex, std::defer_lock); - lock.try_lock(); // Even if we don't get the lock, deallocate the buffer + (void)lock.try_lock(); // Even if we don't get the lock, deallocate the buffer m_process->DeallocateMemory(m_get_thread_item_info_return_buffer_addr); } } @@ -185,8 +183,8 @@ lldb::addr_t AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction( // Also make the FunctionCaller for this UtilityFunction: - ClangASTContext *clang_ast_context = - ClangASTContext::GetScratch(thread.GetProcess()->GetTarget()); + TypeSystemClang *clang_ast_context = + TypeSystemClang::GetScratch(thread.GetProcess()->GetTarget()); CompilerType get_thread_item_info_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); @@ -237,7 +235,7 @@ AppleGetThreadItemInfoHandler::GetThreadItemInfo(Thread &thread, lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0); ProcessSP process_sp(thread.CalculateProcess()); TargetSP target_sp(thread.CalculateTarget()); - ClangASTContext *clang_ast_context = ClangASTContext::GetScratch(*target_sp); + TypeSystemClang *clang_ast_context = TypeSystemClang::GetScratch(*target_sp); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME)); GetThreadItemInfoReturnInfo return_value; diff --git a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h index b45314df85b..0f7201a0e81 100644 --- a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h +++ b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_AppleGetThreadItemInfoHandler_h_ -#define lldb_AppleGetThreadItemInfoHandler_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYSTEMRUNTIME_MACOSX_APPLEGETTHREADITEMINFOHANDLER_H +#define LLDB_SOURCE_PLUGINS_SYSTEMRUNTIME_MACOSX_APPLEGETTHREADITEMINFOHANDLER_H #include #include @@ -108,4 +108,4 @@ private: } // using namespace lldb_private -#endif // lldb_AppleGetThreadItemInfoHandler_h_ +#endif // LLDB_SOURCE_PLUGINS_SYSTEMRUNTIME_MACOSX_APPLEGETTHREADITEMINFOHANDLER_H diff --git a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/CMakeLists.txt index ac5781b98b0..04d30652ba4 100644 --- a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/CMakeLists.txt @@ -14,4 +14,5 @@ add_lldb_library(lldbPluginSystemRuntimeMacOSX PLUGIN lldbTarget lldbUtility lldbPluginProcessUtility + lldbPluginTypeSystemClang ) diff --git a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp index 69a4470c258..33b1ed115e9 100644 --- a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp +++ b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp @@ -1,4 +1,4 @@ -//===-- SystemRuntimeMacOSX.cpp ---------------------------------*- C++ -*-===// +//===-- SystemRuntimeMacOSX.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,12 +7,12 @@ //===----------------------------------------------------------------------===// #include "Plugins/Process/Utility/HistoryThread.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/Process.h" @@ -34,6 +34,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(SystemRuntimeMacOSX) + // Create an instance of this class. This function is filled into the plugin // info class that gets handed out by the plugin factory and allows the lldb to // instantiate an instance of this class. @@ -411,29 +413,30 @@ void SystemRuntimeMacOSX::ReadLibdispatchTSDIndexes() { } #endif - ClangASTContext *ast_ctx = - ClangASTContext::GetScratch(m_process->GetTarget()); + TypeSystemClang *ast_ctx = + TypeSystemClang::GetScratch(m_process->GetTarget()); if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS) { CompilerType uint16 = ast_ctx->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 16); CompilerType dispatch_tsd_indexes_s = ast_ctx->CreateRecordType( - nullptr, lldb::eAccessPublic, "__lldb_dispatch_tsd_indexes_s", - clang::TTK_Struct, lldb::eLanguageTypeC); + nullptr, OptionalClangModuleID(), lldb::eAccessPublic, + "__lldb_dispatch_tsd_indexes_s", clang::TTK_Struct, + lldb::eLanguageTypeC); - ClangASTContext::StartTagDeclarationDefinition(dispatch_tsd_indexes_s); - ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s, + TypeSystemClang::StartTagDeclarationDefinition(dispatch_tsd_indexes_s); + TypeSystemClang::AddFieldToRecordType(dispatch_tsd_indexes_s, "dti_version", uint16, lldb::eAccessPublic, 0); - ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s, + TypeSystemClang::AddFieldToRecordType(dispatch_tsd_indexes_s, "dti_queue_index", uint16, lldb::eAccessPublic, 0); - ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s, + TypeSystemClang::AddFieldToRecordType(dispatch_tsd_indexes_s, "dti_voucher_index", uint16, lldb::eAccessPublic, 0); - ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s, + TypeSystemClang::AddFieldToRecordType(dispatch_tsd_indexes_s, "dti_qos_class_index", uint16, lldb::eAccessPublic, 0); - ClangASTContext::CompleteTagDeclarationDefinition(dispatch_tsd_indexes_s); + TypeSystemClang::CompleteTagDeclarationDefinition(dispatch_tsd_indexes_s); ProcessStructReader struct_reader(m_process, m_dispatch_tsd_indexes_addr, dispatch_tsd_indexes_s); @@ -793,8 +796,8 @@ SystemRuntimeMacOSX::GetPendingItemRefsForQueue(lldb::addr_t queue) { static_cast(i) < pending_items_pointer.count) { offset = start_of_array_offset + (i * item_size); ItemRefAndCodeAddress item; - item.item_ref = extractor.GetPointer(&offset); - item.code_address = extractor.GetPointer(&offset); + item.item_ref = extractor.GetAddress(&offset); + item.code_address = extractor.GetAddress(&offset); pending_item_refs.item_refs_and_code_addresses.push_back(item); i++; } @@ -804,7 +807,7 @@ SystemRuntimeMacOSX::GetPendingItemRefsForQueue(lldb::addr_t queue) { while (offset < pending_items_pointer.items_buffer_size && static_cast(i) < pending_items_pointer.count) { ItemRefAndCodeAddress item; - item.item_ref = extractor.GetPointer(&offset); + item.item_ref = extractor.GetAddress(&offset); item.code_address = LLDB_INVALID_ADDRESS; pending_item_refs.item_refs_and_code_addresses.push_back(item); i++; @@ -911,7 +914,7 @@ void SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR( uint32_t offset_to_next = extractor.GetU32(&offset); offset += 4; // Skip over the 4 bytes of reserved space - addr_t queue = extractor.GetPointer(&offset); + addr_t queue = extractor.GetAddress(&offset); uint64_t serialnum = extractor.GetU64(&offset); uint32_t running_work_items_count = extractor.GetU32(&offset); uint32_t pending_work_items_count = extractor.GetU32(&offset); @@ -952,8 +955,8 @@ SystemRuntimeMacOSX::ItemInfo SystemRuntimeMacOSX::ExtractItemInfoFromBuffer( offset_t offset = 0; - item.item_that_enqueued_this = extractor.GetPointer(&offset); - item.function_or_block = extractor.GetPointer(&offset); + item.item_that_enqueued_this = extractor.GetAddress(&offset); + item.function_or_block = extractor.GetAddress(&offset); item.enqueuing_thread_id = extractor.GetU64(&offset); item.enqueuing_queue_serialnum = extractor.GetU64(&offset); item.target_queue_serialnum = extractor.GetU64(&offset); @@ -963,7 +966,7 @@ SystemRuntimeMacOSX::ItemInfo SystemRuntimeMacOSX::ExtractItemInfoFromBuffer( offset = m_lib_backtrace_recording_info.item_info_data_offset; for (uint32_t i = 0; i < item.enqueuing_callstack_frame_count; i++) { - item.enqueuing_callstack.push_back(extractor.GetPointer(&offset)); + item.enqueuing_callstack.push_back(extractor.GetAddress(&offset)); } item.enqueuing_thread_label = extractor.GetCStr(&offset); item.enqueuing_queue_label = extractor.GetCStr(&offset); diff --git a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h index d6a18e2f6b0..844682e53ad 100644 --- a/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h +++ b/gnu/llvm/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SystemRuntimeMacOSX_h_ -#define liblldb_SystemRuntimeMacOSX_h_ +#ifndef LLDB_SOURCE_PLUGINS_SYSTEMRUNTIME_MACOSX_SYSTEMRUNTIMEMACOSX_H +#define LLDB_SOURCE_PLUGINS_SYSTEMRUNTIME_MACOSX_SYSTEMRUNTIMEMACOSX_H #include #include @@ -286,7 +286,8 @@ private: lldb::addr_t m_dispatch_voucher_offsets_addr; struct LibdispatchVoucherOffsets m_libdispatch_voucher_offsets; - DISALLOW_COPY_AND_ASSIGN(SystemRuntimeMacOSX); + SystemRuntimeMacOSX(const SystemRuntimeMacOSX &) = delete; + const SystemRuntimeMacOSX &operator=(const SystemRuntimeMacOSX &) = delete; }; -#endif // liblldb_SystemRuntimeMacOSX_h_ +#endif // LLDB_SOURCE_PLUGINS_SYSTEMRUNTIME_MACOSX_SYSTEMRUNTIMEMACOSX_H diff --git a/gnu/llvm/lldb/source/Plugins/TypeSystem/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/TypeSystem/CMakeLists.txt new file mode 100644 index 00000000000..17c40aee44c --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/TypeSystem/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(Clang) diff --git a/gnu/llvm/lldb/source/Plugins/TypeSystem/Clang/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/TypeSystem/Clang/CMakeLists.txt new file mode 100644 index 00000000000..37a3142da72 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/TypeSystem/Clang/CMakeLists.txt @@ -0,0 +1,20 @@ +add_lldb_library(lldbPluginTypeSystemClang PLUGIN + TypeSystemClang.cpp + + LINK_LIBS + lldbCore + lldbSymbol + lldbTarget + lldbUtility + lldbPluginExpressionParserClang + lldbPluginSymbolFileDWARF + lldbPluginSymbolFilePDB + lldbPluginObjCRuntime + CLANG_LIBS + clangAST + clangBasic + clangFrontend + clangSema + LINK_COMPONENTS + Support +) diff --git a/gnu/llvm/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/gnu/llvm/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp new file mode 100644 index 00000000000..bc06ea8164d --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -0,0 +1,9587 @@ +//===-- TypeSystemClang.cpp -----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "TypeSystemClang.h" + +#include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/FormatVariadic.h" + +#include +#include +#include + +#include "clang/AST/ASTContext.h" +#include "clang/AST/ASTImporter.h" +#include "clang/AST/Attr.h" +#include "clang/AST/CXXInheritance.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclTemplate.h" +#include "clang/AST/Mangle.h" +#include "clang/AST/RecordLayout.h" +#include "clang/AST/Type.h" +#include "clang/AST/VTableBuilder.h" +#include "clang/Basic/Builtins.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/FileSystemOptions.h" +#include "clang/Basic/LangStandard.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Basic/TargetOptions.h" +#include "clang/Frontend/FrontendOptions.h" +#include "clang/Lex/HeaderSearch.h" +#include "clang/Lex/HeaderSearchOptions.h" +#include "clang/Lex/ModuleMap.h" +#include "clang/Sema/Sema.h" + +#include "llvm/Support/Signals.h" +#include "llvm/Support/Threading.h" + +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" +#include "Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h" +#include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h" +#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" +#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" +#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h" +#include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/Flags.h" + +#include "lldb/Core/DumpDataExtractor.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Core/ThreadSafeDenseMap.h" +#include "lldb/Core/UniqueCStringMap.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/SymbolFile.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Language.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Scalar.h" + +#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" +#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h" +#include "Plugins/SymbolFile/PDB/PDBASTParser.h" + +#include + +#include + +using namespace lldb; +using namespace lldb_private; +using namespace clang; +using llvm::StringSwitch; + +LLDB_PLUGIN_DEFINE(TypeSystemClang) + +namespace { +static void VerifyDecl(clang::Decl *decl) { + assert(decl && "VerifyDecl called with nullptr?"); +#ifndef NDEBUG + // We don't care about the actual access value here but only want to trigger + // that Clang calls its internal Decl::AccessDeclContextSanity check. + decl->getAccess(); +#endif +} + +static inline bool +TypeSystemClangSupportsLanguage(lldb::LanguageType language) { + return language == eLanguageTypeUnknown || // Clang is the default type system + lldb_private::Language::LanguageIsC(language) || + lldb_private::Language::LanguageIsCPlusPlus(language) || + lldb_private::Language::LanguageIsObjC(language) || + lldb_private::Language::LanguageIsPascal(language) || + // Use Clang for Rust until there is a proper language plugin for it + language == eLanguageTypeRust || + language == eLanguageTypeExtRenderScript || + // Use Clang for D until there is a proper language plugin for it + language == eLanguageTypeD || + // Open Dylan compiler debug info is designed to be Clang-compatible + 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.GetAddress(&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 + ClangASTMap; + +static ClangASTMap &GetASTMap() { + static ClangASTMap *g_map_ptr = nullptr; + static llvm::once_flag g_once_flag; + llvm::call_once(g_once_flag, []() { + g_map_ptr = new ClangASTMap(); // leaked on purpose to avoid spins + }); + return *g_map_ptr; +} + +TypePayloadClang::TypePayloadClang(OptionalClangModuleID owning_module, + bool is_complete_objc_class) + : m_payload(owning_module.GetValue()) { + SetIsCompleteObjCClass(is_complete_objc_class); +} + +void TypePayloadClang::SetOwningModule(OptionalClangModuleID id) { + assert(id.GetValue() < ObjCClassBit); + bool is_complete = IsCompleteObjCClass(); + m_payload = id.GetValue(); + SetIsCompleteObjCClass(is_complete); +} + +static void SetMemberOwningModule(clang::Decl *member, + const clang::Decl *parent) { + if (!member || !parent) + return; + + OptionalClangModuleID id(parent->getOwningModuleID()); + if (!id.HasValue()) + return; + + member->setFromASTFile(); + member->setOwningModuleID(id.GetValue()); + member->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible); + if (llvm::isa(member)) + if (auto *dc = llvm::dyn_cast(parent)) { + dc->setHasExternalVisibleStorage(true); + // This triggers ExternalASTSource::FindExternalVisibleDeclsByName() to be + // called when searching for members. + dc->setHasExternalLexicalStorage(true); + } +} + +char TypeSystemClang::ID; + +bool TypeSystemClang::IsOperator(llvm::StringRef name, + clang::OverloadedOperatorKind &op_kind) { + // All operators have to start with "operator". + if (!name.consume_front("operator")) + return false; + + // Remember if there was a space after "operator". This is necessary to + // check for collisions with strangely named functions like "operatorint()". + bool space_after_operator = name.consume_front(" "); + + op_kind = StringSwitch(name) + .Case("+", clang::OO_Plus) + .Case("+=", clang::OO_PlusEqual) + .Case("++", clang::OO_PlusPlus) + .Case("-", clang::OO_Minus) + .Case("-=", clang::OO_MinusEqual) + .Case("--", clang::OO_MinusMinus) + .Case("->", clang::OO_Arrow) + .Case("->*", clang::OO_ArrowStar) + .Case("*", clang::OO_Star) + .Case("*=", clang::OO_StarEqual) + .Case("/", clang::OO_Slash) + .Case("/=", clang::OO_SlashEqual) + .Case("%", clang::OO_Percent) + .Case("%=", clang::OO_PercentEqual) + .Case("^", clang::OO_Caret) + .Case("^=", clang::OO_CaretEqual) + .Case("&", clang::OO_Amp) + .Case("&=", clang::OO_AmpEqual) + .Case("&&", clang::OO_AmpAmp) + .Case("|", clang::OO_Pipe) + .Case("|=", clang::OO_PipeEqual) + .Case("||", clang::OO_PipePipe) + .Case("~", clang::OO_Tilde) + .Case("!", clang::OO_Exclaim) + .Case("!=", clang::OO_ExclaimEqual) + .Case("=", clang::OO_Equal) + .Case("==", clang::OO_EqualEqual) + .Case("<", clang::OO_Less) + .Case("<<", clang::OO_LessLess) + .Case("<<=", clang::OO_LessLessEqual) + .Case("<=", clang::OO_LessEqual) + .Case(">", clang::OO_Greater) + .Case(">>", clang::OO_GreaterGreater) + .Case(">>=", clang::OO_GreaterGreaterEqual) + .Case(">=", clang::OO_GreaterEqual) + .Case("()", clang::OO_Call) + .Case("[]", clang::OO_Subscript) + .Case(",", clang::OO_Comma) + .Default(clang::NUM_OVERLOADED_OPERATORS); + + // We found a fitting operator, so we can exit now. + if (op_kind != clang::NUM_OVERLOADED_OPERATORS) + return true; + + // After the "operator " or "operator" part is something unknown. This means + // it's either one of the named operators (new/delete), a conversion operator + // (e.g. operator bool) or a function which name starts with "operator" + // (e.g. void operatorbool). + + // If it's a function that starts with operator it can't have a space after + // "operator" because identifiers can't contain spaces. + // E.g. "operator int" (conversion operator) + // vs. "operatorint" (function with colliding name). + if (!space_after_operator) + return false; // not an operator. + + // Now the operator is either one of the named operators or a conversion + // operator. + op_kind = StringSwitch(name) + .Case("new", clang::OO_New) + .Case("new[]", clang::OO_Array_New) + .Case("delete", clang::OO_Delete) + .Case("delete[]", clang::OO_Array_Delete) + // conversion operators hit this case. + .Default(clang::NUM_OVERLOADED_OPERATORS); + + return true; +} + +clang::AccessSpecifier +TypeSystemClang::ConvertAccessTypeToAccessSpecifier(AccessType access) { + switch (access) { + default: + break; + case eAccessNone: + return AS_none; + case eAccessPublic: + return AS_public; + case eAccessPrivate: + return AS_private; + case eAccessProtected: + return AS_protected; + } + return AS_none; +} + +static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) { + // FIXME: Cleanup per-file based stuff. + + // Set some properties which depend solely on the input kind; it would be + // nice to move these to the language standard, and have the driver resolve + // the input kind + language standard. + if (IK.getLanguage() == clang::Language::Asm) { + Opts.AsmPreprocessor = 1; + } else if (IK.isObjectiveC()) { + Opts.ObjC = 1; + } + + LangStandard::Kind LangStd = LangStandard::lang_unspecified; + + if (LangStd == LangStandard::lang_unspecified) { + // Based on the base language, pick one. + switch (IK.getLanguage()) { + case clang::Language::Unknown: + case clang::Language::LLVM_IR: + case clang::Language::RenderScript: + llvm_unreachable("Invalid input kind!"); + case clang::Language::OpenCL: + LangStd = LangStandard::lang_opencl10; + break; + case clang::Language::CUDA: + LangStd = LangStandard::lang_cuda; + break; + case clang::Language::Asm: + case clang::Language::C: + case clang::Language::ObjC: + LangStd = LangStandard::lang_gnu99; + break; + case clang::Language::CXX: + case clang::Language::ObjCXX: + LangStd = LangStandard::lang_gnucxx98; + break; + case clang::Language::HIP: + LangStd = LangStandard::lang_hip; + break; + } + } + + const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd); + Opts.LineComment = Std.hasLineComments(); + Opts.C99 = Std.isC99(); + Opts.CPlusPlus = Std.isCPlusPlus(); + Opts.CPlusPlus11 = Std.isCPlusPlus11(); + Opts.Digraphs = Std.hasDigraphs(); + Opts.GNUMode = Std.isGNUMode(); + Opts.GNUInline = !Std.isC99(); + Opts.HexFloats = Std.hasHexFloats(); + Opts.ImplicitInt = Std.hasImplicitInt(); + + Opts.WChar = true; + + // OpenCL has some additional defaults. + if (LangStd == LangStandard::lang_opencl10) { + Opts.OpenCL = 1; + Opts.AltiVec = 1; + Opts.CXXOperatorNames = 1; + Opts.setLaxVectorConversions(LangOptions::LaxVectorConversionKind::All); + } + + // OpenCL and C++ both have bool, true, false keywords. + Opts.Bool = Opts.OpenCL || Opts.CPlusPlus; + + Opts.setValueVisibilityMode(DefaultVisibility); + + // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs is + // specified, or -std is set to a conforming mode. + Opts.Trigraphs = !Opts.GNUMode; + Opts.CharIsSigned = ArchSpec(triple).CharIsSignedByDefault(); + Opts.OptimizeSize = 0; + + // FIXME: Eliminate this dependency. + // unsigned Opt = + // Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags); + // Opts.Optimize = Opt != 0; + unsigned Opt = 0; + + // This is the __NO_INLINE__ define, which just depends on things like the + // optimization level and -fno-inline, not actually whether the backend has + // inlining enabled. + // + // FIXME: This is affected by other options (-fno-inline). + Opts.NoInlineDefine = !Opt; + + // This is needed to allocate the extra space for the owning module + // on each decl. + Opts.ModulesLocalVisibility = 1; +} + +TypeSystemClang::TypeSystemClang(llvm::StringRef name, + llvm::Triple target_triple) { + m_display_name = name.str(); + if (!target_triple.str().empty()) + SetTargetTriple(target_triple.str()); + // The caller didn't pass an ASTContext so create a new one for this + // TypeSystemClang. + CreateASTContext(); +} + +TypeSystemClang::TypeSystemClang(llvm::StringRef name, + ASTContext &existing_ctxt) { + m_display_name = name.str(); + SetTargetTriple(existing_ctxt.getTargetInfo().getTriple().str()); + + m_ast_up.reset(&existing_ctxt); + GetASTMap().Insert(&existing_ctxt, this); +} + +// Destructor +TypeSystemClang::~TypeSystemClang() { Finalize(); } + +ConstString TypeSystemClang::GetPluginNameStatic() { + return ConstString("clang"); +} + +ConstString TypeSystemClang::GetPluginName() { + return TypeSystemClang::GetPluginNameStatic(); +} + +uint32_t TypeSystemClang::GetPluginVersion() { return 1; } + +lldb::TypeSystemSP TypeSystemClang::CreateInstance(lldb::LanguageType language, + lldb_private::Module *module, + Target *target) { + if (!TypeSystemClangSupportsLanguage(language)) + return lldb::TypeSystemSP(); + ArchSpec arch; + if (module) + arch = module->GetArchitecture(); + else if (target) + arch = target->GetArchitecture(); + + if (!arch.IsValid()) + return lldb::TypeSystemSP(); + + llvm::Triple triple = arch.GetTriple(); + // LLVM wants this to be set to iOS or MacOSX; if we're working on + // a bare-boards type image, change the triple for llvm's benefit. + if (triple.getVendor() == llvm::Triple::Apple && + triple.getOS() == llvm::Triple::UnknownOS) { + if (triple.getArch() == llvm::Triple::arm || + triple.getArch() == llvm::Triple::aarch64 || + triple.getArch() == llvm::Triple::aarch64_32 || + triple.getArch() == llvm::Triple::thumb) { + triple.setOS(llvm::Triple::IOS); + } else { + triple.setOS(llvm::Triple::MacOSX); + } + } + + if (module) { + std::string ast_name = + "ASTContext for '" + module->GetFileSpec().GetPath() + "'"; + return std::make_shared(ast_name, triple); + } else if (target && target->IsValid()) + return std::make_shared(*target, triple); + return lldb::TypeSystemSP(); +} + +LanguageSet TypeSystemClang::GetSupportedLanguagesForTypes() { + LanguageSet languages; + languages.Insert(lldb::eLanguageTypeC89); + languages.Insert(lldb::eLanguageTypeC); + languages.Insert(lldb::eLanguageTypeC11); + languages.Insert(lldb::eLanguageTypeC_plus_plus); + languages.Insert(lldb::eLanguageTypeC99); + languages.Insert(lldb::eLanguageTypeObjC); + languages.Insert(lldb::eLanguageTypeObjC_plus_plus); + languages.Insert(lldb::eLanguageTypeC_plus_plus_03); + languages.Insert(lldb::eLanguageTypeC_plus_plus_11); + languages.Insert(lldb::eLanguageTypeC11); + languages.Insert(lldb::eLanguageTypeC_plus_plus_14); + return languages; +} + +LanguageSet TypeSystemClang::GetSupportedLanguagesForExpressions() { + LanguageSet languages; + languages.Insert(lldb::eLanguageTypeC_plus_plus); + languages.Insert(lldb::eLanguageTypeObjC_plus_plus); + languages.Insert(lldb::eLanguageTypeC_plus_plus_03); + languages.Insert(lldb::eLanguageTypeC_plus_plus_11); + languages.Insert(lldb::eLanguageTypeC_plus_plus_14); + return languages; +} + +void TypeSystemClang::Initialize() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), "clang base AST context plug-in", CreateInstance, + GetSupportedLanguagesForTypes(), GetSupportedLanguagesForExpressions()); +} + +void TypeSystemClang::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +void TypeSystemClang::Finalize() { + assert(m_ast_up); + GetASTMap().Erase(m_ast_up.get()); + if (!m_ast_owned) + m_ast_up.release(); + + m_builtins_up.reset(); + m_selector_table_up.reset(); + m_identifier_table_up.reset(); + m_target_info_up.reset(); + m_target_options_rp.reset(); + m_diagnostics_engine_up.reset(); + m_source_manager_up.reset(); + m_language_options_up.reset(); +} + +void TypeSystemClang::setSema(Sema *s) { + // Ensure that the new sema actually belongs to our ASTContext. + assert(s == nullptr || &s->getASTContext() == m_ast_up.get()); + m_sema = s; +} + +const char *TypeSystemClang::GetTargetTriple() { + return m_target_triple.c_str(); +} + +void TypeSystemClang::SetTargetTriple(llvm::StringRef target_triple) { + m_target_triple = target_triple.str(); +} + +void TypeSystemClang::SetExternalSource( + llvm::IntrusiveRefCntPtr &ast_source_up) { + ASTContext &ast = getASTContext(); + ast.setExternalSource(ast_source_up); + ast.getTranslationUnitDecl()->setHasExternalLexicalStorage(true); +} + +ASTContext &TypeSystemClang::getASTContext() { + assert(m_ast_up); + return *m_ast_up; +} + +class NullDiagnosticConsumer : public DiagnosticConsumer { +public: + NullDiagnosticConsumer() { + m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + } + + void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, + const clang::Diagnostic &info) override { + if (m_log) { + llvm::SmallVector diag_str(10); + info.FormatDiagnostic(diag_str); + diag_str.push_back('\0'); + LLDB_LOGF(m_log, "Compiler diagnostic: %s\n", diag_str.data()); + } + } + + DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const { + return new NullDiagnosticConsumer(); + } + +private: + Log *m_log; +}; + +void TypeSystemClang::CreateASTContext() { + assert(!m_ast_up); + m_ast_owned = true; + + m_language_options_up = std::make_unique(); + ParseLangArgs(*m_language_options_up, clang::Language::ObjCXX, + GetTargetTriple()); + + m_identifier_table_up = + std::make_unique(*m_language_options_up, nullptr); + m_builtins_up = std::make_unique(); + + m_selector_table_up = std::make_unique(); + + clang::FileSystemOptions file_system_options; + m_file_manager_up = std::make_unique( + file_system_options, FileSystem::Instance().GetVirtualFileSystem()); + + llvm::IntrusiveRefCntPtr diag_id_sp(new DiagnosticIDs()); + m_diagnostics_engine_up = + std::make_unique(diag_id_sp, new DiagnosticOptions()); + + m_source_manager_up = std::make_unique( + *m_diagnostics_engine_up, *m_file_manager_up); + m_ast_up = std::make_unique( + *m_language_options_up, *m_source_manager_up, *m_identifier_table_up, + *m_selector_table_up, *m_builtins_up); + + m_diagnostic_consumer_up = std::make_unique(); + m_ast_up->getDiagnostics().setClient(m_diagnostic_consumer_up.get(), false); + + // This can be NULL if we don't know anything about the architecture or if + // the target for an architecture isn't enabled in the llvm/clang that we + // built + TargetInfo *target_info = getTargetInfo(); + if (target_info) + m_ast_up->InitBuiltinTypes(*target_info); + + GetASTMap().Insert(m_ast_up.get(), this); + + llvm::IntrusiveRefCntPtr ast_source_up( + new ClangExternalASTSourceCallbacks(*this)); + SetExternalSource(ast_source_up); +} + +TypeSystemClang *TypeSystemClang::GetASTContext(clang::ASTContext *ast) { + TypeSystemClang *clang_ast = GetASTMap().Lookup(ast); + return clang_ast; +} + +clang::MangleContext *TypeSystemClang::getMangleContext() { + if (m_mangle_ctx_up == nullptr) + m_mangle_ctx_up.reset(getASTContext().createMangleContext()); + return m_mangle_ctx_up.get(); +} + +std::shared_ptr &TypeSystemClang::getTargetOptions() { + if (m_target_options_rp == nullptr && !m_target_triple.empty()) { + m_target_options_rp = std::make_shared(); + if (m_target_options_rp != nullptr) + m_target_options_rp->Triple = m_target_triple; + } + return m_target_options_rp; +} + +TargetInfo *TypeSystemClang::getTargetInfo() { + // target_triple should be something like "x86_64-apple-macosx" + if (m_target_info_up == nullptr && !m_target_triple.empty()) + m_target_info_up.reset(TargetInfo::CreateTargetInfo( + getASTContext().getDiagnostics(), getTargetOptions())); + return m_target_info_up.get(); +} + +#pragma mark Basic Types + +static inline bool QualTypeMatchesBitSize(const uint64_t bit_size, + ASTContext &ast, QualType qual_type) { + uint64_t qual_type_bit_size = ast.getTypeSize(qual_type); + return qual_type_bit_size == bit_size; +} + +CompilerType +TypeSystemClang::GetBuiltinTypeForEncodingAndBitSize(Encoding encoding, + size_t bit_size) { + ASTContext &ast = getASTContext(); + switch (encoding) { + case eEncodingInvalid: + if (QualTypeMatchesBitSize(bit_size, ast, ast.VoidPtrTy)) + return GetType(ast.VoidPtrTy); + break; + + case eEncodingUint: + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy)) + return GetType(ast.UnsignedCharTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy)) + return GetType(ast.UnsignedShortTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy)) + return GetType(ast.UnsignedIntTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongTy)) + return GetType(ast.UnsignedLongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongLongTy)) + return GetType(ast.UnsignedLongLongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedInt128Ty)) + return GetType(ast.UnsignedInt128Ty); + break; + + case eEncodingSint: + if (QualTypeMatchesBitSize(bit_size, ast, ast.SignedCharTy)) + return GetType(ast.SignedCharTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.ShortTy)) + return GetType(ast.ShortTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.IntTy)) + return GetType(ast.IntTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.LongTy)) + return GetType(ast.LongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.LongLongTy)) + return GetType(ast.LongLongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.Int128Ty)) + return GetType(ast.Int128Ty); + break; + + case eEncodingIEEE754: + if (QualTypeMatchesBitSize(bit_size, ast, ast.FloatTy)) + return GetType(ast.FloatTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.DoubleTy)) + return GetType(ast.DoubleTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleTy)) + return GetType(ast.LongDoubleTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.HalfTy)) + return GetType(ast.HalfTy); + break; + + case eEncodingVector: + // Sanity check that bit_size is a multiple of 8's. + if (bit_size && !(bit_size & 0x7u)) + return GetType(ast.getExtVectorType(ast.UnsignedCharTy, bit_size / 8)); + break; + } + + return CompilerType(); +} + +lldb::BasicType +TypeSystemClang::GetBasicTypeEnumeration(ConstString name) { + 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); + + // "char" + g_type_map.Append(ConstString("char"), eBasicTypeChar); + g_type_map.Append(ConstString("signed char"), eBasicTypeSignedChar); + g_type_map.Append(ConstString("unsigned char"), eBasicTypeUnsignedChar); + g_type_map.Append(ConstString("wchar_t"), eBasicTypeWChar); + g_type_map.Append(ConstString("signed wchar_t"), eBasicTypeSignedWChar); + g_type_map.Append(ConstString("unsigned wchar_t"), + eBasicTypeUnsignedWChar); + // "short" + g_type_map.Append(ConstString("short"), eBasicTypeShort); + g_type_map.Append(ConstString("short int"), eBasicTypeShort); + g_type_map.Append(ConstString("unsigned short"), eBasicTypeUnsignedShort); + g_type_map.Append(ConstString("unsigned short int"), + eBasicTypeUnsignedShort); + + // "int" + g_type_map.Append(ConstString("int"), eBasicTypeInt); + g_type_map.Append(ConstString("signed int"), eBasicTypeInt); + g_type_map.Append(ConstString("unsigned int"), eBasicTypeUnsignedInt); + g_type_map.Append(ConstString("unsigned"), eBasicTypeUnsignedInt); + + // "long" + g_type_map.Append(ConstString("long"), eBasicTypeLong); + g_type_map.Append(ConstString("long int"), eBasicTypeLong); + g_type_map.Append(ConstString("unsigned long"), eBasicTypeUnsignedLong); + g_type_map.Append(ConstString("unsigned long int"), + eBasicTypeUnsignedLong); + + // "long long" + g_type_map.Append(ConstString("long long"), eBasicTypeLongLong); + g_type_map.Append(ConstString("long long int"), eBasicTypeLongLong); + g_type_map.Append(ConstString("unsigned long long"), + eBasicTypeUnsignedLongLong); + g_type_map.Append(ConstString("unsigned long long int"), + eBasicTypeUnsignedLongLong); + + // "int128" + g_type_map.Append(ConstString("__int128_t"), eBasicTypeInt128); + g_type_map.Append(ConstString("__uint128_t"), eBasicTypeUnsignedInt128); + + // Miscellaneous + g_type_map.Append(ConstString("bool"), eBasicTypeBool); + g_type_map.Append(ConstString("float"), eBasicTypeFloat); + g_type_map.Append(ConstString("double"), eBasicTypeDouble); + g_type_map.Append(ConstString("long double"), eBasicTypeLongDouble); + g_type_map.Append(ConstString("id"), eBasicTypeObjCID); + g_type_map.Append(ConstString("SEL"), eBasicTypeObjCSel); + g_type_map.Append(ConstString("nullptr"), eBasicTypeNullPtr); + g_type_map.Sort(); + }); + + return g_type_map.Find(name, eBasicTypeInvalid); + } + return eBasicTypeInvalid; +} + +uint32_t TypeSystemClang::GetPointerByteSize() { + if (m_pointer_byte_size == 0) + if (auto size = GetBasicType(lldb::eBasicTypeVoid) + .GetPointerType() + .GetByteSize(nullptr)) + m_pointer_byte_size = *size; + return m_pointer_byte_size; +} + +CompilerType TypeSystemClang::GetBasicType(lldb::BasicType basic_type) { + clang::ASTContext &ast = getASTContext(); + + lldb::opaque_compiler_type_t clang_type = + GetOpaqueCompilerType(&ast, basic_type); + + if (clang_type) + return CompilerType(this, clang_type); + return CompilerType(); +} + +CompilerType TypeSystemClang::GetBuiltinTypeForDWARFEncodingAndBitSize( + llvm::StringRef type_name, uint32_t dw_ate, uint32_t bit_size) { + ASTContext &ast = getASTContext(); + + switch (dw_ate) { + default: + break; + + case DW_ATE_address: + if (QualTypeMatchesBitSize(bit_size, ast, ast.VoidPtrTy)) + return GetType(ast.VoidPtrTy); + break; + + case DW_ATE_boolean: + if (QualTypeMatchesBitSize(bit_size, ast, ast.BoolTy)) + return GetType(ast.BoolTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy)) + return GetType(ast.UnsignedCharTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy)) + return GetType(ast.UnsignedShortTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy)) + return GetType(ast.UnsignedIntTy); + break; + + case DW_ATE_lo_user: + // This has been seen to mean DW_AT_complex_integer + if (type_name.contains("complex")) { + CompilerType complex_int_clang_type = + GetBuiltinTypeForDWARFEncodingAndBitSize("int", DW_ATE_signed, + bit_size / 2); + return GetType( + ast.getComplexType(ClangUtil::GetQualType(complex_int_clang_type))); + } + break; + + case DW_ATE_complex_float: + if (QualTypeMatchesBitSize(bit_size, ast, ast.FloatComplexTy)) + return GetType(ast.FloatComplexTy); + else if (QualTypeMatchesBitSize(bit_size, ast, ast.DoubleComplexTy)) + return GetType(ast.DoubleComplexTy); + else if (QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleComplexTy)) + return GetType(ast.LongDoubleComplexTy); + else { + CompilerType complex_float_clang_type = + GetBuiltinTypeForDWARFEncodingAndBitSize("float", DW_ATE_float, + bit_size / 2); + return GetType( + ast.getComplexType(ClangUtil::GetQualType(complex_float_clang_type))); + } + break; + + case DW_ATE_float: + if (type_name == "float" && + QualTypeMatchesBitSize(bit_size, ast, ast.FloatTy)) + return GetType(ast.FloatTy); + if (type_name == "double" && + QualTypeMatchesBitSize(bit_size, ast, ast.DoubleTy)) + return GetType(ast.DoubleTy); + if (type_name == "long double" && + QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleTy)) + return GetType(ast.LongDoubleTy); + // Fall back to not requiring a name match + if (QualTypeMatchesBitSize(bit_size, ast, ast.FloatTy)) + return GetType(ast.FloatTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.DoubleTy)) + return GetType(ast.DoubleTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleTy)) + return GetType(ast.LongDoubleTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.HalfTy)) + return GetType(ast.HalfTy); + break; + + case DW_ATE_signed: + if (!type_name.empty()) { + if (type_name == "wchar_t" && + QualTypeMatchesBitSize(bit_size, ast, ast.WCharTy) && + (getTargetInfo() && + TargetInfo::isTypeSigned(getTargetInfo()->getWCharType()))) + return GetType(ast.WCharTy); + if (type_name == "void" && + QualTypeMatchesBitSize(bit_size, ast, ast.VoidTy)) + return GetType(ast.VoidTy); + if (type_name.contains("long long") && + QualTypeMatchesBitSize(bit_size, ast, ast.LongLongTy)) + return GetType(ast.LongLongTy); + if (type_name.contains("long") && + QualTypeMatchesBitSize(bit_size, ast, ast.LongTy)) + return GetType(ast.LongTy); + if (type_name.contains("short") && + QualTypeMatchesBitSize(bit_size, ast, ast.ShortTy)) + return GetType(ast.ShortTy); + if (type_name.contains("char")) { + if (QualTypeMatchesBitSize(bit_size, ast, ast.CharTy)) + return GetType(ast.CharTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.SignedCharTy)) + return GetType(ast.SignedCharTy); + } + if (type_name.contains("int")) { + if (QualTypeMatchesBitSize(bit_size, ast, ast.IntTy)) + return GetType(ast.IntTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.Int128Ty)) + return GetType(ast.Int128Ty); + } + } + // We weren't able to match up a type name, just search by size + if (QualTypeMatchesBitSize(bit_size, ast, ast.CharTy)) + return GetType(ast.CharTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.ShortTy)) + return GetType(ast.ShortTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.IntTy)) + return GetType(ast.IntTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.LongTy)) + return GetType(ast.LongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.LongLongTy)) + return GetType(ast.LongLongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.Int128Ty)) + return GetType(ast.Int128Ty); + break; + + case DW_ATE_signed_char: + if (ast.getLangOpts().CharIsSigned && type_name == "char") { + if (QualTypeMatchesBitSize(bit_size, ast, ast.CharTy)) + return GetType(ast.CharTy); + } + if (QualTypeMatchesBitSize(bit_size, ast, ast.SignedCharTy)) + return GetType(ast.SignedCharTy); + break; + + case DW_ATE_unsigned: + if (!type_name.empty()) { + if (type_name == "wchar_t") { + if (QualTypeMatchesBitSize(bit_size, ast, ast.WCharTy)) { + if (!(getTargetInfo() && + TargetInfo::isTypeSigned(getTargetInfo()->getWCharType()))) + return GetType(ast.WCharTy); + } + } + if (type_name.contains("long long")) { + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongLongTy)) + return GetType(ast.UnsignedLongLongTy); + } else if (type_name.contains("long")) { + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongTy)) + return GetType(ast.UnsignedLongTy); + } else if (type_name.contains("short")) { + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy)) + return GetType(ast.UnsignedShortTy); + } else if (type_name.contains("char")) { + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy)) + return GetType(ast.UnsignedCharTy); + } else if (type_name.contains("int")) { + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy)) + return GetType(ast.UnsignedIntTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedInt128Ty)) + return GetType(ast.UnsignedInt128Ty); + } + } + // We weren't able to match up a type name, just search by size + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy)) + return GetType(ast.UnsignedCharTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy)) + return GetType(ast.UnsignedShortTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy)) + return GetType(ast.UnsignedIntTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongTy)) + return GetType(ast.UnsignedLongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongLongTy)) + return GetType(ast.UnsignedLongLongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedInt128Ty)) + return GetType(ast.UnsignedInt128Ty); + break; + + case DW_ATE_unsigned_char: + if (!ast.getLangOpts().CharIsSigned && type_name == "char") { + if (QualTypeMatchesBitSize(bit_size, ast, ast.CharTy)) + return GetType(ast.CharTy); + } + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy)) + return GetType(ast.UnsignedCharTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy)) + return GetType(ast.UnsignedShortTy); + break; + + case DW_ATE_imaginary_float: + break; + + case DW_ATE_UTF: + switch (bit_size) { + case 8: + return GetType(ast.Char8Ty); + case 16: + return GetType(ast.Char16Ty); + case 32: + return GetType(ast.Char32Ty); + default: + if (!type_name.empty()) { + if (type_name == "char16_t") + return GetType(ast.Char16Ty); + if (type_name == "char32_t") + return GetType(ast.Char32Ty); + if (type_name == "char8_t") + return GetType(ast.Char8Ty); + } + } + break; + } + // This assert should fire for anything that we don't catch above so we know + // to fix any issues we run into. + if (!type_name.empty()) { + std::string type_name_str = type_name.str(); + Host::SystemLog(Host::eSystemLogError, + "error: need to add support for DW_TAG_base_type '%s' " + "encoded with DW_ATE = 0x%x, bit_size = %u\n", + type_name_str.c_str(), dw_ate, bit_size); + } else { + Host::SystemLog(Host::eSystemLogError, "error: need to add support for " + "DW_TAG_base_type encoded with " + "DW_ATE = 0x%x, bit_size = %u\n", + dw_ate, bit_size); + } + return CompilerType(); +} + +CompilerType TypeSystemClang::GetCStringType(bool is_const) { + ASTContext &ast = getASTContext(); + QualType char_type(ast.CharTy); + + if (is_const) + char_type.addConst(); + + return GetType(ast.getPointerType(char_type)); +} + +bool TypeSystemClang::AreTypesSame(CompilerType type1, CompilerType type2, + bool ignore_qualifiers) { + TypeSystemClang *ast = + llvm::dyn_cast_or_null(type1.GetTypeSystem()); + if (!ast || ast != type2.GetTypeSystem()) + return false; + + if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType()) + return true; + + QualType type1_qual = ClangUtil::GetQualType(type1); + QualType type2_qual = ClangUtil::GetQualType(type2); + + if (ignore_qualifiers) { + type1_qual = type1_qual.getUnqualifiedType(); + type2_qual = type2_qual.getUnqualifiedType(); + } + + return ast->getASTContext().hasSameType(type1_qual, type2_qual); +} + +CompilerType TypeSystemClang::GetTypeForDecl(void *opaque_decl) { + if (!opaque_decl) + return CompilerType(); + + clang::Decl *decl = static_cast(opaque_decl); + if (auto *named_decl = llvm::dyn_cast(decl)) + return GetTypeForDecl(named_decl); + return CompilerType(); +} + +CompilerDeclContext TypeSystemClang::CreateDeclContext(DeclContext *ctx) { + // Check that the DeclContext actually belongs to this ASTContext. + assert(&ctx->getParentASTContext() == &getASTContext()); + return CompilerDeclContext(this, ctx); +} + +CompilerType TypeSystemClang::GetTypeForDecl(clang::NamedDecl *decl) { + if (clang::ObjCInterfaceDecl *interface_decl = + llvm::dyn_cast(decl)) + return GetTypeForDecl(interface_decl); + if (clang::TagDecl *tag_decl = llvm::dyn_cast(decl)) + return GetTypeForDecl(tag_decl); + return CompilerType(); +} + +CompilerType TypeSystemClang::GetTypeForDecl(TagDecl *decl) { + return GetType(getASTContext().getTagDeclType(decl)); +} + +CompilerType TypeSystemClang::GetTypeForDecl(ObjCInterfaceDecl *decl) { + return GetType(getASTContext().getObjCInterfaceType(decl)); +} + +#pragma mark Structure, Unions, Classes + +void TypeSystemClang::SetOwningModule(clang::Decl *decl, + OptionalClangModuleID owning_module) { + if (!decl || !owning_module.HasValue()) + return; + + decl->setFromASTFile(); + decl->setOwningModuleID(owning_module.GetValue()); + decl->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible); +} + +OptionalClangModuleID +TypeSystemClang::GetOrCreateClangModule(llvm::StringRef name, + OptionalClangModuleID parent, + bool is_framework, bool is_explicit) { + // Get the external AST source which holds the modules. + auto *ast_source = llvm::dyn_cast_or_null( + getASTContext().getExternalSource()); + assert(ast_source && "external ast source was lost"); + if (!ast_source) + return {}; + + // Lazily initialize the module map. + if (!m_header_search_up) { + auto HSOpts = std::make_shared(); + m_header_search_up = std::make_unique( + HSOpts, *m_source_manager_up, *m_diagnostics_engine_up, + *m_language_options_up, m_target_info_up.get()); + m_module_map_up = std::make_unique( + *m_source_manager_up, *m_diagnostics_engine_up, *m_language_options_up, + m_target_info_up.get(), *m_header_search_up); + } + + // Get or create the module context. + bool created; + clang::Module *module; + auto parent_desc = ast_source->getSourceDescriptor(parent.GetValue()); + std::tie(module, created) = m_module_map_up->findOrCreateModule( + name, parent_desc ? parent_desc->getModuleOrNull() : nullptr, + is_framework, is_explicit); + if (!created) + return ast_source->GetIDForModule(module); + + return ast_source->RegisterModule(module); +} + +CompilerType TypeSystemClang::CreateRecordType( + clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, + AccessType access_type, llvm::StringRef name, int kind, + LanguageType language, ClangASTMetadata *metadata, bool exports_symbols) { + ASTContext &ast = getASTContext(); + + if (decl_ctx == nullptr) + decl_ctx = ast.getTranslationUnitDecl(); + + if (language == eLanguageTypeObjC || + language == eLanguageTypeObjC_plus_plus) { + bool isForwardDecl = true; + bool isInternal = false; + return CreateObjCClass(name, decl_ctx, owning_module, isForwardDecl, + isInternal, metadata); + } + + // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and + // we will need to update this code. I was told to currently always use the + // CXXRecordDecl class since we often don't know from debug information if + // something is struct or a class, so we default to always use the more + // complete definition just in case. + + bool has_name = !name.empty(); + CXXRecordDecl *decl = CXXRecordDecl::CreateDeserialized(ast, 0); + decl->setTagKind(static_cast(kind)); + decl->setDeclContext(decl_ctx); + if (has_name) + decl->setDeclName(&ast.Idents.get(name)); + SetOwningModule(decl, owning_module); + + if (!has_name) { + // In C++ a lambda is also represented as an unnamed class. This is + // different from an *anonymous class* that the user wrote: + // + // struct A { + // // anonymous class (GNU/MSVC extension) + // struct { + // int x; + // }; + // // unnamed class within a class + // struct { + // int y; + // } B; + // }; + // + // void f() { + // // unammed class outside of a class + // struct { + // int z; + // } C; + // } + // + // Anonymous classes is a GNU/MSVC extension that clang supports. It + // requires the anonymous class be embedded within a class. So the new + // heuristic verifies this condition. + if (isa(decl_ctx) && exports_symbols) + decl->setAnonymousStructOrUnion(true); + } + + if (decl) { + if (metadata) + SetMetadata(decl, *metadata); + + if (access_type != eAccessNone) + decl->setAccess(ConvertAccessTypeToAccessSpecifier(access_type)); + + if (decl_ctx) + decl_ctx->addDecl(decl); + + return GetType(ast.getTagDeclType(decl)); + } + return CompilerType(); +} + +namespace { + bool IsValueParam(const clang::TemplateArgument &argument) { + return argument.getKind() == TemplateArgument::Integral; + } +} + +static TemplateParameterList *CreateTemplateParameterList( + ASTContext &ast, + const TypeSystemClang::TemplateParameterInfos &template_param_infos, + llvm::SmallVector &template_param_decls) { + const bool parameter_pack = false; + const bool is_typename = false; + const unsigned depth = 0; + const size_t num_template_params = template_param_infos.args.size(); + DeclContext *const decl_context = + ast.getTranslationUnitDecl(); // Is this the right decl context?, + for (size_t i = 0; i < num_template_params; ++i) { + const char *name = template_param_infos.names[i]; + + IdentifierInfo *identifier_info = nullptr; + if (name && name[0]) + identifier_info = &ast.Idents.get(name); + if (IsValueParam(template_param_infos.args[i])) { + QualType template_param_type = + template_param_infos.args[i].getIntegralType(); + template_param_decls.push_back(NonTypeTemplateParmDecl::Create( + ast, decl_context, SourceLocation(), SourceLocation(), depth, i, + identifier_info, template_param_type, parameter_pack, + ast.getTrivialTypeSourceInfo(template_param_type))); + } else { + template_param_decls.push_back(TemplateTypeParmDecl::Create( + ast, decl_context, SourceLocation(), SourceLocation(), depth, i, + identifier_info, is_typename, parameter_pack)); + } + } + + if (template_param_infos.packed_args) { + IdentifierInfo *identifier_info = nullptr; + if (template_param_infos.pack_name && template_param_infos.pack_name[0]) + identifier_info = &ast.Idents.get(template_param_infos.pack_name); + const bool parameter_pack_true = true; + + if (!template_param_infos.packed_args->args.empty() && + IsValueParam(template_param_infos.packed_args->args[0])) { + QualType template_param_type = + template_param_infos.packed_args->args[0].getIntegralType(); + template_param_decls.push_back(NonTypeTemplateParmDecl::Create( + ast, decl_context, SourceLocation(), SourceLocation(), depth, + num_template_params, identifier_info, template_param_type, + parameter_pack_true, + ast.getTrivialTypeSourceInfo(template_param_type))); + } else { + template_param_decls.push_back(TemplateTypeParmDecl::Create( + ast, decl_context, SourceLocation(), SourceLocation(), depth, + num_template_params, identifier_info, is_typename, + parameter_pack_true)); + } + } + clang::Expr *const requires_clause = nullptr; // TODO: Concepts + TemplateParameterList *template_param_list = TemplateParameterList::Create( + ast, SourceLocation(), SourceLocation(), template_param_decls, + SourceLocation(), requires_clause); + return template_param_list; +} + +clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl( + clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, + clang::FunctionDecl *func_decl, const char *name, + const TemplateParameterInfos &template_param_infos) { + // /// Create a function template node. + ASTContext &ast = getASTContext(); + + llvm::SmallVector template_param_decls; + TemplateParameterList *template_param_list = CreateTemplateParameterList( + ast, template_param_infos, template_param_decls); + FunctionTemplateDecl *func_tmpl_decl = + FunctionTemplateDecl::CreateDeserialized(ast, 0); + func_tmpl_decl->setDeclContext(decl_ctx); + func_tmpl_decl->setLocation(func_decl->getLocation()); + func_tmpl_decl->setDeclName(func_decl->getDeclName()); + func_tmpl_decl->init(func_decl, template_param_list); + SetOwningModule(func_tmpl_decl, owning_module); + + for (size_t i = 0, template_param_decl_count = template_param_decls.size(); + i < template_param_decl_count; ++i) { + // TODO: verify which decl context we should put template_param_decls into.. + template_param_decls[i]->setDeclContext(func_decl); + } + // Function templates inside a record need to have an access specifier. + // It doesn't matter what access specifier we give the template as LLDB + // anyway allows accessing everything inside a record. + if (decl_ctx->isRecord()) + func_tmpl_decl->setAccess(clang::AccessSpecifier::AS_public); + + return func_tmpl_decl; +} + +void TypeSystemClang::CreateFunctionTemplateSpecializationInfo( + FunctionDecl *func_decl, clang::FunctionTemplateDecl *func_tmpl_decl, + const TemplateParameterInfos &infos) { + TemplateArgumentList *template_args_ptr = + TemplateArgumentList::CreateCopy(func_decl->getASTContext(), infos.args); + + func_decl->setFunctionTemplateSpecialization(func_tmpl_decl, + template_args_ptr, nullptr); +} + +ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl( + DeclContext *decl_ctx, OptionalClangModuleID owning_module, + lldb::AccessType access_type, const char *class_name, int kind, + const TemplateParameterInfos &template_param_infos) { + ASTContext &ast = getASTContext(); + + ClassTemplateDecl *class_template_decl = nullptr; + if (decl_ctx == nullptr) + decl_ctx = ast.getTranslationUnitDecl(); + + IdentifierInfo &identifier_info = ast.Idents.get(class_name); + DeclarationName decl_name(&identifier_info); + + clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name); + + for (NamedDecl *decl : result) { + class_template_decl = dyn_cast(decl); + if (class_template_decl) + return class_template_decl; + } + + llvm::SmallVector template_param_decls; + + TemplateParameterList *template_param_list = CreateTemplateParameterList( + ast, template_param_infos, template_param_decls); + + CXXRecordDecl *template_cxx_decl = CXXRecordDecl::CreateDeserialized(ast, 0); + template_cxx_decl->setTagKind(static_cast(kind)); + // What decl context do we use here? TU? The actual decl context? + template_cxx_decl->setDeclContext(decl_ctx); + template_cxx_decl->setDeclName(decl_name); + SetOwningModule(template_cxx_decl, owning_module); + + for (size_t i = 0, template_param_decl_count = template_param_decls.size(); + i < template_param_decl_count; ++i) { + template_param_decls[i]->setDeclContext(template_cxx_decl); + } + + // With templated classes, we say that a class is templated with + // specializations, but that the bare class has no functions. + // template_cxx_decl->startDefinition(); + // template_cxx_decl->completeDefinition(); + + class_template_decl = ClassTemplateDecl::CreateDeserialized(ast, 0); + // What decl context do we use here? TU? The actual decl context? + class_template_decl->setDeclContext(decl_ctx); + class_template_decl->setDeclName(decl_name); + class_template_decl->init(template_cxx_decl, template_param_list); + template_cxx_decl->setDescribedClassTemplate(class_template_decl); + SetOwningModule(class_template_decl, owning_module); + + if (class_template_decl) { + if (access_type != eAccessNone) + class_template_decl->setAccess( + ConvertAccessTypeToAccessSpecifier(access_type)); + + decl_ctx->addDecl(class_template_decl); + + VerifyDecl(class_template_decl); + } + + return class_template_decl; +} + +TemplateTemplateParmDecl * +TypeSystemClang::CreateTemplateTemplateParmDecl(const char *template_name) { + ASTContext &ast = getASTContext(); + + auto *decl_ctx = ast.getTranslationUnitDecl(); + + IdentifierInfo &identifier_info = ast.Idents.get(template_name); + llvm::SmallVector template_param_decls; + + TypeSystemClang::TemplateParameterInfos template_param_infos; + TemplateParameterList *template_param_list = CreateTemplateParameterList( + ast, template_param_infos, template_param_decls); + + // LLDB needs to create those decls only to be able to display a + // type that includes a template template argument. Only the name matters for + // this purpose, so we use dummy values for the other characteristics of the + // type. + return TemplateTemplateParmDecl::Create( + ast, decl_ctx, SourceLocation(), + /*Depth*/ 0, /*Position*/ 0, + /*IsParameterPack*/ false, &identifier_info, template_param_list); +} + +ClassTemplateSpecializationDecl * +TypeSystemClang::CreateClassTemplateSpecializationDecl( + DeclContext *decl_ctx, OptionalClangModuleID owning_module, + ClassTemplateDecl *class_template_decl, int kind, + const TemplateParameterInfos &template_param_infos) { + ASTContext &ast = getASTContext(); + llvm::SmallVector args( + template_param_infos.args.size() + + (template_param_infos.packed_args ? 1 : 0)); + std::copy(template_param_infos.args.begin(), template_param_infos.args.end(), + args.begin()); + if (template_param_infos.packed_args) { + args[args.size() - 1] = TemplateArgument::CreatePackCopy( + ast, template_param_infos.packed_args->args); + } + ClassTemplateSpecializationDecl *class_template_specialization_decl = + ClassTemplateSpecializationDecl::CreateDeserialized(ast, 0); + class_template_specialization_decl->setTagKind( + static_cast(kind)); + class_template_specialization_decl->setDeclContext(decl_ctx); + class_template_specialization_decl->setInstantiationOf(class_template_decl); + class_template_specialization_decl->setTemplateArgs( + TemplateArgumentList::CreateCopy(ast, args)); + ast.getTypeDeclType(class_template_specialization_decl, nullptr); + class_template_specialization_decl->setDeclName( + class_template_decl->getDeclName()); + SetOwningModule(class_template_specialization_decl, owning_module); + decl_ctx->addDecl(class_template_specialization_decl); + + class_template_specialization_decl->setSpecializationKind( + TSK_ExplicitSpecialization); + + return class_template_specialization_decl; +} + +CompilerType TypeSystemClang::CreateClassTemplateSpecializationType( + ClassTemplateSpecializationDecl *class_template_specialization_decl) { + if (class_template_specialization_decl) { + ASTContext &ast = getASTContext(); + return GetType(ast.getTagDeclType(class_template_specialization_decl)); + } + return CompilerType(); +} + +static inline bool check_op_param(bool is_method, + clang::OverloadedOperatorKind op_kind, + bool unary, bool binary, + uint32_t num_params) { + // Special-case call since it can take any number of operands + if (op_kind == OO_Call) + return true; + + // The parameter count doesn't include "this" + if (is_method) + ++num_params; + if (num_params == 1) + return unary; + if (num_params == 2) + return binary; + else + return false; +} + +bool TypeSystemClang::CheckOverloadedOperatorKindParameterCount( + bool is_method, clang::OverloadedOperatorKind op_kind, + uint32_t num_params) { + switch (op_kind) { + default: + break; + // C++ standard allows any number of arguments to new/delete + case OO_New: + case OO_Array_New: + case OO_Delete: + case OO_Array_Delete: + return true; + } + +#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \ + case OO_##Name: \ + return check_op_param(is_method, op_kind, Unary, Binary, num_params); + switch (op_kind) { +#include "clang/Basic/OperatorKinds.def" + default: + break; + } + return false; +} + +clang::AccessSpecifier +TypeSystemClang::UnifyAccessSpecifiers(clang::AccessSpecifier lhs, + clang::AccessSpecifier rhs) { + // Make the access equal to the stricter of the field and the nested field's + // access + if (lhs == AS_none || rhs == AS_none) + return AS_none; + if (lhs == AS_private || rhs == AS_private) + return AS_private; + if (lhs == AS_protected || rhs == AS_protected) + return AS_protected; + return AS_public; +} + +bool TypeSystemClang::FieldIsBitfield(FieldDecl *field, + uint32_t &bitfield_bit_size) { + ASTContext &ast = getASTContext(); + if (field == nullptr) + return false; + + if (field->isBitField()) { + Expr *bit_width_expr = field->getBitWidth(); + if (bit_width_expr) { + llvm::APSInt bit_width_apsint; + if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, ast)) { + bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX); + return true; + } + } + } + return false; +} + +bool TypeSystemClang::RecordHasFields(const RecordDecl *record_decl) { + if (record_decl == nullptr) + return false; + + if (!record_decl->field_empty()) + return true; + + // No fields, lets check this is a CXX record and check the base classes + const CXXRecordDecl *cxx_record_decl = dyn_cast(record_decl); + if (cxx_record_decl) { + CXXRecordDecl::base_class_const_iterator base_class, base_class_end; + for (base_class = cxx_record_decl->bases_begin(), + base_class_end = cxx_record_decl->bases_end(); + base_class != base_class_end; ++base_class) { + const CXXRecordDecl *base_class_decl = cast( + base_class->getType()->getAs()->getDecl()); + if (RecordHasFields(base_class_decl)) + return true; + } + } + return false; +} + +#pragma mark Objective-C Classes + +CompilerType TypeSystemClang::CreateObjCClass( + llvm::StringRef name, clang::DeclContext *decl_ctx, + OptionalClangModuleID owning_module, bool isForwardDecl, bool isInternal, + ClangASTMetadata *metadata) { + ASTContext &ast = getASTContext(); + assert(!name.empty()); + if (!decl_ctx) + decl_ctx = ast.getTranslationUnitDecl(); + + ObjCInterfaceDecl *decl = ObjCInterfaceDecl::CreateDeserialized(ast, 0); + decl->setDeclContext(decl_ctx); + decl->setDeclName(&ast.Idents.get(name)); + /*isForwardDecl,*/ + decl->setImplicit(isInternal); + SetOwningModule(decl, owning_module); + + if (decl && metadata) + SetMetadata(decl, *metadata); + + return GetType(ast.getObjCInterfaceType(decl)); +} + +static inline bool BaseSpecifierIsEmpty(const CXXBaseSpecifier *b) { + return !TypeSystemClang::RecordHasFields(b->getType()->getAsCXXRecordDecl()); +} + +uint32_t +TypeSystemClang::GetNumBaseClasses(const CXXRecordDecl *cxx_record_decl, + bool omit_empty_base_classes) { + uint32_t num_bases = 0; + if (cxx_record_decl) { + if (omit_empty_base_classes) { + CXXRecordDecl::base_class_const_iterator base_class, base_class_end; + for (base_class = cxx_record_decl->bases_begin(), + base_class_end = cxx_record_decl->bases_end(); + base_class != base_class_end; ++base_class) { + // Skip empty base classes + if (BaseSpecifierIsEmpty(base_class)) + continue; + ++num_bases; + } + } else + num_bases = cxx_record_decl->getNumBases(); + } + return num_bases; +} + +#pragma mark Namespace Declarations + +NamespaceDecl *TypeSystemClang::GetUniqueNamespaceDeclaration( + const char *name, clang::DeclContext *decl_ctx, + OptionalClangModuleID owning_module, bool is_inline) { + NamespaceDecl *namespace_decl = nullptr; + ASTContext &ast = getASTContext(); + TranslationUnitDecl *translation_unit_decl = ast.getTranslationUnitDecl(); + if (!decl_ctx) + decl_ctx = translation_unit_decl; + + if (name) { + IdentifierInfo &identifier_info = ast.Idents.get(name); + DeclarationName decl_name(&identifier_info); + clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name); + for (NamedDecl *decl : result) { + namespace_decl = dyn_cast(decl); + if (namespace_decl) + return namespace_decl; + } + + namespace_decl = + NamespaceDecl::Create(ast, decl_ctx, is_inline, SourceLocation(), + SourceLocation(), &identifier_info, nullptr); + + decl_ctx->addDecl(namespace_decl); + } else { + if (decl_ctx == translation_unit_decl) { + namespace_decl = translation_unit_decl->getAnonymousNamespace(); + if (namespace_decl) + return namespace_decl; + + namespace_decl = + NamespaceDecl::Create(ast, decl_ctx, false, SourceLocation(), + SourceLocation(), nullptr, nullptr); + translation_unit_decl->setAnonymousNamespace(namespace_decl); + translation_unit_decl->addDecl(namespace_decl); + assert(namespace_decl == translation_unit_decl->getAnonymousNamespace()); + } else { + NamespaceDecl *parent_namespace_decl = cast(decl_ctx); + if (parent_namespace_decl) { + namespace_decl = parent_namespace_decl->getAnonymousNamespace(); + if (namespace_decl) + return namespace_decl; + namespace_decl = + NamespaceDecl::Create(ast, decl_ctx, false, SourceLocation(), + SourceLocation(), nullptr, nullptr); + parent_namespace_decl->setAnonymousNamespace(namespace_decl); + parent_namespace_decl->addDecl(namespace_decl); + assert(namespace_decl == + parent_namespace_decl->getAnonymousNamespace()); + } else { + assert(false && "GetUniqueNamespaceDeclaration called with no name and " + "no namespace as decl_ctx"); + } + } + } + // Note: namespaces can span multiple modules, so perhaps this isn't a good + // idea. + SetOwningModule(namespace_decl, owning_module); + + VerifyDecl(namespace_decl); + return namespace_decl; +} + +clang::BlockDecl * +TypeSystemClang::CreateBlockDeclaration(clang::DeclContext *ctx, + OptionalClangModuleID owning_module) { + if (ctx) { + clang::BlockDecl *decl = + clang::BlockDecl::CreateDeserialized(getASTContext(), 0); + decl->setDeclContext(ctx); + ctx->addDecl(decl); + SetOwningModule(decl, owning_module); + return decl; + } + return nullptr; +} + +clang::DeclContext *FindLCABetweenDecls(clang::DeclContext *left, + clang::DeclContext *right, + clang::DeclContext *root) { + if (root == nullptr) + return nullptr; + + std::set path_left; + for (clang::DeclContext *d = left; d != nullptr; d = d->getParent()) + path_left.insert(d); + + for (clang::DeclContext *d = right; d != nullptr; d = d->getParent()) + if (path_left.find(d) != path_left.end()) + return d; + + return nullptr; +} + +clang::UsingDirectiveDecl *TypeSystemClang::CreateUsingDirectiveDeclaration( + clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, + clang::NamespaceDecl *ns_decl) { + if (decl_ctx && ns_decl) { + auto *translation_unit = getASTContext().getTranslationUnitDecl(); + clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create( + getASTContext(), decl_ctx, clang::SourceLocation(), + clang::SourceLocation(), clang::NestedNameSpecifierLoc(), + clang::SourceLocation(), ns_decl, + FindLCABetweenDecls(decl_ctx, ns_decl, + translation_unit)); + decl_ctx->addDecl(using_decl); + SetOwningModule(using_decl, owning_module); + return using_decl; + } + return nullptr; +} + +clang::UsingDecl * +TypeSystemClang::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx, + OptionalClangModuleID owning_module, + clang::NamedDecl *target) { + if (current_decl_ctx && target) { + clang::UsingDecl *using_decl = clang::UsingDecl::Create( + getASTContext(), current_decl_ctx, clang::SourceLocation(), + clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false); + SetOwningModule(using_decl, owning_module); + clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create( + getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl, + target); + SetOwningModule(shadow_decl, owning_module); + using_decl->addShadowDecl(shadow_decl); + current_decl_ctx->addDecl(using_decl); + return using_decl; + } + return nullptr; +} + +clang::VarDecl *TypeSystemClang::CreateVariableDeclaration( + clang::DeclContext *decl_context, OptionalClangModuleID owning_module, + const char *name, clang::QualType type) { + if (decl_context) { + clang::VarDecl *var_decl = + clang::VarDecl::CreateDeserialized(getASTContext(), 0); + var_decl->setDeclContext(decl_context); + if (name && name[0]) + var_decl->setDeclName(&getASTContext().Idents.getOwn(name)); + var_decl->setType(type); + SetOwningModule(var_decl, owning_module); + var_decl->setAccess(clang::AS_public); + decl_context->addDecl(var_decl); + return var_decl; + } + return nullptr; +} + +lldb::opaque_compiler_type_t +TypeSystemClang::GetOpaqueCompilerType(clang::ASTContext *ast, + lldb::BasicType basic_type) { + switch (basic_type) { + case eBasicTypeVoid: + return ast->VoidTy.getAsOpaquePtr(); + case eBasicTypeChar: + return ast->CharTy.getAsOpaquePtr(); + case eBasicTypeSignedChar: + return ast->SignedCharTy.getAsOpaquePtr(); + case eBasicTypeUnsignedChar: + return ast->UnsignedCharTy.getAsOpaquePtr(); + case eBasicTypeWChar: + return ast->getWCharType().getAsOpaquePtr(); + case eBasicTypeSignedWChar: + return ast->getSignedWCharType().getAsOpaquePtr(); + case eBasicTypeUnsignedWChar: + return ast->getUnsignedWCharType().getAsOpaquePtr(); + case eBasicTypeChar16: + return ast->Char16Ty.getAsOpaquePtr(); + case eBasicTypeChar32: + return ast->Char32Ty.getAsOpaquePtr(); + case eBasicTypeShort: + return ast->ShortTy.getAsOpaquePtr(); + case eBasicTypeUnsignedShort: + return ast->UnsignedShortTy.getAsOpaquePtr(); + case eBasicTypeInt: + return ast->IntTy.getAsOpaquePtr(); + case eBasicTypeUnsignedInt: + return ast->UnsignedIntTy.getAsOpaquePtr(); + case eBasicTypeLong: + return ast->LongTy.getAsOpaquePtr(); + case eBasicTypeUnsignedLong: + return ast->UnsignedLongTy.getAsOpaquePtr(); + case eBasicTypeLongLong: + return ast->LongLongTy.getAsOpaquePtr(); + case eBasicTypeUnsignedLongLong: + return ast->UnsignedLongLongTy.getAsOpaquePtr(); + case eBasicTypeInt128: + return ast->Int128Ty.getAsOpaquePtr(); + case eBasicTypeUnsignedInt128: + return ast->UnsignedInt128Ty.getAsOpaquePtr(); + case eBasicTypeBool: + return ast->BoolTy.getAsOpaquePtr(); + case eBasicTypeHalf: + return ast->HalfTy.getAsOpaquePtr(); + case eBasicTypeFloat: + return ast->FloatTy.getAsOpaquePtr(); + case eBasicTypeDouble: + return ast->DoubleTy.getAsOpaquePtr(); + case eBasicTypeLongDouble: + return ast->LongDoubleTy.getAsOpaquePtr(); + case eBasicTypeFloatComplex: + return ast->FloatComplexTy.getAsOpaquePtr(); + case eBasicTypeDoubleComplex: + return ast->DoubleComplexTy.getAsOpaquePtr(); + case eBasicTypeLongDoubleComplex: + return ast->LongDoubleComplexTy.getAsOpaquePtr(); + case eBasicTypeObjCID: + return ast->getObjCIdType().getAsOpaquePtr(); + case eBasicTypeObjCClass: + return ast->getObjCClassType().getAsOpaquePtr(); + case eBasicTypeObjCSel: + return ast->getObjCSelType().getAsOpaquePtr(); + case eBasicTypeNullPtr: + return ast->NullPtrTy.getAsOpaquePtr(); + default: + return nullptr; + } +} + +#pragma mark Function Types + +clang::DeclarationName +TypeSystemClang::GetDeclarationName(const char *name, + const CompilerType &function_clang_type) { + if (!name || !name[0]) + return clang::DeclarationName(); + + clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS; + if (!IsOperator(name, op_kind) || op_kind == clang::NUM_OVERLOADED_OPERATORS) + return DeclarationName(&getASTContext().Idents.get( + name)); // Not operator, but a regular function. + + // Check the number of operator parameters. Sometimes we have seen bad DWARF + // that doesn't correctly describe operators and if we try to create a method + // and add it to the class, clang will assert and crash, so we need to make + // sure things are acceptable. + clang::QualType method_qual_type(ClangUtil::GetQualType(function_clang_type)); + const clang::FunctionProtoType *function_type = + llvm::dyn_cast(method_qual_type.getTypePtr()); + if (function_type == nullptr) + return clang::DeclarationName(); + + const bool is_method = false; + const unsigned int num_params = function_type->getNumParams(); + if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount( + is_method, op_kind, num_params)) + return clang::DeclarationName(); + + return getASTContext().DeclarationNames.getCXXOperatorName(op_kind); +} + +FunctionDecl *TypeSystemClang::CreateFunctionDeclaration( + clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, + const char *name, const CompilerType &function_clang_type, int storage, + bool is_inline) { + FunctionDecl *func_decl = nullptr; + ASTContext &ast = getASTContext(); + if (!decl_ctx) + decl_ctx = ast.getTranslationUnitDecl(); + + const bool hasWrittenPrototype = true; + const bool isConstexprSpecified = false; + + clang::DeclarationName declarationName = + GetDeclarationName(name, function_clang_type); + func_decl = FunctionDecl::CreateDeserialized(ast, 0); + func_decl->setDeclContext(decl_ctx); + func_decl->setDeclName(declarationName); + func_decl->setType(ClangUtil::GetQualType(function_clang_type)); + func_decl->setStorageClass(static_cast(storage)); + func_decl->setInlineSpecified(is_inline); + func_decl->setHasWrittenPrototype(hasWrittenPrototype); + func_decl->setConstexprKind(isConstexprSpecified ? CSK_constexpr + : CSK_unspecified); + SetOwningModule(func_decl, owning_module); + if (func_decl) + decl_ctx->addDecl(func_decl); + + VerifyDecl(func_decl); + + return func_decl; +} + +CompilerType +TypeSystemClang::CreateFunctionType(const CompilerType &result_type, + const CompilerType *args, unsigned num_args, + bool is_variadic, unsigned type_quals, + clang::CallingConv cc) { + if (!result_type || !ClangUtil::IsClangType(result_type)) + return CompilerType(); // invalid return type + + std::vector qual_type_args; + if (num_args > 0 && args == nullptr) + return CompilerType(); // invalid argument array passed in + + // Verify that all arguments are valid and the right type + for (unsigned i = 0; i < num_args; ++i) { + if (args[i]) { + // Make sure we have a clang type in args[i] and not a type from another + // language whose name might match + const bool is_clang_type = ClangUtil::IsClangType(args[i]); + lldbassert(is_clang_type); + if (is_clang_type) + qual_type_args.push_back(ClangUtil::GetQualType(args[i])); + else + return CompilerType(); // invalid argument type (must be a clang type) + } else + return CompilerType(); // invalid argument type (empty) + } + + // 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 = clang::Qualifiers::fromFastMask(type_quals); + proto_info.RefQualifier = RQ_None; + + return GetType(getASTContext().getFunctionType( + ClangUtil::GetQualType(result_type), qual_type_args, proto_info)); +} + +ParmVarDecl *TypeSystemClang::CreateParameterDeclaration( + clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, + const char *name, const CompilerType ¶m_type, int storage, + bool add_decl) { + ASTContext &ast = getASTContext(); + auto *decl = ParmVarDecl::CreateDeserialized(ast, 0); + decl->setDeclContext(decl_ctx); + if (name && name[0]) + decl->setDeclName(&ast.Idents.get(name)); + decl->setType(ClangUtil::GetQualType(param_type)); + decl->setStorageClass(static_cast(storage)); + SetOwningModule(decl, owning_module); + if (add_decl) + decl_ctx->addDecl(decl); + + return decl; +} + +void TypeSystemClang::SetFunctionParameters(FunctionDecl *function_decl, + ParmVarDecl **params, + unsigned num_params) { + if (function_decl) + function_decl->setParams(ArrayRef(params, num_params)); +} + +CompilerType +TypeSystemClang::CreateBlockPointerType(const CompilerType &function_type) { + QualType block_type = m_ast_up->getBlockPointerType( + clang::QualType::getFromOpaquePtr(function_type.GetOpaqueQualType())); + + return GetType(block_type); +} + +#pragma mark Array Types + +CompilerType TypeSystemClang::CreateArrayType(const CompilerType &element_type, + size_t element_count, + bool is_vector) { + if (element_type.IsValid()) { + ASTContext &ast = getASTContext(); + + if (is_vector) { + return GetType(ast.getExtVectorType(ClangUtil::GetQualType(element_type), + element_count)); + } else { + + llvm::APInt ap_element_count(64, element_count); + if (element_count == 0) { + return GetType(ast.getIncompleteArrayType( + ClangUtil::GetQualType(element_type), clang::ArrayType::Normal, 0)); + } else { + return GetType(ast.getConstantArrayType( + ClangUtil::GetQualType(element_type), ap_element_count, nullptr, + clang::ArrayType::Normal, 0)); + } + } + } + return CompilerType(); +} + +CompilerType TypeSystemClang::CreateStructForIdentifier( + ConstString type_name, + const std::initializer_list> + &type_fields, + bool packed) { + CompilerType type; + if (!type_name.IsEmpty() && + (type = GetTypeForIdentifier(type_name)) + .IsValid()) { + lldbassert(0 && "Trying to create a type for an existing name"); + return type; + } + + type = CreateRecordType(nullptr, OptionalClangModuleID(), lldb::eAccessPublic, + type_name.GetCString(), clang::TTK_Struct, + lldb::eLanguageTypeC); + StartTagDeclarationDefinition(type); + for (const auto &field : type_fields) + AddFieldToRecordType(type, field.first, field.second, lldb::eAccessPublic, + 0); + if (packed) + SetIsPacked(type); + CompleteTagDeclarationDefinition(type); + return type; +} + +CompilerType TypeSystemClang::GetOrCreateStructForIdentifier( + ConstString type_name, + const std::initializer_list> + &type_fields, + bool packed) { + CompilerType type; + if ((type = GetTypeForIdentifier(type_name)).IsValid()) + return type; + + return CreateStructForIdentifier(type_name, type_fields, packed); +} + +#pragma mark Enumeration Types + +CompilerType TypeSystemClang::CreateEnumerationType( + const char *name, clang::DeclContext *decl_ctx, + OptionalClangModuleID owning_module, const Declaration &decl, + const CompilerType &integer_clang_type, bool is_scoped) { + // TODO: Do something intelligent with the Declaration object passed in + // like maybe filling in the SourceLocation with it... + ASTContext &ast = getASTContext(); + + // TODO: ask about these... + // const bool IsFixed = false; + EnumDecl *enum_decl = EnumDecl::CreateDeserialized(ast, 0); + enum_decl->setDeclContext(decl_ctx); + if (name && name[0]) + enum_decl->setDeclName(&ast.Idents.get(name)); + enum_decl->setScoped(is_scoped); + enum_decl->setScopedUsingClassTag(is_scoped); + enum_decl->setFixed(false); + SetOwningModule(enum_decl, owning_module); + 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)); + + enum_decl->setAccess(AS_public); // TODO respect what's in the debug info + + return GetType(ast.getTagDeclType(enum_decl)); + } + return CompilerType(); +} + +CompilerType TypeSystemClang::GetIntTypeFromBitSize(size_t bit_size, + bool is_signed) { + clang::ASTContext &ast = getASTContext(); + + if (is_signed) { + if (bit_size == ast.getTypeSize(ast.SignedCharTy)) + return GetType(ast.SignedCharTy); + + if (bit_size == ast.getTypeSize(ast.ShortTy)) + return GetType(ast.ShortTy); + + if (bit_size == ast.getTypeSize(ast.IntTy)) + return GetType(ast.IntTy); + + if (bit_size == ast.getTypeSize(ast.LongTy)) + return GetType(ast.LongTy); + + if (bit_size == ast.getTypeSize(ast.LongLongTy)) + return GetType(ast.LongLongTy); + + if (bit_size == ast.getTypeSize(ast.Int128Ty)) + return GetType(ast.Int128Ty); + } else { + if (bit_size == ast.getTypeSize(ast.UnsignedCharTy)) + return GetType(ast.UnsignedCharTy); + + if (bit_size == ast.getTypeSize(ast.UnsignedShortTy)) + return GetType(ast.UnsignedShortTy); + + if (bit_size == ast.getTypeSize(ast.UnsignedIntTy)) + return GetType(ast.UnsignedIntTy); + + if (bit_size == ast.getTypeSize(ast.UnsignedLongTy)) + return GetType(ast.UnsignedLongTy); + + if (bit_size == ast.getTypeSize(ast.UnsignedLongLongTy)) + return GetType(ast.UnsignedLongLongTy); + + if (bit_size == ast.getTypeSize(ast.UnsignedInt128Ty)) + return GetType(ast.UnsignedInt128Ty); + } + return CompilerType(); +} + +CompilerType TypeSystemClang::GetPointerSizedIntType(bool is_signed) { + return GetIntTypeFromBitSize( + getASTContext().getTypeSize(getASTContext().VoidPtrTy), is_signed); +} + +void TypeSystemClang::DumpDeclContextHiearchy(clang::DeclContext *decl_ctx) { + if (decl_ctx) { + DumpDeclContextHiearchy(decl_ctx->getParent()); + + clang::NamedDecl *named_decl = llvm::dyn_cast(decl_ctx); + if (named_decl) { + printf("%20s: %s\n", decl_ctx->getDeclKindName(), + named_decl->getDeclName().getAsString().c_str()); + } else { + printf("%20s\n", decl_ctx->getDeclKindName()); + } + } +} + +void TypeSystemClang::DumpDeclHiearchy(clang::Decl *decl) { + if (decl == nullptr) + return; + DumpDeclContextHiearchy(decl->getDeclContext()); + + clang::RecordDecl *record_decl = llvm::dyn_cast(decl); + if (record_decl) { + printf("%20s: %s%s\n", decl->getDeclKindName(), + record_decl->getDeclName().getAsString().c_str(), + record_decl->isInjectedClassName() ? " (injected class name)" : ""); + + } else { + clang::NamedDecl *named_decl = llvm::dyn_cast(decl); + if (named_decl) { + printf("%20s: %s\n", decl->getDeclKindName(), + named_decl->getDeclName().getAsString().c_str()); + } else { + printf("%20s\n", decl->getDeclKindName()); + } + } +} + +bool TypeSystemClang::DeclsAreEquivalent(clang::Decl *lhs_decl, + clang::Decl *rhs_decl) { + if (lhs_decl && rhs_decl) { + // Make sure the decl kinds match first + const clang::Decl::Kind lhs_decl_kind = lhs_decl->getKind(); + const clang::Decl::Kind rhs_decl_kind = rhs_decl->getKind(); + + if (lhs_decl_kind == rhs_decl_kind) { + // Now check that the decl contexts kinds are all equivalent before we + // have to check any names of the decl contexts... + clang::DeclContext *lhs_decl_ctx = lhs_decl->getDeclContext(); + clang::DeclContext *rhs_decl_ctx = rhs_decl->getDeclContext(); + if (lhs_decl_ctx && rhs_decl_ctx) { + while (true) { + if (lhs_decl_ctx && rhs_decl_ctx) { + const clang::Decl::Kind lhs_decl_ctx_kind = + lhs_decl_ctx->getDeclKind(); + const clang::Decl::Kind rhs_decl_ctx_kind = + rhs_decl_ctx->getDeclKind(); + if (lhs_decl_ctx_kind == rhs_decl_ctx_kind) { + lhs_decl_ctx = lhs_decl_ctx->getParent(); + rhs_decl_ctx = rhs_decl_ctx->getParent(); + + if (lhs_decl_ctx == nullptr && rhs_decl_ctx == nullptr) + break; + } else + return false; + } else + return false; + } + + // Now make sure the name of the decls match + clang::NamedDecl *lhs_named_decl = + llvm::dyn_cast(lhs_decl); + clang::NamedDecl *rhs_named_decl = + llvm::dyn_cast(rhs_decl); + if (lhs_named_decl && rhs_named_decl) { + clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName(); + clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName(); + if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) { + if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString()) + return false; + } else + return false; + } else + return false; + + // We know that the decl context kinds all match, so now we need to + // make sure the names match as well + lhs_decl_ctx = lhs_decl->getDeclContext(); + rhs_decl_ctx = rhs_decl->getDeclContext(); + while (true) { + switch (lhs_decl_ctx->getDeclKind()) { + case clang::Decl::TranslationUnit: + // We don't care about the translation unit names + return true; + default: { + clang::NamedDecl *lhs_named_decl = + llvm::dyn_cast(lhs_decl_ctx); + clang::NamedDecl *rhs_named_decl = + llvm::dyn_cast(rhs_decl_ctx); + if (lhs_named_decl && rhs_named_decl) { + clang::DeclarationName lhs_decl_name = + lhs_named_decl->getDeclName(); + clang::DeclarationName rhs_decl_name = + rhs_named_decl->getDeclName(); + if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) { + if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString()) + return false; + } else + return false; + } else + return false; + } break; + } + lhs_decl_ctx = lhs_decl_ctx->getParent(); + rhs_decl_ctx = rhs_decl_ctx->getParent(); + } + } + } + } + return false; +} +bool TypeSystemClang::GetCompleteDecl(clang::ASTContext *ast, + clang::Decl *decl) { + if (!decl) + return false; + + ExternalASTSource *ast_source = ast->getExternalSource(); + + if (!ast_source) + return false; + + if (clang::TagDecl *tag_decl = llvm::dyn_cast(decl)) { + if (tag_decl->isCompleteDefinition()) + return true; + + if (!tag_decl->hasExternalLexicalStorage()) + return false; + + ast_source->CompleteType(tag_decl); + + return !tag_decl->getTypeForDecl()->isIncompleteType(); + } else if (clang::ObjCInterfaceDecl *objc_interface_decl = + llvm::dyn_cast(decl)) { + if (objc_interface_decl->getDefinition()) + return true; + + if (!objc_interface_decl->hasExternalLexicalStorage()) + return false; + + ast_source->CompleteType(objc_interface_decl); + + return !objc_interface_decl->getTypeForDecl()->isIncompleteType(); + } else { + return false; + } +} + +void TypeSystemClang::SetMetadataAsUserID(const clang::Decl *decl, + user_id_t user_id) { + ClangASTMetadata meta_data; + meta_data.SetUserID(user_id); + SetMetadata(decl, meta_data); +} + +void TypeSystemClang::SetMetadataAsUserID(const clang::Type *type, + user_id_t user_id) { + ClangASTMetadata meta_data; + meta_data.SetUserID(user_id); + SetMetadata(type, meta_data); +} + +void TypeSystemClang::SetMetadata(const clang::Decl *object, + ClangASTMetadata &metadata) { + m_decl_metadata[object] = metadata; +} + +void TypeSystemClang::SetMetadata(const clang::Type *object, + ClangASTMetadata &metadata) { + m_type_metadata[object] = metadata; +} + +ClangASTMetadata *TypeSystemClang::GetMetadata(const clang::Decl *object) { + auto It = m_decl_metadata.find(object); + if (It != m_decl_metadata.end()) + return &It->second; + return nullptr; +} + +ClangASTMetadata *TypeSystemClang::GetMetadata(const clang::Type *object) { + auto It = m_type_metadata.find(object); + if (It != m_type_metadata.end()) + return &It->second; + return nullptr; +} + +bool TypeSystemClang::SetTagTypeKind(clang::QualType tag_qual_type, + int kind) const { + const clang::Type *clang_type = tag_qual_type.getTypePtr(); + if (clang_type) { + const clang::TagType *tag_type = llvm::dyn_cast(clang_type); + if (tag_type) { + clang::TagDecl *tag_decl = + llvm::dyn_cast(tag_type->getDecl()); + if (tag_decl) { + tag_decl->setTagKind((clang::TagDecl::TagKind)kind); + return true; + } + } + } + return false; +} + +bool TypeSystemClang::SetDefaultAccessForRecordFields( + clang::RecordDecl *record_decl, int default_accessibility, + int *assigned_accessibilities, size_t num_assigned_accessibilities) { + if (record_decl) { + uint32_t field_idx; + clang::RecordDecl::field_iterator field, field_end; + for (field = record_decl->field_begin(), + field_end = record_decl->field_end(), field_idx = 0; + field != field_end; ++field, ++field_idx) { + // If no accessibility was assigned, assign the correct one + if (field_idx < num_assigned_accessibilities && + assigned_accessibilities[field_idx] == clang::AS_none) + field->setAccess((clang::AccessSpecifier)default_accessibility); + } + return true; + } + return false; +} + +clang::DeclContext * +TypeSystemClang::GetDeclContextForType(const CompilerType &type) { + return GetDeclContextForType(ClangUtil::GetQualType(type)); +} + +/// Aggressively desugar the provided type, skipping past various kinds of +/// syntactic sugar and other constructs one typically wants to ignore. +/// The \p mask argument allows one to skip certain kinds of simplifications, +/// when one wishes to handle a certain kind of type directly. +static QualType +RemoveWrappingTypes(QualType type, ArrayRef mask = {}) { + while (true) { + if (find(mask, type->getTypeClass()) != mask.end()) + return type; + switch (type->getTypeClass()) { + // This is not fully correct as _Atomic is more than sugar, but it is + // sufficient for the purposes we care about. + case clang::Type::Atomic: + type = cast(type)->getValueType(); + break; + case clang::Type::Auto: + case clang::Type::Decltype: + case clang::Type::Elaborated: + case clang::Type::Paren: + case clang::Type::Typedef: + case clang::Type::TypeOf: + case clang::Type::TypeOfExpr: + type = type->getLocallyUnqualifiedSingleStepDesugaredType(); + break; + default: + return type; + } + } +} + +clang::DeclContext * +TypeSystemClang::GetDeclContextForType(clang::QualType type) { + if (type.isNull()) + return nullptr; + + clang::QualType qual_type = RemoveWrappingTypes(type.getCanonicalType()); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::ObjCInterface: + return llvm::cast(qual_type.getTypePtr()) + ->getInterface(); + case clang::Type::ObjCObjectPointer: + return GetDeclContextForType( + llvm::cast(qual_type.getTypePtr()) + ->getPointeeType()); + case clang::Type::Record: + return llvm::cast(qual_type)->getDecl(); + case clang::Type::Enum: + return llvm::cast(qual_type)->getDecl(); + default: + break; + } + // No DeclContext in this type... + return nullptr; +} + +static bool GetCompleteQualType(clang::ASTContext *ast, + clang::QualType qual_type, + bool allow_completion = true) { + qual_type = RemoveWrappingTypes(qual_type); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::ConstantArray: + case clang::Type::IncompleteArray: + case clang::Type::VariableArray: { + const clang::ArrayType *array_type = + llvm::dyn_cast(qual_type.getTypePtr()); + + if (array_type) + return GetCompleteQualType(ast, array_type->getElementType(), + allow_completion); + } break; + case clang::Type::Record: { + clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) { + if (cxx_record_decl->hasExternalLexicalStorage()) { + const bool is_complete = cxx_record_decl->isCompleteDefinition(); + const bool fields_loaded = + cxx_record_decl->hasLoadedFieldsFromExternalStorage(); + if (is_complete && fields_loaded) + return true; + + if (!allow_completion) + return false; + + // Call the field_begin() accessor to for it to use the external source + // to load the fields... + clang::ExternalASTSource *external_ast_source = + ast->getExternalSource(); + if (external_ast_source) { + external_ast_source->CompleteType(cxx_record_decl); + if (cxx_record_decl->isCompleteDefinition()) { + cxx_record_decl->field_begin(); + cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true); + } + } + } + } + const clang::TagType *tag_type = + llvm::cast(qual_type.getTypePtr()); + return !tag_type->isIncompleteType(); + } break; + + case clang::Type::Enum: { + const clang::TagType *tag_type = + llvm::dyn_cast(qual_type.getTypePtr()); + if (tag_type) { + clang::TagDecl *tag_decl = tag_type->getDecl(); + if (tag_decl) { + if (tag_decl->getDefinition()) + return true; + + if (!allow_completion) + return false; + + if (tag_decl->hasExternalLexicalStorage()) { + if (ast) { + clang::ExternalASTSource *external_ast_source = + ast->getExternalSource(); + if (external_ast_source) { + external_ast_source->CompleteType(tag_decl); + return !tag_type->isIncompleteType(); + } + } + } + return false; + } + } + + } break; + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: { + const clang::ObjCObjectType *objc_class_type = + llvm::dyn_cast(qual_type); + if (objc_class_type) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + // We currently can't complete objective C types through the newly added + // ASTContext because it only supports TagDecl objects right now... + if (class_interface_decl) { + if (class_interface_decl->getDefinition()) + return true; + + if (!allow_completion) + return false; + + if (class_interface_decl->hasExternalLexicalStorage()) { + if (ast) { + clang::ExternalASTSource *external_ast_source = + ast->getExternalSource(); + if (external_ast_source) { + external_ast_source->CompleteType(class_interface_decl); + return !objc_class_type->isIncompleteType(); + } + } + } + return false; + } + } + } break; + + case clang::Type::Attributed: + return GetCompleteQualType( + ast, llvm::cast(qual_type)->getModifiedType(), + allow_completion); + + default: + break; + } + + return true; +} + +static clang::ObjCIvarDecl::AccessControl +ConvertAccessTypeToObjCIvarAccessControl(AccessType access) { + switch (access) { + case eAccessNone: + return clang::ObjCIvarDecl::None; + case eAccessPublic: + return clang::ObjCIvarDecl::Public; + case eAccessPrivate: + return clang::ObjCIvarDecl::Private; + case eAccessProtected: + return clang::ObjCIvarDecl::Protected; + case eAccessPackage: + return clang::ObjCIvarDecl::Package; + } + return clang::ObjCIvarDecl::None; +} + +// Tests + +#ifndef NDEBUG +bool TypeSystemClang::Verify(lldb::opaque_compiler_type_t type) { + return !type || llvm::isa(GetQualType(type).getTypePtr()); +} +#endif + +bool TypeSystemClang::IsAggregateType(lldb::opaque_compiler_type_t type) { + clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::IncompleteArray: + case clang::Type::VariableArray: + case clang::Type::ConstantArray: + case clang::Type::ExtVector: + case clang::Type::Vector: + case clang::Type::Record: + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + return true; + default: + break; + } + // The clang type does have a value + return false; +} + +bool TypeSystemClang::IsAnonymousType(lldb::opaque_compiler_type_t type) { + clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: { + if (const clang::RecordType *record_type = + llvm::dyn_cast_or_null( + qual_type.getTypePtrOrNull())) { + if (const clang::RecordDecl *record_decl = record_type->getDecl()) { + return record_decl->isAnonymousStructOrUnion(); + } + } + break; + } + default: + break; + } + // The clang type does have a value + return false; +} + +bool TypeSystemClang::IsArrayType(lldb::opaque_compiler_type_t type, + CompilerType *element_type_ptr, + uint64_t *size, bool *is_incomplete) { + clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + default: + break; + + case clang::Type::ConstantArray: + if (element_type_ptr) + element_type_ptr->SetCompilerType( + this, llvm::cast(qual_type) + ->getElementType() + .getAsOpaquePtr()); + if (size) + *size = llvm::cast(qual_type) + ->getSize() + .getLimitedValue(ULLONG_MAX); + if (is_incomplete) + *is_incomplete = false; + return true; + + case clang::Type::IncompleteArray: + if (element_type_ptr) + element_type_ptr->SetCompilerType( + this, llvm::cast(qual_type) + ->getElementType() + .getAsOpaquePtr()); + if (size) + *size = 0; + if (is_incomplete) + *is_incomplete = true; + return true; + + case clang::Type::VariableArray: + if (element_type_ptr) + element_type_ptr->SetCompilerType( + this, llvm::cast(qual_type) + ->getElementType() + .getAsOpaquePtr()); + if (size) + *size = 0; + if (is_incomplete) + *is_incomplete = false; + return true; + + case clang::Type::DependentSizedArray: + if (element_type_ptr) + element_type_ptr->SetCompilerType( + this, llvm::cast(qual_type) + ->getElementType() + .getAsOpaquePtr()); + if (size) + *size = 0; + if (is_incomplete) + *is_incomplete = false; + return true; + } + if (element_type_ptr) + element_type_ptr->Clear(); + if (size) + *size = 0; + if (is_incomplete) + *is_incomplete = false; + return false; +} + +bool TypeSystemClang::IsVectorType(lldb::opaque_compiler_type_t type, + CompilerType *element_type, uint64_t *size) { + clang::QualType qual_type(GetCanonicalQualType(type)); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Vector: { + const clang::VectorType *vector_type = + qual_type->getAs(); + if (vector_type) { + if (size) + *size = vector_type->getNumElements(); + if (element_type) + *element_type = GetType(vector_type->getElementType()); + } + return true; + } break; + case clang::Type::ExtVector: { + const clang::ExtVectorType *ext_vector_type = + qual_type->getAs(); + if (ext_vector_type) { + if (size) + *size = ext_vector_type->getNumElements(); + if (element_type) + *element_type = + CompilerType(this, ext_vector_type->getElementType().getAsOpaquePtr()); + } + return true; + } + default: + break; + } + return false; +} + +bool TypeSystemClang::IsRuntimeGeneratedType( + lldb::opaque_compiler_type_t type) { + clang::DeclContext *decl_ctx = GetDeclContextForType(GetQualType(type)); + if (!decl_ctx) + return false; + + if (!llvm::isa(decl_ctx)) + return false; + + clang::ObjCInterfaceDecl *result_iface_decl = + llvm::dyn_cast(decl_ctx); + + ClangASTMetadata *ast_metadata = GetMetadata(result_iface_decl); + if (!ast_metadata) + return false; + return (ast_metadata->GetISAPtr() != 0); +} + +bool TypeSystemClang::IsCharType(lldb::opaque_compiler_type_t type) { + return GetQualType(type).getUnqualifiedType()->isCharType(); +} + +bool TypeSystemClang::IsCompleteType(lldb::opaque_compiler_type_t type) { + const bool allow_completion = false; + return GetCompleteQualType(&getASTContext(), GetQualType(type), + allow_completion); +} + +bool TypeSystemClang::IsConst(lldb::opaque_compiler_type_t type) { + return GetQualType(type).isConstQualified(); +} + +bool TypeSystemClang::IsCStringType(lldb::opaque_compiler_type_t type, + uint32_t &length) { + CompilerType pointee_or_element_clang_type; + length = 0; + Flags type_flags(GetTypeInfo(type, &pointee_or_element_clang_type)); + + if (!pointee_or_element_clang_type.IsValid()) + return false; + + if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer)) { + if (pointee_or_element_clang_type.IsCharType()) { + if (type_flags.Test(eTypeIsArray)) { + // We know the size of the array and it could be a C string since it is + // an array of characters + length = llvm::cast( + GetCanonicalQualType(type).getTypePtr()) + ->getSize() + .getLimitedValue(); + } + return true; + } + } + return false; +} + +bool TypeSystemClang::IsFunctionType(lldb::opaque_compiler_type_t type, + bool *is_variadic_ptr) { + if (type) { + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + + if (qual_type->isFunctionType()) { + if (is_variadic_ptr) { + const clang::FunctionProtoType *function_proto_type = + llvm::dyn_cast(qual_type.getTypePtr()); + if (function_proto_type) + *is_variadic_ptr = function_proto_type->isVariadic(); + else + *is_variadic_ptr = false; + } + return true; + } + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + default: + break; + case clang::Type::LValueReference: + case clang::Type::RValueReference: { + const clang::ReferenceType *reference_type = + llvm::cast(qual_type.getTypePtr()); + if (reference_type) + return IsFunctionType(reference_type->getPointeeType().getAsOpaquePtr(), + nullptr); + } break; + } + } + return false; +} + +// Used to detect "Homogeneous Floating-point Aggregates" +uint32_t +TypeSystemClang::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, + CompilerType *base_type_ptr) { + if (!type) + return 0; + + clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: + if (GetCompleteType(type)) { + const clang::CXXRecordDecl *cxx_record_decl = + qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) { + if (cxx_record_decl->getNumBases() || cxx_record_decl->isDynamicClass()) + return 0; + } + const clang::RecordType *record_type = + llvm::cast(qual_type.getTypePtr()); + if (record_type) { + const clang::RecordDecl *record_decl = record_type->getDecl(); + if (record_decl) { + // We are looking for a structure that contains only floating point + // types + clang::RecordDecl::field_iterator field_pos, + field_end = record_decl->field_end(); + uint32_t num_fields = 0; + bool is_hva = false; + bool is_hfa = false; + clang::QualType base_qual_type; + uint64_t base_bitwidth = 0; + for (field_pos = record_decl->field_begin(); field_pos != field_end; + ++field_pos) { + clang::QualType field_qual_type = field_pos->getType(); + uint64_t field_bitwidth = getASTContext().getTypeSize(qual_type); + if (field_qual_type->isFloatingType()) { + if (field_qual_type->isComplexType()) + return 0; + else { + if (num_fields == 0) + base_qual_type = field_qual_type; + else { + if (is_hva) + return 0; + is_hfa = true; + if (field_qual_type.getTypePtr() != + base_qual_type.getTypePtr()) + return 0; + } + } + } else if (field_qual_type->isVectorType() || + field_qual_type->isExtVectorType()) { + if (num_fields == 0) { + base_qual_type = field_qual_type; + base_bitwidth = field_bitwidth; + } else { + if (is_hfa) + return 0; + is_hva = true; + if (base_bitwidth != field_bitwidth) + return 0; + if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr()) + return 0; + } + } else + return 0; + ++num_fields; + } + if (base_type_ptr) + *base_type_ptr = CompilerType(this, base_qual_type.getAsOpaquePtr()); + return num_fields; + } + } + } + break; + + default: + break; + } + return 0; +} + +size_t TypeSystemClang::GetNumberOfFunctionArguments( + lldb::opaque_compiler_type_t type) { + if (type) { + clang::QualType qual_type(GetCanonicalQualType(type)); + const clang::FunctionProtoType *func = + llvm::dyn_cast(qual_type.getTypePtr()); + if (func) + return func->getNumParams(); + } + return 0; +} + +CompilerType +TypeSystemClang::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, + const size_t index) { + if (type) { + clang::QualType qual_type(GetQualType(type)); + const clang::FunctionProtoType *func = + llvm::dyn_cast(qual_type.getTypePtr()); + if (func) { + if (index < func->getNumParams()) + return CompilerType(this, func->getParamType(index).getAsOpaquePtr()); + } + } + return CompilerType(); +} + +bool TypeSystemClang::IsFunctionPointerType(lldb::opaque_compiler_type_t type) { + if (type) { + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + + if (qual_type->isFunctionPointerType()) + return true; + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + default: + break; + + case clang::Type::LValueReference: + case clang::Type::RValueReference: { + const clang::ReferenceType *reference_type = + llvm::cast(qual_type.getTypePtr()); + if (reference_type) + return IsFunctionPointerType( + reference_type->getPointeeType().getAsOpaquePtr()); + } break; + } + } + return false; +} + +bool TypeSystemClang::IsBlockPointerType( + lldb::opaque_compiler_type_t type, + CompilerType *function_pointer_type_ptr) { + if (type) { + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + + if (qual_type->isBlockPointerType()) { + if (function_pointer_type_ptr) { + const clang::BlockPointerType *block_pointer_type = + qual_type->getAs(); + QualType pointee_type = block_pointer_type->getPointeeType(); + QualType function_pointer_type = m_ast_up->getPointerType(pointee_type); + *function_pointer_type_ptr = + CompilerType(this, function_pointer_type.getAsOpaquePtr()); + } + return true; + } + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + default: + break; + + case clang::Type::LValueReference: + case clang::Type::RValueReference: { + const clang::ReferenceType *reference_type = + llvm::cast(qual_type.getTypePtr()); + if (reference_type) + return IsBlockPointerType( + reference_type->getPointeeType().getAsOpaquePtr(), + function_pointer_type_ptr); + } break; + } + } + return false; +} + +bool TypeSystemClang::IsIntegerType(lldb::opaque_compiler_type_t type, + bool &is_signed) { + if (!type) + return false; + + clang::QualType qual_type(GetCanonicalQualType(type)); + const clang::BuiltinType *builtin_type = + llvm::dyn_cast(qual_type->getCanonicalTypeInternal()); + + if (builtin_type) { + if (builtin_type->isInteger()) { + is_signed = builtin_type->isSignedInteger(); + return true; + } + } + + return false; +} + +bool TypeSystemClang::IsEnumerationType(lldb::opaque_compiler_type_t type, + bool &is_signed) { + if (type) { + const clang::EnumType *enum_type = llvm::dyn_cast( + GetCanonicalQualType(type)->getCanonicalTypeInternal()); + + if (enum_type) { + IsIntegerType(enum_type->getDecl()->getIntegerType().getAsOpaquePtr(), + is_signed); + return true; + } + } + + return false; +} + +bool TypeSystemClang::IsPointerType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type) { + if (type) { + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Builtin: + switch (llvm::cast(qual_type)->getKind()) { + default: + break; + case clang::BuiltinType::ObjCId: + case clang::BuiltinType::ObjCClass: + return true; + } + return false; + case clang::Type::ObjCObjectPointer: + if (pointee_type) + pointee_type->SetCompilerType( + this, llvm::cast(qual_type) + ->getPointeeType() + .getAsOpaquePtr()); + return true; + case clang::Type::BlockPointer: + if (pointee_type) + pointee_type->SetCompilerType( + this, llvm::cast(qual_type) + ->getPointeeType() + .getAsOpaquePtr()); + return true; + case clang::Type::Pointer: + if (pointee_type) + pointee_type->SetCompilerType(this, + llvm::cast(qual_type) + ->getPointeeType() + .getAsOpaquePtr()); + return true; + case clang::Type::MemberPointer: + if (pointee_type) + pointee_type->SetCompilerType( + this, llvm::cast(qual_type) + ->getPointeeType() + .getAsOpaquePtr()); + return true; + default: + break; + } + } + if (pointee_type) + pointee_type->Clear(); + return false; +} + +bool TypeSystemClang::IsPointerOrReferenceType( + lldb::opaque_compiler_type_t type, CompilerType *pointee_type) { + if (type) { + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Builtin: + switch (llvm::cast(qual_type)->getKind()) { + default: + break; + case clang::BuiltinType::ObjCId: + case clang::BuiltinType::ObjCClass: + return true; + } + return false; + case clang::Type::ObjCObjectPointer: + if (pointee_type) + pointee_type->SetCompilerType( + this, llvm::cast(qual_type) + ->getPointeeType().getAsOpaquePtr()); + return true; + case clang::Type::BlockPointer: + if (pointee_type) + pointee_type->SetCompilerType( + this, llvm::cast(qual_type) + ->getPointeeType() + .getAsOpaquePtr()); + return true; + case clang::Type::Pointer: + if (pointee_type) + pointee_type->SetCompilerType(this, + llvm::cast(qual_type) + ->getPointeeType() + .getAsOpaquePtr()); + return true; + case clang::Type::MemberPointer: + if (pointee_type) + pointee_type->SetCompilerType( + this, llvm::cast(qual_type) + ->getPointeeType() + .getAsOpaquePtr()); + return true; + case clang::Type::LValueReference: + if (pointee_type) + pointee_type->SetCompilerType( + this, llvm::cast(qual_type) + ->desugar() + .getAsOpaquePtr()); + return true; + case clang::Type::RValueReference: + if (pointee_type) + pointee_type->SetCompilerType( + this, llvm::cast(qual_type) + ->desugar() + .getAsOpaquePtr()); + return true; + default: + break; + } + } + if (pointee_type) + pointee_type->Clear(); + return false; +} + +bool TypeSystemClang::IsReferenceType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type, + bool *is_rvalue) { + if (type) { + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + + switch (type_class) { + case clang::Type::LValueReference: + if (pointee_type) + pointee_type->SetCompilerType( + this, llvm::cast(qual_type) + ->desugar() + .getAsOpaquePtr()); + if (is_rvalue) + *is_rvalue = false; + return true; + case clang::Type::RValueReference: + if (pointee_type) + pointee_type->SetCompilerType( + this, llvm::cast(qual_type) + ->desugar() + .getAsOpaquePtr()); + if (is_rvalue) + *is_rvalue = true; + return true; + + default: + break; + } + } + if (pointee_type) + pointee_type->Clear(); + return false; +} + +bool TypeSystemClang::IsFloatingPointType(lldb::opaque_compiler_type_t type, + uint32_t &count, bool &is_complex) { + if (type) { + clang::QualType qual_type(GetCanonicalQualType(type)); + + if (const clang::BuiltinType *BT = llvm::dyn_cast( + qual_type->getCanonicalTypeInternal())) { + clang::BuiltinType::Kind kind = BT->getKind(); + if (kind >= clang::BuiltinType::Float && + kind <= clang::BuiltinType::LongDouble) { + count = 1; + is_complex = false; + return true; + } + } else if (const clang::ComplexType *CT = + llvm::dyn_cast( + qual_type->getCanonicalTypeInternal())) { + if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, + is_complex)) { + count = 2; + is_complex = true; + return true; + } + } else if (const clang::VectorType *VT = llvm::dyn_cast( + qual_type->getCanonicalTypeInternal())) { + if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, + is_complex)) { + count = VT->getNumElements(); + is_complex = false; + return true; + } + } + } + count = 0; + is_complex = false; + return false; +} + +bool TypeSystemClang::IsDefined(lldb::opaque_compiler_type_t type) { + if (!type) + return false; + + clang::QualType qual_type(GetQualType(type)); + const clang::TagType *tag_type = + llvm::dyn_cast(qual_type.getTypePtr()); + if (tag_type) { + clang::TagDecl *tag_decl = tag_type->getDecl(); + if (tag_decl) + return tag_decl->isCompleteDefinition(); + return false; + } else { + const clang::ObjCObjectType *objc_class_type = + llvm::dyn_cast(qual_type); + if (objc_class_type) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + if (class_interface_decl) + return class_interface_decl->getDefinition() != nullptr; + return false; + } + } + return true; +} + +bool TypeSystemClang::IsObjCClassType(const CompilerType &type) { + if (ClangUtil::IsClangType(type)) { + clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); + + const clang::ObjCObjectPointerType *obj_pointer_type = + llvm::dyn_cast(qual_type); + + if (obj_pointer_type) + return obj_pointer_type->isObjCClassType(); + } + return false; +} + +bool TypeSystemClang::IsObjCObjectOrInterfaceType(const CompilerType &type) { + if (ClangUtil::IsClangType(type)) + return ClangUtil::GetCanonicalQualType(type)->isObjCObjectOrInterfaceType(); + return false; +} + +bool TypeSystemClang::IsClassType(lldb::opaque_compiler_type_t type) { + if (!type) + return false; + clang::QualType qual_type(GetCanonicalQualType(type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + return (type_class == clang::Type::Record); +} + +bool TypeSystemClang::IsEnumType(lldb::opaque_compiler_type_t type) { + if (!type) + return false; + clang::QualType qual_type(GetCanonicalQualType(type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + return (type_class == clang::Type::Enum); +} + +bool TypeSystemClang::IsPolymorphicClass(lldb::opaque_compiler_type_t type) { + if (type) { + clang::QualType qual_type(GetCanonicalQualType(type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: + if (GetCompleteType(type)) { + const clang::RecordType *record_type = + llvm::cast(qual_type.getTypePtr()); + const clang::RecordDecl *record_decl = record_type->getDecl(); + if (record_decl) { + const clang::CXXRecordDecl *cxx_record_decl = + llvm::dyn_cast(record_decl); + if (cxx_record_decl) + return cxx_record_decl->isPolymorphic(); + } + } + break; + + default: + break; + } + } + return false; +} + +bool TypeSystemClang::IsPossibleDynamicType(lldb::opaque_compiler_type_t type, + CompilerType *dynamic_pointee_type, + bool check_cplusplus, + bool check_objc) { + clang::QualType pointee_qual_type; + if (type) { + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + bool success = false; + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Builtin: + if (check_objc && + llvm::cast(qual_type)->getKind() == + clang::BuiltinType::ObjCId) { + if (dynamic_pointee_type) + dynamic_pointee_type->SetCompilerType(this, type); + return true; + } + break; + + case clang::Type::ObjCObjectPointer: + if (check_objc) { + if (const auto *objc_pointee_type = + qual_type->getPointeeType().getTypePtrOrNull()) { + if (const auto *objc_object_type = + llvm::dyn_cast_or_null( + objc_pointee_type)) { + if (objc_object_type->isObjCClass()) + return false; + } + } + if (dynamic_pointee_type) + dynamic_pointee_type->SetCompilerType( + this, llvm::cast(qual_type) + ->getPointeeType() + .getAsOpaquePtr()); + return true; + } + break; + + case clang::Type::Pointer: + pointee_qual_type = + llvm::cast(qual_type)->getPointeeType(); + success = true; + break; + + case clang::Type::LValueReference: + case clang::Type::RValueReference: + pointee_qual_type = + llvm::cast(qual_type)->getPointeeType(); + success = true; + break; + + default: + break; + } + + if (success) { + // Check to make sure what we are pointing too is a possible dynamic C++ + // type We currently accept any "void *" (in case we have a class that + // has been watered down to an opaque pointer) and virtual C++ classes. + const clang::Type::TypeClass pointee_type_class = + pointee_qual_type.getCanonicalType()->getTypeClass(); + switch (pointee_type_class) { + case clang::Type::Builtin: + switch (llvm::cast(pointee_qual_type)->getKind()) { + case clang::BuiltinType::UnknownAny: + case clang::BuiltinType::Void: + if (dynamic_pointee_type) + dynamic_pointee_type->SetCompilerType( + this, pointee_qual_type.getAsOpaquePtr()); + return true; + default: + break; + } + break; + + case clang::Type::Record: + if (check_cplusplus) { + clang::CXXRecordDecl *cxx_record_decl = + pointee_qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) { + bool is_complete = cxx_record_decl->isCompleteDefinition(); + + if (is_complete) + success = cxx_record_decl->isDynamicClass(); + else { + ClangASTMetadata *metadata = GetMetadata(cxx_record_decl); + if (metadata) + success = metadata->GetIsDynamicCXXType(); + else { + is_complete = GetType(pointee_qual_type).GetCompleteType(); + if (is_complete) + success = cxx_record_decl->isDynamicClass(); + else + success = false; + } + } + + if (success) { + if (dynamic_pointee_type) + dynamic_pointee_type->SetCompilerType( + this, pointee_qual_type.getAsOpaquePtr()); + return true; + } + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (check_objc) { + if (dynamic_pointee_type) + dynamic_pointee_type->SetCompilerType( + this, pointee_qual_type.getAsOpaquePtr()); + return true; + } + break; + + default: + break; + } + } + } + if (dynamic_pointee_type) + dynamic_pointee_type->Clear(); + return false; +} + +bool TypeSystemClang::IsScalarType(lldb::opaque_compiler_type_t type) { + if (!type) + return false; + + return (GetTypeInfo(type, nullptr) & eTypeIsScalar) != 0; +} + +bool TypeSystemClang::IsTypedefType(lldb::opaque_compiler_type_t type) { + if (!type) + return false; + return RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef}) + ->getTypeClass() == clang::Type::Typedef; +} + +bool TypeSystemClang::IsVoidType(lldb::opaque_compiler_type_t type) { + if (!type) + return false; + return GetCanonicalQualType(type)->isVoidType(); +} + +bool TypeSystemClang::CanPassInRegisters(const CompilerType &type) { + if (auto *record_decl = + TypeSystemClang::GetAsRecordDecl(type)) { + return record_decl->canPassInRegisters(); + } + return false; +} + +bool TypeSystemClang::SupportsLanguage(lldb::LanguageType language) { + return TypeSystemClangSupportsLanguage(language); +} + +Optional +TypeSystemClang::GetCXXClassName(const CompilerType &type) { + if (!type) + return llvm::None; + + clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); + if (qual_type.isNull()) + return llvm::None; + + clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (!cxx_record_decl) + return llvm::None; + + return std::string(cxx_record_decl->getIdentifier()->getNameStart()); +} + +bool TypeSystemClang::IsCXXClassType(const CompilerType &type) { + if (!type) + return false; + + clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); + return !qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr; +} + +bool TypeSystemClang::IsBeingDefined(lldb::opaque_compiler_type_t type) { + if (!type) + return false; + clang::QualType qual_type(GetCanonicalQualType(type)); + const clang::TagType *tag_type = llvm::dyn_cast(qual_type); + if (tag_type) + return tag_type->isBeingDefined(); + return false; +} + +bool TypeSystemClang::IsObjCObjectPointerType(const CompilerType &type, + CompilerType *class_type_ptr) { + if (!ClangUtil::IsClangType(type)) + return false; + + clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); + + if (!qual_type.isNull() && qual_type->isObjCObjectPointerType()) { + if (class_type_ptr) { + if (!qual_type->isObjCClassType() && !qual_type->isObjCIdType()) { + const clang::ObjCObjectPointerType *obj_pointer_type = + llvm::dyn_cast(qual_type); + if (obj_pointer_type == nullptr) + class_type_ptr->Clear(); + else + class_type_ptr->SetCompilerType( + type.GetTypeSystem(), + clang::QualType(obj_pointer_type->getInterfaceType(), 0) + .getAsOpaquePtr()); + } + } + return true; + } + if (class_type_ptr) + class_type_ptr->Clear(); + return false; +} + +// Type Completion + +bool TypeSystemClang::GetCompleteType(lldb::opaque_compiler_type_t type) { + if (!type) + return false; + const bool allow_completion = true; + return GetCompleteQualType(&getASTContext(), GetQualType(type), + allow_completion); +} + +ConstString TypeSystemClang::GetTypeName(lldb::opaque_compiler_type_t type) { + if (!type) + return ConstString(); + + clang::QualType qual_type(GetQualType(type)); + + // For a typedef just return the qualified name. + if (const auto *typedef_type = qual_type->getAs()) { + const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl(); + return ConstString(typedef_decl->getQualifiedNameAsString()); + } + + clang::PrintingPolicy printing_policy(getASTContext().getPrintingPolicy()); + printing_policy.SuppressTagKeyword = true; + return ConstString(qual_type.getAsString(printing_policy)); +} + +ConstString +TypeSystemClang::GetDisplayTypeName(lldb::opaque_compiler_type_t type) { + if (!type) + return ConstString(); + + clang::QualType qual_type(GetQualType(type)); + clang::PrintingPolicy printing_policy(getASTContext().getPrintingPolicy()); + printing_policy.SuppressTagKeyword = true; + printing_policy.SuppressScope = false; + printing_policy.SuppressUnwrittenScope = true; + return ConstString(qual_type.getAsString(printing_policy)); +} + +uint32_t +TypeSystemClang::GetTypeInfo(lldb::opaque_compiler_type_t type, + CompilerType *pointee_or_element_clang_type) { + if (!type) + return 0; + + if (pointee_or_element_clang_type) + pointee_or_element_clang_type->Clear(); + + clang::QualType qual_type = + RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef}); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Attributed: + return GetTypeInfo( + qual_type->getAs() + ->getModifiedType().getAsOpaquePtr(), + pointee_or_element_clang_type); + case clang::Type::Builtin: { + const clang::BuiltinType *builtin_type = llvm::dyn_cast( + qual_type->getCanonicalTypeInternal()); + + uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue; + switch (builtin_type->getKind()) { + case clang::BuiltinType::ObjCId: + case clang::BuiltinType::ObjCClass: + if (pointee_or_element_clang_type) + pointee_or_element_clang_type->SetCompilerType( + this, getASTContext().ObjCBuiltinClassTy.getAsOpaquePtr()); + builtin_type_flags |= eTypeIsPointer | eTypeIsObjC; + break; + + case clang::BuiltinType::ObjCSel: + if (pointee_or_element_clang_type) + pointee_or_element_clang_type->SetCompilerType( + this, getASTContext().CharTy.getAsOpaquePtr()); + builtin_type_flags |= eTypeIsPointer | eTypeIsObjC; + break; + + case clang::BuiltinType::Bool: + case clang::BuiltinType::Char_U: + case clang::BuiltinType::UChar: + case clang::BuiltinType::WChar_U: + case clang::BuiltinType::Char16: + case clang::BuiltinType::Char32: + case clang::BuiltinType::UShort: + case clang::BuiltinType::UInt: + case clang::BuiltinType::ULong: + case clang::BuiltinType::ULongLong: + case clang::BuiltinType::UInt128: + case clang::BuiltinType::Char_S: + case clang::BuiltinType::SChar: + case clang::BuiltinType::WChar_S: + case clang::BuiltinType::Short: + case clang::BuiltinType::Int: + case clang::BuiltinType::Long: + case clang::BuiltinType::LongLong: + case clang::BuiltinType::Int128: + case clang::BuiltinType::Float: + case clang::BuiltinType::Double: + case clang::BuiltinType::LongDouble: + builtin_type_flags |= eTypeIsScalar; + if (builtin_type->isInteger()) { + builtin_type_flags |= eTypeIsInteger; + if (builtin_type->isSignedInteger()) + builtin_type_flags |= eTypeIsSigned; + } else if (builtin_type->isFloatingPoint()) + builtin_type_flags |= eTypeIsFloat; + break; + default: + break; + } + return builtin_type_flags; + } + + case clang::Type::BlockPointer: + if (pointee_or_element_clang_type) + pointee_or_element_clang_type->SetCompilerType( + this, qual_type->getPointeeType().getAsOpaquePtr()); + return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock; + + case clang::Type::Complex: { + uint32_t complex_type_flags = + eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex; + const clang::ComplexType *complex_type = llvm::dyn_cast( + qual_type->getCanonicalTypeInternal()); + if (complex_type) { + clang::QualType complex_element_type(complex_type->getElementType()); + if (complex_element_type->isIntegerType()) + complex_type_flags |= eTypeIsFloat; + else if (complex_element_type->isFloatingType()) + complex_type_flags |= eTypeIsInteger; + } + return complex_type_flags; + } break; + + case clang::Type::ConstantArray: + case clang::Type::DependentSizedArray: + case clang::Type::IncompleteArray: + case clang::Type::VariableArray: + if (pointee_or_element_clang_type) + pointee_or_element_clang_type->SetCompilerType( + this, llvm::cast(qual_type.getTypePtr()) + ->getElementType() + .getAsOpaquePtr()); + return eTypeHasChildren | eTypeIsArray; + + case clang::Type::DependentName: + return 0; + case clang::Type::DependentSizedExtVector: + return eTypeHasChildren | eTypeIsVector; + case clang::Type::DependentTemplateSpecialization: + return eTypeIsTemplate; + + case clang::Type::Enum: + if (pointee_or_element_clang_type) + pointee_or_element_clang_type->SetCompilerType( + this, llvm::cast(qual_type) + ->getDecl() + ->getIntegerType() + .getAsOpaquePtr()); + return eTypeIsEnumeration | eTypeHasValue; + + case clang::Type::FunctionProto: + return eTypeIsFuncPrototype | eTypeHasValue; + case clang::Type::FunctionNoProto: + return eTypeIsFuncPrototype | eTypeHasValue; + case clang::Type::InjectedClassName: + return 0; + + case clang::Type::LValueReference: + case clang::Type::RValueReference: + if (pointee_or_element_clang_type) + pointee_or_element_clang_type->SetCompilerType( + this, llvm::cast(qual_type.getTypePtr()) + ->getPointeeType() + .getAsOpaquePtr()); + return eTypeHasChildren | eTypeIsReference | eTypeHasValue; + + case clang::Type::MemberPointer: + return eTypeIsPointer | eTypeIsMember | eTypeHasValue; + + case clang::Type::ObjCObjectPointer: + if (pointee_or_element_clang_type) + pointee_or_element_clang_type->SetCompilerType( + this, qual_type->getPointeeType().getAsOpaquePtr()); + return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | + eTypeHasValue; + + case clang::Type::ObjCObject: + return eTypeHasChildren | eTypeIsObjC | eTypeIsClass; + case clang::Type::ObjCInterface: + return eTypeHasChildren | eTypeIsObjC | eTypeIsClass; + + case clang::Type::Pointer: + if (pointee_or_element_clang_type) + pointee_or_element_clang_type->SetCompilerType( + this, qual_type->getPointeeType().getAsOpaquePtr()); + return eTypeHasChildren | eTypeIsPointer | eTypeHasValue; + + case clang::Type::Record: + if (qual_type->getAsCXXRecordDecl()) + return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus; + else + return eTypeHasChildren | eTypeIsStructUnion; + break; + case clang::Type::SubstTemplateTypeParm: + return eTypeIsTemplate; + case clang::Type::TemplateTypeParm: + return eTypeIsTemplate; + case clang::Type::TemplateSpecialization: + return eTypeIsTemplate; + + case clang::Type::Typedef: + return eTypeIsTypedef | GetType(llvm::cast(qual_type) + ->getDecl() + ->getUnderlyingType()) + .GetTypeInfo(pointee_or_element_clang_type); + case clang::Type::UnresolvedUsing: + return 0; + + case clang::Type::ExtVector: + case clang::Type::Vector: { + uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector; + const clang::VectorType *vector_type = llvm::dyn_cast( + qual_type->getCanonicalTypeInternal()); + if (vector_type) { + if (vector_type->isIntegerType()) + vector_type_flags |= eTypeIsFloat; + else if (vector_type->isFloatingType()) + vector_type_flags |= eTypeIsInteger; + } + return vector_type_flags; + } + default: + return 0; + } + return 0; +} + +lldb::LanguageType +TypeSystemClang::GetMinimumLanguage(lldb::opaque_compiler_type_t type) { + if (!type) + return lldb::eLanguageTypeC; + + // If the type is a reference, then resolve it to what it refers to first: + clang::QualType qual_type(GetCanonicalQualType(type).getNonReferenceType()); + if (qual_type->isAnyPointerType()) { + if (qual_type->isObjCObjectPointerType()) + return lldb::eLanguageTypeObjC; + if (qual_type->getPointeeCXXRecordDecl()) + return lldb::eLanguageTypeC_plus_plus; + + clang::QualType pointee_type(qual_type->getPointeeType()); + if (pointee_type->getPointeeCXXRecordDecl()) + return lldb::eLanguageTypeC_plus_plus; + if (pointee_type->isObjCObjectOrInterfaceType()) + return lldb::eLanguageTypeObjC; + if (pointee_type->isObjCClassType()) + return lldb::eLanguageTypeObjC; + if (pointee_type.getTypePtr() == + getASTContext().ObjCBuiltinIdTy.getTypePtr()) + return lldb::eLanguageTypeObjC; + } else { + if (qual_type->isObjCObjectOrInterfaceType()) + return lldb::eLanguageTypeObjC; + if (qual_type->getAsCXXRecordDecl()) + return lldb::eLanguageTypeC_plus_plus; + switch (qual_type->getTypeClass()) { + default: + break; + case clang::Type::Builtin: + switch (llvm::cast(qual_type)->getKind()) { + default: + case clang::BuiltinType::Void: + case clang::BuiltinType::Bool: + case clang::BuiltinType::Char_U: + case clang::BuiltinType::UChar: + case clang::BuiltinType::WChar_U: + case clang::BuiltinType::Char16: + case clang::BuiltinType::Char32: + case clang::BuiltinType::UShort: + case clang::BuiltinType::UInt: + case clang::BuiltinType::ULong: + case clang::BuiltinType::ULongLong: + case clang::BuiltinType::UInt128: + case clang::BuiltinType::Char_S: + case clang::BuiltinType::SChar: + case clang::BuiltinType::WChar_S: + case clang::BuiltinType::Short: + case clang::BuiltinType::Int: + case clang::BuiltinType::Long: + case clang::BuiltinType::LongLong: + case clang::BuiltinType::Int128: + case clang::BuiltinType::Float: + case clang::BuiltinType::Double: + case clang::BuiltinType::LongDouble: + break; + + case clang::BuiltinType::NullPtr: + return eLanguageTypeC_plus_plus; + + case clang::BuiltinType::ObjCId: + case clang::BuiltinType::ObjCClass: + case clang::BuiltinType::ObjCSel: + return eLanguageTypeObjC; + + case clang::BuiltinType::Dependent: + case clang::BuiltinType::Overload: + case clang::BuiltinType::BoundMember: + case clang::BuiltinType::UnknownAny: + break; + } + break; + case clang::Type::Typedef: + return GetType(llvm::cast(qual_type) + ->getDecl() + ->getUnderlyingType()) + .GetMinimumLanguage(); + } + } + return lldb::eLanguageTypeC; +} + +lldb::TypeClass +TypeSystemClang::GetTypeClass(lldb::opaque_compiler_type_t type) { + if (!type) + return lldb::eTypeClassInvalid; + + clang::QualType qual_type = + RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef}); + + switch (qual_type->getTypeClass()) { + case clang::Type::Atomic: + case clang::Type::Auto: + case clang::Type::Decltype: + case clang::Type::Elaborated: + case clang::Type::Paren: + case clang::Type::TypeOf: + case clang::Type::TypeOfExpr: + llvm_unreachable("Handled in RemoveWrappingTypes!"); + case clang::Type::UnaryTransform: + break; + case clang::Type::FunctionNoProto: + return lldb::eTypeClassFunction; + case clang::Type::FunctionProto: + return lldb::eTypeClassFunction; + case clang::Type::IncompleteArray: + return lldb::eTypeClassArray; + case clang::Type::VariableArray: + return lldb::eTypeClassArray; + case clang::Type::ConstantArray: + return lldb::eTypeClassArray; + case clang::Type::DependentSizedArray: + return lldb::eTypeClassArray; + case clang::Type::DependentSizedExtVector: + return lldb::eTypeClassVector; + case clang::Type::DependentVector: + return lldb::eTypeClassVector; + case clang::Type::ExtVector: + return lldb::eTypeClassVector; + case clang::Type::Vector: + return lldb::eTypeClassVector; + case clang::Type::Builtin: + // Ext-Int is just an integer type. + case clang::Type::ExtInt: + case clang::Type::DependentExtInt: + return lldb::eTypeClassBuiltin; + case clang::Type::ObjCObjectPointer: + return lldb::eTypeClassObjCObjectPointer; + case clang::Type::BlockPointer: + return lldb::eTypeClassBlockPointer; + case clang::Type::Pointer: + return lldb::eTypeClassPointer; + case clang::Type::LValueReference: + return lldb::eTypeClassReference; + case clang::Type::RValueReference: + return lldb::eTypeClassReference; + case clang::Type::MemberPointer: + return lldb::eTypeClassMemberPointer; + case clang::Type::Complex: + if (qual_type->isComplexType()) + return lldb::eTypeClassComplexFloat; + else + return lldb::eTypeClassComplexInteger; + case clang::Type::ObjCObject: + return lldb::eTypeClassObjCObject; + case clang::Type::ObjCInterface: + return lldb::eTypeClassObjCInterface; + case clang::Type::Record: { + const clang::RecordType *record_type = + llvm::cast(qual_type.getTypePtr()); + const clang::RecordDecl *record_decl = record_type->getDecl(); + if (record_decl->isUnion()) + return lldb::eTypeClassUnion; + else if (record_decl->isStruct()) + return lldb::eTypeClassStruct; + else + return lldb::eTypeClassClass; + } break; + case clang::Type::Enum: + return lldb::eTypeClassEnumeration; + case clang::Type::Typedef: + return lldb::eTypeClassTypedef; + case clang::Type::UnresolvedUsing: + break; + + case clang::Type::Attributed: + break; + case clang::Type::TemplateTypeParm: + break; + case clang::Type::SubstTemplateTypeParm: + break; + case clang::Type::SubstTemplateTypeParmPack: + break; + case clang::Type::InjectedClassName: + break; + case clang::Type::DependentName: + break; + case clang::Type::DependentTemplateSpecialization: + break; + case clang::Type::PackExpansion: + break; + + case clang::Type::TemplateSpecialization: + break; + case clang::Type::DeducedTemplateSpecialization: + break; + case clang::Type::Pipe: + break; + + // pointer type decayed from an array or function type. + case clang::Type::Decayed: + break; + case clang::Type::Adjusted: + break; + case clang::Type::ObjCTypeParam: + break; + + case clang::Type::DependentAddressSpace: + break; + case clang::Type::MacroQualified: + break; + + // Matrix types that we're not sure how to display at the moment. + case clang::Type::ConstantMatrix: + case clang::Type::DependentSizedMatrix: + break; + } + // We don't know hot to display this type... + return lldb::eTypeClassOther; +} + +unsigned TypeSystemClang::GetTypeQualifiers(lldb::opaque_compiler_type_t type) { + if (type) + return GetQualType(type).getQualifiers().getCVRQualifiers(); + return 0; +} + +// Creating related types + +CompilerType +TypeSystemClang::GetArrayElementType(lldb::opaque_compiler_type_t type, + uint64_t *stride) { + if (type) { + clang::QualType qual_type(GetQualType(type)); + + const clang::Type *array_eletype = + qual_type.getTypePtr()->getArrayElementTypeNoTypeQual(); + + if (!array_eletype) + return CompilerType(); + + CompilerType element_type = GetType(clang::QualType(array_eletype, 0)); + + // TODO: the real stride will be >= this value.. find the real one! + if (stride) + if (Optional size = element_type.GetByteSize(nullptr)) + *stride = *size; + + return element_type; + } + return CompilerType(); +} + +CompilerType TypeSystemClang::GetArrayType(lldb::opaque_compiler_type_t type, + uint64_t size) { + if (type) { + clang::QualType qual_type(GetCanonicalQualType(type)); + clang::ASTContext &ast_ctx = getASTContext(); + if (size != 0) + return GetType(ast_ctx.getConstantArrayType( + qual_type, llvm::APInt(64, size), nullptr, + clang::ArrayType::ArraySizeModifier::Normal, 0)); + else + return GetType(ast_ctx.getIncompleteArrayType( + qual_type, clang::ArrayType::ArraySizeModifier::Normal, 0)); + } + + return CompilerType(); +} + +CompilerType +TypeSystemClang::GetCanonicalType(lldb::opaque_compiler_type_t type) { + if (type) + return GetType(GetCanonicalQualType(type)); + return CompilerType(); +} + +static clang::QualType GetFullyUnqualifiedType_Impl(clang::ASTContext *ast, + clang::QualType qual_type) { + if (qual_type->isPointerType()) + qual_type = ast->getPointerType( + GetFullyUnqualifiedType_Impl(ast, qual_type->getPointeeType())); + else + qual_type = qual_type.getUnqualifiedType(); + qual_type.removeLocalConst(); + qual_type.removeLocalRestrict(); + qual_type.removeLocalVolatile(); + return qual_type; +} + +CompilerType +TypeSystemClang::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) { + if (type) + return GetType( + GetFullyUnqualifiedType_Impl(&getASTContext(), GetQualType(type))); + return CompilerType(); +} + +int TypeSystemClang::GetFunctionArgumentCount( + lldb::opaque_compiler_type_t type) { + if (type) { + const clang::FunctionProtoType *func = + llvm::dyn_cast(GetCanonicalQualType(type)); + if (func) + return func->getNumParams(); + } + return -1; +} + +CompilerType TypeSystemClang::GetFunctionArgumentTypeAtIndex( + lldb::opaque_compiler_type_t type, size_t idx) { + if (type) { + const clang::FunctionProtoType *func = + llvm::dyn_cast(GetQualType(type)); + if (func) { + const uint32_t num_args = func->getNumParams(); + if (idx < num_args) + return GetType(func->getParamType(idx)); + } + } + return CompilerType(); +} + +CompilerType +TypeSystemClang::GetFunctionReturnType(lldb::opaque_compiler_type_t type) { + if (type) { + clang::QualType qual_type(GetQualType(type)); + const clang::FunctionProtoType *func = + llvm::dyn_cast(qual_type.getTypePtr()); + if (func) + return GetType(func->getReturnType()); + } + return CompilerType(); +} + +size_t +TypeSystemClang::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) { + size_t num_functions = 0; + if (type) { + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + switch (qual_type->getTypeClass()) { + case clang::Type::Record: + if (GetCompleteQualType(&getASTContext(), qual_type)) { + const clang::RecordType *record_type = + llvm::cast(qual_type.getTypePtr()); + const clang::RecordDecl *record_decl = record_type->getDecl(); + assert(record_decl); + const clang::CXXRecordDecl *cxx_record_decl = + llvm::dyn_cast(record_decl); + if (cxx_record_decl) + num_functions = std::distance(cxx_record_decl->method_begin(), + cxx_record_decl->method_end()); + } + break; + + case clang::Type::ObjCObjectPointer: { + const clang::ObjCObjectPointerType *objc_class_type = + qual_type->getAs(); + const clang::ObjCInterfaceType *objc_interface_type = + objc_class_type->getInterfaceType(); + if (objc_interface_type && + GetCompleteType(static_cast( + const_cast(objc_interface_type)))) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_interface_type->getDecl(); + if (class_interface_decl) { + num_functions = std::distance(class_interface_decl->meth_begin(), + class_interface_decl->meth_end()); + } + } + break; + } + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteType(type)) { + const clang::ObjCObjectType *objc_class_type = + llvm::dyn_cast(qual_type.getTypePtr()); + if (objc_class_type) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + if (class_interface_decl) + num_functions = std::distance(class_interface_decl->meth_begin(), + class_interface_decl->meth_end()); + } + } + break; + + default: + break; + } + } + return num_functions; +} + +TypeMemberFunctionImpl +TypeSystemClang::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, + size_t idx) { + std::string name; + MemberFunctionKind kind(MemberFunctionKind::eMemberFunctionKindUnknown); + CompilerType clang_type; + CompilerDecl clang_decl; + if (type) { + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + switch (qual_type->getTypeClass()) { + case clang::Type::Record: + if (GetCompleteQualType(&getASTContext(), qual_type)) { + const clang::RecordType *record_type = + llvm::cast(qual_type.getTypePtr()); + const clang::RecordDecl *record_decl = record_type->getDecl(); + assert(record_decl); + const clang::CXXRecordDecl *cxx_record_decl = + llvm::dyn_cast(record_decl); + if (cxx_record_decl) { + auto method_iter = cxx_record_decl->method_begin(); + auto method_end = cxx_record_decl->method_end(); + if (idx < + static_cast(std::distance(method_iter, method_end))) { + std::advance(method_iter, idx); + clang::CXXMethodDecl *cxx_method_decl = + method_iter->getCanonicalDecl(); + if (cxx_method_decl) { + name = cxx_method_decl->getDeclName().getAsString(); + if (cxx_method_decl->isStatic()) + kind = lldb::eMemberFunctionKindStaticMethod; + else if (llvm::isa(cxx_method_decl)) + kind = lldb::eMemberFunctionKindConstructor; + else if (llvm::isa(cxx_method_decl)) + kind = lldb::eMemberFunctionKindDestructor; + else + kind = lldb::eMemberFunctionKindInstanceMethod; + clang_type = GetType(cxx_method_decl->getType()); + clang_decl = GetCompilerDecl(cxx_method_decl); + } + } + } + } + break; + + case clang::Type::ObjCObjectPointer: { + const clang::ObjCObjectPointerType *objc_class_type = + qual_type->getAs(); + const clang::ObjCInterfaceType *objc_interface_type = + objc_class_type->getInterfaceType(); + if (objc_interface_type && + GetCompleteType(static_cast( + const_cast(objc_interface_type)))) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_interface_type->getDecl(); + if (class_interface_decl) { + auto method_iter = class_interface_decl->meth_begin(); + auto method_end = class_interface_decl->meth_end(); + if (idx < + static_cast(std::distance(method_iter, method_end))) { + std::advance(method_iter, idx); + clang::ObjCMethodDecl *objc_method_decl = + method_iter->getCanonicalDecl(); + if (objc_method_decl) { + clang_decl = GetCompilerDecl(objc_method_decl); + name = objc_method_decl->getSelector().getAsString(); + if (objc_method_decl->isClassMethod()) + kind = lldb::eMemberFunctionKindStaticMethod; + else + kind = lldb::eMemberFunctionKindInstanceMethod; + } + } + } + } + break; + } + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteType(type)) { + const clang::ObjCObjectType *objc_class_type = + llvm::dyn_cast(qual_type.getTypePtr()); + if (objc_class_type) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + if (class_interface_decl) { + auto method_iter = class_interface_decl->meth_begin(); + auto method_end = class_interface_decl->meth_end(); + if (idx < + static_cast(std::distance(method_iter, method_end))) { + std::advance(method_iter, idx); + clang::ObjCMethodDecl *objc_method_decl = + method_iter->getCanonicalDecl(); + if (objc_method_decl) { + clang_decl = GetCompilerDecl(objc_method_decl); + name = objc_method_decl->getSelector().getAsString(); + if (objc_method_decl->isClassMethod()) + kind = lldb::eMemberFunctionKindStaticMethod; + else + kind = lldb::eMemberFunctionKindInstanceMethod; + } + } + } + } + } + break; + + default: + break; + } + } + + if (kind == eMemberFunctionKindUnknown) + return TypeMemberFunctionImpl(); + else + return TypeMemberFunctionImpl(clang_type, clang_decl, name, kind); +} + +CompilerType +TypeSystemClang::GetNonReferenceType(lldb::opaque_compiler_type_t type) { + if (type) + return GetType(GetQualType(type).getNonReferenceType()); + return CompilerType(); +} + +CompilerType TypeSystemClang::CreateTypedefType( + const CompilerType &type, const char *typedef_name, + const CompilerDeclContext &compiler_decl_ctx, uint32_t payload) { + if (type && typedef_name && typedef_name[0]) { + TypeSystemClang *ast = + llvm::dyn_cast(type.GetTypeSystem()); + if (!ast) + return CompilerType(); + clang::ASTContext &clang_ast = ast->getASTContext(); + clang::QualType qual_type(ClangUtil::GetQualType(type)); + + clang::DeclContext *decl_ctx = + TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx); + if (!decl_ctx) + decl_ctx = ast->getASTContext().getTranslationUnitDecl(); + + clang::TypedefDecl *decl = + clang::TypedefDecl::CreateDeserialized(clang_ast, 0); + decl->setDeclContext(decl_ctx); + decl->setDeclName(&clang_ast.Idents.get(typedef_name)); + decl->setTypeSourceInfo(clang_ast.getTrivialTypeSourceInfo(qual_type)); + + SetOwningModule(decl, TypePayloadClang(payload).GetOwningModule()); + 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 ast->GetType(clang_ast.getTypedefType(decl)); + } + return CompilerType(); +} + +CompilerType +TypeSystemClang::GetPointeeType(lldb::opaque_compiler_type_t type) { + if (type) { + clang::QualType qual_type(GetQualType(type)); + return GetType(qual_type.getTypePtr()->getPointeeType()); + } + return CompilerType(); +} + +CompilerType +TypeSystemClang::GetPointerType(lldb::opaque_compiler_type_t type) { + if (type) { + clang::QualType qual_type(GetQualType(type)); + + switch (qual_type.getDesugaredType(getASTContext())->getTypeClass()) { + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + return GetType(getASTContext().getObjCObjectPointerType(qual_type)); + + default: + return GetType(getASTContext().getPointerType(qual_type)); + } + } + return CompilerType(); +} + +CompilerType +TypeSystemClang::GetLValueReferenceType(lldb::opaque_compiler_type_t type) { + if (type) + return GetType(getASTContext().getLValueReferenceType(GetQualType(type))); + else + return CompilerType(); +} + +CompilerType +TypeSystemClang::GetRValueReferenceType(lldb::opaque_compiler_type_t type) { + if (type) + return GetType(getASTContext().getRValueReferenceType(GetQualType(type))); + else + return CompilerType(); +} + +CompilerType TypeSystemClang::GetAtomicType(lldb::opaque_compiler_type_t type) { + if (!type) + return CompilerType(); + return GetType(getASTContext().getAtomicType(GetQualType(type))); +} + +CompilerType +TypeSystemClang::AddConstModifier(lldb::opaque_compiler_type_t type) { + if (type) { + clang::QualType result(GetQualType(type)); + result.addConst(); + return GetType(result); + } + return CompilerType(); +} + +CompilerType +TypeSystemClang::AddVolatileModifier(lldb::opaque_compiler_type_t type) { + if (type) { + clang::QualType result(GetQualType(type)); + result.addVolatile(); + return GetType(result); + } + return CompilerType(); +} + +CompilerType +TypeSystemClang::AddRestrictModifier(lldb::opaque_compiler_type_t type) { + if (type) { + clang::QualType result(GetQualType(type)); + result.addRestrict(); + return GetType(result); + } + return CompilerType(); +} + +CompilerType TypeSystemClang::CreateTypedef( + lldb::opaque_compiler_type_t type, const char *typedef_name, + const CompilerDeclContext &compiler_decl_ctx, uint32_t payload) { + if (type) { + clang::ASTContext &clang_ast = getASTContext(); + clang::QualType qual_type(GetQualType(type)); + + clang::DeclContext *decl_ctx = + TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx); + if (!decl_ctx) + decl_ctx = getASTContext().getTranslationUnitDecl(); + + clang::TypedefDecl *decl = clang::TypedefDecl::Create( + clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(), + &clang_ast.Idents.get(typedef_name), + clang_ast.getTrivialTypeSourceInfo(qual_type)); + SetOwningModule(decl, TypePayloadClang(payload).GetOwningModule()); + + clang::TagDecl *tdecl = nullptr; + if (!qual_type.isNull()) { + if (const clang::RecordType *rt = qual_type->getAs()) + tdecl = rt->getDecl(); + if (const clang::EnumType *et = qual_type->getAs()) + tdecl = et->getDecl(); + } + + // Check whether this declaration is an anonymous struct, union, or enum, + // hidden behind a typedef. If so, we try to check whether we have a + // typedef tag to attach to the original record declaration + if (tdecl && !tdecl->getIdentifier() && !tdecl->getTypedefNameForAnonDecl()) + tdecl->setTypedefNameForAnonDecl(decl); + + decl->setAccess(clang::AS_public); // TODO respect proper access specifier + + // Get a uniqued clang::QualType for the typedef decl type + return GetType(clang_ast.getTypedefType(decl)); + } + return CompilerType(); +} + +CompilerType +TypeSystemClang::GetTypedefedType(lldb::opaque_compiler_type_t type) { + if (type) { + const clang::TypedefType *typedef_type = llvm::dyn_cast( + RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef})); + if (typedef_type) + return GetType(typedef_type->getDecl()->getUnderlyingType()); + } + return CompilerType(); +} + +// Create related types using the current type's AST + +CompilerType TypeSystemClang::GetBasicTypeFromAST(lldb::BasicType basic_type) { + return TypeSystemClang::GetBasicType(basic_type); +} +// Exploring the type + +const llvm::fltSemantics & +TypeSystemClang::GetFloatTypeSemantics(size_t byte_size) { + clang::ASTContext &ast = getASTContext(); + const size_t bit_size = byte_size * 8; + if (bit_size == ast.getTypeSize(ast.FloatTy)) + return ast.getFloatTypeSemantics(ast.FloatTy); + else if (bit_size == ast.getTypeSize(ast.DoubleTy)) + return ast.getFloatTypeSemantics(ast.DoubleTy); + else if (bit_size == ast.getTypeSize(ast.LongDoubleTy)) + return ast.getFloatTypeSemantics(ast.LongDoubleTy); + else if (bit_size == ast.getTypeSize(ast.HalfTy)) + return ast.getFloatTypeSemantics(ast.HalfTy); + return llvm::APFloatBase::Bogus(); +} + +Optional +TypeSystemClang::GetBitSize(lldb::opaque_compiler_type_t type, + ExecutionContextScope *exe_scope) { + if (GetCompleteType(type)) { + clang::QualType qual_type(GetCanonicalQualType(type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: + if (GetCompleteType(type)) + return getASTContext().getTypeSize(qual_type); + else + return None; + break; + + case clang::Type::ObjCInterface: + case clang::Type::ObjCObject: { + ExecutionContext exe_ctx(exe_scope); + Process *process = exe_ctx.GetProcessPtr(); + if (process) { + ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process); + if (objc_runtime) { + uint64_t bit_size = 0; + if (objc_runtime->GetTypeBitSize(GetType(qual_type), bit_size)) + return bit_size; + } + } else { + static bool g_printed = false; + if (!g_printed) { + StreamString s; + DumpTypeDescription(type, &s); + + llvm::outs() << "warning: trying to determine the size of type "; + llvm::outs() << s.GetString() << "\n"; + llvm::outs() << "without a valid ExecutionContext. this is not " + "reliable. please file a bug against LLDB.\n"; + llvm::outs() << "backtrace:\n"; + llvm::sys::PrintStackTrace(llvm::outs()); + llvm::outs() << "\n"; + g_printed = true; + } + } + } + LLVM_FALLTHROUGH; + default: + const uint32_t bit_size = getASTContext().getTypeSize(qual_type); + if (bit_size == 0) { + if (qual_type->isIncompleteArrayType()) + return getASTContext().getTypeSize( + qual_type->getArrayElementTypeNoTypeQual() + ->getCanonicalTypeUnqualified()); + } + if (qual_type->isObjCObjectOrInterfaceType()) + return bit_size + + getASTContext().getTypeSize(getASTContext().ObjCBuiltinClassTy); + // Function types actually have a size of 0, that's not an error. + if (qual_type->isFunctionProtoType()) + return bit_size; + if (bit_size) + return bit_size; + } + } + return None; +} + +llvm::Optional +TypeSystemClang::GetTypeBitAlign(lldb::opaque_compiler_type_t type, + ExecutionContextScope *exe_scope) { + if (GetCompleteType(type)) + return getASTContext().getTypeAlign(GetQualType(type)); + return {}; +} + +lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type, + uint64_t &count) { + if (!type) + return lldb::eEncodingInvalid; + + count = 1; + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + + switch (qual_type->getTypeClass()) { + case clang::Type::Atomic: + case clang::Type::Auto: + case clang::Type::Decltype: + case clang::Type::Elaborated: + case clang::Type::Paren: + case clang::Type::Typedef: + case clang::Type::TypeOf: + case clang::Type::TypeOfExpr: + llvm_unreachable("Handled in RemoveWrappingTypes!"); + + case clang::Type::UnaryTransform: + break; + + case clang::Type::FunctionNoProto: + case clang::Type::FunctionProto: + break; + + case clang::Type::IncompleteArray: + case clang::Type::VariableArray: + break; + + case clang::Type::ConstantArray: + break; + + case clang::Type::DependentVector: + case clang::Type::ExtVector: + case clang::Type::Vector: + // TODO: Set this to more than one??? + break; + + case clang::Type::ExtInt: + case clang::Type::DependentExtInt: + return qual_type->isUnsignedIntegerType() ? lldb::eEncodingUint + : lldb::eEncodingSint; + + case clang::Type::Builtin: + switch (llvm::cast(qual_type)->getKind()) { + case clang::BuiltinType::Void: + break; + + case clang::BuiltinType::Bool: + case clang::BuiltinType::Char_S: + case clang::BuiltinType::SChar: + case clang::BuiltinType::WChar_S: + case clang::BuiltinType::Short: + case clang::BuiltinType::Int: + case clang::BuiltinType::Long: + case clang::BuiltinType::LongLong: + case clang::BuiltinType::Int128: + return lldb::eEncodingSint; + + case clang::BuiltinType::Char_U: + case clang::BuiltinType::UChar: + case clang::BuiltinType::WChar_U: + case clang::BuiltinType::Char8: + case clang::BuiltinType::Char16: + case clang::BuiltinType::Char32: + case clang::BuiltinType::UShort: + case clang::BuiltinType::UInt: + case clang::BuiltinType::ULong: + case clang::BuiltinType::ULongLong: + case clang::BuiltinType::UInt128: + return lldb::eEncodingUint; + + // Fixed point types. Note that they are currently ignored. + case clang::BuiltinType::ShortAccum: + case clang::BuiltinType::Accum: + case clang::BuiltinType::LongAccum: + case clang::BuiltinType::UShortAccum: + case clang::BuiltinType::UAccum: + case clang::BuiltinType::ULongAccum: + case clang::BuiltinType::ShortFract: + case clang::BuiltinType::Fract: + case clang::BuiltinType::LongFract: + case clang::BuiltinType::UShortFract: + case clang::BuiltinType::UFract: + case clang::BuiltinType::ULongFract: + case clang::BuiltinType::SatShortAccum: + case clang::BuiltinType::SatAccum: + case clang::BuiltinType::SatLongAccum: + case clang::BuiltinType::SatUShortAccum: + case clang::BuiltinType::SatUAccum: + case clang::BuiltinType::SatULongAccum: + case clang::BuiltinType::SatShortFract: + case clang::BuiltinType::SatFract: + case clang::BuiltinType::SatLongFract: + case clang::BuiltinType::SatUShortFract: + case clang::BuiltinType::SatUFract: + case clang::BuiltinType::SatULongFract: + break; + + case clang::BuiltinType::Half: + case clang::BuiltinType::Float: + case clang::BuiltinType::Float16: + case clang::BuiltinType::Float128: + case clang::BuiltinType::Double: + case clang::BuiltinType::LongDouble: + case clang::BuiltinType::BFloat16: + return lldb::eEncodingIEEE754; + + case clang::BuiltinType::ObjCClass: + case clang::BuiltinType::ObjCId: + case clang::BuiltinType::ObjCSel: + return lldb::eEncodingUint; + + case clang::BuiltinType::NullPtr: + return lldb::eEncodingUint; + + case clang::BuiltinType::Kind::ARCUnbridgedCast: + case clang::BuiltinType::Kind::BoundMember: + case clang::BuiltinType::Kind::BuiltinFn: + case clang::BuiltinType::Kind::Dependent: + case clang::BuiltinType::Kind::OCLClkEvent: + case clang::BuiltinType::Kind::OCLEvent: + case clang::BuiltinType::Kind::OCLImage1dRO: + case clang::BuiltinType::Kind::OCLImage1dWO: + case clang::BuiltinType::Kind::OCLImage1dRW: + case clang::BuiltinType::Kind::OCLImage1dArrayRO: + case clang::BuiltinType::Kind::OCLImage1dArrayWO: + case clang::BuiltinType::Kind::OCLImage1dArrayRW: + case clang::BuiltinType::Kind::OCLImage1dBufferRO: + case clang::BuiltinType::Kind::OCLImage1dBufferWO: + case clang::BuiltinType::Kind::OCLImage1dBufferRW: + case clang::BuiltinType::Kind::OCLImage2dRO: + case clang::BuiltinType::Kind::OCLImage2dWO: + case clang::BuiltinType::Kind::OCLImage2dRW: + case clang::BuiltinType::Kind::OCLImage2dArrayRO: + case clang::BuiltinType::Kind::OCLImage2dArrayWO: + case clang::BuiltinType::Kind::OCLImage2dArrayRW: + case clang::BuiltinType::Kind::OCLImage2dArrayDepthRO: + case clang::BuiltinType::Kind::OCLImage2dArrayDepthWO: + case clang::BuiltinType::Kind::OCLImage2dArrayDepthRW: + case clang::BuiltinType::Kind::OCLImage2dArrayMSAARO: + case clang::BuiltinType::Kind::OCLImage2dArrayMSAAWO: + case clang::BuiltinType::Kind::OCLImage2dArrayMSAARW: + case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRO: + case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthWO: + case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRW: + case clang::BuiltinType::Kind::OCLImage2dDepthRO: + case clang::BuiltinType::Kind::OCLImage2dDepthWO: + case clang::BuiltinType::Kind::OCLImage2dDepthRW: + case clang::BuiltinType::Kind::OCLImage2dMSAARO: + case clang::BuiltinType::Kind::OCLImage2dMSAAWO: + case clang::BuiltinType::Kind::OCLImage2dMSAARW: + case clang::BuiltinType::Kind::OCLImage2dMSAADepthRO: + case clang::BuiltinType::Kind::OCLImage2dMSAADepthWO: + case clang::BuiltinType::Kind::OCLImage2dMSAADepthRW: + case clang::BuiltinType::Kind::OCLImage3dRO: + case clang::BuiltinType::Kind::OCLImage3dWO: + case clang::BuiltinType::Kind::OCLImage3dRW: + case clang::BuiltinType::Kind::OCLQueue: + case clang::BuiltinType::Kind::OCLReserveID: + case clang::BuiltinType::Kind::OCLSampler: + case clang::BuiltinType::Kind::OMPArraySection: + case clang::BuiltinType::Kind::OMPArrayShaping: + case clang::BuiltinType::Kind::OMPIterator: + case clang::BuiltinType::Kind::Overload: + 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; + + case clang::BuiltinType::SveBool: + case clang::BuiltinType::SveInt8: + case clang::BuiltinType::SveInt8x2: + case clang::BuiltinType::SveInt8x3: + case clang::BuiltinType::SveInt8x4: + case clang::BuiltinType::SveInt16: + case clang::BuiltinType::SveInt16x2: + case clang::BuiltinType::SveInt16x3: + case clang::BuiltinType::SveInt16x4: + case clang::BuiltinType::SveInt32: + case clang::BuiltinType::SveInt32x2: + case clang::BuiltinType::SveInt32x3: + case clang::BuiltinType::SveInt32x4: + case clang::BuiltinType::SveInt64: + case clang::BuiltinType::SveInt64x2: + case clang::BuiltinType::SveInt64x3: + case clang::BuiltinType::SveInt64x4: + case clang::BuiltinType::SveUint8: + case clang::BuiltinType::SveUint8x2: + case clang::BuiltinType::SveUint8x3: + case clang::BuiltinType::SveUint8x4: + case clang::BuiltinType::SveUint16: + case clang::BuiltinType::SveUint16x2: + case clang::BuiltinType::SveUint16x3: + case clang::BuiltinType::SveUint16x4: + case clang::BuiltinType::SveUint32: + case clang::BuiltinType::SveUint32x2: + case clang::BuiltinType::SveUint32x3: + case clang::BuiltinType::SveUint32x4: + case clang::BuiltinType::SveUint64: + case clang::BuiltinType::SveUint64x2: + case clang::BuiltinType::SveUint64x3: + case clang::BuiltinType::SveUint64x4: + case clang::BuiltinType::SveFloat16: + case clang::BuiltinType::SveBFloat16: + case clang::BuiltinType::SveBFloat16x2: + case clang::BuiltinType::SveBFloat16x3: + case clang::BuiltinType::SveBFloat16x4: + case clang::BuiltinType::SveFloat16x2: + case clang::BuiltinType::SveFloat16x3: + case clang::BuiltinType::SveFloat16x4: + case clang::BuiltinType::SveFloat32: + case clang::BuiltinType::SveFloat32x2: + case clang::BuiltinType::SveFloat32x3: + case clang::BuiltinType::SveFloat32x4: + case clang::BuiltinType::SveFloat64: + case clang::BuiltinType::SveFloat64x2: + case clang::BuiltinType::SveFloat64x3: + case clang::BuiltinType::SveFloat64x4: + break; + + case clang::BuiltinType::IncompleteMatrixIdx: + break; + } + break; + // All pointer types are represented as unsigned integer encodings. We may + // nee to add a eEncodingPointer if we ever need to know the difference + case clang::Type::ObjCObjectPointer: + case clang::Type::BlockPointer: + case clang::Type::Pointer: + case clang::Type::LValueReference: + case clang::Type::RValueReference: + case clang::Type::MemberPointer: + return lldb::eEncodingUint; + case clang::Type::Complex: { + lldb::Encoding encoding = lldb::eEncodingIEEE754; + if (qual_type->isComplexType()) + encoding = lldb::eEncodingIEEE754; + else { + const clang::ComplexType *complex_type = + qual_type->getAsComplexIntegerType(); + if (complex_type) + encoding = GetType(complex_type->getElementType()).GetEncoding(count); + else + encoding = lldb::eEncodingSint; + } + count = 2; + return encoding; + } + + case clang::Type::ObjCInterface: + break; + case clang::Type::Record: + break; + case clang::Type::Enum: + return lldb::eEncodingSint; + case clang::Type::DependentSizedArray: + case clang::Type::DependentSizedExtVector: + case clang::Type::UnresolvedUsing: + case clang::Type::Attributed: + case clang::Type::TemplateTypeParm: + case clang::Type::SubstTemplateTypeParm: + case clang::Type::SubstTemplateTypeParmPack: + case clang::Type::InjectedClassName: + case clang::Type::DependentName: + case clang::Type::DependentTemplateSpecialization: + case clang::Type::PackExpansion: + case clang::Type::ObjCObject: + + case clang::Type::TemplateSpecialization: + case clang::Type::DeducedTemplateSpecialization: + case clang::Type::Adjusted: + case clang::Type::Pipe: + break; + + // pointer type decayed from an array or function type. + case clang::Type::Decayed: + break; + case clang::Type::ObjCTypeParam: + break; + + case clang::Type::DependentAddressSpace: + break; + case clang::Type::MacroQualified: + break; + + case clang::Type::ConstantMatrix: + case clang::Type::DependentSizedMatrix: + break; + } + count = 0; + return lldb::eEncodingInvalid; +} + +lldb::Format TypeSystemClang::GetFormat(lldb::opaque_compiler_type_t type) { + if (!type) + return lldb::eFormatDefault; + + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + + switch (qual_type->getTypeClass()) { + case clang::Type::Atomic: + case clang::Type::Auto: + case clang::Type::Decltype: + case clang::Type::Elaborated: + case clang::Type::Paren: + case clang::Type::Typedef: + case clang::Type::TypeOf: + case clang::Type::TypeOfExpr: + llvm_unreachable("Handled in RemoveWrappingTypes!"); + case clang::Type::UnaryTransform: + break; + + case clang::Type::FunctionNoProto: + case clang::Type::FunctionProto: + break; + + case clang::Type::IncompleteArray: + case clang::Type::VariableArray: + break; + + case clang::Type::ConstantArray: + return lldb::eFormatVoid; // no value + + case clang::Type::DependentVector: + case clang::Type::ExtVector: + case clang::Type::Vector: + break; + + case clang::Type::ExtInt: + case clang::Type::DependentExtInt: + return qual_type->isUnsignedIntegerType() ? lldb::eFormatUnsigned + : lldb::eFormatDecimal; + + case clang::Type::Builtin: + switch (llvm::cast(qual_type)->getKind()) { + case clang::BuiltinType::UnknownAny: + case clang::BuiltinType::Void: + case clang::BuiltinType::BoundMember: + break; + + case clang::BuiltinType::Bool: + return lldb::eFormatBoolean; + case clang::BuiltinType::Char_S: + case clang::BuiltinType::SChar: + case clang::BuiltinType::WChar_S: + case clang::BuiltinType::Char_U: + case clang::BuiltinType::UChar: + case clang::BuiltinType::WChar_U: + return lldb::eFormatChar; + case clang::BuiltinType::Char16: + return lldb::eFormatUnicode16; + case clang::BuiltinType::Char32: + return lldb::eFormatUnicode32; + case clang::BuiltinType::UShort: + return lldb::eFormatUnsigned; + case clang::BuiltinType::Short: + return lldb::eFormatDecimal; + case clang::BuiltinType::UInt: + return lldb::eFormatUnsigned; + case clang::BuiltinType::Int: + return lldb::eFormatDecimal; + case clang::BuiltinType::ULong: + return lldb::eFormatUnsigned; + case clang::BuiltinType::Long: + return lldb::eFormatDecimal; + case clang::BuiltinType::ULongLong: + return lldb::eFormatUnsigned; + case clang::BuiltinType::LongLong: + return lldb::eFormatDecimal; + case clang::BuiltinType::UInt128: + return lldb::eFormatUnsigned; + case clang::BuiltinType::Int128: + return lldb::eFormatDecimal; + case clang::BuiltinType::Half: + case clang::BuiltinType::Float: + case clang::BuiltinType::Double: + case clang::BuiltinType::LongDouble: + return lldb::eFormatFloat; + default: + return lldb::eFormatHex; + } + break; + case clang::Type::ObjCObjectPointer: + return lldb::eFormatHex; + case clang::Type::BlockPointer: + return lldb::eFormatHex; + case clang::Type::Pointer: + return lldb::eFormatHex; + case clang::Type::LValueReference: + case clang::Type::RValueReference: + return lldb::eFormatHex; + case clang::Type::MemberPointer: + break; + case clang::Type::Complex: { + if (qual_type->isComplexType()) + return lldb::eFormatComplex; + else + return lldb::eFormatComplexInteger; + } + case clang::Type::ObjCInterface: + break; + case clang::Type::Record: + break; + case clang::Type::Enum: + return lldb::eFormatEnum; + case clang::Type::DependentSizedArray: + case clang::Type::DependentSizedExtVector: + case clang::Type::UnresolvedUsing: + case clang::Type::Attributed: + case clang::Type::TemplateTypeParm: + case clang::Type::SubstTemplateTypeParm: + case clang::Type::SubstTemplateTypeParmPack: + case clang::Type::InjectedClassName: + case clang::Type::DependentName: + case clang::Type::DependentTemplateSpecialization: + case clang::Type::PackExpansion: + case clang::Type::ObjCObject: + + case clang::Type::TemplateSpecialization: + case clang::Type::DeducedTemplateSpecialization: + case clang::Type::Adjusted: + case clang::Type::Pipe: + break; + + // pointer type decayed from an array or function type. + case clang::Type::Decayed: + break; + case clang::Type::ObjCTypeParam: + break; + + case clang::Type::DependentAddressSpace: + break; + case clang::Type::MacroQualified: + break; + + // Matrix types we're not sure how to display yet. + case clang::Type::ConstantMatrix: + case clang::Type::DependentSizedMatrix: + break; + } + // We don't know hot to display this type... + return lldb::eFormatBytes; +} + +static bool ObjCDeclHasIVars(clang::ObjCInterfaceDecl *class_interface_decl, + bool check_superclass) { + while (class_interface_decl) { + if (class_interface_decl->ivar_size() > 0) + return true; + + if (check_superclass) + class_interface_decl = class_interface_decl->getSuperClass(); + else + break; + } + return false; +} + +static Optional +GetDynamicArrayInfo(TypeSystemClang &ast, SymbolFile *sym_file, + clang::QualType qual_type, + const ExecutionContext *exe_ctx) { + if (qual_type->isIncompleteArrayType()) + if (auto *metadata = ast.GetMetadata(qual_type.getTypePtr())) + return sym_file->GetDynamicArrayInfoForUID(metadata->GetUserID(), + exe_ctx); + return llvm::None; +} + +uint32_t TypeSystemClang::GetNumChildren(lldb::opaque_compiler_type_t type, + bool omit_empty_base_classes, + const ExecutionContext *exe_ctx) { + if (!type) + return 0; + + uint32_t num_children = 0; + clang::QualType qual_type(RemoveWrappingTypes(GetQualType(type))); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Builtin: + switch (llvm::cast(qual_type)->getKind()) { + case clang::BuiltinType::ObjCId: // child is Class + case clang::BuiltinType::ObjCClass: // child is Class + num_children = 1; + break; + + default: + break; + } + break; + + case clang::Type::Complex: + return 0; + case clang::Type::Record: + if (GetCompleteQualType(&getASTContext(), qual_type)) { + const clang::RecordType *record_type = + llvm::cast(qual_type.getTypePtr()); + const clang::RecordDecl *record_decl = record_type->getDecl(); + assert(record_decl); + const clang::CXXRecordDecl *cxx_record_decl = + llvm::dyn_cast(record_decl); + if (cxx_record_decl) { + if (omit_empty_base_classes) { + // Check each base classes to see if it or any of its base classes + // contain any fields. This can help limit the noise in variable + // views by not having to show base classes that contain no members. + clang::CXXRecordDecl::base_class_const_iterator base_class, + base_class_end; + for (base_class = cxx_record_decl->bases_begin(), + base_class_end = cxx_record_decl->bases_end(); + base_class != base_class_end; ++base_class) { + const clang::CXXRecordDecl *base_class_decl = + llvm::cast( + base_class->getType() + ->getAs() + ->getDecl()); + + // Skip empty base classes + if (!TypeSystemClang::RecordHasFields(base_class_decl)) + continue; + + num_children++; + } + } else { + // Include all base classes + num_children += cxx_record_decl->getNumBases(); + } + } + clang::RecordDecl::field_iterator field, field_end; + for (field = record_decl->field_begin(), + field_end = record_decl->field_end(); + field != field_end; ++field) + ++num_children; + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteQualType(&getASTContext(), qual_type)) { + const clang::ObjCObjectType *objc_class_type = + llvm::dyn_cast(qual_type.getTypePtr()); + assert(objc_class_type); + if (objc_class_type) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + + if (class_interface_decl) { + + clang::ObjCInterfaceDecl *superclass_interface_decl = + class_interface_decl->getSuperClass(); + if (superclass_interface_decl) { + if (omit_empty_base_classes) { + if (ObjCDeclHasIVars(superclass_interface_decl, true)) + ++num_children; + } else + ++num_children; + } + + num_children += class_interface_decl->ivar_size(); + } + } + } + break; + + case clang::Type::LValueReference: + case clang::Type::RValueReference: + case clang::Type::ObjCObjectPointer: { + CompilerType pointee_clang_type(GetPointeeType(type)); + + uint32_t num_pointee_children = 0; + if (pointee_clang_type.IsAggregateType()) + num_pointee_children = + pointee_clang_type.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; + else + num_children = num_pointee_children; + } break; + + case clang::Type::Vector: + case clang::Type::ExtVector: + num_children = + llvm::cast(qual_type.getTypePtr())->getNumElements(); + break; + + case clang::Type::ConstantArray: + num_children = llvm::cast(qual_type.getTypePtr()) + ->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 = + llvm::cast(qual_type.getTypePtr()); + clang::QualType pointee_type(pointer_type->getPointeeType()); + CompilerType pointee_clang_type(GetType(pointee_type)); + uint32_t num_pointee_children = 0; + if (pointee_clang_type.IsAggregateType()) + num_pointee_children = + pointee_clang_type.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 + num_children = GetNumPointeeChildren(pointee_type); + } else + num_children = num_pointee_children; + } break; + + default: + break; + } + return num_children; +} + +CompilerType TypeSystemClang::GetBuiltinTypeByName(ConstString name) { + return GetBasicType(GetBasicTypeEnumeration(name)); +} + +lldb::BasicType +TypeSystemClang::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) { + if (type) { + clang::QualType qual_type(GetQualType(type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + if (type_class == clang::Type::Builtin) { + switch (llvm::cast(qual_type)->getKind()) { + case clang::BuiltinType::Void: + return eBasicTypeVoid; + case clang::BuiltinType::Bool: + return eBasicTypeBool; + case clang::BuiltinType::Char_S: + return eBasicTypeSignedChar; + case clang::BuiltinType::Char_U: + return eBasicTypeUnsignedChar; + case clang::BuiltinType::Char16: + return eBasicTypeChar16; + case clang::BuiltinType::Char32: + return eBasicTypeChar32; + case clang::BuiltinType::UChar: + return eBasicTypeUnsignedChar; + case clang::BuiltinType::SChar: + return eBasicTypeSignedChar; + case clang::BuiltinType::WChar_S: + return eBasicTypeSignedWChar; + case clang::BuiltinType::WChar_U: + return eBasicTypeUnsignedWChar; + case clang::BuiltinType::Short: + return eBasicTypeShort; + case clang::BuiltinType::UShort: + return eBasicTypeUnsignedShort; + case clang::BuiltinType::Int: + return eBasicTypeInt; + case clang::BuiltinType::UInt: + return eBasicTypeUnsignedInt; + case clang::BuiltinType::Long: + return eBasicTypeLong; + case clang::BuiltinType::ULong: + return eBasicTypeUnsignedLong; + case clang::BuiltinType::LongLong: + return eBasicTypeLongLong; + case clang::BuiltinType::ULongLong: + return eBasicTypeUnsignedLongLong; + case clang::BuiltinType::Int128: + return eBasicTypeInt128; + case clang::BuiltinType::UInt128: + return eBasicTypeUnsignedInt128; + + case clang::BuiltinType::Half: + return eBasicTypeHalf; + case clang::BuiltinType::Float: + return eBasicTypeFloat; + case clang::BuiltinType::Double: + return eBasicTypeDouble; + case clang::BuiltinType::LongDouble: + return eBasicTypeLongDouble; + + case clang::BuiltinType::NullPtr: + return eBasicTypeNullPtr; + case clang::BuiltinType::ObjCId: + return eBasicTypeObjCID; + case clang::BuiltinType::ObjCClass: + return eBasicTypeObjCClass; + case clang::BuiltinType::ObjCSel: + return eBasicTypeObjCSel; + default: + return eBasicTypeOther; + } + } + } + return eBasicTypeInvalid; +} + +void TypeSystemClang::ForEachEnumerator( + lldb::opaque_compiler_type_t type, + std::function const &callback) { + const clang::EnumType *enum_type = + llvm::dyn_cast(GetCanonicalQualType(type)); + if (enum_type) { + const clang::EnumDecl *enum_decl = enum_type->getDecl(); + if (enum_decl) { + CompilerType integer_type = GetType(enum_decl->getIntegerType()); + + clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos; + for (enum_pos = enum_decl->enumerator_begin(), + enum_end_pos = enum_decl->enumerator_end(); + enum_pos != enum_end_pos; ++enum_pos) { + ConstString name(enum_pos->getNameAsString().c_str()); + if (!callback(integer_type, name, enum_pos->getInitVal())) + break; + } + } + } +} + +#pragma mark Aggregate Types + +uint32_t TypeSystemClang::GetNumFields(lldb::opaque_compiler_type_t type) { + if (!type) + return 0; + + uint32_t count = 0; + clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: + if (GetCompleteType(type)) { + const clang::RecordType *record_type = + llvm::dyn_cast(qual_type.getTypePtr()); + if (record_type) { + clang::RecordDecl *record_decl = record_type->getDecl(); + if (record_decl) { + uint32_t field_idx = 0; + clang::RecordDecl::field_iterator field, field_end; + for (field = record_decl->field_begin(), + field_end = record_decl->field_end(); + field != field_end; ++field) + ++field_idx; + count = field_idx; + } + } + } + break; + + case clang::Type::ObjCObjectPointer: { + const clang::ObjCObjectPointerType *objc_class_type = + qual_type->getAs(); + const clang::ObjCInterfaceType *objc_interface_type = + objc_class_type->getInterfaceType(); + if (objc_interface_type && + GetCompleteType(static_cast( + const_cast(objc_interface_type)))) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_interface_type->getDecl(); + if (class_interface_decl) { + count = class_interface_decl->ivar_size(); + } + } + break; + } + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteType(type)) { + const clang::ObjCObjectType *objc_class_type = + llvm::dyn_cast(qual_type.getTypePtr()); + if (objc_class_type) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + + if (class_interface_decl) + count = class_interface_decl->ivar_size(); + } + } + break; + + default: + break; + } + return count; +} + +static lldb::opaque_compiler_type_t +GetObjCFieldAtIndex(clang::ASTContext *ast, + clang::ObjCInterfaceDecl *class_interface_decl, size_t idx, + std::string &name, uint64_t *bit_offset_ptr, + uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) { + if (class_interface_decl) { + if (idx < (class_interface_decl->ivar_size())) { + clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, + ivar_end = class_interface_decl->ivar_end(); + uint32_t ivar_idx = 0; + + for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; + ++ivar_pos, ++ivar_idx) { + if (ivar_idx == idx) { + const clang::ObjCIvarDecl *ivar_decl = *ivar_pos; + + clang::QualType ivar_qual_type(ivar_decl->getType()); + + name.assign(ivar_decl->getNameAsString()); + + if (bit_offset_ptr) { + const clang::ASTRecordLayout &interface_layout = + ast->getASTObjCInterfaceLayout(class_interface_decl); + *bit_offset_ptr = interface_layout.getFieldOffset(ivar_idx); + } + + const bool is_bitfield = ivar_pos->isBitField(); + + if (bitfield_bit_size_ptr) { + *bitfield_bit_size_ptr = 0; + + if (is_bitfield && ast) { + clang::Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth(); + clang::Expr::EvalResult result; + if (bitfield_bit_size_expr && + bitfield_bit_size_expr->EvaluateAsInt(result, *ast)) { + llvm::APSInt bitfield_apsint = result.Val.getInt(); + *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue(); + } + } + } + if (is_bitfield_ptr) + *is_bitfield_ptr = is_bitfield; + + return ivar_qual_type.getAsOpaquePtr(); + } + } + } + } + return nullptr; +} + +CompilerType TypeSystemClang::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 (!type) + return CompilerType(); + + clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: + if (GetCompleteType(type)) { + const clang::RecordType *record_type = + llvm::cast(qual_type.getTypePtr()); + const clang::RecordDecl *record_decl = record_type->getDecl(); + uint32_t field_idx = 0; + clang::RecordDecl::field_iterator field, field_end; + for (field = record_decl->field_begin(), + field_end = record_decl->field_end(); + field != field_end; ++field, ++field_idx) { + if (idx == field_idx) { + // Print the member type if requested + // Print the member name and equal sign + name.assign(field->getNameAsString()); + + // Figure out the type byte size (field_type_info.first) and + // alignment (field_type_info.second) from the AST context. + if (bit_offset_ptr) { + const clang::ASTRecordLayout &record_layout = + getASTContext().getASTRecordLayout(record_decl); + *bit_offset_ptr = record_layout.getFieldOffset(field_idx); + } + + const bool is_bitfield = field->isBitField(); + + if (bitfield_bit_size_ptr) { + *bitfield_bit_size_ptr = 0; + + if (is_bitfield) { + clang::Expr *bitfield_bit_size_expr = field->getBitWidth(); + clang::Expr::EvalResult result; + if (bitfield_bit_size_expr && + bitfield_bit_size_expr->EvaluateAsInt(result, + getASTContext())) { + llvm::APSInt bitfield_apsint = result.Val.getInt(); + *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue(); + } + } + } + if (is_bitfield_ptr) + *is_bitfield_ptr = is_bitfield; + + return GetType(field->getType()); + } + } + } + break; + + case clang::Type::ObjCObjectPointer: { + const clang::ObjCObjectPointerType *objc_class_type = + qual_type->getAs(); + const clang::ObjCInterfaceType *objc_interface_type = + objc_class_type->getInterfaceType(); + if (objc_interface_type && + GetCompleteType(static_cast( + const_cast(objc_interface_type)))) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_interface_type->getDecl(); + if (class_interface_decl) { + return CompilerType( + this, GetObjCFieldAtIndex(&getASTContext(), class_interface_decl, + idx, name, bit_offset_ptr, + bitfield_bit_size_ptr, is_bitfield_ptr)); + } + } + break; + } + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteType(type)) { + const clang::ObjCObjectType *objc_class_type = + llvm::dyn_cast(qual_type.getTypePtr()); + assert(objc_class_type); + if (objc_class_type) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + return CompilerType( + this, GetObjCFieldAtIndex(&getASTContext(), class_interface_decl, + idx, name, bit_offset_ptr, + bitfield_bit_size_ptr, is_bitfield_ptr)); + } + } + break; + + default: + break; + } + return CompilerType(); +} + +uint32_t +TypeSystemClang::GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) { + uint32_t count = 0; + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: + if (GetCompleteType(type)) { + const clang::CXXRecordDecl *cxx_record_decl = + qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + count = cxx_record_decl->getNumBases(); + } + break; + + case clang::Type::ObjCObjectPointer: + count = GetPointeeType(type).GetNumDirectBaseClasses(); + break; + + case clang::Type::ObjCObject: + if (GetCompleteType(type)) { + const clang::ObjCObjectType *objc_class_type = + qual_type->getAsObjCQualifiedInterfaceType(); + if (objc_class_type) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + + if (class_interface_decl && class_interface_decl->getSuperClass()) + count = 1; + } + } + break; + case clang::Type::ObjCInterface: + if (GetCompleteType(type)) { + const clang::ObjCInterfaceType *objc_interface_type = + qual_type->getAs(); + if (objc_interface_type) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_interface_type->getInterface(); + + if (class_interface_decl && class_interface_decl->getSuperClass()) + count = 1; + } + } + break; + + default: + break; + } + return count; +} + +uint32_t +TypeSystemClang::GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) { + uint32_t count = 0; + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: + if (GetCompleteType(type)) { + const clang::CXXRecordDecl *cxx_record_decl = + qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + count = cxx_record_decl->getNumVBases(); + } + break; + + default: + break; + } + return count; +} + +CompilerType TypeSystemClang::GetDirectBaseClassAtIndex( + lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) { + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: + if (GetCompleteType(type)) { + const clang::CXXRecordDecl *cxx_record_decl = + qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) { + uint32_t curr_idx = 0; + clang::CXXRecordDecl::base_class_const_iterator base_class, + base_class_end; + for (base_class = cxx_record_decl->bases_begin(), + base_class_end = cxx_record_decl->bases_end(); + base_class != base_class_end; ++base_class, ++curr_idx) { + if (curr_idx == idx) { + if (bit_offset_ptr) { + const clang::ASTRecordLayout &record_layout = + getASTContext().getASTRecordLayout(cxx_record_decl); + const clang::CXXRecordDecl *base_class_decl = + llvm::cast( + base_class->getType() + ->getAs() + ->getDecl()); + if (base_class->isVirtual()) + *bit_offset_ptr = + record_layout.getVBaseClassOffset(base_class_decl) + .getQuantity() * + 8; + else + *bit_offset_ptr = + record_layout.getBaseClassOffset(base_class_decl) + .getQuantity() * + 8; + } + return GetType(base_class->getType()); + } + } + } + } + break; + + case clang::Type::ObjCObjectPointer: + return GetPointeeType(type).GetDirectBaseClassAtIndex(idx, bit_offset_ptr); + + case clang::Type::ObjCObject: + if (idx == 0 && GetCompleteType(type)) { + const clang::ObjCObjectType *objc_class_type = + qual_type->getAsObjCQualifiedInterfaceType(); + if (objc_class_type) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + + if (class_interface_decl) { + clang::ObjCInterfaceDecl *superclass_interface_decl = + class_interface_decl->getSuperClass(); + if (superclass_interface_decl) { + if (bit_offset_ptr) + *bit_offset_ptr = 0; + return GetType(getASTContext().getObjCInterfaceType( + superclass_interface_decl)); + } + } + } + } + break; + case clang::Type::ObjCInterface: + if (idx == 0 && GetCompleteType(type)) { + const clang::ObjCObjectType *objc_interface_type = + qual_type->getAs(); + if (objc_interface_type) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_interface_type->getInterface(); + + if (class_interface_decl) { + clang::ObjCInterfaceDecl *superclass_interface_decl = + class_interface_decl->getSuperClass(); + if (superclass_interface_decl) { + if (bit_offset_ptr) + *bit_offset_ptr = 0; + return GetType(getASTContext().getObjCInterfaceType( + superclass_interface_decl)); + } + } + } + } + break; + + default: + break; + } + return CompilerType(); +} + +CompilerType TypeSystemClang::GetVirtualBaseClassAtIndex( + lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) { + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: + if (GetCompleteType(type)) { + const clang::CXXRecordDecl *cxx_record_decl = + qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) { + uint32_t curr_idx = 0; + clang::CXXRecordDecl::base_class_const_iterator base_class, + base_class_end; + for (base_class = cxx_record_decl->vbases_begin(), + base_class_end = cxx_record_decl->vbases_end(); + base_class != base_class_end; ++base_class, ++curr_idx) { + if (curr_idx == idx) { + if (bit_offset_ptr) { + const clang::ASTRecordLayout &record_layout = + getASTContext().getASTRecordLayout(cxx_record_decl); + const clang::CXXRecordDecl *base_class_decl = + llvm::cast( + base_class->getType() + ->getAs() + ->getDecl()); + *bit_offset_ptr = + record_layout.getVBaseClassOffset(base_class_decl) + .getQuantity() * + 8; + } + return GetType(base_class->getType()); + } + } + } + } + break; + + default: + break; + } + return CompilerType(); +} + +// If a pointer to a pointee type (the clang_type arg) says that it has no +// children, then we either need to trust it, or override it and return a +// different result. For example, an "int *" has one child that is an integer, +// but a function pointer doesn't have any children. Likewise if a Record type +// claims it has no children, then there really is nothing to show. +uint32_t TypeSystemClang::GetNumPointeeChildren(clang::QualType type) { + if (type.isNull()) + return 0; + + clang::QualType qual_type = RemoveWrappingTypes(type.getCanonicalType()); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Builtin: + switch (llvm::cast(qual_type)->getKind()) { + case clang::BuiltinType::UnknownAny: + case clang::BuiltinType::Void: + case clang::BuiltinType::NullPtr: + case clang::BuiltinType::OCLEvent: + case clang::BuiltinType::OCLImage1dRO: + case clang::BuiltinType::OCLImage1dWO: + case clang::BuiltinType::OCLImage1dRW: + case clang::BuiltinType::OCLImage1dArrayRO: + case clang::BuiltinType::OCLImage1dArrayWO: + case clang::BuiltinType::OCLImage1dArrayRW: + case clang::BuiltinType::OCLImage1dBufferRO: + case clang::BuiltinType::OCLImage1dBufferWO: + case clang::BuiltinType::OCLImage1dBufferRW: + case clang::BuiltinType::OCLImage2dRO: + case clang::BuiltinType::OCLImage2dWO: + case clang::BuiltinType::OCLImage2dRW: + case clang::BuiltinType::OCLImage2dArrayRO: + case clang::BuiltinType::OCLImage2dArrayWO: + case clang::BuiltinType::OCLImage2dArrayRW: + case clang::BuiltinType::OCLImage3dRO: + case clang::BuiltinType::OCLImage3dWO: + case clang::BuiltinType::OCLImage3dRW: + case clang::BuiltinType::OCLSampler: + return 0; + case clang::BuiltinType::Bool: + case clang::BuiltinType::Char_U: + case clang::BuiltinType::UChar: + case clang::BuiltinType::WChar_U: + case clang::BuiltinType::Char16: + case clang::BuiltinType::Char32: + case clang::BuiltinType::UShort: + case clang::BuiltinType::UInt: + case clang::BuiltinType::ULong: + case clang::BuiltinType::ULongLong: + case clang::BuiltinType::UInt128: + case clang::BuiltinType::Char_S: + case clang::BuiltinType::SChar: + case clang::BuiltinType::WChar_S: + case clang::BuiltinType::Short: + case clang::BuiltinType::Int: + case clang::BuiltinType::Long: + case clang::BuiltinType::LongLong: + case clang::BuiltinType::Int128: + case clang::BuiltinType::Float: + case clang::BuiltinType::Double: + case clang::BuiltinType::LongDouble: + case clang::BuiltinType::Dependent: + case clang::BuiltinType::Overload: + case clang::BuiltinType::ObjCId: + case clang::BuiltinType::ObjCClass: + case clang::BuiltinType::ObjCSel: + case clang::BuiltinType::BoundMember: + case clang::BuiltinType::Half: + case clang::BuiltinType::ARCUnbridgedCast: + case clang::BuiltinType::PseudoObject: + case clang::BuiltinType::BuiltinFn: + case clang::BuiltinType::OMPArraySection: + return 1; + default: + return 0; + } + break; + + case clang::Type::Complex: + return 1; + case clang::Type::Pointer: + return 1; + case clang::Type::BlockPointer: + return 0; // If block pointers don't have debug info, then no children for + // them + case clang::Type::LValueReference: + return 1; + case clang::Type::RValueReference: + return 1; + case clang::Type::MemberPointer: + return 0; + case clang::Type::ConstantArray: + return 0; + case clang::Type::IncompleteArray: + return 0; + case clang::Type::VariableArray: + return 0; + case clang::Type::DependentSizedArray: + return 0; + case clang::Type::DependentSizedExtVector: + return 0; + case clang::Type::Vector: + return 0; + case clang::Type::ExtVector: + return 0; + case clang::Type::FunctionProto: + return 0; // When we function pointers, they have no children... + case clang::Type::FunctionNoProto: + return 0; // When we function pointers, they have no children... + case clang::Type::UnresolvedUsing: + return 0; + case clang::Type::Record: + return 0; + case clang::Type::Enum: + return 1; + case clang::Type::TemplateTypeParm: + return 1; + case clang::Type::SubstTemplateTypeParm: + return 1; + case clang::Type::TemplateSpecialization: + return 1; + case clang::Type::InjectedClassName: + return 0; + case clang::Type::DependentName: + return 1; + case clang::Type::DependentTemplateSpecialization: + return 1; + case clang::Type::ObjCObject: + return 0; + case clang::Type::ObjCInterface: + return 0; + case clang::Type::ObjCObjectPointer: + return 1; + default: + break; + } + return 0; +} + +CompilerType TypeSystemClang::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) { + if (!type) + return CompilerType(); + + auto get_exe_scope = [&exe_ctx]() { + return exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr; + }; + + clang::QualType parent_qual_type( + RemoveWrappingTypes(GetCanonicalQualType(type))); + const clang::Type::TypeClass parent_type_class = + parent_qual_type->getTypeClass(); + child_bitfield_bit_size = 0; + child_bitfield_bit_offset = 0; + child_is_base_class = false; + language_flags = 0; + + 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) { + switch (llvm::cast(parent_qual_type)->getKind()) { + case clang::BuiltinType::ObjCId: + case clang::BuiltinType::ObjCClass: + child_name = "isa"; + child_byte_size = + getASTContext().getTypeSize(getASTContext().ObjCBuiltinClassTy) / + CHAR_BIT; + return GetType(getASTContext().ObjCBuiltinClassTy); + + default: + break; + } + } + break; + + case clang::Type::Record: + if (idx_is_valid && GetCompleteType(type)) { + const clang::RecordType *record_type = + llvm::cast(parent_qual_type.getTypePtr()); + const clang::RecordDecl *record_decl = record_type->getDecl(); + assert(record_decl); + const clang::ASTRecordLayout &record_layout = + getASTContext().getASTRecordLayout(record_decl); + uint32_t child_idx = 0; + + const clang::CXXRecordDecl *cxx_record_decl = + llvm::dyn_cast(record_decl); + if (cxx_record_decl) { + // We might have base classes to print out first + clang::CXXRecordDecl::base_class_const_iterator base_class, + base_class_end; + for (base_class = cxx_record_decl->bases_begin(), + base_class_end = cxx_record_decl->bases_end(); + base_class != base_class_end; ++base_class) { + const clang::CXXRecordDecl *base_class_decl = nullptr; + + // Skip empty base classes + if (omit_empty_base_classes) { + base_class_decl = llvm::cast( + base_class->getType()->getAs()->getDecl()); + if (!TypeSystemClang::RecordHasFields(base_class_decl)) + continue; + } + + if (idx == child_idx) { + if (base_class_decl == nullptr) + base_class_decl = llvm::cast( + base_class->getType()->getAs()->getDecl()); + + if (base_class->isVirtual()) { + bool handled = false; + if (valobj) { + 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) + .getQuantity() * + 8; + } else + bit_offset = record_layout.getBaseClassOffset(base_class_decl) + .getQuantity() * + 8; + + // Base classes should be a multiple of 8 bits in size + child_byte_offset = bit_offset / 8; + CompilerType base_class_clang_type = GetType(base_class->getType()); + child_name = base_class_clang_type.GetTypeName().AsCString(""); + 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); + child_byte_size = base_class_clang_type_bit_size / 8; + child_is_base_class = true; + return base_class_clang_type; + } + // We don't increment the child index in the for loop since we might + // be skipping empty base classes + ++child_idx; + } + } + // Make sure index is in range... + uint32_t field_idx = 0; + clang::RecordDecl::field_iterator field, field_end; + for (field = record_decl->field_begin(), + field_end = record_decl->field_end(); + field != field_end; ++field, ++field_idx, ++child_idx) { + if (idx == child_idx) { + // Print the member type if requested + // Print the member name and equal sign + child_name.assign(field->getNameAsString()); + + // Figure out the type byte size (field_type_info.first) and + // alignment (field_type_info.second) from the AST context. + CompilerType field_clang_type = GetType(field->getType()); + assert(field_idx < record_layout.getFieldCount()); + 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 + // type + bit_offset = record_layout.getFieldOffset(field_idx); + if (FieldIsBitfield(*field, child_bitfield_bit_size)) { + child_bitfield_bit_offset = bit_offset % child_bit_size; + const uint32_t child_bit_offset = + bit_offset - child_bitfield_bit_offset; + child_byte_offset = child_bit_offset / 8; + } else { + child_byte_offset = bit_offset / 8; + } + + return field_clang_type; + } + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (idx_is_valid && GetCompleteType(type)) { + const clang::ObjCObjectType *objc_class_type = + llvm::dyn_cast(parent_qual_type.getTypePtr()); + assert(objc_class_type); + if (objc_class_type) { + uint32_t child_idx = 0; + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + + if (class_interface_decl) { + + const clang::ASTRecordLayout &interface_layout = + getASTContext().getASTObjCInterfaceLayout(class_interface_decl); + clang::ObjCInterfaceDecl *superclass_interface_decl = + class_interface_decl->getSuperClass(); + if (superclass_interface_decl) { + if (omit_empty_base_classes) { + CompilerType base_class_clang_type = + GetType(getASTContext().getObjCInterfaceType( + superclass_interface_decl)); + if (base_class_clang_type.GetNumChildren(omit_empty_base_classes, + exe_ctx) > 0) { + if (idx == 0) { + clang::QualType ivar_qual_type( + getASTContext().getObjCInterfaceType( + superclass_interface_decl)); + + child_name.assign( + superclass_interface_decl->getNameAsString()); + + clang::TypeInfo ivar_type_info = + getASTContext().getTypeInfo(ivar_qual_type.getTypePtr()); + + child_byte_size = ivar_type_info.Width / 8; + child_byte_offset = 0; + child_is_base_class = true; + + return GetType(ivar_qual_type); + } + + ++child_idx; + } + } else + ++child_idx; + } + + const uint32_t superclass_idx = child_idx; + + if (idx < (child_idx + class_interface_decl->ivar_size())) { + clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, + ivar_end = class_interface_decl->ivar_end(); + + for (ivar_pos = class_interface_decl->ivar_begin(); + ivar_pos != ivar_end; ++ivar_pos) { + if (child_idx == idx) { + clang::ObjCIvarDecl *ivar_decl = *ivar_pos; + + clang::QualType ivar_qual_type(ivar_decl->getType()); + + child_name.assign(ivar_decl->getNameAsString()); + + clang::TypeInfo ivar_type_info = + getASTContext().getTypeInfo(ivar_qual_type.getTypePtr()); + + child_byte_size = ivar_type_info.Width / 8; + + // Figure out the field offset within the current + // struct/union/class type For ObjC objects, we can't trust the + // bit offset we get from the Clang AST, since that doesn't + // account for the space taken up by unbacked properties, or + // from the changing size of base classes that are newer than + // this class. So if we have a process around that we can ask + // about this object, do so. + child_byte_offset = LLDB_INVALID_IVAR_OFFSET; + Process *process = nullptr; + if (exe_ctx) + process = exe_ctx->GetProcessPtr(); + if (process) { + ObjCLanguageRuntime *objc_runtime = + ObjCLanguageRuntime::Get(*process); + if (objc_runtime != nullptr) { + CompilerType parent_ast_type = GetType(parent_qual_type); + child_byte_offset = objc_runtime->GetByteOffsetForIvar( + parent_ast_type, ivar_decl->getNameAsString().c_str()); + } + } + + // Setting this to INT32_MAX to make sure we don't compute it + // twice... + bit_offset = INT32_MAX; + + if (child_byte_offset == + static_cast(LLDB_INVALID_IVAR_OFFSET)) { + bit_offset = interface_layout.getFieldOffset(child_idx - + superclass_idx); + child_byte_offset = bit_offset / 8; + } + + // Note, the ObjC Ivar Byte offset is just that, it doesn't + // account for the bit offset of a bitfield within its + // containing object. So regardless of where we get the byte + // offset from, we still need to get the bit offset for + // bitfields from the layout. + + if (FieldIsBitfield(ivar_decl, child_bitfield_bit_size)) { + if (bit_offset == INT32_MAX) + bit_offset = interface_layout.getFieldOffset( + child_idx - superclass_idx); + + child_bitfield_bit_offset = bit_offset % 8; + } + return GetType(ivar_qual_type); + } + ++child_idx; + } + } + } + } + } + break; + + case clang::Type::ObjCObjectPointer: + if (idx_is_valid) { + CompilerType pointee_clang_type(GetPointeeType(type)); + + if (transparent_pointers && pointee_clang_type.IsAggregateType()) { + child_is_deref_of_parent = false; + bool tmp_child_is_deref_of_parent = false; + return pointee_clang_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, tmp_child_is_deref_of_parent, valobj, + language_flags); + } else { + child_is_deref_of_parent = true; + const char *parent_name = + valobj ? valobj->GetName().GetCString() : nullptr; + if (parent_name) { + child_name.assign(1, '*'); + child_name += parent_name; + } + + // We have a pointer to an simple type + if (idx == 0 && pointee_clang_type.GetCompleteType()) { + if (Optional size = + pointee_clang_type.GetByteSize(get_exe_scope())) { + child_byte_size = *size; + child_byte_offset = 0; + return pointee_clang_type; + } + } + } + } + break; + + case clang::Type::Vector: + case clang::Type::ExtVector: + if (idx_is_valid) { + const clang::VectorType *array = + llvm::cast(parent_qual_type.getTypePtr()); + if (array) { + CompilerType element_type = GetType(array->getElementType()); + if (element_type.GetCompleteType()) { + char element_name[64]; + ::snprintf(element_name, sizeof(element_name), "[%" PRIu64 "]", + static_cast(idx)); + child_name.assign(element_name); + 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; + } + } + } + } + break; + + case clang::Type::ConstantArray: + case clang::Type::IncompleteArray: + if (ignore_array_bounds || idx_is_valid) { + const clang::ArrayType *array = GetQualType(type)->getAsArrayTypeUnsafe(); + if (array) { + CompilerType element_type = GetType(array->getElementType()); + if (element_type.GetCompleteType()) { + child_name = std::string(llvm::formatv("[{0}]", idx)); + 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; + } + } + } + } + break; + + case clang::Type::Pointer: { + CompilerType pointee_clang_type(GetPointeeType(type)); + + // Don't dereference "void *" pointers + if (pointee_clang_type.IsVoidType()) + return CompilerType(); + + if (transparent_pointers && pointee_clang_type.IsAggregateType()) { + child_is_deref_of_parent = false; + bool tmp_child_is_deref_of_parent = false; + return pointee_clang_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, tmp_child_is_deref_of_parent, valobj, + language_flags); + } else { + child_is_deref_of_parent = true; + + const char *parent_name = + valobj ? valobj->GetName().GetCString() : nullptr; + if (parent_name) { + child_name.assign(1, '*'); + child_name += parent_name; + } + + // We have a pointer to an simple type + if (idx == 0) { + if (Optional size = + pointee_clang_type.GetByteSize(get_exe_scope())) { + child_byte_size = *size; + child_byte_offset = 0; + return pointee_clang_type; + } + } + } + break; + } + + case clang::Type::LValueReference: + case clang::Type::RValueReference: + if (idx_is_valid) { + const clang::ReferenceType *reference_type = + llvm::cast(parent_qual_type.getTypePtr()); + CompilerType pointee_clang_type = + GetType(reference_type->getPointeeType()); + if (transparent_pointers && pointee_clang_type.IsAggregateType()) { + child_is_deref_of_parent = false; + bool tmp_child_is_deref_of_parent = false; + return pointee_clang_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, tmp_child_is_deref_of_parent, valobj, + language_flags); + } else { + const char *parent_name = + valobj ? valobj->GetName().GetCString() : nullptr; + if (parent_name) { + child_name.assign(1, '&'); + child_name += parent_name; + } + + // We have a pointer to an simple type + if (idx == 0) { + if (Optional size = + pointee_clang_type.GetByteSize(get_exe_scope())) { + child_byte_size = *size; + child_byte_offset = 0; + return pointee_clang_type; + } + } + } + } + break; + + default: + break; + } + return CompilerType(); +} + +static uint32_t GetIndexForRecordBase(const clang::RecordDecl *record_decl, + const clang::CXXBaseSpecifier *base_spec, + bool omit_empty_base_classes) { + uint32_t child_idx = 0; + + const clang::CXXRecordDecl *cxx_record_decl = + llvm::dyn_cast(record_decl); + + if (cxx_record_decl) { + clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end; + for (base_class = cxx_record_decl->bases_begin(), + base_class_end = cxx_record_decl->bases_end(); + base_class != base_class_end; ++base_class) { + if (omit_empty_base_classes) { + if (BaseSpecifierIsEmpty(base_class)) + continue; + } + + if (base_class == base_spec) + return child_idx; + ++child_idx; + } + } + + return UINT32_MAX; +} + +static uint32_t GetIndexForRecordChild(const clang::RecordDecl *record_decl, + clang::NamedDecl *canonical_decl, + bool omit_empty_base_classes) { + uint32_t child_idx = TypeSystemClang::GetNumBaseClasses( + llvm::dyn_cast(record_decl), + omit_empty_base_classes); + + clang::RecordDecl::field_iterator field, field_end; + for (field = record_decl->field_begin(), field_end = record_decl->field_end(); + field != field_end; ++field, ++child_idx) { + if (field->getCanonicalDecl() == canonical_decl) + return child_idx; + } + + return UINT32_MAX; +} + +// Look for a child member (doesn't include base classes, but it does include +// their members) in the type hierarchy. Returns an index path into +// "clang_type" on how to reach the appropriate member. +// +// class A +// { +// public: +// int m_a; +// int m_b; +// }; +// +// class B +// { +// }; +// +// class C : +// public B, +// public A +// { +// }; +// +// If we have a clang type that describes "class C", and we wanted to looked +// "m_b" in it: +// +// With omit_empty_base_classes == false we would get an integer array back +// with: { 1, 1 } The first index 1 is the child index for "class A" within +// class C The second index 1 is the child index for "m_b" within class A +// +// With omit_empty_base_classes == true we would get an integer array back +// with: { 0, 1 } The first index 0 is the child index for "class A" within +// class C (since class B doesn't have any members it doesn't count) The second +// index 1 is the child index for "m_b" within class A + +size_t TypeSystemClang::GetIndexOfChildMemberWithName( + lldb::opaque_compiler_type_t type, const char *name, + bool omit_empty_base_classes, std::vector &child_indexes) { + if (type && name && name[0]) { + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: + if (GetCompleteType(type)) { + const clang::RecordType *record_type = + llvm::cast(qual_type.getTypePtr()); + const clang::RecordDecl *record_decl = record_type->getDecl(); + + assert(record_decl); + uint32_t child_idx = 0; + + const clang::CXXRecordDecl *cxx_record_decl = + llvm::dyn_cast(record_decl); + + // Try and find a field that matches NAME + clang::RecordDecl::field_iterator field, field_end; + llvm::StringRef name_sref(name); + for (field = record_decl->field_begin(), + field_end = record_decl->field_end(); + field != field_end; ++field, ++child_idx) { + llvm::StringRef field_name = field->getName(); + if (field_name.empty()) { + CompilerType field_type = GetType(field->getType()); + child_indexes.push_back(child_idx); + if (field_type.GetIndexOfChildMemberWithName( + name, omit_empty_base_classes, child_indexes)) + return child_indexes.size(); + child_indexes.pop_back(); + + } else if (field_name.equals(name_sref)) { + // We have to add on the number of base classes to this index! + child_indexes.push_back( + child_idx + TypeSystemClang::GetNumBaseClasses( + cxx_record_decl, omit_empty_base_classes)); + return child_indexes.size(); + } + } + + if (cxx_record_decl) { + const clang::RecordDecl *parent_record_decl = cxx_record_decl; + + // Didn't find things easily, lets let clang do its thang... + clang::IdentifierInfo &ident_ref = + getASTContext().Idents.get(name_sref); + clang::DeclarationName decl_name(&ident_ref); + + clang::CXXBasePaths paths; + if (cxx_record_decl->lookupInBases( + [decl_name](const clang::CXXBaseSpecifier *specifier, + clang::CXXBasePath &path) { + return clang::CXXRecordDecl::FindOrdinaryMember( + specifier, path, decl_name); + }, + paths)) { + clang::CXXBasePaths::const_paths_iterator path, + path_end = paths.end(); + for (path = paths.begin(); path != path_end; ++path) { + const size_t num_path_elements = path->size(); + for (size_t e = 0; e < num_path_elements; ++e) { + clang::CXXBasePathElement elem = (*path)[e]; + + child_idx = GetIndexForRecordBase(parent_record_decl, elem.Base, + omit_empty_base_classes); + if (child_idx == UINT32_MAX) { + child_indexes.clear(); + return 0; + } else { + child_indexes.push_back(child_idx); + parent_record_decl = llvm::cast( + elem.Base->getType() + ->getAs() + ->getDecl()); + } + } + for (clang::NamedDecl *path_decl : path->Decls) { + child_idx = GetIndexForRecordChild( + parent_record_decl, path_decl, omit_empty_base_classes); + if (child_idx == UINT32_MAX) { + child_indexes.clear(); + return 0; + } else { + child_indexes.push_back(child_idx); + } + } + } + return child_indexes.size(); + } + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteType(type)) { + llvm::StringRef name_sref(name); + const clang::ObjCObjectType *objc_class_type = + llvm::dyn_cast(qual_type.getTypePtr()); + assert(objc_class_type); + if (objc_class_type) { + uint32_t child_idx = 0; + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + + if (class_interface_decl) { + clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, + ivar_end = class_interface_decl->ivar_end(); + clang::ObjCInterfaceDecl *superclass_interface_decl = + class_interface_decl->getSuperClass(); + + for (ivar_pos = class_interface_decl->ivar_begin(); + ivar_pos != ivar_end; ++ivar_pos, ++child_idx) { + const clang::ObjCIvarDecl *ivar_decl = *ivar_pos; + + if (ivar_decl->getName().equals(name_sref)) { + if ((!omit_empty_base_classes && superclass_interface_decl) || + (omit_empty_base_classes && + ObjCDeclHasIVars(superclass_interface_decl, true))) + ++child_idx; + + child_indexes.push_back(child_idx); + return child_indexes.size(); + } + } + + if (superclass_interface_decl) { + // The super class index is always zero for ObjC classes, so we + // push it onto the child indexes in case we find an ivar in our + // superclass... + child_indexes.push_back(0); + + CompilerType superclass_clang_type = + GetType(getASTContext().getObjCInterfaceType( + superclass_interface_decl)); + if (superclass_clang_type.GetIndexOfChildMemberWithName( + name, omit_empty_base_classes, child_indexes)) { + // We did find an ivar in a superclass so just return the + // results! + return child_indexes.size(); + } + + // We didn't find an ivar matching "name" in our superclass, pop + // the superclass zero index that we pushed on above. + child_indexes.pop_back(); + } + } + } + } + break; + + case clang::Type::ObjCObjectPointer: { + CompilerType objc_object_clang_type = GetType( + llvm::cast(qual_type.getTypePtr()) + ->getPointeeType()); + return objc_object_clang_type.GetIndexOfChildMemberWithName( + name, omit_empty_base_classes, child_indexes); + } break; + + case clang::Type::ConstantArray: { + // const clang::ConstantArrayType *array = + // llvm::cast(parent_qual_type.getTypePtr()); + // const uint64_t element_count = + // array->getSize().getLimitedValue(); + // + // if (idx < element_count) + // { + // std::pair field_type_info = + // ast->getTypeInfo(array->getElementType()); + // + // char element_name[32]; + // ::snprintf (element_name, sizeof (element_name), + // "%s[%u]", parent_name ? parent_name : "", idx); + // + // child_name.assign(element_name); + // assert(field_type_info.first % 8 == 0); + // child_byte_size = field_type_info.first / 8; + // child_byte_offset = idx * child_byte_size; + // return array->getElementType().getAsOpaquePtr(); + // } + } break; + + // case clang::Type::MemberPointerType: + // { + // MemberPointerType *mem_ptr_type = + // llvm::cast(qual_type.getTypePtr()); + // clang::QualType pointee_type = + // mem_ptr_type->getPointeeType(); + // + // if (TypeSystemClang::IsAggregateType + // (pointee_type.getAsOpaquePtr())) + // { + // return GetIndexOfChildWithName (ast, + // mem_ptr_type->getPointeeType().getAsOpaquePtr(), + // name); + // } + // } + // break; + // + case clang::Type::LValueReference: + case clang::Type::RValueReference: { + const clang::ReferenceType *reference_type = + llvm::cast(qual_type.getTypePtr()); + clang::QualType pointee_type(reference_type->getPointeeType()); + CompilerType pointee_clang_type = GetType(pointee_type); + + if (pointee_clang_type.IsAggregateType()) { + return pointee_clang_type.GetIndexOfChildMemberWithName( + name, omit_empty_base_classes, child_indexes); + } + } break; + + case clang::Type::Pointer: { + CompilerType pointee_clang_type(GetPointeeType(type)); + + if (pointee_clang_type.IsAggregateType()) { + return pointee_clang_type.GetIndexOfChildMemberWithName( + name, omit_empty_base_classes, child_indexes); + } + } break; + + default: + break; + } + } + return 0; +} + +// Get the index of the child of "clang_type" whose name matches. This function +// doesn't descend into the children, but only looks one level deep and name +// matches can include base class names. + +uint32_t +TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, + const char *name, + bool omit_empty_base_classes) { + if (type && name && name[0]) { + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + + switch (type_class) { + case clang::Type::Record: + if (GetCompleteType(type)) { + const clang::RecordType *record_type = + llvm::cast(qual_type.getTypePtr()); + const clang::RecordDecl *record_decl = record_type->getDecl(); + + assert(record_decl); + uint32_t child_idx = 0; + + const clang::CXXRecordDecl *cxx_record_decl = + llvm::dyn_cast(record_decl); + + if (cxx_record_decl) { + clang::CXXRecordDecl::base_class_const_iterator base_class, + base_class_end; + for (base_class = cxx_record_decl->bases_begin(), + base_class_end = cxx_record_decl->bases_end(); + base_class != base_class_end; ++base_class) { + // Skip empty base classes + clang::CXXRecordDecl *base_class_decl = + llvm::cast( + base_class->getType() + ->getAs() + ->getDecl()); + if (omit_empty_base_classes && + !TypeSystemClang::RecordHasFields(base_class_decl)) + continue; + + CompilerType base_class_clang_type = GetType(base_class->getType()); + std::string base_class_type_name( + base_class_clang_type.GetTypeName().AsCString("")); + if (base_class_type_name == name) + return child_idx; + ++child_idx; + } + } + + // Try and find a field that matches NAME + clang::RecordDecl::field_iterator field, field_end; + llvm::StringRef name_sref(name); + for (field = record_decl->field_begin(), + field_end = record_decl->field_end(); + field != field_end; ++field, ++child_idx) { + if (field->getName().equals(name_sref)) + return child_idx; + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteType(type)) { + llvm::StringRef name_sref(name); + const clang::ObjCObjectType *objc_class_type = + llvm::dyn_cast(qual_type.getTypePtr()); + assert(objc_class_type); + if (objc_class_type) { + uint32_t child_idx = 0; + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + + if (class_interface_decl) { + clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, + ivar_end = class_interface_decl->ivar_end(); + clang::ObjCInterfaceDecl *superclass_interface_decl = + class_interface_decl->getSuperClass(); + + for (ivar_pos = class_interface_decl->ivar_begin(); + ivar_pos != ivar_end; ++ivar_pos, ++child_idx) { + const clang::ObjCIvarDecl *ivar_decl = *ivar_pos; + + if (ivar_decl->getName().equals(name_sref)) { + if ((!omit_empty_base_classes && superclass_interface_decl) || + (omit_empty_base_classes && + ObjCDeclHasIVars(superclass_interface_decl, true))) + ++child_idx; + + return child_idx; + } + } + + if (superclass_interface_decl) { + if (superclass_interface_decl->getName().equals(name_sref)) + return 0; + } + } + } + } + break; + + case clang::Type::ObjCObjectPointer: { + CompilerType pointee_clang_type = GetType( + llvm::cast(qual_type.getTypePtr()) + ->getPointeeType()); + return pointee_clang_type.GetIndexOfChildWithName( + name, omit_empty_base_classes); + } break; + + case clang::Type::ConstantArray: { + // const clang::ConstantArrayType *array = + // llvm::cast(parent_qual_type.getTypePtr()); + // const uint64_t element_count = + // array->getSize().getLimitedValue(); + // + // if (idx < element_count) + // { + // std::pair field_type_info = + // ast->getTypeInfo(array->getElementType()); + // + // char element_name[32]; + // ::snprintf (element_name, sizeof (element_name), + // "%s[%u]", parent_name ? parent_name : "", idx); + // + // child_name.assign(element_name); + // assert(field_type_info.first % 8 == 0); + // child_byte_size = field_type_info.first / 8; + // child_byte_offset = idx * child_byte_size; + // return array->getElementType().getAsOpaquePtr(); + // } + } break; + + // case clang::Type::MemberPointerType: + // { + // MemberPointerType *mem_ptr_type = + // llvm::cast(qual_type.getTypePtr()); + // clang::QualType pointee_type = + // mem_ptr_type->getPointeeType(); + // + // if (TypeSystemClang::IsAggregateType + // (pointee_type.getAsOpaquePtr())) + // { + // return GetIndexOfChildWithName (ast, + // mem_ptr_type->getPointeeType().getAsOpaquePtr(), + // name); + // } + // } + // break; + // + case clang::Type::LValueReference: + case clang::Type::RValueReference: { + const clang::ReferenceType *reference_type = + llvm::cast(qual_type.getTypePtr()); + CompilerType pointee_type = GetType(reference_type->getPointeeType()); + + if (pointee_type.IsAggregateType()) { + return pointee_type.GetIndexOfChildWithName(name, + omit_empty_base_classes); + } + } break; + + case clang::Type::Pointer: { + const clang::PointerType *pointer_type = + llvm::cast(qual_type.getTypePtr()); + CompilerType pointee_type = GetType(pointer_type->getPointeeType()); + + if (pointee_type.IsAggregateType()) { + return pointee_type.GetIndexOfChildWithName(name, + omit_empty_base_classes); + } else { + // if (parent_name) + // { + // child_name.assign(1, '*'); + // child_name += parent_name; + // } + // + // // We have a pointer to an simple type + // if (idx == 0) + // { + // std::pair clang_type_info + // = ast->getTypeInfo(pointee_type); + // assert(clang_type_info.first % 8 == 0); + // child_byte_size = clang_type_info.first / 8; + // child_byte_offset = 0; + // return pointee_type.getAsOpaquePtr(); + // } + } + } break; + + default: + break; + } + } + return UINT32_MAX; +} + +size_t +TypeSystemClang::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) { + if (!type) + return 0; + + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: + if (GetCompleteType(type)) { + const clang::CXXRecordDecl *cxx_record_decl = + qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) { + const clang::ClassTemplateSpecializationDecl *template_decl = + llvm::dyn_cast( + cxx_record_decl); + if (template_decl) + return template_decl->getTemplateArgs().size(); + } + } + break; + + default: + break; + } + + return 0; +} + +const clang::ClassTemplateSpecializationDecl * +TypeSystemClang::GetAsTemplateSpecialization( + lldb::opaque_compiler_type_t type) { + if (!type) + return nullptr; + + clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: { + if (! GetCompleteType(type)) + return nullptr; + const clang::CXXRecordDecl *cxx_record_decl = + qual_type->getAsCXXRecordDecl(); + if (!cxx_record_decl) + return nullptr; + return llvm::dyn_cast( + cxx_record_decl); + } + + default: + return nullptr; + } +} + +lldb::TemplateArgumentKind +TypeSystemClang::GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, + size_t arg_idx) { + const clang::ClassTemplateSpecializationDecl *template_decl = + GetAsTemplateSpecialization(type); + if (! template_decl || arg_idx >= template_decl->getTemplateArgs().size()) + return eTemplateArgumentKindNull; + + switch (template_decl->getTemplateArgs()[arg_idx].getKind()) { + case clang::TemplateArgument::Null: + return eTemplateArgumentKindNull; + + case clang::TemplateArgument::NullPtr: + return eTemplateArgumentKindNullPtr; + + case clang::TemplateArgument::Type: + return eTemplateArgumentKindType; + + case clang::TemplateArgument::Declaration: + return eTemplateArgumentKindDeclaration; + + case clang::TemplateArgument::Integral: + return eTemplateArgumentKindIntegral; + + case clang::TemplateArgument::Template: + return eTemplateArgumentKindTemplate; + + case clang::TemplateArgument::TemplateExpansion: + return eTemplateArgumentKindTemplateExpansion; + + case clang::TemplateArgument::Expression: + return eTemplateArgumentKindExpression; + + case clang::TemplateArgument::Pack: + return eTemplateArgumentKindPack; + } + llvm_unreachable("Unhandled clang::TemplateArgument::ArgKind"); +} + +CompilerType +TypeSystemClang::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, + size_t idx) { + const clang::ClassTemplateSpecializationDecl *template_decl = + GetAsTemplateSpecialization(type); + if (!template_decl || idx >= template_decl->getTemplateArgs().size()) + return CompilerType(); + + const clang::TemplateArgument &template_arg = + template_decl->getTemplateArgs()[idx]; + if (template_arg.getKind() != clang::TemplateArgument::Type) + return CompilerType(); + + return GetType(template_arg.getAsType()); +} + +Optional +TypeSystemClang::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, + size_t idx) { + const clang::ClassTemplateSpecializationDecl *template_decl = + GetAsTemplateSpecialization(type); + if (! template_decl || idx >= template_decl->getTemplateArgs().size()) + return llvm::None; + + const clang::TemplateArgument &template_arg = + template_decl->getTemplateArgs()[idx]; + if (template_arg.getKind() != clang::TemplateArgument::Integral) + return llvm::None; + + return { + {template_arg.getAsIntegral(), GetType(template_arg.getIntegralType())}}; +} + +CompilerType TypeSystemClang::GetTypeForFormatters(void *type) { + if (type) + return ClangUtil::RemoveFastQualifiers(CompilerType(this, type)); + return CompilerType(); +} + +clang::EnumDecl *TypeSystemClang::GetAsEnumDecl(const CompilerType &type) { + const clang::EnumType *enutype = + llvm::dyn_cast(ClangUtil::GetCanonicalQualType(type)); + if (enutype) + return enutype->getDecl(); + return nullptr; +} + +clang::RecordDecl *TypeSystemClang::GetAsRecordDecl(const CompilerType &type) { + const clang::RecordType *record_type = + llvm::dyn_cast(ClangUtil::GetCanonicalQualType(type)); + if (record_type) + return record_type->getDecl(); + return nullptr; +} + +clang::TagDecl *TypeSystemClang::GetAsTagDecl(const CompilerType &type) { + return ClangUtil::GetAsTagDecl(type); +} + +clang::TypedefNameDecl * +TypeSystemClang::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 * +TypeSystemClang::GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type) { + return GetCanonicalQualType(type)->getAsCXXRecordDecl(); +} + +clang::ObjCInterfaceDecl * +TypeSystemClang::GetAsObjCInterfaceDecl(const CompilerType &type) { + const clang::ObjCObjectType *objc_class_type = + llvm::dyn_cast( + ClangUtil::GetCanonicalQualType(type)); + if (objc_class_type) + return objc_class_type->getInterface(); + return nullptr; +} + +clang::FieldDecl *TypeSystemClang::AddFieldToRecordType( + 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()) + return nullptr; + TypeSystemClang *ast = + llvm::dyn_cast_or_null(type.GetTypeSystem()); + 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; + + clang::Expr *bit_width = nullptr; + if (bitfield_bit_size != 0) { + llvm::APInt bitfield_bit_size_apint(clang_ast.getTypeSize(clang_ast.IntTy), + bitfield_bit_size); + bit_width = new (clang_ast) + clang::IntegerLiteral(clang_ast, bitfield_bit_size_apint, + clang_ast.IntTy, clang::SourceLocation()); + } + + clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type); + if (record_decl) { + field = clang::FieldDecl::CreateDeserialized(clang_ast, 0); + field->setDeclContext(record_decl); + field->setDeclName(ident); + field->setType(ClangUtil::GetQualType(field_clang_type)); + if (bit_width) + field->setBitWidth(bit_width); + SetMemberOwningModule(field, record_decl); + + if (name.empty()) { + // Determine whether this field corresponds to an anonymous struct or + // union. + if (const clang::TagType *TagT = + field->getType()->getAs()) { + if (clang::RecordDecl *Rec = + llvm::dyn_cast(TagT->getDecl())) + if (!Rec->getDeclName()) { + Rec->setAnonymousStructOrUnion(true); + field->setImplicit(); + } + } + } + + if (field) { + field->setAccess( + TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access)); + + record_decl->addDecl(field); + + VerifyDecl(field); + } + } else { + clang::ObjCInterfaceDecl *class_interface_decl = + ast->GetAsObjCInterfaceDecl(type); + + if (class_interface_decl) { + const bool is_synthesized = false; + + field_clang_type.GetCompleteType(); + + auto *ivar = clang::ObjCIvarDecl::CreateDeserialized(clang_ast, 0); + ivar->setDeclContext(class_interface_decl); + ivar->setDeclName(ident); + ivar->setType(ClangUtil::GetQualType(field_clang_type)); + ivar->setAccessControl(ConvertAccessTypeToObjCIvarAccessControl(access)); + if (bit_width) + ivar->setBitWidth(bit_width); + ivar->setSynthesize(is_synthesized); + field = ivar; + SetMemberOwningModule(field, class_interface_decl); + + if (field) { + class_interface_decl->addDecl(field); + + VerifyDecl(field); + } + } + } + return field; +} + +void TypeSystemClang::BuildIndirectFields(const CompilerType &type) { + if (!type) + return; + + TypeSystemClang *ast = llvm::dyn_cast(type.GetTypeSystem()); + if (!ast) + return; + + clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type); + + if (!record_decl) + return; + + typedef llvm::SmallVector IndirectFieldVector; + + IndirectFieldVector indirect_fields; + clang::RecordDecl::field_iterator field_pos; + clang::RecordDecl::field_iterator field_end_pos = record_decl->field_end(); + clang::RecordDecl::field_iterator last_field_pos = field_end_pos; + for (field_pos = record_decl->field_begin(); field_pos != field_end_pos; + last_field_pos = field_pos++) { + if (field_pos->isAnonymousStructOrUnion()) { + clang::QualType field_qual_type = field_pos->getType(); + + const clang::RecordType *field_record_type = + field_qual_type->getAs(); + + if (!field_record_type) + continue; + + clang::RecordDecl *field_record_decl = field_record_type->getDecl(); + + if (!field_record_decl) + continue; + + for (clang::RecordDecl::decl_iterator + di = field_record_decl->decls_begin(), + de = field_record_decl->decls_end(); + di != de; ++di) { + if (clang::FieldDecl *nested_field_decl = + llvm::dyn_cast(*di)) { + clang::NamedDecl **chain = + new (ast->getASTContext()) clang::NamedDecl *[2]; + chain[0] = *field_pos; + chain[1] = nested_field_decl; + clang::IndirectFieldDecl *indirect_field = + clang::IndirectFieldDecl::Create( + ast->getASTContext(), record_decl, clang::SourceLocation(), + nested_field_decl->getIdentifier(), + nested_field_decl->getType(), {chain, 2}); + SetMemberOwningModule(indirect_field, record_decl); + + indirect_field->setImplicit(); + + indirect_field->setAccess(TypeSystemClang::UnifyAccessSpecifiers( + field_pos->getAccess(), nested_field_decl->getAccess())); + + indirect_fields.push_back(indirect_field); + } else if (clang::IndirectFieldDecl *nested_indirect_field_decl = + llvm::dyn_cast(*di)) { + size_t nested_chain_size = + nested_indirect_field_decl->getChainingSize(); + clang::NamedDecl **chain = new (ast->getASTContext()) + clang::NamedDecl *[nested_chain_size + 1]; + chain[0] = *field_pos; + + int chain_index = 1; + for (clang::IndirectFieldDecl::chain_iterator + nci = nested_indirect_field_decl->chain_begin(), + nce = nested_indirect_field_decl->chain_end(); + nci < nce; ++nci) { + chain[chain_index] = *nci; + chain_index++; + } + + clang::IndirectFieldDecl *indirect_field = + clang::IndirectFieldDecl::Create( + ast->getASTContext(), record_decl, clang::SourceLocation(), + nested_indirect_field_decl->getIdentifier(), + nested_indirect_field_decl->getType(), + {chain, nested_chain_size + 1}); + SetMemberOwningModule(indirect_field, record_decl); + + indirect_field->setImplicit(); + + indirect_field->setAccess(TypeSystemClang::UnifyAccessSpecifiers( + field_pos->getAccess(), nested_indirect_field_decl->getAccess())); + + indirect_fields.push_back(indirect_field); + } + } + } + } + + // Check the last field to see if it has an incomplete array type as its last + // member and if it does, the tell the record decl about it + if (last_field_pos != field_end_pos) { + if (last_field_pos->getType()->isIncompleteArrayType()) + record_decl->hasFlexibleArrayMember(); + } + + for (IndirectFieldVector::iterator ifi = indirect_fields.begin(), + ife = indirect_fields.end(); + ifi < ife; ++ifi) { + record_decl->addDecl(*ifi); + } +} + +void TypeSystemClang::SetIsPacked(const CompilerType &type) { + if (type) { + TypeSystemClang *ast = + llvm::dyn_cast(type.GetTypeSystem()); + if (ast) { + clang::RecordDecl *record_decl = GetAsRecordDecl(type); + + if (!record_decl) + return; + + record_decl->addAttr( + clang::PackedAttr::CreateImplicit(ast->getASTContext())); + } + } +} + +clang::VarDecl *TypeSystemClang::AddVariableToRecordType( + const CompilerType &type, llvm::StringRef name, + const CompilerType &var_type, AccessType access) { + if (!type.IsValid() || !var_type.IsValid()) + return nullptr; + + TypeSystemClang *ast = llvm::dyn_cast(type.GetTypeSystem()); + if (!ast) + return nullptr; + + clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type); + 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::CreateDeserialized(ast->getASTContext(), 0); + var_decl->setDeclContext(record_decl); + var_decl->setDeclName(ident); + var_decl->setType(ClangUtil::GetQualType(var_type)); + var_decl->setStorageClass(clang::SC_Static); + SetMemberOwningModule(var_decl, record_decl); + if (!var_decl) + return nullptr; + + var_decl->setAccess( + TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access)); + record_decl->addDecl(var_decl); + + VerifyDecl(var_decl); + + return var_decl; +} + +void TypeSystemClang::SetIntegerInitializerForVariable( + VarDecl *var, const llvm::APInt &init_value) { + assert(!var->hasInit() && "variable already initialized"); + + clang::ASTContext &ast = var->getASTContext(); + QualType qt = var->getType(); + assert(qt->isIntegralOrEnumerationType() && + "only integer or enum types supported"); + // If the variable is an enum type, take the underlying integer type as + // the type of the integer literal. + if (const EnumType *enum_type = llvm::dyn_cast(qt.getTypePtr())) { + const EnumDecl *enum_decl = enum_type->getDecl(); + qt = enum_decl->getIntegerType(); + } + var->setInit(IntegerLiteral::Create(ast, init_value, qt.getUnqualifiedType(), + SourceLocation())); +} + +void TypeSystemClang::SetFloatingInitializerForVariable( + clang::VarDecl *var, const llvm::APFloat &init_value) { + assert(!var->hasInit() && "variable already initialized"); + + clang::ASTContext &ast = var->getASTContext(); + QualType qt = var->getType(); + assert(qt->isFloatingType() && "only floating point types supported"); + var->setInit(FloatingLiteral::Create( + ast, init_value, true, qt.getUnqualifiedType(), SourceLocation())); +} + +clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType( + lldb::opaque_compiler_type_t type, llvm::StringRef name, + const char *mangled_name, const CompilerType &method_clang_type, + lldb::AccessType access, bool is_virtual, bool is_static, bool is_inline, + bool is_explicit, bool is_attr_used, bool is_artificial) { + if (!type || !method_clang_type.IsValid() || name.empty()) + return nullptr; + + clang::QualType record_qual_type(GetCanonicalQualType(type)); + + clang::CXXRecordDecl *cxx_record_decl = + record_qual_type->getAsCXXRecordDecl(); + + if (cxx_record_decl == nullptr) + return nullptr; + + clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type)); + + clang::CXXMethodDecl *cxx_method_decl = nullptr; + + clang::DeclarationName decl_name(&getASTContext().Idents.get(name)); + + const clang::FunctionType *function_type = + llvm::dyn_cast(method_qual_type.getTypePtr()); + + if (function_type == nullptr) + return nullptr; + + const clang::FunctionProtoType *method_function_prototype( + llvm::dyn_cast(function_type)); + + if (!method_function_prototype) + return nullptr; + + unsigned int num_params = method_function_prototype->getNumParams(); + + clang::CXXDestructorDecl *cxx_dtor_decl(nullptr); + clang::CXXConstructorDecl *cxx_ctor_decl(nullptr); + + if (is_artificial) + return nullptr; // skip everything artificial + + const clang::ExplicitSpecifier explicit_spec( + nullptr /*expr*/, is_explicit ? clang::ExplicitSpecKind::ResolvedTrue + : clang::ExplicitSpecKind::ResolvedFalse); + + if (name.startswith("~")) { + cxx_dtor_decl = + clang::CXXDestructorDecl::CreateDeserialized(getASTContext(), 0); + cxx_dtor_decl->setDeclContext(cxx_record_decl); + cxx_dtor_decl->setDeclName( + getASTContext().DeclarationNames.getCXXDestructorName( + getASTContext().getCanonicalType(record_qual_type))); + cxx_dtor_decl->setType(method_qual_type); + cxx_dtor_decl->setImplicit(is_artificial); + cxx_dtor_decl->setInlineSpecified(is_inline); + cxx_dtor_decl->setConstexprKind(CSK_unspecified); + cxx_method_decl = cxx_dtor_decl; + } else if (decl_name == cxx_record_decl->getDeclName()) { + cxx_ctor_decl = clang::CXXConstructorDecl::CreateDeserialized( + getASTContext(), 0, 0); + cxx_ctor_decl->setDeclContext(cxx_record_decl); + cxx_ctor_decl->setDeclName( + getASTContext().DeclarationNames.getCXXConstructorName( + getASTContext().getCanonicalType(record_qual_type))); + cxx_ctor_decl->setType(method_qual_type); + cxx_ctor_decl->setImplicit(is_artificial); + cxx_ctor_decl->setInlineSpecified(is_inline); + cxx_ctor_decl->setConstexprKind(CSK_unspecified); + cxx_ctor_decl->setNumCtorInitializers(0); + cxx_ctor_decl->setExplicitSpecifier(explicit_spec); + cxx_method_decl = cxx_ctor_decl; + } else { + clang::StorageClass SC = is_static ? clang::SC_Static : clang::SC_None; + clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS; + + if (IsOperator(name, op_kind)) { + if (op_kind != clang::NUM_OVERLOADED_OPERATORS) { + // Check the number of operator parameters. Sometimes we have seen bad + // DWARF that doesn't correctly describe operators and if we try to + // create a method and add it to the class, clang will assert and + // crash, so we need to make sure things are acceptable. + const bool is_method = true; + if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount( + is_method, op_kind, num_params)) + return nullptr; + cxx_method_decl = + clang::CXXMethodDecl::CreateDeserialized(getASTContext(), 0); + cxx_method_decl->setDeclContext(cxx_record_decl); + cxx_method_decl->setDeclName( + getASTContext().DeclarationNames.getCXXOperatorName(op_kind)); + cxx_method_decl->setType(method_qual_type); + cxx_method_decl->setStorageClass(SC); + cxx_method_decl->setInlineSpecified(is_inline); + cxx_method_decl->setConstexprKind(CSK_unspecified); + } else if (num_params == 0) { + // Conversion operators don't take params... + auto *cxx_conversion_decl = + clang::CXXConversionDecl::CreateDeserialized(getASTContext(), 0); + cxx_conversion_decl->setDeclContext(cxx_record_decl); + cxx_conversion_decl->setDeclName( + getASTContext().DeclarationNames.getCXXConversionFunctionName( + getASTContext().getCanonicalType( + function_type->getReturnType()))); + cxx_conversion_decl->setType(method_qual_type); + cxx_conversion_decl->setInlineSpecified(is_inline); + cxx_conversion_decl->setExplicitSpecifier(explicit_spec); + cxx_conversion_decl->setConstexprKind(CSK_unspecified); + cxx_method_decl = cxx_conversion_decl; + } + } + + if (cxx_method_decl == nullptr) { + cxx_method_decl = + clang::CXXMethodDecl::CreateDeserialized(getASTContext(), 0); + cxx_method_decl->setDeclContext(cxx_record_decl); + cxx_method_decl->setDeclName(decl_name); + cxx_method_decl->setType(method_qual_type); + cxx_method_decl->setInlineSpecified(is_inline); + cxx_method_decl->setStorageClass(SC); + cxx_method_decl->setConstexprKind(CSK_unspecified); + } + } + SetMemberOwningModule(cxx_method_decl, cxx_record_decl); + + clang::AccessSpecifier access_specifier = + TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access); + + cxx_method_decl->setAccess(access_specifier); + cxx_method_decl->setVirtualAsWritten(is_virtual); + + if (is_attr_used) + cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(getASTContext())); + + if (mangled_name != nullptr) { + cxx_method_decl->addAttr(clang::AsmLabelAttr::CreateImplicit( + getASTContext(), mangled_name, /*literal=*/false)); + } + + // Populate the method decl with parameter decls + + llvm::SmallVector params; + + for (unsigned param_index = 0; param_index < num_params; ++param_index) { + params.push_back(clang::ParmVarDecl::Create( + getASTContext(), cxx_method_decl, clang::SourceLocation(), + clang::SourceLocation(), + nullptr, // anonymous + method_function_prototype->getParamType(param_index), nullptr, + clang::SC_None, nullptr)); + } + + cxx_method_decl->setParams(llvm::ArrayRef(params)); + + cxx_record_decl->addDecl(cxx_method_decl); + + // Sometimes the debug info will mention a constructor (default/copy/move), + // destructor, or assignment operator (copy/move) but there won't be any + // version of this in the code. So we check if the function was artificially + // generated and if it is trivial and this lets the compiler/backend know + // that it can inline the IR for these when it needs to and we can avoid a + // "missing function" error when running expressions. + + if (is_artificial) { + if (cxx_ctor_decl && ((cxx_ctor_decl->isDefaultConstructor() && + cxx_record_decl->hasTrivialDefaultConstructor()) || + (cxx_ctor_decl->isCopyConstructor() && + cxx_record_decl->hasTrivialCopyConstructor()) || + (cxx_ctor_decl->isMoveConstructor() && + cxx_record_decl->hasTrivialMoveConstructor()))) { + cxx_ctor_decl->setDefaulted(); + cxx_ctor_decl->setTrivial(true); + } else if (cxx_dtor_decl) { + if (cxx_record_decl->hasTrivialDestructor()) { + cxx_dtor_decl->setDefaulted(); + cxx_dtor_decl->setTrivial(true); + } + } else if ((cxx_method_decl->isCopyAssignmentOperator() && + cxx_record_decl->hasTrivialCopyAssignment()) || + (cxx_method_decl->isMoveAssignmentOperator() && + cxx_record_decl->hasTrivialMoveAssignment())) { + cxx_method_decl->setDefaulted(); + cxx_method_decl->setTrivial(true); + } + } + + VerifyDecl(cxx_method_decl); + + return cxx_method_decl; +} + +void TypeSystemClang::AddMethodOverridesForCXXRecordType( + lldb::opaque_compiler_type_t type) { + if (auto *record = GetAsCXXRecordDecl(type)) + for (auto *method : record->methods()) + addOverridesForMethod(method); +} + +#pragma mark C++ Base Classes + +std::unique_ptr +TypeSystemClang::CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type, + AccessType access, bool is_virtual, + bool base_of_class) { + if (!type) + return nullptr; + + return std::make_unique( + clang::SourceRange(), is_virtual, base_of_class, + TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access), + getASTContext().getTrivialTypeSourceInfo(GetQualType(type)), + clang::SourceLocation()); +} + +bool TypeSystemClang::TransferBaseClasses( + lldb::opaque_compiler_type_t type, + 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 TypeSystemClang::SetObjCSuperClass( + const CompilerType &type, const CompilerType &superclass_clang_type) { + TypeSystemClang *ast = + llvm::dyn_cast_or_null(type.GetTypeSystem()); + if (!ast) + return false; + clang::ASTContext &clang_ast = ast->getASTContext(); + + if (type && superclass_clang_type.IsValid() && + superclass_clang_type.GetTypeSystem() == type.GetTypeSystem()) { + clang::ObjCInterfaceDecl *class_interface_decl = + GetAsObjCInterfaceDecl(type); + clang::ObjCInterfaceDecl *super_interface_decl = + GetAsObjCInterfaceDecl(superclass_clang_type); + if (class_interface_decl && super_interface_decl) { + class_interface_decl->setSuperClass(clang_ast.getTrivialTypeSourceInfo( + clang_ast.getObjCInterfaceType(super_interface_decl))); + return true; + } + } + return false; +} + +bool TypeSystemClang::AddObjCClassProperty( + const CompilerType &type, const char *property_name, + const CompilerType &property_clang_type, clang::ObjCIvarDecl *ivar_decl, + const char *property_setter_name, const char *property_getter_name, + uint32_t property_attributes, ClangASTMetadata *metadata) { + if (!type || !property_clang_type.IsValid() || property_name == nullptr || + property_name[0] == '\0') + return false; + TypeSystemClang *ast = llvm::dyn_cast(type.GetTypeSystem()); + if (!ast) + return false; + clang::ASTContext &clang_ast = ast->getASTContext(); + + clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type); + if (!class_interface_decl) + return false; + + CompilerType property_clang_type_to_access; + + if (property_clang_type.IsValid()) + property_clang_type_to_access = property_clang_type; + else if (ivar_decl) + property_clang_type_to_access = ast->GetType(ivar_decl->getType()); + + if (!class_interface_decl || !property_clang_type_to_access.IsValid()) + return false; + + clang::TypeSourceInfo *prop_type_source; + if (ivar_decl) + prop_type_source = clang_ast.getTrivialTypeSourceInfo(ivar_decl->getType()); + else + prop_type_source = clang_ast.getTrivialTypeSourceInfo( + ClangUtil::GetQualType(property_clang_type)); + + clang::ObjCPropertyDecl *property_decl = + clang::ObjCPropertyDecl::CreateDeserialized(clang_ast, 0); + property_decl->setDeclContext(class_interface_decl); + property_decl->setDeclName(&clang_ast.Idents.get(property_name)); + property_decl->setType(ivar_decl + ? ivar_decl->getType() + : ClangUtil::GetQualType(property_clang_type), + prop_type_source); + SetMemberOwningModule(property_decl, class_interface_decl); + + if (!property_decl) + return false; + + if (metadata) + ast->SetMetadata(property_decl, *metadata); + + class_interface_decl->addDecl(property_decl); + + clang::Selector setter_sel, getter_sel; + + if (property_setter_name) { + std::string property_setter_no_colon(property_setter_name, + strlen(property_setter_name) - 1); + clang::IdentifierInfo *setter_ident = + &clang_ast.Idents.get(property_setter_no_colon); + setter_sel = clang_ast.Selectors.getSelector(1, &setter_ident); + } else if (!(property_attributes & DW_APPLE_PROPERTY_readonly)) { + std::string setter_sel_string("set"); + setter_sel_string.push_back(::toupper(property_name[0])); + setter_sel_string.append(&property_name[1]); + clang::IdentifierInfo *setter_ident = + &clang_ast.Idents.get(setter_sel_string); + setter_sel = clang_ast.Selectors.getSelector(1, &setter_ident); + } + property_decl->setSetterName(setter_sel); + property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_setter); + + if (property_getter_name != nullptr) { + clang::IdentifierInfo *getter_ident = + &clang_ast.Idents.get(property_getter_name); + getter_sel = clang_ast.Selectors.getSelector(0, &getter_ident); + } else { + clang::IdentifierInfo *getter_ident = &clang_ast.Idents.get(property_name); + getter_sel = clang_ast.Selectors.getSelector(0, &getter_ident); + } + property_decl->setGetterName(getter_sel); + property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_getter); + + if (ivar_decl) + property_decl->setPropertyIvarDecl(ivar_decl); + + if (property_attributes & DW_APPLE_PROPERTY_readonly) + property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_readonly); + if (property_attributes & DW_APPLE_PROPERTY_readwrite) + property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_readwrite); + if (property_attributes & DW_APPLE_PROPERTY_assign) + property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_assign); + if (property_attributes & DW_APPLE_PROPERTY_retain) + property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_retain); + if (property_attributes & DW_APPLE_PROPERTY_copy) + property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_copy); + if (property_attributes & DW_APPLE_PROPERTY_nonatomic) + property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_nonatomic); + if (property_attributes & ObjCPropertyAttribute::kind_nullability) + property_decl->setPropertyAttributes( + ObjCPropertyAttribute::kind_nullability); + if (property_attributes & ObjCPropertyAttribute::kind_null_resettable) + property_decl->setPropertyAttributes( + ObjCPropertyAttribute::kind_null_resettable); + if (property_attributes & ObjCPropertyAttribute::kind_class) + property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_class); + + const bool isInstance = + (property_attributes & ObjCPropertyAttribute::kind_class) == 0; + + clang::ObjCMethodDecl *getter = nullptr; + if (!getter_sel.isNull()) + getter = isInstance ? class_interface_decl->lookupInstanceMethod(getter_sel) + : class_interface_decl->lookupClassMethod(getter_sel); + if (!getter_sel.isNull() && !getter) { + const bool isVariadic = false; + const bool isPropertyAccessor = true; + const bool isSynthesizedAccessorStub = false; + const bool isImplicitlyDeclared = true; + const bool isDefined = false; + const clang::ObjCMethodDecl::ImplementationControl impControl = + clang::ObjCMethodDecl::None; + const bool HasRelatedResultType = false; + + getter = clang::ObjCMethodDecl::CreateDeserialized(clang_ast, 0); + getter->setDeclName(getter_sel); + getter->setReturnType(ClangUtil::GetQualType(property_clang_type_to_access)); + getter->setDeclContext(class_interface_decl); + getter->setInstanceMethod(isInstance); + getter->setVariadic(isVariadic); + getter->setPropertyAccessor(isPropertyAccessor); + getter->setSynthesizedAccessorStub(isSynthesizedAccessorStub); + getter->setImplicit(isImplicitlyDeclared); + getter->setDefined(isDefined); + getter->setDeclImplementation(impControl); + getter->setRelatedResultType(HasRelatedResultType); + SetMemberOwningModule(getter, class_interface_decl); + + if (getter) { + if (metadata) + ast->SetMetadata(getter, *metadata); + + getter->setMethodParams(clang_ast, llvm::ArrayRef(), + llvm::ArrayRef()); + class_interface_decl->addDecl(getter); + } + } + if (getter) { + getter->setPropertyAccessor(true); + property_decl->setGetterMethodDecl(getter); + } + + clang::ObjCMethodDecl *setter = nullptr; + setter = isInstance ? class_interface_decl->lookupInstanceMethod(setter_sel) + : class_interface_decl->lookupClassMethod(setter_sel); + if (!setter_sel.isNull() && !setter) { + clang::QualType result_type = clang_ast.VoidTy; + const bool isVariadic = false; + const bool isPropertyAccessor = true; + const bool isSynthesizedAccessorStub = false; + const bool isImplicitlyDeclared = true; + const bool isDefined = false; + const clang::ObjCMethodDecl::ImplementationControl impControl = + clang::ObjCMethodDecl::None; + const bool HasRelatedResultType = false; + + setter = clang::ObjCMethodDecl::CreateDeserialized(clang_ast, 0); + setter->setDeclName(setter_sel); + setter->setReturnType(result_type); + setter->setDeclContext(class_interface_decl); + setter->setInstanceMethod(isInstance); + setter->setVariadic(isVariadic); + setter->setPropertyAccessor(isPropertyAccessor); + setter->setSynthesizedAccessorStub(isSynthesizedAccessorStub); + setter->setImplicit(isImplicitlyDeclared); + setter->setDefined(isDefined); + setter->setDeclImplementation(impControl); + setter->setRelatedResultType(HasRelatedResultType); + SetMemberOwningModule(setter, class_interface_decl); + + if (setter) { + if (metadata) + ast->SetMetadata(setter, *metadata); + + llvm::SmallVector params; + params.push_back(clang::ParmVarDecl::Create( + clang_ast, setter, clang::SourceLocation(), clang::SourceLocation(), + nullptr, // anonymous + ClangUtil::GetQualType(property_clang_type_to_access), nullptr, + clang::SC_Auto, nullptr)); + + setter->setMethodParams(clang_ast, + llvm::ArrayRef(params), + llvm::ArrayRef()); + + class_interface_decl->addDecl(setter); + } + } + if (setter) { + setter->setPropertyAccessor(true); + property_decl->setSetterMethodDecl(setter); + } + + return true; +} + +bool TypeSystemClang::IsObjCClassTypeAndHasIVars(const CompilerType &type, + bool check_superclass) { + clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type); + if (class_interface_decl) + return ObjCDeclHasIVars(class_interface_decl, check_superclass); + return false; +} + +clang::ObjCMethodDecl *TypeSystemClang::AddMethodToObjCObjectType( + const CompilerType &type, + const char *name, // the full symbol name as seen in the symbol table + // (lldb::opaque_compiler_type_t type, "-[NString + // stringWithCString:]") + const CompilerType &method_clang_type, lldb::AccessType access, + bool is_artificial, bool is_variadic, bool is_objc_direct_call) { + if (!type || !method_clang_type.IsValid()) + return nullptr; + + clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type); + + if (class_interface_decl == nullptr) + return nullptr; + TypeSystemClang *lldb_ast = + llvm::dyn_cast(type.GetTypeSystem()); + if (lldb_ast == nullptr) + return nullptr; + clang::ASTContext &ast = lldb_ast->getASTContext(); + + const char *selector_start = ::strchr(name, ' '); + if (selector_start == nullptr) + return nullptr; + + selector_start++; + llvm::SmallVector selector_idents; + + size_t len = 0; + const char *start; + + unsigned num_selectors_with_args = 0; + for (start = selector_start; start && *start != '\0' && *start != ']'; + start += len) { + len = ::strcspn(start, ":]"); + bool has_arg = (start[len] == ':'); + if (has_arg) + ++num_selectors_with_args; + selector_idents.push_back(&ast.Idents.get(llvm::StringRef(start, len))); + if (has_arg) + len += 1; + } + + if (selector_idents.size() == 0) + return nullptr; + + clang::Selector method_selector = ast.Selectors.getSelector( + num_selectors_with_args ? selector_idents.size() : 0, + selector_idents.data()); + + clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type)); + + // Populate the method decl with parameter decls + const clang::Type *method_type(method_qual_type.getTypePtr()); + + if (method_type == nullptr) + return nullptr; + + const clang::FunctionProtoType *method_function_prototype( + llvm::dyn_cast(method_type)); + + if (!method_function_prototype) + return nullptr; + + const bool isInstance = (name[0] == '-'); + const bool isVariadic = is_variadic; + const bool isPropertyAccessor = false; + const bool isSynthesizedAccessorStub = false; + /// Force this to true because we don't have source locations. + const bool isImplicitlyDeclared = true; + const bool isDefined = false; + const clang::ObjCMethodDecl::ImplementationControl impControl = + clang::ObjCMethodDecl::None; + const bool HasRelatedResultType = false; + + const unsigned num_args = method_function_prototype->getNumParams(); + + if (num_args != num_selectors_with_args) + return nullptr; // some debug information is corrupt. We are not going to + // deal with it. + + auto *objc_method_decl = clang::ObjCMethodDecl::CreateDeserialized(ast, 0); + objc_method_decl->setDeclName(method_selector); + objc_method_decl->setReturnType(method_function_prototype->getReturnType()); + objc_method_decl->setDeclContext( + lldb_ast->GetDeclContextForType(ClangUtil::GetQualType(type))); + objc_method_decl->setInstanceMethod(isInstance); + objc_method_decl->setVariadic(isVariadic); + objc_method_decl->setPropertyAccessor(isPropertyAccessor); + objc_method_decl->setSynthesizedAccessorStub(isSynthesizedAccessorStub); + objc_method_decl->setImplicit(isImplicitlyDeclared); + objc_method_decl->setDefined(isDefined); + objc_method_decl->setDeclImplementation(impControl); + objc_method_decl->setRelatedResultType(HasRelatedResultType); + SetMemberOwningModule(objc_method_decl, class_interface_decl); + + if (objc_method_decl == nullptr) + return nullptr; + + if (num_args > 0) { + llvm::SmallVector params; + + for (unsigned param_index = 0; param_index < num_args; ++param_index) { + params.push_back(clang::ParmVarDecl::Create( + ast, objc_method_decl, clang::SourceLocation(), + clang::SourceLocation(), + nullptr, // anonymous + method_function_prototype->getParamType(param_index), nullptr, + clang::SC_Auto, nullptr)); + } + + objc_method_decl->setMethodParams( + ast, llvm::ArrayRef(params), + llvm::ArrayRef()); + } + + if (is_objc_direct_call) { + // Add a the objc_direct attribute to the declaration we generate that + // we generate a direct method call for this ObjCMethodDecl. + objc_method_decl->addAttr( + clang::ObjCDirectAttr::CreateImplicit(ast, SourceLocation())); + // Usually Sema is creating implicit parameters (e.g., self) when it + // parses the method. We don't have a parsing Sema when we build our own + // AST here so we manually need to create these implicit parameters to + // make the direct call code generation happy. + objc_method_decl->createImplicitParams(ast, class_interface_decl); + } + + class_interface_decl->addDecl(objc_method_decl); + + VerifyDecl(objc_method_decl); + + return objc_method_decl; +} + +bool TypeSystemClang::SetHasExternalStorage(lldb::opaque_compiler_type_t type, + bool has_extern) { + if (!type) + return false; + + clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: { + clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) { + cxx_record_decl->setHasExternalLexicalStorage(has_extern); + cxx_record_decl->setHasExternalVisibleStorage(has_extern); + return true; + } + } break; + + case clang::Type::Enum: { + clang::EnumDecl *enum_decl = + llvm::cast(qual_type)->getDecl(); + if (enum_decl) { + enum_decl->setHasExternalLexicalStorage(has_extern); + enum_decl->setHasExternalVisibleStorage(has_extern); + return true; + } + } break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: { + const clang::ObjCObjectType *objc_class_type = + llvm::dyn_cast(qual_type.getTypePtr()); + assert(objc_class_type); + if (objc_class_type) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + + if (class_interface_decl) { + class_interface_decl->setHasExternalLexicalStorage(has_extern); + class_interface_decl->setHasExternalVisibleStorage(has_extern); + return true; + } + } + } break; + + default: + break; + } + return false; +} + +#pragma mark TagDecl + +bool TypeSystemClang::StartTagDeclarationDefinition(const CompilerType &type) { + clang::QualType qual_type(ClangUtil::GetQualType(type)); + if (!qual_type.isNull()) { + const clang::TagType *tag_type = qual_type->getAs(); + if (tag_type) { + clang::TagDecl *tag_decl = tag_type->getDecl(); + if (tag_decl) { + tag_decl->startDefinition(); + return true; + } + } + + const clang::ObjCObjectType *object_type = + qual_type->getAs(); + if (object_type) { + clang::ObjCInterfaceDecl *interface_decl = object_type->getInterface(); + if (interface_decl) { + interface_decl->startDefinition(); + return true; + } + } + } + return false; +} + +bool TypeSystemClang::CompleteTagDeclarationDefinition( + const CompilerType &type) { + clang::QualType qual_type(ClangUtil::GetQualType(type)); + if (qual_type.isNull()) + return false; + + // Make sure we use the same methodology as + // TypeSystemClang::StartTagDeclarationDefinition() as to how we start/end + // the definition. + const clang::TagType *tag_type = qual_type->getAs(); + if (tag_type) { + clang::TagDecl *tag_decl = tag_type->getDecl(); + + if (auto *cxx_record_decl = llvm::dyn_cast(tag_decl)) { + // If we have a move constructor declared but no copy constructor we + // need to explicitly mark it as deleted. Usually Sema would do this for + // us in Sema::DeclareImplicitCopyConstructor but we don't have a Sema + // when building an AST from debug information. + // See also: + // C++11 [class.copy]p7, p18: + // If the class definition declares a move constructor or move assignment + // operator, an implicitly declared copy constructor or copy assignment + // operator is defined as deleted. + if (cxx_record_decl->hasUserDeclaredMoveConstructor() || + cxx_record_decl->hasUserDeclaredMoveAssignment()) { + if (cxx_record_decl->needsImplicitCopyConstructor()) + cxx_record_decl->setImplicitCopyConstructorIsDeleted(); + if (cxx_record_decl->needsImplicitCopyAssignment()) + cxx_record_decl->setImplicitCopyAssignmentIsDeleted(); + } + + if (!cxx_record_decl->isCompleteDefinition()) + cxx_record_decl->completeDefinition(); + cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true); + cxx_record_decl->setHasExternalLexicalStorage(false); + cxx_record_decl->setHasExternalVisibleStorage(false); + return true; + } + } + + const clang::EnumType *enutype = qual_type->getAs(); + + if (!enutype) + return false; + clang::EnumDecl *enum_decl = enutype->getDecl(); + + if (enum_decl->isCompleteDefinition()) + return true; + + TypeSystemClang *lldb_ast = + llvm::dyn_cast(type.GetTypeSystem()); + if (lldb_ast == nullptr) + return false; + clang::ASTContext &ast = lldb_ast->getASTContext(); + + /// TODO This really needs to be fixed. + + QualType integer_type(enum_decl->getIntegerType()); + if (!integer_type.isNull()) { + unsigned NumPositiveBits = 1; + unsigned NumNegativeBits = 0; + + clang::QualType promotion_qual_type; + // If the enum integer type is less than an integer in bit width, + // then we must promote it to an integer size. + if (ast.getTypeSize(enum_decl->getIntegerType()) < + ast.getTypeSize(ast.IntTy)) { + if (enum_decl->getIntegerType()->isSignedIntegerType()) + promotion_qual_type = ast.IntTy; + else + promotion_qual_type = ast.UnsignedIntTy; + } else + promotion_qual_type = enum_decl->getIntegerType(); + + enum_decl->completeDefinition(enum_decl->getIntegerType(), + promotion_qual_type, NumPositiveBits, + NumNegativeBits); + } + return true; +} + +clang::EnumConstantDecl *TypeSystemClang::AddEnumerationValueToEnumerationType( + const CompilerType &enum_type, const Declaration &decl, const char *name, + const llvm::APSInt &value) { + + if (!enum_type || ConstString(name).IsEmpty()) + return nullptr; + + lldbassert(enum_type.GetTypeSystem() == static_cast(this)); + + 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::CreateDeserialized(getASTContext(), 0); + enumerator_decl->setDeclContext(enutype->getDecl()); + if (name && name[0]) + enumerator_decl->setDeclName(&getASTContext().Idents.get(name)); + enumerator_decl->setType(clang::QualType(enutype, 0)); + enumerator_decl->setInitVal(value); + SetMemberOwningModule(enumerator_decl, enutype->getDecl()); + + if (!enumerator_decl) + return nullptr; + + enutype->getDecl()->addDecl(enumerator_decl); + + VerifyDecl(enumerator_decl); + return enumerator_decl; +} + +clang::EnumConstantDecl *TypeSystemClang::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); + 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 TypeSystemClang::GetEnumerationIntegerType(CompilerType type) { + clang::QualType qt(ClangUtil::GetQualType(type)); + const clang::Type *clang_type = qt.getTypePtrOrNull(); + const auto *enum_type = llvm::dyn_cast_or_null(clang_type); + if (!enum_type) + return CompilerType(); + + return GetType(enum_type->getDecl()->getIntegerType()); +} + +CompilerType +TypeSystemClang::CreateMemberPointerType(const CompilerType &type, + const CompilerType &pointee_type) { + if (type && pointee_type.IsValid() && + type.GetTypeSystem() == pointee_type.GetTypeSystem()) { + TypeSystemClang *ast = + llvm::dyn_cast(type.GetTypeSystem()); + if (!ast) + return CompilerType(); + return ast->GetType(ast->getASTContext().getMemberPointerType( + ClangUtil::GetQualType(pointee_type), + ClangUtil::GetQualType(type).getTypePtr())); + } + return CompilerType(); +} + +// Dumping types +#define DEPTH_INCREMENT 2 + +#ifndef NDEBUG +LLVM_DUMP_METHOD void +TypeSystemClang::dump(lldb::opaque_compiler_type_t type) const { + if (!type) + return; + clang::QualType qual_type(GetQualType(type)); + qual_type.dump(); +} +#endif + +void TypeSystemClang::Dump(Stream &s) { + Decl *tu = Decl::castFromDeclContext(GetTranslationUnitDecl()); + tu->dump(s.AsRawOstream()); +} + +void TypeSystemClang::DumpFromSymbolFile(Stream &s, + llvm::StringRef symbol_name) { + SymbolFile *symfile = GetSymbolFile(); + + if (!symfile) + return; + + lldb_private::TypeList type_list; + symfile->GetTypes(nullptr, eTypeClassAny, type_list); + size_t ntypes = type_list.GetSize(); + + for (size_t i = 0; i < ntypes; ++i) { + TypeSP type = type_list.GetTypeAtIndex(i); + + if (!symbol_name.empty()) + if (symbol_name != type->GetName().GetStringRef()) + continue; + + s << type->GetName().AsCString() << "\n"; + + CompilerType full_type = type->GetFullCompilerType(); + if (clang::TagDecl *tag_decl = GetAsTagDecl(full_type)) { + tag_decl->dump(s.AsRawOstream()); + continue; + } + if (clang::TypedefNameDecl *typedef_decl = GetAsTypedefDecl(full_type)) { + typedef_decl->dump(s.AsRawOstream()); + continue; + } + if (auto *objc_obj = llvm::dyn_cast( + ClangUtil::GetQualType(full_type).getTypePtr())) { + if (clang::ObjCInterfaceDecl *interface_decl = objc_obj->getInterface()) { + interface_decl->dump(s.AsRawOstream()); + continue; + } + } + GetCanonicalQualType(full_type.GetOpaqueQualType()) + .dump(s.AsRawOstream(), getASTContext()); + } +} + +void TypeSystemClang::DumpValue( + lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, + lldb::Format format, const lldb_private::DataExtractor &data, + lldb::offset_t data_byte_offset, size_t data_byte_size, + uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types, + bool show_summary, bool verbose, uint32_t depth) { + if (!type) + return; + + clang::QualType qual_type(GetQualType(type)); + switch (qual_type->getTypeClass()) { + case clang::Type::Record: + if (GetCompleteType(type)) { + const clang::RecordType *record_type = + llvm::cast(qual_type.getTypePtr()); + const clang::RecordDecl *record_decl = record_type->getDecl(); + assert(record_decl); + uint32_t field_bit_offset = 0; + uint32_t field_byte_offset = 0; + const clang::ASTRecordLayout &record_layout = + getASTContext().getASTRecordLayout(record_decl); + uint32_t child_idx = 0; + + const clang::CXXRecordDecl *cxx_record_decl = + llvm::dyn_cast(record_decl); + if (cxx_record_decl) { + // We might have base classes to print out first + clang::CXXRecordDecl::base_class_const_iterator base_class, + base_class_end; + for (base_class = cxx_record_decl->bases_begin(), + base_class_end = cxx_record_decl->bases_end(); + base_class != base_class_end; ++base_class) { + const clang::CXXRecordDecl *base_class_decl = + llvm::cast( + base_class->getType()->getAs()->getDecl()); + + // Skip empty base classes + if (!verbose && !TypeSystemClang::RecordHasFields(base_class_decl)) + continue; + + if (base_class->isVirtual()) + field_bit_offset = + record_layout.getVBaseClassOffset(base_class_decl) + .getQuantity() * + 8; + else + field_bit_offset = record_layout.getBaseClassOffset(base_class_decl) + .getQuantity() * + 8; + field_byte_offset = field_bit_offset / 8; + assert(field_bit_offset % 8 == 0); + if (child_idx == 0) + s->PutChar('{'); + else + s->PutChar(','); + + clang::QualType base_class_qual_type = base_class->getType(); + std::string base_class_type_name(base_class_qual_type.getAsString()); + + // Indent and print the base class type name + s->Format("\n{0}{1}", llvm::fmt_repeat(" ", depth + DEPTH_INCREMENT), + base_class_type_name); + + clang::TypeInfo base_class_type_info = + getASTContext().getTypeInfo(base_class_qual_type); + + // Dump the value of the member + CompilerType base_clang_type = GetType(base_class_qual_type); + base_clang_type.DumpValue( + exe_ctx, + s, // Stream to dump to + base_clang_type + .GetFormat(), // The format with which to display the member + data, // Data buffer containing all bytes for this type + data_byte_offset + field_byte_offset, // Offset into "data" where + // to grab value from + base_class_type_info.Width / 8, // 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 + + ++child_idx; + } + } + uint32_t field_idx = 0; + clang::RecordDecl::field_iterator field, field_end; + for (field = record_decl->field_begin(), + field_end = record_decl->field_end(); + field != field_end; ++field, ++field_idx, ++child_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 (child_idx == 0) + s->PutChar('{'); + else + s->PutChar(','); + + // Indent + s->Printf("\n%*s", depth + DEPTH_INCREMENT, ""); + + clang::QualType field_type = field->getType(); + // Print the member type if requested + // Figure out the type byte size (field_type_info.first) and alignment + // (field_type_info.second) from the AST context. + clang::TypeInfo field_type_info = + getASTContext().getTypeInfo(field_type); + assert(field_idx < record_layout.getFieldCount()); + // Figure out the field offset within the current struct/union/class + // type + field_bit_offset = record_layout.getFieldOffset(field_idx); + field_byte_offset = field_bit_offset / 8; + uint32_t field_bitfield_bit_size = 0; + uint32_t field_bitfield_bit_offset = 0; + if (FieldIsBitfield(*field, field_bitfield_bit_size)) + field_bitfield_bit_offset = field_bit_offset % 8; + + if (show_types) { + std::string field_type_name(field_type.getAsString()); + if (field_bitfield_bit_size > 0) + s->Printf("(%s:%u) ", field_type_name.c_str(), + field_bitfield_bit_size); + else + s->Printf("(%s) ", field_type_name.c_str()); + } + // Print the member name and equal sign + s->Printf("%s = ", field->getNameAsString().c_str()); + + // Dump the value of the member + CompilerType field_clang_type = GetType(field_type); + field_clang_type.DumpValue( + exe_ctx, + s, // Stream to dump to + field_clang_type + .GetFormat(), // The format with which to display the member + data, // Data buffer containing all bytes for this type + data_byte_offset + field_byte_offset, // Offset into "data" where to + // grab value from + field_type_info.Width / 8, // Size of this type in bytes + field_bitfield_bit_size, // Bitfield bit size + field_bitfield_bit_offset, // 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 (child_idx > 0) + s->Printf("\n%*s}", depth, ""); + } + return; + + case clang::Type::Enum: + if (GetCompleteType(type)) { + const clang::EnumType *enutype = + llvm::cast(qual_type.getTypePtr()); + const clang::EnumDecl *enum_decl = enutype->getDecl(); + assert(enum_decl); + clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos; + lldb::offset_t offset = data_byte_offset; + const int64_t enum_value = data.GetMaxU64Bitfield( + &offset, data_byte_size, bitfield_bit_size, bitfield_bit_offset); + for (enum_pos = enum_decl->enumerator_begin(), + enum_end_pos = enum_decl->enumerator_end(); + enum_pos != enum_end_pos; ++enum_pos) { + if (enum_pos->getInitVal() == enum_value) { + s->Printf("%s", enum_pos->getNameAsString().c_str()); + return; + } + } + // If we have gotten here we didn't get find the enumerator in the enum + // decl, so just print the integer. + s->Printf("%" PRIi64, enum_value); + } + return; + + case clang::Type::ConstantArray: { + const clang::ConstantArrayType *array = + llvm::cast(qual_type.getTypePtr()); + bool is_array_of_characters = false; + clang::QualType element_qual_type = array->getElementType(); + + const clang::Type *canonical_type = + element_qual_type->getCanonicalTypeInternal().getTypePtr(); + if (canonical_type) + is_array_of_characters = canonical_type->isCharType(); + + const uint64_t element_count = array->getSize().getLimitedValue(); + + clang::TypeInfo field_type_info = + getASTContext().getTypeInfo(element_qual_type); + + uint32_t element_idx = 0; + uint32_t element_offset = 0; + uint64_t element_byte_size = field_type_info.Width / 8; + uint32_t element_stride = element_byte_size; + + if (is_array_of_characters) { + s->PutChar('"'); + DumpDataExtractor(data, s, data_byte_offset, lldb::eFormatChar, + element_byte_size, element_count, UINT32_MAX, + LLDB_INVALID_ADDRESS, 0, 0); + s->PutChar('"'); + return; + } else { + CompilerType element_clang_type = GetType(element_qual_type); + lldb::Format element_format = element_clang_type.GetFormat(); + + for (element_idx = 0; element_idx < element_count; ++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[%u] ", depth + DEPTH_INCREMENT, "", element_idx); + + // Figure out the field offset within the current struct/union/class + // type + element_offset = element_idx * element_stride; + + // 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, ""); + } + } + return; + + case clang::Type::Typedef: { + clang::QualType typedef_qual_type = + llvm::cast(qual_type) + ->getDecl() + ->getUnderlyingType(); + + CompilerType typedef_clang_type = GetType(typedef_qual_type); + lldb::Format typedef_format = typedef_clang_type.GetFormat(); + clang::TypeInfo typedef_type_info = + getASTContext().getTypeInfo(typedef_qual_type); + uint64_t typedef_byte_size = typedef_type_info.Width / 8; + + return typedef_clang_type.DumpValue( + exe_ctx, + s, // Stream to dump to + typedef_format, // The format with which to display the element + data, // Data buffer containing all bytes for this type + data_byte_offset, // Offset into "data" where to grab value from + typedef_byte_size, // Size of this type in bytes + bitfield_bit_size, // Bitfield bit size + bitfield_bit_offset, // 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); // Scope depth for any types that have children + } break; + + case clang::Type::Auto: { + clang::QualType elaborated_qual_type = + llvm::cast(qual_type)->getDeducedType(); + CompilerType elaborated_clang_type = GetType(elaborated_qual_type); + lldb::Format elaborated_format = elaborated_clang_type.GetFormat(); + clang::TypeInfo elaborated_type_info = + getASTContext().getTypeInfo(elaborated_qual_type); + uint64_t elaborated_byte_size = elaborated_type_info.Width / 8; + + return elaborated_clang_type.DumpValue( + exe_ctx, + s, // Stream to dump to + elaborated_format, // The format with which to display the element + data, // Data buffer containing all bytes for this type + data_byte_offset, // Offset into "data" where to grab value from + elaborated_byte_size, // Size of this type in bytes + bitfield_bit_size, // Bitfield bit size + bitfield_bit_offset, // 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); // Scope depth for any types that have children + } break; + + case clang::Type::Elaborated: { + clang::QualType elaborated_qual_type = + llvm::cast(qual_type)->getNamedType(); + CompilerType elaborated_clang_type = GetType(elaborated_qual_type); + lldb::Format elaborated_format = elaborated_clang_type.GetFormat(); + clang::TypeInfo elaborated_type_info = + getASTContext().getTypeInfo(elaborated_qual_type); + uint64_t elaborated_byte_size = elaborated_type_info.Width / 8; + + return elaborated_clang_type.DumpValue( + exe_ctx, + s, // Stream to dump to + elaborated_format, // The format with which to display the element + data, // Data buffer containing all bytes for this type + data_byte_offset, // Offset into "data" where to grab value from + elaborated_byte_size, // Size of this type in bytes + bitfield_bit_size, // Bitfield bit size + bitfield_bit_offset, // 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); // Scope depth for any types that have children + } break; + + case clang::Type::Paren: { + clang::QualType desugar_qual_type = + llvm::cast(qual_type)->desugar(); + CompilerType desugar_clang_type = GetType(desugar_qual_type); + + lldb::Format desugar_format = desugar_clang_type.GetFormat(); + clang::TypeInfo desugar_type_info = + getASTContext().getTypeInfo(desugar_qual_type); + uint64_t desugar_byte_size = desugar_type_info.Width / 8; + + return desugar_clang_type.DumpValue( + exe_ctx, + s, // Stream to dump to + desugar_format, // The format with which to display the element + data, // Data buffer containing all bytes for this type + data_byte_offset, // Offset into "data" where to grab value from + desugar_byte_size, // Size of this type in bytes + bitfield_bit_size, // Bitfield bit size + bitfield_bit_offset, // 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); // Scope depth for any types that have children + } break; + + default: + // We are down to a scalar type that we just need to display. + DumpDataExtractor(data, s, data_byte_offset, format, data_byte_size, 1, + UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size, + bitfield_bit_offset); + + if (show_summary) + DumpSummary(type, exe_ctx, s, data, data_byte_offset, data_byte_size); + break; + } +} + +static bool DumpEnumValue(const clang::QualType &qual_type, Stream *s, + const DataExtractor &data, lldb::offset_t byte_offset, + size_t byte_size, uint32_t bitfield_bit_offset, + uint32_t bitfield_bit_size) { + const clang::EnumType *enutype = + llvm::cast(qual_type.getTypePtr()); + const clang::EnumDecl *enum_decl = enutype->getDecl(); + assert(enum_decl); + lldb::offset_t offset = byte_offset; + const uint64_t enum_svalue = data.GetMaxS64Bitfield( + &offset, byte_size, bitfield_bit_size, bitfield_bit_offset); + bool can_be_bitfield = true; + uint64_t covered_bits = 0; + int num_enumerators = 0; + + // Try to find an exact match for the value. + // At the same time, we're applying a heuristic to determine whether we want + // to print this enum as a bitfield. We're likely dealing with a bitfield if + // every enumerator is either a one bit value or a superset of the previous + // enumerators. Also 0 doesn't make sense when the enumerators are used as + // flags. + for (auto *enumerator : enum_decl->enumerators()) { + uint64_t val = enumerator->getInitVal().getSExtValue(); + val = llvm::SignExtend64(val, 8*byte_size); + if (llvm::countPopulation(val) != 1 && (val & ~covered_bits) != 0) + can_be_bitfield = false; + covered_bits |= val; + ++num_enumerators; + if (val == enum_svalue) { + // Found an exact match, that's all we need to do. + s->PutCString(enumerator->getNameAsString()); + return true; + } + } + + // Unsigned values make more sense for flags. + offset = byte_offset; + const uint64_t enum_uvalue = data.GetMaxU64Bitfield( + &offset, byte_size, bitfield_bit_size, bitfield_bit_offset); + + // No exact match, but we don't think this is a bitfield. Print the value as + // decimal. + if (!can_be_bitfield) { + if (qual_type->isSignedIntegerOrEnumerationType()) + s->Printf("%" PRIi64, enum_svalue); + else + s->Printf("%" PRIu64, enum_uvalue); + return true; + } + + uint64_t remaining_value = enum_uvalue; + std::vector> values; + values.reserve(num_enumerators); + for (auto *enumerator : enum_decl->enumerators()) + if (auto val = enumerator->getInitVal().getZExtValue()) + values.emplace_back(val, enumerator->getName()); + + // Sort in reverse order of the number of the population count, so that in + // `enum {A, B, ALL = A|B }` we visit ALL first. Use a stable sort so that + // A | C where A is declared before C is displayed in this order. + std::stable_sort(values.begin(), values.end(), [](const auto &a, const auto &b) { + return llvm::countPopulation(a.first) > llvm::countPopulation(b.first); + }); + + for (const auto &val : values) { + if ((remaining_value & val.first) != val.first) + continue; + remaining_value &= ~val.first; + s->PutCString(val.second); + if (remaining_value) + s->PutCString(" | "); + } + + // If there is a remainder that is not covered by the value, print it as hex. + if (remaining_value) + s->Printf("0x%" PRIx64, remaining_value); + + return true; +} + +bool TypeSystemClang::DumpTypeValue( + lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format, + const lldb_private::DataExtractor &data, lldb::offset_t byte_offset, + size_t byte_size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, + ExecutionContextScope *exe_scope) { + if (!type) + return false; + if (IsAggregateType(type)) { + return false; + } else { + clang::QualType qual_type(GetQualType(type)); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + + if (type_class == clang::Type::Elaborated) { + qual_type = llvm::cast(qual_type)->getNamedType(); + return DumpTypeValue(qual_type.getAsOpaquePtr(), s, format, data, byte_offset, byte_size, + bitfield_bit_size, bitfield_bit_offset, exe_scope); + } + + switch (type_class) { + case clang::Type::Typedef: { + clang::QualType typedef_qual_type = + llvm::cast(qual_type) + ->getDecl() + ->getUnderlyingType(); + CompilerType typedef_clang_type = GetType(typedef_qual_type); + if (format == eFormatDefault) + format = typedef_clang_type.GetFormat(); + clang::TypeInfo typedef_type_info = + getASTContext().getTypeInfo(typedef_qual_type); + uint64_t typedef_byte_size = typedef_type_info.Width / 8; + + return typedef_clang_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); + } break; + + case clang::Type::Enum: + // If our format is enum or default, show the enumeration value as its + // enumeration string value, else just display it as requested. + if ((format == eFormatEnum || format == eFormatDefault) && + GetCompleteType(type)) + return DumpEnumValue(qual_type, s, data, byte_offset, byte_size, + bitfield_bit_offset, bitfield_bit_size); + // format was not enum, just fall through and dump the value as + // requested.... + LLVM_FALLTHROUGH; + + default: + // We are down to a scalar type that we just need to display. + { + 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); + } + break; + } + } + return false; +} + +void TypeSystemClang::DumpSummary(lldb::opaque_compiler_type_t type, + ExecutionContext *exe_ctx, Stream *s, + const lldb_private::DataExtractor &data, + lldb::offset_t data_byte_offset, + size_t data_byte_size) { + uint32_t length = 0; + if (IsCStringType(type, length)) { + if (exe_ctx) { + Process *process = exe_ctx->GetProcessPtr(); + if (process) { + lldb::offset_t offset = data_byte_offset; + lldb::addr_t pointer_address = data.GetMaxU64(&offset, data_byte_size); + std::vector buf; + if (length > 0) + buf.resize(length); + else + buf.resize(256); + + DataExtractor cstr_data(&buf.front(), buf.size(), + process->GetByteOrder(), 4); + buf.back() = '\0'; + size_t bytes_read; + size_t total_cstr_len = 0; + Status error; + while ((bytes_read = process->ReadMemory(pointer_address, &buf.front(), + buf.size(), error)) > 0) { + const size_t len = strlen((const char *)&buf.front()); + if (len == 0) + break; + if (total_cstr_len == 0) + s->PutCString(" \""); + DumpDataExtractor(cstr_data, s, 0, lldb::eFormatChar, 1, len, + UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); + total_cstr_len += len; + if (len < buf.size()) + break; + pointer_address += total_cstr_len; + } + if (total_cstr_len > 0) + s->PutChar('"'); + } + } + } +} + +void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type, + lldb::DescriptionLevel level) { + StreamFile s(stdout, false); + DumpTypeDescription(type, &s, level); + + CompilerType ct(this, type); + const clang::Type *clang_type = ClangUtil::GetQualType(ct).getTypePtr(); + ClangASTMetadata *metadata = GetMetadata(clang_type); + if (metadata) { + metadata->Dump(&s); + } +} + +void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type, + Stream *s, + lldb::DescriptionLevel level) { + if (type) { + clang::QualType qual_type = + RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef}); + + llvm::SmallVector buf; + llvm::raw_svector_ostream llvm_ostrm(buf); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: { + GetCompleteType(type); + + auto *objc_class_type = + llvm::dyn_cast(qual_type.getTypePtr()); + assert(objc_class_type); + if (!objc_class_type) + break; + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + if (!class_interface_decl) + break; + if (level == eDescriptionLevelVerbose) + class_interface_decl->dump(llvm_ostrm); + else + class_interface_decl->print(llvm_ostrm, + getASTContext().getPrintingPolicy(), + s->GetIndentLevel()); + } break; + + case clang::Type::Typedef: { + auto *typedef_type = qual_type->getAs(); + if (!typedef_type) + break; + const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl(); + if (level == eDescriptionLevelVerbose) + typedef_decl->dump(llvm_ostrm); + else { + std::string clang_typedef_name( + typedef_decl->getQualifiedNameAsString()); + if (!clang_typedef_name.empty()) { + s->PutCString("typedef "); + s->PutCString(clang_typedef_name); + } + } + } break; + + case clang::Type::Record: { + GetCompleteType(type); + + auto *record_type = llvm::cast(qual_type.getTypePtr()); + const clang::RecordDecl *record_decl = record_type->getDecl(); + if (level == eDescriptionLevelVerbose) + record_decl->dump(llvm_ostrm); + else { + if (auto *cxx_record_decl = + llvm::dyn_cast(record_decl)) + cxx_record_decl->print(llvm_ostrm, + getASTContext().getPrintingPolicy(), + s->GetIndentLevel()); + else + record_decl->print(llvm_ostrm, getASTContext().getPrintingPolicy(), + s->GetIndentLevel()); + } + } break; + + default: { + if (auto *tag_type = + llvm::dyn_cast(qual_type.getTypePtr())) { + if (clang::TagDecl *tag_decl = tag_type->getDecl()) { + if (level == eDescriptionLevelVerbose) + tag_decl->dump(llvm_ostrm); + else + tag_decl->print(llvm_ostrm, 0); + } + } else { + if (level == eDescriptionLevelVerbose) + qual_type->dump(llvm_ostrm, getASTContext()); + else { + std::string clang_type_name(qual_type.getAsString()); + if (!clang_type_name.empty()) + s->PutCString(clang_type_name); + } + } + } + } + + if (buf.size() > 0) { + s->Write(buf.data(), buf.size()); + } +} +} + +void TypeSystemClang::DumpTypeName(const CompilerType &type) { + if (ClangUtil::IsClangType(type)) { + clang::QualType qual_type( + ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type))); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { + case clang::Type::Record: { + const clang::CXXRecordDecl *cxx_record_decl = + qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + printf("class %s", cxx_record_decl->getName().str().c_str()); + } break; + + case clang::Type::Enum: { + clang::EnumDecl *enum_decl = + llvm::cast(qual_type)->getDecl(); + if (enum_decl) { + printf("enum %s", enum_decl->getName().str().c_str()); + } + } break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: { + const clang::ObjCObjectType *objc_class_type = + llvm::dyn_cast(qual_type); + if (objc_class_type) { + clang::ObjCInterfaceDecl *class_interface_decl = + objc_class_type->getInterface(); + // We currently can't complete objective C types through the newly + // added ASTContext because it only supports TagDecl objects right + // now... + if (class_interface_decl) + printf("@class %s", class_interface_decl->getName().str().c_str()); + } + } break; + + case clang::Type::Typedef: + printf("typedef %s", llvm::cast(qual_type) + ->getDecl() + ->getName() + .str() + .c_str()); + break; + + case clang::Type::Auto: + printf("auto "); + return DumpTypeName(CompilerType(type.GetTypeSystem(), + llvm::cast(qual_type) + ->getDeducedType() + .getAsOpaquePtr())); + + case clang::Type::Elaborated: + printf("elaborated "); + return DumpTypeName(CompilerType( + type.GetTypeSystem(), llvm::cast(qual_type) + ->getNamedType() + .getAsOpaquePtr())); + + case clang::Type::Paren: + printf("paren "); + return DumpTypeName(CompilerType( + type.GetTypeSystem(), + llvm::cast(qual_type)->desugar().getAsOpaquePtr())); + + default: + printf("TypeSystemClang::DumpTypeName() type_class = %u", type_class); + break; + } + } +} + +clang::ClassTemplateDecl *TypeSystemClang::ParseClassTemplateDecl( + clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, + lldb::AccessType access_type, const char *parent_name, int tag_decl_kind, + const TypeSystemClang::TemplateParameterInfos &template_param_infos) { + if (template_param_infos.IsValid()) { + std::string template_basename(parent_name); + template_basename.erase(template_basename.find('<')); + + return CreateClassTemplateDecl(decl_ctx, owning_module, access_type, + template_basename.c_str(), tag_decl_kind, + template_param_infos); + } + return nullptr; +} + +void TypeSystemClang::CompleteTagDecl(clang::TagDecl *decl) { + SymbolFile *sym_file = GetSymbolFile(); + if (sym_file) { + CompilerType clang_type = GetTypeForDecl(decl); + if (clang_type) + sym_file->CompleteType(clang_type); + } +} + +void TypeSystemClang::CompleteObjCInterfaceDecl( + clang::ObjCInterfaceDecl *decl) { + SymbolFile *sym_file = GetSymbolFile(); + if (sym_file) { + CompilerType clang_type = GetTypeForDecl(decl); + if (clang_type) + sym_file->CompleteType(clang_type); + } +} + +DWARFASTParser *TypeSystemClang::GetDWARFParser() { + if (!m_dwarf_ast_parser_up) + m_dwarf_ast_parser_up = std::make_unique(*this); + return m_dwarf_ast_parser_up.get(); +} + +PDBASTParser *TypeSystemClang::GetPDBParser() { + if (!m_pdb_ast_parser_up) + m_pdb_ast_parser_up = std::make_unique(*this); + return m_pdb_ast_parser_up.get(); +} + +bool TypeSystemClang::LayoutRecordType( + const clang::RecordDecl *record_decl, uint64_t &bit_size, + uint64_t &alignment, + llvm::DenseMap &field_offsets, + llvm::DenseMap + &base_offsets, + llvm::DenseMap + &vbase_offsets) { + lldb_private::ClangASTImporter *importer = nullptr; + if (m_dwarf_ast_parser_up) + importer = &m_dwarf_ast_parser_up->GetClangASTImporter(); + if (!importer && m_pdb_ast_parser_up) + importer = &m_pdb_ast_parser_up->GetClangASTImporter(); + if (!importer) + return false; + + return importer->LayoutRecordType(record_decl, bit_size, alignment, + field_offsets, base_offsets, vbase_offsets); +} + +// CompilerDecl override functions + +ConstString TypeSystemClang::DeclGetName(void *opaque_decl) { + if (opaque_decl) { + clang::NamedDecl *nd = + llvm::dyn_cast((clang::Decl *)opaque_decl); + if (nd != nullptr) + return ConstString(nd->getDeclName().getAsString()); + } + return ConstString(); +} + +ConstString TypeSystemClang::DeclGetMangledName(void *opaque_decl) { + if (opaque_decl) { + clang::NamedDecl *nd = + llvm::dyn_cast((clang::Decl *)opaque_decl); + if (nd != nullptr && !llvm::isa(nd)) { + clang::MangleContext *mc = getMangleContext(); + if (mc && mc->shouldMangleCXXName(nd)) { + llvm::SmallVector buf; + llvm::raw_svector_ostream llvm_ostrm(buf); + if (llvm::isa(nd)) { + mc->mangleName( + clang::GlobalDecl(llvm::dyn_cast(nd), + Ctor_Complete), + llvm_ostrm); + } else if (llvm::isa(nd)) { + mc->mangleName( + clang::GlobalDecl(llvm::dyn_cast(nd), + Dtor_Complete), + llvm_ostrm); + } else { + mc->mangleName(nd, llvm_ostrm); + } + if (buf.size() > 0) + return ConstString(buf.data(), buf.size()); + } + } + } + return ConstString(); +} + +CompilerDeclContext TypeSystemClang::DeclGetDeclContext(void *opaque_decl) { + if (opaque_decl) + return CreateDeclContext(((clang::Decl *)opaque_decl)->getDeclContext()); + return CompilerDeclContext(); +} + +CompilerType TypeSystemClang::DeclGetFunctionReturnType(void *opaque_decl) { + if (clang::FunctionDecl *func_decl = + llvm::dyn_cast((clang::Decl *)opaque_decl)) + return GetType(func_decl->getReturnType()); + if (clang::ObjCMethodDecl *objc_method = + llvm::dyn_cast((clang::Decl *)opaque_decl)) + return GetType(objc_method->getReturnType()); + else + return CompilerType(); +} + +size_t TypeSystemClang::DeclGetFunctionNumArguments(void *opaque_decl) { + if (clang::FunctionDecl *func_decl = + llvm::dyn_cast((clang::Decl *)opaque_decl)) + return func_decl->param_size(); + if (clang::ObjCMethodDecl *objc_method = + llvm::dyn_cast((clang::Decl *)opaque_decl)) + return objc_method->param_size(); + else + return 0; +} + +CompilerType TypeSystemClang::DeclGetFunctionArgumentType(void *opaque_decl, + size_t idx) { + if (clang::FunctionDecl *func_decl = + llvm::dyn_cast((clang::Decl *)opaque_decl)) { + if (idx < func_decl->param_size()) { + ParmVarDecl *var_decl = func_decl->getParamDecl(idx); + if (var_decl) + return GetType(var_decl->getOriginalType()); + } + } else if (clang::ObjCMethodDecl *objc_method = + llvm::dyn_cast( + (clang::Decl *)opaque_decl)) { + if (idx < objc_method->param_size()) + return GetType(objc_method->parameters()[idx]->getOriginalType()); + } + return CompilerType(); +} + +// CompilerDeclContext functions + +std::vector TypeSystemClang::DeclContextFindDeclByName( + void *opaque_decl_ctx, ConstString name, const bool ignore_using_decls) { + std::vector found_decls; + if (opaque_decl_ctx) { + DeclContext *root_decl_ctx = (DeclContext *)opaque_decl_ctx; + std::set searched; + std::multimap search_queue; + SymbolFile *symbol_file = GetSymbolFile(); + + for (clang::DeclContext *decl_context = root_decl_ctx; + decl_context != nullptr && found_decls.empty(); + decl_context = decl_context->getParent()) { + search_queue.insert(std::make_pair(decl_context, decl_context)); + + for (auto it = search_queue.find(decl_context); it != search_queue.end(); + it++) { + if (!searched.insert(it->second).second) + continue; + symbol_file->ParseDeclsForContext( + CreateDeclContext(it->second)); + + for (clang::Decl *child : it->second->decls()) { + if (clang::UsingDirectiveDecl *ud = + llvm::dyn_cast(child)) { + if (ignore_using_decls) + continue; + clang::DeclContext *from = ud->getCommonAncestor(); + if (searched.find(ud->getNominatedNamespace()) == searched.end()) + search_queue.insert( + std::make_pair(from, ud->getNominatedNamespace())); + } else if (clang::UsingDecl *ud = + llvm::dyn_cast(child)) { + if (ignore_using_decls) + continue; + for (clang::UsingShadowDecl *usd : ud->shadows()) { + clang::Decl *target = usd->getTargetDecl(); + if (clang::NamedDecl *nd = + llvm::dyn_cast(target)) { + IdentifierInfo *ii = nd->getIdentifier(); + if (ii != nullptr && + ii->getName().equals(name.AsCString(nullptr))) + found_decls.push_back(GetCompilerDecl(nd)); + } + } + } else if (clang::NamedDecl *nd = + llvm::dyn_cast(child)) { + IdentifierInfo *ii = nd->getIdentifier(); + if (ii != nullptr && ii->getName().equals(name.AsCString(nullptr))) + found_decls.push_back(GetCompilerDecl(nd)); + } + } + } + } + } + return found_decls; +} + +// Look for child_decl_ctx's lookup scope in frame_decl_ctx and its parents, +// and return the number of levels it took to find it, or +// LLDB_INVALID_DECL_LEVEL if not found. If the decl was imported via a using +// declaration, its name and/or type, if set, will be used to check that the +// decl found in the scope is a match. +// +// The optional name is required by languages (like C++) to handle using +// declarations like: +// +// void poo(); +// namespace ns { +// void foo(); +// void goo(); +// } +// void bar() { +// using ns::foo; +// // CountDeclLevels returns 0 for 'foo', 1 for 'poo', and +// // LLDB_INVALID_DECL_LEVEL for 'goo'. +// } +// +// The optional type is useful in the case that there's a specific overload +// that we're looking for that might otherwise be shadowed, like: +// +// void foo(int); +// namespace ns { +// void foo(); +// } +// void bar() { +// using ns::foo; +// // CountDeclLevels returns 0 for { 'foo', void() }, +// // 1 for { 'foo', void(int) }, and +// // LLDB_INVALID_DECL_LEVEL for { 'foo', void(int, int) }. +// } +// +// NOTE: Because file statics are at the TranslationUnit along with globals, a +// function at file scope will return the same level as a function at global +// scope. Ideally we'd like to treat the file scope as an additional scope just +// below the global scope. More work needs to be done to recognise that, if +// the decl we're trying to look up is static, we should compare its source +// file with that of the current scope and return a lower number for it. +uint32_t TypeSystemClang::CountDeclLevels(clang::DeclContext *frame_decl_ctx, + clang::DeclContext *child_decl_ctx, + ConstString *child_name, + CompilerType *child_type) { + if (frame_decl_ctx) { + std::set searched; + std::multimap search_queue; + SymbolFile *symbol_file = GetSymbolFile(); + + // Get the lookup scope for the decl we're trying to find. + clang::DeclContext *parent_decl_ctx = child_decl_ctx->getParent(); + + // Look for it in our scope's decl context and its parents. + uint32_t level = 0; + for (clang::DeclContext *decl_ctx = frame_decl_ctx; decl_ctx != nullptr; + decl_ctx = decl_ctx->getParent()) { + if (!decl_ctx->isLookupContext()) + continue; + if (decl_ctx == parent_decl_ctx) + // Found it! + return level; + search_queue.insert(std::make_pair(decl_ctx, decl_ctx)); + for (auto it = search_queue.find(decl_ctx); it != search_queue.end(); + it++) { + if (searched.find(it->second) != searched.end()) + continue; + + // Currently DWARF has one shared translation unit for all Decls at top + // level, so this would erroneously find using statements anywhere. So + // don't look at the top-level translation unit. + // TODO fix this and add a testcase that depends on it. + + if (llvm::isa(it->second)) + continue; + + searched.insert(it->second); + symbol_file->ParseDeclsForContext( + CreateDeclContext(it->second)); + + for (clang::Decl *child : it->second->decls()) { + if (clang::UsingDirectiveDecl *ud = + llvm::dyn_cast(child)) { + clang::DeclContext *ns = ud->getNominatedNamespace(); + if (ns == parent_decl_ctx) + // Found it! + return level; + clang::DeclContext *from = ud->getCommonAncestor(); + if (searched.find(ns) == searched.end()) + search_queue.insert(std::make_pair(from, ns)); + } else if (child_name) { + if (clang::UsingDecl *ud = + llvm::dyn_cast(child)) { + for (clang::UsingShadowDecl *usd : ud->shadows()) { + clang::Decl *target = usd->getTargetDecl(); + clang::NamedDecl *nd = llvm::dyn_cast(target); + if (!nd) + continue; + // Check names. + IdentifierInfo *ii = nd->getIdentifier(); + if (ii == nullptr || + !ii->getName().equals(child_name->AsCString(nullptr))) + continue; + // Check types, if one was provided. + if (child_type) { + CompilerType clang_type = GetTypeForDecl(nd); + if (!AreTypesSame(clang_type, *child_type, + /*ignore_qualifiers=*/true)) + continue; + } + // Found it! + return level; + } + } + } + } + } + ++level; + } + } + return LLDB_INVALID_DECL_LEVEL; +} + +ConstString TypeSystemClang::DeclContextGetName(void *opaque_decl_ctx) { + if (opaque_decl_ctx) { + clang::NamedDecl *named_decl = + llvm::dyn_cast((clang::DeclContext *)opaque_decl_ctx); + if (named_decl) + return ConstString(named_decl->getName()); + } + return ConstString(); +} + +ConstString +TypeSystemClang::DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) { + if (opaque_decl_ctx) { + clang::NamedDecl *named_decl = + llvm::dyn_cast((clang::DeclContext *)opaque_decl_ctx); + if (named_decl) + return ConstString( + llvm::StringRef(named_decl->getQualifiedNameAsString())); + } + return ConstString(); +} + +bool TypeSystemClang::DeclContextIsClassMethod( + void *opaque_decl_ctx, lldb::LanguageType *language_ptr, + bool *is_instance_method_ptr, ConstString *language_object_name_ptr) { + if (opaque_decl_ctx) { + clang::DeclContext *decl_ctx = (clang::DeclContext *)opaque_decl_ctx; + if (ObjCMethodDecl *objc_method = + llvm::dyn_cast(decl_ctx)) { + if (is_instance_method_ptr) + *is_instance_method_ptr = objc_method->isInstanceMethod(); + if (language_ptr) + *language_ptr = eLanguageTypeObjC; + if (language_object_name_ptr) + language_object_name_ptr->SetCString("self"); + return true; + } else if (CXXMethodDecl *cxx_method = + llvm::dyn_cast(decl_ctx)) { + if (is_instance_method_ptr) + *is_instance_method_ptr = cxx_method->isInstance(); + if (language_ptr) + *language_ptr = eLanguageTypeC_plus_plus; + if (language_object_name_ptr) + language_object_name_ptr->SetCString("this"); + return true; + } else if (clang::FunctionDecl *function_decl = + llvm::dyn_cast(decl_ctx)) { + ClangASTMetadata *metadata = GetMetadata(function_decl); + if (metadata && metadata->HasObjectPtr()) { + if (is_instance_method_ptr) + *is_instance_method_ptr = true; + if (language_ptr) + *language_ptr = eLanguageTypeObjC; + if (language_object_name_ptr) + language_object_name_ptr->SetCString(metadata->GetObjectPtrName()); + return true; + } + } + } + return false; +} + +bool TypeSystemClang::DeclContextIsContainedInLookup( + void *opaque_decl_ctx, void *other_opaque_decl_ctx) { + auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx; + auto *other = (clang::DeclContext *)other_opaque_decl_ctx; + + do { + // A decl context always includes its own contents in its lookup. + if (decl_ctx == other) + return true; + + // If we have an inline namespace, then the lookup of the parent context + // also includes the inline namespace contents. + } while (other->isInlineNamespace() && (other = other->getParent())); + + return false; +} + +static bool IsClangDeclContext(const CompilerDeclContext &dc) { + return dc.IsValid() && isa(dc.GetTypeSystem()); +} + +clang::DeclContext * +TypeSystemClang::DeclContextGetAsDeclContext(const CompilerDeclContext &dc) { + if (IsClangDeclContext(dc)) + return (clang::DeclContext *)dc.GetOpaqueDeclContext(); + return nullptr; +} + +ObjCMethodDecl * +TypeSystemClang::DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc) { + if (IsClangDeclContext(dc)) + return llvm::dyn_cast( + (clang::DeclContext *)dc.GetOpaqueDeclContext()); + return nullptr; +} + +CXXMethodDecl * +TypeSystemClang::DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc) { + if (IsClangDeclContext(dc)) + return llvm::dyn_cast( + (clang::DeclContext *)dc.GetOpaqueDeclContext()); + return nullptr; +} + +clang::FunctionDecl * +TypeSystemClang::DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc) { + if (IsClangDeclContext(dc)) + return llvm::dyn_cast( + (clang::DeclContext *)dc.GetOpaqueDeclContext()); + return nullptr; +} + +clang::NamespaceDecl * +TypeSystemClang::DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc) { + if (IsClangDeclContext(dc)) + return llvm::dyn_cast( + (clang::DeclContext *)dc.GetOpaqueDeclContext()); + return nullptr; +} + +ClangASTMetadata * +TypeSystemClang::DeclContextGetMetaData(const CompilerDeclContext &dc, + const Decl *object) { + TypeSystemClang *ast = llvm::cast(dc.GetTypeSystem()); + return ast->GetMetadata(object); +} + +clang::ASTContext * +TypeSystemClang::DeclContextGetTypeSystemClang(const CompilerDeclContext &dc) { + TypeSystemClang *ast = + llvm::dyn_cast_or_null(dc.GetTypeSystem()); + if (ast) + return &ast->getASTContext(); + return nullptr; +} + +TypeSystemClangForExpressions::TypeSystemClangForExpressions( + Target &target, llvm::Triple triple) + : TypeSystemClang("scratch ASTContext", triple), + m_target_wp(target.shared_from_this()), + m_persistent_variables(new ClangPersistentVariables) { + m_scratch_ast_source_up = std::make_unique( + target.shared_from_this(), m_persistent_variables->GetClangASTImporter()); + m_scratch_ast_source_up->InstallASTContext(*this); + llvm::IntrusiveRefCntPtr proxy_ast_source( + m_scratch_ast_source_up->CreateProxy()); + SetExternalSource(proxy_ast_source); +} + +void TypeSystemClangForExpressions::Finalize() { + TypeSystemClang::Finalize(); + m_scratch_ast_source_up.reset(); +} + +UserExpression *TypeSystemClangForExpressions::GetUserExpression( + llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, + Expression::ResultType desired_type, + const EvaluateExpressionOptions &options, + ValueObject *ctx_obj) { + TargetSP target_sp = m_target_wp.lock(); + if (!target_sp) + return nullptr; + + return new ClangUserExpression(*target_sp.get(), expr, prefix, language, + desired_type, options, ctx_obj); +} + +FunctionCaller *TypeSystemClangForExpressions::GetFunctionCaller( + const CompilerType &return_type, const Address &function_address, + const ValueList &arg_value_list, const char *name) { + TargetSP target_sp = m_target_wp.lock(); + if (!target_sp) + return nullptr; + + Process *process = target_sp->GetProcessSP().get(); + if (!process) + return nullptr; + + return new ClangFunctionCaller(*process, return_type, function_address, + arg_value_list, name); +} + +UtilityFunction * +TypeSystemClangForExpressions::GetUtilityFunction(const char *text, + const char *name) { + TargetSP target_sp = m_target_wp.lock(); + if (!target_sp) + return nullptr; + + return new ClangUtilityFunction(*target_sp.get(), text, name); +} + +PersistentExpressionState * +TypeSystemClangForExpressions::GetPersistentExpressionState() { + return m_persistent_variables.get(); +} diff --git a/gnu/llvm/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/gnu/llvm/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h new file mode 100644 index 00000000000..9475e4d9f44 --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -0,0 +1,1153 @@ +//===-- TypeSystemClang.h ---------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_TYPESYSTEM_CLANG_TYPESYSTEMCLANG_H +#define LLDB_SOURCE_PLUGINS_TYPESYSTEM_CLANG_TYPESYSTEMCLANG_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clang/AST/ASTContext.h" +#include "clang/AST/ASTFwd.h" +#include "clang/AST/TemplateBase.h" +#include "clang/Basic/TargetInfo.h" +#include "llvm/ADT/APSInt.h" +#include "llvm/ADT/SmallVector.h" + +#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" +#include "lldb/Expression/ExpressionVariable.h" +#include "lldb/Symbol/CompilerType.h" +#include "lldb/Symbol/TypeSystem.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Flags.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" +#include "lldb/lldb-enumerations.h" + +class DWARFASTParserClang; +class PDBASTParser; + +namespace clang { +class FileManager; +class HeaderSearch; +class ModuleMap; +} // namespace clang + +namespace lldb_private { + +class ClangASTMetadata; +class ClangASTSource; +class Declaration; + +/// A Clang module ID. +class OptionalClangModuleID { + unsigned m_id = 0; + +public: + OptionalClangModuleID() = default; + explicit OptionalClangModuleID(unsigned id) : m_id(id) {} + bool HasValue() const { return m_id != 0; } + unsigned GetValue() const { return m_id; } +}; + +/// The implementation of lldb::Type's m_payload field for TypeSystemClang. +class TypePayloadClang { + /// The Layout is as follows: + /// \verbatim + /// bit 0..30 ... Owning Module ID. + /// bit 31 ...... IsCompleteObjCClass. + /// \endverbatim + Type::Payload m_payload = 0; + +public: + TypePayloadClang() = default; + explicit TypePayloadClang(OptionalClangModuleID owning_module, + bool is_complete_objc_class = false); + explicit TypePayloadClang(uint32_t opaque_payload) : m_payload(opaque_payload) {} + operator Type::Payload() { return m_payload; } + + static constexpr unsigned ObjCClassBit = 1 << 31; + bool IsCompleteObjCClass() { return Flags(m_payload).Test(ObjCClassBit); } + void SetIsCompleteObjCClass(bool is_complete_objc_class) { + m_payload = is_complete_objc_class ? Flags(m_payload).Set(ObjCClassBit) + : Flags(m_payload).Clear(ObjCClassBit); + } + OptionalClangModuleID GetOwningModule() { + return OptionalClangModuleID(Flags(m_payload).Clear(ObjCClassBit)); + } + void SetOwningModule(OptionalClangModuleID id); + /// \} +}; + +/// A TypeSystem implementation based on Clang. +/// +/// This class uses a single clang::ASTContext as the backend for storing +/// its types and declarations. Every clang::ASTContext should also just have +/// a single associated TypeSystemClang instance that manages it. +/// +/// The clang::ASTContext instance can either be created by TypeSystemClang +/// itself or it can adopt an existing clang::ASTContext (for example, when +/// it is necessary to provide a TypeSystem interface for an existing +/// clang::ASTContext that was created by clang::CompilerInstance). +class TypeSystemClang : public TypeSystem { + // LLVM RTTI support + static char ID; + +public: + typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *); + typedef void (*CompleteObjCInterfaceDeclCallback)(void *baton, + clang::ObjCInterfaceDecl *); + + // llvm casting support + bool isA(const void *ClassID) const override { return ClassID == &ID; } + static bool classof(const TypeSystem *ts) { return ts->isA(&ID); } + + /// Constructs a TypeSystemClang with an ASTContext using the given triple. + /// + /// \param name The name for the TypeSystemClang (for logging purposes) + /// \param triple The llvm::Triple used for the ASTContext. The triple defines + /// certain characteristics of the ASTContext and its types + /// (e.g., whether certain primitive types exist or what their + /// signedness is). + explicit TypeSystemClang(llvm::StringRef name, llvm::Triple triple); + + /// Constructs a TypeSystemClang that uses an existing ASTContext internally. + /// Useful when having an existing ASTContext created by Clang. + /// + /// \param name The name for the TypeSystemClang (for logging purposes) + /// \param existing_ctxt An existing ASTContext. + explicit TypeSystemClang(llvm::StringRef name, + clang::ASTContext &existing_ctxt); + + ~TypeSystemClang() override; + + void Finalize() 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 LanguageSet GetSupportedLanguagesForTypes(); + static LanguageSet GetSupportedLanguagesForExpressions(); + + static void Initialize(); + + static void Terminate(); + + static TypeSystemClang *GetASTContext(clang::ASTContext *ast_ctx); + + static TypeSystemClang *GetScratch(Target &target, + bool create_on_demand = true) { + auto type_system_or_err = target.GetScratchTypeSystemForLanguage( + lldb::eLanguageTypeC, create_on_demand); + if (auto err = type_system_or_err.takeError()) { + LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET), + std::move(err), "Couldn't get scratch TypeSystemClang"); + return nullptr; + } + return llvm::dyn_cast(&type_system_or_err.get()); + } + + /// Returns the display name of this TypeSystemClang that indicates what + /// purpose it serves in LLDB. Used for example in logs. + llvm::StringRef getDisplayName() const { return m_display_name; } + + /// Returns the clang::ASTContext instance managed by this TypeSystemClang. + clang::ASTContext &getASTContext(); + + clang::MangleContext *getMangleContext(); + + std::shared_ptr &getTargetOptions(); + + clang::TargetInfo *getTargetInfo(); + + void setSema(clang::Sema *s); + clang::Sema *getSema() { return m_sema; } + + const char *GetTargetTriple(); + + void SetExternalSource( + llvm::IntrusiveRefCntPtr &ast_source_up); + + bool GetCompleteDecl(clang::Decl *decl) { + return TypeSystemClang::GetCompleteDecl(&getASTContext(), decl); + } + + static void DumpDeclHiearchy(clang::Decl *decl); + + static void DumpDeclContextHiearchy(clang::DeclContext *decl_ctx); + + static bool DeclsAreEquivalent(clang::Decl *lhs_decl, clang::Decl *rhs_decl); + + static bool GetCompleteDecl(clang::ASTContext *ast, clang::Decl *decl); + + void SetMetadataAsUserID(const clang::Decl *decl, lldb::user_id_t user_id); + void SetMetadataAsUserID(const clang::Type *type, lldb::user_id_t user_id); + + void SetMetadata(const clang::Decl *object, ClangASTMetadata &meta_data); + + void SetMetadata(const clang::Type *object, ClangASTMetadata &meta_data); + ClangASTMetadata *GetMetadata(const clang::Decl *object); + ClangASTMetadata *GetMetadata(const clang::Type *object); + + // Basic Types + CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, + size_t bit_size) override; + + CompilerType GetBasicType(lldb::BasicType type); + + static lldb::BasicType GetBasicTypeEnumeration(ConstString name); + + CompilerType + GetBuiltinTypeForDWARFEncodingAndBitSize(llvm::StringRef type_name, + uint32_t dw_ate, uint32_t bit_size); + + CompilerType GetCStringType(bool is_const); + + static clang::DeclContext *GetDeclContextForType(clang::QualType type); + + static clang::DeclContext *GetDeclContextForType(const CompilerType &type); + + uint32_t GetPointerByteSize() override; + + clang::TranslationUnitDecl *GetTranslationUnitDecl() { + return getASTContext().getTranslationUnitDecl(); + } + + static bool AreTypesSame(CompilerType type1, CompilerType type2, + bool ignore_qualifiers = false); + + /// Creates a CompilerType form the given QualType with the current + /// TypeSystemClang instance as the CompilerType's typesystem. + /// \param qt The QualType for a type that belongs to the ASTContext of this + /// TypeSystemClang. + /// \return The CompilerType representing the given QualType. If the + /// QualType's type pointer is a nullptr then the function returns an + /// invalid CompilerType. + CompilerType GetType(clang::QualType qt) { + if (qt.getTypePtrOrNull() == nullptr) + return CompilerType(); + // Check that the type actually belongs to this TypeSystemClang. + assert(qt->getAsTagDecl() == nullptr || + &qt->getAsTagDecl()->getASTContext() == &getASTContext()); + return CompilerType(this, qt.getAsOpaquePtr()); + } + + CompilerType GetTypeForDecl(clang::NamedDecl *decl); + + CompilerType GetTypeForDecl(clang::TagDecl *decl); + + CompilerType GetTypeForDecl(clang::ObjCInterfaceDecl *objc_decl); + + template + CompilerType + GetTypeForIdentifier(ConstString type_name, + clang::DeclContext *decl_context = nullptr) { + CompilerType compiler_type; + + if (type_name.GetLength()) { + clang::ASTContext &ast = getASTContext(); + if (!decl_context) + decl_context = ast.getTranslationUnitDecl(); + + clang::IdentifierInfo &myIdent = ast.Idents.get(type_name.GetCString()); + clang::DeclarationName myName = + ast.DeclarationNames.getIdentifier(&myIdent); + + clang::DeclContext::lookup_result result = decl_context->lookup(myName); + + if (!result.empty()) { + clang::NamedDecl *named_decl = result[0]; + if (const RecordDeclType *record_decl = + llvm::dyn_cast(named_decl)) + compiler_type.SetCompilerType( + this, clang::QualType(record_decl->getTypeForDecl(), 0) + .getAsOpaquePtr()); + } + } + + return compiler_type; + } + + CompilerType CreateStructForIdentifier( + ConstString type_name, + const std::initializer_list> + &type_fields, + bool packed = false); + + CompilerType GetOrCreateStructForIdentifier( + ConstString type_name, + const std::initializer_list> + &type_fields, + bool packed = false); + + static bool IsOperator(llvm::StringRef name, + clang::OverloadedOperatorKind &op_kind); + + // Structure, Unions, Classes + + static clang::AccessSpecifier + ConvertAccessTypeToAccessSpecifier(lldb::AccessType access); + + static clang::AccessSpecifier + UnifyAccessSpecifiers(clang::AccessSpecifier lhs, clang::AccessSpecifier rhs); + + static uint32_t GetNumBaseClasses(const clang::CXXRecordDecl *cxx_record_decl, + bool omit_empty_base_classes); + + /// Synthesize a clang::Module and return its ID or a default-constructed ID. + OptionalClangModuleID GetOrCreateClangModule(llvm::StringRef name, + OptionalClangModuleID parent, + bool is_framework = false, + bool is_explicit = false); + + CompilerType CreateRecordType(clang::DeclContext *decl_ctx, + OptionalClangModuleID owning_module, + lldb::AccessType access_type, + llvm::StringRef name, int kind, + lldb::LanguageType language, + ClangASTMetadata *metadata = nullptr, + bool exports_symbols = false); + + class TemplateParameterInfos { + public: + bool IsValid() const { + if (args.empty()) + return false; + return args.size() == names.size() && + ((bool)pack_name == (bool)packed_args) && + (!packed_args || !packed_args->packed_args); + } + + llvm::SmallVector names; + llvm::SmallVector args; + + const char * pack_name = nullptr; + std::unique_ptr packed_args; + }; + + clang::FunctionTemplateDecl * + CreateFunctionTemplateDecl(clang::DeclContext *decl_ctx, + OptionalClangModuleID owning_module, + clang::FunctionDecl *func_decl, const char *name, + const TemplateParameterInfos &infos); + + void CreateFunctionTemplateSpecializationInfo( + clang::FunctionDecl *func_decl, clang::FunctionTemplateDecl *Template, + const TemplateParameterInfos &infos); + + clang::ClassTemplateDecl * + CreateClassTemplateDecl(clang::DeclContext *decl_ctx, + OptionalClangModuleID owning_module, + lldb::AccessType access_type, const char *class_name, + int kind, const TemplateParameterInfos &infos); + + clang::TemplateTemplateParmDecl * + CreateTemplateTemplateParmDecl(const char *template_name); + + clang::ClassTemplateSpecializationDecl *CreateClassTemplateSpecializationDecl( + clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, + clang::ClassTemplateDecl *class_template_decl, int kind, + const TemplateParameterInfos &infos); + + CompilerType + CreateClassTemplateSpecializationType(clang::ClassTemplateSpecializationDecl * + class_template_specialization_decl); + + static clang::DeclContext * + GetAsDeclContext(clang::FunctionDecl *function_decl); + + static bool CheckOverloadedOperatorKindParameterCount( + bool is_method, clang::OverloadedOperatorKind op_kind, + uint32_t num_params); + + bool FieldIsBitfield(clang::FieldDecl *field, uint32_t &bitfield_bit_size); + + static bool RecordHasFields(const clang::RecordDecl *record_decl); + + CompilerType CreateObjCClass(llvm::StringRef name, + clang::DeclContext *decl_ctx, + OptionalClangModuleID owning_module, + bool isForwardDecl, bool isInternal, + ClangASTMetadata *metadata = nullptr); + + bool SetTagTypeKind(clang::QualType type, int kind) const; + + bool SetDefaultAccessForRecordFields(clang::RecordDecl *record_decl, + int default_accessibility, + int *assigned_accessibilities, + size_t num_assigned_accessibilities); + + // Returns a mask containing bits from the TypeSystemClang::eTypeXXX + // enumerations + + // Namespace Declarations + + clang::NamespaceDecl * + GetUniqueNamespaceDeclaration(const char *name, clang::DeclContext *decl_ctx, + OptionalClangModuleID owning_module, + bool is_inline = false); + + // Function Types + + clang::FunctionDecl * + CreateFunctionDeclaration(clang::DeclContext *decl_ctx, + OptionalClangModuleID owning_module, + const char *name, const CompilerType &function_Type, + int storage, bool is_inline); + + CompilerType CreateFunctionType(const CompilerType &result_type, + const CompilerType *args, unsigned num_args, + bool is_variadic, unsigned type_quals, + clang::CallingConv cc); + + CompilerType CreateFunctionType(const CompilerType &result_type, + const CompilerType *args, unsigned num_args, + bool is_variadic, unsigned type_quals) { + return CreateFunctionType(result_type, args, num_args, is_variadic, + type_quals, clang::CC_C); + } + + clang::ParmVarDecl * + CreateParameterDeclaration(clang::DeclContext *decl_ctx, + OptionalClangModuleID owning_module, + const char *name, const CompilerType ¶m_type, + int storage, bool add_decl = false); + + void SetFunctionParameters(clang::FunctionDecl *function_decl, + clang::ParmVarDecl **params, unsigned num_params); + + CompilerType CreateBlockPointerType(const CompilerType &function_type); + + // Array Types + + CompilerType CreateArrayType(const CompilerType &element_type, + size_t element_count, bool is_vector); + + // Enumeration Types + CompilerType CreateEnumerationType(const char *name, + clang::DeclContext *decl_ctx, + OptionalClangModuleID owning_module, + const Declaration &decl, + const CompilerType &integer_qual_type, + bool is_scoped); + + // Integer type functions + + CompilerType GetIntTypeFromBitSize(size_t bit_size, bool is_signed); + + CompilerType GetPointerSizedIntType(bool is_signed); + + // Floating point functions + + static CompilerType GetFloatTypeFromBitSize(clang::ASTContext *ast, + size_t bit_size); + + // TypeSystem methods + DWARFASTParser *GetDWARFParser() override; + PDBASTParser *GetPDBParser() override; + + // TypeSystemClang callbacks for external source lookups. + void CompleteTagDecl(clang::TagDecl *); + + void CompleteObjCInterfaceDecl(clang::ObjCInterfaceDecl *); + + bool LayoutRecordType( + const clang::RecordDecl *record_decl, uint64_t &size, uint64_t &alignment, + llvm::DenseMap &field_offsets, + llvm::DenseMap + &base_offsets, + llvm::DenseMap + &vbase_offsets); + + /// Creates a CompilerDecl from the given Decl with the current + /// TypeSystemClang instance as its typesystem. + /// The Decl has to come from the ASTContext of this + /// TypeSystemClang. + CompilerDecl GetCompilerDecl(clang::Decl *decl) { + assert(&decl->getASTContext() == &getASTContext() && + "CreateCompilerDecl for Decl from wrong ASTContext?"); + return CompilerDecl(this, decl); + } + + // CompilerDecl override functions + ConstString DeclGetName(void *opaque_decl) override; + + ConstString DeclGetMangledName(void *opaque_decl) override; + + CompilerDeclContext DeclGetDeclContext(void *opaque_decl) override; + + CompilerType DeclGetFunctionReturnType(void *opaque_decl) override; + + size_t DeclGetFunctionNumArguments(void *opaque_decl) override; + + CompilerType DeclGetFunctionArgumentType(void *opaque_decl, + size_t arg_idx) override; + + CompilerType GetTypeForDecl(void *opaque_decl) override; + + // CompilerDeclContext override functions + + /// Creates a CompilerDeclContext from the given DeclContext + /// with the current TypeSystemClang instance as its typesystem. + /// The DeclContext has to come from the ASTContext of this + /// TypeSystemClang. + CompilerDeclContext CreateDeclContext(clang::DeclContext *ctx); + + /// Set the owning module for \p decl. + static void SetOwningModule(clang::Decl *decl, + OptionalClangModuleID owning_module); + + std::vector + DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, + const bool ignore_using_decls) override; + + ConstString DeclContextGetName(void *opaque_decl_ctx) override; + + ConstString DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) override; + + bool DeclContextIsClassMethod(void *opaque_decl_ctx, + lldb::LanguageType *language_ptr, + bool *is_instance_method_ptr, + ConstString *language_object_name_ptr) override; + + bool DeclContextIsContainedInLookup(void *opaque_decl_ctx, + void *other_opaque_decl_ctx) override; + + // Clang specific clang::DeclContext functions + + static clang::DeclContext * + DeclContextGetAsDeclContext(const CompilerDeclContext &dc); + + static clang::ObjCMethodDecl * + DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc); + + static clang::CXXMethodDecl * + DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc); + + static clang::FunctionDecl * + DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc); + + static clang::NamespaceDecl * + DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc); + + static ClangASTMetadata *DeclContextGetMetaData(const CompilerDeclContext &dc, + const clang::Decl *object); + + static clang::ASTContext * + DeclContextGetTypeSystemClang(const CompilerDeclContext &dc); + + // Tests + +#ifndef NDEBUG + bool Verify(lldb::opaque_compiler_type_t type) override; +#endif + + bool IsArrayType(lldb::opaque_compiler_type_t type, + CompilerType *element_type, uint64_t *size, + bool *is_incomplete) override; + + bool IsVectorType(lldb::opaque_compiler_type_t type, + CompilerType *element_type, uint64_t *size) override; + + bool IsAggregateType(lldb::opaque_compiler_type_t type) override; + + bool IsAnonymousType(lldb::opaque_compiler_type_t type) override; + + bool IsBeingDefined(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 IsConst(lldb::opaque_compiler_type_t type) override; + + bool IsCStringType(lldb::opaque_compiler_type_t type, + uint32_t &length) override; + + static bool IsCXXClassType(const CompilerType &type); + + 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) override; + + uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, + CompilerType *base_type_ptr) 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 IsEnumerationType(lldb::opaque_compiler_type_t type, + bool &is_signed) override; + + static bool IsObjCClassType(const CompilerType &type); + + static bool IsObjCClassTypeAndHasIVars(const CompilerType &type, + bool check_superclass); + + static bool IsObjCObjectOrInterfaceType(const CompilerType &type); + + static bool IsObjCObjectPointerType(const CompilerType &type, + CompilerType *target_type = nullptr); + + bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) override; + + static bool IsClassType(lldb::opaque_compiler_type_t type); + + static bool IsEnumType(lldb::opaque_compiler_type_t type); + + bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type, + CompilerType *target_type, // Can pass nullptr + bool check_cplusplus, bool check_objc) override; + + bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override; + + bool IsPointerType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type) override; + + bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type) override; + + bool IsReferenceType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type, bool *is_rvalue) override; + + bool IsScalarType(lldb::opaque_compiler_type_t type) override; + + bool IsTypedefType(lldb::opaque_compiler_type_t type) override; + + bool IsVoidType(lldb::opaque_compiler_type_t type) override; + + bool CanPassInRegisters(const CompilerType &type) override; + + bool SupportsLanguage(lldb::LanguageType language) override; + + static llvm::Optional GetCXXClassName(const CompilerType &type); + + // Type Completion + + bool GetCompleteType(lldb::opaque_compiler_type_t type) override; + + // Accessors + + ConstString GetTypeName(lldb::opaque_compiler_type_t type) override; + + ConstString GetDisplayTypeName(lldb::opaque_compiler_type_t type) override; + + uint32_t GetTypeInfo(lldb::opaque_compiler_type_t type, + CompilerType *pointee_or_element_compiler_type) override; + + lldb::LanguageType + GetMinimumLanguage(lldb::opaque_compiler_type_t type) override; + + lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override; + + unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) override; + + // Creating related types + + /// Using the current type, create a new typedef to that type using + /// "typedef_name" as the name and "decl_ctx" as the decl context. + /// \param payload is an opaque TypePayloadClang. + static CompilerType + CreateTypedefType(const CompilerType &type, const char *typedef_name, + const CompilerDeclContext &compiler_decl_ctx, + uint32_t opaque_payload); + + CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type, + uint64_t *stride) override; + + CompilerType GetArrayType(lldb::opaque_compiler_type_t type, + uint64_t size) override; + + CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override; + + CompilerType + GetFullyUnqualifiedType(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 GetNonReferenceType(lldb::opaque_compiler_type_t type) override; + + CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) override; + + CompilerType GetPointerType(lldb::opaque_compiler_type_t type) override; + + CompilerType + GetLValueReferenceType(lldb::opaque_compiler_type_t type) override; + + CompilerType + GetRValueReferenceType(lldb::opaque_compiler_type_t type) override; + + CompilerType GetAtomicType(lldb::opaque_compiler_type_t type) override; + + CompilerType AddConstModifier(lldb::opaque_compiler_type_t type) override; + + CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type) override; + + CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type) override; + + CompilerType CreateTypedef(lldb::opaque_compiler_type_t type, + const char *name, + const CompilerDeclContext &decl_ctx, + uint32_t opaque_payload) override; + + // If the current object represents a typedef type, get the underlying type + CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override; + + // Create related types using the current type's AST + CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override; + + // Exploring the type + + const llvm::fltSemantics &GetFloatTypeSemantics(size_t byte_size) override; + + llvm::Optional GetByteSize(lldb::opaque_compiler_type_t type, + ExecutionContextScope *exe_scope) { + if (llvm::Optional bit_size = GetBitSize(type, exe_scope)) + return (*bit_size + 7) / 8; + return llvm::None; + } + + llvm::Optional + 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; + + llvm::Optional + GetTypeBitAlign(lldb::opaque_compiler_type_t type, + ExecutionContextScope *exe_scope) override; + + uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, + bool omit_empty_base_classes, + const ExecutionContext *exe_ctx) override; + + CompilerType GetBuiltinTypeByName(ConstString name) override; + + lldb::BasicType + GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override; + + static lldb::BasicType + GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type, + ConstString name); + + void ForEachEnumerator( + lldb::opaque_compiler_type_t type, + std::function const &callback) 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; + + 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; + + static uint32_t GetNumPointeeChildren(clang::QualType type); + + 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; + + lldb::TemplateArgumentKind + GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, + size_t idx) override; + CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, + size_t idx) override; + llvm::Optional + GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, + size_t idx) override; + + CompilerType GetTypeForFormatters(void *type) override; + +#define LLDB_INVALID_DECL_LEVEL UINT32_MAX + // LLDB_INVALID_DECL_LEVEL is returned by CountDeclLevels if child_decl_ctx + // could not be found in decl_ctx. + uint32_t CountDeclLevels(clang::DeclContext *frame_decl_ctx, + clang::DeclContext *child_decl_ctx, + ConstString *child_name = nullptr, + CompilerType *child_type = nullptr); + + // Modifying RecordType + static clang::FieldDecl *AddFieldToRecordType(const CompilerType &type, + llvm::StringRef name, + const CompilerType &field_type, + lldb::AccessType access, + uint32_t bitfield_bit_size); + + static void BuildIndirectFields(const CompilerType &type); + + static void SetIsPacked(const CompilerType &type); + + static clang::VarDecl *AddVariableToRecordType(const CompilerType &type, + llvm::StringRef name, + const CompilerType &var_type, + lldb::AccessType access); + + /// Initializes a variable with an integer value. + /// \param var The variable to initialize. Must not already have an + /// initializer and must have an integer or enum type. + /// \param init_value The integer value that the variable should be + /// initialized to. Has to match the bit width of the + /// variable type. + static void SetIntegerInitializerForVariable(clang::VarDecl *var, + const llvm::APInt &init_value); + + /// Initializes a variable with a floating point value. + /// \param var The variable to initialize. Must not already have an + /// initializer and must have a floating point type. + /// \param init_value The float value that the variable should be + /// initialized to. + static void + SetFloatingInitializerForVariable(clang::VarDecl *var, + const llvm::APFloat &init_value); + + clang::CXXMethodDecl *AddMethodToCXXRecordType( + lldb::opaque_compiler_type_t type, llvm::StringRef name, + const char *mangled_name, const CompilerType &method_type, + lldb::AccessType access, bool is_virtual, 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 + std::unique_ptr + CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type, + lldb::AccessType access, bool is_virtual, + bool base_of_class); + + bool TransferBaseClasses( + lldb::opaque_compiler_type_t type, + std::vector> bases); + + static bool SetObjCSuperClass(const CompilerType &type, + const CompilerType &superclass_compiler_type); + + static bool AddObjCClassProperty(const CompilerType &type, + const char *property_name, + const CompilerType &property_compiler_type, + clang::ObjCIvarDecl *ivar_decl, + const char *property_setter_name, + const char *property_getter_name, + uint32_t property_attributes, + ClangASTMetadata *metadata); + + static clang::ObjCMethodDecl *AddMethodToObjCObjectType( + const CompilerType &type, + const char *name, // the full symbol name as seen in the symbol table + // (lldb::opaque_compiler_type_t type, "-[NString + // stringWithCString:]") + const CompilerType &method_compiler_type, lldb::AccessType access, + bool is_artificial, bool is_variadic, bool is_objc_direct_call); + + static bool SetHasExternalStorage(lldb::opaque_compiler_type_t type, + bool has_extern); + + // Tag Declarations + static bool StartTagDeclarationDefinition(const CompilerType &type); + + static bool CompleteTagDeclarationDefinition(const CompilerType &type); + + // Modifying Enumeration types + 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); + + /// Returns the underlying integer type for an enum type. If the given type + /// is invalid or not an enum-type, the function returns an invalid + /// CompilerType. + CompilerType GetEnumerationIntegerType(CompilerType type); + + // Pointers & References + + // Call this function using the class type when you want to make a member + // pointer type to pointee_type. + static CompilerType CreateMemberPointerType(const CompilerType &type, + const CompilerType &pointee_type); + + // Dumping types +#ifndef NDEBUG + /// Convenience LLVM-style dump method for use in the debugger only. + /// In contrast to the other \p Dump() methods this directly invokes + /// \p clang::QualType::dump(). + LLVM_DUMP_METHOD void dump(lldb::opaque_compiler_type_t type) const override; +#endif + + void Dump(Stream &s); + + /// Dump clang AST types from the symbol file. + /// + /// \param[in] s + /// A stream to send the dumped AST node(s) to + /// \param[in] symbol_name + /// The name of the symbol to dump, if it is empty dump all the symbols + void DumpFromSymbolFile(Stream &s, llvm::StringRef symbol_name); + + void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, + Stream *s, lldb::Format format, const DataExtractor &data, + 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 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; + + void DumpTypeDescription( + lldb::opaque_compiler_type_t type, + lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) override; + + void DumpTypeDescription( + lldb::opaque_compiler_type_t type, Stream *s, + lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) override; + + static void DumpTypeName(const CompilerType &type); + + static clang::EnumDecl *GetAsEnumDecl(const CompilerType &type); + + static clang::RecordDecl *GetAsRecordDecl(const CompilerType &type); + + static clang::TagDecl *GetAsTagDecl(const CompilerType &type); + + static clang::TypedefNameDecl *GetAsTypedefDecl(const CompilerType &type); + + static clang::CXXRecordDecl * + GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type); + + static clang::ObjCInterfaceDecl * + GetAsObjCInterfaceDecl(const CompilerType &type); + + clang::ClassTemplateDecl *ParseClassTemplateDecl( + clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, + lldb::AccessType access_type, const char *parent_name, int tag_decl_kind, + const TypeSystemClang::TemplateParameterInfos &template_param_infos); + + clang::BlockDecl *CreateBlockDeclaration(clang::DeclContext *ctx, + OptionalClangModuleID owning_module); + + clang::UsingDirectiveDecl * + CreateUsingDirectiveDeclaration(clang::DeclContext *decl_ctx, + OptionalClangModuleID owning_module, + clang::NamespaceDecl *ns_decl); + + clang::UsingDecl *CreateUsingDeclaration(clang::DeclContext *current_decl_ctx, + OptionalClangModuleID owning_module, + clang::NamedDecl *target); + + clang::VarDecl *CreateVariableDeclaration(clang::DeclContext *decl_context, + OptionalClangModuleID owning_module, + const char *name, + clang::QualType type); + + static lldb::opaque_compiler_type_t + GetOpaqueCompilerType(clang::ASTContext *ast, lldb::BasicType basic_type); + + static clang::QualType GetQualType(lldb::opaque_compiler_type_t type) { + if (type) + return clang::QualType::getFromOpaquePtr(type); + return clang::QualType(); + } + + static clang::QualType + GetCanonicalQualType(lldb::opaque_compiler_type_t type) { + if (type) + return clang::QualType::getFromOpaquePtr(type).getCanonicalType(); + return clang::QualType(); + } + + clang::DeclarationName + GetDeclarationName(const char *name, const CompilerType &function_clang_type); + + clang::LangOptions *GetLangOpts() const { + return m_language_options_up.get(); + } + clang::SourceManager *GetSourceMgr() const { + return m_source_manager_up.get(); + } + +private: + const clang::ClassTemplateSpecializationDecl * + GetAsTemplateSpecialization(lldb::opaque_compiler_type_t type); + + // Classes that inherit from TypeSystemClang can see and modify these + std::string m_target_triple; + std::unique_ptr m_ast_up; + std::unique_ptr m_language_options_up; + std::unique_ptr m_file_manager_up; + std::unique_ptr m_source_manager_up; + std::unique_ptr m_diagnostics_engine_up; + std::unique_ptr m_diagnostic_consumer_up; + std::shared_ptr m_target_options_rp; + std::unique_ptr m_target_info_up; + std::unique_ptr m_identifier_table_up; + std::unique_ptr m_selector_table_up; + std::unique_ptr m_builtins_up; + std::unique_ptr m_header_search_up; + std::unique_ptr m_module_map_up; + std::unique_ptr m_dwarf_ast_parser_up; + std::unique_ptr m_pdb_ast_parser_up; + std::unique_ptr m_mangle_ctx_up; + uint32_t m_pointer_byte_size = 0; + bool m_ast_owned = false; + /// A string describing what this TypeSystemClang represents (e.g., + /// AST for debug information, an expression, some other utility ClangAST). + /// Useful for logging and debugging. + std::string m_display_name; + + typedef llvm::DenseMap DeclMetadataMap; + /// Maps Decls to their associated ClangASTMetadata. + DeclMetadataMap m_decl_metadata; + + typedef llvm::DenseMap TypeMetadataMap; + /// Maps Types to their associated ClangASTMetadata. + TypeMetadataMap m_type_metadata; + + /// The sema associated that is currently used to build this ASTContext. + /// May be null if we are already done parsing this ASTContext or the + /// ASTContext wasn't created by parsing source code. + clang::Sema *m_sema = nullptr; + + // For TypeSystemClang only + TypeSystemClang(const TypeSystemClang &); + const TypeSystemClang &operator=(const TypeSystemClang &); + /// Creates the internal ASTContext. + void CreateASTContext(); + void SetTargetTriple(llvm::StringRef target_triple); +}; + +/// The TypeSystemClang instance used for the scratch ASTContext in a +/// lldb::Target. +class TypeSystemClangForExpressions : public TypeSystemClang { +public: + TypeSystemClangForExpressions(Target &target, llvm::Triple triple); + + ~TypeSystemClangForExpressions() override = default; + + void Finalize() override; + + UserExpression * + GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix, + lldb::LanguageType language, + Expression::ResultType desired_type, + const EvaluateExpressionOptions &options, + ValueObject *ctx_obj) override; + + FunctionCaller *GetFunctionCaller(const CompilerType &return_type, + const Address &function_address, + const ValueList &arg_value_list, + const char *name) override; + + UtilityFunction *GetUtilityFunction(const char *text, + const char *name) override; + + PersistentExpressionState *GetPersistentExpressionState() override; +private: + lldb::TargetWP m_target_wp; + std::unique_ptr + m_persistent_variables; // These are the persistent variables associated + // with this process for the expression parser + std::unique_ptr m_scratch_ast_source_up; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_TYPESYSTEM_CLANG_TYPESYSTEMCLANG_H diff --git a/gnu/llvm/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/gnu/llvm/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp index 4aa9fb634b6..1bc071c2b16 100644 --- a/gnu/llvm/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp +++ b/gnu/llvm/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp @@ -1,4 +1,4 @@ -//===-- UnwindAssemblyInstEmulation.cpp --------------------------*- C++-*-===// +//===-- UnwindAssemblyInstEmulation.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -28,6 +28,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(UnwindAssemblyInstEmulation) + // UnwindAssemblyInstEmulation method definitions bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly( @@ -123,18 +125,12 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly( // Add the initial state to the save list with offset 0. saved_unwind_states.insert({0, {last_row, m_register_values}}); - // cache the pc register number (in whatever register numbering this - // UnwindPlan uses) for quick reference during instruction parsing. - RegisterInfo pc_reg_info; - m_inst_emulator_up->GetRegisterInfo( - eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc_reg_info); - - // cache the return address register number (in whatever register + // cache the stack pointer register number (in whatever register // numbering this UnwindPlan uses) for quick reference during // instruction parsing. - RegisterInfo ra_reg_info; + RegisterInfo sp_reg_info; m_inst_emulator_up->GetRegisterInfo( - eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, ra_reg_info); + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp_reg_info); // The architecture dependent condition code of the last processed // instruction. @@ -165,6 +161,23 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly( *newrow = *it->second.first; m_curr_row.reset(newrow); m_register_values = it->second.second; + // re-set the CFA register ivars to match the + // new m_curr_row. + if (sp_reg_info.name && + m_curr_row->GetCFAValue().IsRegisterPlusOffset()) { + uint32_t row_cfa_regnum = + m_curr_row->GetCFAValue().GetRegisterNumber(); + lldb::RegisterKind row_kind = + m_unwind_plan_ptr->GetRegisterKind(); + // set m_cfa_reg_info to the row's CFA reg. + m_inst_emulator_up->GetRegisterInfo(row_kind, row_cfa_regnum, + m_cfa_reg_info); + // set m_fp_is_cfa. + if (sp_reg_info.kinds[row_kind] == row_cfa_regnum) + m_fp_is_cfa = false; + else + m_fp_is_cfa = true; + } } m_inst_emulator_up->SetInstruction(inst->GetOpcode(), @@ -195,6 +208,23 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly( std::make_shared(*saved_state.first); m_curr_row->SetOffset(current_offset); m_register_values = saved_state.second; + // re-set the CFA register ivars to match the + // new m_curr_row. + if (sp_reg_info.name && + m_curr_row->GetCFAValue().IsRegisterPlusOffset()) { + uint32_t row_cfa_regnum = + m_curr_row->GetCFAValue().GetRegisterNumber(); + lldb::RegisterKind row_kind = + m_unwind_plan_ptr->GetRegisterKind(); + // set m_cfa_reg_info to the row's CFA reg. + m_inst_emulator_up->GetRegisterInfo(row_kind, row_cfa_regnum, + m_cfa_reg_info); + // set m_fp_is_cfa. + if (sp_reg_info.kinds[row_kind] == row_cfa_regnum) + m_fp_is_cfa = false; + else + m_fp_is_cfa = true; + } bool replace_existing = true; // The last instruction might already // created a row for this offset and diff --git a/gnu/llvm/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h b/gnu/llvm/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h index 9125bd5b1fe..5784a42a826 100644 --- a/gnu/llvm/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h +++ b/gnu/llvm/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_UnwindAssemblyInstEmulation_h_ -#define liblldb_UnwindAssemblyInstEmulation_h_ +#ifndef LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_INSTEMULATION_UNWINDASSEMBLYINSTEMULATION_H +#define LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_INSTEMULATION_UNWINDASSEMBLYINSTEMULATION_H #include "lldb/Core/EmulateInstruction.h" #include "lldb/Symbol/UnwindPlan.h" @@ -151,4 +151,4 @@ private: uint32_t m_forward_branch_offset; }; -#endif // liblldb_UnwindAssemblyInstEmulation_h_ +#endif // LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_INSTEMULATION_UNWINDASSEMBLYINSTEMULATION_H diff --git a/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp b/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp index ce168f02104..fe1275d5b0c 100644 --- a/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp +++ b/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp @@ -1,4 +1,4 @@ -//===-- UnwindAssembly-x86.cpp ----------------------------------*- C++ -*-===// +//===-- UnwindAssembly-x86.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -30,6 +30,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE_ADV(UnwindAssembly_x86, UnwindAssemblyX86) + // UnwindAssemblyParser_x86 method definitions UnwindAssembly_x86::UnwindAssembly_x86(const ArchSpec &arch) @@ -139,7 +141,7 @@ bool UnwindAssembly_x86::AugmentUnwindPlanFromCallSite( // and we don't need to modify it at all. if (first_row_pc_loc.GetOffset() == -wordsize) { - do_augment_unwindplan = false; + return true; } } } diff --git a/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h b/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h index 7c198bbc33a..3e1588f2065 100644 --- a/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h +++ b/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_UnwindAssembly_x86_h_ -#define liblldb_UnwindAssembly_x86_h_ +#ifndef LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_X86_UNWINDASSEMBLY_X86_H +#define LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_X86_UNWINDASSEMBLY_X86_H #include "x86AssemblyInspectionEngine.h" @@ -62,4 +62,4 @@ private: lldb_private::x86AssemblyInspectionEngine *m_assembly_inspection_engine; }; -#endif // liblldb_UnwindAssembly_x86_h_ +#endif // LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_X86_UNWINDASSEMBLY_X86_H diff --git a/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp b/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp index 4cdca72b29f..36e7b90cad2 100644 --- a/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp +++ b/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp @@ -1,4 +1,4 @@ -//===-- x86AssemblyInspectionEngine.cpp -------------------------*- C++ -*-===// +//===-- x86AssemblyInspectionEngine.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -870,18 +870,6 @@ int16_t x86AssemblyInspectionEngine::extract_2_signed(uint8_t *b) { return v; } -// movq $0x????????(%rip), $reg [(0x4c || 0x48) 0x8b ?? ?? ?? ?? ??] -// xorq $off(%rsp), $reg [(0x4c || 0x48) 0x33 ?? 0x24] -bool x86AssemblyInspectionEngine::retguard_prologue_p(size_t offset, int insn_len) { - uint8_t *p = m_cur_insn; - if (offset == 0 && insn_len == 7) - return (*p == 0x48 || *p == 0x4c) && (*(p + 1) == 0x8b); - else if (offset == 7 && insn_len == 4) - return (*p == 0x48 || *p == 0x4c) && (*(p + 1) == 0x33) && (*(p + 3) == 0x24); - - return false; -} - uint32_t x86AssemblyInspectionEngine::extract_4(uint8_t *b) { uint32_t v = 0; for (int i = 3; i >= 0; i--) @@ -1613,7 +1601,6 @@ bool x86AssemblyInspectionEngine::FindFirstNonPrologueInstruction( if (push_rbp_pattern_p() || mov_rsp_rbp_pattern_p() || sub_rsp_pattern_p(scratch) || push_reg_p(regno) || mov_reg_to_local_stack_frame_p(regno, scratch) || - retguard_prologue_p(offset, insn_len) || (lea_rsp_pattern_p(scratch) && offset == 0)) { offset += insn_len; continue; diff --git a/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h b/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h index eb23f073422..f39dce1afaa 100644 --- a/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h +++ b/gnu/llvm/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_x86AssemblyInspectionEngine_h_ -#define liblldb_x86AssemblyInspectionEngine_h_ +#ifndef LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_X86_X86ASSEMBLYINSPECTIONENGINE_H +#define LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_X86_X86ASSEMBLYINSPECTIONENGINE_H #include "llvm-c/Disassembler.h" @@ -114,7 +114,6 @@ private: bool call_next_insn_pattern_p(); bool mov_reg_to_local_stack_frame_p(int ®no, int &rbp_offset); bool ret_pattern_p(); - bool retguard_prologue_p(size_t offset, int insn_len); bool jmp_to_reg_p(); bool pc_rel_branch_or_jump_p (const int instruction_length, int &offset); bool non_local_branch_p (const lldb::addr_t current_func_text_offset, @@ -192,9 +191,11 @@ private: ::LLVMDisasmContextRef m_disasm_context; - DISALLOW_COPY_AND_ASSIGN(x86AssemblyInspectionEngine); + x86AssemblyInspectionEngine(const x86AssemblyInspectionEngine &) = delete; + const x86AssemblyInspectionEngine & + operator=(const x86AssemblyInspectionEngine &) = delete; }; } // namespace lldb_private -#endif // liblldb_x86AssemblyInspectionEngine_h_ +#endif // LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_X86_X86ASSEMBLYINSPECTIONENGINE_H diff --git a/gnu/llvm/lldb/source/Symbol/ArmUnwindInfo.cpp b/gnu/llvm/lldb/source/Symbol/ArmUnwindInfo.cpp index fdf4e30b2db..f2887035e5c 100644 --- a/gnu/llvm/lldb/source/Symbol/ArmUnwindInfo.cpp +++ b/gnu/llvm/lldb/source/Symbol/ArmUnwindInfo.cpp @@ -1,4 +1,4 @@ -//===-- ArmUnwindInfo.cpp ---------------------------------------*- C++ -*-===// +//===-- ArmUnwindInfo.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -29,7 +29,7 @@ using namespace lldb; using namespace lldb_private; -// Converts a prel31 avlue to lldb::addr_t with sign extension +// Converts a prel31 value to lldb::addr_t with sign extension static addr_t Prel31ToAddr(uint32_t prel31) { addr_t res = prel31; if (prel31 & (1 << 30)) diff --git a/gnu/llvm/lldb/source/Symbol/Block.cpp b/gnu/llvm/lldb/source/Symbol/Block.cpp index bf380064200..afcdf3e21e1 100644 --- a/gnu/llvm/lldb/source/Symbol/Block.cpp +++ b/gnu/llvm/lldb/source/Symbol/Block.cpp @@ -1,4 +1,4 @@ -//===-- Block.cpp -----------------------------------------------*- C++ -*-===// +//===-- Block.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Symbol/CMakeLists.txt b/gnu/llvm/lldb/source/Symbol/CMakeLists.txt index 4bfef895f7e..95bf156ff53 100644 --- a/gnu/llvm/lldb/source/Symbol/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Symbol/CMakeLists.txt @@ -7,17 +7,11 @@ endif() add_lldb_library(lldbSymbol ArmUnwindInfo.cpp Block.cpp - ClangASTContext.cpp - ClangASTImporter.cpp - ClangASTMetadata.cpp - ClangExternalASTSourceCallbacks.cpp - ClangUtil.cpp CompactUnwindInfo.cpp CompileUnit.cpp CompilerDecl.cpp CompilerDeclContext.cpp CompilerType.cpp - CxxModuleHandler.cpp DWARFCallFrameInfo.cpp DebugMacros.cpp Declaration.cpp @@ -51,16 +45,7 @@ add_lldb_library(lldbSymbol lldbHost lldbTarget lldbUtility - lldbPluginExpressionParserClang - lldbPluginSymbolFileDWARF - lldbPluginSymbolFilePDB lldbPluginObjCLanguage - lldbPluginObjCRuntime - - CLANG_LIBS - clangAST - clangBasic - clangFrontend LINK_COMPONENTS Support diff --git a/gnu/llvm/lldb/source/Symbol/CompactUnwindInfo.cpp b/gnu/llvm/lldb/source/Symbol/CompactUnwindInfo.cpp index 3eee7f785f3..1bb7cd1fc05 100644 --- a/gnu/llvm/lldb/source/Symbol/CompactUnwindInfo.cpp +++ b/gnu/llvm/lldb/source/Symbol/CompactUnwindInfo.cpp @@ -1,4 +1,4 @@ -//===-- CompactUnwindInfo.cpp -----------------------------------*- C++ -*-===// +//===-- CompactUnwindInfo.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Symbol/CompileUnit.cpp b/gnu/llvm/lldb/source/Symbol/CompileUnit.cpp index b05036e27fc..0c67bf5b702 100644 --- a/gnu/llvm/lldb/source/Symbol/CompileUnit.cpp +++ b/gnu/llvm/lldb/source/Symbol/CompileUnit.cpp @@ -1,4 +1,4 @@ -//===-- CompileUnit.cpp -----------------------------------------*- C++ -*-===// +//===-- CompileUnit.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Symbol/CompilerDecl.cpp b/gnu/llvm/lldb/source/Symbol/CompilerDecl.cpp index 48d9169c1a7..3cafa9535a7 100644 --- a/gnu/llvm/lldb/source/Symbol/CompilerDecl.cpp +++ b/gnu/llvm/lldb/source/Symbol/CompilerDecl.cpp @@ -1,4 +1,4 @@ -//===-- CompilerDecl.cpp ----------------------------------------*- C++ -*-===// +//===-- CompilerDecl.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Symbol/CompilerDeclContext.cpp b/gnu/llvm/lldb/source/Symbol/CompilerDeclContext.cpp index 581e0872a6a..a3af568e7c9 100644 --- a/gnu/llvm/lldb/source/Symbol/CompilerDeclContext.cpp +++ b/gnu/llvm/lldb/source/Symbol/CompilerDeclContext.cpp @@ -1,4 +1,4 @@ -//===-- CompilerDeclContext.cpp ---------------------------------*- C++ -*-===// +//===-- CompilerDeclContext.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Symbol/CompilerType.cpp b/gnu/llvm/lldb/source/Symbol/CompilerType.cpp index 09930f7a800..f819c9f8ce2 100644 --- a/gnu/llvm/lldb/source/Symbol/CompilerType.cpp +++ b/gnu/llvm/lldb/source/Symbol/CompilerType.cpp @@ -1,4 +1,4 @@ -//===-- CompilerType.cpp ----------------------------------------*- C++ -*-===// +//===-- CompilerType.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -268,19 +268,6 @@ size_t CompilerType::GetPointerByteSize() const { return 0; } -ConstString CompilerType::GetConstQualifiedTypeName() const { - return GetConstTypeName(); -} - -ConstString CompilerType::GetConstTypeName() const { - if (IsValid()) { - ConstString type_name(GetTypeName()); - if (type_name) - return type_name; - } - return ConstString(""); -} - ConstString CompilerType::GetTypeName() const { if (IsValid()) { return m_type_system->GetTypeName(m_type); @@ -288,7 +275,11 @@ ConstString CompilerType::GetTypeName() const { return ConstString(""); } -ConstString CompilerType::GetDisplayTypeName() const { return GetTypeName(); } +ConstString CompilerType::GetDisplayTypeName() const { + if (IsValid()) + return m_type_system->GetDisplayTypeName(m_type); + return ConstString(""); +} uint32_t CompilerType::GetTypeInfo( CompilerType *pointee_or_element_compiler_type) const { @@ -448,11 +439,11 @@ CompilerType CompilerType::AddRestrictModifier() const { return CompilerType(); } -CompilerType -CompilerType::CreateTypedef(const char *name, - const CompilerDeclContext &decl_ctx) const { +CompilerType CompilerType::CreateTypedef(const char *name, + const CompilerDeclContext &decl_ctx, + uint32_t payload) const { if (IsValid()) - return m_type_system->CreateTypedef(m_type, name, decl_ctx); + return m_type_system->CreateTypedef(m_type, name, decl_ctx, payload); else return CompilerType(); } @@ -715,7 +706,6 @@ CompilerType::GetIndexOfChildWithName(const char *name, } // Dumping types -#define DEPTH_INCREMENT 2 void CompilerType::DumpValue(ExecutionContext *exe_ctx, Stream *s, lldb::Format format, const DataExtractor &data, @@ -753,14 +743,15 @@ void CompilerType::DumpSummary(ExecutionContext *exe_ctx, Stream *s, data_byte_size); } -void CompilerType::DumpTypeDescription() const { +void CompilerType::DumpTypeDescription(lldb::DescriptionLevel level) const { if (IsValid()) - m_type_system->DumpTypeDescription(m_type); + m_type_system->DumpTypeDescription(m_type, level); } -void CompilerType::DumpTypeDescription(Stream *s) const { +void CompilerType::DumpTypeDescription(Stream *s, + lldb::DescriptionLevel level) const { if (IsValid()) { - m_type_system->DumpTypeDescription(m_type, s); + m_type_system->DumpTypeDescription(m_type, s, level); } } @@ -874,6 +865,12 @@ bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data, return false; } +#ifndef NDEBUG +bool CompilerType::Verify() const { + return !IsValid() || m_type_system->Verify(m_type); +} +#endif + bool lldb_private::operator==(const lldb_private::CompilerType &lhs, const lldb_private::CompilerType &rhs) { return lhs.GetTypeSystem() == rhs.GetTypeSystem() && diff --git a/gnu/llvm/lldb/source/Symbol/DWARFCallFrameInfo.cpp b/gnu/llvm/lldb/source/Symbol/DWARFCallFrameInfo.cpp index b4e74e9a289..3111c33c710 100644 --- a/gnu/llvm/lldb/source/Symbol/DWARFCallFrameInfo.cpp +++ b/gnu/llvm/lldb/source/Symbol/DWARFCallFrameInfo.cpp @@ -1,4 +1,4 @@ -//===-- DWARFCallFrameInfo.cpp ----------------------------------*- C++ -*-===// +//===-- DWARFCallFrameInfo.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -690,7 +690,7 @@ bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset, UnwindPlan::Row *newrow = new UnwindPlan::Row; *newrow = *row.get(); row.reset(newrow); - row->SetOffset(m_cfi_data.GetPointer(&offset) - + row->SetOffset(m_cfi_data.GetAddress(&offset) - startaddr.GetFileAddress()); break; } diff --git a/gnu/llvm/lldb/source/Symbol/DebugMacros.cpp b/gnu/llvm/lldb/source/Symbol/DebugMacros.cpp index d119a78868a..d6a4ca96a30 100644 --- a/gnu/llvm/lldb/source/Symbol/DebugMacros.cpp +++ b/gnu/llvm/lldb/source/Symbol/DebugMacros.cpp @@ -1,4 +1,4 @@ -//===-- DebugMacros.cpp -----------------------------------------*- C++ -*-===// +//===-- DebugMacros.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Symbol/DeclVendor.cpp b/gnu/llvm/lldb/source/Symbol/DeclVendor.cpp index 9ccf422e3be..cf87f4f879b 100644 --- a/gnu/llvm/lldb/source/Symbol/DeclVendor.cpp +++ b/gnu/llvm/lldb/source/Symbol/DeclVendor.cpp @@ -1,4 +1,4 @@ -//===-- DeclVendor.cpp ------------------------------------------*- C++ -*-===// +//===-- DeclVendor.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Symbol/Declaration.cpp b/gnu/llvm/lldb/source/Symbol/Declaration.cpp index 4d0975d3425..48d8013811d 100644 --- a/gnu/llvm/lldb/source/Symbol/Declaration.cpp +++ b/gnu/llvm/lldb/source/Symbol/Declaration.cpp @@ -1,4 +1,4 @@ -//===-- Declaration.cpp -----------------------------------------*- C++ -*-===// +//===-- Declaration.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Symbol/FuncUnwinders.cpp b/gnu/llvm/lldb/source/Symbol/FuncUnwinders.cpp index 7a6f3cefea6..30266120d05 100644 --- a/gnu/llvm/lldb/source/Symbol/FuncUnwinders.cpp +++ b/gnu/llvm/lldb/source/Symbol/FuncUnwinders.cpp @@ -1,4 +1,4 @@ -//===-- FuncUnwinders.cpp ----------------------------------*- C++ -*-===// +//===-- FuncUnwinders.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Symbol/Function.cpp b/gnu/llvm/lldb/source/Symbol/Function.cpp index e92585ccfed..67013f6dd8b 100644 --- a/gnu/llvm/lldb/source/Symbol/Function.cpp +++ b/gnu/llvm/lldb/source/Symbol/Function.cpp @@ -1,4 +1,4 @@ -//===-- Function.cpp --------------------------------------------*- C++ -*-===// +//===-- Function.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -82,25 +82,24 @@ void InlineFunctionInfo::Dump(Stream *s, bool show_fullpaths) const { m_mangled.Dump(s); } -void InlineFunctionInfo::DumpStopContext(Stream *s, - LanguageType language) const { +void InlineFunctionInfo::DumpStopContext(Stream *s) const { // s->Indent("[inlined] "); s->Indent(); if (m_mangled) - s->PutCString(m_mangled.GetName(language).AsCString()); + s->PutCString(m_mangled.GetName().AsCString()); else s->PutCString(m_name.AsCString()); } -ConstString InlineFunctionInfo::GetName(LanguageType language) const { +ConstString InlineFunctionInfo::GetName() const { if (m_mangled) - return m_mangled.GetName(language); + return m_mangled.GetName(); return m_name; } -ConstString InlineFunctionInfo::GetDisplayName(LanguageType language) const { +ConstString InlineFunctionInfo::GetDisplayName() const { if (m_mangled) - return m_mangled.GetDisplayDemangledName(language); + return m_mangled.GetDisplayDemangledName(); return m_name; } @@ -121,10 +120,32 @@ size_t InlineFunctionInfo::MemorySize() const { /// @name Call site related structures /// @{ +lldb::addr_t CallEdge::GetLoadAddress(lldb::addr_t unresolved_pc, + Function &caller, Target &target) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + + const Address &caller_start_addr = caller.GetAddressRange().GetBaseAddress(); + + ModuleSP caller_module_sp = caller_start_addr.GetModule(); + if (!caller_module_sp) { + LLDB_LOG(log, "GetLoadAddress: cannot get Module for caller"); + return LLDB_INVALID_ADDRESS; + } + + SectionList *section_list = caller_module_sp->GetSectionList(); + if (!section_list) { + LLDB_LOG(log, "GetLoadAddress: cannot get SectionList for Module"); + return LLDB_INVALID_ADDRESS; + } + + Address the_addr = Address(unresolved_pc, section_list); + lldb::addr_t load_addr = the_addr.GetLoadAddress(&target); + return load_addr; +} + lldb::addr_t CallEdge::GetReturnPCAddress(Function &caller, Target &target) const { - const Address &base = caller.GetAddressRange().GetBaseAddress(); - return base.GetLoadAddress(&target) + return_pc; + return GetLoadAddress(GetUnresolvedReturnPCAddress(), caller, target); } void DirectCallEdge::ParseSymbolFileAndResolve(ModuleList &images) { @@ -269,6 +290,8 @@ void Function::GetEndLineSourceInfo(FileSpec &source_file, uint32_t &line_no) { } llvm::ArrayRef> Function::GetCallEdges() { + std::lock_guard guard(m_call_edges_lock); + if (m_call_edges_resolved) return m_call_edges; @@ -288,36 +311,34 @@ llvm::ArrayRef> Function::GetCallEdges() { 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 std::unique_ptr &LHS, - const std::unique_ptr &RHS) { - return LHS->GetUnresolvedReturnPCAddress() < - RHS->GetUnresolvedReturnPCAddress(); - }); + llvm::sort(m_call_edges, [](const std::unique_ptr &LHS, + const std::unique_ptr &RHS) { + return LHS->GetSortKey() < RHS->GetSortKey(); + }); return m_call_edges; } llvm::ArrayRef> 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 std::unique_ptr &edge) { - return edge->GetUnresolvedReturnPCAddress() == LLDB_INVALID_ADDRESS; - }); + // Tail calling edges are sorted at the end of the list. Find them by dropping + // all non-tail-calls. + return GetCallEdges().drop_until( + [](const std::unique_ptr &edge) { return edge->IsTailCall(); }); } CallEdge *Function::GetCallEdgeForReturnAddress(addr_t return_pc, Target &target) { auto edges = GetCallEdges(); auto edge_it = - std::lower_bound(edges.begin(), edges.end(), return_pc, - [&](const std::unique_ptr &edge, addr_t pc) { - return edge->GetReturnPCAddress(*this, target) < pc; - }); + llvm::partition_point(edges, [&](const std::unique_ptr &edge) { + return std::make_pair(edge->IsTailCall(), + edge->GetReturnPCAddress(*this, target)) < + std::make_pair(false, return_pc); + }); if (edge_it == edges.end() || edge_it->get()->GetReturnPCAddress(*this, target) != return_pc) return nullptr; - return &const_cast(*edge_it->get()); + return edge_it->get(); } Block &Function::GetBlock(bool can_create) { @@ -349,9 +370,9 @@ void Function::GetDescription(Stream *s, lldb::DescriptionLevel level, *s << "id = " << (const UserID &)*this; if (name) - *s << ", name = \"" << name.GetCString() << '"'; + s->AsRawOstream() << ", name = \"" << name << '"'; if (mangled) - *s << ", mangled = \"" << mangled.GetCString() << '"'; + s->AsRawOstream() << ", mangled = \"" << mangled << '"'; *s << ", range = "; Address::DumpStyle fallback_style; if (level == eDescriptionLevelVerbose) @@ -404,11 +425,11 @@ lldb::DisassemblerSP Function::GetInstructions(const ExecutionContext &exe_ctx, const char *flavor, bool prefer_file_cache) { ModuleSP module_sp(GetAddressRange().GetBaseAddress().GetModule()); - if (module_sp) { + if (module_sp && exe_ctx.HasTargetScope()) { const bool prefer_file_cache = false; return Disassembler::DisassembleRange(module_sp->GetArchitecture(), nullptr, - flavor, exe_ctx, GetAddressRange(), - prefer_file_cache); + flavor, exe_ctx.GetTargetRef(), + GetAddressRange(), prefer_file_cache); } return lldb::DisassemblerSP(); } @@ -465,7 +486,7 @@ bool Function::IsTopLevelFunction() { } ConstString Function::GetDisplayName() const { - return m_mangled.GetDisplayDemangledName(GetLanguage()); + return m_mangled.GetDisplayDemangledName(); } CompilerDeclContext Function::GetDeclContext() { @@ -633,15 +654,9 @@ lldb::LanguageType Function::GetLanguage() const { } ConstString Function::GetName() const { - LanguageType language = lldb::eLanguageTypeUnknown; - if (m_comp_unit) - language = m_comp_unit->GetLanguage(); - return m_mangled.GetName(language); + return m_mangled.GetName(); } ConstString Function::GetNameNoArguments() const { - LanguageType language = lldb::eLanguageTypeUnknown; - if (m_comp_unit) - language = m_comp_unit->GetLanguage(); - return m_mangled.GetName(language, Mangled::ePreferDemangledWithoutArguments); + return m_mangled.GetName(Mangled::ePreferDemangledWithoutArguments); } diff --git a/gnu/llvm/lldb/source/Symbol/LineEntry.cpp b/gnu/llvm/lldb/source/Symbol/LineEntry.cpp index bb3828fef78..a3907f4dd9c 100644 --- a/gnu/llvm/lldb/source/Symbol/LineEntry.cpp +++ b/gnu/llvm/lldb/source/Symbol/LineEntry.cpp @@ -1,4 +1,4 @@ -//===-- LineEntry.cpp -------------------------------------------*- C++ -*-===// +//===-- LineEntry.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Symbol/LineTable.cpp b/gnu/llvm/lldb/source/Symbol/LineTable.cpp index fecc90c409f..19c39bd0aeb 100644 --- a/gnu/llvm/lldb/source/Symbol/LineTable.cpp +++ b/gnu/llvm/lldb/source/Symbol/LineTable.cpp @@ -1,4 +1,4 @@ -//===-- LineTable.cpp -------------------------------------------*- C++ -*-===// +//===-- LineTable.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -21,6 +21,18 @@ using namespace lldb_private; LineTable::LineTable(CompileUnit *comp_unit) : m_comp_unit(comp_unit), m_entries() {} +LineTable::LineTable(CompileUnit *comp_unit, + std::vector> &&sequences) + : m_comp_unit(comp_unit), m_entries() { + LineTable::Entry::LessThanBinaryPredicate less_than_bp(this); + llvm::stable_sort(sequences, less_than_bp); + for (const auto &sequence : sequences) { + LineSequenceImpl *seq = static_cast(sequence.get()); + m_entries.insert(m_entries.end(), seq->m_entries.begin(), + seq->m_entries.end()); + } +} + // Destructor LineTable::~LineTable() {} @@ -50,8 +62,8 @@ LineSequence::LineSequence() {} void LineTable::LineSequenceImpl::Clear() { m_entries.clear(); } -LineSequence *LineTable::CreateLineSequenceContainer() { - return new LineTable::LineSequenceImpl(); +std::unique_ptr LineTable::CreateLineSequenceContainer() { + return std::make_unique(); } void LineTable::AppendLineEntryToSequence( @@ -154,6 +166,14 @@ operator()(const LineTable::Entry &a, const LineTable::Entry &b) const { #undef LT_COMPARE } +bool LineTable::Entry::LessThanBinaryPredicate:: +operator()(const std::unique_ptr &sequence_a, + const std::unique_ptr &sequence_b) const { + auto *seq_a = static_cast(sequence_a.get()); + auto *seq_b = static_cast(sequence_b.get()); + return (*this)(seq_a->m_entries.front(), seq_b->m_entries.front()); +} + uint32_t LineTable::GetSize() const { return m_entries.size(); } bool LineTable::GetLineEntryAtIndex(uint32_t idx, LineEntry &line_entry) { diff --git a/gnu/llvm/lldb/source/Symbol/LocateSymbolFile.cpp b/gnu/llvm/lldb/source/Symbol/LocateSymbolFile.cpp index d2b39d6acd7..95ae2ca7917 100644 --- a/gnu/llvm/lldb/source/Symbol/LocateSymbolFile.cpp +++ b/gnu/llvm/lldb/source/Symbol/LocateSymbolFile.cpp @@ -1,4 +1,4 @@ -//===-- LocateSymbolFile.cpp ------------------------------------*- C++ -*-===// +//===-- LocateSymbolFile.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp b/gnu/llvm/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp index 5ee632ec207..251605085c5 100644 --- a/gnu/llvm/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp +++ b/gnu/llvm/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp @@ -1,4 +1,4 @@ -//===-- LocateSymbolFileMacOSX.cpp ------------------------------*- C++ -*-===// +//===-- LocateSymbolFileMacOSX.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -253,48 +253,34 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec, const lldb_private::UUID *uuid, const ArchSpec *arch) { - char path[PATH_MAX]; - if (dsym_bundle_fspec.GetPath(path, sizeof(path)) == 0) - return {}; - - ::strncat(path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1); - - DIR *dirp = opendir(path); - if (!dirp) - return {}; - - // Make sure we close the directory before exiting this scope. - auto cleanup_dir = llvm::make_scope_exit([&]() { closedir(dirp); }); - - FileSpec dsym_fspec; - dsym_fspec.GetDirectory().SetCString(path); - struct dirent *dp; - while ((dp = readdir(dirp)) != NULL) { - // Only search directories - if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) { - if (dp->d_namlen == 1 && dp->d_name[0] == '.') - continue; - - if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.') - continue; - } - - if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) { - dsym_fspec.GetFilename().SetCString(dp->d_name); - ModuleSpecList module_specs; - if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs)) { - ModuleSpec spec; - for (size_t i = 0; i < module_specs.GetSize(); ++i) { - bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec); - UNUSED_IF_ASSERT_DISABLED(got_spec); - assert(got_spec); - if ((uuid == NULL || - (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) && - (arch == NULL || - (spec.GetArchitecturePtr() && - spec.GetArchitecture().IsCompatibleMatch(*arch)))) { - return dsym_fspec; - } + std::string dsym_bundle_path = dsym_bundle_fspec.GetPath(); + llvm::SmallString<128> buffer(dsym_bundle_path); + llvm::sys::path::append(buffer, "Contents", "Resources", "DWARF"); + + std::error_code EC; + llvm::IntrusiveRefCntPtr vfs = + FileSystem::Instance().GetVirtualFileSystem(); + llvm::vfs::recursive_directory_iterator Iter(*vfs, buffer.str(), EC); + llvm::vfs::recursive_directory_iterator End; + for (; Iter != End && !EC; Iter.increment(EC)) { + llvm::ErrorOr Status = vfs->status(Iter->path()); + if (Status->isDirectory()) + continue; + + FileSpec dsym_fspec(Iter->path()); + ModuleSpecList module_specs; + if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs)) { + ModuleSpec spec; + for (size_t i = 0; i < module_specs.GetSize(); ++i) { + bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec); + assert(got_spec); // The call has side-effects so can't be inlined. + UNUSED_IF_ASSERT_DISABLED(got_spec); + if ((uuid == nullptr || + (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) && + (arch == nullptr || + (spec.GetArchitecturePtr() && + spec.GetArchitecture().IsCompatibleMatch(*arch)))) { + return dsym_fspec; } } } diff --git a/gnu/llvm/lldb/source/Symbol/ObjectFile.cpp b/gnu/llvm/lldb/source/Symbol/ObjectFile.cpp index 8a72b5fe6f6..6b552dd0c19 100644 --- a/gnu/llvm/lldb/source/Symbol/ObjectFile.cpp +++ b/gnu/llvm/lldb/source/Symbol/ObjectFile.cpp @@ -1,4 +1,4 @@ -//===-- ObjectFile.cpp ------------------------------------------*- C++ -*-===// +//===-- ObjectFile.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -47,8 +47,8 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file, FileSpec archive_file; ObjectContainerCreateInstance create_object_container_callback; - const bool file_exists = FileSystem::Instance().Exists(*file); if (!data_sp) { + const bool file_exists = FileSystem::Instance().Exists(*file); // 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 // first without reading any data first @@ -207,9 +207,11 @@ ObjectFileSP ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, size_t ObjectFile::GetModuleSpecifications(const FileSpec &file, lldb::offset_t file_offset, lldb::offset_t file_size, - ModuleSpecList &specs) { - DataBufferSP data_sp = - FileSystem::Instance().CreateDataBuffer(file.GetPath(), 512, file_offset); + ModuleSpecList &specs, + DataBufferSP data_sp) { + if (!data_sp) + data_sp = FileSystem::Instance().CreateDataBuffer(file.GetPath(), 512, + file_offset); if (data_sp) { if (file_size == 0) { const lldb::offset_t actual_file_size = @@ -367,6 +369,7 @@ AddressClass ObjectFile::GetAddressClass(addr_t file_addr) { case eSectionTypeDWARFDebugStrDwo: case eSectionTypeDWARFDebugStrOffsets: case eSectionTypeDWARFDebugStrOffsetsDwo: + case eSectionTypeDWARFDebugTuIndex: case eSectionTypeDWARFDebugTypes: case eSectionTypeDWARFDebugTypesDwo: case eSectionTypeDWARFAppleNames: diff --git a/gnu/llvm/lldb/source/Symbol/PostfixExpression.cpp b/gnu/llvm/lldb/source/Symbol/PostfixExpression.cpp index 8ecd571ed92..588b3f92c3f 100644 --- a/gnu/llvm/lldb/source/Symbol/PostfixExpression.cpp +++ b/gnu/llvm/lldb/source/Symbol/PostfixExpression.cpp @@ -1,4 +1,4 @@ -//===-- PostfixExpression.cpp -----------------------------------*- C++ -*-===// +//===-- PostfixExpression.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Symbol/Symbol.cpp b/gnu/llvm/lldb/source/Symbol/Symbol.cpp index 3ace153d32a..8d099e0cc7e 100644 --- a/gnu/llvm/lldb/source/Symbol/Symbol.cpp +++ b/gnu/llvm/lldb/source/Symbol/Symbol.cpp @@ -1,4 +1,4 @@ -//===-- Symbol.cpp ----------------------------------------------*- C++ -*-===// +//===-- Symbol.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -120,7 +120,7 @@ bool Symbol::ValueIsAddress() const { } ConstString Symbol::GetDisplayName() const { - return m_mangled.GetDisplayDemangledName(GetLanguage()); + return m_mangled.GetDisplayDemangledName(); } ConstString Symbol::GetReExportedSymbolName() const { @@ -203,7 +203,7 @@ void Symbol::GetDescription(Stream *s, lldb::DescriptionLevel level, s->Printf(", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset()); } - ConstString demangled = m_mangled.GetDemangledName(GetLanguage()); + ConstString demangled = m_mangled.GetDemangledName(); if (demangled) s->Printf(", name=\"%s\"", demangled.AsCString()); if (m_mangled.GetMangledName()) @@ -219,7 +219,7 @@ void Symbol::Dump(Stream *s, Target *target, uint32_t index, // Make sure the size of the symbol is up to date before dumping GetByteSize(); - ConstString name = m_mangled.GetName(GetLanguage(), name_preference); + ConstString name = m_mangled.GetName(name_preference); if (ValueIsAddress()) { if (!m_addr_range.GetBaseAddress().Dump(s, nullptr, Address::DumpStyleFileAddress)) @@ -333,7 +333,7 @@ uint32_t Symbol::GetPrologueByteSize() { bool Symbol::Compare(ConstString name, SymbolType type) const { if (type == eSymbolTypeAny || m_type == type) return m_mangled.GetMangledName() == name || - m_mangled.GetDemangledName(GetLanguage()) == name; + m_mangled.GetDemangledName() == name; return false; } @@ -496,11 +496,10 @@ lldb::addr_t Symbol::GetLoadAddress(Target *target) const { return LLDB_INVALID_ADDRESS; } -ConstString Symbol::GetName() const { return m_mangled.GetName(GetLanguage()); } +ConstString Symbol::GetName() const { return m_mangled.GetName(); } ConstString Symbol::GetNameNoArguments() const { - return m_mangled.GetName(GetLanguage(), - Mangled::ePreferDemangledWithoutArguments); + return m_mangled.GetName(Mangled::ePreferDemangledWithoutArguments); } lldb::addr_t Symbol::ResolveCallableAddress(Target &target) const { @@ -542,11 +541,11 @@ lldb::DisassemblerSP Symbol::GetInstructions(const ExecutionContext &exe_ctx, const char *flavor, bool prefer_file_cache) { ModuleSP module_sp(m_addr_range.GetBaseAddress().GetModule()); - if (module_sp) { + if (module_sp && exe_ctx.HasTargetScope()) { const bool prefer_file_cache = false; return Disassembler::DisassembleRange(module_sp->GetArchitecture(), nullptr, - flavor, exe_ctx, m_addr_range, - prefer_file_cache); + flavor, exe_ctx.GetTargetRef(), + m_addr_range, prefer_file_cache); } return lldb::DisassemblerSP(); } diff --git a/gnu/llvm/lldb/source/Symbol/SymbolContext.cpp b/gnu/llvm/lldb/source/Symbol/SymbolContext.cpp index 9eb805976f9..12c2077154b 100644 --- a/gnu/llvm/lldb/source/Symbol/SymbolContext.cpp +++ b/gnu/llvm/lldb/source/Symbol/SymbolContext.cpp @@ -1,4 +1,4 @@ -//===-- SymbolContext.cpp ---------------------------------------*- C++ -*-===// +//===-- SymbolContext.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -117,9 +117,7 @@ bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, Block *inlined_block = block->GetContainingInlinedBlock(); const InlineFunctionInfo *inlined_block_info = inlined_block->GetInlinedFunctionInfo(); - s->Printf( - " [inlined] %s", - inlined_block_info->GetName(function->GetLanguage()).GetCString()); + s->Printf(" [inlined] %s", inlined_block_info->GetName().GetCString()); lldb_private::AddressRange block_range; if (inlined_block->GetRangeContainingAddress(addr, block_range)) { @@ -657,12 +655,12 @@ SymbolContext::GetFunctionName(Mangled::NamePreference preference) const { const InlineFunctionInfo *inline_info = inlined_block->GetInlinedFunctionInfo(); if (inline_info) - return inline_info->GetName(function->GetLanguage()); + return inline_info->GetName(); } } - return function->GetMangled().GetName(function->GetLanguage(), preference); + return function->GetMangled().GetName(preference); } else if (symbol && symbol->ValueIsAddress()) { - return symbol->GetMangled().GetName(symbol->GetLanguage(), preference); + return symbol->GetMangled().GetName(preference); } else { // No function, return an empty string. return ConstString(); @@ -970,7 +968,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_up.reset(new FileSpec(spec_string)); + m_file_spec_up = std::make_unique(spec_string); m_type |= eFileSpecified; break; case eLineStartSpecified: @@ -1076,19 +1074,17 @@ bool SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) { if (inline_info != nullptr) { was_inlined = true; const Mangled &name = inline_info->GetMangled(); - if (!name.NameMatches(func_name, sc.function->GetLanguage())) + if (!name.NameMatches(func_name)) return false; } } // If it wasn't inlined, check the name in the function or symbol: if (!was_inlined) { if (sc.function != nullptr) { - if (!sc.function->GetMangled().NameMatches(func_name, - sc.function->GetLanguage())) + if (!sc.function->GetMangled().NameMatches(func_name)) return false; } else if (sc.symbol != nullptr) { - if (!sc.symbol->GetMangled().NameMatches(func_name, - sc.symbol->GetLanguage())) + if (!sc.symbol->GetMangled().NameMatches(func_name)) return false; } } diff --git a/gnu/llvm/lldb/source/Symbol/SymbolFile.cpp b/gnu/llvm/lldb/source/Symbol/SymbolFile.cpp index 90f7d101171..3f9cdefc8d4 100644 --- a/gnu/llvm/lldb/source/Symbol/SymbolFile.cpp +++ b/gnu/llvm/lldb/source/Symbol/SymbolFile.cpp @@ -1,4 +1,4 @@ -//===-- SymbolFile.cpp ------------------------------------------*- C++ -*-===// +//===-- SymbolFile.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -105,7 +105,7 @@ uint32_t SymbolFile::ResolveSymbolContext(const FileSpec &file_spec, } void SymbolFile::FindGlobalVariables(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, VariableList &variables) {} @@ -114,7 +114,7 @@ void SymbolFile::FindGlobalVariables(const RegularExpression ®ex, VariableList &variables) {} void SymbolFile::FindFunctions(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, lldb::FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) {} @@ -130,7 +130,7 @@ void SymbolFile::GetMangledNamesForFunction( } void SymbolFile::FindTypes( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) {} diff --git a/gnu/llvm/lldb/source/Symbol/SymbolVendor.cpp b/gnu/llvm/lldb/source/Symbol/SymbolVendor.cpp index 1e1dea71d7f..0a5acbc48eb 100644 --- a/gnu/llvm/lldb/source/Symbol/SymbolVendor.cpp +++ b/gnu/llvm/lldb/source/Symbol/SymbolVendor.cpp @@ -1,4 +1,4 @@ -//===-- SymbolVendor.cpp ----------------------------------------*- C++ -*-===// +//===-- SymbolVendor.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -51,7 +51,7 @@ SymbolVendor *SymbolVendor::FindPlugin(const lldb::ModuleSP &module_sp, } if (!sym_objfile_sp) sym_objfile_sp = module_sp->GetObjectFile()->shared_from_this(); - instance_up.reset(new SymbolVendor(module_sp)); + instance_up = std::make_unique(module_sp); instance_up->AddSymbolFileRepresentation(sym_objfile_sp); return instance_up.release(); } diff --git a/gnu/llvm/lldb/source/Symbol/Symtab.cpp b/gnu/llvm/lldb/source/Symbol/Symtab.cpp index f5bd22ee5ee..3f697e6076b 100644 --- a/gnu/llvm/lldb/source/Symbol/Symtab.cpp +++ b/gnu/llvm/lldb/source/Symbol/Symtab.cpp @@ -1,4 +1,4 @@ -//===-- Symtab.cpp ----------------------------------------------*- C++ -*-===// +//===-- Symtab.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -299,7 +299,7 @@ void Symtab::InitNameIndexes() { // Symbol name strings that didn't match a Mangled::ManglingScheme, are // stored in the demangled field. - if (ConstString name = mangled.GetDemangledName(symbol->GetLanguage())) { + if (ConstString name = mangled.GetDemangledName()) { m_name_to_index.Append(name, value); if (symbol->ContainsLinkerAnnotations()) { @@ -425,7 +425,7 @@ void Symtab::AppendSymbolNamesToMap(const IndexCollection &indexes, const Mangled &mangled = symbol->GetMangled(); if (add_demangled) { - if (ConstString name = mangled.GetDemangledName(symbol->GetLanguage())) + if (ConstString name = mangled.GetDemangledName()) name_to_index_map.Append(name, value); } diff --git a/gnu/llvm/lldb/source/Symbol/Type.cpp b/gnu/llvm/lldb/source/Symbol/Type.cpp index f194356a0a0..307e99ac84b 100644 --- a/gnu/llvm/lldb/source/Symbol/Type.cpp +++ b/gnu/llvm/lldb/source/Symbol/Type.cpp @@ -1,4 +1,4 @@ -//===-- Type.cpp ------------------------------------------------*- C++ -*-===// +//===-- Type.cpp ----------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -143,15 +143,14 @@ Type::Type(lldb::user_id_t uid, SymbolFile *symbol_file, ConstString name, llvm::Optional byte_size, SymbolContextScope *context, user_id_t encoding_uid, EncodingDataType encoding_uid_type, const Declaration &decl, const CompilerType &compiler_type, - ResolveState compiler_type_resolve_state) + ResolveState compiler_type_resolve_state, uint32_t opaque_payload) : std::enable_shared_from_this(), UserID(uid), m_name(name), m_symbol_file(symbol_file), m_context(context), m_encoding_type(nullptr), m_encoding_uid(encoding_uid), m_encoding_uid_type(encoding_uid_type), m_decl(decl), m_compiler_type(compiler_type), - m_compiler_type_resolve_state( - compiler_type ? compiler_type_resolve_state - : ResolveState::Unresolved), - m_is_complete_objc_class(false) { + m_compiler_type_resolve_state(compiler_type ? compiler_type_resolve_state + : ResolveState::Unresolved), + m_payload(opaque_payload) { if (byte_size) { m_byte_size = *byte_size; m_byte_size_has_value = true; @@ -235,7 +234,7 @@ void Type::GetDescription(Stream *s, lldb::DescriptionLevel level, } } -void Type::Dump(Stream *s, bool show_context) { +void Type::Dump(Stream *s, bool show_context, lldb::DescriptionLevel level) { s->Printf("%p: ", static_cast(this)); s->Indent(); *s << "Type" << static_cast(*this) << ' '; @@ -256,7 +255,7 @@ void Type::Dump(Stream *s, bool show_context) { if (m_compiler_type.IsValid()) { *s << ", compiler_type = " << m_compiler_type.GetOpaqueQualType() << ' '; - GetForwardCompilerType().DumpTypeDescription(s); + GetForwardCompilerType().DumpTypeDescription(s, level); } else if (m_encoding_uid != LLDB_INVALID_UID) { s->Format(", type_data = {0:x-16}", m_encoding_uid); switch (m_encoding_uid_type) { @@ -303,7 +302,7 @@ void Type::Dump(Stream *s, bool show_context) { ConstString Type::GetName() { if (!m_name) - m_name = GetForwardCompilerType().GetConstTypeName(); + m_name = GetForwardCompilerType().GetTypeName(); return m_name; } @@ -313,7 +312,7 @@ void Type::DumpValue(ExecutionContext *exe_ctx, Stream *s, const DataExtractor &data, uint32_t data_byte_offset, bool show_types, bool show_summary, bool verbose, lldb::Format format) { - if (ResolveClangType(ResolveState::Forward)) { + if (ResolveCompilerType(ResolveState::Forward)) { if (show_types) { s->PutChar('('); if (verbose) @@ -466,7 +465,7 @@ bool Type::WriteToMemory(ExecutionContext *exe_ctx, lldb::addr_t addr, const Declaration &Type::GetDeclaration() const { return m_decl; } -bool Type::ResolveClangType(ResolveState compiler_type_resolve_state) { +bool Type::ResolveCompilerType(ResolveState compiler_type_resolve_state) { // TODO: This needs to consider the correct type system to use. Type *encoding_type = nullptr; if (!m_compiler_type.IsValid()) { @@ -506,7 +505,7 @@ bool Type::ResolveClangType(ResolveState compiler_type_resolve_state) { case eEncodingIsTypedefUID: m_compiler_type = encoding_type->GetForwardCompilerType().CreateTypedef( m_name.AsCString("__lldb_invalid_typedef_name"), - GetSymbolFile()->GetDeclContextContainingUID(GetID())); + GetSymbolFile()->GetDeclContextContainingUID(GetID()), m_payload); m_name.Clear(); break; @@ -536,7 +535,7 @@ bool Type::ResolveClangType(ResolveState compiler_type_resolve_state) { LLDB_LOG_ERROR( lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), std::move(err), - "Unable to construct void type from ClangASTContext"); + "Unable to construct void type from TypeSystemClang"); } else { CompilerType void_compiler_type = type_system_or_err->GetBasicTypeFromAST(eBasicTypeVoid); @@ -564,7 +563,7 @@ bool Type::ResolveClangType(ResolveState compiler_type_resolve_state) { case eEncodingIsTypedefUID: m_compiler_type = void_compiler_type.CreateTypedef( m_name.AsCString("__lldb_invalid_typedef_name"), - GetSymbolFile()->GetDeclContextContainingUID(GetID())); + GetSymbolFile()->GetDeclContextContainingUID(GetID()), m_payload); break; case eEncodingIsPointerUID: @@ -627,7 +626,7 @@ bool Type::ResolveClangType(ResolveState compiler_type_resolve_state) { break; } } - encoding_type->ResolveClangType(encoding_compiler_type_resolve_state); + encoding_type->ResolveCompilerType(encoding_compiler_type_resolve_state); } } return m_compiler_type.IsValid(); @@ -642,22 +641,22 @@ uint32_t Type::GetEncodingMask() { } CompilerType Type::GetFullCompilerType() { - ResolveClangType(ResolveState::Full); + ResolveCompilerType(ResolveState::Full); return m_compiler_type; } CompilerType Type::GetLayoutCompilerType() { - ResolveClangType(ResolveState::Layout); + ResolveCompilerType(ResolveState::Layout); return m_compiler_type; } CompilerType Type::GetForwardCompilerType() { - ResolveClangType(ResolveState::Forward); + ResolveCompilerType(ResolveState::Forward); return m_compiler_type; } ConstString Type::GetQualifiedName() { - return GetForwardCompilerType().GetConstTypeName(); + return GetForwardCompilerType().GetTypeName(); } bool Type::GetTypeScopeAndBasename(const llvm::StringRef& name, diff --git a/gnu/llvm/lldb/source/Symbol/TypeList.cpp b/gnu/llvm/lldb/source/Symbol/TypeList.cpp index 1813e8ecca9..f0506c7c5bf 100644 --- a/gnu/llvm/lldb/source/Symbol/TypeList.cpp +++ b/gnu/llvm/lldb/source/Symbol/TypeList.cpp @@ -1,4 +1,4 @@ -//===-- TypeList.cpp --------------------------------------------*- C++ -*-===// +//===-- TypeList.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -107,7 +107,8 @@ void TypeList::RemoveMismatchedTypes(const char *qualified_typename, type_basename = qualified_typename; type_scope = ""; } - return RemoveMismatchedTypes(type_scope, type_basename, type_class, + return RemoveMismatchedTypes(std::string(type_scope), + std::string(type_basename), type_class, exact_match); } diff --git a/gnu/llvm/lldb/source/Symbol/TypeMap.cpp b/gnu/llvm/lldb/source/Symbol/TypeMap.cpp index 4ee1026bed2..e810d302007 100644 --- a/gnu/llvm/lldb/source/Symbol/TypeMap.cpp +++ b/gnu/llvm/lldb/source/Symbol/TypeMap.cpp @@ -1,4 +1,4 @@ -//===-- TypeMap.cpp --------------------------------------------*- C++ -*-===// +//===-- TypeMap.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -121,9 +121,9 @@ bool TypeMap::Remove(const lldb::TypeSP &type_sp) { return false; } -void TypeMap::Dump(Stream *s, bool show_context) { +void TypeMap::Dump(Stream *s, bool show_context, lldb::DescriptionLevel level) { for (iterator pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) { - pos->second->Dump(s, show_context); + pos->second->Dump(s, show_context, level); } } @@ -137,7 +137,8 @@ void TypeMap::RemoveMismatchedTypes(const char *qualified_typename, type_basename = qualified_typename; type_scope = ""; } - return RemoveMismatchedTypes(type_scope, type_basename, type_class, + return RemoveMismatchedTypes(std::string(type_scope), + std::string(type_basename), type_class, exact_match); } diff --git a/gnu/llvm/lldb/source/Symbol/TypeSystem.cpp b/gnu/llvm/lldb/source/Symbol/TypeSystem.cpp index 29a49a6fb1d..5e57813c28b 100644 --- a/gnu/llvm/lldb/source/Symbol/TypeSystem.cpp +++ b/gnu/llvm/lldb/source/Symbol/TypeSystem.cpp @@ -1,4 +1,4 @@ -//===-- TypeSystem.cpp ------------------------------------------*- C++ -*-===// +//===-- TypeSystem.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -70,6 +70,10 @@ lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language, return CreateInstanceHelper(language, nullptr, target); } +#ifndef NDEBUG +bool TypeSystem::Verify(lldb::opaque_compiler_type_t type) { return true; } +#endif + bool TypeSystem::IsAnonymousType(lldb::opaque_compiler_type_t type) { return false; } @@ -109,7 +113,8 @@ TypeSystem::AddRestrictModifier(lldb::opaque_compiler_type_t type) { CompilerType TypeSystem::CreateTypedef(lldb::opaque_compiler_type_t type, const char *name, - const CompilerDeclContext &decl_ctx) { + const CompilerDeclContext &decl_ctx, + uint32_t opaque_payload) { return CompilerType(); } @@ -239,7 +244,7 @@ TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language, } error = llvm::make_error( "TypeSystem for language " + - llvm::toStringRef(Language::GetNameForLanguageType(language)) + + llvm::StringRef(Language::GetNameForLanguageType(language)) + " doesn't exist", llvm::inconvertibleErrorCode()); return std::move(error); @@ -256,7 +261,7 @@ TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language, } error = llvm::make_error( "TypeSystem for language " + - llvm::toStringRef(Language::GetNameForLanguageType(language)) + + llvm::StringRef(Language::GetNameForLanguageType(language)) + " doesn't exist", llvm::inconvertibleErrorCode()); return std::move(error); @@ -266,7 +271,7 @@ TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language, if (!can_create) { error = llvm::make_error( "Unable to find type system for language " + - llvm::toStringRef(Language::GetNameForLanguageType(language)), + llvm::StringRef(Language::GetNameForLanguageType(language)), llvm::inconvertibleErrorCode()); } else { // Cache even if we get a shared pointer that contains a null type system @@ -279,7 +284,7 @@ TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language, } error = llvm::make_error( "TypeSystem for language " + - llvm::toStringRef(Language::GetNameForLanguageType(language)) + + llvm::StringRef(Language::GetNameForLanguageType(language)) + " doesn't exist", llvm::inconvertibleErrorCode()); } @@ -308,7 +313,7 @@ TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language, } error = llvm::make_error( "TypeSystem for language " + - llvm::toStringRef(Language::GetNameForLanguageType(language)) + + llvm::StringRef(Language::GetNameForLanguageType(language)) + " doesn't exist", llvm::inconvertibleErrorCode()); return std::move(error); @@ -325,7 +330,7 @@ TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language, } error = llvm::make_error( "TypeSystem for language " + - llvm::toStringRef(Language::GetNameForLanguageType(language)) + + llvm::StringRef(Language::GetNameForLanguageType(language)) + " doesn't exist", llvm::inconvertibleErrorCode()); return std::move(error); @@ -335,7 +340,7 @@ TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language, if (!can_create) { error = llvm::make_error( "Unable to find type system for language " + - llvm::toStringRef(Language::GetNameForLanguageType(language)), + llvm::StringRef(Language::GetNameForLanguageType(language)), llvm::inconvertibleErrorCode()); } else { // Cache even if we get a shared pointer that contains a null type system @@ -348,7 +353,7 @@ TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language, } error = llvm::make_error( "TypeSystem for language " + - llvm::toStringRef(Language::GetNameForLanguageType(language)) + + llvm::StringRef(Language::GetNameForLanguageType(language)) + " doesn't exist", llvm::inconvertibleErrorCode()); } diff --git a/gnu/llvm/lldb/source/Symbol/UnwindPlan.cpp b/gnu/llvm/lldb/source/Symbol/UnwindPlan.cpp index 15443ce5d8a..e8906f38e2f 100644 --- a/gnu/llvm/lldb/source/Symbol/UnwindPlan.cpp +++ b/gnu/llvm/lldb/source/Symbol/UnwindPlan.cpp @@ -1,4 +1,4 @@ -//===-- UnwindPlan.cpp ----------------------------------*- C++ -*-===// +//===-- UnwindPlan.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -15,6 +15,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" +#include "llvm/DebugInfo/DWARF/DWARFExpression.h" using namespace lldb; using namespace lldb_private; @@ -79,13 +80,10 @@ GetByteOrderAndAddrSize(Thread *thread) { static void DumpDWARFExpr(Stream &s, llvm::ArrayRef expr, Thread *thread) { if (auto order_and_width = GetByteOrderAndAddrSize(thread)) { - DataExtractor extractor(expr.data(), expr.size(), order_and_width->first, - order_and_width->second); - if (!DWARFExpression::PrintDWARFExpression(s, extractor, - order_and_width->second, - /*dwarf_ref_size*/ 4, - /*location_expression*/ false)) - s.PutCString("invalid-dwarf-expr"); + llvm::DataExtractor data(expr, order_and_width->first == eByteOrderLittle, + order_and_width->second); + llvm::DWARFExpression(data, order_and_width->second, llvm::dwarf::DWARF32) + .print(s.AsRawOstream(), nullptr, nullptr); } else s.PutCString("dwarf-expr"); } diff --git a/gnu/llvm/lldb/source/Symbol/UnwindTable.cpp b/gnu/llvm/lldb/source/Symbol/UnwindTable.cpp index 045957a67b3..3faa528a339 100644 --- a/gnu/llvm/lldb/source/Symbol/UnwindTable.cpp +++ b/gnu/llvm/lldb/source/Symbol/UnwindTable.cpp @@ -1,4 +1,4 @@ -//===-- UnwindTable.cpp -----------------------------------------*- C++ -*-===// +//===-- UnwindTable.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -57,26 +57,28 @@ void UnwindTable::Initialize() { SectionSP sect = sl->FindSectionByType(eSectionTypeEHFrame, true); if (sect.get()) { - m_eh_frame_up.reset( - new DWARFCallFrameInfo(*object_file, sect, DWARFCallFrameInfo::EH)); + m_eh_frame_up = std::make_unique( + *object_file, sect, DWARFCallFrameInfo::EH); } sect = sl->FindSectionByType(eSectionTypeDWARFDebugFrame, true); if (sect) { - m_debug_frame_up.reset( - new DWARFCallFrameInfo(*object_file, sect, DWARFCallFrameInfo::DWARF)); + m_debug_frame_up = std::make_unique( + *object_file, sect, DWARFCallFrameInfo::DWARF); } sect = sl->FindSectionByType(eSectionTypeCompactUnwind, true); if (sect) { - m_compact_unwind_up.reset(new CompactUnwindInfo(*object_file, sect)); + m_compact_unwind_up = + std::make_unique(*object_file, sect); } sect = sl->FindSectionByType(eSectionTypeARMexidx, true); if (sect) { SectionSP sect_extab = sl->FindSectionByType(eSectionTypeARMextab, true); if (sect_extab.get()) { - m_arm_unwind_up.reset(new ArmUnwindInfo(*object_file, sect, sect_extab)); + m_arm_unwind_up = + std::make_unique(*object_file, sect, sect_extab); } } } diff --git a/gnu/llvm/lldb/source/Symbol/Variable.cpp b/gnu/llvm/lldb/source/Symbol/Variable.cpp index a0496824a0a..6c18ef15e1a 100644 --- a/gnu/llvm/lldb/source/Symbol/Variable.cpp +++ b/gnu/llvm/lldb/source/Symbol/Variable.cpp @@ -1,4 +1,4 @@ -//===-- Variable.cpp --------------------------------------------*- C++ -*-===// +//===-- Variable.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -68,7 +68,7 @@ lldb::LanguageType Variable::GetLanguage() const { } ConstString Variable::GetName() const { - ConstString name = m_mangled.GetName(GetLanguage()); + ConstString name = m_mangled.GetName(); if (name) return name; return m_name; @@ -82,16 +82,13 @@ bool Variable::NameMatches(ConstString name) const { SymbolContext variable_sc; m_owner_scope->CalculateSymbolContext(&variable_sc); - LanguageType language = eLanguageTypeUnknown; - if (variable_sc.comp_unit) - language = variable_sc.comp_unit->GetLanguage(); - return m_mangled.NameMatches(name, language); + return m_mangled.NameMatches(name); } bool Variable::NameMatches(const RegularExpression ®ex) const { if (regex.Execute(m_name.AsCString())) return true; if (m_mangled) - return m_mangled.NameMatches(regex, GetLanguage()); + return m_mangled.NameMatches(regex); return false; } @@ -532,7 +529,7 @@ static void PrivateAutoCompleteMembers( i, member_name, nullptr, nullptr, nullptr); if (partial_member_name.empty() || - member_name.find(partial_member_name) == 0) { + llvm::StringRef(member_name).startswith(partial_member_name)) { if (member_name == partial_member_name) { PrivateAutoComplete( frame, partial_path, @@ -684,8 +681,8 @@ static void PrivateAutoComplete( break; } - std::string token(partial_path, 0, pos); - remaining_partial_path = partial_path.substr(pos); + std::string token(std::string(partial_path), 0, pos); + remaining_partial_path = std::string(partial_path.substr(pos)); if (compiler_type.IsValid()) { PrivateAutoCompleteMembers(frame, token, remaining_partial_path, diff --git a/gnu/llvm/lldb/source/Symbol/VariableList.cpp b/gnu/llvm/lldb/source/Symbol/VariableList.cpp index 51312472e26..f7a441472bc 100644 --- a/gnu/llvm/lldb/source/Symbol/VariableList.cpp +++ b/gnu/llvm/lldb/source/Symbol/VariableList.cpp @@ -1,4 +1,4 @@ -//===-- VariableList.cpp ----------------------------------------*- C++ -*-===// +//===-- VariableList.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/ABI.cpp b/gnu/llvm/lldb/source/Target/ABI.cpp index 58396ba7058..4320eb93adf 100644 --- a/gnu/llvm/lldb/source/Target/ABI.cpp +++ b/gnu/llvm/lldb/source/Target/ABI.cpp @@ -1,4 +1,4 @@ -//===-- ABI.cpp -------------------------------------------------*- C++ -*-===// +//===-- ABI.cpp -----------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -17,6 +17,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/Log.h" #include "llvm/Support/TargetRegistry.h" +#include using namespace lldb; using namespace lldb_private; @@ -41,20 +42,27 @@ ABI::FindPlugin(lldb::ProcessSP process_sp, const ArchSpec &arch) { ABI::~ABI() = default; -bool ABI::GetRegisterInfoByName(ConstString name, RegisterInfo &info) { +bool RegInfoBasedABI::GetRegisterInfoByName(ConstString name, RegisterInfo &info) { uint32_t count = 0; const RegisterInfo *register_info_array = GetRegisterInfoArray(count); if (register_info_array) { const char *unique_name_cstr = name.GetCString(); uint32_t i; for (i = 0; i < count; ++i) { - if (register_info_array[i].name == unique_name_cstr) { + const char *reg_name = register_info_array[i].name; + assert(ConstString(reg_name).GetCString() == reg_name && + "register_info_array[i].name not from a ConstString?"); + if (reg_name == unique_name_cstr) { info = register_info_array[i]; return true; } } for (i = 0; i < count; ++i) { - if (register_info_array[i].alt_name == unique_name_cstr) { + const char *reg_alt_name = register_info_array[i].alt_name; + assert((reg_alt_name == nullptr || + ConstString(reg_alt_name).GetCString() == reg_alt_name) && + "register_info_array[i].alt_name not from a ConstString?"); + if (reg_alt_name == unique_name_cstr) { info = register_info_array[i]; return true; } @@ -89,10 +97,8 @@ ValueObjectSP ABI::GetReturnValueObject(Thread &thread, CompilerType &ast_type, if (!persistent_expression_state) return {}; - auto prefix = persistent_expression_state->GetPersistentVariablePrefix(); ConstString persistent_variable_name = - persistent_expression_state->GetNextPersistentVariableName(target, - prefix); + persistent_expression_state->GetNextPersistentVariableName(); lldb::ValueObjectSP const_valobj_sp; @@ -212,7 +218,7 @@ std::unique_ptr ABI::MakeMCRegisterInfo(const ArchSpec &ar return info_up; } -void ABI::AugmentRegisterInfo(RegisterInfo &info) { +void RegInfoBasedABI::AugmentRegisterInfo(RegisterInfo &info) { if (info.kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM && info.kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM) return; @@ -228,3 +234,44 @@ void ABI::AugmentRegisterInfo(RegisterInfo &info) { if (info.kinds[eRegisterKindGeneric] == LLDB_INVALID_REGNUM) info.kinds[eRegisterKindGeneric] = abi_info.kinds[eRegisterKindGeneric]; } + +void MCBasedABI::AugmentRegisterInfo(RegisterInfo &info) { + uint32_t eh, dwarf; + std::tie(eh, dwarf) = GetEHAndDWARFNums(info.name); + + if (info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM) + info.kinds[eRegisterKindEHFrame] = eh; + if (info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM) + info.kinds[eRegisterKindDWARF] = dwarf; + if (info.kinds[eRegisterKindGeneric] == LLDB_INVALID_REGNUM) + info.kinds[eRegisterKindGeneric] = GetGenericNum(info.name); +} + +std::pair +MCBasedABI::GetEHAndDWARFNums(llvm::StringRef name) { + std::string mc_name = GetMCName(name.str()); + for (char &c : mc_name) + c = std::toupper(c); + int eh = -1; + int dwarf = -1; + for (unsigned reg = 0; reg < m_mc_register_info_up->getNumRegs(); ++reg) { + if (m_mc_register_info_up->getName(reg) == mc_name) { + eh = m_mc_register_info_up->getDwarfRegNum(reg, /*isEH=*/true); + dwarf = m_mc_register_info_up->getDwarfRegNum(reg, /*isEH=*/false); + break; + } + } + return std::pair(eh == -1 ? LLDB_INVALID_REGNUM : eh, + dwarf == -1 ? LLDB_INVALID_REGNUM + : dwarf); +} + +void MCBasedABI::MapRegisterName(std::string &name, llvm::StringRef from_prefix, + llvm::StringRef to_prefix) { + llvm::StringRef name_ref = name; + if (!name_ref.consume_front(from_prefix)) + return; + uint64_t _; + if (name_ref.empty() || to_integer(name_ref, _, 10)) + name = (to_prefix + name_ref).str(); +} diff --git a/gnu/llvm/lldb/source/Target/AssertFrameRecognizer.cpp b/gnu/llvm/lldb/source/Target/AssertFrameRecognizer.cpp new file mode 100644 index 00000000000..d87459ac2fd --- /dev/null +++ b/gnu/llvm/lldb/source/Target/AssertFrameRecognizer.cpp @@ -0,0 +1,168 @@ +#include "lldb/Core/Module.h" +#include "lldb/Symbol/Function.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/StackFrameList.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" + +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" + +#include "lldb/Target/AssertFrameRecognizer.h" + +using namespace llvm; +using namespace lldb; +using namespace lldb_private; + +namespace lldb_private { + +/// Stores a function module spec, symbol name and possibly an alternate symbol +/// name. +struct SymbolLocation { + FileSpec module_spec; + std::vector symbols; +}; + +/// Fetches the abort frame location depending on the current platform. +/// +/// \param[in] os +/// The target's os type. +/// \param[in,out] location +/// The struct that will contain the abort module spec and symbol names. +/// \return +/// \b true, if the platform is supported +/// \b false, otherwise. +bool GetAbortLocation(llvm::Triple::OSType os, SymbolLocation &location) { + switch (os) { + case llvm::Triple::Darwin: + case llvm::Triple::MacOSX: + location.module_spec = FileSpec("libsystem_kernel.dylib"); + location.symbols.push_back(ConstString("__pthread_kill")); + break; + case llvm::Triple::Linux: + location.module_spec = FileSpec("libc.so.6"); + location.symbols.push_back(ConstString("raise")); + location.symbols.push_back(ConstString("__GI_raise")); + location.symbols.push_back(ConstString("gsignal")); + break; + default: + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + LLDB_LOG(log, "AssertFrameRecognizer::GetAbortLocation Unsupported OS"); + return false; + } + + return true; +} + +/// Fetches the assert frame location depending on the current platform. +/// +/// \param[in] os +/// The target's os type. +/// \param[in,out] location +/// The struct that will contain the assert module spec and symbol names. +/// \return +/// \b true, if the platform is supported +/// \b false, otherwise. +bool GetAssertLocation(llvm::Triple::OSType os, SymbolLocation &location) { + switch (os) { + case llvm::Triple::Darwin: + case llvm::Triple::MacOSX: + location.module_spec = FileSpec("libsystem_c.dylib"); + location.symbols.push_back(ConstString("__assert_rtn")); + break; + case llvm::Triple::Linux: + location.module_spec = FileSpec("libc.so.6"); + location.symbols.push_back(ConstString("__assert_fail")); + location.symbols.push_back(ConstString("__GI___assert_fail")); + break; + default: + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + LLDB_LOG(log, "AssertFrameRecognizer::GetAssertLocation Unsupported OS"); + return false; + } + + return true; +} + +void RegisterAssertFrameRecognizer(Process *process) { + static llvm::once_flag g_once_flag; + llvm::call_once(g_once_flag, [process]() { + Target &target = process->GetTarget(); + llvm::Triple::OSType os = target.GetArchitecture().GetTriple().getOS(); + SymbolLocation location; + + if (!GetAbortLocation(os, location)) + return; + + StackFrameRecognizerManager::AddRecognizer( + StackFrameRecognizerSP(new AssertFrameRecognizer()), + location.module_spec.GetFilename(), location.symbols, + /*first_instruction_only*/ false); + }); +} + +} // namespace lldb_private + +lldb::RecognizedStackFrameSP +AssertFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) { + ThreadSP thread_sp = frame_sp->GetThread(); + ProcessSP process_sp = thread_sp->GetProcess(); + Target &target = process_sp->GetTarget(); + llvm::Triple::OSType os = target.GetArchitecture().GetTriple().getOS(); + SymbolLocation location; + + if (!GetAssertLocation(os, location)) + return RecognizedStackFrameSP(); + + const uint32_t frames_to_fetch = 5; + const uint32_t last_frame_index = frames_to_fetch - 1; + StackFrameSP prev_frame_sp = nullptr; + + // Fetch most relevant frame + for (uint32_t frame_index = 0; frame_index < frames_to_fetch; frame_index++) { + prev_frame_sp = thread_sp->GetStackFrameAtIndex(frame_index); + + if (!prev_frame_sp) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + LLDB_LOG(log, "Abort Recognizer: Hit unwinding bound ({1} frames)!", + frames_to_fetch); + break; + } + + SymbolContext sym_ctx = + prev_frame_sp->GetSymbolContext(eSymbolContextEverything); + + if (!sym_ctx.module_sp->GetFileSpec().FileEquals(location.module_spec)) + continue; + + ConstString func_name = sym_ctx.GetFunctionName(); + + if (llvm::is_contained(location.symbols, func_name)) { + // We go a frame beyond the assert location because the most relevant + // frame for the user is the one in which the assert function was called. + // If the assert location is the last frame fetched, then it is set as + // the most relevant frame. + + StackFrameSP most_relevant_frame_sp = thread_sp->GetStackFrameAtIndex( + std::min(frame_index + 1, last_frame_index)); + + // Pass assert location to AbortRecognizedStackFrame to set as most + // relevant frame. + return lldb::RecognizedStackFrameSP( + new AssertRecognizedStackFrame(most_relevant_frame_sp)); + } + } + + return RecognizedStackFrameSP(); +} + +AssertRecognizedStackFrame::AssertRecognizedStackFrame( + StackFrameSP most_relevant_frame_sp) + : m_most_relevant_frame(most_relevant_frame_sp) { + m_stop_desc = "hit program assert"; +} + +lldb::StackFrameSP AssertRecognizedStackFrame::GetMostRelevantFrame() { + return m_most_relevant_frame; +} diff --git a/gnu/llvm/lldb/source/Target/CMakeLists.txt b/gnu/llvm/lldb/source/Target/CMakeLists.txt index a92951e6a73..ca80b5b6477 100644 --- a/gnu/llvm/lldb/source/Target/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Target/CMakeLists.txt @@ -8,11 +8,12 @@ lldb_tablegen(TargetPropertiesEnum.inc -gen-lldb-property-enum-defs add_lldb_library(lldbTarget ABI.cpp + AssertFrameRecognizer.cpp ExecutionContext.cpp - JITLoader.cpp - JITLoaderList.cpp InstrumentationRuntime.cpp InstrumentationRuntimeStopInfo.cpp + JITLoader.cpp + JITLoaderList.cpp Language.cpp LanguageRuntime.cpp Memory.cpp @@ -27,6 +28,7 @@ add_lldb_library(lldbTarget QueueItem.cpp QueueList.cpp RegisterContext.cpp + RegisterContextUnwind.cpp RegisterNumber.cpp RemoteAwarePlatform.cpp SectionLoadHistory.cpp @@ -61,9 +63,11 @@ add_lldb_library(lldbTarget ThreadPlanStepThrough.cpp ThreadPlanStepUntil.cpp ThreadPlanTracer.cpp + ThreadPlanStack.cpp ThreadSpec.cpp UnixSignals.cpp UnwindAssembly.cpp + UnwindLLDB.cpp LINK_LIBS lldbBreakpoint @@ -78,6 +82,7 @@ add_lldb_library(lldbTarget LINK_COMPONENTS Support + MC ) add_dependencies(lldbTarget diff --git a/gnu/llvm/lldb/source/Target/ExecutionContext.cpp b/gnu/llvm/lldb/source/Target/ExecutionContext.cpp index a24a098eb30..20932ee63dc 100644 --- a/gnu/llvm/lldb/source/Target/ExecutionContext.cpp +++ b/gnu/llvm/lldb/source/Target/ExecutionContext.cpp @@ -1,4 +1,4 @@ -//===-- ExecutionContext.cpp ------------------------------------*- C++ -*-===// +//===-- ExecutionContext.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/InstrumentationRuntime.cpp b/gnu/llvm/lldb/source/Target/InstrumentationRuntime.cpp index 4c2eb064fbb..9f22a1be20c 100644 --- a/gnu/llvm/lldb/source/Target/InstrumentationRuntime.cpp +++ b/gnu/llvm/lldb/source/Target/InstrumentationRuntime.cpp @@ -1,4 +1,4 @@ -//===-- InstrumentationRuntime.cpp ------------------------------*- C++ -*-===// +//===-- InstrumentationRuntime.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/InstrumentationRuntimeStopInfo.cpp b/gnu/llvm/lldb/source/Target/InstrumentationRuntimeStopInfo.cpp index f2767ffbff0..7f82581cc60 100644 --- a/gnu/llvm/lldb/source/Target/InstrumentationRuntimeStopInfo.cpp +++ b/gnu/llvm/lldb/source/Target/InstrumentationRuntimeStopInfo.cpp @@ -1,4 +1,4 @@ -//===-- InstrumentationRuntimeStopInfo.cpp ----------------------*- C++ -*-===// +//===-- InstrumentationRuntimeStopInfo.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/JITLoader.cpp b/gnu/llvm/lldb/source/Target/JITLoader.cpp index e7c13bddcb3..8ff349e063b 100644 --- a/gnu/llvm/lldb/source/Target/JITLoader.cpp +++ b/gnu/llvm/lldb/source/Target/JITLoader.cpp @@ -1,4 +1,4 @@ -//===-- JITLoader.cpp -------------------------------------------*- C++ -*-===// +//===-- JITLoader.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/JITLoaderList.cpp b/gnu/llvm/lldb/source/Target/JITLoaderList.cpp index 4d1f06d0843..f5a90d58d58 100644 --- a/gnu/llvm/lldb/source/Target/JITLoaderList.cpp +++ b/gnu/llvm/lldb/source/Target/JITLoaderList.cpp @@ -1,4 +1,4 @@ -//===-- JITLoaderList.cpp ---------------------------------------*- C++ -*-===// +//===-- JITLoaderList.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/Language.cpp b/gnu/llvm/lldb/source/Target/Language.cpp index 10a9ddd56c4..b1a8a9517f3 100644 --- a/gnu/llvm/lldb/source/Target/Language.cpp +++ b/gnu/llvm/lldb/source/Target/Language.cpp @@ -1,5 +1,4 @@ -//===-- Language.cpp -------------------------------------------------*- C++ -//-*-===// +//===-- Language.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -140,13 +139,6 @@ Language::GetPossibleFormattersMatches(ValueObject &valobj, return {}; } -lldb_private::formatters::StringPrinter::EscapingHelper -Language::GetStringPrinterEscapingHelper( - lldb_private::formatters::StringPrinter::GetPrintableElementType - elem_type) { - return StringPrinter::GetDefaultEscapingHelper(elem_type); -} - struct language_name_pair { const char *name; LanguageType type; diff --git a/gnu/llvm/lldb/source/Target/LanguageRuntime.cpp b/gnu/llvm/lldb/source/Target/LanguageRuntime.cpp index 32dd805a00b..58ad70c2b90 100644 --- a/gnu/llvm/lldb/source/Target/LanguageRuntime.cpp +++ b/gnu/llvm/lldb/source/Target/LanguageRuntime.cpp @@ -1,4 +1,4 @@ -//===-- LanguageRuntime.cpp -------------------------------------*- C++ -*-===// +//===-- LanguageRuntime.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -78,8 +78,7 @@ void ExceptionSearchFilter::UpdateModuleListIfNeeded() { } } -SearchFilterSP -ExceptionSearchFilter::DoCopyForBreakpoint(Breakpoint &breakpoint) { +SearchFilterSP ExceptionSearchFilter::DoCreateCopy() { return SearchFilterSP( new ExceptionSearchFilter(TargetSP(), m_language, false)); } @@ -154,17 +153,17 @@ public: } protected: - BreakpointResolverSP CopyForBreakpoint(Breakpoint &breakpoint) override { + BreakpointResolverSP CopyForBreakpoint(BreakpointSP &breakpoint) override { BreakpointResolverSP ret_sp( new ExceptionBreakpointResolver(m_language, m_catch_bp, m_throw_bp)); - ret_sp->SetBreakpoint(&breakpoint); + ret_sp->SetBreakpoint(breakpoint); return ret_sp; } bool SetActualResolver() { - ProcessSP process_sp; - if (m_breakpoint) { - process_sp = m_breakpoint->GetTarget().GetProcessSP(); + BreakpointSP breakpoint_sp = GetBreakpoint(); + if (breakpoint_sp) { + ProcessSP process_sp = breakpoint_sp->GetTarget().GetProcessSP(); if (process_sp) { bool refreash_resolver = !m_actual_resolver_sp; if (m_language_runtime == nullptr) { @@ -181,7 +180,7 @@ protected: if (refreash_resolver && m_language_runtime) { m_actual_resolver_sp = m_language_runtime->CreateExceptionResolver( - m_breakpoint, m_catch_bp, m_throw_bp); + breakpoint_sp, m_catch_bp, m_throw_bp); } } else { m_actual_resolver_sp.reset(); diff --git a/gnu/llvm/lldb/source/Target/Memory.cpp b/gnu/llvm/lldb/source/Target/Memory.cpp index 7c77cc06eb0..a7ed1a3d97b 100644 --- a/gnu/llvm/lldb/source/Target/Memory.cpp +++ b/gnu/llvm/lldb/source/Target/Memory.cpp @@ -1,4 +1,4 @@ -//===-- Memory.cpp ----------------------------------------------*- C++ -*-===// +//===-- Memory.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -116,7 +116,7 @@ bool MemoryCache::RemoveInvalidRange(lldb::addr_t base_addr, const InvalidRanges::Entry *entry = m_invalid_ranges.GetEntryAtIndex(idx); if (entry->GetRangeBase() == base_addr && entry->GetByteSize() == byte_size) - return m_invalid_ranges.RemoveEntrtAtIndex(idx); + return m_invalid_ranges.RemoveEntryAtIndex(idx); } } return false; @@ -232,8 +232,13 @@ size_t MemoryCache::Read(addr_t addr, void *dst, size_t dst_len, if (process_bytes_read == 0) return dst_len - bytes_left; - if (process_bytes_read != cache_line_byte_size) + if (process_bytes_read != cache_line_byte_size) { + if (process_bytes_read < data_buffer_heap_up->GetByteSize()) { + dst_len -= data_buffer_heap_up->GetByteSize() - process_bytes_read; + bytes_left = process_bytes_read; + } data_buffer_heap_up->SetByteSize(process_bytes_read); + } m_L2_cache[curr_addr] = DataBufferSP(data_buffer_heap_up.release()); // We have read data and put it into the cache, continue through the // loop again to get the data out of the cache... diff --git a/gnu/llvm/lldb/source/Target/MemoryHistory.cpp b/gnu/llvm/lldb/source/Target/MemoryHistory.cpp index 37148e1e72e..0ebf796a56b 100644 --- a/gnu/llvm/lldb/source/Target/MemoryHistory.cpp +++ b/gnu/llvm/lldb/source/Target/MemoryHistory.cpp @@ -1,4 +1,4 @@ -//===-- MemoryHistory.cpp ---------------------------------------*- C++ -*-===// +//===-- MemoryHistory.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/MemoryRegionInfo.cpp b/gnu/llvm/lldb/source/Target/MemoryRegionInfo.cpp index 2c31563786a..c7fb349ee1c 100644 --- a/gnu/llvm/lldb/source/Target/MemoryRegionInfo.cpp +++ b/gnu/llvm/lldb/source/Target/MemoryRegionInfo.cpp @@ -1,4 +1,4 @@ -//===-- MemoryRegionInfo.cpp ------------------------------------*- C++ -*-===// +//===-- MemoryRegionInfo.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/ModuleCache.cpp b/gnu/llvm/lldb/source/Target/ModuleCache.cpp index 124cdacfb4d..20661a7b7a2 100644 --- a/gnu/llvm/lldb/source/Target/ModuleCache.cpp +++ b/gnu/llvm/lldb/source/Target/ModuleCache.cpp @@ -1,4 +1,4 @@ -//===--------------------- ModuleCache.cpp ----------------------*- C++ -*-===// +//===-- ModuleCache.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -169,7 +169,7 @@ ModuleLock::ModuleLock(const FileSpec &root_dir_spec, const UUID &uuid, return; } - m_lock.reset(new lldb_private::LockFile(m_file_up->GetDescriptor())); + m_lock = std::make_unique(m_file_up->GetDescriptor()); error = m_lock->WriteLock(0, 1); if (error.Fail()) error.SetErrorStringWithFormat("Failed to lock file: %s", diff --git a/gnu/llvm/lldb/source/Target/OperatingSystem.cpp b/gnu/llvm/lldb/source/Target/OperatingSystem.cpp index c78c197db5b..ddffab4553c 100644 --- a/gnu/llvm/lldb/source/Target/OperatingSystem.cpp +++ b/gnu/llvm/lldb/source/Target/OperatingSystem.cpp @@ -1,4 +1,4 @@ -//===-- OperatingSystem.cpp -------------------------------------*- C++ -*-===// +//===-- OperatingSystem.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/PathMappingList.cpp b/gnu/llvm/lldb/source/Target/PathMappingList.cpp index 58c2c43c936..b22673f5547 100644 --- a/gnu/llvm/lldb/source/Target/PathMappingList.cpp +++ b/gnu/llvm/lldb/source/Target/PathMappingList.cpp @@ -1,4 +1,4 @@ -//===-- PathMappingList.cpp -------------------------------------*- C++ -*-===// +//===-- PathMappingList.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/Platform.cpp b/gnu/llvm/lldb/source/Target/Platform.cpp index aaf48f35f92..e5afb4c7b8d 100644 --- a/gnu/llvm/lldb/source/Target/Platform.cpp +++ b/gnu/llvm/lldb/source/Target/Platform.cpp @@ -1,4 +1,4 @@ -//===-- Platform.cpp --------------------------------------------*- C++ -*-===// +//===-- Platform.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -12,9 +12,6 @@ #include #include -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" - #include "lldb/Breakpoint/BreakpointIDList.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Debugger.h" @@ -26,6 +23,7 @@ #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/OptionParser.h" +#include "lldb/Interpreter/OptionValueFileSpec.h" #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Interpreter/Property.h" #include "lldb/Symbol/ObjectFile.h" @@ -39,8 +37,8 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StructuredData.h" - #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" // Define these constants from POSIX mman.h rather than include the file so // that they will be correct even when compiled on Linux. @@ -93,6 +91,7 @@ PlatformProperties::PlatformProperties() { module_cache_dir = FileSpec(user_home_dir.c_str()); module_cache_dir.AppendPathComponent(".lldb"); module_cache_dir.AppendPathComponent("module_cache"); + SetDefaultModuleCacheDirectory(module_cache_dir); SetModuleCacheDirectory(module_cache_dir); } @@ -117,6 +116,14 @@ bool PlatformProperties::SetModuleCacheDirectory(const FileSpec &dir_spec) { nullptr, ePropertyModuleCacheDirectory, dir_spec); } +void PlatformProperties::SetDefaultModuleCacheDirectory( + const FileSpec &dir_spec) { + auto f_spec_opt = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpec( + nullptr, false, ePropertyModuleCacheDirectory); + assert(f_spec_opt); + f_spec_opt->SetDefaultValue(dir_spec); +} + /// Get the native host platform plug-in. /// /// There should only be one of these for each host that LLDB runs @@ -211,15 +218,14 @@ Platform::LocateExecutableScriptingResources(Target *target, Module &module, // return PlatformSP(); //} -Status Platform::GetSharedModule(const ModuleSpec &module_spec, - Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, - ModuleSP *old_module_sp_ptr, - bool *did_create_ptr) { +Status Platform::GetSharedModule( + const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { if (IsHost()) - return ModuleList::GetSharedModule( - module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, - did_create_ptr, false); + return ModuleList::GetSharedModule(module_spec, module_sp, + module_search_paths_ptr, old_modules, + did_create_ptr, false); // Module resolver lambda. auto resolver = [&](const ModuleSpec &spec) { @@ -232,17 +238,17 @@ Status Platform::GetSharedModule(const ModuleSpec &module_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); + error = ModuleList::GetSharedModule(resolved_spec, module_sp, + module_search_paths_ptr, old_modules, + 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); + error = ModuleList::GetSharedModule(resolved_spec, module_sp, + module_search_paths_ptr, old_modules, + did_create_ptr, false); } if (error.Success() && module_sp) module_sp->SetPlatformFileSpec(resolved_spec.GetFileSpec()); @@ -421,9 +427,6 @@ void Platform::GetStatus(Stream &strm) { strm.EOL(); } - if (GetOSKernelDescription(s)) - strm.Printf(" Kernel: %s\n", s.c_str()); - if (IsHost()) { strm.Printf(" Hostname: %s\n", GetHostname()); } else { @@ -443,6 +446,9 @@ void Platform::GetStatus(Stream &strm) { if (!specific_info.empty()) strm.Printf("Platform-specific connection: %s\n", specific_info.c_str()); + + if (GetOSKernelDescription(s)) + strm.Printf(" Kernel: %s\n", s.c_str()); } llvm::VersionTuple Platform::GetOSVersion(Process *process) { @@ -1144,10 +1150,10 @@ Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, process_sp->SetShouldDetach(false); // If we didn't have any file actions, the pseudo terminal might have - // been used where the slave side was given as the file to open for + // been used where the secondary side was given as the file to open for // stdin/out/err after we have already opened the master so we can // read/write stdin/out/err. - int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor(); + int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor(); if (pty_fd != PseudoTerminal::invalid_fd) { process_sp->SetSTDIOFileDescriptor(pty_fd); } @@ -1400,11 +1406,11 @@ OptionGroupPlatformRSync::SetOptionValue(uint32_t option_idx, break; case 'R': - m_rsync_opts.assign(option_arg); + m_rsync_opts.assign(std::string(option_arg)); break; case 'P': - m_rsync_prefix.assign(option_arg); + m_rsync_prefix.assign(std::string(option_arg)); break; case 'i': @@ -1446,7 +1452,7 @@ OptionGroupPlatformSSH::SetOptionValue(uint32_t option_idx, break; case 'S': - m_ssh_opts.assign(option_arg); + m_ssh_opts.assign(std::string(option_arg)); break; default: @@ -1473,7 +1479,7 @@ lldb_private::Status OptionGroupPlatformCaching::SetOptionValue( char short_option = (char)GetDefinitions()[option_idx].short_option; switch (short_option) { case 'c': - m_cache_dir.assign(option_arg); + m_cache_dir.assign(std::string(option_arg)); break; default: @@ -1557,21 +1563,29 @@ Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec, if (error.Success() && module_sp) break; } - if (module_sp) + if (module_sp) { + resolved_module_spec = arch_module_spec; got_module_spec = true; + } } if (!got_module_spec) { // Get module information from a target. - if (!GetModuleSpec(module_spec.GetFileSpec(), module_spec.GetArchitecture(), - resolved_module_spec)) { + if (GetModuleSpec(module_spec.GetFileSpec(), module_spec.GetArchitecture(), + resolved_module_spec)) { if (!module_spec.GetUUID().IsValid() || module_spec.GetUUID() == resolved_module_spec.GetUUID()) { - return module_resolver(module_spec); + got_module_spec = true; } } } + if (!got_module_spec) { + // Fall back to the given module resolver, which may have its own + // search logic. + return module_resolver(module_spec); + } + // If we are looking for a specific UUID, make sure resolved_module_spec has // the same one before we search. if (module_spec.GetUUID().IsValid()) { @@ -1764,9 +1778,23 @@ Status Platform::UnloadImage(lldb_private::Process *process, lldb::ProcessSP Platform::ConnectProcess(llvm::StringRef connect_url, llvm::StringRef plugin_name, - lldb_private::Debugger &debugger, - lldb_private::Target *target, - lldb_private::Status &error) { + Debugger &debugger, Target *target, + Status &error) { + return DoConnectProcess(connect_url, plugin_name, debugger, nullptr, target, + error); +} + +lldb::ProcessSP Platform::ConnectProcessSynchronous( + llvm::StringRef connect_url, llvm::StringRef plugin_name, + Debugger &debugger, Stream &stream, Target *target, Status &error) { + return DoConnectProcess(connect_url, plugin_name, debugger, &stream, target, + error); +} + +lldb::ProcessSP Platform::DoConnectProcess(llvm::StringRef connect_url, + llvm::StringRef plugin_name, + Debugger &debugger, Stream *stream, + Target *target, Status &error) { error.Clear(); if (!target) { @@ -1793,12 +1821,34 @@ lldb::ProcessSP Platform::ConnectProcess(llvm::StringRef connect_url, lldb::ProcessSP process_sp = target->CreateProcess(debugger.GetListener(), plugin_name, nullptr); + if (!process_sp) return nullptr; - error = process_sp->ConnectRemote(&debugger.GetOutputStream(), connect_url); - if (error.Fail()) + // If this private method is called with a stream we are synchronous. + const bool synchronous = stream != nullptr; + + ListenerSP listener_sp( + Listener::MakeListener("lldb.Process.ConnectProcess.hijack")); + if (synchronous) + process_sp->HijackProcessEvents(listener_sp); + + error = process_sp->ConnectRemote(connect_url); + if (error.Fail()) { + if (synchronous) + process_sp->RestoreProcessEvents(); return nullptr; + } + + if (synchronous) { + EventSP event_sp; + process_sp->WaitForProcessToStop(llvm::None, &event_sp, true, listener_sp, + nullptr); + process_sp->RestoreProcessEvents(); + bool pop_process_io_handler = false; + Process::HandleProcessStateChangedEvent(event_sp, stream, + pop_process_io_handler); + } return process_sp; } @@ -1812,6 +1862,7 @@ size_t Platform::ConnectToWaitingProcesses(lldb_private::Debugger &debugger, size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target, BreakpointSite *bp_site) { ArchSpec arch = target.GetArchitecture(); + assert(arch.IsValid()); const uint8_t *trap_opcode = nullptr; size_t trap_opcode_size = 0; @@ -1855,6 +1906,12 @@ size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target, } } break; + case llvm::Triple::avr: { + static const uint8_t g_hex_opcode[] = {0x98, 0x95}; + trap_opcode = g_hex_opcode; + trap_opcode_size = sizeof(g_hex_opcode); + } break; + case llvm::Triple::mips: case llvm::Triple::mips64: { static const uint8_t g_hex_opcode[] = {0x00, 0x00, 0x00, 0x0d}; @@ -1902,8 +1959,7 @@ size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target, } break; default: - llvm_unreachable( - "Unhandled architecture in Platform::GetSoftwareBreakpointTrapOpcode"); + return 0; } assert(bp_site); diff --git a/gnu/llvm/lldb/source/Target/Process.cpp b/gnu/llvm/lldb/source/Target/Process.cpp index 6711dc37eca..d777a271391 100644 --- a/gnu/llvm/lldb/source/Target/Process.cpp +++ b/gnu/llvm/lldb/source/Target/Process.cpp @@ -1,4 +1,4 @@ -//===-- Process.cpp ---------------------------------------------*- C++ -*-===// +//===-- Process.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -38,6 +38,7 @@ #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/ABI.h" +#include "lldb/Target/AssertFrameRecognizer.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/InstrumentationRuntime.h" #include "lldb/Target/JITLoader.h" @@ -59,6 +60,7 @@ #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanBase.h" #include "lldb/Target/ThreadPlanCallFunction.h" +#include "lldb/Target/ThreadPlanStack.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/Event.h" #include "lldb/Utility/Log.h" @@ -118,8 +120,30 @@ public: enum { #define LLDB_PROPERTIES_process #include "TargetPropertiesEnum.inc" + ePropertyExperimental, }; +#define LLDB_PROPERTIES_process_experimental +#include "TargetProperties.inc" + +enum { +#define LLDB_PROPERTIES_process_experimental +#include "TargetPropertiesEnum.inc" +}; + +class ProcessExperimentalOptionValueProperties : public OptionValueProperties { +public: + ProcessExperimentalOptionValueProperties() + : OptionValueProperties( + ConstString(Properties::GetExperimentalSettingsName())) {} +}; + +ProcessExperimentalProperties::ProcessExperimentalProperties() + : Properties(OptionValuePropertiesSP( + new ProcessExperimentalOptionValueProperties())) { + m_collection_sp->Initialize(g_process_experimental_properties); +} + ProcessProperties::ProcessProperties(lldb_private::Process *process) : Properties(), m_process(process) // Can be nullptr for global ProcessProperties @@ -139,6 +163,14 @@ ProcessProperties::ProcessProperties(lldb_private::Process *process) ePropertyPythonOSPluginPath, [this] { m_process->LoadOperatingSystemPlugin(true); }); } + + m_experimental_properties_up = + std::make_unique(); + m_collection_sp->AppendProperty( + ConstString(Properties::GetExperimentalSettingsName()), + ConstString("Experimental settings - setting these won't produce " + "errors if the setting is not present."), + true, m_experimental_properties_up->GetValueProperties()); } ProcessProperties::~ProcessProperties() = default; @@ -227,6 +259,12 @@ bool ProcessProperties::GetWarningsOptimization() const { nullptr, idx, g_process_properties[idx].default_uint_value != 0); } +bool ProcessProperties::GetWarningsUnsupportedLanguage() const { + const uint32_t idx = ePropertyWarningUnsupportedLanguage; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_process_properties[idx].default_uint_value != 0); +} + bool ProcessProperties::GetStopOnExec() const { const uint32_t idx = ePropertyStopOnExec; return m_collection_sp->GetPropertyAtIndexAsBoolean( @@ -240,6 +278,29 @@ std::chrono::seconds ProcessProperties::GetUtilityExpressionTimeout() const { return std::chrono::seconds(value); } +bool ProcessProperties::GetOSPluginReportsAllThreads() const { + const bool fail_value = true; + const Property *exp_property = + m_collection_sp->GetPropertyAtIndex(nullptr, true, ePropertyExperimental); + OptionValueProperties *exp_values = + exp_property->GetValue()->GetAsProperties(); + if (!exp_values) + return fail_value; + + return exp_values->GetPropertyAtIndexAsBoolean( + nullptr, ePropertyOSPluginReportsAllThreads, fail_value); +} + +void ProcessProperties::SetOSPluginReportsAllThreads(bool does_report) { + const Property *exp_property = + m_collection_sp->GetPropertyAtIndex(nullptr, true, ePropertyExperimental); + OptionValueProperties *exp_values = + exp_property->GetValue()->GetAsProperties(); + if (exp_values) + exp_values->SetPropertyAtIndexAsBoolean( + nullptr, ePropertyOSPluginReportsAllThreads, does_report); +} + Status ProcessLaunchCommandOptions::SetOptionValue( uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) { @@ -476,7 +537,7 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp, m_mod_id(), m_process_unique_id(0), m_thread_index_id(0), m_thread_id_to_index_id_map(), m_exit_status(-1), m_exit_string(), m_exit_status_mutex(), m_thread_mutex(), m_thread_list_real(this), - m_thread_list(this), m_extended_thread_list(this), + m_thread_list(this), m_thread_plans(*this), m_extended_thread_list(this), m_extended_thread_stop_id(0), m_queue_list(this), m_queue_list_stop_id(0), m_notifications(), m_image_tokens(), m_listener_sp(listener_sp), m_breakpoint_site_list(), m_dynamic_checkers_up(), @@ -538,6 +599,8 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp, target_sp->GetPlatform()->GetDefaultMemoryCacheLineSize(); if (!value_sp->OptionWasSet() && platform_cache_line_size != 0) value_sp->SetUInt64Value(platform_cache_line_size); + + RegisterAssertFrameRecognizer(this); } Process::~Process() { @@ -597,6 +660,7 @@ void Process::Finalize() { m_system_runtime_up.reset(); m_dyld_up.reset(); m_jit_loaders_up.reset(); + m_thread_plans.Clear(); m_thread_list_real.Destroy(); m_thread_list.Destroy(); m_extended_thread_list.Destroy(); @@ -934,11 +998,17 @@ bool Process::HandleProcessStateChangedEvent(const EventSP &event_sp, Debugger &debugger = process_sp->GetTarget().GetDebugger(); if (debugger.GetTargetList().GetSelectedTarget().get() == &process_sp->GetTarget()) { + ThreadSP thread_sp = process_sp->GetThreadList().GetSelectedThread(); + + if (!thread_sp || !thread_sp->IsValid()) + return false; + const bool only_threads_with_stop_reason = true; - const uint32_t start_frame = 0; + const uint32_t start_frame = thread_sp->GetSelectedFrameIndex(); const uint32_t num_frames = 1; const uint32_t num_frames_with_source = 1; const bool stop_format = true; + process_sp->GetStatus(*stream); process_sp->GetThreadStatus(*stream, only_threads_with_stop_reason, start_frame, num_frames, @@ -949,14 +1019,11 @@ bool Process::HandleProcessStateChangedEvent(const EventSP &event_sp, ValueObjectSP valobj_sp = StopInfo::GetCrashingDereference( curr_thread_stop_info_sp, &crashing_address); if (valobj_sp) { - const bool qualify_cxx_base_classes = false; - const ValueObject::GetExpressionPathFormat format = ValueObject::GetExpressionPathFormat:: eGetExpressionPathFormatHonorPointers; stream->PutCString("Likely cause: "); - valobj_sp->GetExpressionPath(*stream, qualify_cxx_base_classes, - format); + valobj_sp->GetExpressionPath(*stream, format); stream->Printf(" accessed 0x%" PRIx64 "\n", crashing_address); } } @@ -1176,9 +1243,12 @@ void Process::UpdateThreadListIfNeeded() { const uint32_t stop_id = GetStopID(); if (m_thread_list.GetSize(false) == 0 || stop_id != m_thread_list.GetStopID()) { + bool clear_unused_threads = true; const StateType state = GetPrivateState(); if (StateIsStoppedState(state, true)) { std::lock_guard guard(m_thread_list.GetMutex()); + m_thread_list.SetStopID(stop_id); + // m_thread_list does have its own mutex, but we need to hold onto the // mutex between the call to UpdateThreadList(...) and the // os->UpdateThreadList(...) so it doesn't change on us @@ -1199,6 +1269,10 @@ void Process::UpdateThreadListIfNeeded() { size_t num_old_threads = old_thread_list.GetSize(false); for (size_t i = 0; i < num_old_threads; ++i) old_thread_list.GetThreadAtIndex(i, false)->ClearBackingThread(); + // See if the OS plugin reports all threads. If it does, then + // it is safe to clear unseen thread's plans here. Otherwise we + // should preserve them in case they show up again: + clear_unused_threads = GetOSPluginReportsAllThreads(); // Turn off dynamic types to ensure we don't run any expressions. // Objective-C can run an expression to determine if a SBValue is a @@ -1225,7 +1299,7 @@ void Process::UpdateThreadListIfNeeded() { target.SetPreferDynamicValue(saved_prefer_dynamic); } else { // No OS plug-in, the new thread list is the same as the real thread - // list + // list. new_thread_list = real_thread_list; } @@ -1242,10 +1316,42 @@ void Process::UpdateThreadListIfNeeded() { m_queue_list_stop_id = GetLastNaturalStopID(); } } + // Now update the plan stack map. + // If we do have an OS plugin, any absent real threads in the + // m_thread_list have already been removed from the ThreadPlanStackMap. + // So any remaining threads are OS Plugin threads, and those we want to + // preserve in case they show up again. + m_thread_plans.Update(m_thread_list, clear_unused_threads); } } } +ThreadPlanStack *Process::FindThreadPlans(lldb::tid_t tid) { + return m_thread_plans.Find(tid); +} + +bool Process::PruneThreadPlansForTID(lldb::tid_t tid) { + return m_thread_plans.PrunePlansForTID(tid); +} + +void Process::PruneThreadPlans() { + m_thread_plans.Update(GetThreadList(), true, false); +} + +bool Process::DumpThreadPlansForTID(Stream &strm, lldb::tid_t tid, + lldb::DescriptionLevel desc_level, + bool internal, bool condense_trivial, + bool skip_unreported_plans) { + return m_thread_plans.DumpPlansForTID( + strm, tid, desc_level, internal, condense_trivial, skip_unreported_plans); +} +void Process::DumpThreadPlans(Stream &strm, lldb::DescriptionLevel desc_level, + bool internal, bool condense_trivial, + bool skip_unreported_plans) { + m_thread_plans.DumpPlans(strm, desc_level, internal, condense_trivial, + skip_unreported_plans); +} + void Process::UpdateQueueListIfNeeded() { if (m_system_runtime_up) { if (m_queue_list.GetSize() == 0 || @@ -2643,7 +2749,7 @@ DataExtractor Process::GetAuxvData() { return DataExtractor(); } JITLoaderList &Process::GetJITLoaders() { if (!m_jit_loaders_up) { - m_jit_loaders_up.reset(new JITLoaderList()); + m_jit_loaders_up = std::make_unique(); JITLoader::LoadPlugins(this, *m_jit_loaders_up); } return *m_jit_loaders_up; @@ -2793,9 +2899,9 @@ Status Process::Attach(ProcessAttachInfo &attach_info) { match_info.GetProcessInfo() = attach_info; match_info.SetNameMatchType(NameMatch::Equals); platform_sp->FindProcesses(match_info, process_infos); - const uint32_t num_matches = process_infos.GetSize(); + const uint32_t num_matches = process_infos.size(); if (num_matches == 1) { - attach_pid = process_infos.GetProcessIDAtIndex(0); + attach_pid = process_infos[0].GetProcessID(); // Fall through and attach using the above process ID } else { match_info.GetProcessInfo().GetExecutableFile().GetPath( @@ -2804,7 +2910,7 @@ Status Process::Attach(ProcessAttachInfo &attach_info) { StreamString s; ProcessInstanceInfo::DumpTableHeader(s, true, false); for (size_t i = 0; i < num_matches; i++) { - process_infos.GetProcessInfoAtIndex(i).DumpAsTableRow( + process_infos[i].DumpAsTableRow( s, platform_sp->GetUserIDResolver(), true, false); } error.SetErrorStringWithFormat( @@ -2990,14 +3096,14 @@ void Process::CompleteAttach() { } } -Status Process::ConnectRemote(Stream *strm, llvm::StringRef remote_url) { +Status Process::ConnectRemote(llvm::StringRef remote_url) { m_abi_sp.reset(); m_process_input_reader.reset(); // Find the process and its architecture. Make sure it matches the // architecture of the current Target, and if not adjust it. - Status error(DoConnectRemote(strm, remote_url)); + Status error(DoConnectRemote(remote_url)); if (error.Success()) { if (GetID() != LLDB_INVALID_PROCESS_ID) { EventSP event_sp; @@ -3225,6 +3331,10 @@ Status Process::Detach(bool keep_stopped) { } Status Process::Destroy(bool force_kill) { + // If we've already called Process::Finalize then there's nothing useful to + // be done here. Finalize has actually called Destroy already. + if (m_finalize_called) + return {}; // Tell ourselves we are in the process of destroying the process, so that we // don't do any unnecessary work that might hinder the destruction. Remember @@ -3265,8 +3375,8 @@ Status Process::Destroy(bool force_kill) { DidDestroy(); StopPrivateStateThread(); } - m_stdio_communication.Disconnect(); m_stdio_communication.StopReadThread(); + m_stdio_communication.Disconnect(); m_stdin_forward = false; if (m_process_input_reader) { @@ -3335,8 +3445,8 @@ bool Process::ShouldBroadcastEvent(Event *event_ptr) { case eStateExited: case eStateUnloaded: m_stdio_communication.SynchronizeWithReadThread(); - m_stdio_communication.Disconnect(); m_stdio_communication.StopReadThread(); + m_stdio_communication.Disconnect(); m_stdin_forward = false; LLVM_FALLTHROUGH; @@ -3889,6 +3999,114 @@ ConstString Process::ProcessEventData::GetFlavor() const { return ProcessEventData::GetFlavorString(); } +bool Process::ProcessEventData::ShouldStop(Event *event_ptr, + bool &found_valid_stopinfo) { + found_valid_stopinfo = false; + + ProcessSP process_sp(m_process_wp.lock()); + if (!process_sp) + return false; + + ThreadList &curr_thread_list = process_sp->GetThreadList(); + uint32_t num_threads = curr_thread_list.GetSize(); + uint32_t idx; + + // The actions might change one of the thread's stop_info's opinions about + // whether we should stop the process, so we need to query that as we go. + + // One other complication here, is that we try to catch any case where the + // target has run (except for expressions) and immediately exit, but if we + // get that wrong (which is possible) then the thread list might have + // changed, and that would cause our iteration here to crash. We could + // make a copy of the thread list, but we'd really like to also know if it + // has changed at all, so we make up a vector of the thread ID's and check + // what we get back against this list & bag out if anything differs. + ThreadList not_suspended_thread_list(process_sp.get()); + std::vector thread_index_array(num_threads); + uint32_t not_suspended_idx = 0; + for (idx = 0; idx < num_threads; ++idx) { + lldb::ThreadSP thread_sp = curr_thread_list.GetThreadAtIndex(idx); + + /* + Filter out all suspended threads, they could not be the reason + of stop and no need to perform any actions on them. + */ + if (thread_sp->GetResumeState() != eStateSuspended) { + not_suspended_thread_list.AddThread(thread_sp); + thread_index_array[not_suspended_idx] = thread_sp->GetIndexID(); + not_suspended_idx++; + } + } + + // Use this to track whether we should continue from here. We will only + // continue the target running if no thread says we should stop. Of course + // if some thread's PerformAction actually sets the target running, then it + // doesn't matter what the other threads say... + + bool still_should_stop = false; + + // Sometimes - for instance if we have a bug in the stub we are talking to, + // we stop but no thread has a valid stop reason. In that case we should + // just stop, because we have no way of telling what the right thing to do + // is, and it's better to let the user decide than continue behind their + // backs. + + for (idx = 0; idx < not_suspended_thread_list.GetSize(); ++idx) { + curr_thread_list = process_sp->GetThreadList(); + if (curr_thread_list.GetSize() != num_threads) { + Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP | + LIBLLDB_LOG_PROCESS)); + LLDB_LOGF( + log, + "Number of threads changed from %u to %u while processing event.", + num_threads, curr_thread_list.GetSize()); + break; + } + + lldb::ThreadSP thread_sp = not_suspended_thread_list.GetThreadAtIndex(idx); + + if (thread_sp->GetIndexID() != thread_index_array[idx]) { + Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP | + LIBLLDB_LOG_PROCESS)); + LLDB_LOGF(log, + "The thread at position %u changed from %u to %u while " + "processing event.", + idx, thread_index_array[idx], thread_sp->GetIndexID()); + break; + } + + StopInfoSP stop_info_sp = thread_sp->GetStopInfo(); + if (stop_info_sp && stop_info_sp->IsValid()) { + found_valid_stopinfo = true; + bool this_thread_wants_to_stop; + if (stop_info_sp->GetOverrideShouldStop()) { + this_thread_wants_to_stop = + stop_info_sp->GetOverriddenShouldStopValue(); + } else { + stop_info_sp->PerformAction(event_ptr); + // The stop action might restart the target. If it does, then we + // want to mark that in the event so that whoever is receiving it + // will know to wait for the running event and reflect that state + // appropriately. We also need to stop processing actions, since they + // aren't expecting the target to be running. + + // FIXME: we might have run. + if (stop_info_sp->HasTargetRunSinceMe()) { + SetRestarted(true); + break; + } + + this_thread_wants_to_stop = stop_info_sp->ShouldStop(event_ptr); + } + + if (!still_should_stop) + still_should_stop = this_thread_wants_to_stop; + } + } + + return still_should_stop; +} + void Process::ProcessEventData::DoOnRemoval(Event *event_ptr) { ProcessSP process_sp(m_process_wp.lock()); @@ -3923,121 +4141,40 @@ void Process::ProcessEventData::DoOnRemoval(Event *event_ptr) { if (m_interrupted) return; - // If we're stopped and haven't restarted, then do the StopInfo actions here: - if (m_state == eStateStopped && !m_restarted) { - ThreadList &curr_thread_list = process_sp->GetThreadList(); - uint32_t num_threads = curr_thread_list.GetSize(); - uint32_t idx; - - // The actions might change one of the thread's stop_info's opinions about - // whether we should stop the process, so we need to query that as we go. - - // One other complication here, is that we try to catch any case where the - // target has run (except for expressions) and immediately exit, but if we - // get that wrong (which is possible) then the thread list might have - // changed, and that would cause our iteration here to crash. We could - // make a copy of the thread list, but we'd really like to also know if it - // has changed at all, so we make up a vector of the thread ID's and check - // what we get back against this list & bag out if anything differs. - std::vector thread_index_array(num_threads); - for (idx = 0; idx < num_threads; ++idx) - thread_index_array[idx] = - curr_thread_list.GetThreadAtIndex(idx)->GetIndexID(); - - // Use this to track whether we should continue from here. We will only - // continue the target running if no thread says we should stop. Of course - // if some thread's PerformAction actually sets the target running, then it - // doesn't matter what the other threads say... - - bool still_should_stop = false; - - // Sometimes - for instance if we have a bug in the stub we are talking to, - // we stop but no thread has a valid stop reason. In that case we should - // just stop, because we have no way of telling what the right thing to do - // is, and it's better to let the user decide than continue behind their - // backs. - - bool does_anybody_have_an_opinion = false; - - for (idx = 0; idx < num_threads; ++idx) { - curr_thread_list = process_sp->GetThreadList(); - if (curr_thread_list.GetSize() != num_threads) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP | - LIBLLDB_LOG_PROCESS)); - LLDB_LOGF( - log, - "Number of threads changed from %u to %u while processing event.", - num_threads, curr_thread_list.GetSize()); - break; - } - - lldb::ThreadSP thread_sp = curr_thread_list.GetThreadAtIndex(idx); - - if (thread_sp->GetIndexID() != thread_index_array[idx]) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP | - LIBLLDB_LOG_PROCESS)); - LLDB_LOGF(log, - "The thread at position %u changed from %u to %u while " - "processing event.", - idx, thread_index_array[idx], thread_sp->GetIndexID()); - break; - } - - StopInfoSP stop_info_sp = thread_sp->GetStopInfo(); - if (stop_info_sp && stop_info_sp->IsValid()) { - does_anybody_have_an_opinion = true; - bool this_thread_wants_to_stop; - if (stop_info_sp->GetOverrideShouldStop()) { - this_thread_wants_to_stop = - stop_info_sp->GetOverriddenShouldStopValue(); - } else { - stop_info_sp->PerformAction(event_ptr); - // The stop action might restart the target. If it does, then we - // want to mark that in the event so that whoever is receiving it - // will know to wait for the running event and reflect that state - // appropriately. We also need to stop processing actions, since they - // aren't expecting the target to be running. - - // FIXME: we might have run. - if (stop_info_sp->HasTargetRunSinceMe()) { - SetRestarted(true); - break; - } + // If we're not stopped or have restarted, then skip the StopInfo actions: + if (m_state != eStateStopped || m_restarted) { + return; + } - this_thread_wants_to_stop = stop_info_sp->ShouldStop(event_ptr); - } + bool does_anybody_have_an_opinion = false; + bool still_should_stop = ShouldStop(event_ptr, does_anybody_have_an_opinion); - if (!still_should_stop) - still_should_stop = this_thread_wants_to_stop; - } - } + if (GetRestarted()) { + return; + } - if (!GetRestarted()) { - if (!still_should_stop && does_anybody_have_an_opinion) { - // We've been asked to continue, so do that here. + if (!still_should_stop && does_anybody_have_an_opinion) { + // We've been asked to continue, so do that here. + SetRestarted(true); + // Use the public resume method here, since this is just extending a + // public resume. + process_sp->PrivateResume(); + } else { + bool hijacked = process_sp->IsHijackedForEvent(eBroadcastBitStateChanged) && + !process_sp->StateChangedIsHijackedForSynchronousResume(); + + if (!hijacked) { + // If we didn't restart, run the Stop Hooks here. + // Don't do that if state changed events aren't hooked up to the + // public (or SyncResume) broadcasters. StopHooks are just for + // real public stops. They might also restart the target, + // so watch for that. + process_sp->GetTarget().RunStopHooks(); + if (process_sp->GetPrivateState() == eStateRunning) SetRestarted(true); - // Use the public resume method here, since this is just extending a - // public resume. - process_sp->PrivateResume(); - } else { - bool hijacked = - process_sp->IsHijackedForEvent(eBroadcastBitStateChanged) && - !process_sp->StateChangedIsHijackedForSynchronousResume(); - - if (!hijacked) { - // If we didn't restart, run the Stop Hooks here. - // Don't do that if state changed events aren't hooked up to the - // public (or SyncResume) broadcasters. StopHooks are just for - // real public stops. They might also restart the target, - // so watch for that. - process_sp->GetTarget().RunStopHooks(); - if (process_sp->GetPrivateState() == eStateRunning) - SetRestarted(true); - } } } } -} void Process::ProcessEventData::Dump(Stream *s) const { ProcessSP process_sp(m_process_wp.lock()); @@ -4422,23 +4559,18 @@ protected: void Process::SetSTDIOFileDescriptor(int fd) { // First set up the Read Thread for reading/handling process I/O + m_stdio_communication.SetConnection( + std::make_unique(fd, true)); + if (m_stdio_communication.IsConnected()) { + m_stdio_communication.SetReadThreadBytesReceivedCallback( + STDIOReadThreadBytesReceived, this); + m_stdio_communication.StartReadThread(); - std::unique_ptr conn_up( - new ConnectionFileDescriptor(fd, true)); - - if (conn_up) { - m_stdio_communication.SetConnection(conn_up.release()); - if (m_stdio_communication.IsConnected()) { - m_stdio_communication.SetReadThreadBytesReceivedCallback( - STDIOReadThreadBytesReceived, this); - m_stdio_communication.StartReadThread(); + // Now read thread is set up, set up input reader. - // Now read thread is set up, set up input reader. - - if (!m_process_input_reader) - m_process_input_reader = - std::make_shared(this, fd); - } + if (!m_process_input_reader) + m_process_input_reader = + std::make_shared(this, fd); } } @@ -4460,7 +4592,8 @@ bool Process::PushProcessIOHandler() { // 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); + GetTarget().GetDebugger().RunIOHandlerAsync(io_handler_sp, + cancel_top_handler); return true; } return false; @@ -4469,7 +4602,7 @@ bool Process::PushProcessIOHandler() { bool Process::PopProcessIOHandler() { IOHandlerSP io_handler_sp(m_process_input_reader); if (io_handler_sp) - return GetTarget().GetDebugger().PopIOHandler(io_handler_sp); + return GetTarget().GetDebugger().RemoveIOHandler(io_handler_sp); return false; } @@ -4553,13 +4686,27 @@ GetExpressionTimeout(const EvaluateExpressionOptions &options, } static llvm::Optional -HandleStoppedEvent(Thread &thread, const ThreadPlanSP &thread_plan_sp, +HandleStoppedEvent(lldb::tid_t thread_id, const ThreadPlanSP &thread_plan_sp, RestorePlanState &restorer, const EventSP &event_sp, EventSP &event_to_broadcast_sp, - const EvaluateExpressionOptions &options, bool handle_interrupts) { + const EvaluateExpressionOptions &options, + bool handle_interrupts) { Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP | LIBLLDB_LOG_PROCESS); - ThreadPlanSP plan = thread.GetCompletedPlan(); + ThreadSP thread_sp = thread_plan_sp->GetTarget() + .GetProcessSP() + ->GetThreadList() + .FindThreadByID(thread_id); + if (!thread_sp) { + LLDB_LOG(log, + "The thread on which we were running the " + "expression: tid = {0}, exited while " + "the expression was running.", + thread_id); + return eExpressionThreadVanished; + } + + ThreadPlanSP plan = thread_sp->GetCompletedPlan(); if (plan == thread_plan_sp && plan->PlanSucceeded()) { LLDB_LOG(log, "execution completed successfully"); @@ -4569,7 +4716,7 @@ HandleStoppedEvent(Thread &thread, const ThreadPlanSP &thread_plan_sp, return eExpressionCompleted; } - StopInfoSP stop_info_sp = thread.GetStopInfo(); + StopInfoSP stop_info_sp = thread_sp->GetStopInfo(); if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint && stop_info_sp->ShouldNotify(event_sp.get())) { LLDB_LOG(log, "stopped for breakpoint: {0}.", stop_info_sp->GetDescription()); @@ -4631,6 +4778,10 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, return eExpressionSetupError; } + // Record the thread's id so we can tell when a thread we were using + // to run the expression exits during the expression evaluation. + lldb::tid_t expr_thread_id = thread->GetID(); + // We need to change some of the thread plan attributes for the thread plan // runner. This will restore them when we are done: @@ -4775,7 +4926,7 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, LLDB_LOGF(log, "Process::RunThreadPlan(): Resuming thread %u - 0x%4.4" PRIx64 " to run thread plan \"%s\".", - thread->GetIndexID(), thread->GetID(), s.GetData()); + thread_idx_id, expr_thread_id, s.GetData()); } bool got_event; @@ -4975,33 +5126,23 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, switch (stop_state) { case lldb::eStateStopped: { - // We stopped, figure out what we are going to do now. - ThreadSP thread_sp = - GetThreadList().FindThreadByIndexID(thread_idx_id); - if (!thread_sp) { - // Ooh, our thread has vanished. Unlikely that this was - // successful execution... - LLDB_LOGF(log, - "Process::RunThreadPlan(): execution completed " - "but our thread (index-id=%u) has vanished.", - thread_idx_id); - return_value = eExpressionInterrupted; - } else if (Process::ProcessEventData::GetRestartedFromEvent( - event_sp.get())) { + if (Process::ProcessEventData::GetRestartedFromEvent( + event_sp.get())) { // If we were restarted, we just need to go back up to fetch // another event. - if (log) { - LLDB_LOGF(log, "Process::RunThreadPlan(): Got a stop and " - "restart, so we'll continue waiting."); - } + LLDB_LOGF(log, "Process::RunThreadPlan(): Got a stop and " + "restart, so we'll continue waiting."); keep_going = true; do_resume = false; handle_running_event = true; } else { const bool handle_interrupts = true; return_value = *HandleStoppedEvent( - *thread, thread_plan_sp, thread_plan_restorer, event_sp, - event_to_broadcast_sp, options, handle_interrupts); + expr_thread_id, thread_plan_sp, thread_plan_restorer, + event_sp, event_to_broadcast_sp, options, + handle_interrupts); + if (return_value == eExpressionThreadVanished) + keep_going = false; } } break; @@ -5123,8 +5264,9 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, // job. Check that here: const bool handle_interrupts = false; if (auto result = HandleStoppedEvent( - *thread, thread_plan_sp, thread_plan_restorer, event_sp, - event_to_broadcast_sp, options, handle_interrupts)) { + expr_thread_id, thread_plan_sp, thread_plan_restorer, + event_sp, event_to_broadcast_sp, options, + handle_interrupts)) { return_value = *result; back_to_top = false; break; @@ -5196,6 +5338,13 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, m_public_state.SetValueNoLock(old_state); } + // If our thread went away on us, we need to get out of here without + // doing any more work. We don't have to clean up the thread plan, that + // will have happened when the Thread was destroyed. + if (return_value == eExpressionThreadVanished) { + return return_value; + } + if (return_value != eExpressionCompleted && log) { // Print a backtrace into the log so we can figure out where we are: StreamString s; @@ -5384,7 +5533,7 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, } const char *Process::ExecutionResultAsCString(ExpressionResults result) { - const char *result_name; + const char *result_name = ""; switch (result) { case eExpressionCompleted: @@ -5414,6 +5563,8 @@ const char *Process::ExecutionResultAsCString(ExpressionResults result) { case eExpressionStoppedForDebug: result_name = "eExpressionStoppedForDebug"; break; + case eExpressionThreadVanished: + result_name = "eExpressionThreadVanished"; } return result_name; } @@ -5662,9 +5813,6 @@ void Process::PrintWarning(uint64_t warning_type, const void *repeat_key, StreamSP stream_sp = GetTarget().GetDebugger().GetAsyncOutputStream(); if (!stream_sp) return; - if (warning_type == eWarningsOptimization && !GetWarningsOptimization()) { - return; - } if (repeat_key != nullptr) { WarningsCollection::iterator it = m_warnings_issued.find(warning_type); @@ -5689,8 +5837,11 @@ void Process::PrintWarning(uint64_t warning_type, const void *repeat_key, } void Process::PrintWarningOptimization(const SymbolContext &sc) { - if (GetWarningsOptimization() && sc.module_sp && - !sc.module_sp->GetFileSpec().GetFilename().IsEmpty() && sc.function && + if (!GetWarningsOptimization()) + return; + if (!sc.module_sp) + return; + if (!sc.module_sp->GetFileSpec().GetFilename().IsEmpty() && sc.function && sc.function->GetIsOptimized()) { PrintWarning(Process::Warnings::eWarningsOptimization, sc.module_sp.get(), "%s was compiled with optimization - stepping may behave " @@ -5699,6 +5850,25 @@ void Process::PrintWarningOptimization(const SymbolContext &sc) { } } +void Process::PrintWarningUnsupportedLanguage(const SymbolContext &sc) { + if (!GetWarningsUnsupportedLanguage()) + return; + if (!sc.module_sp) + return; + LanguageType language = sc.GetLanguage(); + if (language == eLanguageTypeUnknown) + return; + auto type_system_or_err = sc.module_sp->GetTypeSystemForLanguage(language); + if (auto err = type_system_or_err.takeError()) { + llvm::consumeError(std::move(err)); + PrintWarning(Process::Warnings::eWarningsUnsupportedLanguage, + sc.module_sp.get(), + "This version of LLDB has no plugin for the %s language. " + "Inspection of frame variables will be limited.\n", + Language::GetNameForLanguageType(language)); + } +} + bool Process::GetProcessInfo(ProcessInstanceInfo &info) { info.Clear(); @@ -5749,12 +5919,12 @@ size_t Process::AddImageToken(lldb::addr_t image_ptr) { lldb::addr_t Process::GetImagePtrFromToken(size_t token) const { if (token < m_image_tokens.size()) return m_image_tokens[token]; - return LLDB_INVALID_IMAGE_TOKEN; + return LLDB_INVALID_ADDRESS; } void Process::ResetImageToken(size_t token) { if (token < m_image_tokens.size()) - m_image_tokens[token] = LLDB_INVALID_IMAGE_TOKEN; + m_image_tokens[token] = LLDB_INVALID_ADDRESS; } Address @@ -5771,12 +5941,11 @@ Process::AdvanceAddressToNextBranchInstruction(Address default_stop_addr, if (!default_stop_addr.IsValid()) return retval; - ExecutionContext exe_ctx(this); const char *plugin_name = nullptr; const char *flavor = nullptr; const bool prefer_file_cache = true; disassembler_sp = Disassembler::DisassembleRange( - target.GetArchitecture(), plugin_name, flavor, exe_ctx, range_bounds, + target.GetArchitecture(), plugin_name, flavor, GetTarget(), range_bounds, prefer_file_cache); if (disassembler_sp) insn_list = &disassembler_sp->GetInstructionList(); diff --git a/gnu/llvm/lldb/source/Target/Queue.cpp b/gnu/llvm/lldb/source/Target/Queue.cpp index fc2a93dbe89..67eae632767 100644 --- a/gnu/llvm/lldb/source/Target/Queue.cpp +++ b/gnu/llvm/lldb/source/Target/Queue.cpp @@ -1,4 +1,4 @@ -//===-- Queue.cpp -----------------------------------------------*- C++ -*-===// +//===-- Queue.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/QueueItem.cpp b/gnu/llvm/lldb/source/Target/QueueItem.cpp index 47ff9e028fc..740b2a6771a 100644 --- a/gnu/llvm/lldb/source/Target/QueueItem.cpp +++ b/gnu/llvm/lldb/source/Target/QueueItem.cpp @@ -1,4 +1,4 @@ -//===-- QueueItem.cpp -------------------------------------------*- C++ -*-===// +//===-- QueueItem.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/QueueList.cpp b/gnu/llvm/lldb/source/Target/QueueList.cpp index 79682513518..84ec24f03f5 100644 --- a/gnu/llvm/lldb/source/Target/QueueList.cpp +++ b/gnu/llvm/lldb/source/Target/QueueList.cpp @@ -1,4 +1,4 @@ -//===-- QueueList.cpp -------------------------------------------*- C++ -*-===// +//===-- QueueList.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/RegisterContext.cpp b/gnu/llvm/lldb/source/Target/RegisterContext.cpp index f29cf435d02..cdc7653cea6 100644 --- a/gnu/llvm/lldb/source/Target/RegisterContext.cpp +++ b/gnu/llvm/lldb/source/Target/RegisterContext.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContext.cpp -------------------------------------*- C++ -*-===// +//===-- RegisterContext.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -274,6 +274,24 @@ uint32_t RegisterContext::SetHardwareBreakpoint(lldb::addr_t addr, return LLDB_INVALID_INDEX32; } +// Used when parsing DWARF and EH frame information and any other object file +// sections that contain register numbers in them. +uint32_t +RegisterContext::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) { + const uint32_t num_regs = GetRegisterCount(); + + assert(kind < kNumRegisterKinds); + for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { + const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx); + + if (reg_info->kinds[kind] == num) + return reg_idx; + } + + return LLDB_INVALID_REGNUM; +} + bool RegisterContext::ClearHardwareBreakpoint(uint32_t hw_idx) { return false; } uint32_t RegisterContext::NumSupportedHardwareWatchpoints() { return 0; } @@ -397,6 +415,17 @@ Status RegisterContext::WriteRegisterValueToMemory( return error; } +lldb::ByteOrder RegisterContext::GetByteOrder() { + // Get the target process whose privileged thread was used for the register + // read. + lldb::ByteOrder byte_order = lldb::eByteOrderInvalid; + lldb_private::Process *process = CalculateProcess().get(); + + if (process) + byte_order = process->GetByteOrder(); + return byte_order; +} + bool RegisterContext::ReadAllRegisterValues( lldb_private::RegisterCheckpoint ®_checkpoint) { return ReadAllRegisterValues(reg_checkpoint.GetData()); diff --git a/gnu/llvm/lldb/source/Target/RegisterContextUnwind.cpp b/gnu/llvm/lldb/source/Target/RegisterContextUnwind.cpp new file mode 100644 index 00000000000..f33f4180be2 --- /dev/null +++ b/gnu/llvm/lldb/source/Target/RegisterContextUnwind.cpp @@ -0,0 +1,2215 @@ +//===-- RegisterContextUnwind.cpp -----------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/RegisterContextUnwind.h" +#include "lldb/Core/Address.h" +#include "lldb/Core/AddressRange.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/Value.h" +#include "lldb/Expression/DWARFExpression.h" +#include "lldb/Symbol/ArmUnwindInfo.h" +#include "lldb/Symbol/CallFrameInfo.h" +#include "lldb/Symbol/DWARFCallFrameInfo.h" +#include "lldb/Symbol/FuncUnwinders.h" +#include "lldb/Symbol/Function.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/SymbolFile.h" +#include "lldb/Target/ABI.h" +#include "lldb/Target/DynamicLoader.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Platform.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/SectionLoadList.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#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 + +using namespace lldb; +using namespace lldb_private; + +static ConstString GetSymbolOrFunctionName(const SymbolContext &sym_ctx) { + if (sym_ctx.symbol) + return sym_ctx.symbol->GetName(); + else if (sym_ctx.function) + return sym_ctx.function->GetName(); + return ConstString(); +} + +RegisterContextUnwind::RegisterContextUnwind(Thread &thread, + const SharedPtr &next_frame, + SymbolContext &sym_ctx, + uint32_t frame_number, + UnwindLLDB &unwind_lldb) + : 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_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) { + m_sym_ctx.Clear(false); + m_sym_ctx_valid = false; + + if (IsFrameZero()) { + InitializeZerothFrame(); + } else { + InitializeNonZerothFrame(); + } + + // This same code exists over in the GetFullUnwindPlanForFrame() but it may + // not have been executed yet + if (IsFrameZero() || next_frame->m_frame_type == eTrapHandlerFrame || + next_frame->m_frame_type == eDebuggerFrame) { + m_all_registers_available = true; + } +} + +bool RegisterContextUnwind::IsUnwindPlanValidForCurrentPC( + lldb::UnwindPlanSP unwind_plan_sp, int &valid_pc_offset) { + if (!unwind_plan_sp) + return false; + + // check if m_current_pc is valid + if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { + // yes - current offset can be used as is + valid_pc_offset = m_current_offset; + return true; + } + + // if m_current_offset <= 0, we've got nothing else to try + if (m_current_offset <= 0) + return false; + + // check pc - 1 to see if it's valid + Address pc_minus_one(m_current_pc); + pc_minus_one.SetOffset(m_current_pc.GetOffset() - 1); + if (unwind_plan_sp->PlanValidAtAddress(pc_minus_one)) { + // *valid_pc_offset = m_current_offset - 1; + valid_pc_offset = m_current_pc.GetOffset() - 1; + return true; + } + + return false; +} + +// Initialize a RegisterContextUnwind which is the first frame of a stack -- the +// zeroth frame or currently executing frame. + +void RegisterContextUnwind::InitializeZerothFrame() { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + ExecutionContext exe_ctx(m_thread.shared_from_this()); + RegisterContextSP reg_ctx_sp = m_thread.GetRegisterContext(); + + if (reg_ctx_sp.get() == nullptr) { + m_frame_type = eNotAValidFrame; + UnwindLogMsg("frame does not have a register context"); + return; + } + + addr_t current_pc = reg_ctx_sp->GetPC(); + + if (current_pc == LLDB_INVALID_ADDRESS) { + m_frame_type = eNotAValidFrame; + UnwindLogMsg("frame does not have a pc"); + return; + } + + Process *process = exe_ctx.GetProcessPtr(); + + // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs + // this will strip bit zero in case we read a PC from memory or from the LR. + // (which would be a no-op in frame 0 where we get it from the register set, + // but still a good idea to make the call here for other ABIs that may + // exist.) + ABI *abi = process->GetABI().get(); + if (abi) + current_pc = abi->FixCodeAddress(current_pc); + + // Initialize m_current_pc, an Address object, based on current_pc, an + // addr_t. + m_current_pc.SetLoadAddress(current_pc, &process->GetTarget()); + + // If we don't have a Module for some reason, we're not going to find + // symbol/function information - just stick in some reasonable defaults and + // hope we can unwind past this frame. + ModuleSP pc_module_sp(m_current_pc.GetModule()); + if (!m_current_pc.IsValid() || !pc_module_sp) { + UnwindLogMsg("using architectural default unwind method"); + } + + AddressRange addr_range; + m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range); + + if (m_sym_ctx.symbol) { + UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'", + current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); + } else if (m_sym_ctx.function) { + UnwindLogMsg("with pc value of 0x%" PRIx64 ", function name is '%s'", + current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); + } else { + UnwindLogMsg("with pc value of 0x%" PRIx64 + ", no symbol/function name is known.", + current_pc); + } + + if (IsTrapHandlerSymbol(process, m_sym_ctx)) { + m_frame_type = eTrapHandlerFrame; + } else { + // FIXME: Detect eDebuggerFrame here. + m_frame_type = eNormalFrame; + } + + // If we were able to find a symbol/function, set addr_range to the bounds of + // that symbol/function. else treat the current pc value as the start_pc and + // record no offset. + if (addr_range.GetBaseAddress().IsValid()) { + m_start_pc = addr_range.GetBaseAddress(); + if (m_current_pc.GetSection() == m_start_pc.GetSection()) { + m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset(); + } else if (m_current_pc.GetModule() == m_start_pc.GetModule()) { + // This means that whatever symbol we kicked up isn't really correct --- + // we should not cross section boundaries ... We really should NULL out + // the function/symbol in this case unless there is a bad assumption here + // due to inlined functions? + m_current_offset = + m_current_pc.GetFileAddress() - m_start_pc.GetFileAddress(); + } + m_current_offset_backed_up_one = m_current_offset; + } else { + m_start_pc = m_current_pc; + m_current_offset = -1; + m_current_offset_backed_up_one = -1; + } + + // We've set m_frame_type and m_sym_ctx before these calls. + + m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame(); + m_full_unwind_plan_sp = GetFullUnwindPlanForFrame(); + + UnwindPlan::RowSP active_row; + lldb::RegisterKind row_register_kind = eRegisterKindGeneric; + if (m_full_unwind_plan_sp && + m_full_unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { + active_row = + m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); + row_register_kind = m_full_unwind_plan_sp->GetRegisterKind(); + if (active_row.get() && log) { + StreamString active_row_strm; + active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, + m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); + UnwindLogMsg("%s", active_row_strm.GetData()); + } + } + + if (!active_row.get()) { + UnwindLogMsg("could not find an unwindplan row for this frame's pc"); + m_frame_type = eNotAValidFrame; + return; + } + + 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; + UnwindPlanSP call_site_unwind_plan; + bool cfa_status = false; + + if (m_sym_ctx_valid) { + func_unwinders_sp = + pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress( + m_current_pc, m_sym_ctx); + } + + if (func_unwinders_sp.get() != nullptr) + call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite( + process->GetTarget(), m_thread); + + if (call_site_unwind_plan.get() != nullptr) { + m_fallback_unwind_plan_sp = call_site_unwind_plan; + if (TryFallbackUnwindPlan()) + cfa_status = true; + } + if (!cfa_status) { + UnwindLogMsg("could not read CFA value for first frame."); + 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 + " 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()); +} + +// Initialize a RegisterContextUnwind for the non-zeroth frame -- rely on the +// RegisterContextUnwind "below" it to provide things like its current pc value. + +void RegisterContextUnwind::InitializeNonZerothFrame() { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + if (IsFrameZero()) { + m_frame_type = eNotAValidFrame; + UnwindLogMsg("non-zeroth frame tests positive for IsFrameZero -- that " + "shouldn't happen."); + return; + } + + if (!GetNextFrame().get() || !GetNextFrame()->IsValid()) { + m_frame_type = eNotAValidFrame; + UnwindLogMsg("Could not get next frame, marking this frame as invalid."); + return; + } + if (!m_thread.GetRegisterContext()) { + m_frame_type = eNotAValidFrame; + UnwindLogMsg("Could not get register context for this thread, marking this " + "frame as invalid."); + return; + } + + addr_t pc; + if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) { + UnwindLogMsg("could not get pc value"); + m_frame_type = eNotAValidFrame; + return; + } + + ExecutionContext exe_ctx(m_thread.shared_from_this()); + Process *process = exe_ctx.GetProcessPtr(); + // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs + // this will strip bit zero in case we read a PC from memory or from the LR. + ABI *abi = process->GetABI().get(); + if (abi) + pc = abi->FixCodeAddress(pc); + + if (log) { + UnwindLogMsg("pc = 0x%" PRIx64, pc); + addr_t reg_val; + if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val)) + UnwindLogMsg("fp = 0x%" PRIx64, reg_val); + if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val)) + UnwindLogMsg("sp = 0x%" PRIx64, reg_val); + } + + // A pc of 0x0 means it's the end of the stack crawl unless we're above a trap + // handler function + bool above_trap_handler = false; + if (GetNextFrame().get() && GetNextFrame()->IsValid() && + GetNextFrame()->IsTrapHandlerFrame()) + above_trap_handler = true; + + if (pc == 0 || pc == 0x1) { + if (!above_trap_handler) { + m_frame_type = eNotAValidFrame; + UnwindLogMsg("this frame has a pc of 0x0"); + return; + } + } + + const bool allow_section_end = true; + m_current_pc.SetLoadAddress(pc, &process->GetTarget(), allow_section_end); + + // If we don't have a Module for some reason, we're not going to find + // symbol/function information - just stick in some reasonable defaults and + // hope we can unwind past this frame. If we're above a trap handler, + // we may be at a bogus address because we jumped through a bogus function + // pointer and trapped, so don't force the arch default unwind plan in that + // case. + ModuleSP pc_module_sp(m_current_pc.GetModule()); + if ((!m_current_pc.IsValid() || !pc_module_sp) && + above_trap_handler == false) { + UnwindLogMsg("using architectural default unwind method"); + + // Test the pc value to see if we know it's in an unmapped/non-executable + // region of memory. + uint32_t permissions; + if (process->GetLoadAddressPermissions(pc, permissions) && + (permissions & ePermissionsExecutable) == 0) { + // If this is the second frame off the stack, we may have unwound the + // first frame incorrectly. But using the architecture default unwind + // plan may get us back on track -- albeit possibly skipping a real + // frame. Give this frame a clearly-invalid pc and see if we can get any + // further. + if (GetNextFrame().get() && GetNextFrame()->IsValid() && + GetNextFrame()->IsFrameZero()) { + UnwindLogMsg("had a pc of 0x%" PRIx64 " which is not in executable " + "memory but on frame 1 -- " + "allowing it once.", + (uint64_t)pc); + m_frame_type = eSkipFrame; + } else { + // anywhere other than the second frame, a non-executable pc means + // we're off in the weeds -- stop now. + m_frame_type = eNotAValidFrame; + UnwindLogMsg("pc is in a non-executable section of memory and this " + "isn't the 2nd frame in the stack walk."); + return; + } + } + + if (abi) { + m_fast_unwind_plan_sp.reset(); + m_full_unwind_plan_sp = + std::make_shared(lldb::eRegisterKindGeneric); + abi->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp); + if (m_frame_type != eSkipFrame) // don't override eSkipFrame + { + m_frame_type = eNormalFrame; + } + m_all_registers_available = false; + m_current_offset = -1; + m_current_offset_backed_up_one = -1; + RegisterKind row_register_kind = m_full_unwind_plan_sp->GetRegisterKind(); + UnwindPlan::RowSP row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0); + if (row.get()) { + if (!ReadFrameAddress(row_register_kind, row->GetCFAValue(), m_cfa)) { + UnwindLogMsg("failed to get cfa value"); + if (m_frame_type != eSkipFrame) // don't override eSkipFrame + { + m_frame_type = eNotAValidFrame; + } + 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"); + m_frame_type = eNotAValidFrame; + return; + } + + // m_cfa should point into the stack memory; if we can query memory + // region permissions, see if the memory is allocated & readable. + if (process->GetLoadAddressPermissions(m_cfa, permissions) && + (permissions & ePermissionsReadable) == 0) { + m_frame_type = eNotAValidFrame; + UnwindLogMsg( + "the CFA points to a region of memory that is not readable"); + return; + } + } else { + UnwindLogMsg("could not find a row for function offset zero"); + m_frame_type = eNotAValidFrame; + return; + } + + if (CheckIfLoopingStack()) { + TryFallbackUnwindPlan(); + if (CheckIfLoopingStack()) { + UnwindLogMsg("same CFA address as next frame, assuming the unwind is " + "looping - stopping"); + m_frame_type = eNotAValidFrame; + return; + } + } + + UnwindLogMsg("initialized frame cfa is 0x%" PRIx64 " afa is 0x%" PRIx64, + (uint64_t)m_cfa, (uint64_t)m_afa); + return; + } + m_frame_type = eNotAValidFrame; + UnwindLogMsg("could not find any symbol for this pc, or a default unwind " + "plan, to continue unwind."); + return; + } + + AddressRange addr_range; + m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range); + + if (m_sym_ctx.symbol) { + UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'", pc, + GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); + } else if (m_sym_ctx.function) { + UnwindLogMsg("with pc value of 0x%" PRIx64 ", function name is '%s'", pc, + GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); + } else { + UnwindLogMsg("with pc value of 0x%" PRIx64 + ", no symbol/function name is known.", + pc); + } + + bool decr_pc_and_recompute_addr_range; + + if (!m_sym_ctx_valid) { + // Always decrement and recompute if the symbol lookup failed + decr_pc_and_recompute_addr_range = true; + } else if (GetNextFrame()->m_frame_type == eTrapHandlerFrame || + GetNextFrame()->m_frame_type == eDebuggerFrame) { + // Don't decrement if we're "above" an asynchronous event like + // sigtramp. + decr_pc_and_recompute_addr_range = false; + } else if (!addr_range.GetBaseAddress().IsValid() || + addr_range.GetBaseAddress().GetSection() != m_current_pc.GetSection() || + addr_range.GetBaseAddress().GetOffset() != m_current_pc.GetOffset()) { + // If our "current" pc isn't the start of a function, no need + // to decrement and recompute. + decr_pc_and_recompute_addr_range = false; + } else if (IsTrapHandlerSymbol(process, m_sym_ctx)) { + // Signal dispatch may set the return address of the handler it calls to + // point to the first byte of a return trampoline (like __kernel_rt_sigreturn), + // so do not decrement and recompute if the symbol we already found is a trap + // handler. + decr_pc_and_recompute_addr_range = false; + } else { + // Decrement to find the function containing the call. + decr_pc_and_recompute_addr_range = true; + } + + // We need to back up the pc by 1 byte and re-search for the Symbol to handle + // the case where the "saved pc" value is pointing to the next function, e.g. + // if a function ends with a CALL instruction. + // FIXME this may need to be an architectural-dependent behavior; if so we'll + // need to add a member function + // to the ABI plugin and consult that. + if (decr_pc_and_recompute_addr_range) { + UnwindLogMsg("Backing up the pc value of 0x%" PRIx64 + " by 1 and re-doing symbol lookup; old symbol was %s", + pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); + Address temporary_pc; + temporary_pc.SetLoadAddress(pc - 1, &process->GetTarget()); + m_sym_ctx.Clear(false); + m_sym_ctx_valid = temporary_pc.ResolveFunctionScope(m_sym_ctx, &addr_range); + + UnwindLogMsg("Symbol is now %s", + GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); + } + + // If we were able to find a symbol/function, set addr_range_ptr to the + // bounds of that symbol/function. else treat the current pc value as the + // start_pc and record no offset. + if (addr_range.GetBaseAddress().IsValid()) { + m_start_pc = addr_range.GetBaseAddress(); + m_current_offset = pc - m_start_pc.GetLoadAddress(&process->GetTarget()); + m_current_offset_backed_up_one = m_current_offset; + if (decr_pc_and_recompute_addr_range && + m_current_offset_backed_up_one > 0) { + m_current_offset_backed_up_one--; + if (m_sym_ctx_valid) { + m_current_pc.SetLoadAddress(pc - 1, &process->GetTarget()); + } + } + } else { + m_start_pc = m_current_pc; + m_current_offset = -1; + m_current_offset_backed_up_one = -1; + } + + if (IsTrapHandlerSymbol(process, m_sym_ctx)) { + m_frame_type = eTrapHandlerFrame; + } else { + // FIXME: Detect eDebuggerFrame here. + if (m_frame_type != eSkipFrame) // don't override eSkipFrame + { + m_frame_type = eNormalFrame; + } + } + + // We've set m_frame_type and m_sym_ctx before this call. + m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame(); + + UnwindPlan::RowSP active_row; + RegisterKind row_register_kind = eRegisterKindGeneric; + + // Try to get by with just the fast UnwindPlan if possible - the full + // UnwindPlan may be expensive to get (e.g. if we have to parse the entire + // eh_frame section of an ObjectFile for the first time.) + + if (m_fast_unwind_plan_sp && + m_fast_unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { + active_row = + m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); + row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind(); + PropagateTrapHandlerFlagFromUnwindPlan(m_fast_unwind_plan_sp); + if (active_row.get() && log) { + StreamString active_row_strm; + active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread, + m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); + UnwindLogMsg("active row: %s", active_row_strm.GetData()); + } + } else { + m_full_unwind_plan_sp = GetFullUnwindPlanForFrame(); + int valid_offset = -1; + if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp, valid_offset)) { + active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset(valid_offset); + row_register_kind = m_full_unwind_plan_sp->GetRegisterKind(); + PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp); + if (active_row.get() && log) { + StreamString active_row_strm; + active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), + &m_thread, + m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); + UnwindLogMsg("active row: %s", active_row_strm.GetData()); + } + } + } + + if (!active_row.get()) { + m_frame_type = eNotAValidFrame; + UnwindLogMsg("could not find unwind row for this pc"); + return; + } + + if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), m_cfa)) { + UnwindLogMsg("failed to get cfa"); + m_frame_type = eNotAValidFrame; + return; + } + + 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(); + if (CheckIfLoopingStack()) { + UnwindLogMsg("same CFA address as next frame, assuming the unwind is " + "looping - stopping"); + m_frame_type = eNotAValidFrame; + return; + } + } + + UnwindLogMsg("initialized frame current pc 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_afa); +} + +bool RegisterContextUnwind::CheckIfLoopingStack() { + // If we have a bad stack setup, we can get the same CFA value multiple times + // -- or even more devious, we can actually oscillate between two CFA values. + // Detect that here and break out to avoid a possible infinite loop in lldb + // trying to unwind the stack. To detect when we have the same CFA value + // multiple times, we compare the + // CFA of the current + // frame with the 2nd next frame because in some specail case (e.g. signal + // hanlders, hand written assembly without ABI compliance) we can have 2 + // frames with the same + // CFA (in theory we + // can have arbitrary number of frames with the same CFA, but more then 2 is + // very very unlikely) + + RegisterContextUnwind::SharedPtr next_frame = GetNextFrame(); + if (next_frame) { + RegisterContextUnwind::SharedPtr next_next_frame = + next_frame->GetNextFrame(); + addr_t next_next_frame_cfa = LLDB_INVALID_ADDRESS; + if (next_next_frame && next_next_frame->GetCFA(next_next_frame_cfa)) { + if (next_next_frame_cfa == m_cfa) { + // We have a loop in the stack unwind + return true; + } + } + } + return false; +} + +bool RegisterContextUnwind::IsFrameZero() const { return m_frame_number == 0; } + +// Find a fast unwind plan for this frame, if possible. +// +// On entry to this method, +// +// 1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame +// if either of those are correct, +// 2. m_sym_ctx should already be filled in, and +// 3. m_current_pc should have the current pc value for this frame +// 4. m_current_offset_backed_up_one should have the current byte offset into +// the function, maybe backed up by 1, -1 if unknown + +UnwindPlanSP RegisterContextUnwind::GetFastUnwindPlanForFrame() { + UnwindPlanSP unwind_plan_sp; + ModuleSP pc_module_sp(m_current_pc.GetModule()); + + if (!m_current_pc.IsValid() || !pc_module_sp || + pc_module_sp->GetObjectFile() == nullptr) + return unwind_plan_sp; + + if (IsFrameZero()) + return unwind_plan_sp; + + FuncUnwindersSP func_unwinders_sp( + pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress( + m_current_pc, m_sym_ctx)); + if (!func_unwinders_sp) + return unwind_plan_sp; + + // If we're in _sigtramp(), unwinding past this frame requires special + // knowledge. + if (m_frame_type == eTrapHandlerFrame || m_frame_type == eDebuggerFrame) + return unwind_plan_sp; + + unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind( + *m_thread.CalculateTarget(), m_thread); + if (unwind_plan_sp) { + if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + if (log && log->GetVerbose()) { + if (m_fast_unwind_plan_sp) + UnwindLogMsgVerbose("frame, and has a fast UnwindPlan"); + else + UnwindLogMsgVerbose("frame"); + } + m_frame_type = eNormalFrame; + return unwind_plan_sp; + } else { + unwind_plan_sp.reset(); + } + } + return unwind_plan_sp; +} + +// On entry to this method, +// +// 1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame +// if either of those are correct, +// 2. m_sym_ctx should already be filled in, and +// 3. m_current_pc should have the current pc value for this frame +// 4. m_current_offset_backed_up_one should have the current byte offset into +// the function, maybe backed up by 1, -1 if unknown + +UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() { + UnwindPlanSP unwind_plan_sp; + UnwindPlanSP arch_default_unwind_plan_sp; + ExecutionContext exe_ctx(m_thread.shared_from_this()); + Process *process = exe_ctx.GetProcessPtr(); + ABI *abi = process ? process->GetABI().get() : nullptr; + if (abi) { + arch_default_unwind_plan_sp = + std::make_shared(lldb::eRegisterKindGeneric); + abi->CreateDefaultUnwindPlan(*arch_default_unwind_plan_sp); + } else { + UnwindLogMsg( + "unable to get architectural default UnwindPlan from ABI plugin"); + } + + bool behaves_like_zeroth_frame = false; + if (IsFrameZero() || GetNextFrame()->m_frame_type == eTrapHandlerFrame || + GetNextFrame()->m_frame_type == eDebuggerFrame) { + behaves_like_zeroth_frame = true; + // If this frame behaves like a 0th frame (currently executing or + // interrupted asynchronously), all registers can be retrieved. + m_all_registers_available = true; + } + + // If we've done a jmp 0x0 / bl 0x0 (called through a null function pointer) + // so the pc is 0x0 in the zeroth frame, we need to use the "unwind at first + // instruction" arch default UnwindPlan Also, if this Process can report on + // memory region attributes, any non-executable region means we jumped + // through a bad function pointer - handle the same way as 0x0. Note, if we + // have a symbol context & a symbol, we don't want to follow this code path. + // This is for jumping to memory regions without any information available. + + if ((!m_sym_ctx_valid || + (m_sym_ctx.function == nullptr && m_sym_ctx.symbol == nullptr)) && + behaves_like_zeroth_frame && m_current_pc.IsValid()) { + uint32_t permissions; + addr_t current_pc_addr = + m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()); + if (current_pc_addr == 0 || + (process && + process->GetLoadAddressPermissions(current_pc_addr, permissions) && + (permissions & ePermissionsExecutable) == 0)) { + if (abi) { + unwind_plan_sp = + std::make_shared(lldb::eRegisterKindGeneric); + abi->CreateFunctionEntryUnwindPlan(*unwind_plan_sp); + m_frame_type = eNormalFrame; + return unwind_plan_sp; + } + } + } + + // No Module for the current pc, try using the architecture default unwind. + ModuleSP pc_module_sp(m_current_pc.GetModule()); + if (!m_current_pc.IsValid() || !pc_module_sp || + pc_module_sp->GetObjectFile() == nullptr) { + m_frame_type = eNormalFrame; + return arch_default_unwind_plan_sp; + } + + FuncUnwindersSP func_unwinders_sp; + if (m_sym_ctx_valid) { + func_unwinders_sp = + pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress( + m_current_pc, m_sym_ctx); + } + + // No FuncUnwinders available for this pc (stripped function symbols, lldb + // could not augment its function table with another source, like + // LC_FUNCTION_STARTS or eh_frame in ObjectFileMachO). See if eh_frame or the + // .ARM.exidx tables have unwind information for this address, else fall back + // to the architectural default unwind. + if (!func_unwinders_sp) { + m_frame_type = eNormalFrame; + + if (!pc_module_sp || !pc_module_sp->GetObjectFile() || + !m_current_pc.IsValid()) + return arch_default_unwind_plan_sp; + + // Even with -fomit-frame-pointer, we can try eh_frame to get back on + // track. + DWARFCallFrameInfo *eh_frame = + pc_module_sp->GetUnwindTable().GetEHFrameInfo(); + if (eh_frame) { + unwind_plan_sp = std::make_shared(lldb::eRegisterKindGeneric); + if (eh_frame->GetUnwindPlan(m_current_pc, *unwind_plan_sp)) + return unwind_plan_sp; + else + unwind_plan_sp.reset(); + } + + ArmUnwindInfo *arm_exidx = + pc_module_sp->GetUnwindTable().GetArmUnwindInfo(); + if (arm_exidx) { + unwind_plan_sp = std::make_shared(lldb::eRegisterKindGeneric); + if (arm_exidx->GetUnwindPlan(exe_ctx.GetTargetRef(), m_current_pc, + *unwind_plan_sp)) + return unwind_plan_sp; + else + unwind_plan_sp.reset(); + } + + CallFrameInfo *object_file_unwind = + pc_module_sp->GetUnwindTable().GetObjectFileUnwindInfo(); + if (object_file_unwind) { + unwind_plan_sp = std::make_shared(lldb::eRegisterKindGeneric); + if (object_file_unwind->GetUnwindPlan(m_current_pc, *unwind_plan_sp)) + return unwind_plan_sp; + else + unwind_plan_sp.reset(); + } + + return arch_default_unwind_plan_sp; + } + + // If we're in _sigtramp(), unwinding past this frame requires special + // knowledge. On Mac OS X this knowledge is properly encoded in the eh_frame + // section, so prefer that if available. On other platforms we may need to + // provide a platform-specific UnwindPlan which encodes the details of how to + // unwind out of sigtramp. + if (m_frame_type == eTrapHandlerFrame && process) { + m_fast_unwind_plan_sp.reset(); + unwind_plan_sp = + func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget()); + if (!unwind_plan_sp) + unwind_plan_sp = + func_unwinders_sp->GetObjectFileUnwindPlan(process->GetTarget()); + if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc) && + unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) { + return unwind_plan_sp; + } + } + + // Ask the DynamicLoader if the eh_frame CFI should be trusted in this frame + // even when it's frame zero This comes up if we have hand-written functions + // in a Module and hand-written eh_frame. The assembly instruction + // inspection may fail and the eh_frame CFI were probably written with some + // care to do the right thing. It'd be nice if there was a way to ask the + // eh_frame directly if it is asynchronous (can be trusted at every + // instruction point) or synchronous (the normal case - only at call sites). + // But there is not. + if (process && process->GetDynamicLoader() && + process->GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo(m_sym_ctx)) { + // We must specifically call the GetEHFrameUnwindPlan() method here -- + // normally we would call GetUnwindPlanAtCallSite() -- because CallSite may + // return an unwind plan sourced from either eh_frame (that's what we + // intend) or compact unwind (this won't work) + unwind_plan_sp = + func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget()); + if (!unwind_plan_sp) + unwind_plan_sp = + func_unwinders_sp->GetObjectFileUnwindPlan(process->GetTarget()); + if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { + UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because the " + "DynamicLoader suggested we prefer it", + unwind_plan_sp->GetSourceName().GetCString()); + return unwind_plan_sp; + } + } + + // Typically the NonCallSite UnwindPlan is the unwind created by inspecting + // the assembly language instructions + if (behaves_like_zeroth_frame && process) { + unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite( + process->GetTarget(), m_thread); + if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) { + if (unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) { + // We probably have an UnwindPlan created by inspecting assembly + // instructions. The assembly profilers work really well with compiler- + // generated functions but hand- written assembly can be problematic. + // We set the eh_frame based unwind plan as our fallback unwind plan if + // instruction emulation doesn't work out even for non call sites if it + // is available and use the architecture default unwind plan if it is + // not available. The eh_frame unwind plan is more reliable even on non + // call sites then the architecture default plan and for hand written + // assembly code it is often written in a way that it valid at all + // location what helps in the most common cases when the instruction + // emulation fails. + UnwindPlanSP call_site_unwind_plan = + func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(), + m_thread); + if (call_site_unwind_plan && + call_site_unwind_plan.get() != unwind_plan_sp.get() && + call_site_unwind_plan->GetSourceName() != + unwind_plan_sp->GetSourceName()) { + m_fallback_unwind_plan_sp = call_site_unwind_plan; + } else { + m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp; + } + } + UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because this " + "is the non-call site unwind plan and this is a " + "zeroth frame", + unwind_plan_sp->GetSourceName().GetCString()); + return unwind_plan_sp; + } + + // If we're on the first instruction of a function, and we have an + // architectural default UnwindPlan for the initial instruction of a + // function, use that. + if (m_current_offset == 0) { + unwind_plan_sp = + func_unwinders_sp->GetUnwindPlanArchitectureDefaultAtFunctionEntry( + m_thread); + if (unwind_plan_sp) { + UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because we are at " + "the first instruction of a function", + unwind_plan_sp->GetSourceName().GetCString()); + return unwind_plan_sp; + } + } + } + + // Typically this is unwind info from an eh_frame section intended for + // exception handling; only valid at call sites + if (process) { + unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite( + process->GetTarget(), m_thread); + } + int valid_offset = -1; + if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) { + UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because this " + "is the call-site unwind plan", + unwind_plan_sp->GetSourceName().GetCString()); + return unwind_plan_sp; + } + + // We'd prefer to use an UnwindPlan intended for call sites when we're at a + // call site but if we've struck out on that, fall back to using the non- + // call-site assembly inspection UnwindPlan if possible. + if (process) { + unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite( + process->GetTarget(), m_thread); + } + if (unwind_plan_sp && + unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) { + // We probably have an UnwindPlan created by inspecting assembly + // instructions. The assembly profilers work really well with compiler- + // generated functions but hand- written assembly can be problematic. We + // set the eh_frame based unwind plan as our fallback unwind plan if + // instruction emulation doesn't work out even for non call sites if it is + // available and use the architecture default unwind plan if it is not + // available. The eh_frame unwind plan is more reliable even on non call + // sites then the architecture default plan and for hand written assembly + // code it is often written in a way that it valid at all location what + // helps in the most common cases when the instruction emulation fails. + UnwindPlanSP call_site_unwind_plan = + func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(), + m_thread); + if (call_site_unwind_plan && + call_site_unwind_plan.get() != unwind_plan_sp.get() && + call_site_unwind_plan->GetSourceName() != + unwind_plan_sp->GetSourceName()) { + m_fallback_unwind_plan_sp = call_site_unwind_plan; + } else { + m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp; + } + } + + if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) { + UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because we " + "failed to find a call-site unwind plan that would work", + unwind_plan_sp->GetSourceName().GetCString()); + return unwind_plan_sp; + } + + // If nothing else, use the architectural default UnwindPlan and hope that + // does the job. + if (arch_default_unwind_plan_sp) + UnwindLogMsgVerbose( + "frame uses %s for full UnwindPlan because we are falling back " + "to the arch default plan", + arch_default_unwind_plan_sp->GetSourceName().GetCString()); + else + UnwindLogMsg( + "Unable to find any UnwindPlan for full unwind of this frame."); + + return arch_default_unwind_plan_sp; +} + +void RegisterContextUnwind::InvalidateAllRegisters() { + m_frame_type = eNotAValidFrame; +} + +size_t RegisterContextUnwind::GetRegisterCount() { + return m_thread.GetRegisterContext()->GetRegisterCount(); +} + +const RegisterInfo *RegisterContextUnwind::GetRegisterInfoAtIndex(size_t reg) { + return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg); +} + +size_t RegisterContextUnwind::GetRegisterSetCount() { + return m_thread.GetRegisterContext()->GetRegisterSetCount(); +} + +const RegisterSet *RegisterContextUnwind::GetRegisterSet(size_t reg_set) { + return m_thread.GetRegisterContext()->GetRegisterSet(reg_set); +} + +uint32_t RegisterContextUnwind::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t num) { + return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber( + kind, num); +} + +bool RegisterContextUnwind::ReadRegisterValueFromRegisterLocation( + lldb_private::UnwindLLDB::RegisterLocation regloc, + const RegisterInfo *reg_info, RegisterValue &value) { + if (!IsValid()) + return false; + bool success = false; + + switch (regloc.type) { + case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext: { + const RegisterInfo *other_reg_info = + GetRegisterInfoAtIndex(regloc.location.register_number); + + if (!other_reg_info) + return false; + + success = + m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value); + } break; + case UnwindLLDB::RegisterLocation::eRegisterInRegister: { + const RegisterInfo *other_reg_info = + GetRegisterInfoAtIndex(regloc.location.register_number); + + if (!other_reg_info) + return false; + + if (IsFrameZero()) { + success = + m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value); + } else { + success = GetNextFrame()->ReadRegister(other_reg_info, value); + } + } break; + case UnwindLLDB::RegisterLocation::eRegisterValueInferred: + success = + value.SetUInt(regloc.location.inferred_value, reg_info->byte_size); + break; + + case UnwindLLDB::RegisterLocation::eRegisterNotSaved: + break; + case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation: + llvm_unreachable("FIXME debugger inferior function call unwind"); + case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation: { + Status error(ReadRegisterValueFromMemory( + reg_info, regloc.location.target_memory_location, reg_info->byte_size, + value)); + success = error.Success(); + } break; + default: + llvm_unreachable("Unknown RegisterLocation type."); + } + return success; +} + +bool RegisterContextUnwind::WriteRegisterValueToRegisterLocation( + lldb_private::UnwindLLDB::RegisterLocation regloc, + const RegisterInfo *reg_info, const RegisterValue &value) { + if (!IsValid()) + return false; + + bool success = false; + + switch (regloc.type) { + case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext: { + const RegisterInfo *other_reg_info = + GetRegisterInfoAtIndex(regloc.location.register_number); + success = + m_thread.GetRegisterContext()->WriteRegister(other_reg_info, value); + } break; + case UnwindLLDB::RegisterLocation::eRegisterInRegister: { + const RegisterInfo *other_reg_info = + GetRegisterInfoAtIndex(regloc.location.register_number); + if (IsFrameZero()) { + success = + m_thread.GetRegisterContext()->WriteRegister(other_reg_info, value); + } else { + success = GetNextFrame()->WriteRegister(other_reg_info, value); + } + } break; + case UnwindLLDB::RegisterLocation::eRegisterValueInferred: + case UnwindLLDB::RegisterLocation::eRegisterNotSaved: + break; + case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation: + llvm_unreachable("FIXME debugger inferior function call unwind"); + case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation: { + Status error(WriteRegisterValueToMemory( + reg_info, regloc.location.target_memory_location, reg_info->byte_size, + value)); + success = error.Success(); + } break; + default: + llvm_unreachable("Unknown RegisterLocation type."); + } + return success; +} + +bool RegisterContextUnwind::IsValid() const { + return m_frame_type != eNotAValidFrame; +} + +// After the final stack frame in a stack walk we'll get one invalid +// (eNotAValidFrame) stack frame -- one past the end of the stack walk. But +// higher-level code will need to tell the difference between "the unwind plan +// below this frame failed" versus "we successfully completed the stack walk" +// so this method helps to disambiguate that. + +bool RegisterContextUnwind::IsTrapHandlerFrame() const { + return m_frame_type == eTrapHandlerFrame; +} + +// A skip frame is a bogus frame on the stack -- but one where we're likely to +// find a real frame farther +// up the stack if we keep looking. It's always the second frame in an unwind +// (i.e. the first frame after frame zero) where unwinding can be the +// trickiest. Ideally we'll mark up this frame in some way so the user knows +// we're displaying bad data and we may have skipped one frame of their real +// program in the process of getting back on track. + +bool RegisterContextUnwind::IsSkipFrame() const { + return m_frame_type == eSkipFrame; +} + +bool RegisterContextUnwind::IsTrapHandlerSymbol( + lldb_private::Process *process, + const lldb_private::SymbolContext &m_sym_ctx) const { + PlatformSP platform_sp(process->GetTarget().GetPlatform()); + if (platform_sp) { + const std::vector trap_handler_names( + platform_sp->GetTrapHandlerSymbolNames()); + for (ConstString name : trap_handler_names) { + if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) || + (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name)) { + return true; + } + } + } + const std::vector user_specified_trap_handler_names( + m_parent_unwind.GetUserSpecifiedTrapHandlerFunctionNames()); + for (ConstString name : user_specified_trap_handler_names) { + if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) || + (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name)) { + return true; + } + } + + return false; +} + +// Answer the question: Where did THIS frame save the CALLER frame ("previous" +// frame)'s register value? + +enum UnwindLLDB::RegisterSearchResult +RegisterContextUnwind::SavedLocationForRegister( + uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc) { + RegisterNumber regnum(m_thread, eRegisterKindLLDB, lldb_regnum); + + // Have we already found this register location? + if (!m_registers.empty()) { + std::map::const_iterator + iterator; + iterator = m_registers.find(regnum.GetAsKind(eRegisterKindLLDB)); + if (iterator != m_registers.end()) { + regloc = iterator->second; + UnwindLogMsg("supplying caller's saved %s (%d)'s location, cached", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); + return UnwindLLDB::RegisterSearchResult::eRegisterFound; + } + } + + // Look through the available UnwindPlans for the register location. + + UnwindPlan::Row::RegisterLocation unwindplan_regloc; + bool have_unwindplan_regloc = false; + RegisterKind unwindplan_registerkind = kNumRegisterKinds; + + if (m_fast_unwind_plan_sp) { + UnwindPlan::RowSP active_row = + m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); + unwindplan_registerkind = m_fast_unwind_plan_sp->GetRegisterKind(); + if (regnum.GetAsKind(unwindplan_registerkind) == LLDB_INVALID_REGNUM) { + UnwindLogMsg("could not convert lldb regnum %s (%d) into %d RegisterKind " + "reg numbering scheme", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), + (int)unwindplan_registerkind); + return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; + } + if (active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind), + unwindplan_regloc)) { + UnwindLogMsg( + "supplying caller's saved %s (%d)'s location using FastUnwindPlan", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); + have_unwindplan_regloc = true; + } + } + + if (!have_unwindplan_regloc) { + // m_full_unwind_plan_sp being NULL means that we haven't tried to find a + // full UnwindPlan yet + if (!m_full_unwind_plan_sp) + m_full_unwind_plan_sp = GetFullUnwindPlanForFrame(); + + if (m_full_unwind_plan_sp) { + RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_PC); + + UnwindPlan::RowSP active_row = + m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); + unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind(); + + RegisterNumber return_address_reg; + + // If we're fetching the saved pc and this UnwindPlan defines a + // ReturnAddress register (e.g. lr on arm), look for the return address + // register number in the UnwindPlan's row. + if (pc_regnum.IsValid() && pc_regnum == regnum && + m_full_unwind_plan_sp->GetReturnAddressRegister() != + LLDB_INVALID_REGNUM) { + // If this is a trap handler frame, we should have access to + // the complete register context when the interrupt/async + // signal was received, we should fetch the actual saved $pc + // value instead of the Return Address register. + // If $pc is not available, fall back to the RA reg. + UnwindPlan::Row::RegisterLocation scratch; + if (m_frame_type == eTrapHandlerFrame && + active_row->GetRegisterInfo + (pc_regnum.GetAsKind (unwindplan_registerkind), scratch)) { + UnwindLogMsg("Providing pc register instead of rewriting to " + "RA reg because this is a trap handler and there is " + "a location for the saved pc register value."); + } else { + return_address_reg.init( + m_thread, m_full_unwind_plan_sp->GetRegisterKind(), + m_full_unwind_plan_sp->GetReturnAddressRegister()); + regnum = return_address_reg; + UnwindLogMsg("requested caller's saved PC but this UnwindPlan uses a " + "RA reg; getting %s (%d) instead", + return_address_reg.GetName(), + return_address_reg.GetAsKind(eRegisterKindLLDB)); + } + } else { + if (regnum.GetAsKind(unwindplan_registerkind) == LLDB_INVALID_REGNUM) { + if (unwindplan_registerkind == eRegisterKindGeneric) { + UnwindLogMsg("could not convert lldb regnum %s (%d) into " + "eRegisterKindGeneric reg numbering scheme", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); + } else { + UnwindLogMsg("could not convert lldb regnum %s (%d) into %d " + "RegisterKind reg numbering scheme", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), + (int)unwindplan_registerkind); + } + return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; + } + } + + if (regnum.IsValid() && + active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind), + unwindplan_regloc)) { + have_unwindplan_regloc = true; + UnwindLogMsg( + "supplying caller's saved %s (%d)'s location using %s UnwindPlan", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), + m_full_unwind_plan_sp->GetSourceName().GetCString()); + } + + // This is frame 0 and we're retrieving the PC and it's saved in a Return + // 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 && return_address_reg.IsValid() && + IsFrameZero()) { + if (return_address_reg.GetAsKind(eRegisterKindLLDB) != + LLDB_INVALID_REGNUM) { + lldb_private::UnwindLLDB::RegisterLocation new_regloc; + new_regloc.type = + UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext; + new_regloc.location.register_number = + return_address_reg.GetAsKind(eRegisterKindLLDB); + m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc; + regloc = new_regloc; + UnwindLogMsg("supplying caller's register %s (%d) from the live " + "RegisterContext at frame 0, saved in %d", + return_address_reg.GetName(), + return_address_reg.GetAsKind(eRegisterKindLLDB), + return_address_reg.GetAsKind(eRegisterKindLLDB)); + return UnwindLLDB::RegisterSearchResult::eRegisterFound; + } + } + + // If this architecture stores the return address in a register (it + // defines a Return Address register) and we're on a non-zero stack frame + // and the Full UnwindPlan says that the pc is stored in the + // RA registers (e.g. lr on arm), then we know that the full unwindplan is + // not trustworthy -- this + // is an impossible situation and the instruction emulation code has + // likely been misled. If this stack frame meets those criteria, we need + // to throw away the Full UnwindPlan that the instruction emulation came + // up with and fall back to the architecture's Default UnwindPlan so the + // stack walk can get past this point. + + // Special note: If the Full UnwindPlan was generated from the compiler, + // don't second-guess it when we're at a call site location. + + // arch_default_ra_regnum is the return address register # in the Full + // UnwindPlan register numbering + RegisterNumber arch_default_ra_regnum(m_thread, eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_RA); + + if (arch_default_ra_regnum.GetAsKind(unwindplan_registerkind) != + LLDB_INVALID_REGNUM && + pc_regnum == regnum && unwindplan_regloc.IsInOtherRegister() && + unwindplan_regloc.GetRegisterNumber() == + arch_default_ra_regnum.GetAsKind(unwindplan_registerkind) && + m_full_unwind_plan_sp->GetSourcedFromCompiler() != eLazyBoolYes && + !m_all_registers_available) { + UnwindLogMsg("%s UnwindPlan tried to restore the pc from the link " + "register but this is a non-zero frame", + m_full_unwind_plan_sp->GetSourceName().GetCString()); + + // Throw away the full unwindplan; install the arch default unwindplan + if (ForceSwitchToFallbackUnwindPlan()) { + // Update for the possibly new unwind plan + unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind(); + UnwindPlan::RowSP active_row = + m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); + + // Sanity check: Verify that we can fetch a pc value and CFA value + // with this unwind plan + + RegisterNumber arch_default_pc_reg(m_thread, eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_PC); + bool can_fetch_pc_value = false; + bool can_fetch_cfa = false; + addr_t cfa_value; + if (active_row) { + if (arch_default_pc_reg.GetAsKind(unwindplan_registerkind) != + LLDB_INVALID_REGNUM && + active_row->GetRegisterInfo( + arch_default_pc_reg.GetAsKind(unwindplan_registerkind), + unwindplan_regloc)) { + can_fetch_pc_value = true; + } + if (ReadFrameAddress(unwindplan_registerkind, + active_row->GetCFAValue(), cfa_value)) { + can_fetch_cfa = true; + } + } + + 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; + } + } + } + } + + ExecutionContext exe_ctx(m_thread.shared_from_this()); + Process *process = exe_ctx.GetProcessPtr(); + 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, + // the ABI may set volatile registers to the undefined state. + ABI *abi = process ? process->GetABI().get() : nullptr; + if (abi) { + const RegisterInfo *reg_info = + GetRegisterInfoAtIndex(regnum.GetAsKind(eRegisterKindLLDB)); + if (reg_info && + abi->GetFallbackRegisterLocation(reg_info, unwindplan_regloc)) { + UnwindLogMsg( + "supplying caller's saved %s (%d)'s location using ABI default", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); + have_unwindplan_regloc = true; + } + } + } + + if (!have_unwindplan_regloc) { + if (IsFrameZero()) { + // This is frame 0 - we should return the actual live register context + // value + lldb_private::UnwindLLDB::RegisterLocation new_regloc; + new_regloc.type = + UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext; + new_regloc.location.register_number = regnum.GetAsKind(eRegisterKindLLDB); + m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc; + regloc = new_regloc; + UnwindLogMsg("supplying caller's register %s (%d) from the live " + "RegisterContext at frame 0", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); + return UnwindLLDB::RegisterSearchResult::eRegisterFound; + } else { + std::string unwindplan_name(""); + if (m_full_unwind_plan_sp) { + unwindplan_name += "via '"; + unwindplan_name += m_full_unwind_plan_sp->GetSourceName().AsCString(); + unwindplan_name += "'"; + } + UnwindLogMsg("no save location for %s (%d) %s", regnum.GetName(), + regnum.GetAsKind(eRegisterKindLLDB), + unwindplan_name.c_str()); + } + return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; + } + + // unwindplan_regloc has valid contents about where to retrieve the register + if (unwindplan_regloc.IsUnspecified()) { + lldb_private::UnwindLLDB::RegisterLocation new_regloc; + new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved; + m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc; + UnwindLogMsg("save location for %s (%d) is unspecified, continue searching", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); + return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; + } + + if (unwindplan_regloc.IsUndefined()) { + UnwindLogMsg( + "did not supply reg location for %s (%d) because it is volatile", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); + return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile; + } + + if (unwindplan_regloc.IsSame()) { + 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 " + "return address reg on a non-zero frame -- treat as if we " + "have no information", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); + return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; + } else { + regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister; + regloc.location.register_number = regnum.GetAsKind(eRegisterKindLLDB); + m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; + UnwindLogMsg( + "supplying caller's register %s (%d), saved in register %s (%d)", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); + return UnwindLLDB::RegisterSearchResult::eRegisterFound; + } + } + + if (unwindplan_regloc.IsCFAPlusOffset()) { + int offset = unwindplan_regloc.GetOffset(); + regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred; + regloc.location.inferred_value = m_cfa + offset; + m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; + UnwindLogMsg("supplying caller's register %s (%d), value is CFA plus " + "offset %d [value is 0x%" PRIx64 "]", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset, + regloc.location.inferred_value); + return UnwindLLDB::RegisterSearchResult::eRegisterFound; + } + + if (unwindplan_regloc.IsAtCFAPlusOffset()) { + int offset = unwindplan_regloc.GetOffset(); + regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation; + regloc.location.target_memory_location = m_cfa + offset; + m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; + UnwindLogMsg("supplying caller's register %s (%d) from the stack, saved at " + "CFA 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.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, + unwindplan_regnum); + if (row_regnum.GetAsKind(eRegisterKindLLDB) == LLDB_INVALID_REGNUM) { + UnwindLogMsg("could not supply caller's %s (%d) location - was saved in " + "another reg but couldn't convert that regnum", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); + return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; + } + regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister; + regloc.location.register_number = row_regnum.GetAsKind(eRegisterKindLLDB); + m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; + UnwindLogMsg( + "supplying caller's register %s (%d), saved in register %s (%d)", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), + row_regnum.GetName(), row_regnum.GetAsKind(eRegisterKindLLDB)); + return UnwindLLDB::RegisterSearchResult::eRegisterFound; + } + + if (unwindplan_regloc.IsDWARFExpression() || + unwindplan_regloc.IsAtDWARFExpression()) { + DataExtractor dwarfdata(unwindplan_regloc.GetDWARFExpressionBytes(), + unwindplan_regloc.GetDWARFExpressionLength(), + process->GetByteOrder(), + process->GetAddressByteSize()); + ModuleSP opcode_ctx; + DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr); + dwarfexpr.SetRegisterKind(unwindplan_registerkind); + Value cfa_val = Scalar(m_cfa); + cfa_val.SetValueType(Value::eValueTypeLoadAddress); + Value result; + Status error; + if (dwarfexpr.Evaluate(&exe_ctx, this, 0, &cfa_val, nullptr, result, + &error)) { + addr_t val; + val = result.GetScalar().ULongLong(); + if (unwindplan_regloc.IsDWARFExpression()) { + regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred; + regloc.location.inferred_value = val; + m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; + UnwindLogMsg("supplying caller's register %s (%d) via DWARF expression " + "(IsDWARFExpression)", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); + return UnwindLLDB::RegisterSearchResult::eRegisterFound; + } else { + regloc.type = + UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation; + regloc.location.target_memory_location = val; + m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; + UnwindLogMsg("supplying caller's register %s (%d) via DWARF expression " + "(IsAtDWARFExpression)", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); + return UnwindLLDB::RegisterSearchResult::eRegisterFound; + } + } + UnwindLogMsg("tried to use IsDWARFExpression or IsAtDWARFExpression for %s " + "(%d) but failed", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); + return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; + } + + UnwindLogMsg("no save location for %s (%d) in this stack frame", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB)); + + // FIXME UnwindPlan::Row types atDWARFExpression and isDWARFExpression are + // unsupported. + + return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; +} + +// TryFallbackUnwindPlan() -- this method is a little tricky. +// +// When this is called, the frame above -- the caller frame, the "previous" +// frame -- is invalid or bad. +// +// Instead of stopping the stack walk here, we'll try a different UnwindPlan +// and see if we can get a valid frame above us. +// +// This most often happens when an unwind plan based on assembly instruction +// inspection is not correct -- mostly with hand-written assembly functions or +// functions where the stack frame is set up "out of band", e.g. the kernel +// saved the register context and then called an asynchronous trap handler like +// _sigtramp. +// +// Often in these cases, if we just do a dumb stack walk we'll get past this +// tricky frame and our usual techniques can continue to be used. + +bool RegisterContextUnwind::TryFallbackUnwindPlan() { + if (m_fallback_unwind_plan_sp.get() == nullptr) + return false; + + if (m_full_unwind_plan_sp.get() == nullptr) + return false; + + if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() || + m_full_unwind_plan_sp->GetSourceName() == + m_fallback_unwind_plan_sp->GetSourceName()) { + return false; + } + + // If a compiler generated unwind plan failed, trying the arch default + // unwindplan isn't going to do any better. + if (m_full_unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) + return false; + + // Get the caller's pc value and our own CFA value. Swap in the fallback + // unwind plan, re-fetch the caller's pc value and CFA value. If they're the + // same, then the fallback unwind plan provides no benefit. + + RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_PC); + + addr_t old_caller_pc_value = LLDB_INVALID_ADDRESS; + addr_t new_caller_pc_value = LLDB_INVALID_ADDRESS; + UnwindLLDB::RegisterLocation regloc; + if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB), + regloc) == + UnwindLLDB::RegisterSearchResult::eRegisterFound) { + const RegisterInfo *reg_info = + GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB)); + if (reg_info) { + RegisterValue reg_value; + if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) { + old_caller_pc_value = reg_value.GetAsUInt64(); + } + } + } + + // This is a tricky wrinkle! If SavedLocationForRegister() detects a really + // impossible register location for the full unwind plan, it may call + // ForceSwitchToFallbackUnwindPlan() which in turn replaces the full + // unwindplan with the fallback... in short, we're done, we're using the + // fallback UnwindPlan. We checked if m_fallback_unwind_plan_sp was nullptr + // at the top -- the only way it became nullptr since then is via + // SavedLocationForRegister(). + if (m_fallback_unwind_plan_sp.get() == nullptr) + return true; + + // Switch the full UnwindPlan to be the fallback UnwindPlan. If we decide + // this isn't working, we need to restore. We'll also need to save & restore + // 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(); + + m_full_unwind_plan_sp = m_fallback_unwind_plan_sp; + + UnwindPlan::RowSP active_row = + m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); + + if (active_row && + active_row->GetCFAValue().GetValueType() != + UnwindPlan::Row::FAValue::unspecified) { + addr_t 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; + 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) { + const RegisterInfo *reg_info = + GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB)); + if (reg_info) { + RegisterValue reg_value; + if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, + reg_value)) { + new_caller_pc_value = reg_value.GetAsUInt64(); + } + } + } + + if (new_caller_pc_value == LLDB_INVALID_ADDRESS) { + UnwindLogMsg("failed to get a pc value for the caller frame with the " + "fallback unwind plan"); + 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 == 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' " + "because UnwindPlan '%s' failed.", + m_fallback_unwind_plan_sp->GetSourceName().GetCString(), + original_full_unwind_plan_sp->GetSourceName().GetCString()); + + // We've copied the fallback unwind plan into the full - now clear the + // fallback. + m_fallback_unwind_plan_sp.reset(); + PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp); + } + + return true; +} + +bool RegisterContextUnwind::ForceSwitchToFallbackUnwindPlan() { + if (m_fallback_unwind_plan_sp.get() == nullptr) + return false; + + if (m_full_unwind_plan_sp.get() == nullptr) + return false; + + if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() || + m_full_unwind_plan_sp->GetSourceName() == + m_fallback_unwind_plan_sp->GetSourceName()) { + return false; + } + + UnwindPlan::RowSP active_row = + m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset); + + if (active_row && + active_row->GetCFAValue().GetValueType() != + UnwindPlan::Row::FAValue::unspecified) { + addr_t 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(); + + m_registers.clear(); + + m_cfa = new_cfa; + + PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp); + + UnwindLogMsg("switched unconditionally to the fallback unwindplan %s", + m_full_unwind_plan_sp->GetSourceName().GetCString()); + return true; + } + return false; +} + +void RegisterContextUnwind::PropagateTrapHandlerFlagFromUnwindPlan( + lldb::UnwindPlanSP unwind_plan) { + if (unwind_plan->GetUnwindPlanForSignalTrap() != eLazyBoolYes) { + // Unwind plan does not indicate trap handler. Do nothing. We may + // already be flagged as trap handler flag due to the symbol being + // in the trap handler symbol list, and that should take precedence. + return; + } else if (m_frame_type != eNormalFrame) { + // If this is already a trap handler frame, nothing to do. + // If this is a skip or debug or invalid frame, don't override that. + return; + } + + m_frame_type = eTrapHandlerFrame; + + if (m_current_offset_backed_up_one != m_current_offset) { + // We backed up the pc by 1 to compute the symbol context, but + // now need to undo that because the pc of the trap handler + // frame may in fact be the first instruction of a signal return + // trampoline, rather than the instruction after a call. This + // happens on systems where the signal handler dispatch code, rather + // than calling the handler and being returned to, jumps to the + // handler after pushing the address of a return trampoline on the + // stack -- on these systems, when the handler returns, control will + // be transferred to the return trampoline, so that's the best + // symbol we can present in the callstack. + UnwindLogMsg("Resetting current offset and re-doing symbol lookup; " + "old symbol was %s", + GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); + m_current_offset_backed_up_one = m_current_offset; + + AddressRange addr_range; + m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range); + + UnwindLogMsg("Symbol is now %s", + GetSymbolOrFunctionName(m_sym_ctx).AsCString("")); + + ExecutionContext exe_ctx(m_thread.shared_from_this()); + Process *process = exe_ctx.GetProcessPtr(); + Target *target = &process->GetTarget(); + + m_start_pc = addr_range.GetBaseAddress(); + m_current_offset = + m_current_pc.GetLoadAddress(target) - m_start_pc.GetLoadAddress(target); + } +} + +bool RegisterContextUnwind::ReadFrameAddress( + lldb::RegisterKind row_register_kind, UnwindPlan::Row::FAValue &fa, + addr_t &address) { + RegisterValue reg_value; + + address = LLDB_INVALID_ADDRESS; + addr_t cfa_reg_contents; + + switch (fa.GetValueType()) { + case UnwindPlan::Row::FAValue::isRegisterDereferenced: { + RegisterNumber cfa_reg(m_thread, row_register_kind, + fa.GetRegisterNumber()); + if (ReadGPRValue(cfa_reg, cfa_reg_contents)) { + const RegisterInfo *reg_info = + GetRegisterInfoAtIndex(cfa_reg.GetAsKind(eRegisterKindLLDB)); + RegisterValue reg_value; + if (reg_info) { + Status error = ReadRegisterValueFromMemory( + reg_info, cfa_reg_contents, reg_info->byte_size, reg_value); + if (error.Success()) { + 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, address); + return true; + } else { + UnwindLogMsg("Tried to deref reg %s (%d) [0x%" PRIx64 + "] but memory read failed.", + cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB), + cfa_reg_contents); + } + } + } + break; + } + case UnwindPlan::Row::FAValue::isRegisterPlusOffset: { + RegisterNumber cfa_reg(m_thread, row_register_kind, + fa.GetRegisterNumber()); + if (ReadGPRValue(cfa_reg, cfa_reg_contents)) { + if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 || + cfa_reg_contents == 1) { + UnwindLogMsg( + "Got an invalid CFA register value - reg %s (%d), value 0x%" PRIx64, + cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB), + cfa_reg_contents); + cfa_reg_contents = LLDB_INVALID_ADDRESS; + return false; + } + address = cfa_reg_contents + fa.GetOffset(); + UnwindLogMsg( + "CFA is 0x%" PRIx64 ": Register %s (%d) contents are 0x%" PRIx64 + ", offset is %d", + address, cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB), + cfa_reg_contents, fa.GetOffset()); + return true; + } + break; + } + case UnwindPlan::Row::FAValue::isDWARFExpression: { + ExecutionContext exe_ctx(m_thread.shared_from_this()); + Process *process = exe_ctx.GetProcessPtr(); + DataExtractor dwarfdata(fa.GetDWARFExpressionBytes(), + fa.GetDWARFExpressionLength(), + process->GetByteOrder(), + process->GetAddressByteSize()); + ModuleSP opcode_ctx; + DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr); + dwarfexpr.SetRegisterKind(row_register_kind); + Value result; + Status error; + if (dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr, result, + &error)) { + address = result.GetScalar().ULongLong(); + + UnwindLogMsg("CFA value set by DWARF expression is 0x%" PRIx64, + address); + return true; + } + UnwindLogMsg("Failed to set CFA value via DWARF expression: %s", + error.AsCString()); + break; + } + case UnwindPlan::Row::FAValue::isRaSearch: { + Process &process = *m_thread.GetProcess(); + lldb::addr_t return_address_hint = GetReturnAddressHint(fa.GetOffset()); + if (return_address_hint == LLDB_INVALID_ADDRESS) + return false; + const unsigned max_iterations = 256; + for (unsigned i = 0; i < max_iterations; ++i) { + Status st; + lldb::addr_t candidate_addr = + return_address_hint + i * process.GetAddressByteSize(); + lldb::addr_t candidate = + process.ReadPointerFromMemory(candidate_addr, st); + if (st.Fail()) { + UnwindLogMsg("Cannot read memory at 0x%" PRIx64 ": %s", candidate_addr, + st.AsCString()); + return false; + } + Address addr; + uint32_t permissions; + if (process.GetLoadAddressPermissions(candidate, permissions) && + permissions & lldb::ePermissionsExecutable) { + address = candidate_addr; + UnwindLogMsg("Heuristically found CFA: 0x%" PRIx64, address); + return true; + } + } + UnwindLogMsg("No suitable CFA found"); + break; + } + default: + return false; + } + return false; +} + +lldb::addr_t RegisterContextUnwind::GetReturnAddressHint(int32_t plan_offset) { + addr_t hint; + if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, hint)) + return LLDB_INVALID_ADDRESS; + if (!m_sym_ctx.module_sp || !m_sym_ctx.symbol) + return LLDB_INVALID_ADDRESS; + + hint += plan_offset; + + if (auto next = GetNextFrame()) { + if (!next->m_sym_ctx.module_sp || !next->m_sym_ctx.symbol) + return LLDB_INVALID_ADDRESS; + if (auto expected_size = + next->m_sym_ctx.module_sp->GetSymbolFile()->GetParameterStackSize( + *next->m_sym_ctx.symbol)) + hint += *expected_size; + else { + UnwindLogMsgVerbose("Could not retrieve parameter size: %s", + llvm::toString(expected_size.takeError()).c_str()); + return LLDB_INVALID_ADDRESS; + } + } + return hint; +} + +// Retrieve a general purpose register value for THIS frame, as saved by the +// NEXT frame, i.e. the frame that +// this frame called. e.g. +// +// foo () { } +// bar () { foo (); } +// main () { bar (); } +// +// stopped in foo() so +// frame 0 - foo +// frame 1 - bar +// frame 2 - main +// and this RegisterContext is for frame 1 (bar) - if we want to get the pc +// value for frame 1, we need to ask +// where frame 0 (the "next" frame) saved that and retrieve the value. + +bool RegisterContextUnwind::ReadGPRValue(lldb::RegisterKind register_kind, + uint32_t regnum, addr_t &value) { + if (!IsValid()) + return false; + + uint32_t lldb_regnum; + if (register_kind == eRegisterKindLLDB) { + lldb_regnum = regnum; + } else if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds( + register_kind, regnum, eRegisterKindLLDB, lldb_regnum)) { + return false; + } + + const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum); + RegisterValue reg_value; + // if this is frame 0 (currently executing frame), get the requested reg + // contents from the actual thread registers + if (IsFrameZero()) { + if (m_thread.GetRegisterContext()->ReadRegister(reg_info, reg_value)) { + value = reg_value.GetAsUInt64(); + return true; + } + return false; + } + + bool pc_register = false; + uint32_t generic_regnum; + if (register_kind == eRegisterKindGeneric && + (regnum == LLDB_REGNUM_GENERIC_PC || regnum == LLDB_REGNUM_GENERIC_RA)) { + pc_register = true; + } else if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds( + register_kind, regnum, eRegisterKindGeneric, generic_regnum) && + (generic_regnum == LLDB_REGNUM_GENERIC_PC || + generic_regnum == LLDB_REGNUM_GENERIC_RA)) { + pc_register = true; + } + + lldb_private::UnwindLLDB::RegisterLocation regloc; + if (!m_parent_unwind.SearchForSavedLocationForRegister( + lldb_regnum, regloc, m_frame_number - 1, pc_register)) { + return false; + } + if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) { + value = reg_value.GetAsUInt64(); + return true; + } + return false; +} + +bool RegisterContextUnwind::ReadGPRValue(const RegisterNumber ®num, + addr_t &value) { + return ReadGPRValue(regnum.GetRegisterKind(), regnum.GetRegisterNumber(), + value); +} + +// Find the value of a register in THIS frame + +bool RegisterContextUnwind::ReadRegister(const RegisterInfo *reg_info, + RegisterValue &value) { + if (!IsValid()) + return false; + + const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB]; + UnwindLogMsgVerbose("looking for register saved location for reg %d", + lldb_regnum); + + // If this is the 0th frame, hand this over to the live register context + if (IsFrameZero()) { + UnwindLogMsgVerbose("passing along to the live register context for reg %d", + lldb_regnum); + return m_thread.GetRegisterContext()->ReadRegister(reg_info, value); + } + + bool is_pc_regnum = false; + if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC || + reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_RA) { + is_pc_regnum = true; + } + + lldb_private::UnwindLLDB::RegisterLocation regloc; + // Find out where the NEXT frame saved THIS frame's register contents + if (!m_parent_unwind.SearchForSavedLocationForRegister( + lldb_regnum, regloc, m_frame_number - 1, is_pc_regnum)) + return false; + + return ReadRegisterValueFromRegisterLocation(regloc, reg_info, value); +} + +bool RegisterContextUnwind::WriteRegister(const RegisterInfo *reg_info, + const RegisterValue &value) { + if (!IsValid()) + return false; + + const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB]; + UnwindLogMsgVerbose("looking for register saved location for reg %d", + lldb_regnum); + + // If this is the 0th frame, hand this over to the live register context + if (IsFrameZero()) { + UnwindLogMsgVerbose("passing along to the live register context for reg %d", + lldb_regnum); + return m_thread.GetRegisterContext()->WriteRegister(reg_info, value); + } + + lldb_private::UnwindLLDB::RegisterLocation regloc; + // Find out where the NEXT frame saved THIS frame's register contents + if (!m_parent_unwind.SearchForSavedLocationForRegister( + lldb_regnum, regloc, m_frame_number - 1, false)) + return false; + + return WriteRegisterValueToRegisterLocation(regloc, reg_info, value); +} + +// Don't need to implement this one +bool RegisterContextUnwind::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) { + return false; +} + +// Don't need to implement this one +bool RegisterContextUnwind::WriteAllRegisterValues( + const lldb::DataBufferSP &data_sp) { + return false; +} + +// Retrieve the pc value for THIS from + +bool RegisterContextUnwind::GetCFA(addr_t &cfa) { + if (!IsValid()) { + return false; + } + if (m_cfa == LLDB_INVALID_ADDRESS) { + return false; + } + cfa = m_cfa; + return true; +} + +RegisterContextUnwind::SharedPtr RegisterContextUnwind::GetNextFrame() const { + RegisterContextUnwind::SharedPtr regctx; + if (m_frame_number == 0) + return regctx; + return m_parent_unwind.GetRegisterContextForFrameNum(m_frame_number - 1); +} + +RegisterContextUnwind::SharedPtr RegisterContextUnwind::GetPrevFrame() const { + RegisterContextUnwind::SharedPtr regctx; + return m_parent_unwind.GetRegisterContextForFrameNum(m_frame_number + 1); +} + +// Retrieve the address of the start of the function of THIS frame + +bool RegisterContextUnwind::GetStartPC(addr_t &start_pc) { + if (!IsValid()) + return false; + + if (!m_start_pc.IsValid()) { + bool read_successfully = ReadPC (start_pc); + if (read_successfully) + { + ProcessSP process_sp (m_thread.GetProcess()); + if (process_sp) + { + ABI *abi = process_sp->GetABI().get(); + if (abi) + start_pc = abi->FixCodeAddress(start_pc); + } + } + return read_successfully; + } + start_pc = m_start_pc.GetLoadAddress(CalculateTarget().get()); + return true; +} + +// Retrieve the current pc value for THIS frame, as saved by the NEXT frame. + +bool RegisterContextUnwind::ReadPC(addr_t &pc) { + if (!IsValid()) + return false; + + bool above_trap_handler = false; + if (GetNextFrame().get() && GetNextFrame()->IsValid() && + GetNextFrame()->IsTrapHandlerFrame()) + above_trap_handler = true; + + if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) { + // A pc value of 0 or 1 is impossible in the middle of the stack -- it + // indicates the end of a stack walk. + // On the currently executing frame (or such a frame interrupted + // asynchronously by sigtramp et al) this may occur if code has jumped + // through a NULL pointer -- we want to be able to unwind past that frame + // to help find the bug. + + ProcessSP process_sp (m_thread.GetProcess()); + if (process_sp) + { + ABI *abi = process_sp->GetABI().get(); + if (abi) + pc = abi->FixCodeAddress(pc); + } + + return !(m_all_registers_available == false && + above_trap_handler == false && (pc == 0 || pc == 1)); + } else { + return false; + } +} + +void RegisterContextUnwind::UnwindLogMsg(const char *fmt, ...) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + if (log) { + va_list args; + va_start(args, fmt); + + char *logmsg; + if (vasprintf(&logmsg, fmt, args) == -1 || logmsg == nullptr) { + if (logmsg) + free(logmsg); + va_end(args); + return; + } + va_end(args); + + LLDB_LOGF(log, "%*sth%d/fr%u %s", + m_frame_number < 100 ? m_frame_number : 100, "", + m_thread.GetIndexID(), m_frame_number, logmsg); + free(logmsg); + } +} + +void RegisterContextUnwind::UnwindLogMsgVerbose(const char *fmt, ...) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + if (log && log->GetVerbose()) { + va_list args; + va_start(args, fmt); + + char *logmsg; + if (vasprintf(&logmsg, fmt, args) == -1 || logmsg == nullptr) { + if (logmsg) + free(logmsg); + va_end(args); + return; + } + va_end(args); + + LLDB_LOGF(log, "%*sth%d/fr%u %s", + m_frame_number < 100 ? m_frame_number : 100, "", + m_thread.GetIndexID(), m_frame_number, logmsg); + free(logmsg); + } +} diff --git a/gnu/llvm/lldb/source/Target/RegisterNumber.cpp b/gnu/llvm/lldb/source/Target/RegisterNumber.cpp index 63b58d3582f..0ea9f212c69 100644 --- a/gnu/llvm/lldb/source/Target/RegisterNumber.cpp +++ b/gnu/llvm/lldb/source/Target/RegisterNumber.cpp @@ -1,4 +1,4 @@ -//===--------------------- RegisterNumber.cpp -------------------*- C++ -*-===// +//===-- RegisterNumber.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/RemoteAwarePlatform.cpp b/gnu/llvm/lldb/source/Target/RemoteAwarePlatform.cpp index faa217ac83e..f53158b06b8 100644 --- a/gnu/llvm/lldb/source/Target/RemoteAwarePlatform.cpp +++ b/gnu/llvm/lldb/source/Target/RemoteAwarePlatform.cpp @@ -1,4 +1,4 @@ -//===-- RemoteAwarePlatform.cpp ---------------------------------*- C++ -*-===// +//===-- RemoteAwarePlatform.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,12 +7,17 @@ //===----------------------------------------------------------------------===// #include "lldb/Target/RemoteAwarePlatform.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Core/ModuleSpec.h" #include "lldb/Host/FileCache.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" +#include "lldb/Utility/StreamString.h" using namespace lldb_private; +using namespace lldb; bool RemoteAwarePlatform::GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, @@ -21,7 +26,148 @@ bool RemoteAwarePlatform::GetModuleSpec(const FileSpec &module_file_spec, return m_remote_platform_sp->GetModuleSpec(module_file_spec, arch, module_spec); - return Platform::GetModuleSpec(module_file_spec, arch, module_spec); + return false; +} + +Status RemoteAwarePlatform::ResolveExecutable( + const ModuleSpec &module_spec, ModuleSP &exe_module_sp, + const FileSpecList *module_search_paths_ptr) { + Status error; + // Nothing special to do here, just use the actual file and architecture + + char exe_path[PATH_MAX]; + ModuleSpec resolved_module_spec(module_spec); + + if (IsHost()) { + // If we have "ls" as the exe_file, resolve the executable location based + // on the current path variables + 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, + FileSpec::Style::native); + FileSystem::Instance().Resolve(resolved_module_spec.GetFileSpec()); + } + + 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 (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) + error.Clear(); + else { + const uint32_t permissions = FileSystem::Instance().GetPermissions( + resolved_module_spec.GetFileSpec()); + if (permissions && (permissions & eFilePermissionsEveryoneR) == 0) + error.SetErrorStringWithFormat( + "executable '%s' is not readable", + resolved_module_spec.GetFileSpec().GetPath().c_str()); + else + error.SetErrorStringWithFormat( + "unable to find executable for '%s'", + resolved_module_spec.GetFileSpec().GetPath().c_str()); + } + } else { + if (m_remote_platform_sp) { + return GetCachedExecutable(resolved_module_spec, exe_module_sp, + module_search_paths_ptr, + *m_remote_platform_sp); + } + + // We may connect to a process and use the provided executable (Don't use + // local $PATH). + + // Resolve any executable within a bundle on MacOSX + Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec()); + + if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) + error.Clear(); + else + error.SetErrorStringWithFormat("the platform is not currently " + "connected, and '%s' doesn't exist in " + "the system root.", + exe_path); + } + + if (error.Success()) { + if (resolved_module_spec.GetArchitecture().IsValid()) { + error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, + module_search_paths_ptr, nullptr, nullptr); + if (error.Fail()) { + // If we failed, it may be because the vendor and os aren't known. If + // that is the case, try setting them to the host architecture and give + // it another try. + llvm::Triple &module_triple = + resolved_module_spec.GetArchitecture().GetTriple(); + bool is_vendor_specified = + (module_triple.getVendor() != llvm::Triple::UnknownVendor); + bool is_os_specified = + (module_triple.getOS() != llvm::Triple::UnknownOS); + if (!is_vendor_specified || !is_os_specified) { + const llvm::Triple &host_triple = + HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple(); + + if (!is_vendor_specified) + module_triple.setVendorName(host_triple.getVendorName()); + if (!is_os_specified) + module_triple.setOSName(host_triple.getOSName()); + + error = ModuleList::GetSharedModule(resolved_module_spec, + exe_module_sp, module_search_paths_ptr, nullptr, nullptr); + } + } + + // TODO find out why exe_module_sp might be NULL + if (error.Fail() || !exe_module_sp || !exe_module_sp->GetObjectFile()) { + exe_module_sp.reset(); + error.SetErrorStringWithFormat( + "'%s' doesn't contain the architecture %s", + resolved_module_spec.GetFileSpec().GetPath().c_str(), + resolved_module_spec.GetArchitecture().GetArchitectureName()); + } + } else { + // No valid architecture was specified, ask the platform for the + // architectures that we should be using (in the correct order) and see + // if we can find a match that way + StreamString arch_names; + for (uint32_t idx = 0; GetSupportedArchitectureAtIndex( + idx, resolved_module_spec.GetArchitecture()); + ++idx) { + error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, + module_search_paths_ptr, nullptr, nullptr); + // Did we find an executable using one of the + if (error.Success()) { + if (exe_module_sp && exe_module_sp->GetObjectFile()) + break; + else + error.SetErrorToGenericError(); + } + + if (idx > 0) + arch_names.PutCString(", "); + arch_names.PutCString( + resolved_module_spec.GetArchitecture().GetArchitectureName()); + } + + if (error.Fail() || !exe_module_sp) { + 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(), + GetPluginName().GetCString(), arch_names.GetData()); + } else { + error.SetErrorStringWithFormat( + "'%s' is not readable", + resolved_module_spec.GetFileSpec().GetPath().c_str()); + } + } + } + } + + return error; } Status RemoteAwarePlatform::RunShellCommand( diff --git a/gnu/llvm/lldb/source/Target/SectionLoadHistory.cpp b/gnu/llvm/lldb/source/Target/SectionLoadHistory.cpp index ec16b58b445..f329d425e34 100644 --- a/gnu/llvm/lldb/source/Target/SectionLoadHistory.cpp +++ b/gnu/llvm/lldb/source/Target/SectionLoadHistory.cpp @@ -1,4 +1,4 @@ -//===-- SectionLoadHistory.cpp ----------------------------------*- C++ -*-===// +//===-- SectionLoadHistory.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/SectionLoadList.cpp b/gnu/llvm/lldb/source/Target/SectionLoadList.cpp index f2546a89319..f1a626b0480 100644 --- a/gnu/llvm/lldb/source/Target/SectionLoadList.cpp +++ b/gnu/llvm/lldb/source/Target/SectionLoadList.cpp @@ -1,4 +1,4 @@ -//===-- SectionLoadList.cpp -------------------------------------*- C++ -*-===// +//===-- SectionLoadList.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -253,6 +253,6 @@ void SectionLoadList::Dump(Stream &s, Target *target) { ++pos) { s.Printf("addr = 0x%16.16" PRIx64 ", section = %p: ", pos->first, static_cast(pos->second.get())); - pos->second->Dump(&s, target, 0); + pos->second->Dump(s.AsRawOstream(), s.GetIndentLevel(), target, 0); } } diff --git a/gnu/llvm/lldb/source/Target/StackFrame.cpp b/gnu/llvm/lldb/source/Target/StackFrame.cpp index 5c6ea7a0393..3d6cc5dc90b 100644 --- a/gnu/llvm/lldb/source/Target/StackFrame.cpp +++ b/gnu/llvm/lldb/source/Target/StackFrame.cpp @@ -1,4 +1,4 @@ -//===-- StackFrame.cpp ------------------------------------------*- C++ -*-===// +//===-- StackFrame.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -606,7 +606,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( } // We are dumping at least one child - while (separator_idx != std::string::npos) { + while (!var_expr.empty()) { // Calculate the next separator index ahead of time ValueObjectSP child_valobj_sp; const char separator_type = var_expr[0]; @@ -673,7 +673,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( if (actual_is_ptr != expr_is_ptr) { // Incorrect use of "." with a pointer, or "->" with a // class/union/struct instance or reference. - valobj_sp->GetExpressionPath(var_expr_path_strm, false); + valobj_sp->GetExpressionPath(var_expr_path_strm); if (actual_is_ptr) error.SetErrorStringWithFormat( "\"%s\" is a pointer and . was used to attempt to access " @@ -709,7 +709,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( "this frame", name_const_string.GetCString()); } else { - valobj_sp->GetExpressionPath(var_expr_path_strm, false); + valobj_sp->GetExpressionPath(var_expr_path_strm); if (child_name) { error.SetErrorStringWithFormat( "\"%s\" is not a member of \"(%s) %s\"", @@ -782,7 +782,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( Status error; ValueObjectSP temp(valobj_sp->Dereference(error)); if (error.Fail()) { - valobj_sp->GetExpressionPath(var_expr_path_strm, false); + valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( "could not dereference \"(%s) %s\"", valobj_sp->GetTypeName().AsCString(""), @@ -800,7 +800,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( Status error; ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true)); if (error.Fail()) { - valobj_sp->GetExpressionPath(var_expr_path_strm, false); + valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( "could not get item 0 for \"(%s) %s\"", valobj_sp->GetTypeName().AsCString(""), @@ -837,7 +837,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( || synthetic == valobj_sp) /* synthetic is the same as the original object */ { - valobj_sp->GetExpressionPath(var_expr_path_strm, false); + valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( "\"(%s) %s\" is not an array type", valobj_sp->GetTypeName().AsCString(""), @@ -846,7 +846,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( static_cast(child_index) >= synthetic ->GetNumChildren() /* synthetic does not have that many values */) { - valobj_sp->GetExpressionPath(var_expr_path_strm, false); + valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( "array index %ld is not valid for \"(%s) %s\"", child_index, valobj_sp->GetTypeName().AsCString(""), @@ -854,7 +854,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( } else { child_valobj_sp = synthetic->GetChildAtIndex(child_index, true); if (!child_valobj_sp) { - valobj_sp->GetExpressionPath(var_expr_path_strm, false); + valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( "array index %ld is not valid for \"(%s) %s\"", child_index, valobj_sp->GetTypeName().AsCString(""), @@ -865,7 +865,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( child_valobj_sp = valobj_sp->GetSyntheticArrayMember(child_index, true); if (!child_valobj_sp) { - valobj_sp->GetExpressionPath(var_expr_path_strm, false); + valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( "failed to use pointer as array for index %ld for " "\"(%s) %s\"", @@ -884,7 +884,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( valobj_sp->GetSyntheticArrayMember(child_index, true); if (!child_valobj_sp) { - valobj_sp->GetExpressionPath(var_expr_path_strm, false); + valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( "array index %ld is not valid for \"(%s) %s\"", child_index, valobj_sp->GetTypeName().AsCString(""), @@ -895,7 +895,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild( child_index, child_index, true); if (!child_valobj_sp) { - valobj_sp->GetExpressionPath(var_expr_path_strm, false); + valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( "bitfield range %ld-%ld is not valid for \"(%s) %s\"", child_index, child_index, @@ -909,7 +909,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( || synthetic == valobj_sp) /* synthetic is the same as the original object */ { - valobj_sp->GetExpressionPath(var_expr_path_strm, false); + valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( "\"(%s) %s\" is not an array type", valobj_sp->GetTypeName().AsCString(""), @@ -918,7 +918,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( static_cast(child_index) >= synthetic ->GetNumChildren() /* synthetic does not have that many values */) { - valobj_sp->GetExpressionPath(var_expr_path_strm, false); + valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( "array index %ld is not valid for \"(%s) %s\"", child_index, valobj_sp->GetTypeName().AsCString(""), @@ -926,7 +926,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( } else { child_valobj_sp = synthetic->GetChildAtIndex(child_index, true); if (!child_valobj_sp) { - valobj_sp->GetExpressionPath(var_expr_path_strm, false); + valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( "array index %ld is not valid for \"(%s) %s\"", child_index, valobj_sp->GetTypeName().AsCString(""), @@ -940,7 +940,6 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( return ValueObjectSP(); } - separator_idx = var_expr.find_first_of(".-["); if (use_dynamic != eNoDynamicValues) { ValueObjectSP dynamic_value_sp( child_valobj_sp->GetDynamicValue(use_dynamic)); @@ -982,7 +981,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( Status error; ValueObjectSP temp(valobj_sp->Dereference(error)); if (error.Fail()) { - valobj_sp->GetExpressionPath(var_expr_path_strm, false); + valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( "could not dereference \"(%s) %s\"", valobj_sp->GetTypeName().AsCString(""), @@ -999,7 +998,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( Status error; ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true)); if (error.Fail()) { - valobj_sp->GetExpressionPath(var_expr_path_strm, false); + valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( "could not get item 0 for \"(%s) %s\"", valobj_sp->GetTypeName().AsCString(""), @@ -1013,7 +1012,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true); if (!child_valobj_sp) { - valobj_sp->GetExpressionPath(var_expr_path_strm, false); + valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( "bitfield range %ld-%ld is not valid for \"(%s) %s\"", child_index, final_index, valobj_sp->GetTypeName().AsCString(""), @@ -1025,7 +1024,6 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( return ValueObjectSP(); } - separator_idx = var_expr.find_first_of(".-["); if (use_dynamic != eNoDynamicValues) { ValueObjectSP dynamic_value_sp( child_valobj_sp->GetDynamicValue(use_dynamic)); @@ -1039,7 +1037,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( default: // Failure... { - valobj_sp->GetExpressionPath(var_expr_path_strm, false); + valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( "unexpected char '%c' encountered after \"%s\" in \"%s\"", separator_type, var_expr_path_strm.GetData(), @@ -1051,9 +1049,6 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( if (child_valobj_sp) valobj_sp = child_valobj_sp; - - if (var_expr.empty()) - break; } if (valobj_sp) { if (deref) { @@ -1321,14 +1316,13 @@ lldb::ValueObjectSP StackFrame::GuessValueForAddress(lldb::addr_t addr) { pc_range.GetBaseAddress() = GetFrameCodeAddress(); pc_range.SetByteSize(target_arch.GetMaximumOpcodeByteSize()); - ExecutionContext exe_ctx(shared_from_this()); - const char *plugin_name = nullptr; const char *flavor = nullptr; const bool prefer_file_cache = false; - DisassemblerSP disassembler_sp = Disassembler::DisassembleRange( - target_arch, plugin_name, flavor, exe_ctx, pc_range, prefer_file_cache); + DisassemblerSP disassembler_sp = + Disassembler::DisassembleRange(target_arch, plugin_name, flavor, + *target_sp, pc_range, prefer_file_cache); if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) { return ValueObjectSP(); @@ -1500,7 +1494,7 @@ lldb::ValueObjectSP DoGuessValueAt(StackFrame &frame, ConstString reg, // +18 that assigns to rdi, and calls itself recursively for that dereference // DoGuessValueAt(frame, rdi, 8, dis, vars, 0x18) finds the instruction at // +14 that assigns to rdi, and calls itself recursively for that - // derefernece + // dereference // DoGuessValueAt(frame, rbp, -8, dis, vars, 0x14) finds "f" in the // variable list. // Returns a ValueObject for f. (That's what was stored at rbp-8 at +14) @@ -1702,13 +1696,12 @@ lldb::ValueObjectSP StackFrame::GuessValueForRegisterAndOffset(ConstString reg, return ValueObjectSP(); } - ExecutionContext exe_ctx(shared_from_this()); - const char *plugin_name = nullptr; const char *flavor = nullptr; const bool prefer_file_cache = false; - DisassemblerSP disassembler_sp = Disassembler::DisassembleRange( - target_arch, plugin_name, flavor, exe_ctx, pc_range, prefer_file_cache); + DisassemblerSP disassembler_sp = + Disassembler::DisassembleRange(target_arch, plugin_name, flavor, + *target_sp, pc_range, prefer_file_cache); if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) { return ValueObjectSP(); @@ -1863,6 +1856,7 @@ void StackFrame::UpdatePreviousFrameFromCurrentFrame(StackFrame &curr_frame) { m_concrete_frame_index = curr_frame.m_concrete_frame_index; m_reg_context_sp = curr_frame.m_reg_context_sp; m_frame_code_addr = curr_frame.m_frame_code_addr; + m_behaves_like_zeroth_frame = curr_frame.m_behaves_like_zeroth_frame; assert(!m_sc.target_sp || !curr_frame.m_sc.target_sp || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get()); assert(!m_sc.module_sp || !curr_frame.m_sc.module_sp || @@ -1942,16 +1936,14 @@ bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source, const uint32_t disasm_lines = debugger.GetDisassemblyLineCount(); if (disasm_lines > 0) { const ArchSpec &target_arch = target->GetArchitecture(); - AddressRange pc_range; - pc_range.GetBaseAddress() = GetFrameCodeAddress(); - pc_range.SetByteSize(disasm_lines * - target_arch.GetMaximumOpcodeByteSize()); const char *plugin_name = nullptr; const char *flavor = nullptr; const bool mixed_source_and_assembly = false; Disassembler::Disassemble( target->GetDebugger(), target_arch, plugin_name, flavor, - exe_ctx, pc_range, disasm_lines, mixed_source_and_assembly, 0, + exe_ctx, GetFrameCodeAddress(), + {Disassembler::Limit::Instructions, disasm_lines}, + mixed_source_and_assembly, 0, Disassembler::eOptionMarkPCAddress, strm); } } diff --git a/gnu/llvm/lldb/source/Target/StackFrameList.cpp b/gnu/llvm/lldb/source/Target/StackFrameList.cpp index 87b49849bc9..e4f5d302836 100644 --- a/gnu/llvm/lldb/source/Target/StackFrameList.cpp +++ b/gnu/llvm/lldb/source/Target/StackFrameList.cpp @@ -1,4 +1,4 @@ -//===-- StackFrameList.cpp --------------------------------------*- C++ -*-===// +//===-- StackFrameList.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -218,17 +218,14 @@ void StackFrameList::SetCurrentInlinedDepth(uint32_t new_depth) { } void StackFrameList::GetOnlyConcreteFramesUpTo(uint32_t end_idx, - Unwind *unwinder) { + 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); + uint32_t num_frames = unwinder.GetFramesUpTo(end_idx); if (num_frames <= end_idx + 1) { // Done unwinding. m_concrete_frames_fetched = UINT32_MAX; @@ -239,13 +236,22 @@ void StackFrameList::GetOnlyConcreteFramesUpTo(uint32_t end_idx, m_frames.resize(num_frames); } +/// A sequence of calls that comprise some portion of a backtrace. Each frame +/// is represented as a pair of a callee (Function *) and an address within the +/// callee. +struct CallDescriptor { + Function *func; + CallEdge::AddrType address_type = CallEdge::AddrType::Call; + addr_t address = LLDB_INVALID_ADDRESS; +}; +using CallSequence = std::vector; + /// 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, ExecutionContext &exe_ctx, Target &target, - addr_t return_pc, - std::vector &path, + addr_t return_pc, CallSequence &path, ModuleList &images, Log *log) { LLDB_LOG(log, "Finding frames between {0} and {1}, retn-pc={2:x}", begin.GetDisplayName(), end.GetDisplayName(), return_pc); @@ -278,24 +284,27 @@ static void FindInterveningFrames(Function &begin, Function &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 = {}; + CallSequence active_path = {}; + CallSequence solution_path = {}; llvm::SmallPtrSet visited_nodes = {}; bool ambiguous = false; Function *end; ModuleList &images; + Target ⌖ ExecutionContext &context; - DFS(Function *end, ModuleList &images, ExecutionContext &context) - : end(end), images(images), context(context) {} + DFS(Function *end, ModuleList &images, Target &target, + ExecutionContext &context) + : end(end), images(images), target(target), context(context) {} - void search(Function &first_callee, std::vector &path) { - dfs(first_callee); + void search(CallEdge &first_edge, Function &first_callee, + CallSequence &path) { + dfs(first_edge, first_callee); if (!ambiguous) path = std::move(solution_path); } - void dfs(Function &callee) { + void dfs(CallEdge ¤t_edge, Function &callee) { // Found a path to the target function. if (&callee == end) { if (solution_path.empty()) @@ -315,13 +324,16 @@ static void FindInterveningFrames(Function &begin, Function &end, } // Search the calls made from this callee. - active_path.push_back(&callee); + active_path.push_back(CallDescriptor{&callee}); for (const auto &edge : callee.GetTailCallingEdges()) { Function *next_callee = edge->GetCallee(images, context); if (!next_callee) continue; - dfs(*next_callee); + std::tie(active_path.back().address_type, active_path.back().address) = + edge->GetCallerAddress(callee, target); + + dfs(*edge, *next_callee); if (ambiguous) return; } @@ -329,7 +341,7 @@ static void FindInterveningFrames(Function &begin, Function &end, } }; - DFS(&end, images, exe_ctx).search(*first_callee, path); + DFS(&end, images, target, exe_ctx).search(*first_edge, *first_callee, path); } /// Given that \p next_frame will be appended to the frame list, synthesize @@ -348,6 +360,11 @@ static void FindInterveningFrames(Function &begin, Function &end, /// | ... | <- Not-yet-visited frames. /// -------------- void StackFrameList::SynthesizeTailCallFrames(StackFrame &next_frame) { + // Cannot synthesize tail call frames when the stack is empty (there is no + // "previous" frame). + if (m_frames.empty()) + return; + TargetSP target_sp = next_frame.CalculateTarget(); if (!target_sp) return; @@ -358,7 +375,6 @@ void StackFrameList::SynthesizeTailCallFrames(StackFrame &next_frame) { 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 @@ -378,7 +394,7 @@ void StackFrameList::SynthesizeTailCallFrames(StackFrame &next_frame) { // Try to find the unique sequence of (tail) calls which led from next_frame // to prev_frame. - std::vector path; + CallSequence path; addr_t return_pc = next_reg_ctx_sp->GetPC(); Target &target = *target_sp.get(); ModuleList &images = next_frame.CalculateTarget()->GetImages(); @@ -388,14 +404,17 @@ void StackFrameList::SynthesizeTailCallFrames(StackFrame &next_frame) { path, images, log); // Push synthetic tail call frames. - for (Function *callee : llvm::reverse(path)) { + for (auto calleeInfo : llvm::reverse(path)) { + Function *callee = calleeInfo.func; 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); - constexpr bool behaves_like_zeroth_frame = false; + addr_t pc = calleeInfo.address; + // If the callee address refers to the call instruction, we do not want to + // subtract 1 from this value. + const bool behaves_like_zeroth_frame = + calleeInfo.address_type == CallEdge::AddrType::Call; SymbolContext sc; callee->CalculateSymbolContext(&sc); auto synth_frame = std::make_shared( @@ -403,7 +422,7 @@ void StackFrameList::SynthesizeTailCallFrames(StackFrame &next_frame) { cfa_is_valid, pc, StackFrame::Kind::Artificial, behaves_like_zeroth_frame, &sc); m_frames.push_back(synth_frame); - LLDB_LOG(log, "Pushed frame {0}", callee->GetDisplayName()); + LLDB_LOG(log, "Pushed frame {0} at {1:x}", callee->GetDisplayName(), pc); } // If any frames were created, adjust next_frame's index. @@ -421,7 +440,7 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) { if (m_frames.size() > end_idx || GetAllFramesFetched()) return; - Unwind *unwinder = m_thread.GetUnwinder(); + Unwind &unwinder = m_thread.GetUnwinder(); if (!m_show_inlined_frames) { GetOnlyConcreteFramesUpTo(end_idx, unwinder); @@ -459,9 +478,8 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) { RegisterContextSP reg_ctx_sp(m_thread.GetRegisterContext()); if (reg_ctx_sp) { - const bool success = unwinder && - unwinder->GetFrameInfoAtIndex( - idx, cfa, pc, behaves_like_zeroth_frame); + const bool success = unwinder.GetFrameInfoAtIndex( + idx, cfa, pc, behaves_like_zeroth_frame); // 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. @@ -480,9 +498,8 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) { cfa = unwind_frame_sp->m_id.GetCallFrameAddress(); } } else { - const bool success = unwinder && - unwinder->GetFrameInfoAtIndex( - idx, cfa, pc, behaves_like_zeroth_frame); + const bool success = + unwinder.GetFrameInfoAtIndex(idx, cfa, pc, behaves_like_zeroth_frame); if (!success) { // We've gotten to the end of the stack. SetAllFramesFetched(); @@ -665,31 +682,28 @@ StackFrameSP StackFrameList::GetFrameAtIndex(uint32_t idx) { // GetFramesUpTo. frame_sp = m_frames[idx]; } else { - Unwind *unwinder = m_thread.GetUnwinder(); - if (unwinder) { - addr_t pc, cfa; - bool behaves_like_zeroth_frame = (idx == 0); - if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc, - behaves_like_zeroth_frame)) { - const bool cfa_is_valid = true; - frame_sp = std::make_shared( - m_thread.shared_from_this(), idx, idx, cfa, cfa_is_valid, pc, - StackFrame::Kind::Regular, behaves_like_zeroth_frame, nullptr); - - Function *function = - frame_sp->GetSymbolContext(eSymbolContextFunction).function; - if (function) { - // When we aren't showing inline functions we always use the top - // most function block as the scope. - frame_sp->SetSymbolContextScope(&function->GetBlock(false)); - } else { - // Set the symbol scope from the symbol regardless if it is nullptr - // or valid. - frame_sp->SetSymbolContextScope( - frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol); - } - SetFrameAtIndex(idx, frame_sp); + addr_t pc, cfa; + bool behaves_like_zeroth_frame = (idx == 0); + if (m_thread.GetUnwinder().GetFrameInfoAtIndex( + idx, cfa, pc, behaves_like_zeroth_frame)) { + const bool cfa_is_valid = true; + frame_sp = std::make_shared( + m_thread.shared_from_this(), idx, idx, cfa, cfa_is_valid, pc, + StackFrame::Kind::Regular, behaves_like_zeroth_frame, nullptr); + + Function *function = + frame_sp->GetSymbolContext(eSymbolContextFunction).function; + if (function) { + // When we aren't showing inline functions we always use the top + // most function block as the scope. + frame_sp->SetSymbolContextScope(&function->GetBlock(false)); + } else { + // Set the symbol scope from the symbol regardless if it is nullptr + // or valid. + frame_sp->SetSymbolContextScope( + frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol); } + SetFrameAtIndex(idx, frame_sp); } } } else if (original_idx == 0) { diff --git a/gnu/llvm/lldb/source/Target/StackFrameRecognizer.cpp b/gnu/llvm/lldb/source/Target/StackFrameRecognizer.cpp index 75a6cd21512..7dc6e9d1e49 100644 --- a/gnu/llvm/lldb/source/Target/StackFrameRecognizer.cpp +++ b/gnu/llvm/lldb/source/Target/StackFrameRecognizer.cpp @@ -1,4 +1,4 @@ -//===-- StackFrameRecognizer.cpp --------------------------------*- C++ -*-===// +//===-- StackFrameRecognizer.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -50,31 +50,42 @@ ScriptedStackFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame) { class StackFrameRecognizerManagerImpl { public: - void AddRecognizer(StackFrameRecognizerSP recognizer, - ConstString module, ConstString symbol, + void AddRecognizer(StackFrameRecognizerSP recognizer, ConstString module, + llvm::ArrayRef symbols, bool first_instruction_only) { - m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer, false, module, RegularExpressionSP(), - symbol, RegularExpressionSP(), - first_instruction_only}); + m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer, + false, module, RegularExpressionSP(), symbols, + 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}); + m_recognizers.push_front( + {(uint32_t)m_recognizers.size(), false, recognizer, true, ConstString(), + module, std::vector(), symbol, first_instruction_only}); } - void ForEach( - std::function const &callback) { + void ForEach(std::function< + void(uint32_t recognized_id, std::string recognizer_name, + std::string module, llvm::ArrayRef symbols, + bool regexp)> 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); + std::string module_name; + std::string symbol_name; + + if (entry.module_regexp) + module_name = entry.module_regexp->GetText().str(); + if (entry.symbol_regexp) + symbol_name = entry.symbol_regexp->GetText().str(); + + callback(entry.recognizer_id, entry.recognizer->GetName(), module_name, + llvm::makeArrayRef(ConstString(symbol_name)), true); + } else { - callback(entry.recognizer_id, entry.recognizer->GetName(), entry.module.GetCString(), - entry.symbol.GetCString(), false); + callback(entry.recognizer_id, entry.recognizer->GetName(), + entry.module.GetCString(), entry.symbols, false); } } } @@ -91,8 +102,8 @@ public: } StackFrameRecognizerSP GetRecognizerForFrame(StackFrameSP frame) { - const SymbolContext &symctx = - frame->GetSymbolContext(eSymbolContextModule | eSymbolContextFunction); + const SymbolContext &symctx = frame->GetSymbolContext( + eSymbolContextModule | eSymbolContextFunction | eSymbolContextSymbol); ConstString function_name = symctx.GetFunctionName(); ModuleSP module_sp = symctx.module_sp; if (!module_sp) return StackFrameRecognizerSP(); @@ -110,8 +121,9 @@ public: if (entry.module_regexp) if (!entry.module_regexp->Execute(module_name.GetStringRef())) continue; - if (entry.symbol) - if (entry.symbol != function_name) continue; + if (!entry.symbols.empty()) + if (!llvm::is_contained(entry.symbols, function_name)) + continue; if (entry.symbol_regexp) if (!entry.symbol_regexp->Execute(function_name.GetStringRef())) @@ -139,7 +151,7 @@ public: bool is_regexp; ConstString module; RegularExpressionSP module_regexp; - ConstString symbol; + std::vector symbols; RegularExpressionSP symbol_regexp; bool first_instruction_only; }; @@ -155,9 +167,9 @@ StackFrameRecognizerManagerImpl &GetStackFrameRecognizerManagerImpl() { void StackFrameRecognizerManager::AddRecognizer( StackFrameRecognizerSP recognizer, ConstString module, - ConstString symbol, bool first_instruction_only) { - GetStackFrameRecognizerManagerImpl().AddRecognizer(recognizer, module, symbol, - first_instruction_only); + llvm::ArrayRef symbols, bool first_instruction_only) { + GetStackFrameRecognizerManagerImpl().AddRecognizer( + recognizer, module, symbols, first_instruction_only); } void StackFrameRecognizerManager::AddRecognizer( @@ -168,8 +180,9 @@ void StackFrameRecognizerManager::AddRecognizer( } void StackFrameRecognizerManager::ForEach( - std::function const &callback) { + std::function symbols, + bool regexp)> const &callback) { GetStackFrameRecognizerManagerImpl().ForEach(callback); } diff --git a/gnu/llvm/lldb/source/Target/StackID.cpp b/gnu/llvm/lldb/source/Target/StackID.cpp index a8f6b787f4b..410d5b7e820 100644 --- a/gnu/llvm/lldb/source/Target/StackID.cpp +++ b/gnu/llvm/lldb/source/Target/StackID.cpp @@ -1,4 +1,4 @@ -//===-- StackID.cpp ---------------------------------------------*- C++ -*-===// +//===-- StackID.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/StopInfo.cpp b/gnu/llvm/lldb/source/Target/StopInfo.cpp index 28179b7e1ce..7e830c6e2be 100644 --- a/gnu/llvm/lldb/source/Target/StopInfo.cpp +++ b/gnu/llvm/lldb/source/Target/StopInfo.cpp @@ -1,4 +1,4 @@ -//===-- StopInfo.cpp --------------------------------------------*- C++ -*-===// +//===-- StopInfo.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -206,7 +206,7 @@ public: strm.Printf("breakpoint "); bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief); - m_description = strm.GetString(); + m_description = std::string(strm.GetString()); } else { StreamString strm; if (m_break_id != LLDB_INVALID_BREAK_ID) { @@ -239,7 +239,7 @@ public: " which has been deleted - was at 0x%" PRIx64, m_value, m_address); - m_description = strm.GetString(); + m_description = std::string(strm.GetString()); } } } @@ -453,7 +453,7 @@ protected: } else { LLDB_LOGF(log, "Condition evaluated for breakpoint %s on thread " - "0x%llx conditon_says_stop: %i.", + "0x%llx condition_says_stop: %i.", loc_desc.GetData(), static_cast(thread_sp->GetID()), condition_says_stop); @@ -631,7 +631,7 @@ public: if (m_description.empty()) { StreamString strm; strm.Printf("watchpoint %" PRIi64, m_value); - m_description = strm.GetString(); + m_description = std::string(strm.GetString()); } return m_description.c_str(); } @@ -969,7 +969,7 @@ public: strm.Printf("signal %s", signal_name); else strm.Printf("signal %" PRIi64, m_value); - m_description = strm.GetString(); + m_description = std::string(strm.GetString()); } } return m_description.c_str(); @@ -1034,7 +1034,7 @@ public: if (m_description.empty()) { StreamString strm; m_plan_sp->GetDescription(&strm, eDescriptionLevelBrief); - m_description = strm.GetString(); + m_description = std::string(strm.GetString()); } return m_description.c_str(); } diff --git a/gnu/llvm/lldb/source/Target/StructuredDataPlugin.cpp b/gnu/llvm/lldb/source/Target/StructuredDataPlugin.cpp index a22902d99f7..bd899d2f768 100644 --- a/gnu/llvm/lldb/source/Target/StructuredDataPlugin.cpp +++ b/gnu/llvm/lldb/source/Target/StructuredDataPlugin.cpp @@ -1,4 +1,4 @@ -//===-- StructuredDataPlugin.cpp --------------------------------*- C++ -*-===// +//===-- StructuredDataPlugin.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/SystemRuntime.cpp b/gnu/llvm/lldb/source/Target/SystemRuntime.cpp index 286bea09f85..cd3d8ba2c7b 100644 --- a/gnu/llvm/lldb/source/Target/SystemRuntime.cpp +++ b/gnu/llvm/lldb/source/Target/SystemRuntime.cpp @@ -1,4 +1,4 @@ -//===-- SystemRuntime.cpp ---------------------------------------*- C++ -*-===// +//===-- SystemRuntime.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/Target.cpp b/gnu/llvm/lldb/source/Target/Target.cpp index 83e6f306266..19d0c3d477e 100644 --- a/gnu/llvm/lldb/source/Target/Target.cpp +++ b/gnu/llvm/lldb/source/Target/Target.cpp @@ -1,4 +1,4 @@ -//===-- Target.cpp ----------------------------------------------*- C++ -*-===// +//===-- Target.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -27,6 +27,7 @@ #include "lldb/Core/StreamFile.h" #include "lldb/Core/StructuredDataImpl.h" #include "lldb/Core/ValueObject.h" +#include "lldb/Expression/ExpressionVariable.h" #include "lldb/Expression/REPL.h" #include "lldb/Expression/UserExpression.h" #include "lldb/Host/Host.h" @@ -36,8 +37,6 @@ #include "lldb/Interpreter/OptionGroupWatchpoint.h" #include "lldb/Interpreter/OptionValues.h" #include "lldb/Interpreter/Property.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangASTImporter.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/Symbol.h" @@ -91,7 +90,7 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, m_mutex(), m_arch(target_arch), m_images(this), m_section_load_history(), m_breakpoint_list(false), m_internal_breakpoint_list(true), m_watchpoint_list(), m_process_sp(), m_search_filter_sp(), - m_image_search_paths(ImageSearchPathsChanged, this), m_ast_importer_sp(), + m_image_search_paths(ImageSearchPathsChanged, this), m_source_manager_up(), m_stop_hooks(), m_stop_hook_next_id(0), m_valid(true), m_suppress_stop_hooks(false), m_is_dummy_target(is_dummy_target), @@ -114,6 +113,8 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, target_arch.GetArchitectureName(), target_arch.GetTriple().getTriple().c_str()); } + + UpdateLaunchInfoFromProperties(); } Target::~Target() { @@ -128,12 +129,13 @@ void Target::PrimeFromDummyTarget(Target *target) { m_stop_hooks = target->m_stop_hooks; - for (BreakpointSP breakpoint_sp : target->m_breakpoint_list.Breakpoints()) { + for (const auto &breakpoint_sp : target->m_breakpoint_list.Breakpoints()) { if (breakpoint_sp->IsInternal()) continue; - BreakpointSP new_bp(new Breakpoint(*this, *breakpoint_sp.get())); - AddBreakpoint(new_bp, false); + BreakpointSP new_bp( + Breakpoint::CopyFromBreakpoint(shared_from_this(), *breakpoint_sp)); + AddBreakpoint(std::move(new_bp), false); } for (auto bp_name_entry : target->m_breakpoint_names) { @@ -622,7 +624,7 @@ BreakpointSP Target::CreateBreakpoint(SearchFilterSP &filter_sp, 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()); + resolver_sp->SetBreakpoint(bp_sp); AddBreakpoint(bp_sp, internal); } return bp_sp; @@ -1109,8 +1111,8 @@ Status Target::CreateBreakpointsFromFile(const FileSpec &file, !Breakpoint::SerializedBreakpointMatchesNames(bkpt_data_sp, names)) continue; - BreakpointSP bkpt_sp = - Breakpoint::CreateFromStructuredData(*this, bkpt_data_sp, error); + BreakpointSP bkpt_sp = Breakpoint::CreateFromStructuredData( + shared_from_this(), bkpt_data_sp, error); if (!error.Success()) { error.SetErrorStringWithFormat( "Error restoring breakpoint %zu from %s: %s.", i, @@ -1378,7 +1380,6 @@ void Target::ClearModules(bool delete_locations) { m_section_load_history.Clear(); m_images.Clear(); m_scratch_type_system_map.Clear(); - m_ast_importer_sp.reset(); } void Target::DidExec() { @@ -1964,8 +1965,9 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, module_sp = m_images.FindFirstModule(module_spec); if (!module_sp) { - ModuleSP old_module_sp; // This will get filled in if we have a new version - // of the library + llvm::SmallVector + old_modules; // This will get filled in if we have a new version + // of the library bool did_create_module = false; FileSpecList search_paths = GetExecutableSearchPaths(); // If there are image search path entries, try to use them first to acquire @@ -1978,7 +1980,7 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, transformed_spec.GetFileSpec().GetFilename() = module_spec.GetFileSpec().GetFilename(); error = ModuleList::GetSharedModule(transformed_spec, module_sp, - &search_paths, &old_module_sp, + &search_paths, &old_modules, &did_create_module); } } @@ -1996,7 +1998,7 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, // We have a UUID, it is OK to check the global module list... error = ModuleList::GetSharedModule(module_spec, module_sp, &search_paths, - &old_module_sp, &did_create_module); + &old_modules, &did_create_module); } if (!module_sp) { @@ -2005,7 +2007,7 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, if (m_platform_sp) { error = m_platform_sp->GetSharedModule( module_spec, m_process_sp.get(), module_sp, &search_paths, - &old_module_sp, &did_create_module); + &old_modules, &did_create_module); } else { error.SetErrorString("no platform is currently set"); } @@ -2056,18 +2058,18 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, // this target. So let's remove the UUID from the module list, and look // in the target's module list. Only do this if there is SOMETHING else // in the module spec... - if (!old_module_sp) { - if (module_spec.GetUUID().IsValid() && - !module_spec.GetFileSpec().GetFilename().IsEmpty() && - !module_spec.GetFileSpec().GetDirectory().IsEmpty()) { - ModuleSpec module_spec_copy(module_spec.GetFileSpec()); - module_spec_copy.GetUUID().Clear(); - - ModuleList found_modules; - m_images.FindModules(module_spec_copy, found_modules); - if (found_modules.GetSize() == 1) - old_module_sp = found_modules.GetModuleAtIndex(0); - } + if (module_spec.GetUUID().IsValid() && + !module_spec.GetFileSpec().GetFilename().IsEmpty() && + !module_spec.GetFileSpec().GetDirectory().IsEmpty()) { + ModuleSpec module_spec_copy(module_spec.GetFileSpec()); + module_spec_copy.GetUUID().Clear(); + + ModuleList found_modules; + m_images.FindModules(module_spec_copy, found_modules); + found_modules.ForEach([&](const ModuleSP &found_module) -> bool { + old_modules.push_back(found_module); + return true; + }); } // Preload symbols outside of any lock, so hopefully we can do this for @@ -2075,14 +2077,67 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, if (GetPreloadSymbols()) module_sp->PreloadSymbols(); - if (old_module_sp && m_images.GetIndexForModule(old_module_sp.get()) != - LLDB_INVALID_INDEX32) { - m_images.ReplaceModule(old_module_sp, module_sp); + llvm::SmallVector replaced_modules; + for (ModuleSP &old_module_sp : old_modules) { + if (m_images.GetIndexForModule(old_module_sp.get()) != + LLDB_INVALID_INDEX32) { + if (replaced_modules.empty()) + m_images.ReplaceModule(old_module_sp, module_sp); + else + m_images.Remove(old_module_sp); + + replaced_modules.push_back(std::move(old_module_sp)); + } + } + + if (replaced_modules.size() > 1) { + // The same new module replaced multiple old modules + // simultaneously. It's not clear this should ever + // happen (if we always replace old modules as we add + // new ones, presumably we should never have more than + // one old one). If there are legitimate cases where + // this happens, then the ModuleList::Notifier interface + // may need to be adjusted to allow reporting this. + // In the meantime, just log that this has happened; just + // above we called ReplaceModule on the first one, and Remove + // on the rest. + if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET | + LIBLLDB_LOG_MODULES)) { + StreamString message; + auto dump = [&message](Module &dump_module) -> void { + UUID dump_uuid = dump_module.GetUUID(); + + message << '['; + dump_module.GetDescription(message.AsRawOstream()); + message << " (uuid "; + + if (dump_uuid.IsValid()) + dump_uuid.Dump(&message); + else + message << "not specified"; + + message << ")]"; + }; + + message << "New module "; + dump(*module_sp); + message.AsRawOstream() + << llvm::formatv(" simultaneously replaced {0} old modules: ", + replaced_modules.size()); + for (ModuleSP &replaced_module_sp : replaced_modules) + dump(*replaced_module_sp); + + log->PutString(message.GetString()); + } + } + + if (replaced_modules.empty()) + m_images.Append(module_sp, notify); + + for (ModuleSP &old_module_sp : replaced_modules) { Module *old_module_ptr = old_module_sp.get(); old_module_sp.reset(); ModuleList::RemoveSharedModuleIfOrphaned(old_module_ptr); - } else { - m_images.Append(module_sp, notify); } } else module_sp.reset(); @@ -2258,16 +2313,6 @@ Target::GetUtilityFunctionForLanguage(const char *text, return utility_fn; } -ClangASTImporterSP Target::GetClangASTImporter() { - if (m_valid) { - if (!m_ast_importer_sp) { - m_ast_importer_sp = std::make_shared(); - } - return m_ast_importer_sp; - } - return ClangASTImporterSP(); -} - void Target::SettingsInitialize() { Process::SettingsInitialize(); } void Target::SettingsTerminate() { Process::SettingsTerminate(); } @@ -2368,11 +2413,9 @@ ExpressionResults Target::EvaluateExpression( } else { llvm::StringRef prefix = GetExpressionPrefixContents(); Status error; - execution_results = - UserExpression::Evaluate(exe_ctx, options, expr, prefix, - result_valobj_sp, error, fixed_expression, - nullptr, // Module - ctx_obj); + execution_results = UserExpression::Evaluate(exe_ctx, options, expr, prefix, + result_valobj_sp, error, + fixed_expression, ctx_obj); } return execution_results; @@ -2412,21 +2455,13 @@ lldb::addr_t Target::GetPersistentSymbol(ConstString name) { llvm::Expected Target::GetEntryPointAddress() { Module *exe_module = GetExecutableModulePointer(); - llvm::Error error = llvm::Error::success(); - assert(!error); // Check the success value when assertions are enabled. - if (!exe_module || !exe_module->GetObjectFile()) { - error = llvm::make_error("No primary executable found", - llvm::inconvertibleErrorCode()); - } else { + // Try to find the entry point address in the primary executable. + const bool has_primary_executable = exe_module && exe_module->GetObjectFile(); + if (has_primary_executable) { Address entry_addr = exe_module->GetObjectFile()->GetEntryPointAddress(); if (entry_addr.IsValid()) return entry_addr; - - error = llvm::make_error( - "Could not find entry point address for executable module \"" + - exe_module->GetFileSpec().GetFilename().GetStringRef() + "\"", - llvm::inconvertibleErrorCode()); } const ModuleList &modules = GetImages(); @@ -2437,14 +2472,21 @@ llvm::Expected Target::GetEntryPointAddress() { continue; Address entry_addr = module_sp->GetObjectFile()->GetEntryPointAddress(); - if (entry_addr.IsValid()) { - // Discard the error. - llvm::consumeError(std::move(error)); + if (entry_addr.IsValid()) return entry_addr; - } } - return std::move(error); + // We haven't found the entry point address. Return an appropriate error. + if (!has_primary_executable) + return llvm::make_error( + "No primary executable found and could not find entry point address in " + "any executable module", + llvm::inconvertibleErrorCode()); + + return llvm::make_error( + "Could not find entry point address for primary executable module \"" + + exe_module->GetFileSpec().GetFilename().GetStringRef() + "\"", + llvm::inconvertibleErrorCode()); } lldb::addr_t Target::GetCallableLoadAddress(lldb::addr_t load_addr, @@ -2469,7 +2511,7 @@ lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t addr) { SourceManager &Target::GetSourceManager() { if (!m_source_manager_up) - m_source_manager_up.reset(new SourceManager(shared_from_this())); + m_source_manager_up = std::make_unique(shared_from_this()); return *m_source_manager_up; } @@ -2567,7 +2609,7 @@ void Target::RunStopHooks() { if (!any_active_hooks) return; - CommandReturnObject result; + CommandReturnObject result(m_debugger.GetUseColor()); std::vector exc_ctx_with_reasons; std::vector sym_ctx_with_reasons; @@ -2691,8 +2733,10 @@ Status Target::Install(ProcessLaunchInfo *launch_info) { if (platform_sp) { if (platform_sp->IsRemote()) { if (platform_sp->IsConnected()) { - // Install all files that have an install path, and always install the - // main executable when connected to a remote platform + // Install all files that have an install path when connected to a + // remote platform. If target.auto-install-main-executable is set then + // also install the main executable even if it does not have an explicit + // install path specified. const ModuleList &modules = GetImages(); const size_t num_images = modules.GetSize(); for (size_t idx = 0; idx < num_images; ++idx) { @@ -2703,10 +2747,8 @@ Status Target::Install(ProcessLaunchInfo *launch_info) { if (local_file) { FileSpec remote_file(module_sp->GetRemoteInstallFileSpec()); if (!remote_file) { - if (is_main_executable) // TODO: add setting for always - // installing main executable??? - { - // Always install the main executable + if (is_main_executable && GetAutoInstallMainExecutable()) { + // Automatically install the main executable. remote_file = platform_sp->GetRemoteWorkingDirectory(); remote_file.AppendPathComponent( module_sp->GetFileSpec().GetFilename().GetCString()); @@ -2971,11 +3013,6 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { } } m_process_sp->RestoreProcessEvents(); - } else { - Status error2; - error2.SetErrorStringWithFormat("process launch failed: %s", - error.AsCString()); - error = error2; } return error; } @@ -3153,7 +3190,7 @@ Target::StopHook::StopHook(const StopHook &rhs) m_thread_spec_up(), m_active(rhs.m_active), m_auto_continue(rhs.m_auto_continue) { if (rhs.m_thread_spec_up) - m_thread_spec_up.reset(new ThreadSpec(*rhs.m_thread_spec_up)); + m_thread_spec_up = std::make_unique(*rhs.m_thread_spec_up); } Target::StopHook::~StopHook() = default; @@ -3360,16 +3397,13 @@ enum { class TargetOptionValueProperties : public OptionValueProperties { public: - TargetOptionValueProperties(ConstString name) - : OptionValueProperties(name), m_target(nullptr), m_got_host_env(false) {} + TargetOptionValueProperties(ConstString name) : OptionValueProperties(name) {} // This constructor is used when creating TargetOptionValueProperties when it // is part of a new lldb_private::Target instance. It will copy all current // global property values as needed - TargetOptionValueProperties(Target *target, - const TargetPropertiesSP &target_properties_sp) - : OptionValueProperties(*target_properties_sp->GetValueProperties()), - m_target(target), m_got_host_env(false) {} + TargetOptionValueProperties(const TargetPropertiesSP &target_properties_sp) + : OptionValueProperties(*target_properties_sp->GetValueProperties()) {} const Property *GetPropertyAtIndex(const ExecutionContext *exe_ctx, bool will_modify, @@ -3377,9 +3411,6 @@ public: // When getting the value for a key from the target options, we will always // try and grab the setting from the current target if there is one. Else // we just use the one from this instance. - if (idx == ePropertyEnvVars) - GetHostEnvironmentIfNeeded(); - if (exe_ctx) { Target *target = exe_ctx->GetTargetPtr(); if (target) { @@ -3392,49 +3423,14 @@ public: } return ProtectedGetPropertyAtIndex(idx); } - - lldb::TargetSP GetTargetSP() { return m_target->shared_from_this(); } - -protected: - void GetHostEnvironmentIfNeeded() const { - if (!m_got_host_env) { - if (m_target) { - m_got_host_env = true; - const uint32_t idx = ePropertyInheritEnv; - if (GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0)) { - PlatformSP platform_sp(m_target->GetPlatform()); - if (platform_sp) { - Environment env = platform_sp->GetEnvironment(); - OptionValueDictionary *env_dict = - GetPropertyAtIndexAsOptionValueDictionary(nullptr, - ePropertyEnvVars); - if (env_dict) { - const bool can_replace = false; - for (const auto &KV : env) { - // Don't allow existing keys to be replaced with ones we get - // from the platform environment - env_dict->SetValueForKey( - ConstString(KV.first()), - OptionValueSP(new OptionValueString(KV.second.c_str())), - can_replace); - } - } - } - } - } - } - } - Target *m_target; - mutable bool m_got_host_env; }; // TargetProperties -#define LLDB_PROPERTIES_experimental +#define LLDB_PROPERTIES_target_experimental #include "TargetProperties.inc" enum { -#define LLDB_PROPERTIES_experimental +#define LLDB_PROPERTIES_target_experimental #include "TargetPropertiesEnum.inc" }; @@ -3448,15 +3444,15 @@ public: TargetExperimentalProperties::TargetExperimentalProperties() : Properties(OptionValuePropertiesSP( new TargetExperimentalOptionValueProperties())) { - m_collection_sp->Initialize(g_experimental_properties); + m_collection_sp->Initialize(g_target_experimental_properties); } // TargetProperties TargetProperties::TargetProperties(Target *target) - : Properties(), m_launch_info() { + : Properties(), m_launch_info(), m_target(target) { if (target) { m_collection_sp = std::make_shared( - target, Target::GetGlobalProperties()); + Target::GetGlobalProperties()); // Set callbacks to update launch_info whenever "settins set" updated any // of these properties @@ -3466,6 +3462,10 @@ TargetProperties::TargetProperties(Target *target) ePropertyRunArgs, [this] { RunArgsValueChangedCallback(); }); m_collection_sp->SetValueChangedCallback( ePropertyEnvVars, [this] { EnvVarsValueChangedCallback(); }); + m_collection_sp->SetValueChangedCallback( + ePropertyUnsetEnvVars, [this] { EnvVarsValueChangedCallback(); }); + m_collection_sp->SetValueChangedCallback( + ePropertyInheritEnv, [this] { EnvVarsValueChangedCallback(); }); m_collection_sp->SetValueChangedCallback( ePropertyInputPath, [this] { InputPathValueChangedCallback(); }); m_collection_sp->SetValueChangedCallback( @@ -3480,29 +3480,19 @@ TargetProperties::TargetProperties(Target *target) m_collection_sp->SetValueChangedCallback( ePropertyDisableSTDIO, [this] { DisableSTDIOValueChangedCallback(); }); - m_experimental_properties_up.reset(new TargetExperimentalProperties()); + m_experimental_properties_up = + std::make_unique(); m_collection_sp->AppendProperty( ConstString(Properties::GetExperimentalSettingsName()), ConstString("Experimental settings - setting these won't produce " "errors if the setting is not present."), true, m_experimental_properties_up->GetValueProperties()); - - // Update m_launch_info once it was created - Arg0ValueChangedCallback(); - RunArgsValueChangedCallback(); - // EnvVarsValueChangedCallback(); // FIXME: cause segfault in - // Target::GetPlatform() - InputPathValueChangedCallback(); - OutputPathValueChangedCallback(); - ErrorPathValueChangedCallback(); - DetachOnErrorValueChangedCallback(); - DisableASLRValueChangedCallback(); - DisableSTDIOValueChangedCallback(); } else { m_collection_sp = std::make_shared(ConstString("target")); m_collection_sp->Initialize(g_target_properties); - m_experimental_properties_up.reset(new TargetExperimentalProperties()); + m_experimental_properties_up = + std::make_unique(); m_collection_sp->AppendProperty( ConstString(Properties::GetExperimentalSettingsName()), ConstString("Experimental settings - setting these won't produce " @@ -3516,6 +3506,18 @@ TargetProperties::TargetProperties(Target *target) TargetProperties::~TargetProperties() = default; +void TargetProperties::UpdateLaunchInfoFromProperties() { + Arg0ValueChangedCallback(); + RunArgsValueChangedCallback(); + EnvVarsValueChangedCallback(); + InputPathValueChangedCallback(); + OutputPathValueChangedCallback(); + ErrorPathValueChangedCallback(); + DetachOnErrorValueChangedCallback(); + DisableASLRValueChangedCallback(); + DisableSTDIOValueChangedCallback(); +} + bool TargetProperties::GetInjectLocalVariables( ExecutionContext *exe_ctx) const { const Property *exp_property = m_collection_sp->GetPropertyAtIndex( @@ -3657,19 +3659,43 @@ void TargetProperties::SetRunArguments(const Args &args) { m_launch_info.GetArguments() = args; } +Environment TargetProperties::ComputeEnvironment() const { + Environment env; + + if (m_target && + m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, ePropertyInheritEnv, + g_target_properties[ePropertyInheritEnv].default_uint_value != 0)) { + if (auto platform_sp = m_target->GetPlatform()) { + Environment platform_env = platform_sp->GetEnvironment(); + for (const auto &KV : platform_env) + env[KV.first()] = KV.second; + } + } + + Args property_unset_env; + m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyUnsetEnvVars, + property_unset_env); + for (const auto &var : property_unset_env) + env.erase(var.ref()); + + Args property_env; + m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyEnvVars, + property_env); + for (const auto &KV : Environment(property_env)) + env[KV.first()] = KV.second; + + return env; +} + Environment TargetProperties::GetEnvironment() const { - // TODO: Get rid of the Args intermediate step - Args env; - const uint32_t idx = ePropertyEnvVars; - m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, env); - return Environment(env); + return ComputeEnvironment(); } void TargetProperties::SetEnvironment(Environment env) { // TODO: Get rid of the Args intermediate step const uint32_t idx = ePropertyEnvVars; m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, Args(env)); - m_launch_info.GetEnvironment() = std::move(env); } bool TargetProperties::GetSkipPrologue() const { @@ -3741,6 +3767,12 @@ bool TargetProperties::GetEnableAutoApplyFixIts() const { nullptr, idx, g_target_properties[idx].default_uint_value != 0); } +uint64_t TargetProperties::GetNumberOfRetriesWithFixits() const { + const uint32_t idx = ePropertyRetriesWithFixIts; + return m_collection_sp->GetPropertyAtIndexAsUInt64( + nullptr, idx, g_target_properties[idx].default_uint_value); +} + bool TargetProperties::GetEnableNotifyAboutFixIts() const { const uint32_t idx = ePropertyNotifyAboutFixIts; return m_collection_sp->GetPropertyAtIndexAsBoolean( @@ -3970,6 +4002,12 @@ void TargetProperties::SetRequireHardwareBreakpoints(bool b) { m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); } +bool TargetProperties::GetAutoInstallMainExecutable() const { + const uint32_t idx = ePropertyAutoInstallMainExecutable; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_target_properties[idx].default_uint_value != 0); +} + void TargetProperties::Arg0ValueChangedCallback() { m_launch_info.SetArg0(GetArg0()); } @@ -3981,7 +4019,7 @@ void TargetProperties::RunArgsValueChangedCallback() { } void TargetProperties::EnvVarsValueChangedCallback() { - m_launch_info.GetEnvironment() = GetEnvironment(); + m_launch_info.GetEnvironment() = ComputeEnvironment(); } void TargetProperties::InputPathValueChangedCallback() { @@ -4073,7 +4111,7 @@ Target::TargetEventData::GetModuleListFromEvent(const Event *event_ptr) { return module_list; } -std::recursive_mutex &Target::GetAPIMutex() { +std::recursive_mutex &Target::GetAPIMutex() { if (GetProcessSP() && GetProcessSP()->CurrentThreadIsPrivateStateThread()) return m_private_mutex; else diff --git a/gnu/llvm/lldb/source/Target/TargetList.cpp b/gnu/llvm/lldb/source/Target/TargetList.cpp index 1b4db0c2aba..3974cb5de41 100644 --- a/gnu/llvm/lldb/source/Target/TargetList.cpp +++ b/gnu/llvm/lldb/source/Target/TargetList.cpp @@ -1,4 +1,4 @@ -//===-- TargetList.cpp ------------------------------------------*- C++ -*-===// +//===-- TargetList.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -398,6 +398,8 @@ Status TargetList::CreateTargetInternal(Debugger &debugger, if (user_exe_path_is_bundle) exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path)); + if (target_sp->GetPreloadSymbols()) + exe_module_sp->PreloadSymbols(); } } else { // No file was specified, just create an empty target with any arch if a diff --git a/gnu/llvm/lldb/source/Target/TargetProperties.td b/gnu/llvm/lldb/source/Target/TargetProperties.td index ff8062aaa2c..ae3abe35485 100644 --- a/gnu/llvm/lldb/source/Target/TargetProperties.td +++ b/gnu/llvm/lldb/source/Target/TargetProperties.td @@ -1,6 +1,6 @@ include "../../include/lldb/Core/PropertiesBase.td" -let Definition = "experimental" in { +let Definition = "target_experimental" in { def InjectLocalVars : Property<"inject-local-vars", "Boolean">, Global, DefaultTrue, Desc<"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.">; @@ -51,6 +51,9 @@ let Definition = "target" in { def AutoApplyFixIts: Property<"auto-apply-fixits", "Boolean">, DefaultTrue, Desc<"Automatically apply fix-it hints to expressions.">; + def RetriesWithFixIts: Property<"retries-with-fixits", "UInt64">, + DefaultUnsignedValue<1>, + Desc<"Maximum number of attempts to fix an expression with Fix-Its">; def NotifyAboutFixIts: Property<"notify-about-fixits", "Boolean">, DefaultTrue, Desc<"Print the fixed expression text.">; @@ -79,8 +82,11 @@ let Definition = "target" in { DefaultStringValue<"">, Desc<"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.">; def EnvVars: Property<"env-vars", "Dictionary">, - DefaultUnsignedValue<16>, - Desc<"A list of all the environment variables to be passed to the executable's environment, and their values.">; + ElementType<"String">, + Desc<"A list of user provided environment variables to be passed to the executable's environment, and their values.">; + def UnsetEnvVars: Property<"unset-env-vars", "Array">, + ElementType<"String">, + Desc<"A list of environment variable names to be unset in the inferior's environment. This is most useful to unset some host environment variables when target.inherit-env is true. target.env-vars takes precedence over target.unset-env-vars.">; def InheritEnv: Property<"inherit-env", "Boolean">, DefaultTrue, Desc<"Inherit the environment from the process that is running LLDB.">; @@ -140,7 +146,7 @@ let Definition = "target" in { Desc<"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.">; def TrapHandlerNames: Property<"trap-handler-names", "Array">, Global, - DefaultUnsignedValue<16>, + ElementType<"String">, Desc<"A list of trap handler function names, e.g. a common Unix user process one is _sigtramp.">; def DisplayRuntimeSupportValues: Property<"display-runtime-support-values", "Boolean">, DefaultFalse, @@ -154,6 +160,16 @@ let Definition = "target" in { def RequireHardwareBreakpoints: Property<"require-hardware-breakpoint", "Boolean">, DefaultFalse, Desc<"Require all breakpoints to be hardware breakpoints.">; + def AutoInstallMainExecutable: Property<"auto-install-main-executable", "Boolean">, + DefaultTrue, + Desc<"Always install the main executable when connected to a remote platform.">; +} + +let Definition = "process_experimental" in { + def OSPluginReportsAllThreads: Property<"os-plugin-reports-all-threads", "Boolean">, + Global, + DefaultTrue, + Desc<"Set to False if your OS Plugins doesn't report all threads on each stop.">; } let Definition = "process" in { @@ -161,7 +177,7 @@ let Definition = "process" in { DefaultFalse, Desc<"Disable reading and caching of memory in fixed-size units.">; def ExtraStartCommand: Property<"extra-startup-command", "Array">, - DefaultUnsignedValue<16>, + ElementType<"String">, Desc<"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;'">; def IgnoreBreakpointsInExpressions: Property<"ignore-breakpoints-in-expressions", "Boolean">, Global, @@ -188,6 +204,9 @@ let Definition = "process" in { def WarningOptimization: Property<"optimization-warnings", "Boolean">, DefaultTrue, Desc<"If true, warn when stopped in code that is optimized where stepping and variable availability may not behave as expected.">; + def WarningUnsupportedLanguage: Property<"unsupported-language-warnings", "Boolean">, + DefaultTrue, + Desc<"If true, warn when stopped in code that is written in a source language that LLDB does not support.">; def StopOnExec: Property<"stop-on-exec", "Boolean">, Global, DefaultTrue, diff --git a/gnu/llvm/lldb/source/Target/Thread.cpp b/gnu/llvm/lldb/source/Target/Thread.cpp index e12b9050110..24cf4bf3ee1 100644 --- a/gnu/llvm/lldb/source/Target/Thread.cpp +++ b/gnu/llvm/lldb/source/Target/Thread.cpp @@ -1,4 +1,4 @@ -//===-- Thread.cpp ----------------------------------------------*- C++ -*-===// +//===-- Thread.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,8 +7,6 @@ //===----------------------------------------------------------------------===// #include "lldb/Target/Thread.h" -#include "Plugins/Process/Utility/UnwindLLDB.h" -#include "Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/FormatEntity.h" @@ -35,6 +33,7 @@ #include "lldb/Target/ThreadPlanCallFunction.h" #include "lldb/Target/ThreadPlanPython.h" #include "lldb/Target/ThreadPlanRunToAddress.h" +#include "lldb/Target/ThreadPlanStack.h" #include "lldb/Target/ThreadPlanStepInRange.h" #include "lldb/Target/ThreadPlanStepInstruction.h" #include "lldb/Target/ThreadPlanStepOut.h" @@ -43,7 +42,7 @@ #include "lldb/Target/ThreadPlanStepThrough.h" #include "lldb/Target/ThreadPlanStepUntil.h" #include "lldb/Target/ThreadSpec.h" -#include "lldb/Target/Unwind.h" +#include "lldb/Target/UnwindLLDB.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/State.h" @@ -230,8 +229,7 @@ Thread::Thread(Process &process, lldb::tid_t tid, bool use_invalid_index_id) m_index_id(use_invalid_index_id ? LLDB_INVALID_INDEX32 : process.GetNextThreadIndexID(tid)), m_reg_context_sp(), m_state(eStateUnloaded), m_state_mutex(), - m_plan_stack(), m_completed_plan_stack(), m_frame_mutex(), - m_curr_frames_sp(), m_prev_frames_sp(), + m_frame_mutex(), m_curr_frames_sp(), m_prev_frames_sp(), m_resume_signal(LLDB_INVALID_SIGNAL_NUMBER), m_resume_state(eStateRunning), m_temporary_resume_state(eStateRunning), m_unwinder_up(), m_destroy_called(false), @@ -242,8 +240,6 @@ Thread::Thread(Process &process, lldb::tid_t tid, bool use_invalid_index_id) static_cast(this), GetID()); CheckInWithManager(); - - QueueFundamentalPlan(true); } Thread::~Thread() { @@ -256,30 +252,7 @@ Thread::~Thread() { } void Thread::DestroyThread() { - // Tell any plans on the plan stacks that the thread is being destroyed since - // any plans that have a thread go away in the middle of might need to do - // cleanup, or in some cases NOT do cleanup... - for (auto plan : m_plan_stack) - plan->ThreadDestroyed(); - - for (auto plan : m_discarded_plan_stack) - plan->ThreadDestroyed(); - - for (auto plan : m_completed_plan_stack) - plan->ThreadDestroyed(); - m_destroy_called = true; - m_plan_stack.clear(); - m_discarded_plan_stack.clear(); - m_completed_plan_stack.clear(); - - // Push a ThreadPlanNull on the plan stack. That way we can continue - // assuming that the plan stack is never empty, but if somebody errantly asks - // questions of a destroyed thread without checking first whether it is - // destroyed, they won't crash. - ThreadPlanSP null_plan_sp(new ThreadPlanNull(*this)); - m_plan_stack.push_back(null_plan_sp); - m_stop_info_sp.reset(); m_reg_context_sp.reset(); m_unwinder_up.reset(); @@ -298,7 +271,7 @@ lldb::StackFrameSP Thread::GetSelectedFrame() { StackFrameListSP stack_frame_list_sp(GetStackFrameList()); StackFrameSP frame_sp = stack_frame_list_sp->GetFrameAtIndex( stack_frame_list_sp->GetSelectedFrameIndex()); - FunctionOptimizationWarning(frame_sp.get()); + FrameSelectedCallback(frame_sp.get()); return frame_sp; } @@ -307,7 +280,7 @@ uint32_t Thread::SetSelectedFrame(lldb_private::StackFrame *frame, uint32_t ret_value = GetStackFrameList()->SetSelectedFrame(frame); if (broadcast) BroadcastSelectedFrameChange(frame->GetStackID()); - FunctionOptimizationWarning(frame); + FrameSelectedCallback(frame); return ret_value; } @@ -317,7 +290,7 @@ bool Thread::SetSelectedFrameByIndex(uint32_t frame_idx, bool broadcast) { GetStackFrameList()->SetSelectedFrame(frame_sp.get()); if (broadcast) BroadcastSelectedFrameChange(frame_sp->GetStackID()); - FunctionOptimizationWarning(frame_sp.get()); + FrameSelectedCallback(frame_sp.get()); return true; } else return false; @@ -341,7 +314,7 @@ bool Thread::SetSelectedFrameByIndexNoisily(uint32_t frame_idx, bool show_frame_info = true; bool show_source = !already_shown; - FunctionOptimizationWarning(frame_sp.get()); + FrameSelectedCallback(frame_sp.get()); return frame_sp->GetStatus(output_stream, show_frame_info, show_source); } return false; @@ -349,12 +322,17 @@ bool Thread::SetSelectedFrameByIndexNoisily(uint32_t frame_idx, return false; } -void Thread::FunctionOptimizationWarning(StackFrame *frame) { - if (frame && frame->HasDebugInformation() && - GetProcess()->GetWarningsOptimization()) { +void Thread::FrameSelectedCallback(StackFrame *frame) { + if (!frame) + return; + + if (frame->HasDebugInformation() && + (GetProcess()->GetWarningsOptimization() || + GetProcess()->GetWarningsUnsupportedLanguage())) { SymbolContext sc = frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextModule); GetProcess()->PrintWarningOptimization(sc); + GetProcess()->PrintWarningUnsupportedLanguage(sc); } } @@ -423,7 +401,7 @@ lldb::StopInfoSP Thread::GetPrivateStopInfo() { // "m_stop_info_stop_id != process_stop_id" as the condition for the if // statement below, we must also check the stop info to see if we need to // override it. See the header documentation in - // Process::GetStopInfoOverrideCallback() for more information on the stop + // Architecture::OverrideStopInfo() for more information on the stop // info override callback. if (m_stop_info_override_stop_id != process_stop_id) { m_stop_info_override_stop_id = process_stop_id; @@ -524,7 +502,8 @@ bool Thread::CheckpointThreadState(ThreadStateCheckpoint &saved_state) { if (process_sp) saved_state.orig_stop_id = process_sp->GetStopID(); saved_state.current_inlined_depth = GetCurrentInlinedDepth(); - saved_state.m_completed_plan_stack = m_completed_plan_stack; + saved_state.m_completed_plan_checkpoint = + GetPlans().CheckpointCompletedPlans(); return true; } @@ -558,7 +537,8 @@ bool Thread::RestoreThreadStateFromCheckpoint( SetStopInfo(saved_state.stop_info_sp); GetStackFrameList()->SetCurrentInlinedDepth( saved_state.current_inlined_depth); - m_completed_plan_stack = saved_state.m_completed_plan_stack; + GetPlans().RestoreCompletedPlanCheckpoint( + saved_state.m_completed_plan_checkpoint); return true; } @@ -573,9 +553,68 @@ void Thread::SetState(StateType state) { m_state = state; } +std::string Thread::GetStopDescription() { + StackFrameSP frame_sp = GetStackFrameAtIndex(0); + + if (!frame_sp) + return GetStopDescriptionRaw(); + + auto recognized_frame_sp = frame_sp->GetRecognizedFrame(); + + if (!recognized_frame_sp) + return GetStopDescriptionRaw(); + + std::string recognized_stop_description = + recognized_frame_sp->GetStopDescription(); + + if (!recognized_stop_description.empty()) + return recognized_stop_description; + + return GetStopDescriptionRaw(); +} + +std::string Thread::GetStopDescriptionRaw() { + StopInfoSP stop_info_sp = GetStopInfo(); + std::string raw_stop_description; + if (stop_info_sp && stop_info_sp->IsValid()) { + raw_stop_description = stop_info_sp->GetDescription(); + assert((!raw_stop_description.empty() || + stop_info_sp->GetStopReason() == eStopReasonNone) && + "StopInfo returned an empty description."); + } + return raw_stop_description; +} + +void Thread::SelectMostRelevantFrame() { + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD); + + auto frames_list_sp = GetStackFrameList(); + + // Only the top frame should be recognized. + auto frame_sp = frames_list_sp->GetFrameAtIndex(0); + + auto recognized_frame_sp = frame_sp->GetRecognizedFrame(); + + if (!recognized_frame_sp) { + LLDB_LOG(log, "Frame #0 not recognized"); + return; + } + + if (StackFrameSP most_relevant_frame_sp = + recognized_frame_sp->GetMostRelevantFrame()) { + LLDB_LOG(log, "Found most relevant frame at index {0}", + most_relevant_frame_sp->GetFrameIndex()); + SetSelectedFrame(most_relevant_frame_sp.get()); + } else { + LLDB_LOG(log, "No relevant frame!"); + } +} + void Thread::WillStop() { ThreadPlan *current_plan = GetCurrentPlan(); + SelectMostRelevantFrame(); + // FIXME: I may decide to disallow threads with no plans. In which // case this should go to an assert. @@ -632,8 +671,7 @@ void Thread::SetupForResume() { bool Thread::ShouldResume(StateType resume_state) { // At this point clear the completed plan stack. - m_completed_plan_stack.clear(); - m_discarded_plan_stack.clear(); + GetPlans().WillResume(); m_override_should_notify = eLazyBoolCalculate; StateType prev_resume_state = GetTemporaryResumeState(); @@ -744,7 +782,9 @@ bool Thread::ShouldStop(Event *event_ptr) { LLDB_LOGF(log, "^^^^^^^^ Thread::ShouldStop Begin ^^^^^^^^"); StreamString s; s.IndentMore(); - DumpThreadPlans(&s); + GetProcess()->DumpThreadPlansForTID( + s, GetID(), eDescriptionLevelVerbose, true /* internal */, + false /* condense_trivial */, true /* skip_unreported */); LLDB_LOGF(log, "Plan stack initial state:\n%s", s.GetData()); } @@ -827,7 +867,7 @@ bool Thread::ShouldStop(Event *event_ptr) { current_plan->GetName(), over_ride_stop); // We're starting from the base plan, so just let it decide; - if (PlanIsBasePlan(current_plan)) { + if (current_plan->IsBasePlan()) { should_stop = current_plan->ShouldStop(event_ptr); LLDB_LOGF(log, "Base plan says should stop: %i.", should_stop); } else { @@ -835,7 +875,7 @@ bool Thread::ShouldStop(Event *event_ptr) { // to do, since presumably if there were other plans they would know what // to do... while (true) { - if (PlanIsBasePlan(current_plan)) + if (current_plan->IsBasePlan()) break; should_stop = current_plan->ShouldStop(event_ptr); @@ -881,7 +921,7 @@ bool Thread::ShouldStop(Event *event_ptr) { // Discard the stale plans and all plans below them in the stack, plus move // the completed plans to the completed plan stack - while (!PlanIsBasePlan(plan_ptr)) { + while (!plan_ptr->IsBasePlan()) { bool stale = plan_ptr->IsPlanStale(); ThreadPlan *examined_plan = plan_ptr; plan_ptr = GetPreviousPlan(examined_plan); @@ -908,7 +948,9 @@ bool Thread::ShouldStop(Event *event_ptr) { if (log) { StreamString s; s.IndentMore(); - DumpThreadPlans(&s); + GetProcess()->DumpThreadPlansForTID( + s, GetID(), eDescriptionLevelVerbose, true /* internal */, + false /* condense_trivial */, true /* skip_unreported */); LLDB_LOGF(log, "Plan stack final state:\n%s", s.GetData()); LLDB_LOGF(log, "vvvvvvvv Thread::ShouldStop End (returning %i) vvvvvvvv", should_stop); @@ -947,13 +989,14 @@ Vote Thread::ShouldReportStop(Event *event_ptr) { return eVoteNoOpinion; } - if (m_completed_plan_stack.size() > 0) { - // Don't use GetCompletedPlan here, since that suppresses private plans. + if (GetPlans().AnyCompletedPlans()) { + // Pass skip_private = false to GetCompletedPlan, since we want to ask + // the last plan, regardless of whether it is private or not. LLDB_LOGF(log, "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote for complete stack's back plan", GetID()); - return m_completed_plan_stack.back()->ShouldReportStop(event_ptr); + return GetPlans().GetCompletedPlan(false)->ShouldReportStop(event_ptr); } else { Vote thread_vote = eVoteNoOpinion; ThreadPlan *plan_ptr = GetCurrentPlan(); @@ -962,7 +1005,7 @@ Vote Thread::ShouldReportStop(Event *event_ptr) { thread_vote = plan_ptr->ShouldReportStop(event_ptr); break; } - if (PlanIsBasePlan(plan_ptr)) + if (plan_ptr->IsBasePlan()) break; else plan_ptr = GetPreviousPlan(plan_ptr); @@ -984,16 +1027,17 @@ Vote Thread::ShouldReportRun(Event *event_ptr) { } Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); - if (m_completed_plan_stack.size() > 0) { - // Don't use GetCompletedPlan here, since that suppresses private plans. + if (GetPlans().AnyCompletedPlans()) { + // Pass skip_private = false to GetCompletedPlan, since we want to ask + // the last plan, regardless of whether it is private or not. LLDB_LOGF(log, "Current Plan for thread %d(%p) (0x%4.4" PRIx64 ", %s): %s being asked whether we should report run.", GetIndexID(), static_cast(this), GetID(), StateAsCString(GetTemporaryResumeState()), - m_completed_plan_stack.back()->GetName()); + GetCompletedPlan()->GetName()); - return m_completed_plan_stack.back()->ShouldReportRun(event_ptr); + return GetPlans().GetCompletedPlan(false)->ShouldReportRun(event_ptr); } else { LLDB_LOGF(log, "Current Plan for thread %d(%p) (0x%4.4" PRIx64 @@ -1010,148 +1054,85 @@ bool Thread::MatchesSpec(const ThreadSpec *spec) { return (spec == nullptr) ? true : spec->ThreadPassesBasicTests(*this); } -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()) { - assert(!m_plan_stack.empty()); - thread_plan_sp->SetThreadPlanTracer( - m_plan_stack.back()->GetThreadPlanTracer()); - } - m_plan_stack.push_back(thread_plan_sp); +ThreadPlanStack &Thread::GetPlans() const { + ThreadPlanStack *plans = GetProcess()->FindThreadPlans(GetID()); + if (plans) + return *plans; - thread_plan_sp->DidPush(); + // History threads don't have a thread plan, but they do ask get asked to + // describe themselves, which usually involves pulling out the stop reason. + // That in turn will check for a completed plan on the ThreadPlanStack. + // Instead of special-casing at that point, we return a Stack with a + // ThreadPlanNull as its base plan. That will give the right answers to the + // queries GetDescription makes, and only assert if you try to run the thread. + if (!m_null_plan_stack_up) + m_null_plan_stack_up = std::make_unique(*this, true); + return *(m_null_plan_stack_up.get()); +} - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); - if (log) { - StreamString s; - thread_plan_sp->GetDescription(&s, lldb::eDescriptionLevelFull); - LLDB_LOGF(log, "Thread::PushPlan(0x%p): \"%s\", tid = 0x%4.4" PRIx64 ".", - static_cast(this), s.GetData(), - thread_plan_sp->GetThread().GetID()); - } +void Thread::PushPlan(ThreadPlanSP thread_plan_sp) { + assert(thread_plan_sp && "Don't push an empty thread plan."); + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + if (log) { + StreamString s; + thread_plan_sp->GetDescription(&s, lldb::eDescriptionLevelFull); + LLDB_LOGF(log, "Thread::PushPlan(0x%p): \"%s\", tid = 0x%4.4" PRIx64 ".", + static_cast(this), s.GetData(), + thread_plan_sp->GetThread().GetID()); } + + GetPlans().PushPlan(std::move(thread_plan_sp)); } void Thread::PopPlan() { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); - - if (m_plan_stack.size() <= 1) - return; - else { - ThreadPlanSP &plan = m_plan_stack.back(); - if (log) { - LLDB_LOGF(log, "Popping plan: \"%s\", tid = 0x%4.4" PRIx64 ".", - plan->GetName(), plan->GetThread().GetID()); - } - m_completed_plan_stack.push_back(plan); - plan->WillPop(); - m_plan_stack.pop_back(); + ThreadPlanSP popped_plan_sp = GetPlans().PopPlan(); + if (log) { + LLDB_LOGF(log, "Popping plan: \"%s\", tid = 0x%4.4" PRIx64 ".", + popped_plan_sp->GetName(), popped_plan_sp->GetThread().GetID()); } } void Thread::DiscardPlan() { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); - if (m_plan_stack.size() > 1) { - ThreadPlanSP &plan = m_plan_stack.back(); - LLDB_LOGF(log, "Discarding plan: \"%s\", tid = 0x%4.4" PRIx64 ".", - plan->GetName(), plan->GetThread().GetID()); - - m_discarded_plan_stack.push_back(plan); - plan->WillPop(); - m_plan_stack.pop_back(); - } -} + ThreadPlanSP discarded_plan_sp = GetPlans().PopPlan(); -ThreadPlan *Thread::GetCurrentPlan() { - // There will always be at least the base plan. If somebody is mucking with - // a thread with an empty plan stack, we should assert right away. - return m_plan_stack.empty() ? nullptr : m_plan_stack.back().get(); + LLDB_LOGF(log, "Discarding plan: \"%s\", tid = 0x%4.4" PRIx64 ".", + discarded_plan_sp->GetName(), + discarded_plan_sp->GetThread().GetID()); } -ThreadPlanSP Thread::GetCompletedPlan() { - ThreadPlanSP empty_plan_sp; - if (!m_completed_plan_stack.empty()) { - for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--) { - ThreadPlanSP completed_plan_sp; - completed_plan_sp = m_completed_plan_stack[i]; - if (!completed_plan_sp->GetPrivate()) - return completed_plan_sp; - } - } - return empty_plan_sp; +ThreadPlan *Thread::GetCurrentPlan() const { + return GetPlans().GetCurrentPlan().get(); } -ValueObjectSP Thread::GetReturnValueObject() { - if (!m_completed_plan_stack.empty()) { - for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--) { - ValueObjectSP return_valobj_sp; - return_valobj_sp = m_completed_plan_stack[i]->GetReturnValueObject(); - if (return_valobj_sp) - return return_valobj_sp; - } - } - return ValueObjectSP(); +ThreadPlanSP Thread::GetCompletedPlan() const { + return GetPlans().GetCompletedPlan(); } -ExpressionVariableSP Thread::GetExpressionVariable() { - if (!m_completed_plan_stack.empty()) { - for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--) { - ExpressionVariableSP expression_variable_sp; - expression_variable_sp = - m_completed_plan_stack[i]->GetExpressionVariable(); - if (expression_variable_sp) - return expression_variable_sp; - } - } - return ExpressionVariableSP(); +ValueObjectSP Thread::GetReturnValueObject() const { + return GetPlans().GetReturnValueObject(); } -bool Thread::IsThreadPlanDone(ThreadPlan *plan) { - if (!m_completed_plan_stack.empty()) { - for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--) { - if (m_completed_plan_stack[i].get() == plan) - return true; - } - } - return false; +ExpressionVariableSP Thread::GetExpressionVariable() const { + return GetPlans().GetExpressionVariable(); } -bool Thread::WasThreadPlanDiscarded(ThreadPlan *plan) { - if (!m_discarded_plan_stack.empty()) { - for (int i = m_discarded_plan_stack.size() - 1; i >= 0; i--) { - if (m_discarded_plan_stack[i].get() == plan) - return true; - } - } - return false; +bool Thread::IsThreadPlanDone(ThreadPlan *plan) const { + return GetPlans().IsPlanDone(plan); } -bool Thread::CompletedPlanOverridesBreakpoint() { - return (!m_completed_plan_stack.empty()) ; +bool Thread::WasThreadPlanDiscarded(ThreadPlan *plan) const { + return GetPlans().WasPlanDiscarded(plan); } -ThreadPlan *Thread::GetPreviousPlan(ThreadPlan *current_plan) { - if (current_plan == nullptr) - return nullptr; - - int stack_size = m_completed_plan_stack.size(); - for (int i = stack_size - 1; i > 0; i--) { - if (current_plan == m_completed_plan_stack[i].get()) - return m_completed_plan_stack[i - 1].get(); - } - - if (stack_size > 0 && m_completed_plan_stack[0].get() == current_plan) { - return GetCurrentPlan(); - } +bool Thread::CompletedPlanOverridesBreakpoint() const { + return GetPlans().AnyCompletedPlans(); +} - stack_size = m_plan_stack.size(); - for (int i = stack_size - 1; i > 0; i--) { - if (current_plan == m_plan_stack[i].get()) - return m_plan_stack[i - 1].get(); - } - return nullptr; +ThreadPlan *Thread::GetPreviousPlan(ThreadPlan *current_plan) const{ + return GetPlans().GetPreviousPlan(current_plan); } Status Thread::QueueThreadPlan(ThreadPlanSP &thread_plan_sp, @@ -1185,38 +1166,18 @@ Status Thread::QueueThreadPlan(ThreadPlanSP &thread_plan_sp, } void Thread::EnableTracer(bool value, bool single_stepping) { - int stack_size = m_plan_stack.size(); - for (int i = 0; i < stack_size; i++) { - if (m_plan_stack[i]->GetThreadPlanTracer()) { - m_plan_stack[i]->GetThreadPlanTracer()->EnableTracing(value); - m_plan_stack[i]->GetThreadPlanTracer()->EnableSingleStep(single_stepping); - } - } + GetPlans().EnableTracer(value, single_stepping); } void Thread::SetTracer(lldb::ThreadPlanTracerSP &tracer_sp) { - int stack_size = m_plan_stack.size(); - for (int i = 0; i < stack_size; i++) - m_plan_stack[i]->SetThreadPlanTracer(tracer_sp); + GetPlans().SetTracer(tracer_sp); } -bool Thread::DiscardUserThreadPlansUpToIndex(uint32_t thread_index) { +bool Thread::DiscardUserThreadPlansUpToIndex(uint32_t plan_index) { // Count the user thread plans from the back end to get the number of the one // we want to discard: - uint32_t idx = 0; - ThreadPlan *up_to_plan_ptr = nullptr; - - for (ThreadPlanSP plan_sp : m_plan_stack) { - if (plan_sp->GetPrivate()) - continue; - if (idx == thread_index) { - up_to_plan_ptr = plan_sp.get(); - break; - } else - idx++; - } - + ThreadPlan *up_to_plan_ptr = GetPlans().GetPlanByIndex(plan_index).get(); if (up_to_plan_ptr == nullptr) return false; @@ -1234,30 +1195,7 @@ void Thread::DiscardThreadPlansUpToPlan(ThreadPlan *up_to_plan_ptr) { "Discarding thread plans for thread tid = 0x%4.4" PRIx64 ", up to %p", GetID(), static_cast(up_to_plan_ptr)); - - int stack_size = m_plan_stack.size(); - - // If the input plan is nullptr, discard all plans. Otherwise make sure this - // plan is in the stack, and if so discard up to and including it. - - if (up_to_plan_ptr == nullptr) { - for (int i = stack_size - 1; i > 0; i--) - DiscardPlan(); - } else { - bool found_it = false; - for (int i = stack_size - 1; i > 0; i--) { - if (m_plan_stack[i].get() == up_to_plan_ptr) - found_it = true; - } - if (found_it) { - bool last_one = false; - for (int i = stack_size - 1; i > 0 && !last_one; i--) { - if (GetCurrentPlan() == up_to_plan_ptr) - last_one = true; - DiscardPlan(); - } - } - } + GetPlans().DiscardPlansUpToPlan(up_to_plan_ptr); } void Thread::DiscardThreadPlans(bool force) { @@ -1270,73 +1208,20 @@ void Thread::DiscardThreadPlans(bool force) { } if (force) { - int stack_size = m_plan_stack.size(); - for (int i = stack_size - 1; i > 0; i--) { - DiscardPlan(); - } + GetPlans().DiscardAllPlans(); return; } - - while (true) { - int master_plan_idx; - bool discard = true; - - // Find the first master plan, see if it wants discarding, and if yes - // discard up to it. - for (master_plan_idx = m_plan_stack.size() - 1; master_plan_idx >= 0; - master_plan_idx--) { - if (m_plan_stack[master_plan_idx]->IsMasterPlan()) { - discard = m_plan_stack[master_plan_idx]->OkayToDiscard(); - break; - } - } - - if (discard) { - // First pop all the dependent plans: - for (int i = m_plan_stack.size() - 1; i > master_plan_idx; i--) { - // FIXME: Do we need a finalize here, or is the rule that - // "PrepareForStop" - // for the plan leaves it in a state that it is safe to pop the plan - // with no more notice? - DiscardPlan(); - } - - // Now discard the master plan itself. - // The bottom-most plan never gets discarded. "OkayToDiscard" for it - // means discard it's dependent plans, but not it... - if (master_plan_idx > 0) { - DiscardPlan(); - } - } else { - // If the master plan doesn't want to get discarded, then we're done. - break; - } - } -} - -bool Thread::PlanIsBasePlan(ThreadPlan *plan_ptr) { - if (plan_ptr->IsBasePlan()) - return true; - else if (m_plan_stack.size() == 0) - return false; - else - return m_plan_stack[0].get() == plan_ptr; + GetPlans().DiscardConsultingMasterPlans(); } Status Thread::UnwindInnermostExpression() { Status error; - int stack_size = m_plan_stack.size(); - - // If the input plan is nullptr, discard all plans. Otherwise make sure this - // plan is in the stack, and if so discard up to and including it. - - for (int i = stack_size - 1; i > 0; i--) { - if (m_plan_stack[i]->GetKind() == ThreadPlan::eKindCallFunction) { - DiscardThreadPlansUpToPlan(m_plan_stack[i].get()); - return error; - } - } - error.SetErrorString("No expressions currently active on this thread"); + ThreadPlan *innermost_expr_plan = GetPlans().GetInnermostExpression(); + if (!innermost_expr_plan) { + error.SetErrorString("No expressions currently active on this thread"); + return error; + } + DiscardThreadPlansUpToPlan(innermost_expr_plan); return error; } @@ -1502,73 +1387,6 @@ lldb::ThreadPlanSP Thread::QueueThreadPlanForStepScripted( uint32_t Thread::GetIndexID() const { return m_index_id; } -static void PrintPlanElement(Stream *s, const ThreadPlanSP &plan, - lldb::DescriptionLevel desc_level, - int32_t elem_idx) { - s->IndentMore(); - s->Indent(); - s->Printf("Element %d: ", elem_idx); - plan->GetDescription(s, desc_level); - s->EOL(); - s->IndentLess(); -} - -static void PrintPlanStack(Stream *s, - const std::vector &plan_stack, - lldb::DescriptionLevel desc_level, - bool include_internal) { - int32_t print_idx = 0; - for (ThreadPlanSP plan_sp : plan_stack) { - if (include_internal || !plan_sp->GetPrivate()) { - PrintPlanElement(s, plan_sp, desc_level, print_idx++); - } - } -} - -void Thread::DumpThreadPlans(Stream *s, lldb::DescriptionLevel desc_level, - bool include_internal, - bool ignore_boring_threads) const { - uint32_t stack_size; - - if (ignore_boring_threads) { - uint32_t stack_size = m_plan_stack.size(); - uint32_t completed_stack_size = m_completed_plan_stack.size(); - uint32_t discarded_stack_size = m_discarded_plan_stack.size(); - if (stack_size == 1 && completed_stack_size == 0 && - discarded_stack_size == 0) { - s->Printf("thread #%u: tid = 0x%4.4" PRIx64 "\n", GetIndexID(), GetID()); - s->IndentMore(); - s->Indent(); - s->Printf("No active thread plans\n"); - s->IndentLess(); - return; - } - } - - s->Indent(); - s->Printf("thread #%u: tid = 0x%4.4" PRIx64 ":\n", GetIndexID(), GetID()); - s->IndentMore(); - s->Indent(); - s->Printf("Active plan stack:\n"); - PrintPlanStack(s, m_plan_stack, desc_level, include_internal); - - stack_size = m_completed_plan_stack.size(); - if (stack_size > 0) { - s->Indent(); - s->Printf("Completed Plan Stack:\n"); - PrintPlanStack(s, m_completed_plan_stack, desc_level, include_internal); - } - - stack_size = m_discarded_plan_stack.size(); - if (stack_size > 0) { - s->Indent(); - s->Printf("Discarded Plan Stack:\n"); - PrintPlanStack(s, m_discarded_plan_stack, desc_level, include_internal); - } - - s->IndentLess(); -} - TargetSP Thread::CalculateTarget() { TargetSP target_sp; ProcessSP process_sp(GetProcess()); @@ -1600,9 +1418,7 @@ StackFrameListSP Thread::GetStackFrameList() { void Thread::ClearStackFrames() { std::lock_guard guard(m_frame_mutex); - Unwind *unwinder = GetUnwinder(); - if (unwinder) - unwinder->Clear(); + GetUnwinder().Clear(); // Only store away the old "reference" StackFrameList if we got all its // frames: @@ -1773,7 +1589,7 @@ Status Thread::JumpToLine(const FileSpec &file, uint32_t line, "first location:\n", file.GetFilename().AsCString(), line); DumpAddressList(sstr, candidates, target); - *warnings = sstr.GetString(); + *warnings = std::string(sstr.GetString()); } if (!reg_ctx->SetPC(dest)) @@ -2041,37 +1857,10 @@ size_t Thread::GetStackFrameStatus(Stream &strm, uint32_t first_frame, strm, first_frame, num_frames, show_frame_info, num_frames_with_source); } -Unwind *Thread::GetUnwinder() { - if (!m_unwinder_up) { - const ArchSpec target_arch(CalculateTarget()->GetArchitecture()); - const llvm::Triple::ArchType machine = target_arch.GetMachine(); - switch (machine) { - case llvm::Triple::x86_64: - case llvm::Triple::x86: - case llvm::Triple::arm: - case llvm::Triple::aarch64: - case llvm::Triple::aarch64_32: - case llvm::Triple::thumb: - case llvm::Triple::mips: - case llvm::Triple::mipsel: - case llvm::Triple::mips64: - case llvm::Triple::mips64el: - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - case llvm::Triple::ppc64le: - case llvm::Triple::systemz: - case llvm::Triple::hexagon: - case llvm::Triple::arc: - m_unwinder_up.reset(new UnwindLLDB(*this)); - break; - - default: - if (target_arch.GetTriple().getVendor() == llvm::Triple::Apple) - m_unwinder_up.reset(new UnwindMacOSXFrameBackchain(*this)); - break; - } - } - return m_unwinder_up.get(); +Unwind &Thread::GetUnwinder() { + if (!m_unwinder_up) + m_unwinder_up = std::make_unique(*this); + return *m_unwinder_up; } void Thread::Flush() { diff --git a/gnu/llvm/lldb/source/Target/ThreadCollection.cpp b/gnu/llvm/lldb/source/Target/ThreadCollection.cpp index cf3c1e24299..05b041c20dd 100644 --- a/gnu/llvm/lldb/source/Target/ThreadCollection.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadCollection.cpp @@ -1,4 +1,4 @@ -//===-- ThreadCollection.cpp ------------------------------------*- C++ -*-===// +//===-- ThreadCollection.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/ThreadList.cpp b/gnu/llvm/lldb/source/Target/ThreadList.cpp index 183b39c2cfa..032dcc9e5fb 100644 --- a/gnu/llvm/lldb/source/Target/ThreadList.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadList.cpp @@ -1,4 +1,4 @@ -//===-- ThreadList.cpp ------------------------------------------*- C++ -*-===// +//===-- ThreadList.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -715,6 +715,11 @@ void ThreadList::Update(ThreadList &rhs) { // to work around the issue collection::iterator rhs_pos, rhs_end = rhs.m_threads.end(); for (rhs_pos = rhs.m_threads.begin(); rhs_pos != rhs_end; ++rhs_pos) { + // If this thread has already been destroyed, we don't need to look for + // it to destroy it again. + if (!(*rhs_pos)->IsValid()) + continue; + const lldb::tid_t tid = (*rhs_pos)->GetID(); bool thread_is_alive = false; const uint32_t num_threads = m_threads.size(); @@ -726,8 +731,9 @@ void ThreadList::Update(ThreadList &rhs) { break; } } - if (!thread_is_alive) + if (!thread_is_alive) { (*rhs_pos)->DestroyThread(); + } } } } diff --git a/gnu/llvm/lldb/source/Target/ThreadPlan.cpp b/gnu/llvm/lldb/source/Target/ThreadPlan.cpp index ba56f8d15d8..d8e92b8fd0d 100644 --- a/gnu/llvm/lldb/source/Target/ThreadPlan.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadPlan.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlan.cpp ------------------------------------------*- C++ -*-===// +//===-- ThreadPlan.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -21,9 +21,10 @@ using namespace lldb_private; // ThreadPlan constructor 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_process(*thread.GetProcess().get()), m_tid(thread.GetID()), + 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_thread(&thread), 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), m_plan_succeeded(true) { @@ -33,6 +34,19 @@ ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, // Destructor ThreadPlan::~ThreadPlan() = default; +Target &ThreadPlan::GetTarget() { return m_process.GetTarget(); } + +const Target &ThreadPlan::GetTarget() const { return m_process.GetTarget(); } + +Thread &ThreadPlan::GetThread() { + if (m_thread) + return *m_thread; + + ThreadSP thread_sp = m_process.GetThreadList().FindThreadByID(m_tid); + m_thread = thread_sp.get(); + return *m_thread; +} + bool ThreadPlan::PlanExplainsStop(Event *event_ptr) { if (m_cached_plan_explains_stop == eLazyBoolCalculate) { bool actual_value = DoPlanExplainsStop(event_ptr); @@ -103,7 +117,7 @@ bool ThreadPlan::WillResume(StateType resume_state, bool current_plan) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); if (log) { - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); + RegisterContext *reg_ctx = GetThread().GetRegisterContext().get(); assert(reg_ctx); addr_t pc = reg_ctx->GetPC(); addr_t sp = reg_ctx->GetSP(); @@ -113,13 +127,17 @@ bool ThreadPlan::WillResume(StateType resume_state, bool current_plan) { "%s Thread #%u (0x%p): tid = 0x%4.4" PRIx64 ", pc = 0x%8.8" PRIx64 ", sp = 0x%8.8" PRIx64 ", fp = 0x%8.8" PRIx64 ", " "plan = '%s', state = %s, stop others = %d", - __FUNCTION__, m_thread.GetIndexID(), static_cast(&m_thread), - m_thread.GetID(), static_cast(pc), + __FUNCTION__, GetThread().GetIndexID(), + static_cast(&GetThread()), m_tid, static_cast(pc), static_cast(sp), static_cast(fp), m_name.c_str(), StateAsCString(resume_state), StopOthers()); } } - return DoWillResume(resume_state, current_plan); + bool success = DoWillResume(resume_state, current_plan); + m_thread = nullptr; // We don't cache the thread pointer over resumes. This + // Thread might go away, and another Thread represent + // the same underlying object on a later stop. + return success; } lldb::user_id_t ThreadPlan::GetNextID() { @@ -174,14 +192,13 @@ bool ThreadPlanNull::ValidatePlan(Stream *error) { fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #else Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); if (log) log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), - m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #endif return true; } @@ -191,14 +208,13 @@ bool ThreadPlanNull::ShouldStop(Event *event_ptr) { fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #else Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); if (log) log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), - m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #endif return true; } @@ -208,14 +224,13 @@ bool ThreadPlanNull::WillStop() { fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #else Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); if (log) log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), - m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #endif return true; } @@ -225,14 +240,13 @@ bool ThreadPlanNull::DoPlanExplainsStop(Event *event_ptr) { fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, GetThread().GetID(), GetThread().GetProtocolID()); #else Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); if (log) log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), - m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #endif return true; } @@ -244,14 +258,13 @@ bool ThreadPlanNull::MischiefManaged() { fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #else Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); if (log) log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), - m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #endif return false; } @@ -262,14 +275,13 @@ lldb::StateType ThreadPlanNull::GetPlanRunState() { fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #else Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); if (log) log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")", - LLVM_PRETTY_FUNCTION, m_thread.GetID(), - m_thread.GetProtocolID()); + LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID()); #endif return eStateRunning; } diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanBase.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanBase.cpp index 821643d4bce..650393d678e 100644 --- a/gnu/llvm/lldb/source/Target/ThreadPlanBase.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadPlanBase.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlanBase.cpp --------------------------------------*- C++ -*-===// +//===-- ThreadPlanBase.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -34,11 +34,11 @@ ThreadPlanBase::ThreadPlanBase(Thread &thread) #define THREAD_PLAN_USE_ASSEMBLY_TRACER 1 #ifdef THREAD_PLAN_USE_ASSEMBLY_TRACER - ThreadPlanTracerSP new_tracer_sp(new ThreadPlanAssemblyTracer(m_thread)); + ThreadPlanTracerSP new_tracer_sp(new ThreadPlanAssemblyTracer(thread)); #else ThreadPlanTracerSP new_tracer_sp(new ThreadPlanTracer(m_thread)); #endif - new_tracer_sp->EnableTracing(m_thread.GetTraceEnabledState()); + new_tracer_sp->EnableTracing(thread.GetTraceEnabledState()); SetThreadPlanTracer(new_tracer_sp); SetIsMasterPlan(true); } @@ -58,7 +58,7 @@ bool ThreadPlanBase::DoPlanExplainsStop(Event *event_ptr) { } Vote ThreadPlanBase::ShouldReportStop(Event *event_ptr) { - StopInfoSP stop_info_sp = m_thread.GetStopInfo(); + StopInfoSP stop_info_sp = GetThread().GetStopInfo(); if (stop_info_sp) { bool should_notify = stop_info_sp->ShouldNotify(event_ptr); if (should_notify) @@ -96,8 +96,8 @@ bool ThreadPlanBase::ShouldStop(Event *event_ptr) { log, "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 " (breakpoint hit.)", - m_thread.GetID()); - m_thread.DiscardThreadPlans(false); + m_tid); + GetThread().DiscardThreadPlans(false); return true; } // If we aren't going to stop at this breakpoint, and it is internal, @@ -125,9 +125,9 @@ bool ThreadPlanBase::ShouldStop(Event *event_ptr) { LLDB_LOGF( log, "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 - " (exception: %s)", - m_thread.GetID(), stop_info_sp->GetDescription()); - m_thread.DiscardThreadPlans(false); + " (exception: %s)", + m_tid, stop_info_sp->GetDescription()); + GetThread().DiscardThreadPlans(false); return true; case eStopReasonExec: @@ -138,8 +138,8 @@ bool ThreadPlanBase::ShouldStop(Event *event_ptr) { log, "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 " (exec.)", - m_thread.GetID()); - m_thread.DiscardThreadPlans(false); + m_tid); + GetThread().DiscardThreadPlans(false); return true; case eStopReasonThreadExiting: @@ -148,9 +148,9 @@ bool ThreadPlanBase::ShouldStop(Event *event_ptr) { LLDB_LOGF( log, "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 - " (signal: %s)", - m_thread.GetID(), stop_info_sp->GetDescription()); - m_thread.DiscardThreadPlans(false); + " (signal: %s)", + m_tid, stop_info_sp->GetDescription()); + GetThread().DiscardThreadPlans(false); return true; } else { // We're not going to stop, but while we are here, let's figure out diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanCallFunction.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanCallFunction.cpp index 23d114e3099..dbe26f42c9b 100644 --- a/gnu/llvm/lldb/source/Target/ThreadPlanCallFunction.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadPlanCallFunction.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlanCallFunction.cpp ------------------------------*- C++ -*-===// +//===-- ThreadPlanCallFunction.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -146,7 +146,7 @@ void ThreadPlanCallFunction::ReportRegisterState(const char *message) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); if (log && log->GetVerbose()) { StreamString strm; - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); + RegisterContext *reg_ctx = GetThread().GetRegisterContext().get(); log->PutCString(message); @@ -178,19 +178,19 @@ void ThreadPlanCallFunction::DoTakedown(bool success) { } if (!m_takedown_done) { + Thread &thread = GetThread(); if (success) { SetReturnValue(); } LLDB_LOGF(log, "ThreadPlanCallFunction(%p): DoTakedown called for thread " "0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", - static_cast(this), m_thread.GetID(), m_valid, - IsPlanComplete()); + static_cast(this), m_tid, m_valid, IsPlanComplete()); m_takedown_done = true; m_stop_address = - m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); + thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); m_real_stop_info_sp = GetPrivateStopInfo(); - if (!m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state)) { + if (!thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state)) { LLDB_LOGF(log, "ThreadPlanCallFunction(%p): DoTakedown failed to restore " "register state", @@ -205,8 +205,7 @@ void ThreadPlanCallFunction::DoTakedown(bool success) { LLDB_LOGF(log, "ThreadPlanCallFunction(%p): DoTakedown called as no-op for " "thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", - static_cast(this), m_thread.GetID(), m_valid, - IsPlanComplete()); + static_cast(this), m_tid, m_valid, IsPlanComplete()); } } @@ -216,9 +215,8 @@ void ThreadPlanCallFunction::GetDescription(Stream *s, DescriptionLevel level) { if (level == eDescriptionLevelBrief) { s->Printf("Function call thread plan"); } else { - TargetSP target_sp(m_thread.CalculateTarget()); s->Printf("Thread plan to call 0x%" PRIx64, - m_function_addr.GetLoadAddress(target_sp.get())); + m_function_addr.GetLoadAddress(&GetTarget())); } } @@ -283,11 +281,9 @@ bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) { // m_ignore_breakpoints. if (stop_reason == eStopReasonBreakpoint) { - ProcessSP process_sp(m_thread.CalculateProcess()); uint64_t break_site_id = m_real_stop_info_sp->GetValue(); BreakpointSiteSP bp_site_sp; - if (process_sp) - bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id); + bp_site_sp = m_process.GetBreakpointSiteList().FindByID(break_site_id); if (bp_site_sp) { uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); bool is_internal = true; @@ -374,10 +370,11 @@ void ThreadPlanCallFunction::DidPush() { GetThread().SetStopInfoToNothing(); #ifndef SINGLE_STEP_EXPRESSIONS - m_subplan_sp = std::make_shared( - m_thread, m_start_addr, m_stop_other_threads); + Thread &thread = GetThread(); + m_subplan_sp = std::make_shared(thread, m_start_addr, + m_stop_other_threads); - m_thread.QueueThreadPlan(m_subplan_sp, false); + thread.QueueThreadPlan(m_subplan_sp, false); m_subplan_sp->SetPrivate(true); #endif } @@ -399,11 +396,10 @@ bool ThreadPlanCallFunction::MischiefManaged() { } void ThreadPlanCallFunction::SetBreakpoints() { - ProcessSP process_sp(m_thread.CalculateProcess()); - if (m_trap_exceptions && process_sp) { + if (m_trap_exceptions) { m_cxx_language_runtime = - process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus); - m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC); + m_process.GetLanguageRuntime(eLanguageTypeC_plus_plus); + m_objc_language_runtime = m_process.GetLanguageRuntime(eLanguageTypeObjC); if (m_cxx_language_runtime) { m_should_clear_cxx_exception_bp = @@ -463,11 +459,10 @@ bool ThreadPlanCallFunction::RestoreThreadState() { } void ThreadPlanCallFunction::SetReturnValue() { - ProcessSP process_sp(m_thread.GetProcess()); - const ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; + const ABI *abi = m_process.GetABI().get(); if (abi && m_return_type.IsValid()) { const bool persistent = false; m_return_valobj_sp = - abi->GetReturnValueObject(m_thread, m_return_type, persistent); + abi->GetReturnValueObject(GetThread(), m_return_type, persistent); } } diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanCallFunctionUsingABI.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanCallFunctionUsingABI.cpp index 3155e6f7965..52b27309e91 100644 --- a/gnu/llvm/lldb/source/Target/ThreadPlanCallFunctionUsingABI.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadPlanCallFunctionUsingABI.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlanCallFunctionUsingABI.cpp ----------------------*- C++ -*-===// +//===-- ThreadPlanCallFunctionUsingABI.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -49,20 +49,18 @@ void ThreadPlanCallFunctionUsingABI::GetDescription(Stream *s, if (level == eDescriptionLevelBrief) { s->Printf("Function call thread plan using ABI instead of JIT"); } else { - TargetSP target_sp(m_thread.CalculateTarget()); s->Printf("Thread plan to call 0x%" PRIx64 " using ABI instead of JIT", - m_function_addr.GetLoadAddress(target_sp.get())); + m_function_addr.GetLoadAddress(&GetTarget())); } } void ThreadPlanCallFunctionUsingABI::SetReturnValue() { - ProcessSP process_sp(m_thread.GetProcess()); - const ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; + const ABI *abi = m_process.GetABI().get(); // Ask the abi for the return value if (abi) { const bool persistent = false; m_return_valobj_sp = - abi->GetReturnValueObject(m_thread, m_return_type, persistent); + abi->GetReturnValueObject(GetThread(), m_return_type, persistent); } } diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp index 3330adc0c2a..7471e9b3d7a 100644 --- a/gnu/llvm/lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlanCallOnFunctionExit.cpp ------------------------*- C++ -*-===// +//===-- ThreadPlanCallOnFunctionExit.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanCallUserExpression.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanCallUserExpression.cpp index 436938c8f20..00b01c76d90 100644 --- a/gnu/llvm/lldb/source/Target/ThreadPlanCallUserExpression.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadPlanCallUserExpression.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlanCallUserExpression.cpp -------------------------*- C++-*-===// +//===-- ThreadPlanCallUserExpression.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -101,8 +101,7 @@ StopInfoSP ThreadPlanCallUserExpression::GetRealStopInfo() { if (stop_info_sp) { lldb::addr_t addr = GetStopAddress(); - DynamicCheckerFunctions *checkers = - m_thread.GetProcess()->GetDynamicCheckers(); + DynamicCheckerFunctions *checkers = m_process.GetDynamicCheckers(); StreamString s; if (checkers && checkers->DoCheckersExplainStop(addr, s)) diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanPython.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanPython.cpp index df432a0af3d..8171186319f 100644 --- a/gnu/llvm/lldb/source/Target/ThreadPlanPython.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadPlanPython.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlanPython.cpp ------------------------------------*- C++ -*-===// +//===-- ThreadPlanPython.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -55,15 +55,16 @@ bool ThreadPlanPython::ValidatePlan(Stream *error) { return true; } +ScriptInterpreter *ThreadPlanPython::GetScriptInterpreter() { + return m_process.GetTarget().GetDebugger().GetScriptInterpreter(); +} + 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() - .GetDebugger() - .GetScriptInterpreter(); + ScriptInterpreter *script_interp = GetScriptInterpreter(); if (script_interp) { m_implementation_sp = script_interp->CreateScriptedThreadPlan( m_class_name.c_str(), m_args_data, m_error_str, @@ -79,10 +80,7 @@ bool ThreadPlanPython::ShouldStop(Event *event_ptr) { bool should_stop = true; if (m_implementation_sp) { - ScriptInterpreter *script_interp = m_thread.GetProcess() - ->GetTarget() - .GetDebugger() - .GetScriptInterpreter(); + ScriptInterpreter *script_interp = GetScriptInterpreter(); if (script_interp) { bool script_error; should_stop = script_interp->ScriptedThreadPlanShouldStop( @@ -101,10 +99,7 @@ bool ThreadPlanPython::IsPlanStale() { bool is_stale = true; if (m_implementation_sp) { - ScriptInterpreter *script_interp = m_thread.GetProcess() - ->GetTarget() - .GetDebugger() - .GetScriptInterpreter(); + ScriptInterpreter *script_interp = GetScriptInterpreter(); if (script_interp) { bool script_error; is_stale = script_interp->ScriptedThreadPlanIsStale(m_implementation_sp, @@ -123,10 +118,7 @@ bool ThreadPlanPython::DoPlanExplainsStop(Event *event_ptr) { bool explains_stop = true; if (m_implementation_sp) { - ScriptInterpreter *script_interp = m_thread.GetProcess() - ->GetTarget() - .GetDebugger() - .GetScriptInterpreter(); + ScriptInterpreter *script_interp = GetScriptInterpreter(); if (script_interp) { bool script_error; explains_stop = script_interp->ScriptedThreadPlanExplainsStop( @@ -159,10 +151,7 @@ lldb::StateType ThreadPlanPython::GetPlanRunState() { m_class_name.c_str()); lldb::StateType run_state = eStateRunning; if (m_implementation_sp) { - ScriptInterpreter *script_interp = m_thread.GetProcess() - ->GetTarget() - .GetDebugger() - .GetScriptInterpreter(); + ScriptInterpreter *script_interp = GetScriptInterpreter(); if (script_interp) { bool script_error; run_state = script_interp->ScriptedThreadPlanGetRunState( diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanRunToAddress.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanRunToAddress.cpp index 32ea2e67527..cb4a58b1cf2 100644 --- a/gnu/llvm/lldb/source/Target/ThreadPlanRunToAddress.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadPlanRunToAddress.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlanRunToAddress.cpp ------------------------------*- C++ -*-===// +//===-- ThreadPlanRunToAddress.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,7 +25,7 @@ ThreadPlanRunToAddress::ThreadPlanRunToAddress(Thread &thread, Address &address, eVoteNoOpinion, eVoteNoOpinion), m_stop_others(stop_others), m_addresses(), m_break_ids() { m_addresses.push_back( - address.GetOpcodeLoadAddress(m_thread.CalculateTarget().get())); + address.GetOpcodeLoadAddress(thread.CalculateTarget().get())); SetInitialBreakpoints(); } @@ -36,7 +36,7 @@ ThreadPlanRunToAddress::ThreadPlanRunToAddress(Thread &thread, eVoteNoOpinion, eVoteNoOpinion), m_stop_others(stop_others), m_addresses(), m_break_ids() { m_addresses.push_back( - m_thread.CalculateTarget()->GetOpcodeLoadAddress(address)); + thread.CalculateTarget()->GetOpcodeLoadAddress(address)); SetInitialBreakpoints(); } @@ -62,14 +62,13 @@ void ThreadPlanRunToAddress::SetInitialBreakpoints() { for (size_t i = 0; i < num_addresses; i++) { Breakpoint *breakpoint; - breakpoint = m_thread.CalculateTarget() - ->CreateBreakpoint(m_addresses[i], true, false) - .get(); + breakpoint = + GetTarget().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->SetThreadID(m_tid); breakpoint->SetBreakpointKind("run-to-address"); } } @@ -78,7 +77,7 @@ void ThreadPlanRunToAddress::SetInitialBreakpoints() { ThreadPlanRunToAddress::~ThreadPlanRunToAddress() { size_t num_break_ids = m_break_ids.size(); for (size_t i = 0; i < num_break_ids; i++) { - m_thread.CalculateTarget()->RemoveBreakpointByID(m_break_ids[i]); + GetTarget().RemoveBreakpointByID(m_break_ids[i]); } m_could_not_resolve_hw_bp = false; } @@ -119,7 +118,7 @@ void ThreadPlanRunToAddress::GetDescription(Stream *s, DumpAddress(s->AsRawOstream(), m_addresses[i], sizeof(addr_t)); s->Printf(" using breakpoint: %d - ", m_break_ids[i]); Breakpoint *breakpoint = - m_thread.CalculateTarget()->GetBreakpointByID(m_break_ids[i]).get(); + GetTarget().GetBreakpointByID(m_break_ids[i]).get(); if (breakpoint) breakpoint->Dump(s); else @@ -178,7 +177,7 @@ bool ThreadPlanRunToAddress::MischiefManaged() { for (size_t i = 0; i < num_break_ids; i++) { if (m_break_ids[i] != LLDB_INVALID_BREAK_ID) { - m_thread.CalculateTarget()->RemoveBreakpointByID(m_break_ids[i]); + GetTarget().RemoveBreakpointByID(m_break_ids[i]); m_break_ids[i] = LLDB_INVALID_BREAK_ID; } } @@ -190,7 +189,7 @@ bool ThreadPlanRunToAddress::MischiefManaged() { } bool ThreadPlanRunToAddress::AtOurAddress() { - lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC(); + lldb::addr_t current_address = GetThread().GetRegisterContext()->GetPC(); bool found_it = false; size_t num_addresses = m_addresses.size(); for (size_t i = 0; i < num_addresses; i++) { diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanShouldStopHere.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanShouldStopHere.cpp index 9599d8197b0..7774e027c05 100644 --- a/gnu/llvm/lldb/source/Target/ThreadPlanShouldStopHere.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadPlanShouldStopHere.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlanShouldStopHere.cpp ----------------------------*- C++ -*-===// +//===-- ThreadPlanShouldStopHere.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanStack.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanStack.cpp new file mode 100644 index 00000000000..1cfc41dcd39 --- /dev/null +++ b/gnu/llvm/lldb/source/Target/ThreadPlanStack.cpp @@ -0,0 +1,508 @@ +//===-- ThreadPlanStack.cpp -------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/ThreadPlanStack.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlan.h" +#include "lldb/Utility/Log.h" + +using namespace lldb; +using namespace lldb_private; + +static void PrintPlanElement(Stream &s, const ThreadPlanSP &plan, + lldb::DescriptionLevel desc_level, + int32_t elem_idx) { + s.IndentMore(); + s.Indent(); + s.Printf("Element %d: ", elem_idx); + plan->GetDescription(&s, desc_level); + s.EOL(); + s.IndentLess(); +} + +ThreadPlanStack::ThreadPlanStack(const Thread &thread, bool make_null) { + if (make_null) { + // The ThreadPlanNull doesn't do anything to the Thread, so this is actually + // still a const operation. + m_plans.push_back( + ThreadPlanSP(new ThreadPlanNull(const_cast(thread)))); + } +} + +void ThreadPlanStack::DumpThreadPlans(Stream &s, + lldb::DescriptionLevel desc_level, + bool include_internal) const { + s.IndentMore(); + PrintOneStack(s, "Active plan stack", m_plans, desc_level, include_internal); + PrintOneStack(s, "Completed plan stack", m_completed_plans, desc_level, + include_internal); + PrintOneStack(s, "Discarded plan stack", m_discarded_plans, desc_level, + include_internal); + s.IndentLess(); +} + +void ThreadPlanStack::PrintOneStack(Stream &s, llvm::StringRef stack_name, + const PlanStack &stack, + lldb::DescriptionLevel desc_level, + bool include_internal) const { + // If the stack is empty, just exit: + if (stack.empty()) + return; + + // Make sure there are public completed plans: + bool any_public = false; + if (!include_internal) { + for (auto plan : stack) { + if (!plan->GetPrivate()) { + any_public = true; + break; + } + } + } + + if (include_internal || any_public) { + int print_idx = 0; + s.Indent(); + s << stack_name << ":\n"; + for (auto plan : stack) { + if (!include_internal && plan->GetPrivate()) + continue; + PrintPlanElement(s, plan, desc_level, print_idx++); + } + } +} + +size_t ThreadPlanStack::CheckpointCompletedPlans() { + m_completed_plan_checkpoint++; + m_completed_plan_store.insert( + std::make_pair(m_completed_plan_checkpoint, m_completed_plans)); + return m_completed_plan_checkpoint; +} + +void ThreadPlanStack::RestoreCompletedPlanCheckpoint(size_t checkpoint) { + auto result = m_completed_plan_store.find(checkpoint); + assert(result != m_completed_plan_store.end() && + "Asked for a checkpoint that didn't exist"); + m_completed_plans.swap((*result).second); + m_completed_plan_store.erase(result); +} + +void ThreadPlanStack::DiscardCompletedPlanCheckpoint(size_t checkpoint) { + m_completed_plan_store.erase(checkpoint); +} + +void ThreadPlanStack::ThreadDestroyed(Thread *thread) { + // Tell the plan stacks that this thread is going away: + for (ThreadPlanSP plan : m_plans) + plan->ThreadDestroyed(); + + for (ThreadPlanSP plan : m_discarded_plans) + plan->ThreadDestroyed(); + + for (ThreadPlanSP plan : m_completed_plans) + plan->ThreadDestroyed(); + + // Now clear the current plan stacks: + m_plans.clear(); + m_discarded_plans.clear(); + m_completed_plans.clear(); + + // Push a ThreadPlanNull on the plan stack. That way we can continue + // assuming that the plan stack is never empty, but if somebody errantly asks + // questions of a destroyed thread without checking first whether it is + // destroyed, they won't crash. + if (thread != nullptr) { + lldb::ThreadPlanSP null_plan_sp(new ThreadPlanNull(*thread)); + m_plans.push_back(null_plan_sp); + } +} + +void ThreadPlanStack::EnableTracer(bool value, bool single_stepping) { + for (ThreadPlanSP plan : m_plans) { + if (plan->GetThreadPlanTracer()) { + plan->GetThreadPlanTracer()->EnableTracing(value); + plan->GetThreadPlanTracer()->EnableSingleStep(single_stepping); + } + } +} + +void ThreadPlanStack::SetTracer(lldb::ThreadPlanTracerSP &tracer_sp) { + for (ThreadPlanSP plan : m_plans) + plan->SetThreadPlanTracer(tracer_sp); +} + +void ThreadPlanStack::PushPlan(lldb::ThreadPlanSP new_plan_sp) { + // If the thread plan doesn't already have a tracer, give it its parent's + // tracer: + // The first plan has to be a base plan: + assert((m_plans.size() > 0 || new_plan_sp->IsBasePlan()) && + "Zeroth plan must be a base plan"); + + if (!new_plan_sp->GetThreadPlanTracer()) { + assert(!m_plans.empty()); + new_plan_sp->SetThreadPlanTracer(m_plans.back()->GetThreadPlanTracer()); + } + m_plans.push_back(new_plan_sp); + new_plan_sp->DidPush(); +} + +lldb::ThreadPlanSP ThreadPlanStack::PopPlan() { + assert(m_plans.size() > 1 && "Can't pop the base thread plan"); + + lldb::ThreadPlanSP plan_sp = std::move(m_plans.back()); + m_completed_plans.push_back(plan_sp); + plan_sp->WillPop(); + m_plans.pop_back(); + return plan_sp; +} + +lldb::ThreadPlanSP ThreadPlanStack::DiscardPlan() { + assert(m_plans.size() > 1 && "Can't discard the base thread plan"); + + lldb::ThreadPlanSP plan_sp = std::move(m_plans.back()); + m_discarded_plans.push_back(plan_sp); + plan_sp->WillPop(); + m_plans.pop_back(); + return plan_sp; +} + +// If the input plan is nullptr, discard all plans. Otherwise make sure this +// plan is in the stack, and if so discard up to and including it. +void ThreadPlanStack::DiscardPlansUpToPlan(ThreadPlan *up_to_plan_ptr) { + int stack_size = m_plans.size(); + + if (up_to_plan_ptr == nullptr) { + for (int i = stack_size - 1; i > 0; i--) + DiscardPlan(); + return; + } + + bool found_it = false; + for (int i = stack_size - 1; i > 0; i--) { + if (m_plans[i].get() == up_to_plan_ptr) { + found_it = true; + break; + } + } + + if (found_it) { + bool last_one = false; + for (int i = stack_size - 1; i > 0 && !last_one; i--) { + if (GetCurrentPlan().get() == up_to_plan_ptr) + last_one = true; + DiscardPlan(); + } + } +} + +void ThreadPlanStack::DiscardAllPlans() { + int stack_size = m_plans.size(); + for (int i = stack_size - 1; i > 0; i--) { + DiscardPlan(); + } + return; +} + +void ThreadPlanStack::DiscardConsultingMasterPlans() { + while (true) { + int master_plan_idx; + bool discard = true; + + // Find the first master plan, see if it wants discarding, and if yes + // discard up to it. + for (master_plan_idx = m_plans.size() - 1; master_plan_idx >= 0; + master_plan_idx--) { + if (m_plans[master_plan_idx]->IsMasterPlan()) { + discard = m_plans[master_plan_idx]->OkayToDiscard(); + break; + } + } + + // If the master plan doesn't want to get discarded, then we're done. + if (!discard) + return; + + // First pop all the dependent plans: + for (int i = m_plans.size() - 1; i > master_plan_idx; i--) { + DiscardPlan(); + } + + // Now discard the master plan itself. + // The bottom-most plan never gets discarded. "OkayToDiscard" for it + // means discard it's dependent plans, but not it... + if (master_plan_idx > 0) { + DiscardPlan(); + } + } +} + +lldb::ThreadPlanSP ThreadPlanStack::GetCurrentPlan() const { + assert(m_plans.size() != 0 && "There will always be a base plan."); + return m_plans.back(); +} + +lldb::ThreadPlanSP ThreadPlanStack::GetCompletedPlan(bool skip_private) const { + if (m_completed_plans.empty()) + return {}; + + if (!skip_private) + return m_completed_plans.back(); + + for (int i = m_completed_plans.size() - 1; i >= 0; i--) { + lldb::ThreadPlanSP completed_plan_sp; + completed_plan_sp = m_completed_plans[i]; + if (!completed_plan_sp->GetPrivate()) + return completed_plan_sp; + } + return {}; +} + +lldb::ThreadPlanSP ThreadPlanStack::GetPlanByIndex(uint32_t plan_idx, + bool skip_private) const { + uint32_t idx = 0; + + for (lldb::ThreadPlanSP plan_sp : m_plans) { + if (skip_private && plan_sp->GetPrivate()) + continue; + if (idx == plan_idx) + return plan_sp; + idx++; + } + return {}; +} + +lldb::ValueObjectSP ThreadPlanStack::GetReturnValueObject() const { + if (m_completed_plans.empty()) + return {}; + + for (int i = m_completed_plans.size() - 1; i >= 0; i--) { + lldb::ValueObjectSP return_valobj_sp; + return_valobj_sp = m_completed_plans[i]->GetReturnValueObject(); + if (return_valobj_sp) + return return_valobj_sp; + } + return {}; +} + +lldb::ExpressionVariableSP ThreadPlanStack::GetExpressionVariable() const { + if (m_completed_plans.empty()) + return {}; + + for (int i = m_completed_plans.size() - 1; i >= 0; i--) { + lldb::ExpressionVariableSP expression_variable_sp; + expression_variable_sp = m_completed_plans[i]->GetExpressionVariable(); + if (expression_variable_sp) + return expression_variable_sp; + } + return {}; +} +bool ThreadPlanStack::AnyPlans() const { + // There is always a base plan... + return m_plans.size() > 1; +} + +bool ThreadPlanStack::AnyCompletedPlans() const { + return !m_completed_plans.empty(); +} + +bool ThreadPlanStack::AnyDiscardedPlans() const { + return !m_discarded_plans.empty(); +} + +bool ThreadPlanStack::IsPlanDone(ThreadPlan *in_plan) const { + for (auto plan : m_completed_plans) { + if (plan.get() == in_plan) + return true; + } + return false; +} + +bool ThreadPlanStack::WasPlanDiscarded(ThreadPlan *in_plan) const { + for (auto plan : m_discarded_plans) { + if (plan.get() == in_plan) + return true; + } + return false; +} + +ThreadPlan *ThreadPlanStack::GetPreviousPlan(ThreadPlan *current_plan) const { + if (current_plan == nullptr) + return nullptr; + + // Look first in the completed plans, if the plan is here and there is + // a completed plan above it, return that. + int stack_size = m_completed_plans.size(); + for (int i = stack_size - 1; i > 0; i--) { + if (current_plan == m_completed_plans[i].get()) + return m_completed_plans[i - 1].get(); + } + + // If this is the first completed plan, the previous one is the + // bottom of the regular plan stack. + if (stack_size > 0 && m_completed_plans[0].get() == current_plan) { + return GetCurrentPlan().get(); + } + + // Otherwise look for it in the regular plans. + stack_size = m_plans.size(); + for (int i = stack_size - 1; i > 0; i--) { + if (current_plan == m_plans[i].get()) + return m_plans[i - 1].get(); + } + return nullptr; +} + +ThreadPlan *ThreadPlanStack::GetInnermostExpression() const { + int stack_size = m_plans.size(); + + for (int i = stack_size - 1; i > 0; i--) { + if (m_plans[i]->GetKind() == ThreadPlan::eKindCallFunction) + return m_plans[i].get(); + } + return nullptr; +} + +void ThreadPlanStack::WillResume() { + m_completed_plans.clear(); + m_discarded_plans.clear(); +} + +const ThreadPlanStack::PlanStack & +ThreadPlanStack::GetStackOfKind(ThreadPlanStack::StackKind kind) const { + switch (kind) { + case ePlans: + return m_plans; + case eCompletedPlans: + return m_completed_plans; + case eDiscardedPlans: + return m_discarded_plans; + } + llvm_unreachable("Invalid StackKind value"); +} + +void ThreadPlanStackMap::Update(ThreadList ¤t_threads, + bool delete_missing, + bool check_for_new) { + + // Now find all the new threads and add them to the map: + if (check_for_new) { + for (auto thread : current_threads.Threads()) { + lldb::tid_t cur_tid = thread->GetID(); + if (!Find(cur_tid)) { + AddThread(*thread.get()); + thread->QueueFundamentalPlan(true); + } + } + } + + // If we aren't reaping missing threads at this point, + // we are done. + if (!delete_missing) + return; + // Otherwise scan for absent TID's. + std::vector missing_threads; + // If we are going to delete plans from the plan stack, + // then scan for absent TID's: + for (auto thread_plans : m_plans_list) { + lldb::tid_t cur_tid = thread_plans.first; + ThreadSP thread_sp = current_threads.FindThreadByID(cur_tid); + if (!thread_sp) + missing_threads.push_back(cur_tid); + } + for (lldb::tid_t tid : missing_threads) { + RemoveTID(tid); + } +} + +void ThreadPlanStackMap::DumpPlans(Stream &strm, + lldb::DescriptionLevel desc_level, + bool internal, bool condense_if_trivial, + bool skip_unreported) { + for (auto elem : m_plans_list) { + lldb::tid_t tid = elem.first; + uint32_t index_id = 0; + ThreadSP thread_sp = m_process.GetThreadList().FindThreadByID(tid); + + if (skip_unreported) { + if (!thread_sp) + continue; + } + if (thread_sp) + index_id = thread_sp->GetIndexID(); + + if (condense_if_trivial) { + if (!elem.second.AnyPlans() && !elem.second.AnyCompletedPlans() && + !elem.second.AnyDiscardedPlans()) { + strm.Printf("thread #%u: tid = 0x%4.4" PRIx64 "\n", index_id, tid); + strm.IndentMore(); + strm.Indent(); + strm.Printf("No active thread plans\n"); + strm.IndentLess(); + return; + } + } + + strm.Indent(); + strm.Printf("thread #%u: tid = 0x%4.4" PRIx64 ":\n", index_id, tid); + + elem.second.DumpThreadPlans(strm, desc_level, internal); + } +} + +bool ThreadPlanStackMap::DumpPlansForTID(Stream &strm, lldb::tid_t tid, + lldb::DescriptionLevel desc_level, + bool internal, + bool condense_if_trivial, + bool skip_unreported) { + uint32_t index_id = 0; + ThreadSP thread_sp = m_process.GetThreadList().FindThreadByID(tid); + + if (skip_unreported) { + if (!thread_sp) { + strm.Format("Unknown TID: {0}", tid); + return false; + } + } + + if (thread_sp) + index_id = thread_sp->GetIndexID(); + ThreadPlanStack *stack = Find(tid); + if (!stack) { + strm.Format("Unknown TID: {0}\n", tid); + return false; + } + + if (condense_if_trivial) { + if (!stack->AnyPlans() && !stack->AnyCompletedPlans() && + !stack->AnyDiscardedPlans()) { + strm.Printf("thread #%u: tid = 0x%4.4" PRIx64 "\n", index_id, tid); + strm.IndentMore(); + strm.Indent(); + strm.Printf("No active thread plans\n"); + strm.IndentLess(); + return true; + } + } + + strm.Indent(); + strm.Printf("thread #%u: tid = 0x%4.4" PRIx64 ":\n", index_id, tid); + + stack->DumpThreadPlans(strm, desc_level, internal); + return true; +} + +bool ThreadPlanStackMap::PrunePlansForTID(lldb::tid_t tid) { + // We only remove the plans for unreported TID's. + ThreadSP thread_sp = m_process.GetThreadList().FindThreadByID(tid); + if (thread_sp) + return false; + + return RemoveTID(tid); +} diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanStepInRange.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanStepInRange.cpp index ab1f6a21a86..c5f81d6665a 100644 --- a/gnu/llvm/lldb/source/Target/ThreadPlanStepInRange.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadPlanStepInRange.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlanStepInRange.cpp -------------------------------*- C++ -*-===// +//===-- ThreadPlanStepInRange.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -69,7 +69,7 @@ void ThreadPlanStepInRange::SetupAvoidNoDebug( LazyBool step_in_avoids_code_without_debug_info, LazyBool step_out_avoids_code_without_debug_info) { bool avoid_nodebug = true; - + Thread &thread = GetThread(); switch (step_in_avoids_code_without_debug_info) { case eLazyBoolYes: avoid_nodebug = true; @@ -78,7 +78,7 @@ void ThreadPlanStepInRange::SetupAvoidNoDebug( avoid_nodebug = false; break; case eLazyBoolCalculate: - avoid_nodebug = m_thread.GetStepInAvoidsNoDebug(); + avoid_nodebug = thread.GetStepInAvoidsNoDebug(); break; } if (avoid_nodebug) @@ -94,7 +94,7 @@ void ThreadPlanStepInRange::SetupAvoidNoDebug( avoid_nodebug = false; break; case eLazyBoolCalculate: - avoid_nodebug = m_thread.GetStepOutAvoidsNoDebug(); + avoid_nodebug = thread.GetStepOutAvoidsNoDebug(); break; } if (avoid_nodebug) @@ -145,9 +145,8 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) { if (log) { StreamString s; - DumpAddress( - s.AsRawOstream(), m_thread.GetRegisterContext()->GetPC(), - m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize()); + DumpAddress(s.AsRawOstream(), GetThread().GetRegisterContext()->GetPC(), + GetTarget().GetArchitecture().GetAddressByteSize()); LLDB_LOGF(log, "ThreadPlanStepInRange reached %s.", s.GetData()); } @@ -180,6 +179,7 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) { FrameComparison frame_order = CompareCurrentFrameToStartFrame(); + Thread &thread = GetThread(); if (frame_order == eFrameCompareOlder || frame_order == eFrameCompareSameParent) { // If we're in an older frame then we should stop. @@ -189,7 +189,7 @@ 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_sub_plan_sp = thread.QueueThreadPlanForStepThrough( m_stack_id, false, stop_others, m_status); if (!m_sub_plan_sp) { // Otherwise check the ShouldStopHere for step out: @@ -233,7 +233,7 @@ 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_sub_plan_sp = thread.QueueThreadPlanForStepThrough( m_stack_id, false, stop_others, m_status); if (log) { @@ -254,10 +254,10 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) { if (!m_sub_plan_sp && frame_order == eFrameCompareYounger && m_step_past_prologue) { - lldb::StackFrameSP curr_frame = m_thread.GetStackFrameAtIndex(0); + lldb::StackFrameSP curr_frame = thread.GetStackFrameAtIndex(0); if (curr_frame) { size_t bytes_to_skip = 0; - lldb::addr_t curr_addr = m_thread.GetRegisterContext()->GetPC(); + lldb::addr_t curr_addr = thread.GetRegisterContext()->GetPC(); Address func_start_address; SymbolContext sc = curr_frame->GetSymbolContext(eSymbolContextFunction | @@ -265,25 +265,20 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) { if (sc.function) { func_start_address = sc.function->GetAddressRange().GetBaseAddress(); - if (curr_addr == - func_start_address.GetLoadAddress( - m_thread.CalculateTarget().get())) + if (curr_addr == func_start_address.GetLoadAddress(&GetTarget())) bytes_to_skip = sc.function->GetPrologueByteSize(); } else if (sc.symbol) { func_start_address = sc.symbol->GetAddress(); - if (curr_addr == - func_start_address.GetLoadAddress( - m_thread.CalculateTarget().get())) + if (curr_addr == func_start_address.GetLoadAddress(&GetTarget())) bytes_to_skip = sc.symbol->GetPrologueByteSize(); } if (bytes_to_skip == 0 && sc.symbol) { - TargetSP target = m_thread.CalculateTarget(); - const Architecture *arch = target->GetArchitecturePlugin(); + const Architecture *arch = GetTarget().GetArchitecturePlugin(); if (arch) { Address curr_sec_addr; - target->GetSectionLoadList().ResolveLoadAddress(curr_addr, - curr_sec_addr); + GetTarget().GetSectionLoadList().ResolveLoadAddress(curr_addr, + curr_sec_addr); bytes_to_skip = arch->GetBytesToSkip(*sc.symbol, curr_sec_addr); } } @@ -293,7 +288,7 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) { log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP); LLDB_LOGF(log, "Pushing past prologue "); - m_sub_plan_sp = m_thread.QueueThreadPlanForRunToAddress( + m_sub_plan_sp = thread.QueueThreadPlanForRunToAddress( false, func_start_address, true, m_status); } } @@ -316,7 +311,7 @@ void ThreadPlanStepInRange::SetAvoidRegexp(const char *name) { if (m_avoid_regexp_up) *m_avoid_regexp_up = RegularExpression(name_ref); else - m_avoid_regexp_up.reset(new RegularExpression(name_ref)); + m_avoid_regexp_up = std::make_unique(name_ref); } void ThreadPlanStepInRange::SetDefaultFlagValue(uint32_t new_value) { @@ -486,15 +481,16 @@ bool ThreadPlanStepInRange::DoWillResume(lldb::StateType resume_state, bool current_plan) { m_virtual_step = false; if (resume_state == eStateStepping && current_plan) { + Thread &thread = GetThread(); // See if we are about to step over a virtual inlined call. - bool step_without_resume = m_thread.DecrementCurrentInlinedDepth(); + bool step_without_resume = thread.DecrementCurrentInlinedDepth(); if (step_without_resume) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); LLDB_LOGF(log, "ThreadPlanStepInRange::DoWillResume: returning false, " "inline_depth: %d", - m_thread.GetCurrentInlinedDepth()); - SetStopInfo(StopInfo::CreateStopReasonToTrace(m_thread)); + thread.GetCurrentInlinedDepth()); + SetStopInfo(StopInfo::CreateStopReasonToTrace(thread)); // FIXME: Maybe it would be better to create a InlineStep stop reason, but // then diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanStepInstruction.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanStepInstruction.cpp index afcc9d608b2..c0da735c44b 100644 --- a/gnu/llvm/lldb/source/Target/ThreadPlanStepInstruction.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadPlanStepInstruction.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlanStepInstruction.cpp ---------------------------*- C++ -*-===// +//===-- ThreadPlanStepInstruction.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -36,14 +36,15 @@ ThreadPlanStepInstruction::ThreadPlanStepInstruction(Thread &thread, ThreadPlanStepInstruction::~ThreadPlanStepInstruction() = default; void ThreadPlanStepInstruction::SetUpState() { - m_instruction_addr = m_thread.GetRegisterContext()->GetPC(0); - StackFrameSP start_frame_sp(m_thread.GetStackFrameAtIndex(0)); + Thread &thread = GetThread(); + m_instruction_addr = thread.GetRegisterContext()->GetPC(0); + StackFrameSP start_frame_sp(thread.GetStackFrameAtIndex(0)); m_stack_id = start_frame_sp->GetStackID(); m_start_has_symbol = start_frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol != nullptr; - StackFrameSP parent_frame_sp = m_thread.GetStackFrameAtIndex(1); + StackFrameSP parent_frame_sp = thread.GetStackFrameAtIndex(1); if (parent_frame_sp) m_parent_frame_id = parent_frame_sp->GetStackID(); } @@ -95,18 +96,19 @@ bool ThreadPlanStepInstruction::DoPlanExplainsStop(Event *event_ptr) { bool ThreadPlanStepInstruction::IsPlanStale() { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); - StackID cur_frame_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); + Thread &thread = GetThread(); + StackID cur_frame_id = thread.GetStackFrameAtIndex(0)->GetStackID(); if (cur_frame_id == m_stack_id) { // Set plan Complete when we reach next instruction - uint64_t pc = m_thread.GetRegisterContext()->GetPC(0); - uint32_t max_opcode_size = m_thread.CalculateTarget() - ->GetArchitecture().GetMaximumOpcodeByteSize(); + uint64_t pc = thread.GetRegisterContext()->GetPC(0); + uint32_t max_opcode_size = + GetTarget().GetArchitecture().GetMaximumOpcodeByteSize(); bool next_instruction_reached = (pc > m_instruction_addr) && (pc <= m_instruction_addr + max_opcode_size); if (next_instruction_reached) { SetPlanComplete(); } - return (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr); + return (thread.GetRegisterContext()->GetPC(0) != m_instruction_addr); } else if (cur_frame_id < m_stack_id) { // If the current frame is younger than the start frame and we are stepping // over, then we need to continue, but if we are doing just one step, we're @@ -123,10 +125,10 @@ bool ThreadPlanStepInstruction::IsPlanStale() { } bool ThreadPlanStepInstruction::ShouldStop(Event *event_ptr) { + Thread &thread = GetThread(); if (m_step_over) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); - - StackFrameSP cur_frame_sp = m_thread.GetStackFrameAtIndex(0); + StackFrameSP cur_frame_sp = thread.GetStackFrameAtIndex(0); if (!cur_frame_sp) { LLDB_LOGF( log, @@ -138,7 +140,7 @@ bool ThreadPlanStepInstruction::ShouldStop(Event *event_ptr) { StackID cur_frame_zero_id = cur_frame_sp->GetStackID(); if (cur_frame_zero_id == m_stack_id || m_stack_id < cur_frame_zero_id) { - if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) { + if (thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) { if (--m_iteration_count <= 0) { SetPlanComplete(); return true; @@ -152,7 +154,7 @@ bool ThreadPlanStepInstruction::ShouldStop(Event *event_ptr) { return false; } else { // We've stepped in, step back out again: - StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get(); + StackFrame *return_frame = thread.GetStackFrameAtIndex(1).get(); if (return_frame) { if (return_frame->GetStackID() != m_parent_frame_id || m_start_has_symbol) { @@ -162,7 +164,7 @@ bool ThreadPlanStepInstruction::ShouldStop(Event *event_ptr) { if (cur_frame_sp->IsInlined()) { StackFrameSP parent_frame_sp = - m_thread.GetFrameWithStackID(m_stack_id); + thread.GetFrameWithStackID(m_stack_id); if (parent_frame_sp && parent_frame_sp->GetConcreteFrameIndex() == @@ -181,24 +183,20 @@ bool ThreadPlanStepInstruction::ShouldStop(Event *event_ptr) { StreamString s; s.PutCString("Stepped in to: "); addr_t stop_addr = - m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); + thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); DumpAddress(s.AsRawOstream(), stop_addr, - m_thread.CalculateTarget() - ->GetArchitecture() - .GetAddressByteSize()); + GetTarget().GetArchitecture().GetAddressByteSize()); s.PutCString(" stepping out to: "); addr_t return_addr = return_frame->GetRegisterContext()->GetPC(); DumpAddress(s.AsRawOstream(), return_addr, - m_thread.CalculateTarget() - ->GetArchitecture() - .GetAddressByteSize()); + GetTarget().GetArchitecture().GetAddressByteSize()); LLDB_LOGF(log, "%s.", s.GetData()); } // StepInstruction should probably have the tri-state RunMode, but // for now it is safer to run others. const bool stop_others = false; - m_thread.QueueThreadPlanForStepOutNoShouldStop( + thread.QueueThreadPlanForStepOutNoShouldStop( false, nullptr, true, stop_others, eVoteNo, eVoteNoOpinion, 0, m_status); return false; @@ -219,7 +217,7 @@ bool ThreadPlanStepInstruction::ShouldStop(Event *event_ptr) { } } } else { - lldb::addr_t pc_addr = m_thread.GetRegisterContext()->GetPC(0); + lldb::addr_t pc_addr = thread.GetRegisterContext()->GetPC(0); if (pc_addr != m_instruction_addr) { if (--m_iteration_count <= 0) { SetPlanComplete(); diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanStepOut.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanStepOut.cpp index f15a343aaa3..9f0749c0fdb 100644 --- a/gnu/llvm/lldb/source/Target/ThreadPlanStepOut.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadPlanStepOut.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlanStepOut.cpp -----------------------------------*- C++ -*-===// +//===-- ThreadPlanStepOut.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -47,13 +47,11 @@ ThreadPlanStepOut::ThreadPlanStepOut( SetFlagsToDefault(); SetupAvoidNoDebug(step_out_avoids_code_without_debug_info); - m_step_from_insn = m_thread.GetRegisterContext()->GetPC(0); + m_step_from_insn = thread.GetRegisterContext()->GetPC(0); 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)); + StackFrameSP return_frame_sp(thread.GetStackFrameAtIndex(return_frame_index)); + StackFrameSP immediate_return_from_sp(thread.GetStackFrameAtIndex(frame_idx)); if (!return_frame_sp || !immediate_return_from_sp) return; // we can't do anything here. ValidatePlan() will return false. @@ -63,7 +61,7 @@ ThreadPlanStepOut::ThreadPlanStepOut( m_stepped_past_frames.push_back(return_frame_sp); ++return_frame_index; - return_frame_sp = m_thread.GetStackFrameAtIndex(return_frame_index); + return_frame_sp = 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. @@ -85,7 +83,7 @@ ThreadPlanStepOut::ThreadPlanStepOut( // 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. m_step_out_to_inline_plan_sp = std::make_shared( - m_thread, nullptr, false, stop_others, eVoteNoOpinion, eVoteNoOpinion, + thread, nullptr, false, stop_others, eVoteNoOpinion, eVoteNoOpinion, frame_idx - 1, eLazyBoolNo, continue_to_next_branch); static_cast(m_step_out_to_inline_plan_sp.get()) ->SetShouldStopHereCallbacks(nullptr, nullptr); @@ -114,28 +112,22 @@ ThreadPlanStepOut::ThreadPlanStepOut( range = return_address_sc.line_entry.GetSameLineContiguousAddressRange( include_inlined_functions); if (range.GetByteSize() > 0) { - return_address = - m_thread.GetProcess()->AdvanceAddressToNextBranchInstruction( - return_address, range); + return_address = m_process.AdvanceAddressToNextBranchInstruction( + return_address, range); } } } - m_return_addr = - return_address.GetLoadAddress(&m_thread.GetProcess()->GetTarget()); + m_return_addr = return_address.GetLoadAddress(&m_process.GetTarget()); if (m_return_addr == LLDB_INVALID_ADDRESS) return; // Perform some additional validation on the return address. uint32_t permissions = 0; - if (!m_thread.GetProcess()->GetLoadAddressPermissions(m_return_addr, - permissions)) { - m_constructor_errors.Printf("Return address (0x%" PRIx64 - ") permissions not found.", - m_return_addr); - LLDB_LOGF(log, "ThreadPlanStepOut(%p): %s", static_cast(this), - m_constructor_errors.GetData()); - return; + if (!m_process.GetLoadAddressPermissions(m_return_addr, permissions)) { + LLDB_LOGF(log, "ThreadPlanStepOut(%p): Return address (0x%" PRIx64 + ") permissions not found.", static_cast(this), + m_return_addr); } else if (!(permissions & ePermissionsExecutable)) { m_constructor_errors.Printf("Return address (0x%" PRIx64 ") did not point to executable memory.", @@ -145,14 +137,13 @@ ThreadPlanStepOut::ThreadPlanStepOut( return; } - Breakpoint *return_bp = m_thread.CalculateTarget() - ->CreateBreakpoint(m_return_addr, true, false) - .get(); + Breakpoint *return_bp = + GetTarget().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()); + return_bp->SetThreadID(m_tid); m_return_bp_id = return_bp->GetID(); return_bp->SetBreakpointKind("step-out"); } @@ -178,7 +169,7 @@ void ThreadPlanStepOut::SetupAvoidNoDebug( avoid_nodebug = false; break; case eLazyBoolCalculate: - avoid_nodebug = m_thread.GetStepOutAvoidsNoDebug(); + avoid_nodebug = GetThread().GetStepOutAvoidsNoDebug(); break; } if (avoid_nodebug) @@ -188,15 +179,16 @@ void ThreadPlanStepOut::SetupAvoidNoDebug( } void ThreadPlanStepOut::DidPush() { + Thread &thread = GetThread(); if (m_step_out_to_inline_plan_sp) - m_thread.QueueThreadPlan(m_step_out_to_inline_plan_sp, false); + thread.QueueThreadPlan(m_step_out_to_inline_plan_sp, false); else if (m_step_through_inline_plan_sp) - m_thread.QueueThreadPlan(m_step_through_inline_plan_sp, false); + thread.QueueThreadPlan(m_step_through_inline_plan_sp, false); } ThreadPlanStepOut::~ThreadPlanStepOut() { if (m_return_bp_id != LLDB_INVALID_BREAK_ID) - m_thread.CalculateTarget()->RemoveBreakpointByID(m_return_bp_id); + GetTarget().RemoveBreakpointByID(m_return_bp_id); } void ThreadPlanStepOut::GetDescription(Stream *s, @@ -212,7 +204,7 @@ void ThreadPlanStepOut::GetDescription(Stream *s, s->Printf("Stepping out from "); Address tmp_address; if (tmp_address.SetLoadAddress(m_step_from_insn, &GetTarget())) { - tmp_address.Dump(s, &GetThread(), Address::DumpStyleResolvedDescription, + tmp_address.Dump(s, &m_process, Address::DumpStyleResolvedDescription, Address::DumpStyleLoadAddress); } else { s->Printf("address 0x%" PRIx64 "", (uint64_t)m_step_from_insn); @@ -224,7 +216,7 @@ void ThreadPlanStepOut::GetDescription(Stream *s, s->Printf(" returning to frame at "); if (tmp_address.SetLoadAddress(m_return_addr, &GetTarget())) { - tmp_address.Dump(s, &GetThread(), Address::DumpStyleResolvedDescription, + tmp_address.Dump(s, &m_process, Address::DumpStyleResolvedDescription, Address::DumpStyleLoadAddress); } else { s->Printf("address 0x%" PRIx64 "", (uint64_t)m_return_addr); @@ -235,6 +227,9 @@ void ThreadPlanStepOut::GetDescription(Stream *s, } } + if (m_stepped_past_frames.empty()) + return; + s->Printf("\n"); for (StackFrameSP frame_sp : m_stepped_past_frames) { s->Printf("Stepped out past: "); @@ -296,12 +291,12 @@ bool ThreadPlanStepOut::DoPlanExplainsStop(Event *event_ptr) { // If this is OUR breakpoint, we're fine, otherwise we don't know why // this happened... BreakpointSiteSP site_sp( - m_thread.GetProcess()->GetBreakpointSiteList().FindByID( - stop_info_sp->GetValue())); + m_process.GetBreakpointSiteList().FindByID(stop_info_sp->GetValue())); if (site_sp && site_sp->IsBreakpointAtThisSite(m_return_bp_id)) { bool done; - StackID frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); + StackID frame_zero_id = + GetThread().GetStackFrameAtIndex(0)->GetStackID(); if (m_step_out_to_id == frame_zero_id) done = true; @@ -368,7 +363,7 @@ bool ThreadPlanStepOut::ShouldStop(Event *event_ptr) { } if (!done) { - StackID frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); + StackID frame_zero_id = GetThread().GetStackFrameAtIndex(0)->GetStackID(); done = !(frame_zero_id < m_step_out_to_id); } @@ -402,8 +397,7 @@ bool ThreadPlanStepOut::DoWillResume(StateType resume_state, return false; if (current_plan) { - Breakpoint *return_bp = - m_thread.CalculateTarget()->GetBreakpointByID(m_return_bp_id).get(); + Breakpoint *return_bp = GetTarget().GetBreakpointByID(m_return_bp_id).get(); if (return_bp != nullptr) return_bp->SetEnabled(true); } @@ -412,8 +406,7 @@ bool ThreadPlanStepOut::DoWillResume(StateType resume_state, bool ThreadPlanStepOut::WillStop() { if (m_return_bp_id != LLDB_INVALID_BREAK_ID) { - Breakpoint *return_bp = - m_thread.CalculateTarget()->GetBreakpointByID(m_return_bp_id).get(); + Breakpoint *return_bp = GetTarget().GetBreakpointByID(m_return_bp_id).get(); if (return_bp != nullptr) return_bp->SetEnabled(false); } @@ -434,7 +427,7 @@ bool ThreadPlanStepOut::MischiefManaged() { if (log) LLDB_LOGF(log, "Completed step out plan."); if (m_return_bp_id != LLDB_INVALID_BREAK_ID) { - m_thread.CalculateTarget()->RemoveBreakpointByID(m_return_bp_id); + GetTarget().RemoveBreakpointByID(m_return_bp_id); m_return_bp_id = LLDB_INVALID_BREAK_ID; } @@ -449,7 +442,8 @@ bool ThreadPlanStepOut::QueueInlinedStepPlan(bool queue_now) { // Now figure out the range of this inlined block, and set up a "step through // range" plan for that. If we've been provided with a context, then use the // block in that context. - StackFrameSP immediate_return_from_sp(m_thread.GetStackFrameAtIndex(0)); + Thread &thread = GetThread(); + StackFrameSP immediate_return_from_sp(thread.GetStackFrameAtIndex(0)); if (!immediate_return_from_sp) return false; @@ -476,7 +470,7 @@ bool ThreadPlanStepOut::QueueInlinedStepPlan(bool queue_now) { m_step_through_inline_plan_sp = std::make_shared( - m_thread, inline_range, inlined_sc, run_mode, avoid_no_debug); + thread, inline_range, inlined_sc, run_mode, avoid_no_debug); ThreadPlanStepOverRange *step_through_inline_plan_ptr = static_cast( m_step_through_inline_plan_sp.get()); @@ -496,7 +490,7 @@ bool ThreadPlanStepOut::QueueInlinedStepPlan(bool queue_now) { } if (queue_now) - m_thread.QueueThreadPlan(m_step_through_inline_plan_sp, false); + thread.QueueThreadPlan(m_step_through_inline_plan_sp, false); return true; } } @@ -517,10 +511,10 @@ void ThreadPlanStepOut::CalculateReturnValue() { m_immediate_step_from_function->GetCompilerType() .GetFunctionReturnType(); if (return_compiler_type) { - lldb::ABISP abi_sp = m_thread.GetProcess()->GetABI(); + lldb::ABISP abi_sp = m_process.GetABI(); if (abi_sp) m_return_valobj_sp = - abi_sp->GetReturnValueObject(m_thread, return_compiler_type); + abi_sp->GetReturnValueObject(GetThread(), return_compiler_type); } } } @@ -529,6 +523,6 @@ bool ThreadPlanStepOut::IsPlanStale() { // If we are still lower on the stack than the frame we are returning to, // then there's something for us to do. Otherwise, we're stale. - StackID frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); + StackID frame_zero_id = GetThread().GetStackFrameAtIndex(0)->GetStackID(); return !(frame_zero_id < m_step_out_to_id); } diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp index 725669b1e9a..f3d35a91fcb 100644 --- a/gnu/llvm/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlanStepOverBreakpoint.cpp ------------------------*- C++ -*-===// +//===-- ThreadPlanStepOverBreakpoint.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -30,9 +30,9 @@ ThreadPlanStepOverBreakpoint::ThreadPlanStepOverBreakpoint(Thread &thread) m_auto_continue(false), m_reenabled_breakpoint_site(false) { - m_breakpoint_addr = m_thread.GetRegisterContext()->GetPC(); + m_breakpoint_addr = thread.GetRegisterContext()->GetPC(); m_breakpoint_site_id = - m_thread.GetProcess()->GetBreakpointSiteList().FindIDByAddress( + thread.GetProcess()->GetBreakpointSiteList().FindIDByAddress( m_breakpoint_addr); } @@ -86,7 +86,7 @@ bool ThreadPlanStepOverBreakpoint::DoPlanExplainsStop(Event *event_ptr) { // Be careful, however, as we may have "seen a breakpoint under the PC // because we stopped without changing the PC, in which case we do want // to re-claim this stop so we'll try again. - lldb::addr_t pc_addr = m_thread.GetRegisterContext()->GetPC(); + lldb::addr_t pc_addr = GetThread().GetRegisterContext()->GetPC(); if (pc_addr == m_breakpoint_addr) { LLDB_LOGF(log, @@ -120,10 +120,9 @@ bool ThreadPlanStepOverBreakpoint::DoWillResume(StateType resume_state, bool current_plan) { if (current_plan) { BreakpointSiteSP bp_site_sp( - m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress( - m_breakpoint_addr)); + m_process.GetBreakpointSiteList().FindByAddress(m_breakpoint_addr)); if (bp_site_sp && bp_site_sp->IsEnabled()) { - m_thread.GetProcess()->DisableBreakpointSite(bp_site_sp.get()); + m_process.DisableBreakpointSite(bp_site_sp.get()); m_reenabled_breakpoint_site = false; } } @@ -140,7 +139,7 @@ void ThreadPlanStepOverBreakpoint::WillPop() { } bool ThreadPlanStepOverBreakpoint::MischiefManaged() { - lldb::addr_t pc_addr = m_thread.GetRegisterContext()->GetPC(); + lldb::addr_t pc_addr = GetThread().GetRegisterContext()->GetPC(); if (pc_addr == m_breakpoint_addr) { // If we are still at the PC of our breakpoint, then for some reason we @@ -161,10 +160,9 @@ void ThreadPlanStepOverBreakpoint::ReenableBreakpointSite() { if (!m_reenabled_breakpoint_site) { m_reenabled_breakpoint_site = true; BreakpointSiteSP bp_site_sp( - m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress( - m_breakpoint_addr)); + m_process.GetBreakpointSiteList().FindByAddress(m_breakpoint_addr)); if (bp_site_sp) { - m_thread.GetProcess()->EnableBreakpointSite(bp_site_sp.get()); + m_process.EnableBreakpointSite(bp_site_sp.get()); } } } @@ -181,5 +179,5 @@ bool ThreadPlanStepOverBreakpoint::ShouldAutoContinue(Event *event_ptr) { } bool ThreadPlanStepOverBreakpoint::IsPlanStale() { - return m_thread.GetRegisterContext()->GetPC() != m_breakpoint_addr; + return GetThread().GetRegisterContext()->GetPC() != m_breakpoint_addr; } diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanStepOverRange.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanStepOverRange.cpp index 3dc1967e6d4..1bf3d5352c5 100644 --- a/gnu/llvm/lldb/source/Target/ThreadPlanStepOverRange.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadPlanStepOverRange.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlanStepOverRange.cpp -----------------------------*- C++ -*-===// +//===-- ThreadPlanStepOverRange.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -85,7 +85,7 @@ void ThreadPlanStepOverRange::SetupAvoidNoDebug( avoid_nodebug = false; break; case eLazyBoolCalculate: - avoid_nodebug = m_thread.GetStepOutAvoidsNoDebug(); + avoid_nodebug = GetThread().GetStepOutAvoidsNoDebug(); break; } if (avoid_nodebug) @@ -125,12 +125,12 @@ bool ThreadPlanStepOverRange::IsEquivalentContext( bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Thread &thread = GetThread(); if (log) { StreamString s; - DumpAddress( - s.AsRawOstream(), m_thread.GetRegisterContext()->GetPC(), - m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize()); + DumpAddress(s.AsRawOstream(), thread.GetRegisterContext()->GetPC(), + GetTarget().GetArchitecture().GetAddressByteSize()); LLDB_LOGF(log, "ThreadPlanStepOverRange reached %s.", s.GetData()); } @@ -151,8 +151,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, m_status); + new_plan_sp = thread.QueueThreadPlanForStepThrough(m_stack_id, false, + stop_others, m_status); if (new_plan_sp && log) LLDB_LOGF(log, @@ -161,7 +161,7 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) { // Make sure we really are in a new frame. Do that by unwinding and seeing // if the start function really is our start function... for (uint32_t i = 1;; ++i) { - StackFrameSP older_frame_sp = m_thread.GetStackFrameAtIndex(i); + StackFrameSP older_frame_sp = thread.GetStackFrameAtIndex(i); if (!older_frame_sp) { // We can't unwind the next frame we should just get out of here & // stop... @@ -171,12 +171,16 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) { const SymbolContext &older_context = older_frame_sp->GetSymbolContext(eSymbolContextEverything); if (IsEquivalentContext(older_context)) { - new_plan_sp = m_thread.QueueThreadPlanForStepOutNoShouldStop( + // If we have the next-branch-breakpoint in the range, we can just + // rely on that breakpoint to trigger once we return to the range. + if (m_next_branch_bp_sp) + return false; + new_plan_sp = thread.QueueThreadPlanForStepOutNoShouldStop( false, nullptr, true, stop_others, eVoteNo, eVoteNoOpinion, 0, m_status, true); break; } else { - new_plan_sp = m_thread.QueueThreadPlanForStepThrough( + new_plan_sp = 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) @@ -196,8 +200,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, m_status); + new_plan_sp = 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 @@ -212,7 +216,7 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) { if (m_addr_context.line_entry.IsValid()) { SymbolContext sc; - StackFrameSP frame_sp = m_thread.GetStackFrameAtIndex(0); + StackFrameSP frame_sp = thread.GetStackFrameAtIndex(0); sc = frame_sp->GetSymbolContext(eSymbolContextEverything); if (sc.line_entry.IsValid()) { if (sc.line_entry.original_file != @@ -278,7 +282,7 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) { m_addr_context.line_entry.original_file) { const bool abort_other_plans = false; const RunMode stop_other_threads = RunMode::eAllThreads; - lldb::addr_t cur_pc = m_thread.GetStackFrameAtIndex(0) + lldb::addr_t cur_pc = thread.GetStackFrameAtIndex(0) ->GetRegisterContext() ->GetPC(); AddressRange step_range( @@ -286,7 +290,7 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) { next_line_address.GetLoadAddress(&GetTarget()) - cur_pc); - new_plan_sp = m_thread.QueueThreadPlanForStepOverRange( + new_plan_sp = thread.QueueThreadPlanForStepOverRange( abort_other_plans, step_range, sc, stop_other_threads, m_status); break; @@ -365,23 +369,24 @@ bool ThreadPlanStepOverRange::DoWillResume(lldb::StateType resume_state, if (resume_state != eStateSuspended && m_first_resume) { m_first_resume = false; if (resume_state == eStateStepping && current_plan) { + Thread &thread = GetThread(); // See if we are about to step over an inlined call in the middle of the // inlined stack, if so figure out its extents and reset our range to // step over that. - bool in_inlined_stack = m_thread.DecrementCurrentInlinedDepth(); + bool in_inlined_stack = thread.DecrementCurrentInlinedDepth(); if (in_inlined_stack) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); LLDB_LOGF(log, "ThreadPlanStepInRange::DoWillResume: adjusting range to " "the frame at inlined depth %d.", - m_thread.GetCurrentInlinedDepth()); - StackFrameSP stack_sp = m_thread.GetStackFrameAtIndex(0); + thread.GetCurrentInlinedDepth()); + StackFrameSP stack_sp = thread.GetStackFrameAtIndex(0); if (stack_sp) { Block *frame_block = stack_sp->GetFrameBlock(); - lldb::addr_t curr_pc = m_thread.GetRegisterContext()->GetPC(); + lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC(); AddressRange my_range; if (frame_block->GetRangeContainingLoadAddress( - curr_pc, m_thread.GetProcess()->GetTarget(), my_range)) { + curr_pc, m_process.GetTarget(), my_range)) { m_address_ranges.clear(); m_address_ranges.push_back(my_range); if (log) { @@ -390,11 +395,7 @@ bool ThreadPlanStepOverRange::DoWillResume(lldb::StateType resume_state, frame_block->GetInlinedFunctionInfo(); const char *name; if (inline_info) - name = - inline_info - ->GetName(frame_block->CalculateSymbolContextFunction() - ->GetLanguage()) - .AsCString(); + name = inline_info->GetName().AsCString(); else name = ""; diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanStepRange.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanStepRange.cpp index d1c56165da5..f4b2ee3d08a 100644 --- a/gnu/llvm/lldb/source/Target/ThreadPlanStepRange.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadPlanStepRange.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlanStepRange.cpp ---------------------------------*- C++ -*-===// +//===-- ThreadPlanStepRange.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -41,8 +41,8 @@ ThreadPlanStepRange::ThreadPlanStepRange(ThreadPlanKind kind, const char *name, m_given_ranges_only(given_ranges_only) { m_use_fast_step = GetTarget().GetUseFastStepping(); AddRange(range); - m_stack_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); - StackFrameSP parent_stack = m_thread.GetStackFrameAtIndex(1); + m_stack_id = thread.GetStackFrameAtIndex(0)->GetStackID(); + StackFrameSP parent_stack = thread.GetStackFrameAtIndex(1); if (parent_stack) m_parent_stack_id = parent_stack->GetStackID(); } @@ -88,13 +88,11 @@ void ThreadPlanStepRange::AddRange(const AddressRange &new_range) { void ThreadPlanStepRange::DumpRanges(Stream *s) { size_t num_ranges = m_address_ranges.size(); if (num_ranges == 1) { - m_address_ranges[0].Dump(s, m_thread.CalculateTarget().get(), - Address::DumpStyleLoadAddress); + m_address_ranges[0].Dump(s, &GetTarget(), Address::DumpStyleLoadAddress); } else { for (size_t i = 0; i < num_ranges; i++) { s->Printf(" %" PRIu64 ": ", uint64_t(i)); - m_address_ranges[i].Dump(s, m_thread.CalculateTarget().get(), - Address::DumpStyleLoadAddress); + m_address_ranges[i].Dump(s, &GetTarget(), Address::DumpStyleLoadAddress); } } } @@ -102,20 +100,20 @@ void ThreadPlanStepRange::DumpRanges(Stream *s) { bool ThreadPlanStepRange::InRange() { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); bool ret_value = false; - - lldb::addr_t pc_load_addr = m_thread.GetRegisterContext()->GetPC(); + Thread &thread = GetThread(); + lldb::addr_t pc_load_addr = thread.GetRegisterContext()->GetPC(); size_t num_ranges = m_address_ranges.size(); for (size_t i = 0; i < num_ranges; i++) { - ret_value = m_address_ranges[i].ContainsLoadAddress( - pc_load_addr, m_thread.CalculateTarget().get()); + ret_value = + m_address_ranges[i].ContainsLoadAddress(pc_load_addr, &GetTarget()); if (ret_value) break; } if (!ret_value && !m_given_ranges_only) { // See if we've just stepped to another part of the same line number... - StackFrame *frame = m_thread.GetStackFrameAtIndex(0).get(); + StackFrame *frame = thread.GetStackFrameAtIndex(0).get(); SymbolContext new_context( frame->GetSymbolContext(eSymbolContextEverything)); @@ -132,8 +130,8 @@ bool ThreadPlanStepRange::InRange() { ret_value = true; if (log) { StreamString s; - m_addr_context.line_entry.Dump(&s, m_thread.CalculateTarget().get(), - true, Address::DumpStyleLoadAddress, + m_addr_context.line_entry.Dump(&s, &GetTarget(), true, + Address::DumpStyleLoadAddress, Address::DumpStyleLoadAddress, true); LLDB_LOGF( @@ -151,8 +149,8 @@ bool ThreadPlanStepRange::InRange() { ret_value = true; if (log) { StreamString s; - m_addr_context.line_entry.Dump(&s, m_thread.CalculateTarget().get(), - true, Address::DumpStyleLoadAddress, + m_addr_context.line_entry.Dump(&s, &GetTarget(), true, + Address::DumpStyleLoadAddress, Address::DumpStyleLoadAddress, true); LLDB_LOGF(log, @@ -161,7 +159,7 @@ bool ThreadPlanStepRange::InRange() { s.GetData()); } } else if (new_context.line_entry.range.GetBaseAddress().GetLoadAddress( - m_thread.CalculateTarget().get()) != pc_load_addr) { + &GetTarget()) != pc_load_addr) { // Another thing that sometimes happens here is that we step out of // one line into the MIDDLE of another line. So far I mostly see // this due to bugs in the debug information. But we probably don't @@ -174,8 +172,8 @@ bool ThreadPlanStepRange::InRange() { ret_value = true; if (log) { StreamString s; - m_addr_context.line_entry.Dump(&s, m_thread.CalculateTarget().get(), - true, Address::DumpStyleLoadAddress, + m_addr_context.line_entry.Dump(&s, &GetTarget(), true, + Address::DumpStyleLoadAddress, Address::DumpStyleLoadAddress, true); LLDB_LOGF(log, @@ -195,14 +193,14 @@ bool ThreadPlanStepRange::InRange() { } bool ThreadPlanStepRange::InSymbol() { - lldb::addr_t cur_pc = m_thread.GetRegisterContext()->GetPC(); + lldb::addr_t cur_pc = GetThread().GetRegisterContext()->GetPC(); if (m_addr_context.function != nullptr) { return m_addr_context.function->GetAddressRange().ContainsLoadAddress( - cur_pc, m_thread.CalculateTarget().get()); + cur_pc, &GetTarget()); } else if (m_addr_context.symbol && m_addr_context.symbol->ValueIsAddress()) { AddressRange range(m_addr_context.symbol->GetAddressRef(), m_addr_context.symbol->GetByteSize()); - return range.ContainsLoadAddress(cur_pc, m_thread.CalculateTarget().get()); + return range.ContainsLoadAddress(cur_pc, &GetTarget()); } return false; } @@ -216,15 +214,15 @@ bool ThreadPlanStepRange::InSymbol() { lldb::FrameComparison ThreadPlanStepRange::CompareCurrentFrameToStartFrame() { FrameComparison frame_order; - - StackID cur_frame_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); + Thread &thread = GetThread(); + StackID cur_frame_id = thread.GetStackFrameAtIndex(0)->GetStackID(); if (cur_frame_id == m_stack_id) { frame_order = eFrameCompareEqual; } else if (cur_frame_id < m_stack_id) { frame_order = eFrameCompareYounger; } else { - StackFrameSP cur_parent_frame = m_thread.GetStackFrameAtIndex(1); + StackFrameSP cur_parent_frame = thread.GetStackFrameAtIndex(1); StackID cur_parent_id; if (cur_parent_frame) cur_parent_id = cur_parent_frame->GetStackID(); @@ -264,12 +262,11 @@ InstructionList *ThreadPlanStepRange::GetInstructionsForAddress( if (!m_instruction_ranges[i]) { // Disassemble the address range given: - ExecutionContext exe_ctx(m_thread.GetProcess()); const char *plugin_name = nullptr; const char *flavor = nullptr; const bool prefer_file_cache = true; m_instruction_ranges[i] = Disassembler::DisassembleRange( - GetTarget().GetArchitecture(), plugin_name, flavor, exe_ctx, + GetTarget().GetArchitecture(), plugin_name, flavor, GetTarget(), m_address_ranges[i], prefer_file_cache); } if (!m_instruction_ranges[i]) @@ -378,11 +375,10 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() { "ThreadPlanStepRange::SetNextBranchBreakpoint - Setting " "breakpoint %d (site %d) to run to address 0x%" PRIx64, m_next_branch_bp_sp->GetID(), bp_site_id, - run_to_address.GetLoadAddress( - &m_thread.GetProcess()->GetTarget())); + run_to_address.GetLoadAddress(&m_process.GetTarget())); } - m_next_branch_bp_sp->SetThreadID(m_thread.GetID()); + m_next_branch_bp_sp->SetThreadID(m_tid); m_next_branch_bp_sp->SetBreakpointKind("next-branch-location"); return true; @@ -401,7 +397,7 @@ bool ThreadPlanStepRange::NextRangeBreakpointExplainsStop( break_id_t bp_site_id = stop_info_sp->GetValue(); BreakpointSiteSP bp_site_sp = - m_thread.GetProcess()->GetBreakpointSiteList().FindByID(bp_site_id); + m_process.GetBreakpointSiteList().FindByID(bp_site_id); if (!bp_site_sp) return false; else if (!bp_site_sp->IsBreakpointAtThisSite(m_next_branch_bp_sp->GetID())) @@ -488,11 +484,11 @@ bool ThreadPlanStepRange::IsPlanStale() { // check that we are in the same symbol. if (!InRange()) { // Set plan Complete when we reach next instruction just after the range - lldb::addr_t addr = m_thread.GetRegisterContext()->GetPC() - 1; + lldb::addr_t addr = GetThread().GetRegisterContext()->GetPC() - 1; size_t num_ranges = m_address_ranges.size(); for (size_t i = 0; i < num_ranges; i++) { - bool in_range = m_address_ranges[i].ContainsLoadAddress( - addr, m_thread.CalculateTarget().get()); + bool in_range = + m_address_ranges[i].ContainsLoadAddress(addr, &GetTarget()); if (in_range) { SetPlanComplete(); } diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanStepThrough.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanStepThrough.cpp index 8c7b180fce2..06b626935ab 100644 --- a/gnu/llvm/lldb/source/Target/ThreadPlanStepThrough.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadPlanStepThrough.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlanStepThrough.cpp -------------------------------*- C++ -*-===// +//===-- ThreadPlanStepThrough.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -44,21 +44,20 @@ ThreadPlanStepThrough::ThreadPlanStepThrough(Thread &thread, // some inlined code that we're in the middle of by doing this, but it's // easier than trying to figure out where the inlined code might return to. - StackFrameSP return_frame_sp = m_thread.GetFrameWithStackID(m_stack_id); + StackFrameSP return_frame_sp = thread.GetFrameWithStackID(m_stack_id); if (return_frame_sp) { m_backstop_addr = return_frame_sp->GetFrameCodeAddress().GetLoadAddress( - m_thread.CalculateTarget().get()); + thread.CalculateTarget().get()); Breakpoint *return_bp = - m_thread.GetProcess() - ->GetTarget() + m_process.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()); + return_bp->SetThreadID(m_tid); m_backstop_bkpt_id = return_bp->GetID(); return_bp->SetBreakpointKind("step-through-backstop"); } @@ -79,18 +78,17 @@ void ThreadPlanStepThrough::DidPush() { } void ThreadPlanStepThrough::LookForPlanToStepThroughFromCurrentPC() { - DynamicLoader *loader = m_thread.GetProcess()->GetDynamicLoader(); + Thread &thread = GetThread(); + DynamicLoader *loader = thread.GetProcess()->GetDynamicLoader(); if (loader) - m_sub_plan_sp = - loader->GetStepThroughTrampolinePlan(m_thread, m_stop_others); + m_sub_plan_sp = loader->GetStepThroughTrampolinePlan(thread, m_stop_others); // If the DynamicLoader was unable to provide us with a ThreadPlan, then we // try the LanguageRuntimes. if (!m_sub_plan_sp) { - for (LanguageRuntime *runtime : - m_thread.GetProcess()->GetLanguageRuntimes()) { + for (LanguageRuntime *runtime : m_process.GetLanguageRuntimes()) { m_sub_plan_sp = - runtime->GetStepThroughTrampolinePlan(m_thread, m_stop_others); + runtime->GetStepThroughTrampolinePlan(thread, m_stop_others); if (m_sub_plan_sp) break; @@ -223,7 +221,7 @@ bool ThreadPlanStepThrough::WillStop() { return true; } void ThreadPlanStepThrough::ClearBackstopBreakpoint() { if (m_backstop_bkpt_id != LLDB_INVALID_BREAK_ID) { - m_thread.GetProcess()->GetTarget().RemoveBreakpointByID(m_backstop_bkpt_id); + m_process.GetTarget().RemoveBreakpointByID(m_backstop_bkpt_id); m_backstop_bkpt_id = LLDB_INVALID_BREAK_ID; m_could_not_resolve_hw_bp = false; } @@ -244,15 +242,15 @@ bool ThreadPlanStepThrough::MischiefManaged() { } bool ThreadPlanStepThrough::HitOurBackstopBreakpoint() { - StopInfoSP stop_info_sp(m_thread.GetStopInfo()); + Thread &thread = GetThread(); + StopInfoSP stop_info_sp(thread.GetStopInfo()); if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint) { break_id_t stop_value = (break_id_t)stop_info_sp->GetValue(); BreakpointSiteSP cur_site_sp = - m_thread.GetProcess()->GetBreakpointSiteList().FindByID(stop_value); + m_process.GetBreakpointSiteList().FindByID(stop_value); if (cur_site_sp && cur_site_sp->IsBreakpointAtThisSite(m_backstop_bkpt_id)) { - StackID cur_frame_zero_id = - m_thread.GetStackFrameAtIndex(0)->GetStackID(); + StackID cur_frame_zero_id = thread.GetStackFrameAtIndex(0)->GetStackID(); if (cur_frame_zero_id == m_return_stack_id) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanStepUntil.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanStepUntil.cpp index 54d27633748..650fa624cd5 100644 --- a/gnu/llvm/lldb/source/Target/ThreadPlanStepUntil.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadPlanStepUntil.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlanStepUntil.cpp ---------------------------------*- C++ -*-===// +//===-- ThreadPlanStepUntil.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -34,17 +34,16 @@ ThreadPlanStepUntil::ThreadPlanStepUntil(Thread &thread, m_should_stop(false), m_ran_analyze(false), m_explains_stop(false), m_until_points(), m_stop_others(stop_others) { // Stash away our "until" addresses: - TargetSP target_sp(m_thread.CalculateTarget()); + TargetSP target_sp(thread.CalculateTarget()); - StackFrameSP frame_sp(m_thread.GetStackFrameAtIndex(frame_idx)); + StackFrameSP frame_sp(thread.GetStackFrameAtIndex(frame_idx)); if (frame_sp) { m_step_from_insn = frame_sp->GetStackID().GetPC(); - lldb::user_id_t thread_id = m_thread.GetID(); // Find the return address and set a breakpoint there: // FIXME - can we do this more securely if we know first_insn? - StackFrameSP return_frame_sp(m_thread.GetStackFrameAtIndex(frame_idx + 1)); + StackFrameSP return_frame_sp(thread.GetStackFrameAtIndex(frame_idx + 1)); if (return_frame_sp) { // TODO: add inline functionality m_return_addr = return_frame_sp->GetStackID().GetPC(); @@ -54,7 +53,7 @@ ThreadPlanStepUntil::ThreadPlanStepUntil(Thread &thread, if (return_bp != nullptr) { if (return_bp->IsHardware() && !return_bp->HasResolvedLocations()) m_could_not_resolve_hw_bp = true; - return_bp->SetThreadID(thread_id); + return_bp->SetThreadID(m_tid); m_return_bp_id = return_bp->GetID(); return_bp->SetBreakpointKind("until-return-backstop"); } @@ -67,7 +66,7 @@ ThreadPlanStepUntil::ThreadPlanStepUntil(Thread &thread, Breakpoint *until_bp = target_sp->CreateBreakpoint(address_list[i], true, false).get(); if (until_bp != nullptr) { - until_bp->SetThreadID(thread_id); + until_bp->SetThreadID(m_tid); m_until_points[address_list[i]] = until_bp->GetID(); until_bp->SetBreakpointKind("until-target"); } else { @@ -80,17 +79,15 @@ ThreadPlanStepUntil::ThreadPlanStepUntil(Thread &thread, ThreadPlanStepUntil::~ThreadPlanStepUntil() { Clear(); } void ThreadPlanStepUntil::Clear() { - TargetSP target_sp(m_thread.CalculateTarget()); - if (target_sp) { - if (m_return_bp_id != LLDB_INVALID_BREAK_ID) { - target_sp->RemoveBreakpointByID(m_return_bp_id); - m_return_bp_id = LLDB_INVALID_BREAK_ID; - } + Target &target = GetTarget(); + if (m_return_bp_id != LLDB_INVALID_BREAK_ID) { + target.RemoveBreakpointByID(m_return_bp_id); + m_return_bp_id = LLDB_INVALID_BREAK_ID; + } - until_collection::iterator pos, end = m_until_points.end(); - for (pos = m_until_points.begin(); pos != end; pos++) { - target_sp->RemoveBreakpointByID((*pos).second); - } + until_collection::iterator pos, end = m_until_points.end(); + for (pos = m_until_points.begin(); pos != end; pos++) { + target.RemoveBreakpointByID((*pos).second); } m_until_points.clear(); m_could_not_resolve_hw_bp = false; @@ -158,8 +155,7 @@ void ThreadPlanStepUntil::AnalyzeStop() { // If this is OUR breakpoint, we're fine, otherwise we don't know why // this happened... BreakpointSiteSP this_site = - m_thread.GetProcess()->GetBreakpointSiteList().FindByID( - stop_info_sp->GetValue()); + m_process.GetBreakpointSiteList().FindByID(stop_info_sp->GetValue()); if (!this_site) { m_explains_stop = false; return; @@ -196,17 +192,17 @@ void ThreadPlanStepUntil::AnalyzeStop() { for (pos = m_until_points.begin(); pos != end; pos++) { if (this_site->IsBreakpointAtThisSite((*pos).second)) { // If we're at the right stack depth, then we're done. - + Thread &thread = GetThread(); bool done; StackID frame_zero_id = - m_thread.GetStackFrameAtIndex(0)->GetStackID(); + thread.GetStackFrameAtIndex(0)->GetStackID(); if (frame_zero_id == m_stack_id) done = true; else if (frame_zero_id < m_stack_id) done = false; else { - StackFrameSP older_frame_sp = m_thread.GetStackFrameAtIndex(1); + StackFrameSP older_frame_sp = thread.GetStackFrameAtIndex(1); // But if we can't even unwind one frame we should just get out // of here & stop... @@ -280,20 +276,16 @@ StateType ThreadPlanStepUntil::GetPlanRunState() { return eStateRunning; } bool ThreadPlanStepUntil::DoWillResume(StateType resume_state, bool current_plan) { if (current_plan) { - TargetSP target_sp(m_thread.CalculateTarget()); - if (target_sp) { - Breakpoint *return_bp = - target_sp->GetBreakpointByID(m_return_bp_id).get(); - if (return_bp != nullptr) - return_bp->SetEnabled(true); + Target &target = GetTarget(); + Breakpoint *return_bp = target.GetBreakpointByID(m_return_bp_id).get(); + if (return_bp != nullptr) + return_bp->SetEnabled(true); - until_collection::iterator pos, end = m_until_points.end(); - for (pos = m_until_points.begin(); pos != end; pos++) { - Breakpoint *until_bp = - target_sp->GetBreakpointByID((*pos).second).get(); - if (until_bp != nullptr) - until_bp->SetEnabled(true); - } + until_collection::iterator pos, end = m_until_points.end(); + for (pos = m_until_points.begin(); pos != end; pos++) { + Breakpoint *until_bp = target.GetBreakpointByID((*pos).second).get(); + if (until_bp != nullptr) + until_bp->SetEnabled(true); } } @@ -304,18 +296,16 @@ bool ThreadPlanStepUntil::DoWillResume(StateType resume_state, } bool ThreadPlanStepUntil::WillStop() { - TargetSP target_sp(m_thread.CalculateTarget()); - if (target_sp) { - Breakpoint *return_bp = target_sp->GetBreakpointByID(m_return_bp_id).get(); - if (return_bp != nullptr) - return_bp->SetEnabled(false); - - until_collection::iterator pos, end = m_until_points.end(); - for (pos = m_until_points.begin(); pos != end; pos++) { - Breakpoint *until_bp = target_sp->GetBreakpointByID((*pos).second).get(); - if (until_bp != nullptr) - until_bp->SetEnabled(false); - } + Target &target = GetTarget(); + Breakpoint *return_bp = target.GetBreakpointByID(m_return_bp_id).get(); + if (return_bp != nullptr) + return_bp->SetEnabled(false); + + until_collection::iterator pos, end = m_until_points.end(); + for (pos = m_until_points.begin(); pos != end; pos++) { + Breakpoint *until_bp = target.GetBreakpointByID((*pos).second).get(); + if (until_bp != nullptr) + until_bp->SetEnabled(false); } return true; } diff --git a/gnu/llvm/lldb/source/Target/ThreadPlanTracer.cpp b/gnu/llvm/lldb/source/Target/ThreadPlanTracer.cpp index b50c1636b7f..c00415f3c1e 100644 --- a/gnu/llvm/lldb/source/Target/ThreadPlanTracer.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadPlanTracer.cpp @@ -1,4 +1,4 @@ -//===-- ThreadPlanTracer.cpp ------------------------------------*- C++ -*-===// +//===-- ThreadPlanTracer.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -34,23 +34,32 @@ using namespace lldb_private; #pragma mark ThreadPlanTracer ThreadPlanTracer::ThreadPlanTracer(Thread &thread, lldb::StreamSP &stream_sp) - : m_thread(thread), m_single_step(true), m_enabled(false), - m_stream_sp(stream_sp) {} + : m_process(*thread.GetProcess().get()), m_tid(thread.GetID()), + m_single_step(true), m_enabled(false), m_stream_sp(stream_sp) {} ThreadPlanTracer::ThreadPlanTracer(Thread &thread) - : m_thread(thread), m_single_step(true), m_enabled(false), m_stream_sp() {} + : m_process(*thread.GetProcess().get()), m_tid(thread.GetID()), + m_single_step(true), m_enabled(false), m_stream_sp() {} Stream *ThreadPlanTracer::GetLogStream() { if (m_stream_sp) return m_stream_sp.get(); else { - TargetSP target_sp(m_thread.CalculateTarget()); + TargetSP target_sp(GetThread().CalculateTarget()); if (target_sp) return &(target_sp->GetDebugger().GetOutputStream()); } return nullptr; } +Thread &ThreadPlanTracer::GetThread() { + if (m_thread) + return *m_thread; + + ThreadSP thread_sp = m_process.GetThreadList().FindThreadByID(m_tid); + m_thread = thread_sp.get(); + return *m_thread; +} void ThreadPlanTracer::Log() { SymbolContext sc; bool show_frame_index = false; @@ -58,8 +67,8 @@ void ThreadPlanTracer::Log() { Stream *stream = GetLogStream(); if (stream) { - m_thread.GetStackFrameAtIndex(0)->Dump(stream, show_frame_index, - show_fullpaths); + GetThread().GetStackFrameAtIndex(0)->Dump(stream, show_frame_index, + show_fullpaths); stream->Printf("\n"); stream->Flush(); } @@ -67,7 +76,7 @@ void ThreadPlanTracer::Log() { bool ThreadPlanTracer::TracerExplainsStop() { if (m_enabled && m_single_step) { - lldb::StopInfoSP stop_info = m_thread.GetStopInfo(); + lldb::StopInfoSP stop_info = GetThread().GetStopInfo(); return (stop_info->GetStopReason() == eStopReasonTrace); } else return false; @@ -87,13 +96,13 @@ ThreadPlanAssemblyTracer::ThreadPlanAssemblyTracer(Thread &thread) Disassembler *ThreadPlanAssemblyTracer::GetDisassembler() { if (!m_disassembler_sp) m_disassembler_sp = Disassembler::FindPlugin( - m_thread.GetProcess()->GetTarget().GetArchitecture(), nullptr, nullptr); + m_process.GetTarget().GetArchitecture(), nullptr, nullptr); return m_disassembler_sp.get(); } TypeFromUser ThreadPlanAssemblyTracer::GetIntPointerType() { if (!m_intptr_type.IsValid()) { - if (auto target_sp = m_thread.CalculateTarget()) { + if (auto target_sp = m_process.CalculateTarget()) { auto type_system_or_err = target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC); if (auto err = type_system_or_err.takeError()) { @@ -125,29 +134,27 @@ void ThreadPlanAssemblyTracer::Log() { if (!stream) return; - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); + RegisterContext *reg_ctx = GetThread().GetRegisterContext().get(); lldb::addr_t pc = reg_ctx->GetPC(); - ProcessSP process_sp(m_thread.GetProcess()); Address pc_addr; bool addr_valid = false; uint8_t buffer[16] = {0}; // Must be big enough for any single instruction - addr_valid = process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress( + addr_valid = m_process.GetTarget().GetSectionLoadList().ResolveLoadAddress( pc, pc_addr); - pc_addr.Dump(stream, &m_thread, Address::DumpStyleResolvedDescription, + pc_addr.Dump(stream, &GetThread(), Address::DumpStyleResolvedDescription, Address::DumpStyleModuleWithFileAddress); stream->PutCString(" "); Disassembler *disassembler = GetDisassembler(); if (disassembler) { Status err; - process_sp->ReadMemory(pc, buffer, sizeof(buffer), err); + m_process.ReadMemory(pc, buffer, sizeof(buffer), err); if (err.Success()) { - DataExtractor extractor(buffer, sizeof(buffer), - process_sp->GetByteOrder(), - process_sp->GetAddressByteSize()); + DataExtractor extractor(buffer, sizeof(buffer), m_process.GetByteOrder(), + m_process.GetAddressByteSize()); bool data_from_file = false; if (addr_valid) @@ -167,10 +174,7 @@ void ThreadPlanAssemblyTracer::Log() { Instruction *instruction = instruction_list.GetInstructionAtIndex(0).get(); const FormatEntity::Entry *disassemble_format = - m_thread.GetProcess() - ->GetTarget() - .GetDebugger() - .GetDisassemblyFormat(); + m_process.GetTarget().GetDebugger().GetDisassemblyFormat(); instruction->Dump(stream, max_opcode_byte_size, show_address, show_bytes, nullptr, nullptr, nullptr, disassemble_format, 0); @@ -178,7 +182,7 @@ void ThreadPlanAssemblyTracer::Log() { } } - const ABI *abi = process_sp->GetABI().get(); + const ABI *abi = m_process.GetABI().get(); TypeFromUser intptr_type = GetIntPointerType(); if (abi && intptr_type.IsValid()) { @@ -192,7 +196,7 @@ void ThreadPlanAssemblyTracer::Log() { value_list.PushValue(value); } - if (abi->GetArgumentValues(m_thread, value_list)) { + if (abi->GetArgumentValues(GetThread(), value_list)) { for (int arg_index = 0; arg_index < num_args; ++arg_index) { stream->Printf( "\n\targ[%d]=%llx", arg_index, @@ -205,7 +209,7 @@ void ThreadPlanAssemblyTracer::Log() { } if (m_register_values.empty()) { - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); + RegisterContext *reg_ctx = GetThread().GetRegisterContext().get(); m_register_values.resize(reg_ctx->GetRegisterCount()); } diff --git a/gnu/llvm/lldb/source/Target/ThreadSpec.cpp b/gnu/llvm/lldb/source/Target/ThreadSpec.cpp index 1a733cb551e..1f6639379c4 100644 --- a/gnu/llvm/lldb/source/Target/ThreadSpec.cpp +++ b/gnu/llvm/lldb/source/Target/ThreadSpec.cpp @@ -1,4 +1,4 @@ -//===-- ThreadSpec.cpp ------------------------------------------*- C++ -*-===// +//===-- ThreadSpec.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/UnixSignals.cpp b/gnu/llvm/lldb/source/Target/UnixSignals.cpp index 72d9fc0a0a6..dce32adbf0a 100644 --- a/gnu/llvm/lldb/source/Target/UnixSignals.cpp +++ b/gnu/llvm/lldb/source/Target/UnixSignals.cpp @@ -1,4 +1,4 @@ -//===-- UnixSignals.cpp -----------------------------------------*- C++ -*-===// +//===-- UnixSignals.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -11,7 +11,6 @@ #include "Plugins/Process/Utility/LinuxSignals.h" #include "Plugins/Process/Utility/MipsLinuxSignals.h" #include "Plugins/Process/Utility/NetBSDSignals.h" -#include "Plugins/Process/Utility/OpenBSDSignals.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/StringConvert.h" #include "lldb/Utility/ArchSpec.h" @@ -43,9 +42,8 @@ lldb::UnixSignalsSP UnixSignals::Create(const ArchSpec &arch) { } } case llvm::Triple::FreeBSD: - return std::make_shared(); case llvm::Triple::OpenBSD: - return std::make_shared(); + return std::make_shared(); case llvm::Triple::NetBSD: return std::make_shared(); default: @@ -147,10 +145,8 @@ bool UnixSignals::SignalIsValid(int32_t signo) const { } ConstString UnixSignals::GetShortName(ConstString name) const { - if (name) { - const char *signame = name.AsCString(); - return ConstString(signame + 3); // Remove "SIG" from name - } + if (name) + return ConstString(name.GetStringRef().substr(3)); // Remove "SIG" from name return name; } diff --git a/gnu/llvm/lldb/source/Target/UnwindAssembly.cpp b/gnu/llvm/lldb/source/Target/UnwindAssembly.cpp index d3d8068687c..3a87e3da5bc 100644 --- a/gnu/llvm/lldb/source/Target/UnwindAssembly.cpp +++ b/gnu/llvm/lldb/source/Target/UnwindAssembly.cpp @@ -1,4 +1,4 @@ -//===-- UnwindAssembly.cpp --------------------------------------*- C++ -*-===// +//===-- UnwindAssembly.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Target/UnwindLLDB.cpp b/gnu/llvm/lldb/source/Target/UnwindLLDB.cpp new file mode 100644 index 00000000000..980ad4d2e34 --- /dev/null +++ b/gnu/llvm/lldb/source/Target/UnwindLLDB.cpp @@ -0,0 +1,518 @@ +//===-- UnwindLLDB.cpp ----------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/UnwindLLDB.h" +#include "lldb/Core/Module.h" +#include "lldb/Symbol/FuncUnwinders.h" +#include "lldb/Symbol/Function.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/ABI.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/RegisterContextUnwind.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/Log.h" + +using namespace lldb; +using namespace lldb_private; + +UnwindLLDB::UnwindLLDB(Thread &thread) + : Unwind(thread), m_frames(), m_unwind_complete(false), + m_user_supplied_trap_handler_functions() { + ProcessSP process_sp(thread.GetProcess()); + if (process_sp) { + Args args; + process_sp->GetTarget().GetUserSpecifiedTrapHandlerNames(args); + size_t count = args.GetArgumentCount(); + for (size_t i = 0; i < count; i++) { + const char *func_name = args.GetArgumentAtIndex(i); + m_user_supplied_trap_handler_functions.push_back(ConstString(func_name)); + } + } +} + +uint32_t UnwindLLDB::DoGetFrameCount() { + if (!m_unwind_complete) { +//#define DEBUG_FRAME_SPEED 1 +#if DEBUG_FRAME_SPEED +#define FRAME_COUNT 10000 + using namespace std::chrono; + auto time_value = steady_clock::now(); +#endif + if (!AddFirstFrame()) + return 0; + + ProcessSP process_sp(m_thread.GetProcess()); + ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; + + while (AddOneMoreFrame(abi)) { +#if DEBUG_FRAME_SPEED + if ((m_frames.size() % FRAME_COUNT) == 0) { + const auto now = steady_clock::now(); + const auto delta_t = now - time_value; + printf("%u frames in %.9f ms (%g frames/sec)\n", FRAME_COUNT, + duration(delta_t).count(), + (float)FRAME_COUNT / duration(delta_t).count()); + time_value = now; + } +#endif + } + } + return m_frames.size(); +} + +bool UnwindLLDB::AddFirstFrame() { + if (m_frames.size() > 0) + return true; + + ProcessSP process_sp(m_thread.GetProcess()); + ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; + + // First, set up the 0th (initial) frame + CursorSP first_cursor_sp(new Cursor()); + RegisterContextLLDBSP reg_ctx_sp(new RegisterContextUnwind( + m_thread, RegisterContextLLDBSP(), first_cursor_sp->sctx, 0, *this)); + if (reg_ctx_sp.get() == nullptr) + goto unwind_done; + + if (!reg_ctx_sp->IsValid()) + goto unwind_done; + + if (!reg_ctx_sp->GetCFA(first_cursor_sp->cfa)) + goto unwind_done; + + if (!reg_ctx_sp->ReadPC(first_cursor_sp->start_pc)) + goto unwind_done; + + // Everything checks out, so release the auto pointer value and let the + // cursor own it in its shared pointer + first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; + m_frames.push_back(first_cursor_sp); + + // Update the Full Unwind Plan for this frame if not valid + UpdateUnwindPlanForFirstFrameIfInvalid(abi); + + return true; + +unwind_done: + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + if (log) { + LLDB_LOGF(log, "th%d Unwind of this thread is complete.", + m_thread.GetIndexID()); + } + m_unwind_complete = true; + return false; +} + +UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { + assert(m_frames.size() != 0 && + "Get one more frame called with empty frame list"); + + // If we've already gotten to the end of the stack, don't bother to try + // again... + if (m_unwind_complete) + return nullptr; + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + + CursorSP prev_frame = m_frames.back(); + uint32_t cur_idx = m_frames.size(); + + CursorSP cursor_sp(new Cursor()); + RegisterContextLLDBSP reg_ctx_sp(new RegisterContextUnwind( + 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 + // blows out and the first 35,000 frames are uninteresting - it's the top + // most 5 frames that you actually care about. So you can't just cap the + // 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 >= max_stack_depth) { + LLDB_LOGF(log, + "%*sFrame %d unwound too many frames, assuming unwind has " + "gone astray, stopping.", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); + return nullptr; + } + + if (reg_ctx_sp.get() == nullptr) { + // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to + // that and return true. Subsequent calls to TryFallbackUnwindPlan() will + // return false. + 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 prev_frame + // still needs to be updated. Hence updating it. + if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) + return nullptr; + + return GetOneMoreFrame(abi); + } + + LLDB_LOGF(log, "%*sFrame %d did not get a RegisterContext, stopping.", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); + return nullptr; + } + + if (!reg_ctx_sp->IsValid()) { + // We failed to get a valid RegisterContext. See if the regctx below this + // on the stack has a fallback unwind plan it can use. Subsequent calls to + // TryFallbackUnwindPlan() will return false. + 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 prev_frame + // still needs to be updated. Hence updating it. + if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) + return nullptr; + + return GetOneMoreFrame(abi); + } + + LLDB_LOGF(log, + "%*sFrame %d invalid RegisterContext for this frame, " + "stopping stack walk", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); + return nullptr; + } + if (!reg_ctx_sp->GetCFA(cursor_sp->cfa)) { + // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to + // that and return true. Subsequent calls to TryFallbackUnwindPlan() will + // return false. + 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 prev_frame + // still needs to be updated. Hence updating it. + if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) + return nullptr; + + return GetOneMoreFrame(abi); + } + + LLDB_LOGF(log, + "%*sFrame %d did not get CFA for this frame, stopping stack walk", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); + return nullptr; + } + if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) { + // 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()) { + // 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() || + !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 + // prev_frame still needs to be updated. Hence updating it. + if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) + return nullptr; + + return GetOneMoreFrame(abi); + } + + LLDB_LOGF(log, + "%*sFrame %d did not get a valid CFA for this frame, " + "stopping stack walk", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); + return nullptr; + } else { + LLDB_LOGF(log, + "%*sFrame %d had a bad CFA value but we switched the " + "UnwindPlan being used and got one that looks more " + "realistic.", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); + } + } + } + if (!reg_ctx_sp->ReadPC(cursor_sp->start_pc)) { + // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to + // that and return true. Subsequent calls to TryFallbackUnwindPlan() will + // return false. + 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 prev_frame + // still needs to be updated. Hence updating it. + if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) + return nullptr; + + return GetOneMoreFrame(abi); + } + + LLDB_LOGF(log, + "%*sFrame %d did not get PC for this frame, stopping stack walk", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); + return nullptr; + } + if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc)) { + // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to + // that and return true. Subsequent calls to TryFallbackUnwindPlan() will + // return false. + 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 prev_frame + // still needs to be updated. Hence updating it. + if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa))) + return nullptr; + + return GetOneMoreFrame(abi); + } + + LLDB_LOGF(log, "%*sFrame %d did not get a valid PC, stopping stack walk", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); + return nullptr; + } + // Infinite loop where the current cursor is the same as the previous one... + if (prev_frame->start_pc == cursor_sp->start_pc && + prev_frame->cfa == cursor_sp->cfa) { + LLDB_LOGF(log, + "th%d pc of this frame is the same as the previous frame and " + "CFAs for both frames are identical -- stopping unwind", + m_thread.GetIndexID()); + return nullptr; + } + + cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; + return cursor_sp; +} + +void UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi) { + // This function is called for First Frame only. + assert(m_frames.size() == 1 && "No. of cursor frames are not 1"); + + bool old_m_unwind_complete = m_unwind_complete; + CursorSP old_m_candidate_frame = m_candidate_frame; + + // Try to unwind 2 more frames using the Unwinder. It uses Full UnwindPlan + // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also update + // the cfa of Frame 0 (if required). + AddOneMoreFrame(abi); + + // Remove all the frames added by above function as the purpose of using + // above function was just to check whether Unwinder of Frame 0 works or not. + for (uint32_t i = 1; i < m_frames.size(); i++) + m_frames.pop_back(); + + // Restore status after calling AddOneMoreFrame + m_unwind_complete = old_m_unwind_complete; + m_candidate_frame = old_m_candidate_frame; + return; +} + +bool UnwindLLDB::AddOneMoreFrame(ABI *abi) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + + // Frame zero is a little different + if (m_frames.empty()) + return false; + + // If we've already gotten to the end of the stack, don't bother to try + // again... + if (m_unwind_complete) + return false; + + CursorSP new_frame = m_candidate_frame; + if (new_frame == nullptr) + new_frame = GetOneMoreFrame(abi); + + if (new_frame == nullptr) { + LLDB_LOGF(log, "th%d Unwind of this thread is complete.", + m_thread.GetIndexID()); + m_unwind_complete = true; + return false; + } + + m_frames.push_back(new_frame); + + // If we can get one more frame further then accept that we get back a + // correct frame. + m_candidate_frame = GetOneMoreFrame(abi); + if (m_candidate_frame) + return true; + + // We can't go further from the frame returned by GetOneMore frame. Lets try + // to get a different frame with using the fallback unwind plan. + if (!m_frames[m_frames.size() - 2] + ->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { + // We don't have a valid fallback unwind plan. Accept the frame as it is. + // This is a valid situation when we are at the bottom of the stack. + return true; + } + + // Remove the possibly incorrect frame from the frame list and try to add a + // different one with the newly selected fallback unwind plan. + m_frames.pop_back(); + CursorSP new_frame_v2 = GetOneMoreFrame(abi); + if (new_frame_v2 == nullptr) { + // We haven't got a new frame from the fallback unwind plan. Accept the + // frame from the original unwind plan. This is a valid situation when we + // are at the bottom of the stack. + m_frames.push_back(new_frame); + return true; + } + + // Push the new frame to the list and try to continue from this frame. If we + // can get a new frame then accept it as the correct one. + m_frames.push_back(new_frame_v2); + m_candidate_frame = GetOneMoreFrame(abi); + if (m_candidate_frame) { + // If control reached here then TryFallbackUnwindPlan had succeeded for + // Cursor::m_frames[m_frames.size() - 2]. It also succeeded to Unwind next + // 2 frames i.e. m_frames[m_frames.size() - 1] and a frame after that. For + // 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. + 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 + // the default unwind plan is usually more reliable then the fallback one. + m_frames.pop_back(); + m_frames.push_back(new_frame); + return true; +} + +bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc, + bool &behaves_like_zeroth_frame) { + if (m_frames.size() == 0) { + if (!AddFirstFrame()) + return false; + } + + ProcessSP process_sp(m_thread.GetProcess()); + ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; + + while (idx >= m_frames.size() && AddOneMoreFrame(abi)) + ; + + if (idx < m_frames.size()) { + cfa = m_frames[idx]->cfa; + pc = m_frames[idx]->start_pc; + if (idx == 0) { + // Frame zero always behaves like it. + behaves_like_zeroth_frame = true; + } else if (m_frames[idx - 1]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) { + // This could be an asynchronous signal, thus the + // pc might point to the interrupted instruction rather + // than a post-call instruction + behaves_like_zeroth_frame = true; + } else if (m_frames[idx]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) { + // This frame may result from signal processing installing + // a pointer to the first byte of a signal-return trampoline + // in the return address slot of the frame below, so this + // too behaves like the zeroth frame (i.e. the pc might not + // be pointing just past a call in it) + behaves_like_zeroth_frame = true; + } else { + behaves_like_zeroth_frame = false; + } + return true; + } + return false; +} + +lldb::RegisterContextSP +UnwindLLDB::DoCreateRegisterContextForFrame(StackFrame *frame) { + lldb::RegisterContextSP reg_ctx_sp; + uint32_t idx = frame->GetConcreteFrameIndex(); + + if (idx == 0) { + return m_thread.GetRegisterContext(); + } + + if (m_frames.size() == 0) { + if (!AddFirstFrame()) + return reg_ctx_sp; + } + + ProcessSP process_sp(m_thread.GetProcess()); + ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; + + while (idx >= m_frames.size()) { + if (!AddOneMoreFrame(abi)) + break; + } + + const uint32_t num_frames = m_frames.size(); + if (idx < num_frames) { + Cursor *frame_cursor = m_frames[idx].get(); + reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp; + } + return reg_ctx_sp; +} + +UnwindLLDB::RegisterContextLLDBSP +UnwindLLDB::GetRegisterContextForFrameNum(uint32_t frame_num) { + RegisterContextLLDBSP reg_ctx_sp; + if (frame_num < m_frames.size()) + reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp; + return reg_ctx_sp; +} + +bool UnwindLLDB::SearchForSavedLocationForRegister( + uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, + uint32_t starting_frame_num, bool pc_reg) { + int64_t frame_num = starting_frame_num; + if (static_cast(frame_num) >= m_frames.size()) + return false; + + // Never interrogate more than one level while looking for the saved pc + // value. If the value isn't saved by frame_num, none of the frames lower on + // the stack will have a useful value. + if (pc_reg) { + UnwindLLDB::RegisterSearchResult result; + result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister( + lldb_regnum, regloc); + return result == UnwindLLDB::RegisterSearchResult::eRegisterFound; + } + while (frame_num >= 0) { + UnwindLLDB::RegisterSearchResult result; + result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister( + lldb_regnum, regloc); + + // We descended down to the live register context aka stack frame 0 and are + // reading the value out of a live register. + if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound && + regloc.type == + UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext) { + return true; + } + + // If we have unwind instructions saying that register N is saved in + // register M in the middle of the stack (and N can equal M here, meaning + // the register was not used in this function), then change the register + // number we're looking for to M and keep looking for a concrete location + // down the stack, or an actual value from a live RegisterContext at frame + // 0. + if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound && + regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister && + frame_num > 0) { + result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound; + lldb_regnum = regloc.location.register_number; + } + + if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound) + return true; + if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile) + return false; + frame_num--; + } + return false; +} diff --git a/gnu/llvm/lldb/source/Utility/ARM64_DWARF_Registers.h b/gnu/llvm/lldb/source/Utility/ARM64_DWARF_Registers.h index 64f69d64356..ed8ff722088 100644 --- a/gnu/llvm/lldb/source/Utility/ARM64_DWARF_Registers.h +++ b/gnu/llvm/lldb/source/Utility/ARM64_DWARF_Registers.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_ARM64_DWARF_Registers_h_ -#define utility_ARM64_DWARF_Registers_h_ +#ifndef LLDB_SOURCE_UTILITY_ARM64_DWARF_REGISTERS_H +#define LLDB_SOURCE_UTILITY_ARM64_DWARF_REGISTERS_H #include "lldb/lldb-private.h" @@ -51,7 +51,31 @@ enum { sp = x31, pc = 32, cpsr = 33, - // 34-63 reserved + // 34-45 reserved + + // 64-bit SVE Vector granule pseudo register + vg = 46, + + // VG ́8-bit SVE first fault register + ffr = 47, + + // VG x ́8-bit SVE predicate registers + p0 = 48, + p1, + p2, + p3, + p4, + p5, + p6, + p7, + p8, + p9, + p10, + p11, + p12, + p13, + p14, + p15, // V0-V31 (128 bit vector registers) v0 = 64, @@ -85,11 +109,43 @@ enum { v28, v29, v30, - v31 + v31, - // 96-127 reserved + // VG ́64-bit SVE vector registers + z0 = 96, + z1, + z2, + z3, + z4, + z5, + z6, + z7, + z8, + z9, + z10, + z11, + z12, + z13, + z14, + z15, + z16, + z17, + z18, + z19, + z20, + z21, + z22, + z23, + z24, + z25, + z26, + z27, + z28, + z29, + z30, + z31 }; } // namespace arm64_dwarf -#endif // utility_ARM64_DWARF_Registers_h_ +#endif // LLDB_SOURCE_UTILITY_ARM64_DWARF_REGISTERS_H diff --git a/gnu/llvm/lldb/source/Utility/ARM64_ehframe_Registers.h b/gnu/llvm/lldb/source/Utility/ARM64_ehframe_Registers.h index 9b5cd931bf2..c235891ec01 100644 --- a/gnu/llvm/lldb/source/Utility/ARM64_ehframe_Registers.h +++ b/gnu/llvm/lldb/source/Utility/ARM64_ehframe_Registers.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_ARM64_ehframe_Registers_h_ -#define utility_ARM64_ehframe_Registers_h_ +#ifndef LLDB_SOURCE_UTILITY_ARM64_EHFRAME_REGISTERS_H +#define LLDB_SOURCE_UTILITY_ARM64_EHFRAME_REGISTERS_H // The register numbers used in the eh_frame unwind information. // Should be the same as DWARF register numbers. @@ -49,10 +49,34 @@ enum { lr, // aka x30 sp, // aka x31 aka wzr pc, // value is 32 - cpsr -}; + cpsr, + // 34-45 reserved -enum { + // 64-bit SVE Vector granule pseudo register + vg = 46, + + // VG ́8-bit SVE first fault register + ffr = 47, + + // VG x ́8-bit SVE predicate registers + p0 = 48, + p1, + p2, + p3, + p4, + p5, + p6, + p7, + p8, + p9, + p10, + p11, + p12, + p13, + p14, + p15, + + // V0-V31 (128 bit vector registers) v0 = 64, v1, v2, @@ -84,8 +108,42 @@ enum { v28, v29, v30, - v31 // 95 + v31, + + // VG ́64-bit SVE vector registers + z0 = 96, + z1, + z2, + z3, + z4, + z5, + z6, + z7, + z8, + z9, + z10, + z11, + z12, + z13, + z14, + z15, + z16, + z17, + z18, + z19, + z20, + z21, + z22, + z23, + z24, + z25, + z26, + z27, + z28, + z29, + z30, + z31 }; } -#endif // utility_ARM64_ehframe_Registers_h_ +#endif // LLDB_SOURCE_UTILITY_ARM64_EHFRAME_REGISTERS_H diff --git a/gnu/llvm/lldb/source/Utility/ARM_DWARF_Registers.h b/gnu/llvm/lldb/source/Utility/ARM_DWARF_Registers.h index e33210dfbfb..8a3018b27e7 100644 --- a/gnu/llvm/lldb/source/Utility/ARM_DWARF_Registers.h +++ b/gnu/llvm/lldb/source/Utility/ARM_DWARF_Registers.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_ARM_DWARF_Registers_h_ -#define utility_ARM_DWARF_Registers_h_ +#ifndef LLDB_SOURCE_UTILITY_ARM_DWARF_REGISTERS_H +#define LLDB_SOURCE_UTILITY_ARM_DWARF_REGISTERS_H #include "lldb/lldb-private.h" @@ -204,4 +204,4 @@ enum { dwarf_q15 }; -#endif // utility_ARM_DWARF_Registers_h_ +#endif // LLDB_SOURCE_UTILITY_ARM_DWARF_REGISTERS_H diff --git a/gnu/llvm/lldb/source/Utility/ARM_ehframe_Registers.h b/gnu/llvm/lldb/source/Utility/ARM_ehframe_Registers.h index 1816b1d9749..c64e1db0c3c 100644 --- a/gnu/llvm/lldb/source/Utility/ARM_ehframe_Registers.h +++ b/gnu/llvm/lldb/source/Utility/ARM_ehframe_Registers.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_ARM_ehframe_Registers_h_ -#define utility_ARM_ehframe_Registers_h_ +#ifndef LLDB_SOURCE_UTILITY_ARM_EHFRAME_REGISTERS_H +#define LLDB_SOURCE_UTILITY_ARM_EHFRAME_REGISTERS_H // The register numbers used in the eh_frame unwind information. // Should be the same as DWARF register numbers. @@ -33,4 +33,4 @@ enum { ehframe_cpsr }; -#endif // utility_ARM_ehframe_Registers_h_ +#endif // LLDB_SOURCE_UTILITY_ARM_EHFRAME_REGISTERS_H diff --git a/gnu/llvm/lldb/source/Utility/ArchSpec.cpp b/gnu/llvm/lldb/source/Utility/ArchSpec.cpp index 8c27a002c94..ca1ce4b3d37 100644 --- a/gnu/llvm/lldb/source/Utility/ArchSpec.cpp +++ b/gnu/llvm/lldb/source/Utility/ArchSpec.cpp @@ -1,4 +1,4 @@ -//===-- ArchSpec.cpp --------------------------------------------*- C++ -*-===// +//===-- ArchSpec.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -100,9 +100,9 @@ static const CoreDefinition g_core_definitions[] = { {eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64, ArchSpec::eCore_arm_armv8, "armv8"}, {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, - ArchSpec::eCore_arm_armv8l, "armv8l"}, + ArchSpec::eCore_arm_armv8l, "armv8l"}, {eByteOrderLittle, 4, 4, 4, llvm::Triple::aarch64_32, - ArchSpec::eCore_arm_arm64_32, "arm64_32"}, + ArchSpec::eCore_arm_arm64_32, "arm64_32"}, {eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64, ArchSpec::eCore_arm_aarch64, "aarch64"}, @@ -205,8 +205,6 @@ static const CoreDefinition g_core_definitions[] = { ArchSpec::eCore_x86_64_x86_64, "x86_64"}, {eByteOrderLittle, 8, 1, 15, llvm::Triple::x86_64, ArchSpec::eCore_x86_64_x86_64h, "x86_64h"}, - {eByteOrderLittle, 8, 1, 15, llvm::Triple::x86_64, - ArchSpec::eCore_x86_64_amd64, "amd64"}, {eByteOrderLittle, 4, 4, 4, llvm::Triple::hexagon, ArchSpec::eCore_hexagon_generic, "hexagon"}, {eByteOrderLittle, 4, 4, 4, llvm::Triple::hexagon, @@ -218,7 +216,12 @@ static const CoreDefinition g_core_definitions[] = { ArchSpec::eCore_uknownMach32, "unknown-mach-32"}, {eByteOrderLittle, 8, 4, 4, llvm::Triple::UnknownArch, ArchSpec::eCore_uknownMach64, "unknown-mach-64"}, - {eByteOrderLittle, 4, 2, 4, llvm::Triple::arc, ArchSpec::eCore_arc, "arc"} + {eByteOrderLittle, 4, 2, 4, llvm::Triple::arc, ArchSpec::eCore_arc, "arc"}, + + {eByteOrderLittle, 2, 2, 4, llvm::Triple::avr, ArchSpec::eCore_avr, "avr"}, + + {eByteOrderLittle, 4, 1, 4, llvm::Triple::wasm32, ArchSpec::eCore_wasm32, + "wasm32"}, }; // Ensure that we have an entry in the g_core_definitions for each core. If you @@ -447,6 +450,8 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = { LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // HEXAGON {ArchSpec::eCore_arc, llvm::ELF::EM_ARC_COMPACT2, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARC + {ArchSpec::eCore_avr, llvm::ELF::EM_AVR, LLDB_INVALID_CPUTYPE, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // AVR }; static const ArchDefinition g_elf_arch_def = { @@ -1203,17 +1208,9 @@ static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2, case ArchSpec::eCore_x86_64_x86_64h: if (!enforce_exact_match) { - if (core2 == ArchSpec::eCore_x86_64_x86_64) - return true; try_inverse = false; - } - break; - - case ArchSpec::eCore_x86_64_amd64: - if (!enforce_exact_match) { if (core2 == ArchSpec::eCore_x86_64_x86_64) return true; - try_inverse = false; } break; @@ -1470,3 +1467,15 @@ void ArchSpec::DumpTriple(llvm::raw_ostream &s) const { if (!environ_str.empty()) s << "-" << environ_str; } + +void llvm::yaml::ScalarTraits::output(const ArchSpec &Val, void *, + raw_ostream &Out) { + Val.DumpTriple(Out); +} + +llvm::StringRef +llvm::yaml::ScalarTraits::input(llvm::StringRef Scalar, void *, + ArchSpec &Val) { + Val = ArchSpec(Scalar); + return {}; +} diff --git a/gnu/llvm/lldb/source/Utility/Args.cpp b/gnu/llvm/lldb/source/Utility/Args.cpp index 9fcc833ce43..f718c6f9ff1 100644 --- a/gnu/llvm/lldb/source/Utility/Args.cpp +++ b/gnu/llvm/lldb/source/Utility/Args.cpp @@ -1,4 +1,4 @@ -//===-- Args.cpp ------------------------------------------------*- C++ -*-===// +//===-- Args.cpp ----------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -44,7 +44,7 @@ static llvm::StringRef ParseDoubleQuotes(llvm::StringRef quoted, break; } - // If the character after the backslash is not a whitelisted escapable + // If the character after the backslash is not an allowed escapable // character, we leave the character sequence untouched. if (strchr(k_escapable_characters, quoted.front()) == nullptr) result += '\\'; @@ -111,7 +111,7 @@ ParseSingleArgument(llvm::StringRef command) { break; } - // If the character after the backslash is not a whitelisted escapable + // If the character after the backslash is not an allowed escapable // character, we leave the character sequence untouched. if (strchr(" \t\\'\"`", command.front()) == nullptr) arg += '\\'; @@ -546,7 +546,7 @@ void Args::ExpandEscapedCharacters(const char *src, std::string &dst) { dst.clear(); if (src) { for (const char *p = src; *p != '\0'; ++p) { - if (isprint(*p)) + if (llvm::isPrint(*p)) dst.append(1, *p); else { switch (*p) { @@ -635,7 +635,7 @@ void OptionsWithRaw::SetFromString(llvm::StringRef arg_string) { // If the string doesn't start with a dash, we just have no options and just // a raw part. if (!arg_string.startswith("-")) { - m_suffix = original_args; + m_suffix = std::string(original_args); return; } @@ -655,7 +655,7 @@ void OptionsWithRaw::SetFromString(llvm::StringRef arg_string) { // The remaining line is the raw suffix, and the line we parsed so far // needs to be interpreted as arguments. m_has_args = true; - m_suffix = arg_string; + m_suffix = std::string(arg_string); found_suffix = true; // The length of the prefix after parsing. @@ -681,6 +681,23 @@ void OptionsWithRaw::SetFromString(llvm::StringRef arg_string) { // If we didn't find a suffix delimiter, the whole string is the raw suffix. if (!found_suffix) { found_suffix = true; - m_suffix = original_args; + m_suffix = std::string(original_args); } } + +void llvm::yaml::MappingTraits::mapping(IO &io, + Args::ArgEntry &v) { + MappingNormalization keys(io, v); + io.mapRequired("value", keys->value); + io.mapRequired("quote", keys->quote); +} + +void llvm::yaml::MappingTraits::mapping(IO &io, Args &v) { + io.mapRequired("entries", v.m_entries); + + // Recompute m_argv vector. + v.m_argv.clear(); + for (auto &entry : v.m_entries) + v.m_argv.push_back(entry.data()); + v.m_argv.push_back(nullptr); +} diff --git a/gnu/llvm/lldb/source/Utility/Baton.cpp b/gnu/llvm/lldb/source/Utility/Baton.cpp index 7bba10dcec9..d6bc8e30858 100644 --- a/gnu/llvm/lldb/source/Utility/Baton.cpp +++ b/gnu/llvm/lldb/source/Utility/Baton.cpp @@ -1,4 +1,4 @@ -//===-- Baton.cpp -----------------------------------------------*- C++ -*-===// +//===-- Baton.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/Broadcaster.cpp b/gnu/llvm/lldb/source/Utility/Broadcaster.cpp index ee0c39f8fd4..342548c0b0e 100644 --- a/gnu/llvm/lldb/source/Utility/Broadcaster.cpp +++ b/gnu/llvm/lldb/source/Utility/Broadcaster.cpp @@ -1,4 +1,4 @@ -//===-- Broadcaster.cpp -----------------------------------------*- C++ -*-===// +//===-- Broadcaster.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -30,7 +30,7 @@ Broadcaster::Broadcaster(BroadcasterManagerSP manager_sp, const char *name) m_manager_sp(std::move(manager_sp)), m_broadcaster_name(name) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); LLDB_LOG(log, "{0} Broadcaster::Broadcaster(\"{1}\")", - static_cast(this), GetBroadcasterName().AsCString()); + static_cast(this), GetBroadcasterName()); } Broadcaster::BroadcasterImpl::BroadcasterImpl(Broadcaster &broadcaster) @@ -40,7 +40,7 @@ Broadcaster::BroadcasterImpl::BroadcasterImpl(Broadcaster &broadcaster) Broadcaster::~Broadcaster() { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); LLDB_LOG(log, "{0} Broadcaster::~Broadcaster(\"{1}\")", - static_cast(this), GetBroadcasterName().AsCString()); + static_cast(this), GetBroadcasterName()); Clear(); } @@ -373,8 +373,8 @@ bool BroadcasterManager::UnregisterListenerForEvents( if (event_bits_to_remove != iter_event_bits) { uint32_t new_event_bits = iter_event_bits & ~event_bits_to_remove; - to_be_readded.push_back( - BroadcastEventSpec(event_spec.GetBroadcasterClass(), new_event_bits)); + to_be_readded.emplace_back(event_spec.GetBroadcasterClass(), + new_event_bits); } m_event_map.erase(iter); } @@ -406,7 +406,7 @@ void BroadcasterManager::RemoveListener(Listener *listener) { listener_collection::iterator iter = m_listeners.begin(), end_iter = m_listeners.end(); - std::find_if(iter, end_iter, predicate); + iter = std::find_if(iter, end_iter, predicate); if (iter != end_iter) m_listeners.erase(iter); diff --git a/gnu/llvm/lldb/source/Utility/CMakeLists.txt b/gnu/llvm/lldb/source/Utility/CMakeLists.txt index df486e2c0a4..c89d4f9e007 100644 --- a/gnu/llvm/lldb/source/Utility/CMakeLists.txt +++ b/gnu/llvm/lldb/source/Utility/CMakeLists.txt @@ -1,6 +1,19 @@ set(LLDB_SYSTEM_LIBS) -list(APPEND LLDB_SYSTEM_LIBS ${system_libs}) +if (APPLE) + list(APPEND LLDB_SYSTEM_LIBS + ${FOUNDATION_LIBRARY} + ${CORE_FOUNDATION_LIBRARY} + ${CORE_SERVICES_LIBRARY} + ${SECURITY_LIBRARY} + ${DEBUG_SYMBOLS_LIBRARY}) +endif() + +if(NOT PURE_WINDOWS) + list(APPEND LLDB_SYSTEM_LIBS ${CMAKE_THREAD_LIBS_INIT}) +endif() + +list(APPEND LLDB_SYSTEM_LIBS ${CMAKE_DL_LIBS}) if (CMAKE_SYSTEM_NAME MATCHES "Windows") list(APPEND LLDB_SYSTEM_LIBS ws2_32 rpcrt4) @@ -39,7 +52,6 @@ add_lldb_library(lldbUtility ReproducerInstrumentation.cpp Scalar.cpp SelectHelper.cpp - SharingPtr.cpp State.cpp Status.cpp Stream.cpp @@ -58,6 +70,7 @@ add_lldb_library(lldbUtility UserIDResolver.cpp VASprintf.cpp VMRange.cpp + XcodeSDK.cpp LINK_LIBS ${LLDB_SYSTEM_LIBS} diff --git a/gnu/llvm/lldb/source/Utility/CompletionRequest.cpp b/gnu/llvm/lldb/source/Utility/CompletionRequest.cpp index 3b5a4570e32..8f9dbb79d37 100644 --- a/gnu/llvm/lldb/source/Utility/CompletionRequest.cpp +++ b/gnu/llvm/lldb/source/Utility/CompletionRequest.cpp @@ -1,4 +1,4 @@ -//===-- CompletionRequest.cpp -----------------------------------*- C++ -*-===// +//===-- CompletionRequest.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/Connection.cpp b/gnu/llvm/lldb/source/Utility/Connection.cpp index 483a0c941be..d5fcd4f3462 100644 --- a/gnu/llvm/lldb/source/Utility/Connection.cpp +++ b/gnu/llvm/lldb/source/Utility/Connection.cpp @@ -1,4 +1,4 @@ -//===-- Connection.cpp ------------------------------------------*- C++ -*-===// +//===-- Connection.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/ConstString.cpp b/gnu/llvm/lldb/source/Utility/ConstString.cpp index e90bb929bb8..62f79b3df7a 100644 --- a/gnu/llvm/lldb/source/Utility/ConstString.cpp +++ b/gnu/llvm/lldb/source/Utility/ConstString.cpp @@ -1,4 +1,4 @@ -//===-- ConstString.cpp -----------------------------------------*- C++ -*-===// +//===-- ConstString.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -29,9 +29,37 @@ using namespace lldb_private; class Pool { public: + /// The default BumpPtrAllocatorImpl slab size. + static const size_t AllocatorSlabSize = 4096; + static const size_t SizeThreshold = AllocatorSlabSize; + /// Every Pool has its own allocator which receives an equal share of + /// the ConstString allocations. This means that when allocating many + /// ConstStrings, every allocator sees only its small share of allocations and + /// assumes LLDB only allocated a small amount of memory so far. In reality + /// LLDB allocated a total memory that is N times as large as what the + /// allocator sees (where N is the number of string pools). This causes that + /// the BumpPtrAllocator continues a long time to allocate memory in small + /// chunks which only makes sense when allocating a small amount of memory + /// (which is true from the perspective of a single allocator). On some + /// systems doing all these small memory allocations causes LLDB to spend + /// a lot of time in malloc, so we need to force all these allocators to + /// behave like one allocator in terms of scaling their memory allocations + /// with increased demand. To do this we set the growth delay for each single + /// allocator to a rate so that our pool of allocators scales their memory + /// allocations similar to a single BumpPtrAllocatorImpl. + /// + /// Currently we have 256 string pools and the normal growth delay of the + /// BumpPtrAllocatorImpl is 128 (i.e., the memory allocation size increases + /// every 128 full chunks), so by changing the delay to 1 we get a + /// total growth delay in our allocator collection of 256/1 = 256. This is + /// still only half as fast as a normal allocator but we can't go any faster + /// without decreasing the number of string pools. + static const size_t AllocatorGrowthDelay = 1; + typedef llvm::BumpPtrAllocatorImpl + Allocator; typedef const char *StringPoolValueType; - typedef llvm::StringMap - StringPool; + typedef llvm::StringMap StringPool; typedef llvm::StringMapEntry StringPoolEntryType; static StringPoolEntryType & @@ -307,5 +335,17 @@ size_t ConstString::StaticMemorySize() { void llvm::format_provider::format(const ConstString &CS, llvm::raw_ostream &OS, llvm::StringRef Options) { - format_provider::format(CS.AsCString(), OS, Options); + format_provider::format(CS.GetStringRef(), OS, Options); +} + +void llvm::yaml::ScalarTraits::output(const ConstString &Val, + void *, raw_ostream &Out) { + Out << Val.GetStringRef(); +} + +llvm::StringRef +llvm::yaml::ScalarTraits::input(llvm::StringRef Scalar, void *, + ConstString &Val) { + Val = ConstString(Scalar); + return {}; } diff --git a/gnu/llvm/lldb/source/Utility/DataBufferHeap.cpp b/gnu/llvm/lldb/source/Utility/DataBufferHeap.cpp index 5bff7775f13..3aa0b6b0ac4 100644 --- a/gnu/llvm/lldb/source/Utility/DataBufferHeap.cpp +++ b/gnu/llvm/lldb/source/Utility/DataBufferHeap.cpp @@ -1,4 +1,4 @@ -//===-- DataBufferHeap.cpp --------------------------------------*- C++ -*-===// +//===-- DataBufferHeap.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/DataBufferLLVM.cpp b/gnu/llvm/lldb/source/Utility/DataBufferLLVM.cpp index c20e1b06f52..235123a31ce 100644 --- a/gnu/llvm/lldb/source/Utility/DataBufferLLVM.cpp +++ b/gnu/llvm/lldb/source/Utility/DataBufferLLVM.cpp @@ -1,4 +1,4 @@ -//===--- DataBufferLLVM.cpp -------------------------------------*- C++ -*-===// +//===-- DataBufferLLVM.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/DataEncoder.cpp b/gnu/llvm/lldb/source/Utility/DataEncoder.cpp index 8a1036e26dc..7532ac1fdca 100644 --- a/gnu/llvm/lldb/source/Utility/DataEncoder.cpp +++ b/gnu/llvm/lldb/source/Utility/DataEncoder.cpp @@ -1,4 +1,4 @@ -//===-- DataEncoder.cpp -----------------------------------------*- C++ -*-===// +//===-- DataEncoder.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/DataExtractor.cpp b/gnu/llvm/lldb/source/Utility/DataExtractor.cpp index fed2a1326b8..64b878d7dee 100644 --- a/gnu/llvm/lldb/source/Utility/DataExtractor.cpp +++ b/gnu/llvm/lldb/source/Utility/DataExtractor.cpp @@ -1,4 +1,4 @@ -//===-- DataExtractor.cpp ---------------------------------------*- C++ -*-===// +//===-- DataExtractor.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -15,7 +15,6 @@ #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/Endian.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" @@ -24,6 +23,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/LEB128.h" #include "llvm/Support/MD5.h" #include "llvm/Support/MathExtras.h" @@ -133,7 +133,7 @@ DataExtractor::DataExtractor(const void *data, offset_t length, m_end(const_cast(static_cast(data)) + length), m_byte_order(endian), m_addr_size(addr_size), m_data_sp(), m_target_byte_size(target_byte_size) { - assert(addr_size == 4 || addr_size == 8); + assert(addr_size >= 1 && addr_size <= 8); } // Make a shared pointer reference to the shared data in "data_sp" and set the @@ -146,7 +146,7 @@ DataExtractor::DataExtractor(const DataBufferSP &data_sp, ByteOrder endian, : m_start(nullptr), m_end(nullptr), m_byte_order(endian), m_addr_size(addr_size), m_data_sp(), m_target_byte_size(target_byte_size) { - assert(addr_size == 4 || addr_size == 8); + assert(addr_size >= 1 && addr_size <= 8); SetData(data_sp); } @@ -160,7 +160,7 @@ DataExtractor::DataExtractor(const DataExtractor &data, offset_t offset, : m_start(nullptr), m_end(nullptr), m_byte_order(data.m_byte_order), m_addr_size(data.m_addr_size), m_data_sp(), m_target_byte_size(target_byte_size) { - assert(m_addr_size == 4 || m_addr_size == 8); + assert(m_addr_size >= 1 && m_addr_size <= 8); if (data.ValidOffset(offset)) { offset_t bytes_available = data.GetByteSize() - offset; if (length > bytes_available) @@ -173,7 +173,7 @@ DataExtractor::DataExtractor(const DataExtractor &rhs) : m_start(rhs.m_start), m_end(rhs.m_end), m_byte_order(rhs.m_byte_order), m_addr_size(rhs.m_addr_size), m_data_sp(rhs.m_data_sp), m_target_byte_size(rhs.m_target_byte_size) { - assert(m_addr_size == 4 || m_addr_size == 8); + assert(m_addr_size >= 1 && m_addr_size <= 8); } // Assignment operator @@ -251,7 +251,7 @@ lldb::offset_t DataExtractor::SetData(const DataExtractor &data, offset_t data_offset, offset_t data_length) { m_addr_size = data.m_addr_size; - assert(m_addr_size == 4 || m_addr_size == 8); + assert(m_addr_size >= 1 && m_addr_size <= 8); // If "data" contains shared pointer to data, then we can use that if (data.m_data_sp) { m_byte_order = data.m_byte_order; @@ -604,59 +604,30 @@ uint64_t DataExtractor::GetMaxU64Bitfield(offset_t *offset_ptr, size_t size, int64_t DataExtractor::GetMaxS64Bitfield(offset_t *offset_ptr, size_t size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset) const { + assert(size >= 1 && "GetMaxS64Bitfield size must be >= 1"); + assert(size <= 8 && "GetMaxS64Bitfield size must be <= 8"); int64_t sval64 = GetMaxS64(offset_ptr, size); - if (bitfield_bit_size > 0) { - int32_t lsbcount = bitfield_bit_offset; - if (m_byte_order == eByteOrderBig) - lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size; - if (lsbcount > 0) - sval64 >>= lsbcount; - uint64_t bitfield_mask = - ((static_cast(1)) << bitfield_bit_size) - 1; - sval64 &= bitfield_mask; - // sign extend if needed - if (sval64 & ((static_cast(1)) << (bitfield_bit_size - 1))) - sval64 |= ~bitfield_mask; - } + if (bitfield_bit_size == 0) + return sval64; + int32_t lsbcount = bitfield_bit_offset; + if (m_byte_order == eByteOrderBig) + lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size; + if (lsbcount > 0) + sval64 >>= lsbcount; + uint64_t bitfield_mask = llvm::maskTrailingOnes(bitfield_bit_size); + sval64 &= bitfield_mask; + // sign extend if needed + if (sval64 & ((static_cast(1)) << (bitfield_bit_size - 1))) + sval64 |= ~bitfield_mask; return sval64; } float DataExtractor::GetFloat(offset_t *offset_ptr) const { - typedef float float_type; - float_type val = 0.0; - const size_t src_size = sizeof(float_type); - const float_type *src = - static_cast(GetData(offset_ptr, src_size)); - if (src) { - if (m_byte_order != endian::InlHostByteOrder()) { - const uint8_t *src_data = reinterpret_cast(src); - uint8_t *dst_data = reinterpret_cast(&val); - for (size_t i = 0; i < sizeof(float_type); ++i) - dst_data[sizeof(float_type) - 1 - i] = src_data[i]; - } else { - val = *src; - } - } - return val; + return Get(offset_ptr, 0.0f); } double DataExtractor::GetDouble(offset_t *offset_ptr) const { - typedef double float_type; - float_type val = 0.0; - const size_t src_size = sizeof(float_type); - const float_type *src = - static_cast(GetData(offset_ptr, src_size)); - if (src) { - if (m_byte_order != endian::InlHostByteOrder()) { - const uint8_t *src_data = reinterpret_cast(src); - uint8_t *dst_data = reinterpret_cast(&val); - for (size_t i = 0; i < sizeof(float_type); ++i) - dst_data[sizeof(float_type) - 1 - i] = src_data[i]; - } else { - val = *src; - } - } - return val; + return Get(offset_ptr, 0.0); } long double DataExtractor::GetLongDouble(offset_t *offset_ptr) const { @@ -679,26 +650,15 @@ long double DataExtractor::GetLongDouble(offset_t *offset_ptr) const { // // RETURNS the address that was extracted, or zero on failure. uint64_t DataExtractor::GetAddress(offset_t *offset_ptr) const { - assert(m_addr_size == 4 || m_addr_size == 8); + assert(m_addr_size >= 1 && m_addr_size <= 8); return GetMaxU64(offset_ptr, m_addr_size); } uint64_t DataExtractor::GetAddress_unchecked(offset_t *offset_ptr) const { - assert(m_addr_size == 4 || m_addr_size == 8); + assert(m_addr_size >= 1 && m_addr_size <= 8); return GetMaxU64_unchecked(offset_ptr, m_addr_size); } -// Extract a single pointer from the data and update the offset pointed to by -// "offset_ptr". The size of the extracted pointer comes from the -// "this->m_addr_size" member variable and should be set correctly prior to -// extracting any pointer values. -// -// RETURNS the pointer that was extracted, or zero on failure. -uint64_t DataExtractor::GetPointer(offset_t *offset_ptr) const { - assert(m_addr_size == 4 || m_addr_size == 8); - return GetMaxU64(offset_ptr, m_addr_size); -} - size_t DataExtractor::ExtractBytes(offset_t offset, offset_t length, ByteOrder dst_byte_order, void *dst) const { const uint8_t *src = PeekData(offset, length); @@ -887,26 +847,10 @@ uint64_t DataExtractor::GetULEB128(offset_t *offset_ptr) const { if (src == nullptr) return 0; - const uint8_t *end = m_end; - - if (src < end) { - uint64_t result = *src++; - if (result >= 0x80) { - result &= 0x7f; - int shift = 7; - while (src < end) { - uint8_t byte = *src++; - result |= static_cast(byte & 0x7f) << shift; - if ((byte & 0x80) == 0) - break; - shift += 7; - } - } - *offset_ptr = src - m_start; - return result; - } - - return 0; + unsigned byte_count = 0; + uint64_t result = llvm::decodeULEB128(src, &byte_count, m_end); + *offset_ptr += byte_count; + return result; } // Extracts an signed LEB128 number from this object's data starting at the @@ -920,33 +864,10 @@ int64_t DataExtractor::GetSLEB128(offset_t *offset_ptr) const { if (src == nullptr) return 0; - const uint8_t *end = m_end; - - if (src < end) { - int64_t result = 0; - int shift = 0; - int size = sizeof(int64_t) * 8; - - uint8_t byte = 0; - int bytecount = 0; - - while (src < end) { - bytecount++; - byte = *src++; - result |= static_cast(byte & 0x7f) << shift; - shift += 7; - if ((byte & 0x80) == 0) - break; - } - - // Sign bit of byte is 2nd high order bit (0x40) - if (shift < size && (byte & 0x40)) - result |= -(1 << shift); - - *offset_ptr += bytecount; - return result; - } - return 0; + unsigned byte_count = 0; + int64_t result = llvm::decodeSLEB128(src, &byte_count, m_end); + *offset_ptr += byte_count; + return result; } // Skips a ULEB128 number (signed or unsigned) from this object's data starting @@ -1012,7 +933,7 @@ lldb::offset_t DataExtractor::PutToLog(Log *log, offset_t start_offset, break; case TypeChar: { char ch = GetU8(&offset); - sstr.Printf(" %c", isprint(ch) ? ch : ' '); + sstr.Printf(" %c", llvm::isPrint(ch) ? ch : ' '); } break; case TypeUInt16: sstr.Printf(" %4.4x", GetU16(&offset)); diff --git a/gnu/llvm/lldb/source/Utility/Environment.cpp b/gnu/llvm/lldb/source/Utility/Environment.cpp index 8cafd302461..5666c2c12ff 100644 --- a/gnu/llvm/lldb/source/Utility/Environment.cpp +++ b/gnu/llvm/lldb/source/Utility/Environment.cpp @@ -1,4 +1,4 @@ -//===-- Environment.cpp -----------------------------------------*- C++ -*-===// +//===-- Environment.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/Event.cpp b/gnu/llvm/lldb/source/Utility/Event.cpp index 579d0dac86e..50cc7f061dc 100644 --- a/gnu/llvm/lldb/source/Utility/Event.cpp +++ b/gnu/llvm/lldb/source/Utility/Event.cpp @@ -1,4 +1,4 @@ -//===-- Event.cpp -----------------------------------------------*- C++ -*-===// +//===-- Event.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -125,7 +125,7 @@ ConstString EventDataBytes::GetFlavor() const { void EventDataBytes::Dump(Stream *s) const { size_t num_printable_chars = - std::count_if(m_bytes.begin(), m_bytes.end(), isprint); + std::count_if(m_bytes.begin(), m_bytes.end(), llvm::isPrint); if (num_printable_chars == m_bytes.size()) s->Format("\"{0}\"", m_bytes); else diff --git a/gnu/llvm/lldb/source/Utility/FileSpec.cpp b/gnu/llvm/lldb/source/Utility/FileSpec.cpp index 5c216d947f7..1ec5d60e278 100644 --- a/gnu/llvm/lldb/source/Utility/FileSpec.cpp +++ b/gnu/llvm/lldb/source/Utility/FileSpec.cpp @@ -1,4 +1,4 @@ -//===-- FileSpec.cpp --------------------------------------------*- C++ -*-===// +//===-- FileSpec.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -537,3 +537,19 @@ void llvm::format_provider::format(const FileSpec &F, if (!file.empty()) Stream << file; } + +void llvm::yaml::ScalarEnumerationTraits::enumeration( + IO &io, FileSpecStyle &value) { + io.enumCase(value, "windows", FileSpecStyle(FileSpec::Style::windows)); + io.enumCase(value, "posix", FileSpecStyle(FileSpec::Style::posix)); + io.enumCase(value, "native", FileSpecStyle(FileSpec::Style::native)); +} + +void llvm::yaml::MappingTraits::mapping(IO &io, FileSpec &f) { + io.mapRequired("directory", f.m_directory); + io.mapRequired("file", f.m_filename); + io.mapRequired("resolved", f.m_is_resolved); + FileSpecStyle style = f.m_style; + io.mapRequired("style", style); + f.m_style = style; +} diff --git a/gnu/llvm/lldb/source/Utility/IOObject.cpp b/gnu/llvm/lldb/source/Utility/IOObject.cpp index 5e3ccddb6a3..964edce0ce1 100644 --- a/gnu/llvm/lldb/source/Utility/IOObject.cpp +++ b/gnu/llvm/lldb/source/Utility/IOObject.cpp @@ -1,4 +1,4 @@ -//===-- IOObject.cpp --------------------------------------------*- C++ -*-===// +//===-- IOObject.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/LLDBAssert.cpp b/gnu/llvm/lldb/source/Utility/LLDBAssert.cpp index 361d6d04a28..6ae0ee50ef1 100644 --- a/gnu/llvm/lldb/source/Utility/LLDBAssert.cpp +++ b/gnu/llvm/lldb/source/Utility/LLDBAssert.cpp @@ -1,4 +1,4 @@ -//===--------------------- LLDBAssert.cpp ------------------------*- C++-*-===// +//===-- LLDBAssert.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/Listener.cpp b/gnu/llvm/lldb/source/Utility/Listener.cpp index c2e537ba7de..d2a4f329396 100644 --- a/gnu/llvm/lldb/source/Utility/Listener.cpp +++ b/gnu/llvm/lldb/source/Utility/Listener.cpp @@ -1,4 +1,4 @@ -//===-- Listener.cpp --------------------------------------------*- C++ -*-===// +//===-- Listener.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/Log.cpp b/gnu/llvm/lldb/source/Utility/Log.cpp index ab5e630114a..4df82f2bf4d 100644 --- a/gnu/llvm/lldb/source/Utility/Log.cpp +++ b/gnu/llvm/lldb/source/Utility/Log.cpp @@ -1,4 +1,4 @@ -//===-- Log.cpp -------------------------------------------------*- C++ -*-===// +//===-- Log.cpp -----------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -138,7 +138,7 @@ void Log::VAPrintf(const char *format, va_list args) { Stream << Content << "\n"; - WriteMessage(FinalMessage.str()); + WriteMessage(std::string(FinalMessage.str())); } // Printing of errors that are not fatal. diff --git a/gnu/llvm/lldb/source/Utility/Logging.cpp b/gnu/llvm/lldb/source/Utility/Logging.cpp index 22f38192fa5..435017e9d74 100644 --- a/gnu/llvm/lldb/source/Utility/Logging.cpp +++ b/gnu/llvm/lldb/source/Utility/Logging.cpp @@ -1,4 +1,4 @@ -//===-- Logging.cpp ---------------------------------------------*- C++ -*-===// +//===-- Logging.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/NameMatches.cpp b/gnu/llvm/lldb/source/Utility/NameMatches.cpp index 5c9579ea733..1c8cd6a0ca3 100644 --- a/gnu/llvm/lldb/source/Utility/NameMatches.cpp +++ b/gnu/llvm/lldb/source/Utility/NameMatches.cpp @@ -1,4 +1,4 @@ -//===-- NameMatches.cpp -----------------------------------------*- C++ -*-===// +//===-- NameMatches.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/PPC64LE_DWARF_Registers.h b/gnu/llvm/lldb/source/Utility/PPC64LE_DWARF_Registers.h index 548c1fda860..cd53e7a2abd 100644 --- a/gnu/llvm/lldb/source/Utility/PPC64LE_DWARF_Registers.h +++ b/gnu/llvm/lldb/source/Utility/PPC64LE_DWARF_Registers.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_PPC64LE_DWARF_Registers_h_ -#define utility_PPC64LE_DWARF_Registers_h_ +#ifndef LLDB_SOURCE_UTILITY_PPC64LE_DWARF_REGISTERS_H +#define LLDB_SOURCE_UTILITY_PPC64LE_DWARF_REGISTERS_H #include "lldb/lldb-private.h" @@ -190,4 +190,4 @@ enum { } // namespace ppc64le_dwarf -#endif // utility_PPC64LE_DWARF_Registers_h_ +#endif // LLDB_SOURCE_UTILITY_PPC64LE_DWARF_REGISTERS_H diff --git a/gnu/llvm/lldb/source/Utility/PPC64_DWARF_Registers.h b/gnu/llvm/lldb/source/Utility/PPC64_DWARF_Registers.h index 6ba5b6ac372..4f279be01b2 100644 --- a/gnu/llvm/lldb/source/Utility/PPC64_DWARF_Registers.h +++ b/gnu/llvm/lldb/source/Utility/PPC64_DWARF_Registers.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_PPC64_DWARF_Registers_h_ -#define utility_PPC64_DWARF_Registers_h_ +#ifndef LLDB_SOURCE_UTILITY_PPC64_DWARF_REGISTERS_H +#define LLDB_SOURCE_UTILITY_PPC64_DWARF_REGISTERS_H #include "lldb/lldb-private.h" @@ -123,4 +123,4 @@ enum { } // namespace ppc64_dwarf -#endif // utility_PPC64_DWARF_Registers_h_ +#endif // LLDB_SOURCE_UTILITY_PPC64_DWARF_REGISTERS_H diff --git a/gnu/llvm/lldb/source/Utility/ProcessInfo.cpp b/gnu/llvm/lldb/source/Utility/ProcessInfo.cpp index b159e264197..aae48d6a487 100644 --- a/gnu/llvm/lldb/source/Utility/ProcessInfo.cpp +++ b/gnu/llvm/lldb/source/Utility/ProcessInfo.cpp @@ -1,4 +1,4 @@ -//===-- ProcessInfo.cpp -----------------------------------------*- C++ -*-===// +//===-- ProcessInfo.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,6 +18,7 @@ using namespace lldb; using namespace lldb_private; +using namespace lldb_private::repro; ProcessInfo::ProcessInfo() : m_executable(), m_arguments(), m_environment(), m_uid(UINT32_MAX), @@ -75,7 +76,7 @@ void ProcessInfo::SetExecutableFile(const FileSpec &exe_file, llvm::StringRef ProcessInfo::GetArg0() const { return m_arg0; } -void ProcessInfo::SetArg0(llvm::StringRef arg) { m_arg0 = arg; } +void ProcessInfo::SetArg0(llvm::StringRef arg) { m_arg0 = std::string(arg); } void ProcessInfo::SetArguments(char const **argv, bool first_arg_is_executable) { @@ -331,3 +332,100 @@ void ProcessInstanceInfoMatch::Clear() { m_name_match_type = NameMatch::Ignore; m_match_all_users = false; } + +void llvm::yaml::MappingTraits::mapping( + IO &io, ProcessInstanceInfo &Info) { + io.mapRequired("executable", Info.m_executable); + io.mapRequired("arg0", Info.m_arg0); + io.mapRequired("args", Info.m_arguments); + io.mapRequired("arch", Info.m_arch); + io.mapRequired("uid", Info.m_uid); + io.mapRequired("gid", Info.m_gid); + io.mapRequired("pid", Info.m_pid); + io.mapRequired("effective-uid", Info.m_euid); + io.mapRequired("effective-gid", Info.m_egid); + io.mapRequired("parent-pid", Info.m_parent_pid); +} + +llvm::Expected> +ProcessInfoRecorder::Create(const FileSpec &filename) { + std::error_code ec; + auto recorder = + std::make_unique(std::move(filename), ec); + if (ec) + return llvm::errorCodeToError(ec); + return std::move(recorder); +} + +void ProcessInfoProvider::Keep() { + std::vector files; + for (auto &recorder : m_process_info_recorders) { + recorder->Stop(); + files.push_back(recorder->GetFilename().GetPath()); + } + + FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file); + std::error_code ec; + llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text); + if (ec) + return; + llvm::yaml::Output yout(os); + yout << files; +} + +void ProcessInfoProvider::Discard() { m_process_info_recorders.clear(); } + +ProcessInfoRecorder *ProcessInfoProvider::GetNewProcessInfoRecorder() { + std::size_t i = m_process_info_recorders.size() + 1; + std::string filename = (llvm::Twine(Info::name) + llvm::Twine("-") + + llvm::Twine(i) + llvm::Twine(".yaml")) + .str(); + auto recorder_or_error = ProcessInfoRecorder::Create( + GetRoot().CopyByAppendingPathComponent(filename)); + if (!recorder_or_error) { + llvm::consumeError(recorder_or_error.takeError()); + return nullptr; + } + + m_process_info_recorders.push_back(std::move(*recorder_or_error)); + return m_process_info_recorders.back().get(); +} + +void ProcessInfoRecorder::Record(const ProcessInstanceInfoList &process_infos) { + if (!m_record) + return; + llvm::yaml::Output yout(m_os); + yout << const_cast(process_infos); + m_os.flush(); +} + +llvm::Optional +repro::GetReplayProcessInstanceInfoList() { + static std::unique_ptr> + loader = repro::MultiLoader::Create( + repro::Reproducer::Instance().GetLoader()); + + if (!loader) + return {}; + + llvm::Optional nextfile = loader->GetNextFile(); + if (!nextfile) + return {}; + + auto error_or_file = llvm::MemoryBuffer::getFile(*nextfile); + if (std::error_code err = error_or_file.getError()) + return {}; + + ProcessInstanceInfoList infos; + llvm::yaml::Input yin((*error_or_file)->getBuffer()); + yin >> infos; + + if (auto err = yin.error()) + return {}; + + return infos; +} + +char ProcessInfoProvider::ID = 0; +const char *ProcessInfoProvider::Info::file = "process-info.yaml"; +const char *ProcessInfoProvider::Info::name = "process-info"; diff --git a/gnu/llvm/lldb/source/Utility/RegisterValue.cpp b/gnu/llvm/lldb/source/Utility/RegisterValue.cpp index 36790f5d8ef..7f545c214a4 100644 --- a/gnu/llvm/lldb/source/Utility/RegisterValue.cpp +++ b/gnu/llvm/lldb/source/Utility/RegisterValue.cpp @@ -1,4 +1,4 @@ -//===-- RegisterValue.cpp ---------------------------------------*- C++ -*-===// +//===-- RegisterValue.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -441,7 +441,7 @@ Status RegisterValue::SetValueFromString(const RegisterInfo *reg_info, break; case eEncodingIEEE754: { - std::string value_string = value_str; + std::string value_string = std::string(value_str); if (byte_size == sizeof(float)) { if (::sscanf(value_string.c_str(), "%f", &flt_val) != 1) { error.SetErrorStringWithFormat("'%s' is not a valid float string value", @@ -728,7 +728,8 @@ const void *RegisterValue::GetBytes() const { case eTypeFloat: case eTypeDouble: case eTypeLongDouble: - return m_scalar.GetBytes(); + m_scalar.GetBytes(buffer.bytes); + return buffer.bytes; case eTypeBytes: return buffer.bytes; } @@ -810,7 +811,7 @@ bool RegisterValue::operator==(const RegisterValue &rhs) const { if (buffer.length != rhs.buffer.length) return false; else { - uint8_t length = buffer.length; + uint16_t length = buffer.length; if (length > kMaxRegisterByteSize) length = kMaxRegisterByteSize; return memcmp(buffer.bytes, rhs.buffer.bytes, length) == 0; diff --git a/gnu/llvm/lldb/source/Utility/RegularExpression.cpp b/gnu/llvm/lldb/source/Utility/RegularExpression.cpp index fd9d963f729..20bebbfe15f 100644 --- a/gnu/llvm/lldb/source/Utility/RegularExpression.cpp +++ b/gnu/llvm/lldb/source/Utility/RegularExpression.cpp @@ -1,4 +1,4 @@ -//===-- RegularExpression.cpp -----------------------------------*- C++ -*-===// +//===-- RegularExpression.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,7 +13,7 @@ using namespace lldb_private; RegularExpression::RegularExpression(llvm::StringRef str) - : m_regex_text(str), + : m_regex_text(std::string(str)), // m_regex does not reference str anymore after it is constructed. m_regex(llvm::Regex(str)) {} @@ -35,7 +35,7 @@ llvm::StringRef RegularExpression::GetText() const { return m_regex_text; } llvm::Error RegularExpression::GetError() const { std::string error; if (!m_regex.isValid(error)) - return llvm::make_error(llvm::inconvertibleErrorCode(), - error); + return llvm::make_error(error, + llvm::inconvertibleErrorCode()); return llvm::Error::success(); } diff --git a/gnu/llvm/lldb/source/Utility/Reproducer.cpp b/gnu/llvm/lldb/source/Utility/Reproducer.cpp index b11e1a577ed..7620ab2c389 100644 --- a/gnu/llvm/lldb/source/Utility/Reproducer.cpp +++ b/gnu/llvm/lldb/source/Utility/Reproducer.cpp @@ -1,4 +1,4 @@ -//===-- Reproducer.cpp ------------------------------------------*- C++ -*-===// +//===-- Reproducer.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,6 +18,15 @@ using namespace lldb_private::repro; using namespace llvm; using namespace llvm::yaml; +static llvm::Optional GetEnv(const char *var) { + std::string val = llvm::StringRef(getenv(var)).lower(); + if (val == "0" || val == "off") + return false; + if (val == "1" || val == "on") + return true; + return {}; +} + Reproducer &Reproducer::Instance() { return *InstanceImpl(); } llvm::Error Reproducer::Initialize(ReproducerMode mode, @@ -27,12 +36,12 @@ llvm::Error Reproducer::Initialize(ReproducerMode mode, // The environment can override the capture mode. if (mode != ReproducerMode::Replay) { - std::string env = - llvm::StringRef(getenv("LLDB_CAPTURE_REPRODUCER")).lower(); - if (env == "0" || env == "off") - mode = ReproducerMode::Off; - else if (env == "1" || env == "on") - mode = ReproducerMode::Capture; + if (llvm::Optional override = GetEnv("LLDB_CAPTURE_REPRODUCER")) { + if (*override) + mode = ReproducerMode::Capture; + else + mode = ReproducerMode::Off; + } } switch (mode) { @@ -53,7 +62,9 @@ llvm::Error Reproducer::Initialize(ReproducerMode mode, return Instance().SetCapture(root); } break; case ReproducerMode::Replay: - return Instance().SetReplay(root); + return Instance().SetReplay(root, /*passive*/ false); + case ReproducerMode::PassiveReplay: + return Instance().SetReplay(root, /*passive*/ true); case ReproducerMode::Off: break; }; @@ -118,7 +129,7 @@ llvm::Error Reproducer::SetCapture(llvm::Optional root) { return Error::success(); } -llvm::Error Reproducer::SetReplay(llvm::Optional root) { +llvm::Error Reproducer::SetReplay(llvm::Optional root, bool passive) { std::lock_guard guard(m_mutex); if (root && m_generator) @@ -131,7 +142,7 @@ llvm::Error Reproducer::SetReplay(llvm::Optional root) { return Error::success(); } - m_loader.emplace(*root); + m_loader.emplace(*root, passive); if (auto e = m_loader->LoadIndex()) return e; @@ -158,8 +169,12 @@ Generator::Generator(FileSpec root) : m_root(MakeAbsolute(std::move(root))) { } Generator::~Generator() { - if (!m_done) - Discard(); + if (!m_done) { + if (m_auto_generate) + Keep(); + else + Discard(); + } } ProviderBase *Generator::Register(std::unique_ptr provider) { @@ -190,6 +205,10 @@ void Generator::Discard() { llvm::sys::fs::remove_directories(m_root.GetPath()); } +void Generator::SetAutoGenerate(bool b) { m_auto_generate = b; } + +bool Generator::IsAutoGenerate() const { return m_auto_generate; } + const FileSpec &Generator::GetRoot() const { return m_root; } void Generator::AddProvidersToIndex() { @@ -210,8 +229,9 @@ void Generator::AddProvidersToIndex() { yout << files; } -Loader::Loader(FileSpec root) - : m_root(MakeAbsolute(std::move(root))), m_loaded(false) {} +Loader::Loader(FileSpec root, bool passive) + : m_root(MakeAbsolute(std::move(root))), m_loaded(false), + m_passive_replay(passive) {} llvm::Error Loader::LoadIndex() { if (m_loaded) @@ -252,40 +272,15 @@ DataRecorder::Create(const FileSpec &filename) { return std::move(recorder); } -DataRecorder *CommandProvider::GetNewDataRecorder() { - std::size_t i = m_data_recorders.size() + 1; - std::string filename = (llvm::Twine(Info::name) + llvm::Twine("-") + - llvm::Twine(i) + llvm::Twine(".yaml")) - .str(); - auto recorder_or_error = - DataRecorder::Create(GetRoot().CopyByAppendingPathComponent(filename)); - if (!recorder_or_error) { - llvm::consumeError(recorder_or_error.takeError()); - return nullptr; - } - - m_data_recorders.push_back(std::move(*recorder_or_error)); - return m_data_recorders.back().get(); -} - -void CommandProvider::Keep() { - std::vector files; - for (auto &recorder : m_data_recorders) { - recorder->Stop(); - files.push_back(recorder->GetFilename().GetPath()); - } - - FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file); +llvm::Expected> +YamlRecorder::Create(const FileSpec &filename) { std::error_code ec; - llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text); + auto recorder = std::make_unique(std::move(filename), ec); if (ec) - return; - yaml::Output yout(os); - yout << files; + return llvm::errorCodeToError(ec); + return std::move(recorder); } -void CommandProvider::Discard() { m_data_recorders.clear(); } - void VersionProvider::Keep() { FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file); std::error_code ec; @@ -304,6 +299,11 @@ void WorkingDirectoryProvider::Keep() { os << m_cwd << "\n"; } +void FileProvider::recordInterestingDirectory(const llvm::Twine &dir) { + if (m_collector) + m_collector->addDirectory(dir); +} + void ProviderBase::anchor() {} char CommandProvider::ID = 0; char FileProvider::ID = 0; diff --git a/gnu/llvm/lldb/source/Utility/ReproducerInstrumentation.cpp b/gnu/llvm/lldb/source/Utility/ReproducerInstrumentation.cpp index 473786ef4d3..09aea69d831 100644 --- a/gnu/llvm/lldb/source/Utility/ReproducerInstrumentation.cpp +++ b/gnu/llvm/lldb/source/Utility/ReproducerInstrumentation.cpp @@ -1,4 +1,4 @@ -//===-- ReproducerInstrumentation.cpp ---------------------------*- C++ -*-===// +//===-- ReproducerInstrumentation.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,6 +8,9 @@ #include "lldb/Utility/ReproducerInstrumentation.h" #include "lldb/Utility/Reproducer.h" +#include +#include +#include using namespace lldb_private; using namespace lldb_private::repro; @@ -21,19 +24,66 @@ void IndexToObject::AddObjectForIndexImpl(unsigned idx, void *object) { m_mapping[idx] = object; } +std::vector IndexToObject::GetAllObjects() const { + std::vector> pairs; + for (auto &e : m_mapping) { + pairs.emplace_back(e.first, e.second); + } + + // Sort based on index. + std::sort(pairs.begin(), pairs.end(), + [](auto &lhs, auto &rhs) { return lhs.first < rhs.first; }); + + std::vector objects; + objects.reserve(pairs.size()); + for (auto &p : pairs) { + objects.push_back(p.second); + } + + return objects; +} + +template <> const uint8_t *Deserializer::Deserialize() { + return Deserialize(); +} + +template <> void *Deserializer::Deserialize() { + return const_cast(Deserialize()); +} + +template <> const void *Deserializer::Deserialize() { + return nullptr; +} + template <> char *Deserializer::Deserialize() { return const_cast(Deserialize()); } template <> const char *Deserializer::Deserialize() { - auto pos = m_buffer.find('\0'); - if (pos == llvm::StringRef::npos) + const size_t size = Deserialize(); + if (size == std::numeric_limits::max()) return nullptr; + assert(HasData(size + 1)); const char *str = m_buffer.data(); - m_buffer = m_buffer.drop_front(pos + 1); + m_buffer = m_buffer.drop_front(size + 1); +#ifdef LLDB_REPRO_INSTR_TRACE + llvm::errs() << "Deserializing with " << LLVM_PRETTY_FUNCTION << " -> \"" + << str << "\"\n"; +#endif return str; } +template <> const char **Deserializer::Deserialize() { + const size_t size = Deserialize(); + if (size == 0) + return nullptr; + const char **r = + reinterpret_cast(calloc(size + 1, sizeof(char *))); + for (size_t i = 0; i < size; ++i) + r[i] = Deserialize(); + return r; +} + bool Registry::Replay(const FileSpec &file) { auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath()); if (auto err = error_or_file.getError()) @@ -43,11 +93,19 @@ bool Registry::Replay(const FileSpec &file) { } bool Registry::Replay(llvm::StringRef buffer) { + Deserializer deserializer(buffer); + return Replay(deserializer); +} + +bool Registry::Replay(Deserializer &deserializer) { #ifndef LLDB_REPRO_INSTR_TRACE Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_API); #endif - Deserializer deserializer(buffer); + // Disable buffering stdout so that we approximate the way things get flushed + // during an interactive session. + setvbuf(stdout, nullptr, _IONBF, 0); + while (deserializer.HasData(1)) { unsigned id = deserializer.Deserialize(); @@ -60,6 +118,10 @@ bool Registry::Replay(llvm::StringRef buffer) { GetReplayer(id)->operator()(deserializer); } + // Add a small artificial delay to ensure that all asynchronous events have + // completed before we exit. + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + return true; } @@ -83,6 +145,22 @@ std::string Registry::GetSignature(unsigned id) { return m_ids[id].second.ToString(); } +void Registry::CheckID(unsigned expected, unsigned actual) { + if (expected != actual) { + llvm::errs() << "Reproducer expected signature " << expected << ": '" + << GetSignature(expected) << "'\n"; + llvm::errs() << "Reproducer actual signature " << actual << ": '" + << GetSignature(actual) << "'\n"; + llvm::report_fatal_error( + "Detected reproducer replay divergence. Refusing to continue."); + } + +#ifdef LLDB_REPRO_INSTR_TRACE + llvm::errs() << "Replaying " << actual << ": " << GetSignature(actual) + << "\n"; +#endif +} + Replayer *Registry::GetReplayer(unsigned id) { assert(m_ids.count(id) != 0 && "ID not in registry"); return m_ids[id].first; @@ -101,6 +179,15 @@ unsigned ObjectToIndex::GetIndexForObjectImpl(const void *object) { return m_mapping[object]; } +Recorder::Recorder() + : m_serializer(nullptr), m_pretty_func(), m_pretty_args(), + m_local_boundary(false), m_result_recorded(true) { + if (!g_global_boundary) { + g_global_boundary = true; + m_local_boundary = true; + } +} + Recorder::Recorder(llvm::StringRef pretty_func, std::string &&pretty_args) : m_serializer(nullptr), m_pretty_func(pretty_func), m_pretty_args(pretty_args), m_local_boundary(false), @@ -119,4 +206,25 @@ Recorder::~Recorder() { UpdateBoundary(); } +void InstrumentationData::Initialize(Serializer &serializer, + Registry ®istry) { + InstanceImpl().emplace(serializer, registry); +} + +void InstrumentationData::Initialize(Deserializer &deserializer, + Registry ®istry) { + InstanceImpl().emplace(deserializer, registry); +} + +InstrumentationData &InstrumentationData::Instance() { + if (!InstanceImpl()) + InstanceImpl().emplace(); + return *InstanceImpl(); +} + +llvm::Optional &InstrumentationData::InstanceImpl() { + static llvm::Optional g_instrumentation_data; + return g_instrumentation_data; +} + bool lldb_private::repro::Recorder::g_global_boundary; diff --git a/gnu/llvm/lldb/source/Utility/Scalar.cpp b/gnu/llvm/lldb/source/Utility/Scalar.cpp index a9293e87220..6c48bbde532 100644 --- a/gnu/llvm/lldb/source/Utility/Scalar.cpp +++ b/gnu/llvm/lldb/source/Utility/Scalar.cpp @@ -1,4 +1,4 @@ -//===-- Scalar.cpp ----------------------------------------------*- C++ -*-===// +//===-- Scalar.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,14 +7,14 @@ //===----------------------------------------------------------------------===// #include "lldb/Utility/Scalar.h" - +#include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" #include "lldb/lldb-types.h" - +#include "llvm/ADT/APSInt.h" #include "llvm/ADT/SmallString.h" #include @@ -23,6 +23,63 @@ using namespace lldb; using namespace lldb_private; +using llvm::APFloat; +using llvm::APInt; + +namespace { +enum class Category { Void, Integral, Float }; +} + +static Category GetCategory(Scalar::Type type) { + switch (type) { + case Scalar::e_void: + return Category::Void; + case Scalar::e_float: + case Scalar::e_double: + case Scalar::e_long_double: + return Category::Float; + case Scalar::e_sint: + case Scalar::e_slong: + case Scalar::e_slonglong: + case Scalar::e_sint128: + case Scalar::e_sint256: + case Scalar::e_sint512: + case Scalar::e_uint: + case Scalar::e_ulong: + case Scalar::e_ulonglong: + case Scalar::e_uint128: + case Scalar::e_uint256: + case Scalar::e_uint512: + return Category::Integral; + } + llvm_unreachable("Unhandled type!"); +} + +static bool IsSigned(Scalar::Type type) { + switch (type) { + case Scalar::e_void: + case Scalar::e_uint: + case Scalar::e_ulong: + case Scalar::e_ulonglong: + case Scalar::e_uint128: + case Scalar::e_uint256: + case Scalar::e_uint512: + return false; + case Scalar::e_sint: + case Scalar::e_slong: + case Scalar::e_slonglong: + case Scalar::e_sint128: + case Scalar::e_sint256: + case Scalar::e_sint512: + case Scalar::e_float: + case Scalar::e_double: + case Scalar::e_long_double: + return true; + } + llvm_unreachable("Unhandled type!"); +} + + // Promote to max type currently follows the ANSI C rule for type promotion in // expressions. static Scalar::Type PromoteToMaxType( @@ -73,112 +130,49 @@ Scalar::Scalar() : m_type(e_void), m_float(static_cast(0)) {} bool Scalar::GetData(DataExtractor &data, size_t limit_byte_size) const { size_t byte_size = GetByteSize(); - if (byte_size > 0) { - const uint8_t *bytes = static_cast(GetBytes()); - - if (limit_byte_size < byte_size) { - if (endian::InlHostByteOrder() == eByteOrderLittle) { - // On little endian systems if we want fewer bytes from the current - // type we just specify fewer bytes since the LSByte is first... - byte_size = limit_byte_size; - } else if (endian::InlHostByteOrder() == eByteOrderBig) { - // On big endian systems if we want fewer bytes from the current type - // have to advance our initial byte pointer and trim down the number of - // bytes since the MSByte is first - bytes += byte_size - limit_byte_size; - byte_size = limit_byte_size; - } + if (byte_size == 0) { + data.Clear(); + return false; + } + auto buffer_up = std::make_unique(byte_size, 0); + GetBytes(buffer_up->GetData()); + lldb::offset_t offset = 0; + + if (limit_byte_size < byte_size) { + if (endian::InlHostByteOrder() == eByteOrderLittle) { + // On little endian systems if we want fewer bytes from the current + // type we just specify fewer bytes since the LSByte is first... + byte_size = limit_byte_size; + } else if (endian::InlHostByteOrder() == eByteOrderBig) { + // On big endian systems if we want fewer bytes from the current type + // have to advance our initial byte pointer and trim down the number of + // bytes since the MSByte is first + offset = byte_size - limit_byte_size; + byte_size = limit_byte_size; } - - data.SetData(bytes, byte_size, endian::InlHostByteOrder()); - return true; } - data.Clear(); - return false; + + data.SetData(std::move(buffer_up), offset, byte_size); + data.SetByteOrder(endian::InlHostByteOrder()); + return true; } -const void *Scalar::GetBytes() const { - const uint64_t *apint_words; - const uint8_t *bytes; - static float_t flt_val; - static double_t dbl_val; - static uint64_t swapped_words[8]; - switch (m_type) { - case e_void: +void Scalar::GetBytes(llvm::MutableArrayRef storage) const { + assert(storage.size() >= GetByteSize()); + + const auto &store = [&](const llvm::APInt val) { + StoreIntToMemory(val, storage.data(), (val.getBitWidth() + 7) / 8); + }; + switch (GetCategory(m_type)) { + case Category::Void: + break; + case Category::Integral: + store(m_integer); + break; + case Category::Float: + store(m_float.bitcastToAPInt()); break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - bytes = reinterpret_cast(m_integer.getRawData()); - // getRawData always returns a pointer to an uint64_t. If we have a - // smaller type, we need to update the pointer on big-endian systems. - if (endian::InlHostByteOrder() == eByteOrderBig) { - size_t byte_size = m_integer.getBitWidth() / 8; - if (byte_size < 8) - bytes += 8 - byte_size; - } - return bytes; - // getRawData always returns a pointer to an array of uint64_t values, - // where the least-significant word always comes first. On big-endian - // systems we need to swap the words. - case e_sint128: - case e_uint128: - apint_words = m_integer.getRawData(); - if (endian::InlHostByteOrder() == eByteOrderBig) { - swapped_words[0] = apint_words[1]; - swapped_words[1] = apint_words[0]; - apint_words = swapped_words; - } - return static_cast(apint_words); - case e_sint256: - case e_uint256: - apint_words = m_integer.getRawData(); - if (endian::InlHostByteOrder() == eByteOrderBig) { - swapped_words[0] = apint_words[3]; - swapped_words[1] = apint_words[2]; - swapped_words[2] = apint_words[1]; - swapped_words[3] = apint_words[0]; - apint_words = swapped_words; - } - return static_cast(apint_words); - case e_sint512: - case e_uint512: - apint_words = m_integer.getRawData(); - if (endian::InlHostByteOrder() == eByteOrderBig) { - swapped_words[0] = apint_words[7]; - swapped_words[1] = apint_words[6]; - swapped_words[2] = apint_words[5]; - swapped_words[3] = apint_words[4]; - swapped_words[4] = apint_words[3]; - swapped_words[5] = apint_words[2]; - swapped_words[6] = apint_words[1]; - swapped_words[7] = apint_words[0]; - apint_words = swapped_words; - } - return static_cast(apint_words); - case e_float: - flt_val = m_float.convertToFloat(); - return static_cast(&flt_val); - case e_double: - dbl_val = m_float.convertToDouble(); - return static_cast(&dbl_val); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - apint_words = ldbl_val.getRawData(); - // getRawData always returns a pointer to an array of two uint64_t values, - // where the least-significant word always comes first. On big-endian - // systems we need to swap the two words. - if (endian::InlHostByteOrder() == eByteOrderBig) { - swapped_words[0] = apint_words[1]; - swapped_words[1] = apint_words[0]; - apint_words = swapped_words; - } - return static_cast(apint_words); } - return nullptr; } size_t Scalar::GetByteSize() const { @@ -209,26 +203,12 @@ size_t Scalar::GetByteSize() const { } bool Scalar::IsZero() const { - llvm::APInt zero_int = llvm::APInt::getNullValue(m_integer.getBitWidth() / 8); - switch (m_type) { - case e_void: + switch (GetCategory(m_type)) { + case Category::Void: break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_uint512: - case e_sint512: - return llvm::APInt::isSameValue(zero_int, m_integer); - case e_float: - case e_double: - case e_long_double: + case Category::Integral: + return m_integer.isNullValue(); + case Category::Float: return m_float.isZero(); } return false; @@ -238,171 +218,18 @@ void Scalar::GetValue(Stream *s, bool show_type) const { if (show_type) s->Printf("(%s) ", GetTypeAsCString()); - switch (m_type) { - case e_void: - break; - case e_sint: - case e_slong: - case e_slonglong: - case e_sint128: - case e_sint256: - case e_sint512: - s->PutCString(m_integer.toString(10, true)); + switch (GetCategory(m_type)) { + case Category::Void: break; - case e_uint: - case e_ulong: - case e_ulonglong: - case e_uint128: - case e_uint256: - case e_uint512: - s->PutCString(m_integer.toString(10, false)); + case Category::Integral: + s->PutCString(m_integer.toString(10, IsSigned(m_type))); break; - case e_float: - case e_double: - case e_long_double: + case Category::Float: llvm::SmallString<24> string; m_float.toString(string); - s->Printf("%s", string.c_str()); - break; - } -} - -const char *Scalar::GetTypeAsCString() const { - switch (m_type) { - case e_void: - return "void"; - case e_sint: - return "int"; - case e_uint: - return "unsigned int"; - case e_slong: - return "long"; - case e_ulong: - return "unsigned long"; - case e_slonglong: - return "long long"; - case e_ulonglong: - return "unsigned long long"; - case e_sint128: - return "int128_t"; - case e_uint128: - return "unsigned int128_t"; - case e_sint256: - return "int256_t"; - case e_uint256: - return "unsigned int256_t"; - case e_sint512: - return "int512_t"; - case e_uint512: - return "unsigned int512_t"; - case e_float: - return "float"; - case e_double: - return "double"; - case e_long_double: - return "long double"; - } - return ""; -} - -Scalar &Scalar::operator=(const int v) { - m_type = e_sint; - m_integer = llvm::APInt(sizeof(int) * 8, v, true); - return *this; -} - -Scalar &Scalar::operator=(unsigned int v) { - m_type = e_uint; - m_integer = llvm::APInt(sizeof(int) * 8, v); - return *this; -} - -Scalar &Scalar::operator=(long v) { - m_type = e_slong; - m_integer = llvm::APInt(sizeof(long) * 8, v, true); - return *this; -} - -Scalar &Scalar::operator=(unsigned long v) { - m_type = e_ulong; - m_integer = llvm::APInt(sizeof(long) * 8, v); - return *this; -} - -Scalar &Scalar::operator=(long long v) { - m_type = e_slonglong; - m_integer = llvm::APInt(sizeof(long) * 8, v, true); - return *this; -} - -Scalar &Scalar::operator=(unsigned long long v) { - m_type = e_ulonglong; - m_integer = llvm::APInt(sizeof(long long) * 8, v); - return *this; -} - -Scalar &Scalar::operator=(float v) { - m_type = e_float; - m_float = llvm::APFloat(v); - return *this; -} - -Scalar &Scalar::operator=(double v) { - m_type = e_double; - m_float = llvm::APFloat(v); - return *this; -} - -Scalar &Scalar::operator=(long double v) { - m_type = e_long_double; - if (m_ieee_quad) - m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), - llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, - (reinterpret_cast(&v))->x)); - else - m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), - llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, - (reinterpret_cast(&v))->x)); - return *this; -} - -Scalar &Scalar::operator=(llvm::APInt rhs) { - m_integer = llvm::APInt(rhs); - switch (m_integer.getBitWidth()) { - case 8: - case 16: - case 32: - if (m_integer.isSignedIntN(sizeof(sint_t) * 8)) - m_type = e_sint; - else - m_type = e_uint; - break; - case 64: - if (m_integer.isSignedIntN(sizeof(slonglong_t) * 8)) - m_type = e_slonglong; - else - m_type = e_ulonglong; - break; - case 128: - if (m_integer.isSignedIntN(BITWIDTH_INT128)) - m_type = e_sint128; - else - m_type = e_uint128; - break; - case 256: - if (m_integer.isSignedIntN(BITWIDTH_INT256)) - m_type = e_sint256; - else - m_type = e_uint256; - break; - case 512: - if (m_integer.isSignedIntN(BITWIDTH_INT512)) - m_type = e_sint512; - else - m_type = e_uint512; + s->PutCString(string); break; } - return *this; } Scalar::~Scalar() = default; @@ -427,1536 +254,481 @@ Scalar::Type Scalar::GetBestTypeForBitSize(size_t bit_size, bool sign) { return Scalar::e_void; } -void Scalar::TruncOrExtendTo(Scalar::Type type, uint16_t bits) { +void Scalar::TruncOrExtendTo(uint16_t bits, bool sign) { + m_integer = sign ? m_integer.sextOrTrunc(bits) : m_integer.zextOrTrunc(bits); + m_type = GetBestTypeForBitSize(bits, sign); +} + +static size_t GetBitSize(Scalar::Type type) { switch (type) { - case e_sint: - case e_slong: - case e_slonglong: - case e_sint128: - case e_sint256: - case e_sint512: - m_integer = m_integer.sextOrTrunc(bits); - break; - case e_uint: - case e_ulong: - case e_ulonglong: - case e_uint128: - case e_uint256: - case e_uint512: - m_integer = m_integer.zextOrTrunc(bits); - break; - default: - llvm_unreachable("Promoting a Scalar to a specific number of bits is only " - "supported for integer types."); + case Scalar::e_void: + return 0; + case Scalar::e_sint: + return 8 * sizeof(int); + case Scalar::e_uint: + return 8 * sizeof(unsigned int); + case Scalar::e_slong: + return 8 * sizeof(long); + case Scalar::e_ulong: + return 8 * sizeof(unsigned long); + case Scalar::e_slonglong: + return 8 * sizeof(long long); + case Scalar::e_ulonglong: + return 8 * sizeof(unsigned long long); + case Scalar::e_sint128: + case Scalar::e_uint128: + return BITWIDTH_INT128; + case Scalar::e_sint256: + case Scalar::e_uint256: + return BITWIDTH_INT256; + case Scalar::e_sint512: + case Scalar::e_uint512: + return BITWIDTH_INT512; + case Scalar::e_float: + return 8 * sizeof(float); + case Scalar::e_double: + return 8 * sizeof(double); + case Scalar::e_long_double: + return 8 * sizeof(long double); + } + llvm_unreachable("Unhandled type!"); +} + +static const llvm::fltSemantics &GetFltSemantics(Scalar::Type type) { + switch (type) { + case Scalar::e_void: + case Scalar::e_sint: + case Scalar::e_slong: + case Scalar::e_slonglong: + case Scalar::e_sint128: + case Scalar::e_sint256: + case Scalar::e_sint512: + case Scalar::e_uint: + case Scalar::e_ulong: + case Scalar::e_ulonglong: + case Scalar::e_uint128: + case Scalar::e_uint256: + case Scalar::e_uint512: + llvm_unreachable("Only floating point types supported!"); + case Scalar::e_float: + return llvm::APFloat::IEEEsingle(); + case Scalar::e_double: + return llvm::APFloat::IEEEdouble(); + case Scalar::e_long_double: + return llvm::APFloat::x87DoubleExtended(); } - m_type = type; + llvm_unreachable("Unhandled type!"); } bool Scalar::Promote(Scalar::Type type) { bool success = false; - switch (m_type) { - case e_void: + switch (GetCategory(m_type)) { + case Category::Void: break; - - case e_sint: - switch (type) { - case e_void: + case Category::Integral: + switch (GetCategory(type)) { + case Category::Void: break; - case e_sint: + case Category::Integral: + if (type < m_type) + break; success = true; + if (IsSigned(m_type)) + m_integer = m_integer.sextOrTrunc(GetBitSize(type)); + else + m_integer = m_integer.zextOrTrunc(GetBitSize(type)); break; - case e_uint: - m_integer = m_integer.sextOrTrunc(sizeof(uint_t) * 8); + case Category::Float: + m_float = llvm::APFloat(GetFltSemantics(type)); + m_float.convertFromAPInt(m_integer, IsSigned(m_type), + llvm::APFloat::rmNearestTiesToEven); success = true; break; - - case e_slong: - m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8); - success = true; + } + break; + case Category::Float: + switch (GetCategory(type)) { + case Category::Void: + case Category::Integral: break; - - case e_ulong: - m_integer = m_integer.sextOrTrunc(sizeof(ulong_t) * 8); - success = true; - break; - - case e_slonglong: - m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8); - success = true; - break; - - case e_ulonglong: - m_integer = m_integer.sextOrTrunc(sizeof(ulonglong_t) * 8); - success = true; - break; - - case e_sint128: - case e_uint128: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128); - success = true; - break; - - case e_sint256: - case e_uint256: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } - break; - - case e_uint: - switch (type) { - case e_void: - case e_sint: - break; - case e_uint: - success = true; - break; - case e_slong: - m_integer = m_integer.zextOrTrunc(sizeof(slong_t) * 8); - success = true; - break; - - case e_ulong: - m_integer = m_integer.zextOrTrunc(sizeof(ulong_t) * 8); - success = true; - break; - - case e_slonglong: - m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8); - success = true; - break; - - case e_ulonglong: - m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8); - success = true; - break; - - case e_sint128: - case e_uint128: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128); - success = true; - break; - - case e_sint256: - case e_uint256: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } - break; - - case e_slong: - switch (type) { - case e_void: - case e_sint: - case e_uint: - break; - case e_slong: - success = true; - break; - case e_ulong: - m_integer = m_integer.sextOrTrunc(sizeof(ulong_t) * 8); - success = true; - break; - - case e_slonglong: - m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8); - success = true; - break; - - case e_ulonglong: - m_integer = m_integer.sextOrTrunc(sizeof(ulonglong_t) * 8); - success = true; - break; - - case e_sint128: - case e_uint128: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128); - success = true; - break; - - case e_sint256: - case e_uint256: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } - break; - - case e_ulong: - switch (type) { - case e_void: - case e_sint: - case e_uint: - case e_slong: - break; - case e_ulong: - success = true; - break; - case e_slonglong: - m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8); - success = true; - break; - - case e_ulonglong: - m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8); - success = true; - break; - - case e_sint128: - case e_uint128: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128); - success = true; - break; - - case e_sint256: - case e_uint256: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } - break; - - case e_slonglong: - switch (type) { - case e_void: - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - break; - case e_slonglong: - success = true; - break; - case e_ulonglong: - m_integer = m_integer.sextOrTrunc(sizeof(ulonglong_t) * 8); - success = true; - break; - - case e_sint128: - case e_uint128: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128); - success = true; - break; - - case e_sint256: - case e_uint256: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } - break; - - case e_ulonglong: - switch (type) { - case e_void: - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - break; - case e_ulonglong: - success = true; - break; - case e_sint128: - case e_uint128: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128); - success = true; - break; - - case e_sint256: - case e_uint256: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } - break; - - case e_sint128: - switch (type) { - case e_void: - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - break; - case e_sint128: - success = true; - break; - case e_uint128: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128); - success = true; - break; - - case e_sint256: - case e_uint256: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } - break; - - case e_uint128: - switch (type) { - case e_void: - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - break; - case e_uint128: - success = true; - break; - case e_sint256: - case e_uint256: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } - break; - - case e_sint256: - switch (type) { - case e_void: - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - break; - case e_sint256: - success = true; - break; - case e_uint256: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } - break; - - case e_uint256: - switch (type) { - case e_void: - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - break; - case e_uint256: - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } - break; - - case e_sint512: - case e_uint512: - lldbassert(false && "unimplemented"); - break; - - case e_float: - switch (type) { - case e_void: - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_uint512: - case e_sint512: - break; - case e_float: - success = true; - break; - case e_double: - m_float = llvm::APFloat(static_cast(m_float.convertToFloat())); - success = true; - break; - - case e_long_double: { - bool ignore; - m_float.convert(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended(), - llvm::APFloat::rmNearestTiesToEven, &ignore); - success = true; - break; - } - } - break; - - case e_double: - switch (type) { - case e_void: - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - case e_float: - break; - case e_double: - success = true; - break; - case e_long_double: { - bool ignore; - m_float.convert(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended(), - llvm::APFloat::rmNearestTiesToEven, &ignore); - success = true; - break; - } - } - break; - - case e_long_double: - switch (type) { - case e_void: - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - case e_float: - case e_double: - break; - case e_long_double: - success = true; - break; - } - break; - } - - if (success) - m_type = type; - return success; -} - -const char *Scalar::GetValueTypeAsCString(Scalar::Type type) { - switch (type) { - case e_void: - return "void"; - case e_sint: - return "int"; - case e_uint: - return "unsigned int"; - case e_slong: - return "long"; - case e_ulong: - return "unsigned long"; - case e_slonglong: - return "long long"; - case e_ulonglong: - return "unsigned long long"; - case e_float: - return "float"; - case e_double: - return "double"; - case e_long_double: - return "long double"; - case e_sint128: - return "int128_t"; - case e_uint128: - return "uint128_t"; - case e_sint256: - return "int256_t"; - case e_uint256: - return "uint256_t"; - case e_sint512: - return "int512_t"; - case e_uint512: - return "uint512_t"; - } - return "???"; -} - -Scalar::Type -Scalar::GetValueTypeForSignedIntegerWithByteSize(size_t byte_size) { - if (byte_size <= sizeof(sint_t)) - return e_sint; - if (byte_size <= sizeof(slong_t)) - return e_slong; - if (byte_size <= sizeof(slonglong_t)) - return e_slonglong; - return e_void; -} - -Scalar::Type -Scalar::GetValueTypeForUnsignedIntegerWithByteSize(size_t byte_size) { - if (byte_size <= sizeof(uint_t)) - return e_uint; - if (byte_size <= sizeof(ulong_t)) - return e_ulong; - if (byte_size <= sizeof(ulonglong_t)) - return e_ulonglong; - return e_void; -} - -Scalar::Type Scalar::GetValueTypeForFloatWithByteSize(size_t byte_size) { - if (byte_size == sizeof(float_t)) - return e_float; - if (byte_size == sizeof(double_t)) - return e_double; - if (byte_size == sizeof(long_double_t)) - return e_long_double; - return e_void; -} - -bool Scalar::MakeSigned() { - bool success = false; - - switch (m_type) { - case e_void: - break; - case e_sint: - success = true; - break; - case e_uint: - m_type = e_sint; - success = true; - break; - case e_slong: - success = true; - break; - case e_ulong: - m_type = e_slong; - success = true; - break; - case e_slonglong: - success = true; - break; - case e_ulonglong: - m_type = e_slonglong; - success = true; - break; - case e_sint128: - success = true; - break; - case e_uint128: - m_type = e_sint128; - success = true; - break; - case e_sint256: - success = true; - break; - case e_uint256: - m_type = e_sint256; - success = true; - break; - case e_sint512: - success = true; - break; - case e_uint512: - m_type = e_sint512; - success = true; - break; - case e_float: - success = true; - break; - case e_double: - success = true; - break; - case e_long_double: - success = true; - break; - } - - return success; -} - -bool Scalar::MakeUnsigned() { - bool success = false; - - switch (m_type) { - case e_void: - break; - case e_sint: - m_type = e_uint; - success = true; - break; - case e_uint: - success = true; - break; - case e_slong: - m_type = e_ulong; - success = true; - break; - case e_ulong: - success = true; - break; - case e_slonglong: - m_type = e_ulonglong; - success = true; - break; - case e_ulonglong: - success = true; - break; - case e_sint128: - m_type = e_uint128; - success = true; - break; - case e_uint128: - success = true; - break; - case e_sint256: - m_type = e_uint256; - success = true; - break; - case e_uint256: - success = true; - break; - case e_sint512: - m_type = e_uint512; - success = true; - break; - case e_uint512: - success = true; - break; - case e_float: - success = true; - break; - case e_double: - success = true; - break; - case e_long_double: - success = true; - break; - } - - return success; -} - -signed char Scalar::SChar(char fail_value) const { - switch (m_type) { - case e_void: - break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - return static_cast( - (m_integer.sextOrTrunc(sizeof(schar_t) * 8)).getSExtValue()); - case e_float: - return static_cast(m_float.convertToFloat()); - case e_double: - return static_cast(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast( - (ldbl_val.sextOrTrunc(sizeof(schar_t) * 8)).getSExtValue()); - } - return fail_value; -} - -unsigned char Scalar::UChar(unsigned char fail_value) const { - switch (m_type) { - case e_void: - break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - return static_cast( - (m_integer.zextOrTrunc(sizeof(uchar_t) * 8)).getZExtValue()); - case e_float: - return static_cast(m_float.convertToFloat()); - case e_double: - return static_cast(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast( - (ldbl_val.zextOrTrunc(sizeof(uchar_t) * 8)).getZExtValue()); - } - return fail_value; -} - -short Scalar::SShort(short fail_value) const { - switch (m_type) { - case e_void: - break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - return static_cast( - (m_integer.sextOrTrunc(sizeof(sshort_t) * 8)).getSExtValue()); - case e_float: - return static_cast(m_float.convertToFloat()); - case e_double: - return static_cast(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast( - (ldbl_val.sextOrTrunc(sizeof(sshort_t) * 8)).getSExtValue()); - } - return fail_value; -} - -unsigned short Scalar::UShort(unsigned short fail_value) const { - switch (m_type) { - case e_void: - break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - return static_cast( - (m_integer.zextOrTrunc(sizeof(ushort_t) * 8)).getZExtValue()); - case e_float: - return static_cast(m_float.convertToFloat()); - case e_double: - return static_cast(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast( - (ldbl_val.zextOrTrunc(sizeof(ushort_t) * 8)).getZExtValue()); - } - return fail_value; -} - -int Scalar::SInt(int fail_value) const { - switch (m_type) { - case e_void: - break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - return static_cast( - (m_integer.sextOrTrunc(sizeof(sint_t) * 8)).getSExtValue()); - case e_float: - return static_cast(m_float.convertToFloat()); - case e_double: - return static_cast(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast( - (ldbl_val.sextOrTrunc(sizeof(sint_t) * 8)).getSExtValue()); + case Category::Float: + if (type < m_type) + break; + bool ignore; + success = true; + m_float.convert(GetFltSemantics(type), llvm::APFloat::rmNearestTiesToEven, + &ignore); + } } - return fail_value; -} -unsigned int Scalar::UInt(unsigned int fail_value) const { - switch (m_type) { - case e_void: - break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - return static_cast( - (m_integer.zextOrTrunc(sizeof(uint_t) * 8)).getZExtValue()); - case e_float: - return static_cast(m_float.convertToFloat()); - case e_double: - return static_cast(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast( - (ldbl_val.zextOrTrunc(sizeof(uint_t) * 8)).getZExtValue()); - } - return fail_value; + if (success) + m_type = type; + return success; } -long Scalar::SLong(long fail_value) const { - switch (m_type) { +const char *Scalar::GetValueTypeAsCString(Scalar::Type type) { + switch (type) { case e_void: - break; + return "void"; case e_sint: + return "int"; case e_uint: + return "unsigned int"; case e_slong: + return "long"; case e_ulong: + return "unsigned long"; case e_slonglong: + return "long long"; case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - return static_cast( - (m_integer.sextOrTrunc(sizeof(slong_t) * 8)).getSExtValue()); + return "unsigned long long"; case e_float: - return static_cast(m_float.convertToFloat()); + return "float"; case e_double: - return static_cast(m_float.convertToDouble()); + return "double"; case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast( - (ldbl_val.sextOrTrunc(sizeof(slong_t) * 8)).getSExtValue()); - } - return fail_value; -} - -unsigned long Scalar::ULong(unsigned long fail_value) const { - switch (m_type) { - case e_void: - break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: + return "long double"; case e_sint128: + return "int128_t"; case e_uint128: + return "uint128_t"; case e_sint256: + return "int256_t"; case e_uint256: + return "uint256_t"; case e_sint512: + return "int512_t"; case e_uint512: - return static_cast( - (m_integer.zextOrTrunc(sizeof(ulong_t) * 8)).getZExtValue()); - case e_float: - return static_cast(m_float.convertToFloat()); - case e_double: - return static_cast(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast( - (ldbl_val.zextOrTrunc(sizeof(ulong_t) * 8)).getZExtValue()); + return "uint512_t"; } - return fail_value; + return "???"; } -long long Scalar::SLongLong(long long fail_value) const { - switch (m_type) { - case e_void: - break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - return static_cast( - (m_integer.sextOrTrunc(sizeof(slonglong_t) * 8)).getSExtValue()); - case e_float: - return static_cast(m_float.convertToFloat()); - case e_double: - return static_cast(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast( - (ldbl_val.sextOrTrunc(sizeof(slonglong_t) * 8)).getSExtValue()); - } - return fail_value; +Scalar::Type +Scalar::GetValueTypeForSignedIntegerWithByteSize(size_t byte_size) { + if (byte_size <= sizeof(sint_t)) + return e_sint; + if (byte_size <= sizeof(slong_t)) + return e_slong; + if (byte_size <= sizeof(slonglong_t)) + return e_slonglong; + return e_void; } -unsigned long long Scalar::ULongLong(unsigned long long fail_value) const { - switch (m_type) { - case e_void: - break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - return static_cast( - (m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8)).getZExtValue()); - case e_float: - return static_cast(m_float.convertToFloat()); - case e_double: { - double d_val = m_float.convertToDouble(); - llvm::APInt rounded_double = - llvm::APIntOps::RoundDoubleToAPInt(d_val, sizeof(ulonglong_t) * 8); - return static_cast( - (rounded_double.zextOrTrunc(sizeof(ulonglong_t) * 8)).getZExtValue()); - } - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast( - (ldbl_val.zextOrTrunc(sizeof(ulonglong_t) * 8)).getZExtValue()); - } - return fail_value; +Scalar::Type +Scalar::GetValueTypeForUnsignedIntegerWithByteSize(size_t byte_size) { + if (byte_size <= sizeof(uint_t)) + return e_uint; + if (byte_size <= sizeof(ulong_t)) + return e_ulong; + if (byte_size <= sizeof(ulonglong_t)) + return e_ulonglong; + return e_void; } -llvm::APInt Scalar::SInt128(llvm::APInt &fail_value) const { - switch (m_type) { - case e_void: - break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - return m_integer; - case e_float: - case e_double: - case e_long_double: - return m_float.bitcastToAPInt(); - } - return fail_value; +Scalar::Type Scalar::GetValueTypeForFloatWithByteSize(size_t byte_size) { + if (byte_size == sizeof(float_t)) + return e_float; + if (byte_size == sizeof(double_t)) + return e_double; + if (byte_size == sizeof(long_double_t)) + return e_long_double; + return e_void; } -llvm::APInt Scalar::UInt128(const llvm::APInt &fail_value) const { - switch (m_type) { - case e_void: - break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - return m_integer; - case e_float: - case e_double: - case e_long_double: - return m_float.bitcastToAPInt(); - } - return fail_value; -} +bool Scalar::MakeSigned() { + bool success = false; -float Scalar::Float(float fail_value) const { switch (m_type) { case e_void: break; case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - return llvm::APIntOps::RoundAPIntToFloat(m_integer); - case e_float: - return m_float.convertToFloat(); - case e_double: - return static_cast(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return ldbl_val.bitsToFloat(); - } - return fail_value; -} - -double Scalar::Double(double fail_value) const { - switch (m_type) { - case e_void: + success = true; break; - case e_sint: case e_uint: + m_type = e_sint; + success = true; + break; case e_slong: + success = true; + break; case e_ulong: + m_type = e_slong; + success = true; + break; case e_slonglong: + success = true; + break; case e_ulonglong: + m_type = e_slonglong; + success = true; + break; case e_sint128: + success = true; + break; case e_uint128: + m_type = e_sint128; + success = true; + break; case e_sint256: + success = true; + break; case e_uint256: + m_type = e_sint256; + success = true; + break; case e_sint512: + success = true; + break; case e_uint512: - return llvm::APIntOps::RoundAPIntToDouble(m_integer); + m_type = e_sint512; + success = true; + break; case e_float: - return static_cast(m_float.convertToFloat()); + success = true; + break; case e_double: - return m_float.convertToDouble(); + success = true; + break; case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return ldbl_val.bitsToFloat(); + success = true; + break; } - return fail_value; + + return success; } -long double Scalar::LongDouble(long double fail_value) const { +bool Scalar::MakeUnsigned() { + bool success = false; + switch (m_type) { case e_void: break; case e_sint: + m_type = e_uint; + success = true; + break; case e_uint: + success = true; + break; case e_slong: + m_type = e_ulong; + success = true; + break; case e_ulong: + success = true; + break; case e_slonglong: + m_type = e_ulonglong; + success = true; + break; case e_ulonglong: + success = true; + break; case e_sint128: + m_type = e_uint128; + success = true; + break; case e_uint128: + success = true; + break; case e_sint256: + m_type = e_uint256; + success = true; + break; case e_uint256: + success = true; + break; case e_sint512: + m_type = e_uint512; + success = true; + break; case e_uint512: - return static_cast( - llvm::APIntOps::RoundAPIntToDouble(m_integer)); + success = true; + break; case e_float: - return static_cast(m_float.convertToFloat()); + success = true; + break; case e_double: - return static_cast(m_float.convertToDouble()); + success = true; + break; case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast(ldbl_val.bitsToDouble()); + success = true; + break; } - return fail_value; + + return success; } -Scalar &Scalar::operator+=(const Scalar &rhs) { - Scalar temp_value; - const Scalar *a; - const Scalar *b; - if ((m_type = PromoteToMaxType(*this, rhs, temp_value, a, b)) != - Scalar::e_void) { - switch (m_type) { - case e_void: - break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - m_integer = a->m_integer + b->m_integer; - break; +static llvm::APInt ToAPInt(const llvm::APFloat &f, unsigned bits, + bool is_unsigned) { + llvm::APSInt result(bits, is_unsigned); + bool isExact; + f.convertToInteger(result, llvm::APFloat::rmTowardZero, &isExact); + return std::move(result); +} - case e_float: - case e_double: - case e_long_double: - m_float = a->m_float + b->m_float; - break; - } +template T Scalar::GetAs(T fail_value) const { + switch (GetCategory(m_type)) { + case Category::Void: + break; + case Category::Integral: + if (IsSigned(m_type)) + return m_integer.sextOrTrunc(sizeof(T) * 8).getSExtValue(); + return m_integer.zextOrTrunc(sizeof(T) * 8).getZExtValue(); + case Category::Float: + return ToAPInt(m_float, sizeof(T) * 8, std::is_unsigned::value) + .getSExtValue(); } - return *this; + return fail_value; } -Scalar &Scalar::operator<<=(const Scalar &rhs) { - switch (m_type) { - case e_void: - case e_float: - case e_double: - case e_long_double: - m_type = e_void; - break; +signed char Scalar::SChar(signed char fail_value) const { + return GetAs(fail_value); +} - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - switch (rhs.m_type) { - case e_void: - case e_float: - case e_double: - case e_long_double: - m_type = e_void; - break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - m_integer = m_integer << rhs.m_integer; - break; - } +unsigned char Scalar::UChar(unsigned char fail_value) const { + return GetAs(fail_value); +} + +short Scalar::SShort(short fail_value) const { + return GetAs(fail_value); +} + +unsigned short Scalar::UShort(unsigned short fail_value) const { + return GetAs(fail_value); +} + +int Scalar::SInt(int fail_value) const { return GetAs(fail_value); } + +unsigned int Scalar::UInt(unsigned int fail_value) const { + return GetAs(fail_value); +} + +long Scalar::SLong(long fail_value) const { return GetAs(fail_value); } + +unsigned long Scalar::ULong(unsigned long fail_value) const { + return GetAs(fail_value); +} + +long long Scalar::SLongLong(long long fail_value) const { + return GetAs(fail_value); +} + +unsigned long long Scalar::ULongLong(unsigned long long fail_value) const { + return GetAs(fail_value); +} + +llvm::APInt Scalar::SInt128(const llvm::APInt &fail_value) const { + switch (GetCategory(m_type)) { + case Category::Void: break; + case Category::Integral: + return m_integer; + case Category::Float: + return ToAPInt(m_float, 128, /*is_unsigned=*/false); } - return *this; + return fail_value; } -bool Scalar::ShiftRightLogical(const Scalar &rhs) { - switch (m_type) { - case e_void: - case e_float: - case e_double: - case e_long_double: - m_type = e_void; +llvm::APInt Scalar::UInt128(const llvm::APInt &fail_value) const { + switch (GetCategory(m_type)) { + case Category::Void: break; + case Category::Integral: + return m_integer; + case Category::Float: + return ToAPInt(m_float, 128, /*is_unsigned=*/true); + } + return fail_value; +} - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - switch (rhs.m_type) { - case e_void: - case e_float: - case e_double: - case e_long_double: - m_type = e_void; - break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - m_integer = m_integer.lshr(rhs.m_integer); - break; - } +float Scalar::Float(float fail_value) const { + switch (GetCategory(m_type)) { + case Category::Void: break; + case Category::Integral: + if (IsSigned(m_type)) + return llvm::APIntOps::RoundSignedAPIntToFloat(m_integer); + return llvm::APIntOps::RoundAPIntToFloat(m_integer); + + case Category::Float: { + APFloat result = m_float; + bool losesInfo; + result.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, + &losesInfo); + return result.convertToFloat(); } - return m_type != e_void; + } + return fail_value; } -Scalar &Scalar::operator>>=(const Scalar &rhs) { - switch (m_type) { - case e_void: - case e_float: - case e_double: - case e_long_double: - m_type = e_void; +double Scalar::Double(double fail_value) const { + switch (GetCategory(m_type)) { + case Category::Void: break; + case Category::Integral: + if (IsSigned(m_type)) + return llvm::APIntOps::RoundSignedAPIntToDouble(m_integer); + return llvm::APIntOps::RoundAPIntToDouble(m_integer); - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - switch (rhs.m_type) { - case e_void: - case e_float: - case e_double: - case e_long_double: - m_type = e_void; - break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: - m_integer = m_integer.ashr(rhs.m_integer); + case Category::Float: { + APFloat result = m_float; + bool losesInfo; + result.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, + &losesInfo); + return result.convertToDouble(); + } + } + return fail_value; +} + +long double Scalar::LongDouble(long double fail_value) const { + /// No way to get more precision at the moment. + return static_cast(Double(fail_value)); +} + +Scalar &Scalar::operator+=(const Scalar &rhs) { + Scalar temp_value; + const Scalar *a; + const Scalar *b; + if ((m_type = PromoteToMaxType(*this, rhs, temp_value, a, b)) != + Scalar::e_void) { + switch (GetCategory(m_type)) { + case Category::Void: + break; + case Category::Integral: + m_integer = a->m_integer + b->m_integer; + break; + + case Category::Float: + m_float = a->m_float + b->m_float; break; } - break; } return *this; } -Scalar &Scalar::operator&=(const Scalar &rhs) { +Scalar &Scalar::operator<<=(const Scalar &rhs) { + if (GetCategory(m_type) == Category::Integral && + GetCategory(rhs.m_type) == Category::Integral) + m_integer <<= rhs.m_integer; + else + m_type = e_void; + return *this; +} + +bool Scalar::ShiftRightLogical(const Scalar &rhs) { + if (GetCategory(m_type) == Category::Integral && + GetCategory(rhs.m_type) == Category::Integral) { + m_integer = m_integer.lshr(rhs.m_integer); + return true; + } + m_type = e_void; + return false; +} + +Scalar &Scalar::operator>>=(const Scalar &rhs) { switch (m_type) { case e_void: case e_float: @@ -1996,7 +768,7 @@ Scalar &Scalar::operator&=(const Scalar &rhs) { case e_uint256: case e_sint512: case e_uint512: - m_integer &= rhs.m_integer; + m_integer = m_integer.ashr(rhs.m_integer); break; } break; @@ -2004,6 +776,15 @@ Scalar &Scalar::operator&=(const Scalar &rhs) { return *this; } +Scalar &Scalar::operator&=(const Scalar &rhs) { + if (GetCategory(m_type) == Category::Integral && + GetCategory(rhs.m_type) == Category::Integral) + m_integer &= rhs.m_integer; + else + m_type = e_void; + return *this; +} + bool Scalar::AbsoluteValue() { switch (m_type) { case e_void: @@ -2036,26 +817,13 @@ bool Scalar::AbsoluteValue() { } bool Scalar::UnaryNegate() { - switch (m_type) { - case e_void: + switch (GetCategory(m_type)) { + case Category::Void: break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: + case Category::Integral: m_integer = -m_integer; return true; - case e_float: - case e_double: - case e_long_double: + case Category::Float: m_float.changeSign(); return true; } @@ -2063,62 +831,17 @@ bool Scalar::UnaryNegate() { } bool Scalar::OnesComplement() { - switch (m_type) { - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - case e_sint512: - case e_uint512: + if (GetCategory(m_type) == Category::Integral) { m_integer = ~m_integer; return true; - - case e_void: - case e_float: - case e_double: - case e_long_double: - break; } + return false; } const Scalar lldb_private::operator+(const Scalar &lhs, const Scalar &rhs) { - Scalar result; - Scalar temp_value; - const Scalar *a; - const Scalar *b; - if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != - Scalar::e_void) { - switch (result.m_type) { - case Scalar::e_void: - break; - case Scalar::e_sint: - case Scalar::e_uint: - case Scalar::e_slong: - case Scalar::e_ulong: - case Scalar::e_slonglong: - case Scalar::e_ulonglong: - case Scalar::e_sint128: - case Scalar::e_uint128: - case Scalar::e_sint256: - case Scalar::e_uint256: - case Scalar::e_sint512: - case Scalar::e_uint512: - result.m_integer = a->m_integer + b->m_integer; - break; - case Scalar::e_float: - case Scalar::e_double: - case Scalar::e_long_double: - result.m_float = a->m_float + b->m_float; - break; - } - } + Scalar result = lhs; + result += rhs; return result; } @@ -2129,26 +852,13 @@ const Scalar lldb_private::operator-(const Scalar &lhs, const Scalar &rhs) { const Scalar *b; if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void) { - switch (result.m_type) { - case Scalar::e_void: + switch (GetCategory(result.m_type)) { + case Category::Void: break; - case Scalar::e_sint: - case Scalar::e_uint: - case Scalar::e_slong: - case Scalar::e_ulong: - case Scalar::e_slonglong: - case Scalar::e_ulonglong: - case Scalar::e_sint128: - case Scalar::e_uint128: - case Scalar::e_sint256: - case Scalar::e_uint256: - case Scalar::e_sint512: - case Scalar::e_uint512: + case Category::Integral: result.m_integer = a->m_integer - b->m_integer; break; - case Scalar::e_float: - case Scalar::e_double: - case Scalar::e_long_double: + case Category::Float: result.m_float = a->m_float - b->m_float; break; } @@ -2162,40 +872,20 @@ const Scalar lldb_private::operator/(const Scalar &lhs, const Scalar &rhs) { const Scalar *a; const Scalar *b; if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != - Scalar::e_void) { - switch (result.m_type) { - case Scalar::e_void: + Scalar::e_void && + !b->IsZero()) { + switch (GetCategory(result.m_type)) { + case Category::Void: break; - case Scalar::e_sint: - case Scalar::e_slong: - case Scalar::e_slonglong: - case Scalar::e_sint128: - case Scalar::e_sint256: - case Scalar::e_sint512: - if (b->m_integer != 0) { + case Category::Integral: + if (IsSigned(result.m_type)) result.m_integer = a->m_integer.sdiv(b->m_integer); - return result; - } - break; - case Scalar::e_uint: - case Scalar::e_ulong: - case Scalar::e_ulonglong: - case Scalar::e_uint128: - case Scalar::e_uint256: - case Scalar::e_uint512: - if (b->m_integer != 0) { + else result.m_integer = a->m_integer.udiv(b->m_integer); - return result; - } - break; - case Scalar::e_float: - case Scalar::e_double: - case Scalar::e_long_double: - if (!b->m_float.isZero()) { - result.m_float = a->m_float / b->m_float; - return result; - } - break; + return result; + case Category::Float: + result.m_float = a->m_float / b->m_float; + return result; } } // For division only, the only way it should make it here is if a promotion @@ -2211,26 +901,13 @@ const Scalar lldb_private::operator*(const Scalar &lhs, const Scalar &rhs) { const Scalar *b; if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void) { - switch (result.m_type) { - case Scalar::e_void: + switch (GetCategory(result.m_type)) { + case Category::Void: break; - case Scalar::e_sint: - case Scalar::e_uint: - case Scalar::e_slong: - case Scalar::e_ulong: - case Scalar::e_slonglong: - case Scalar::e_ulonglong: - case Scalar::e_sint128: - case Scalar::e_uint128: - case Scalar::e_sint256: - case Scalar::e_uint256: - case Scalar::e_sint512: - case Scalar::e_uint512: + case Category::Integral: result.m_integer = a->m_integer * b->m_integer; break; - case Scalar::e_float: - case Scalar::e_double: - case Scalar::e_long_double: + case Category::Float: result.m_float = a->m_float * b->m_float; break; } @@ -2245,29 +922,10 @@ const Scalar lldb_private::operator&(const Scalar &lhs, const Scalar &rhs) { const Scalar *b; if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void) { - switch (result.m_type) { - case Scalar::e_sint: - case Scalar::e_uint: - case Scalar::e_slong: - case Scalar::e_ulong: - case Scalar::e_slonglong: - case Scalar::e_ulonglong: - case Scalar::e_sint128: - case Scalar::e_uint128: - case Scalar::e_sint256: - case Scalar::e_uint256: - case Scalar::e_sint512: - case Scalar::e_uint512: + if (GetCategory(result.m_type) == Category::Integral) result.m_integer = a->m_integer & b->m_integer; - break; - case Scalar::e_void: - case Scalar::e_float: - case Scalar::e_double: - case Scalar::e_long_double: - // No bitwise AND on floats, doubles of long doubles + else result.m_type = Scalar::e_void; - break; - } } return result; } @@ -2279,30 +937,10 @@ const Scalar lldb_private::operator|(const Scalar &lhs, const Scalar &rhs) { const Scalar *b; if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void) { - switch (result.m_type) { - case Scalar::e_sint: - case Scalar::e_uint: - case Scalar::e_slong: - case Scalar::e_ulong: - case Scalar::e_slonglong: - case Scalar::e_ulonglong: - case Scalar::e_sint128: - case Scalar::e_uint128: - case Scalar::e_sint256: - case Scalar::e_uint256: - case Scalar::e_sint512: - case Scalar::e_uint512: + if (GetCategory(result.m_type) == Category::Integral) result.m_integer = a->m_integer | b->m_integer; - break; - - case Scalar::e_void: - case Scalar::e_float: - case Scalar::e_double: - case Scalar::e_long_double: - // No bitwise AND on floats, doubles of long doubles + else result.m_type = Scalar::e_void; - break; - } } return result; } @@ -2314,33 +952,12 @@ const Scalar lldb_private::operator%(const Scalar &lhs, const Scalar &rhs) { const Scalar *b; if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void) { - switch (result.m_type) { - default: - break; - case Scalar::e_void: - break; - case Scalar::e_sint: - case Scalar::e_slong: - case Scalar::e_slonglong: - case Scalar::e_sint128: - case Scalar::e_sint256: - case Scalar::e_sint512: - if (b->m_integer != 0) { + if (!b->IsZero() && GetCategory(result.m_type) == Category::Integral) { + if (IsSigned(result.m_type)) result.m_integer = a->m_integer.srem(b->m_integer); - return result; - } - break; - case Scalar::e_uint: - case Scalar::e_ulong: - case Scalar::e_ulonglong: - case Scalar::e_uint128: - case Scalar::e_uint256: - case Scalar::e_uint512: - if (b->m_integer != 0) { + else result.m_integer = a->m_integer.urem(b->m_integer); - return result; - } - break; + return result; } } result.m_type = Scalar::e_void; @@ -2354,30 +971,10 @@ const Scalar lldb_private::operator^(const Scalar &lhs, const Scalar &rhs) { const Scalar *b; if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void) { - switch (result.m_type) { - case Scalar::e_sint: - case Scalar::e_uint: - case Scalar::e_slong: - case Scalar::e_ulong: - case Scalar::e_slonglong: - case Scalar::e_ulonglong: - case Scalar::e_sint128: - case Scalar::e_uint128: - case Scalar::e_sint256: - case Scalar::e_uint256: - case Scalar::e_sint512: - case Scalar::e_uint512: + if (GetCategory(result.m_type) == Category::Integral) result.m_integer = a->m_integer ^ b->m_integer; - break; - - case Scalar::e_void: - case Scalar::e_float: - case Scalar::e_double: - case Scalar::e_long_double: - // No bitwise AND on floats, doubles of long doubles + else result.m_type = Scalar::e_void; - break; - } } return result; } @@ -2406,116 +1003,60 @@ Status Scalar::SetValueFromCString(const char *value_str, Encoding encoding, error.SetErrorString("Invalid encoding."); break; - case eEncodingUint: - if (byte_size <= sizeof(uint64_t)) { - uint64_t uval64; - if (!llvm::to_integer(value_str, uval64)) - error.SetErrorStringWithFormat( - "'%s' is not a valid unsigned integer string value", value_str); - else if (!UIntValueIsValidForSize(uval64, byte_size)) - error.SetErrorStringWithFormat( - "value 0x%" PRIx64 " is too large to fit in a %" PRIu64 - " byte unsigned integer value", - uval64, static_cast(byte_size)); - else { - m_type = Scalar::GetValueTypeForUnsignedIntegerWithByteSize(byte_size); - switch (m_type) { - case e_uint: - m_integer = llvm::APInt(sizeof(uint_t) * 8, uval64, false); - break; - case e_ulong: - m_integer = llvm::APInt(sizeof(ulong_t) * 8, uval64, false); - break; - case e_ulonglong: - m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, uval64, false); - break; - default: - error.SetErrorStringWithFormat( - "unsupported unsigned integer byte size: %" PRIu64 "", - static_cast(byte_size)); - break; - } - } - } else { - error.SetErrorStringWithFormat( - "unsupported unsigned integer byte size: %" PRIu64 "", - static_cast(byte_size)); - return error; - } - break; - case eEncodingSint: - if (byte_size <= sizeof(int64_t)) { - int64_t sval64; - if (!llvm::to_integer(value_str, sval64)) - error.SetErrorStringWithFormat( - "'%s' is not a valid signed integer string value", value_str); - else if (!SIntValueIsValidForSize(sval64, byte_size)) - error.SetErrorStringWithFormat( - "value 0x%" PRIx64 " is too large to fit in a %" PRIu64 - " byte signed integer value", - sval64, static_cast(byte_size)); - else { - m_type = Scalar::GetValueTypeForSignedIntegerWithByteSize(byte_size); - switch (m_type) { - case e_sint: - m_integer = llvm::APInt(sizeof(sint_t) * 8, sval64, true); - break; - case e_slong: - m_integer = llvm::APInt(sizeof(slong_t) * 8, sval64, true); - break; - case e_slonglong: - m_integer = llvm::APInt(sizeof(slonglong_t) * 8, sval64, true); - break; - default: - error.SetErrorStringWithFormat( - "unsupported signed integer byte size: %" PRIu64 "", - static_cast(byte_size)); - break; - } - } - } else { - error.SetErrorStringWithFormat( - "unsupported signed integer byte size: %" PRIu64 "", - static_cast(byte_size)); - return error; + case eEncodingUint: { + llvm::StringRef str = value_str; + bool is_signed = encoding == eEncodingSint; + bool is_negative = is_signed && str.consume_front("-"); + APInt integer; + if (str.getAsInteger(0, integer)) { + error.SetErrorStringWithFormatv( + "'{0}' is not a valid integer string value", value_str); + break; + } + bool fits; + if (is_signed) { + integer = integer.zext(integer.getBitWidth() + 1); + if (is_negative) + integer.negate(); + fits = integer.isSignedIntN(byte_size * 8); + } else + fits = integer.isIntN(byte_size * 8); + if (!fits) { + error.SetErrorStringWithFormatv( + "value {0} is too large to fit in a {1} byte integer value", + value_str, byte_size); + break; } + m_type = GetBestTypeForBitSize(8 * byte_size, is_signed); + if (m_type == e_void) { + error.SetErrorStringWithFormatv("unsupported integer byte size: {0}", + byte_size); + break; + } + if (is_signed) + m_integer = integer.sextOrTrunc(GetBitSize(m_type)); + else + m_integer = integer.zextOrTrunc(GetBitSize(m_type)); break; + } - case eEncodingIEEE754: - static float f_val; - static double d_val; - static long double l_val; - if (byte_size == sizeof(float)) { - if (::sscanf(value_str, "%f", &f_val) == 1) { - m_float = llvm::APFloat(f_val); - m_type = e_float; - } else - error.SetErrorStringWithFormat("'%s' is not a valid float string value", - value_str); - } else if (byte_size == sizeof(double)) { - if (::sscanf(value_str, "%lf", &d_val) == 1) { - m_float = llvm::APFloat(d_val); - m_type = e_double; - } else - error.SetErrorStringWithFormat("'%s' is not a valid float string value", - value_str); - } else if (byte_size == sizeof(long double)) { - if (::sscanf(value_str, "%Lf", &l_val) == 1) { - m_float = llvm::APFloat( - llvm::APFloat::x87DoubleExtended(), - llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, - (reinterpret_cast(&l_val))->x)); - m_type = e_long_double; - } else - error.SetErrorStringWithFormat("'%s' is not a valid float string value", - value_str); - } else { - error.SetErrorStringWithFormat("unsupported float byte size: %" PRIu64 "", - static_cast(byte_size)); - return error; + case eEncodingIEEE754: { + Type type = GetValueTypeForFloatWithByteSize(byte_size); + if (type == e_void) { + error.SetErrorStringWithFormatv("unsupported float byte size: {0}", + byte_size); + break; } + APFloat f(GetFltSemantics(type)); + if (llvm::Expected op = + f.convertFromString(value_str, APFloat::rmNearestTiesToEven)) { + m_type = type; + m_float = std::move(f); + } else + error = op.takeError(); break; + } case eEncodingVector: error.SetErrorString("vector encoding unsupported."); diff --git a/gnu/llvm/lldb/source/Utility/SelectHelper.cpp b/gnu/llvm/lldb/source/Utility/SelectHelper.cpp index 9f5ca586e1e..40c85bee607 100644 --- a/gnu/llvm/lldb/source/Utility/SelectHelper.cpp +++ b/gnu/llvm/lldb/source/Utility/SelectHelper.cpp @@ -1,4 +1,4 @@ -//===-- SelectHelper.cpp ----------------------------------------*- C++ -*-===// +//===-- SelectHelper.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/State.cpp b/gnu/llvm/lldb/source/Utility/State.cpp index 51fe92bad77..2d76b801dca 100644 --- a/gnu/llvm/lldb/source/Utility/State.cpp +++ b/gnu/llvm/lldb/source/Utility/State.cpp @@ -1,4 +1,4 @@ -//===-- State.cpp -----------------------------------------------*- C++ -*-===// +//===-- State.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/Status.cpp b/gnu/llvm/lldb/source/Utility/Status.cpp index b74db72773d..e3c4284a8e8 100644 --- a/gnu/llvm/lldb/source/Utility/Status.cpp +++ b/gnu/llvm/lldb/source/Utility/Status.cpp @@ -1,5 +1,4 @@ -//===-- Status.cpp -----------------------------------------------*- C++ -//-*-===// +//===-- Status.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -43,8 +42,13 @@ Status::Status() : m_code(0), m_type(eErrorTypeInvalid), m_string() {} Status::Status(ValueType err, ErrorType type) : m_code(err), m_type(type), m_string() {} +// This logic is confusing because c++ calls the traditional (posix) errno codes +// "generic errors", while we use the term "generic" to mean completely +// arbitrary (text-based) errors. Status::Status(std::error_code EC) - : m_code(EC.value()), m_type(ErrorType::eErrorTypeGeneric), + : m_code(EC.value()), + m_type(EC.category() == std::generic_category() ? eErrorTypePOSIX + : eErrorTypeGeneric), m_string(EC.message()) {} Status::Status(const char *format, ...) @@ -242,7 +246,7 @@ void Status::SetErrorString(llvm::StringRef err_str) { if (Success()) SetErrorToGenericError(); } - m_string = err_str; + m_string = std::string(err_str); } /// Set the current error string to a formatted error string. @@ -271,7 +275,7 @@ int Status::SetErrorStringWithVarArg(const char *format, va_list args) { llvm::SmallString<1024> buf; VASprintf(buf, format, args); - m_string = buf.str(); + m_string = std::string(buf.str()); return buf.size(); } else { m_string.clear(); diff --git a/gnu/llvm/lldb/source/Utility/Stream.cpp b/gnu/llvm/lldb/source/Utility/Stream.cpp index b336cb6b518..a0623bfa6e5 100644 --- a/gnu/llvm/lldb/source/Utility/Stream.cpp +++ b/gnu/llvm/lldb/source/Utility/Stream.cpp @@ -1,4 +1,4 @@ -//===-- Stream.cpp ----------------------------------------------*- C++ -*-===// +//===-- Stream.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -22,13 +22,14 @@ using namespace lldb; using namespace lldb_private; -Stream::Stream(uint32_t flags, uint32_t addr_size, ByteOrder byte_order) +Stream::Stream(uint32_t flags, uint32_t addr_size, ByteOrder byte_order, + bool colors) : m_flags(flags), m_addr_size(addr_size), m_byte_order(byte_order), - m_indent_level(0), m_forwarder(*this) {} + m_indent_level(0), m_forwarder(*this, colors) {} -Stream::Stream() +Stream::Stream(bool colors) : m_flags(0), m_addr_size(4), m_byte_order(endian::InlHostByteOrder()), - m_indent_level(0), m_forwarder(*this) {} + m_indent_level(0), m_forwarder(*this, colors) {} // Destructor Stream::~Stream() {} @@ -126,15 +127,10 @@ size_t Stream::PrintfVarArg(const char *format, va_list args) { // Print and End of Line character to the stream size_t Stream::EOL() { return PutChar('\n'); } -// Indent the current line using the current indentation level and print an -// optional string following the indentation spaces. -size_t Stream::Indent(const char *s) { - return Printf("%*.*s%s", m_indent_level, m_indent_level, "", s ? s : ""); -} - size_t Stream::Indent(llvm::StringRef str) { - return Printf("%*.*s%s", m_indent_level, m_indent_level, "", - str.str().c_str()); + const size_t ind_length = PutCString(std::string(m_indent_level, ' ')); + const size_t str_length = PutCString(str); + return ind_length + str_length; } // Stream a character "ch" out to this stream. diff --git a/gnu/llvm/lldb/source/Utility/StreamCallback.cpp b/gnu/llvm/lldb/source/Utility/StreamCallback.cpp index b3d3adea78b..c10f678d7a2 100644 --- a/gnu/llvm/lldb/source/Utility/StreamCallback.cpp +++ b/gnu/llvm/lldb/source/Utility/StreamCallback.cpp @@ -1,4 +1,4 @@ -//===-- StreamCallback.cpp -------------------------------------*- C++ -*-===// +//===-- StreamCallback.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/StreamString.cpp b/gnu/llvm/lldb/source/Utility/StreamString.cpp index 6b5b7d337fc..190be588e88 100644 --- a/gnu/llvm/lldb/source/Utility/StreamString.cpp +++ b/gnu/llvm/lldb/source/Utility/StreamString.cpp @@ -1,4 +1,4 @@ -//===-- StreamString.cpp ----------------------------------------*- C++ -*-===// +//===-- StreamString.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/StringExtractor.cpp b/gnu/llvm/lldb/source/Utility/StringExtractor.cpp index 87fe4f13e45..0553a63a021 100644 --- a/gnu/llvm/lldb/source/Utility/StringExtractor.cpp +++ b/gnu/llvm/lldb/source/Utility/StringExtractor.cpp @@ -1,4 +1,4 @@ -//===-- StringExtractor.cpp -------------------------------------*- C++ -*-===// +//===-- StringExtractor.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Utility/StringExtractor.h" +#include "llvm/ADT/StringExtras.h" #include @@ -365,6 +366,6 @@ bool StringExtractor::GetNameColonValue(llvm::StringRef &name, void StringExtractor::SkipSpaces() { const size_t n = m_packet.size(); - while (m_index < n && isspace(m_packet[m_index])) + while (m_index < n && llvm::isSpace(m_packet[m_index])) ++m_index; } diff --git a/gnu/llvm/lldb/source/Utility/StringExtractorGDBRemote.cpp b/gnu/llvm/lldb/source/Utility/StringExtractorGDBRemote.cpp index a011e9246d1..cfe7577e486 100644 --- a/gnu/llvm/lldb/source/Utility/StringExtractorGDBRemote.cpp +++ b/gnu/llvm/lldb/source/Utility/StringExtractorGDBRemote.cpp @@ -1,4 +1,4 @@ -//===-- StringExtractorGDBRemote.cpp ----------------------------*- C++ -*-===// +//===-- StringExtractorGDBRemote.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/StringLexer.cpp b/gnu/llvm/lldb/source/Utility/StringLexer.cpp index c357cb0fb55..947472a014e 100644 --- a/gnu/llvm/lldb/source/Utility/StringLexer.cpp +++ b/gnu/llvm/lldb/source/Utility/StringLexer.cpp @@ -1,4 +1,4 @@ -//===--------------------- StringLexer.cpp -----------------------*- C++-*-===// +//===-- StringLexer.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/StringList.cpp b/gnu/llvm/lldb/source/Utility/StringList.cpp index 5e06b6b69fc..809c5a02acf 100644 --- a/gnu/llvm/lldb/source/Utility/StringList.cpp +++ b/gnu/llvm/lldb/source/Utility/StringList.cpp @@ -1,4 +1,4 @@ -//===-- StringList.cpp ------------------------------------------*- C++ -*-===// +//===-- StringList.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -199,7 +199,7 @@ std::string StringList::CopyList(const char *item_preamble, strm << item_preamble; strm << GetStringAtIndex(i); } - return strm.GetString(); + return std::string(strm.GetString()); } StringList &StringList::operator<<(const char *str) { diff --git a/gnu/llvm/lldb/source/Utility/StructuredData.cpp b/gnu/llvm/lldb/source/Utility/StructuredData.cpp index d5d7a7ec99a..df1b35618e4 100644 --- a/gnu/llvm/lldb/source/Utility/StructuredData.cpp +++ b/gnu/llvm/lldb/source/Utility/StructuredData.cpp @@ -1,4 +1,4 @@ -//===---------------------StructuredData.cpp ---------------------*- C++-*-===// +//===-- StructuredData.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -156,7 +156,7 @@ void StructuredData::String::Serialize(json::OStream &s) const { void StructuredData::Dictionary::Serialize(json::OStream &s) const { s.objectBegin(); for (const auto &pair : m_dict) { - s.attributeBegin(pair.first.AsCString()); + s.attributeBegin(pair.first.GetStringRef()); pair.second->Serialize(s); s.attributeEnd(); } diff --git a/gnu/llvm/lldb/source/Utility/TildeExpressionResolver.cpp b/gnu/llvm/lldb/source/Utility/TildeExpressionResolver.cpp index b58f45728ce..c8a0800cb80 100644 --- a/gnu/llvm/lldb/source/Utility/TildeExpressionResolver.cpp +++ b/gnu/llvm/lldb/source/Utility/TildeExpressionResolver.cpp @@ -1,4 +1,4 @@ -//===--------------------- TildeExpressionResolver.cpp ----------*- C++ -*-===// +//===-- TildeExpressionResolver.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/Timer.cpp b/gnu/llvm/lldb/source/Utility/Timer.cpp index 6b46d8ba736..d55c9863117 100644 --- a/gnu/llvm/lldb/source/Utility/Timer.cpp +++ b/gnu/llvm/lldb/source/Utility/Timer.cpp @@ -1,4 +1,4 @@ -//===-- Timer.cpp -----------------------------------------------*- C++ -*-===// +//===-- Timer.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -15,6 +15,7 @@ #include #include +#include #include #include diff --git a/gnu/llvm/lldb/source/Utility/UUID.cpp b/gnu/llvm/lldb/source/Utility/UUID.cpp index 2a73f9a482f..4177b43de81 100644 --- a/gnu/llvm/lldb/source/Utility/UUID.cpp +++ b/gnu/llvm/lldb/source/Utility/UUID.cpp @@ -1,4 +1,4 @@ -//===-- UUID.cpp ------------------------------------------------*- C++ -*-===// +//===-- UUID.cpp ----------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -61,10 +61,9 @@ static inline int xdigit_to_int(char ch) { llvm::StringRef UUID::DecodeUUIDBytesFromString(llvm::StringRef p, - llvm::SmallVectorImpl &uuid_bytes, - uint32_t num_uuid_bytes) { + llvm::SmallVectorImpl &uuid_bytes) { uuid_bytes.clear(); - while (!p.empty()) { + while (p.size() >= 2) { if (isxdigit(p[0]) && isxdigit(p[1])) { int hi_nibble = xdigit_to_int(p[0]); int lo_nibble = xdigit_to_int(p[1]); @@ -73,11 +72,6 @@ UUID::DecodeUUIDBytesFromString(llvm::StringRef p, // Skip both hex digits p = p.drop_front(2); - - // Increment the byte that we are decoding within the UUID value and - // break out if we are done - if (uuid_bytes.size() == num_uuid_bytes) - break; } else if (p.front() == '-') { // Skip dashes p = p.drop_front(); @@ -89,35 +83,30 @@ UUID::DecodeUUIDBytesFromString(llvm::StringRef p, return p; } -size_t UUID::SetFromStringRef(llvm::StringRef str, uint32_t num_uuid_bytes) { +bool UUID::SetFromStringRef(llvm::StringRef str) { llvm::StringRef p = str; // Skip leading whitespace characters p = p.ltrim(); llvm::SmallVector bytes; - llvm::StringRef rest = - UUID::DecodeUUIDBytesFromString(p, bytes, num_uuid_bytes); - - // If we successfully decoded a UUID, return the amount of characters that - // were consumed - if (bytes.size() == num_uuid_bytes) { - *this = fromData(bytes); - return str.size() - rest.size(); - } + llvm::StringRef rest = UUID::DecodeUUIDBytesFromString(p, bytes); + + // Return false if we could not consume the entire string or if the parsed + // UUID is empty. + if (!rest.empty() || bytes.empty()) + return false; - // Else return zero to indicate we were not able to parse a UUID value - return 0; + *this = fromData(bytes); + return true; } -size_t UUID::SetFromOptionalStringRef(llvm::StringRef str, - uint32_t num_uuid_bytes) { - size_t num_chars_consumed = SetFromStringRef(str, num_uuid_bytes); - if (num_chars_consumed) { +bool UUID::SetFromOptionalStringRef(llvm::StringRef str) { + bool result = SetFromStringRef(str); + if (result) { if (llvm::all_of(m_bytes, [](uint8_t b) { return b == 0; })) Clear(); } - - return num_chars_consumed; -} + return result; +} diff --git a/gnu/llvm/lldb/source/Utility/UriParser.cpp b/gnu/llvm/lldb/source/Utility/UriParser.cpp index b446958f2f4..8169b0eee12 100644 --- a/gnu/llvm/lldb/source/Utility/UriParser.cpp +++ b/gnu/llvm/lldb/source/Utility/UriParser.cpp @@ -1,4 +1,4 @@ -//===-- UriParser.cpp -------------------------------------------*- C++ -*-===// +//===-- UriParser.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -42,7 +42,7 @@ bool UriParser::Parse(llvm::StringRef uri, llvm::StringRef &scheme, // Extract hostname if (!host_port.empty() && host_port[0] == '[') { // hostname is enclosed with square brackets. - pos = host_port.find(']'); + pos = host_port.rfind(']'); if (pos == std::string::npos) return false; diff --git a/gnu/llvm/lldb/source/Utility/UserID.cpp b/gnu/llvm/lldb/source/Utility/UserID.cpp index b76a1cd84f8..8e0146b9349 100644 --- a/gnu/llvm/lldb/source/Utility/UserID.cpp +++ b/gnu/llvm/lldb/source/Utility/UserID.cpp @@ -1,4 +1,4 @@ -//===-- UserID.cpp ----------------------------------------------*- C++ -*-===// +//===-- UserID.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/UserIDResolver.cpp b/gnu/llvm/lldb/source/Utility/UserIDResolver.cpp index 8aac6f948cd..73bdde77cc0 100644 --- a/gnu/llvm/lldb/source/Utility/UserIDResolver.cpp +++ b/gnu/llvm/lldb/source/Utility/UserIDResolver.cpp @@ -1,4 +1,4 @@ -//===-- UserIDResolver.cpp --------------------------------------*- C++ -*-===// +//===-- UserIDResolver.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/VASprintf.cpp b/gnu/llvm/lldb/source/Utility/VASprintf.cpp index 2ee0f6676fa..aea68dfff9f 100644 --- a/gnu/llvm/lldb/source/Utility/VASprintf.cpp +++ b/gnu/llvm/lldb/source/Utility/VASprintf.cpp @@ -1,4 +1,4 @@ -//===-- VASprintf.cpp -------------------------------------------*- C++ -*-===// +//===-- VASprintf.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/VMRange.cpp b/gnu/llvm/lldb/source/Utility/VMRange.cpp index c8c3334138d..16c50d6e81b 100644 --- a/gnu/llvm/lldb/source/Utility/VMRange.cpp +++ b/gnu/llvm/lldb/source/Utility/VMRange.cpp @@ -1,4 +1,4 @@ -//===-- VMRange.cpp ---------------------------------------------*- C++ -*-===// +//===-- VMRange.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/source/Utility/XcodeSDK.cpp b/gnu/llvm/lldb/source/Utility/XcodeSDK.cpp new file mode 100644 index 00000000000..066bf457966 --- /dev/null +++ b/gnu/llvm/lldb/source/Utility/XcodeSDK.cpp @@ -0,0 +1,309 @@ +//===-- XcodeSDK.cpp ------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/XcodeSDK.h" +#include "lldb/Utility/FileSpec.h" + +#include "lldb/lldb-types.h" + +#include "llvm/ADT/Triple.h" + +#include + +using namespace lldb; +using namespace lldb_private; + +static llvm::StringRef GetName(XcodeSDK::Type type) { + switch (type) { + case XcodeSDK::MacOSX: + return "MacOSX"; + case XcodeSDK::iPhoneSimulator: + return "iPhoneSimulator"; + case XcodeSDK::iPhoneOS: + return "iPhoneOS"; + case XcodeSDK::AppleTVSimulator: + return "AppleTVSimulator"; + case XcodeSDK::AppleTVOS: + return "AppleTVOS"; + case XcodeSDK::WatchSimulator: + return "WatchSimulator"; + case XcodeSDK::watchOS: + return "WatchOS"; + case XcodeSDK::bridgeOS: + return "bridgeOS"; + case XcodeSDK::Linux: + return "Linux"; + case XcodeSDK::unknown: + return {}; + } + llvm_unreachable("Unhandled sdk type!"); +} + +XcodeSDK::XcodeSDK(XcodeSDK::Info info) : m_name(GetName(info.type).str()) { + if (!m_name.empty()) { + if (!info.version.empty()) + m_name += info.version.getAsString(); + if (info.internal) + m_name += ".Internal"; + m_name += ".sdk"; + } +} + +XcodeSDK &XcodeSDK::operator=(XcodeSDK other) { + m_name = other.m_name; + return *this; +} + +bool XcodeSDK::operator==(XcodeSDK other) { + return m_name == other.m_name; +} + +static XcodeSDK::Type ParseSDKName(llvm::StringRef &name) { + if (name.consume_front("MacOSX")) + return XcodeSDK::MacOSX; + if (name.consume_front("iPhoneSimulator")) + return XcodeSDK::iPhoneSimulator; + if (name.consume_front("iPhoneOS")) + return XcodeSDK::iPhoneOS; + if (name.consume_front("AppleTVSimulator")) + return XcodeSDK::AppleTVSimulator; + if (name.consume_front("AppleTVOS")) + return XcodeSDK::AppleTVOS; + if (name.consume_front("WatchSimulator")) + return XcodeSDK::WatchSimulator; + if (name.consume_front("WatchOS")) + return XcodeSDK::watchOS; + if (name.consume_front("bridgeOS")) + return XcodeSDK::bridgeOS; + if (name.consume_front("Linux")) + return XcodeSDK::Linux; + static_assert(XcodeSDK::Linux == XcodeSDK::numSDKTypes - 1, + "New SDK type was added, update this list!"); + return XcodeSDK::unknown; +} + +static llvm::VersionTuple ParseSDKVersion(llvm::StringRef &name) { + unsigned i = 0; + while (i < name.size() && name[i] >= '0' && name[i] <= '9') + ++i; + if (i == name.size() || name[i++] != '.') + return {}; + while (i < name.size() && name[i] >= '0' && name[i] <= '9') + ++i; + if (i == name.size() || name[i++] != '.') + return {}; + + llvm::VersionTuple version; + version.tryParse(name.slice(0, i - 1)); + name = name.drop_front(i); + return version; +} + +static bool ParseAppleInternalSDK(llvm::StringRef &name) { + return name.consume_front("Internal.") || name.consume_front(".Internal."); +} + +XcodeSDK::Info XcodeSDK::Parse() const { + XcodeSDK::Info info; + llvm::StringRef input(m_name); + info.type = ParseSDKName(input); + info.version = ParseSDKVersion(input); + info.internal = ParseAppleInternalSDK(input); + return info; +} + +bool XcodeSDK::IsAppleInternalSDK() const { + llvm::StringRef input(m_name); + ParseSDKName(input); + ParseSDKVersion(input); + return ParseAppleInternalSDK(input); +} + +llvm::VersionTuple XcodeSDK::GetVersion() const { + llvm::StringRef input(m_name); + ParseSDKName(input); + return ParseSDKVersion(input); +} + +XcodeSDK::Type XcodeSDK::GetType() const { + llvm::StringRef input(m_name); + return ParseSDKName(input); +} + +llvm::StringRef XcodeSDK::GetString() const { return m_name; } + +bool XcodeSDK::Info::operator<(const Info &other) const { + return std::tie(type, version, internal) < + std::tie(other.type, other.version, other.internal); +} + +bool XcodeSDK::Info::operator==(const Info &other) const { + return std::tie(type, version, internal) == + std::tie(other.type, other.version, other.internal); +} + +void XcodeSDK::Merge(XcodeSDK other) { + // The "bigger" SDK always wins. + auto l = Parse(); + auto r = other.Parse(); + if (l < r) + *this = other; + else { + // The Internal flag always wins. + if (llvm::StringRef(m_name).endswith(".sdk")) + if (!l.internal && r.internal) + m_name = + m_name.substr(0, m_name.size() - 3) + std::string("Internal.sdk"); + } +} + +std::string XcodeSDK::GetCanonicalName(XcodeSDK::Info info) { + std::string name; + switch (info.type) { + case MacOSX: + name = "macosx"; + break; + case iPhoneSimulator: + name = "iphonesimulator"; + break; + case iPhoneOS: + name = "iphoneos"; + break; + case AppleTVSimulator: + name = "appletvsimulator"; + break; + case AppleTVOS: + name = "appletvos"; + break; + case WatchSimulator: + name = "watchsimulator"; + break; + case watchOS: + name = "watchos"; + break; + case bridgeOS: + name = "bridgeos"; + break; + case Linux: + name = "linux"; + break; + case unknown: + return {}; + } + if (!info.version.empty()) + name += info.version.getAsString(); + if (info.internal) + name += ".internal"; + return name; +} + +bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type sdk_type, + llvm::VersionTuple version) { + switch (sdk_type) { + case Type::MacOSX: + return version >= llvm::VersionTuple(10, 10); + case Type::iPhoneOS: + case Type::iPhoneSimulator: + case Type::AppleTVOS: + case Type::AppleTVSimulator: + return version >= llvm::VersionTuple(8); + case Type::watchOS: + case Type::WatchSimulator: + return version >= llvm::VersionTuple(6); + default: + return false; + } + + return false; +} + +bool XcodeSDK::SupportsSwift() const { + XcodeSDK::Info info = Parse(); + switch (info.type) { + case Type::MacOSX: + return info.version.empty() || info.version >= llvm::VersionTuple(10, 10); + case Type::iPhoneOS: + case Type::iPhoneSimulator: + return info.version.empty() || info.version >= llvm::VersionTuple(8); + case Type::AppleTVSimulator: + case Type::AppleTVOS: + return info.version.empty() || info.version >= llvm::VersionTuple(9); + case Type::WatchSimulator: + case Type::watchOS: + return info.version.empty() || info.version >= llvm::VersionTuple(2); + case Type::Linux: + return true; + default: + return false; + } +} + +bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type desired_type, + const FileSpec &sdk_path) { + ConstString last_path_component = sdk_path.GetLastPathComponent(); + + if (!last_path_component) + return false; + + XcodeSDK sdk(last_path_component.GetStringRef().str()); + if (sdk.GetType() != desired_type) + return false; + return SDKSupportsModules(sdk.GetType(), sdk.GetVersion()); +} + +XcodeSDK::Type XcodeSDK::GetSDKTypeForTriple(const llvm::Triple &triple) { + using namespace llvm; + switch (triple.getOS()) { + case Triple::MacOSX: + case Triple::Darwin: + return XcodeSDK::MacOSX; + case Triple::IOS: + switch (triple.getEnvironment()) { + case Triple::MacABI: + return XcodeSDK::MacOSX; + case Triple::Simulator: + return XcodeSDK::iPhoneSimulator; + default: + return XcodeSDK::iPhoneOS; + } + case Triple::TvOS: + if (triple.getEnvironment() == Triple::Simulator) + return XcodeSDK::AppleTVSimulator; + return XcodeSDK::AppleTVOS; + case Triple::WatchOS: + if (triple.getEnvironment() == Triple::Simulator) + return XcodeSDK::WatchSimulator; + return XcodeSDK::watchOS; + case Triple::Linux: + return XcodeSDK::Linux; + default: + return XcodeSDK::unknown; + } +} + +std::string XcodeSDK::FindXcodeContentsDirectoryInPath(llvm::StringRef path) { + auto begin = llvm::sys::path::begin(path); + auto end = llvm::sys::path::end(path); + + // Iterate over the path components until we find something that ends with + // .app. If the next component is Contents then we've found the Contents + // directory. + for (auto it = begin; it != end; ++it) { + if (it->endswith(".app")) { + auto next = it; + if (++next != end && *next == "Contents") { + llvm::SmallString<128> buffer; + llvm::sys::path::append(buffer, begin, ++next, + llvm::sys::path::Style::posix); + return buffer.str().str(); + } + } + } + + return {}; +} diff --git a/gnu/llvm/lldb/source/lldb.cpp b/gnu/llvm/lldb/source/lldb.cpp index c96f5d9ee7e..6d4ed66074d 100644 --- a/gnu/llvm/lldb/source/lldb.cpp +++ b/gnu/llvm/lldb/source/lldb.cpp @@ -1,4 +1,4 @@ -//===-- lldb.cpp ------------------------------------------------*- C++ -*-===// +//===-- lldb.cpp ----------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -50,8 +50,10 @@ const char *lldb_private::GetVersion() { g_version_str += " ("; if (lldb_repo) g_version_str += lldb_repo; + if (lldb_repo && lldb_rev) + g_version_str += " "; if (lldb_rev) { - g_version_str += " revision "; + g_version_str += "revision "; g_version_str += lldb_rev; } g_version_str += ")"; diff --git a/gnu/llvm/lldb/third_party/Python/module/pexpect-4.6/pexpect/spawnbase.py b/gnu/llvm/lldb/third_party/Python/module/pexpect-4.6/pexpect/spawnbase.py index 63c0b4204eb..4bebe115847 100644 --- a/gnu/llvm/lldb/third_party/Python/module/pexpect-4.6/pexpect/spawnbase.py +++ b/gnu/llvm/lldb/third_party/Python/module/pexpect-4.6/pexpect/spawnbase.py @@ -150,7 +150,7 @@ class SpawnBase(object): self._buffer = self.buffer_type() self._buffer.write(value) - # This property is provided for backwards compatability (self.buffer used + # This property is provided for backwards compatibility (self.buffer used # to be a string/bytes object) buffer = property(_get_buffer, _set_buffer) diff --git a/gnu/llvm/lldb/tools/darwin-debug/CMakeLists.txt b/gnu/llvm/lldb/tools/darwin-debug/CMakeLists.txt index b902788f05a..9039aa3423b 100644 --- a/gnu/llvm/lldb/tools/darwin-debug/CMakeLists.txt +++ b/gnu/llvm/lldb/tools/darwin-debug/CMakeLists.txt @@ -1,3 +1,11 @@ + +# Create an LC_SEGMENT with the special name ExecExtraSuspend which +# debugserver can detect - it tells debugserver that it will exec a +# process and that process will start suspended, so debugserver will +# need to double-resume it to make it run. A random file is copied +# into the segment. +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-sectcreate,ExecExtraSuspend,ExecExtraSuspend,/dev/null") + add_lldb_tool(darwin-debug ADD_TO_FRAMEWORK darwin-debug.cpp ) diff --git a/gnu/llvm/lldb/tools/debugserver/CMakeLists.txt b/gnu/llvm/lldb/tools/debugserver/CMakeLists.txt index 1dc32434ba4..fc23cf3c7e2 100644 --- a/gnu/llvm/lldb/tools/debugserver/CMakeLists.txt +++ b/gnu/llvm/lldb/tools/debugserver/CMakeLists.txt @@ -17,4 +17,9 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) include_directories(${LLDB_SOURCE_DIR}/include) endif() +# debugserver contains ObjC++ code, so let's disable Clang modules +# in this subdirectory to avoid building ObjC++ modules (which often +# doesn't properly work). +remove_module_flags() + add_subdirectory(source) diff --git a/gnu/llvm/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj b/gnu/llvm/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj index f4267b7633a..1c7a55f7108 100644 --- a/gnu/llvm/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj +++ b/gnu/llvm/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj @@ -7,131 +7,165 @@ objects = { /* Begin PBXBuildFile section */ - 23562ED61D342A5A00AB2BD4 /* ActivityStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED51D342A5A00AB2BD4 /* ActivityStore.cpp */; }; - 23562ED71D342A5A00AB2BD4 /* ActivityStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED51D342A5A00AB2BD4 /* ActivityStore.cpp */; }; - 26CE05C5115C36590022F371 /* CFBundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD910D3EBFF6007E4CA2 /* CFBundle.cpp */; }; - 456F67641AD46CE9002850C2 /* CFBundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD910D3EBFF6007E4CA2 /* CFBundle.cpp */; }; - 26CE05C3115C36580022F371 /* CFString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD9B0D3EC160007E4CA2 /* CFString.cpp */; }; - 456F67621AD46CE9002850C2 /* CFString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD9B0D3EC160007E4CA2 /* CFString.cpp */; }; - 26CE05CF115C36F70022F371 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26ACA3340D3E956300A2120B /* CoreFoundation.framework */; settings = {ATTRIBUTES = (Required, ); }; }; - 456F676B1AD46CE9002850C2 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26ACA3340D3E956300A2120B /* CoreFoundation.framework */; settings = {ATTRIBUTES = (Required, ); }; }; - 26CE05B7115C363B0022F371 /* DNB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637D60C71334A0024798E /* DNB.cpp */; }; - 456F67551AD46CE9002850C2 /* DNB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637D60C71334A0024798E /* DNB.cpp */; }; - 264D5D581293835600ED4C01 /* DNBArch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264D5D571293835600ED4C01 /* DNBArch.cpp */; }; - 456F67671AD46CE9002850C2 /* DNBArch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264D5D571293835600ED4C01 /* DNBArch.cpp */; }; - 26CE05C1115C36510022F371 /* DNBArchImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2675D4220CCEB705000F49AF /* DNBArchImpl.cpp */; }; - 26CE05C2115C36550022F371 /* DNBArchImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637FB0C71334A0024798E /* DNBArchImpl.cpp */; }; - 456F67601AD46CE9002850C2 /* DNBArchImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2675D4220CCEB705000F49AF /* DNBArchImpl.cpp */; }; - 456F67611AD46CE9002850C2 /* DNBArchImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637FB0C71334A0024798E /* DNBArchImpl.cpp */; }; - 266B5ED11460A68200E43F0A /* DNBArchImplARM64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266B5ECF1460A68200E43F0A /* DNBArchImplARM64.cpp */; }; - 456F67691AD46CE9002850C2 /* DNBArchImplARM64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266B5ECF1460A68200E43F0A /* DNBArchImplARM64.cpp */; }; - 26CE05C0115C364F0022F371 /* DNBArchImplI386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637EA0C71334A0024798E /* DNBArchImplI386.cpp */; }; - 456F675F1AD46CE9002850C2 /* DNBArchImplI386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637EA0C71334A0024798E /* DNBArchImplI386.cpp */; }; - 26CE05BF115C364D0022F371 /* DNBArchImplX86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26CF99A21142EB7400011AAB /* DNBArchImplX86_64.cpp */; }; - 456F675E1AD46CE9002850C2 /* DNBArchImplX86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26CF99A21142EB7400011AAB /* DNBArchImplX86_64.cpp */; }; - 26CE05B8115C363C0022F371 /* DNBBreakpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637D90C71334A0024798E /* DNBBreakpoint.cpp */; }; - 456F67571AD46CE9002850C2 /* DNBBreakpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637D90C71334A0024798E /* DNBBreakpoint.cpp */; }; - 26CE05B9115C363D0022F371 /* DNBDataRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637DB0C71334A0024798E /* DNBDataRef.cpp */; }; - 456F67581AD46CE9002850C2 /* DNBDataRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637DB0C71334A0024798E /* DNBDataRef.cpp */; }; - 26CE05A7115C360D0022F371 /* DNBError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637DE0C71334A0024798E /* DNBError.cpp */; }; - 456F67461AD46CE9002850C2 /* DNBError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637DE0C71334A0024798E /* DNBError.cpp */; }; - 26CE05BA115C363E0022F371 /* DNBLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E00C71334A0024798E /* DNBLog.cpp */; }; - 456F67591AD46CE9002850C2 /* DNBLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E00C71334A0024798E /* DNBLog.cpp */; }; - 26CE05BB115C363F0022F371 /* DNBRegisterInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E20C71334A0024798E /* DNBRegisterInfo.cpp */; }; - 456F675A1AD46CE9002850C2 /* DNBRegisterInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E20C71334A0024798E /* DNBRegisterInfo.cpp */; }; - 26CE05A8115C36170022F371 /* DNBThreadResumeActions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260E7331114BFFE600D1DFB3 /* DNBThreadResumeActions.cpp */; }; - 456F67471AD46CE9002850C2 /* DNBThreadResumeActions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260E7331114BFFE600D1DFB3 /* DNBThreadResumeActions.cpp */; }; - 23AE72E41D25DECF00945BCE /* DarwinLogCollector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AE72E21D25DECF00945BCE /* DarwinLogCollector.cpp */; }; - 23AE72E51D25DEE100945BCE /* DarwinLogCollector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AE72E21D25DECF00945BCE /* DarwinLogCollector.cpp */; }; - 49D404621E39260F00570CDC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49D404611E39260F00570CDC /* Foundation.framework */; }; - AFA3FCA11E39984900218D5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49D404611E39260F00570CDC /* Foundation.framework */; }; - 456F67561AD46CE9002850C2 /* Genealogy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFEC3363194A8B0B00FF05C6 /* Genealogy.cpp */; }; - AFEC3364194A8B0B00FF05C6 /* Genealogy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFEC3363194A8B0B00FF05C6 /* Genealogy.cpp */; }; 23043C9D1D35DBEC00FC25CA /* JSON.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B4EA51D2DB54300E98261 /* JSON.cpp */; }; + 23043C9E1D35DBFA00FC25CA /* StringConvert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B4EA81D2DB96A00E98261 /* StringConvert.cpp */; }; + 2307CCCB1D4A5D630016ABC0 /* LogFilterExactMatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 237821AE1D4917D20028B7A1 /* LogFilterExactMatch.cpp */; }; 233B4EA71D2DB54300E98261 /* JSON.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B4EA51D2DB54300E98261 /* JSON.cpp */; }; + 233B4EA91D2DB96A00E98261 /* StringConvert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B4EA81D2DB96A00E98261 /* StringConvert.cpp */; }; + 23562ED21D3424DF00AB2BD4 /* LogMessageOsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED01D3424DF00AB2BD4 /* LogMessageOsLog.cpp */; }; + 23562ED31D3424DF00AB2BD4 /* LogMessageOsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED01D3424DF00AB2BD4 /* LogMessageOsLog.cpp */; }; + 23562ED61D342A5A00AB2BD4 /* ActivityStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED51D342A5A00AB2BD4 /* ActivityStore.cpp */; }; + 23562ED71D342A5A00AB2BD4 /* ActivityStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED51D342A5A00AB2BD4 /* ActivityStore.cpp */; }; + 23562ED91D342B0000AB2BD4 /* LogMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED81D342B0000AB2BD4 /* LogMessage.cpp */; }; + 23562EDA1D342B0000AB2BD4 /* LogMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED81D342B0000AB2BD4 /* LogMessage.cpp */; }; + 237821B01D4917D20028B7A1 /* LogFilterExactMatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 237821AE1D4917D20028B7A1 /* LogFilterExactMatch.cpp */; }; 23AC04C61D2F41A00072351D /* LogFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04C41D2F41A00072351D /* LogFilter.cpp */; }; 23AC04C71D2F41A00072351D /* LogFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04C41D2F41A00072351D /* LogFilter.cpp */; }; 23AC04CA1D2F42250072351D /* LogFilterChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04C81D2F42250072351D /* LogFilterChain.cpp */; }; 23AC04CB1D2F42250072351D /* LogFilterChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04C81D2F42250072351D /* LogFilterChain.cpp */; }; - 2307CCCB1D4A5D630016ABC0 /* LogFilterExactMatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 237821AE1D4917D20028B7A1 /* LogFilterExactMatch.cpp */; }; - 237821B01D4917D20028B7A1 /* LogFilterExactMatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 237821AE1D4917D20028B7A1 /* LogFilterExactMatch.cpp */; }; 23AC04CF1D2F58AF0072351D /* LogFilterRegex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04CD1D2F58AF0072351D /* LogFilterRegex.cpp */; }; 23AC04D01D2F58AF0072351D /* LogFilterRegex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04CD1D2F58AF0072351D /* LogFilterRegex.cpp */; }; - 23562ED91D342B0000AB2BD4 /* LogMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED81D342B0000AB2BD4 /* LogMessage.cpp */; }; - 23562EDA1D342B0000AB2BD4 /* LogMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED81D342B0000AB2BD4 /* LogMessage.cpp */; }; - 23562ED21D3424DF00AB2BD4 /* LogMessageOsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED01D3424DF00AB2BD4 /* LogMessageOsLog.cpp */; }; - 23562ED31D3424DF00AB2BD4 /* LogMessageOsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED01D3424DF00AB2BD4 /* LogMessageOsLog.cpp */; }; + 23AE72E41D25DECF00945BCE /* DarwinLogCollector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AE72E21D25DECF00945BCE /* DarwinLogCollector.cpp */; }; + 23AE72E51D25DEE100945BCE /* DarwinLogCollector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AE72E21D25DECF00945BCE /* DarwinLogCollector.cpp */; }; + 23D1B0291D497E8B00FF831B /* OsLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23D1B0271D497E8B00FF831B /* OsLogger.cpp */; }; + 23D1B02A1D497E8B00FF831B /* OsLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23D1B0271D497E8B00FF831B /* OsLogger.cpp */; }; + 264D5D581293835600ED4C01 /* DNBArch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264D5D571293835600ED4C01 /* DNBArch.cpp */; }; + 266B5ED11460A68200E43F0A /* DNBArchImplARM64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266B5ECF1460A68200E43F0A /* DNBArchImplARM64.cpp */; }; + 26CE05A7115C360D0022F371 /* DNBError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637DE0C71334A0024798E /* DNBError.cpp */; }; + 26CE05A8115C36170022F371 /* DNBThreadResumeActions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260E7331114BFFE600D1DFB3 /* DNBThreadResumeActions.cpp */; }; + 26CE05A9115C36250022F371 /* debugserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A02918114AB9240029C479 /* debugserver.cpp */; }; + 26CE05AA115C36260022F371 /* RNBContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A68F7E0D104EC800665A9E /* RNBContext.cpp */; }; + 26CE05AB115C36270022F371 /* RNBServices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EF8878A00D9C797C001831DA /* RNBServices.cpp */; }; + 26CE05AC115C36280022F371 /* RNBSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A68FB00D1054DA00665A9E /* RNBSocket.cpp */; }; + 26CE05AD115C36280022F371 /* RNBRemote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A68FD60D10574500665A9E /* RNBRemote.cpp */; }; + 26CE05AE115C36320022F371 /* dbgnub-mig.defs in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E80C71334A0024798E /* dbgnub-mig.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; }; 26CE05B0115C36340022F371 /* MachException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637EE0C71334A0024798E /* MachException.cpp */; }; - 456F674E1AD46CE9002850C2 /* MachException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637EE0C71334A0024798E /* MachException.cpp */; }; 26CE05B1115C36350022F371 /* MachProcess.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F00C71334A0024798E /* MachProcess.mm */; }; - 456F674F1AD46CE9002850C2 /* MachProcess.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F00C71334A0024798E /* MachProcess.mm */; }; - 26CE05B6115C36390022F371 /* MachTask.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26B67DE10EE9BC30006C8BC0 /* MachTask.mm */; }; - 456F67541AD46CE9002850C2 /* MachTask.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26B67DE10EE9BC30006C8BC0 /* MachTask.mm */; }; 26CE05B2115C36360022F371 /* MachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F20C71334A0024798E /* MachThread.cpp */; }; - 456F67501AD46CE9002850C2 /* MachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F20C71334A0024798E /* MachThread.cpp */; }; 26CE05B3115C36370022F371 /* MachThreadList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F40C71334A0024798E /* MachThreadList.cpp */; }; - 456F67511AD46CE9002850C2 /* MachThreadList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F40C71334A0024798E /* MachThreadList.cpp */; }; 26CE05B4115C36380022F371 /* MachVMMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F60C71334A0024798E /* MachVMMemory.cpp */; }; - 456F67521AD46CE9002850C2 /* MachVMMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F60C71334A0024798E /* MachVMMemory.cpp */; }; 26CE05B5115C36380022F371 /* MachVMRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F80C71334A0024798E /* MachVMRegion.cpp */; }; - 456F67531AD46CE9002850C2 /* MachVMRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F80C71334A0024798E /* MachVMRegion.cpp */; }; - 23D1B0291D497E8B00FF831B /* OsLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23D1B0271D497E8B00FF831B /* OsLogger.cpp */; }; - 23D1B02A1D497E8B00FF831B /* OsLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23D1B0271D497E8B00FF831B /* OsLogger.cpp */; }; + 26CE05B6115C36390022F371 /* MachTask.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26B67DE10EE9BC30006C8BC0 /* MachTask.mm */; }; + 26CE05B7115C363B0022F371 /* DNB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637D60C71334A0024798E /* DNB.cpp */; }; + 26CE05B8115C363C0022F371 /* DNBBreakpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637D90C71334A0024798E /* DNBBreakpoint.cpp */; }; + 26CE05B9115C363D0022F371 /* DNBDataRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637DB0C71334A0024798E /* DNBDataRef.cpp */; }; + 26CE05BA115C363E0022F371 /* DNBLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E00C71334A0024798E /* DNBLog.cpp */; }; + 26CE05BB115C363F0022F371 /* DNBRegisterInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E20C71334A0024798E /* DNBRegisterInfo.cpp */; }; 26CE05BC115C36420022F371 /* PThreadEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637FE0C71334A0024798E /* PThreadEvent.cpp */; }; - 456F675B1AD46CE9002850C2 /* PThreadEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637FE0C71334A0024798E /* PThreadEvent.cpp */; }; 26CE05BD115C36430022F371 /* PThreadMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2672DBEE0EEF446700E92059 /* PThreadMutex.cpp */; }; - 456F675C1AD46CE9002850C2 /* PThreadMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2672DBEE0EEF446700E92059 /* PThreadMutex.cpp */; }; + 26CE05BE115C36440022F371 /* SysSignal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C638010C71334A0024798E /* SysSignal.cpp */; }; + 26CE05BF115C364D0022F371 /* DNBArchImplX86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26CF99A21142EB7400011AAB /* DNBArchImplX86_64.cpp */; }; + 26CE05C0115C364F0022F371 /* DNBArchImplI386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637EA0C71334A0024798E /* DNBArchImplI386.cpp */; }; + 26CE05C1115C36510022F371 /* DNBArchImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2675D4220CCEB705000F49AF /* DNBArchImpl.cpp */; }; + 26CE05C3115C36580022F371 /* CFString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD9B0D3EC160007E4CA2 /* CFString.cpp */; }; + 26CE05C5115C36590022F371 /* CFBundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD910D3EBFF6007E4CA2 /* CFBundle.cpp */; }; + 26CE05CF115C36F70022F371 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26ACA3340D3E956300A2120B /* CoreFoundation.framework */; settings = {ATTRIBUTES = (Required, ); }; }; 26CE05F1115C387C0022F371 /* PseudoTerminal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */; }; - 456F67651AD46CE9002850C2 /* PseudoTerminal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */; }; - 26CE05AA115C36260022F371 /* RNBContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A68F7E0D104EC800665A9E /* RNBContext.cpp */; }; + 456F67461AD46CE9002850C2 /* DNBError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637DE0C71334A0024798E /* DNBError.cpp */; }; + 456F67471AD46CE9002850C2 /* DNBThreadResumeActions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260E7331114BFFE600D1DFB3 /* DNBThreadResumeActions.cpp */; }; + 456F67481AD46CE9002850C2 /* debugserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A02918114AB9240029C479 /* debugserver.cpp */; }; 456F67491AD46CE9002850C2 /* RNBContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A68F7E0D104EC800665A9E /* RNBContext.cpp */; }; - 26CE05AD115C36280022F371 /* RNBRemote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A68FD60D10574500665A9E /* RNBRemote.cpp */; }; - 456F674C1AD46CE9002850C2 /* RNBRemote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A68FD60D10574500665A9E /* RNBRemote.cpp */; }; - 26CE05AB115C36270022F371 /* RNBServices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EF8878A00D9C797C001831DA /* RNBServices.cpp */; }; 456F674A1AD46CE9002850C2 /* RNBServices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EF8878A00D9C797C001831DA /* RNBServices.cpp */; }; - 26CE05AC115C36280022F371 /* RNBSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A68FB00D1054DA00665A9E /* RNBSocket.cpp */; }; 456F674B1AD46CE9002850C2 /* RNBSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A68FB00D1054DA00665A9E /* RNBSocket.cpp */; }; - AF588449206077BD00A0CB5A /* SocketAddress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D6631CA81E848FE9006A7B11 /* SocketAddress.cpp */; }; - D6631CA91E848FE9006A7B11 /* SocketAddress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D6631CA81E848FE9006A7B11 /* SocketAddress.cpp */; }; + 456F674C1AD46CE9002850C2 /* RNBRemote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A68FD60D10574500665A9E /* RNBRemote.cpp */; }; + 456F674D1AD46CE9002850C2 /* dbgnub-mig.defs in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E80C71334A0024798E /* dbgnub-mig.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; }; + 456F674E1AD46CE9002850C2 /* MachException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637EE0C71334A0024798E /* MachException.cpp */; }; + 456F674F1AD46CE9002850C2 /* MachProcess.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F00C71334A0024798E /* MachProcess.mm */; }; + 456F67501AD46CE9002850C2 /* MachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F20C71334A0024798E /* MachThread.cpp */; }; + 456F67511AD46CE9002850C2 /* MachThreadList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F40C71334A0024798E /* MachThreadList.cpp */; }; + 456F67521AD46CE9002850C2 /* MachVMMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F60C71334A0024798E /* MachVMMemory.cpp */; }; + 456F67531AD46CE9002850C2 /* MachVMRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F80C71334A0024798E /* MachVMRegion.cpp */; }; + 456F67541AD46CE9002850C2 /* MachTask.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26B67DE10EE9BC30006C8BC0 /* MachTask.mm */; }; + 456F67551AD46CE9002850C2 /* DNB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637D60C71334A0024798E /* DNB.cpp */; }; + 456F67561AD46CE9002850C2 /* Genealogy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFEC3363194A8B0B00FF05C6 /* Genealogy.cpp */; }; + 456F67571AD46CE9002850C2 /* DNBBreakpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637D90C71334A0024798E /* DNBBreakpoint.cpp */; }; + 456F67581AD46CE9002850C2 /* DNBDataRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637DB0C71334A0024798E /* DNBDataRef.cpp */; }; + 456F67591AD46CE9002850C2 /* DNBLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E00C71334A0024798E /* DNBLog.cpp */; }; + 456F675A1AD46CE9002850C2 /* DNBRegisterInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E20C71334A0024798E /* DNBRegisterInfo.cpp */; }; + 456F675B1AD46CE9002850C2 /* PThreadEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637FE0C71334A0024798E /* PThreadEvent.cpp */; }; + 456F675C1AD46CE9002850C2 /* PThreadMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2672DBEE0EEF446700E92059 /* PThreadMutex.cpp */; }; + 456F675D1AD46CE9002850C2 /* SysSignal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C638010C71334A0024798E /* SysSignal.cpp */; }; + 456F675E1AD46CE9002850C2 /* DNBArchImplX86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26CF99A21142EB7400011AAB /* DNBArchImplX86_64.cpp */; }; + 456F675F1AD46CE9002850C2 /* DNBArchImplI386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637EA0C71334A0024798E /* DNBArchImplI386.cpp */; }; + 456F67601AD46CE9002850C2 /* DNBArchImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2675D4220CCEB705000F49AF /* DNBArchImpl.cpp */; }; + 456F67621AD46CE9002850C2 /* CFString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD9B0D3EC160007E4CA2 /* CFString.cpp */; }; + 456F67641AD46CE9002850C2 /* CFBundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD910D3EBFF6007E4CA2 /* CFBundle.cpp */; }; + 456F67651AD46CE9002850C2 /* PseudoTerminal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */; }; + 456F67671AD46CE9002850C2 /* DNBArch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264D5D571293835600ED4C01 /* DNBArch.cpp */; }; + 456F67691AD46CE9002850C2 /* DNBArchImplARM64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266B5ECF1460A68200E43F0A /* DNBArchImplARM64.cpp */; }; + 456F676B1AD46CE9002850C2 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26ACA3340D3E956300A2120B /* CoreFoundation.framework */; settings = {ATTRIBUTES = (Required, ); }; }; + 49D404621E39260F00570CDC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49D404611E39260F00570CDC /* Foundation.framework */; }; AF48558C1D75126800D19C07 /* StdStringExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF48558B1D75126800D19C07 /* StdStringExtractor.cpp */; }; AF48558D1D75127500D19C07 /* StdStringExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF48558B1D75126800D19C07 /* StdStringExtractor.cpp */; }; - 23043C9E1D35DBFA00FC25CA /* StringConvert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B4EA81D2DB96A00E98261 /* StringConvert.cpp */; }; - 233B4EA91D2DB96A00E98261 /* StringConvert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B4EA81D2DB96A00E98261 /* StringConvert.cpp */; }; - 26CE05BE115C36440022F371 /* SysSignal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C638010C71334A0024798E /* SysSignal.cpp */; }; - 456F675D1AD46CE9002850C2 /* SysSignal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C638010C71334A0024798E /* SysSignal.cpp */; }; - 26CE05AE115C36320022F371 /* dbgnub-mig.defs in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E80C71334A0024798E /* dbgnub-mig.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; }; - 456F674D1AD46CE9002850C2 /* dbgnub-mig.defs in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E80C71334A0024798E /* dbgnub-mig.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; }; - 26CE05A9115C36250022F371 /* debugserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A02918114AB9240029C479 /* debugserver.cpp */; }; - 456F67481AD46CE9002850C2 /* debugserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A02918114AB9240029C479 /* debugserver.cpp */; }; + AF588449206077BD00A0CB5A /* SocketAddress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D6631CA81E848FE9006A7B11 /* SocketAddress.cpp */; }; + AFA3FCA11E39984900218D5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49D404611E39260F00570CDC /* Foundation.framework */; }; + AFEC3364194A8B0B00FF05C6 /* Genealogy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFEC3363194A8B0B00FF05C6 /* Genealogy.cpp */; }; + D6631CA91E848FE9006A7B11 /* SocketAddress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D6631CA81E848FE9006A7B11 /* SocketAddress.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 23562ED51D342A5A00AB2BD4 /* ActivityStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActivityStore.cpp; sourceTree = ""; }; + 2307CCCC1D4A5DAE0016ABC0 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = ""; }; + 233B4EA51D2DB54300E98261 /* JSON.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSON.cpp; sourceTree = ""; }; + 233B4EA61D2DB54300E98261 /* JSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSON.h; sourceTree = ""; }; + 233B4EA81D2DB96A00E98261 /* StringConvert.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringConvert.cpp; path = ../../../source/Host/common/StringConvert.cpp; sourceTree = ""; }; + 23562ECF1D34110D00AB2BD4 /* DarwinLogTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DarwinLogTypes.h; sourceTree = ""; }; + 23562ED01D3424DF00AB2BD4 /* LogMessageOsLog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogMessageOsLog.cpp; sourceTree = ""; }; + 23562ED11D3424DF00AB2BD4 /* LogMessageOsLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogMessageOsLog.h; sourceTree = ""; }; 23562ED41D3426DD00AB2BD4 /* ActivityStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ActivityStore.h; sourceTree = ""; }; + 23562ED51D342A5A00AB2BD4 /* ActivityStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActivityStore.cpp; sourceTree = ""; }; + 23562ED81D342B0000AB2BD4 /* LogMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogMessage.cpp; sourceTree = ""; }; + 237821AD1D4917D20028B7A1 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = ""; }; + 237821AE1D4917D20028B7A1 /* LogFilterExactMatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogFilterExactMatch.cpp; sourceTree = ""; }; + 237821AF1D4917D20028B7A1 /* LogFilterExactMatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogFilterExactMatch.h; sourceTree = ""; }; + 23AC04C41D2F41A00072351D /* LogFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogFilter.cpp; sourceTree = ""; }; + 23AC04C51D2F41A00072351D /* LogFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogFilter.h; sourceTree = ""; }; + 23AC04C81D2F42250072351D /* LogFilterChain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogFilterChain.cpp; sourceTree = ""; }; + 23AC04C91D2F42250072351D /* LogFilterChain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogFilterChain.h; sourceTree = ""; }; + 23AC04CC1D2F42F10072351D /* DarwinLogInterfaces.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DarwinLogInterfaces.h; sourceTree = ""; }; + 23AC04CD1D2F58AF0072351D /* LogFilterRegex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogFilterRegex.cpp; sourceTree = ""; }; + 23AC04CE1D2F58AF0072351D /* LogFilterRegex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogFilterRegex.h; sourceTree = ""; }; + 23AC04D11D2F60130072351D /* LogMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LogMessage.h; sourceTree = ""; }; + 23AE72E21D25DECF00945BCE /* DarwinLogCollector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DarwinLogCollector.cpp; sourceTree = ""; }; + 23AE72E31D25DECF00945BCE /* DarwinLogCollector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DarwinLogCollector.h; sourceTree = ""; }; 23AE72E61D25DEFB00945BCE /* ActivityStreamSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ActivityStreamSPI.h; sourceTree = ""; }; + 23CF6F5E1D28A3760088ADC9 /* DarwinLogEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DarwinLogEvent.h; sourceTree = ""; }; + 23D1B0271D497E8B00FF831B /* OsLogger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OsLogger.cpp; sourceTree = ""; }; + 23D1B0281D497E8B00FF831B /* OsLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OsLogger.h; sourceTree = ""; }; + 260828DE0CBAF7F400F95054 /* DNBRuntimeAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBRuntimeAction.h; sourceTree = ""; }; + 260E7331114BFFE600D1DFB3 /* DNBThreadResumeActions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBThreadResumeActions.cpp; sourceTree = ""; }; + 260E7332114BFFE600D1DFB3 /* DNBThreadResumeActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBThreadResumeActions.h; sourceTree = ""; }; + 260FC7320E5B290400043FC9 /* debugnub-exports */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "debugnub-exports"; sourceTree = SOURCE_ROOT; }; + 26203D1C1641EFB200A662F7 /* com.apple.debugserver.applist.internal.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.applist.internal.plist; sourceTree = ""; }; + 26203D1D1641EFB200A662F7 /* com.apple.debugserver.internal.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.internal.plist; sourceTree = ""; }; + 26242C390DDBD33C0054A4CC /* debugserver-entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "debugserver-entitlements.plist"; sourceTree = ""; }; + 264D5D571293835600ED4C01 /* DNBArch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArch.cpp; sourceTree = ""; }; + 264F679A1B2F9EB200140093 /* JSONGenerator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSONGenerator.h; sourceTree = ""; }; + 26593A060D4931CC001C9FE3 /* ChangeLog */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ChangeLog; sourceTree = ""; }; + 266B5ECF1460A68200E43F0A /* DNBArchImplARM64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArchImplARM64.cpp; sourceTree = ""; }; + 266B5ED01460A68200E43F0A /* DNBArchImplARM64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBArchImplARM64.h; sourceTree = ""; }; + 2672DBEE0EEF446700E92059 /* PThreadMutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PThreadMutex.cpp; sourceTree = ""; }; + 2675D4220CCEB705000F49AF /* DNBArchImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DNBArchImpl.cpp; path = arm/DNBArchImpl.cpp; sourceTree = ""; }; + 2675D4230CCEB705000F49AF /* DNBArchImpl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DNBArchImpl.h; path = arm/DNBArchImpl.h; sourceTree = ""; }; 2695DD910D3EBFF6007E4CA2 /* CFBundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CFBundle.cpp; sourceTree = ""; }; 2695DD920D3EBFF6007E4CA2 /* CFBundle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFBundle.h; sourceTree = ""; }; - 2695DD9B0D3EC160007E4CA2 /* CFString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CFString.cpp; sourceTree = ""; }; 2695DD9A0D3EC160007E4CA2 /* CFString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFString.h; sourceTree = ""; }; - 26C637E70C71334A0024798E /* CFUtils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CFUtils.h; sourceTree = ""; }; - 2307CCCC1D4A5DAE0016ABC0 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = ""; }; - 237821AD1D4917D20028B7A1 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = ""; }; - 26593A060D4931CC001C9FE3 /* ChangeLog */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ChangeLog; sourceTree = ""; }; + 2695DD9B0D3EC160007E4CA2 /* CFString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CFString.cpp; sourceTree = ""; }; + 269E8DF8164B2ED200AD65F6 /* com.apple.debugserver.posix.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.posix.plist; sourceTree = ""; }; + 26A02918114AB9240029C479 /* debugserver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debugserver.cpp; sourceTree = ""; }; + 26A4BAED0D498B7D00A9BEAB /* com.apple.debugserver.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.plist; sourceTree = ""; }; + 26A68F7D0D104EC800665A9E /* RNBContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBContext.h; sourceTree = ""; }; + 26A68F7E0D104EC800665A9E /* RNBContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RNBContext.cpp; sourceTree = ""; }; + 26A68FAF0D1054DA00665A9E /* RNBSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBSocket.h; sourceTree = ""; }; + 26A68FB00D1054DA00665A9E /* RNBSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RNBSocket.cpp; sourceTree = ""; }; + 26A68FD50D10574500665A9E /* RNBRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBRemote.h; sourceTree = ""; }; + 26A68FD60D10574500665A9E /* RNBRemote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RNBRemote.cpp; sourceTree = ""; }; + 26A8FE1E0D11A77B00203048 /* DNBTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBTimer.h; sourceTree = ""; }; 26ACA3340D3E956300A2120B /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; + 26B67DE00EE9BC30006C8BC0 /* MachTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachTask.h; sourceTree = ""; }; + 26B67DE10EE9BC30006C8BC0 /* MachTask.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MachTask.mm; sourceTree = ""; }; 26C637D60C71334A0024798E /* DNB.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DNB.cpp; sourceTree = ""; }; 26C637D70C71334A0024798E /* DNB.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNB.h; sourceTree = ""; }; - 264D5D571293835600ED4C01 /* DNBArch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArch.cpp; sourceTree = ""; }; 26C637D80C71334A0024798E /* DNBArch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNBArch.h; sourceTree = ""; }; - 2675D4220CCEB705000F49AF /* DNBArchImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DNBArchImpl.cpp; path = arm/DNBArchImpl.cpp; sourceTree = ""; }; - 26C637FB0C71334A0024798E /* DNBArchImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArchImpl.cpp; sourceTree = ""; }; - 2675D4230CCEB705000F49AF /* DNBArchImpl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DNBArchImpl.h; path = arm/DNBArchImpl.h; sourceTree = ""; }; - 26C637FC0C71334A0024798E /* DNBArchImpl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNBArchImpl.h; sourceTree = ""; }; - 266B5ECF1460A68200E43F0A /* DNBArchImplARM64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArchImplARM64.cpp; sourceTree = ""; }; - 266B5ED01460A68200E43F0A /* DNBArchImplARM64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBArchImplARM64.h; sourceTree = ""; }; - 26C637EA0C71334A0024798E /* DNBArchImplI386.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArchImplI386.cpp; sourceTree = ""; }; - 26C637EB0C71334A0024798E /* DNBArchImplI386.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNBArchImplI386.h; sourceTree = ""; }; - 26CF99A21142EB7400011AAB /* DNBArchImplX86_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArchImplX86_64.cpp; sourceTree = ""; }; - 26CF99A31142EB7400011AAB /* DNBArchImplX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBArchImplX86_64.h; sourceTree = ""; }; 26C637D90C71334A0024798E /* DNBBreakpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DNBBreakpoint.cpp; sourceTree = ""; }; 26C637DA0C71334A0024798E /* DNBBreakpoint.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNBBreakpoint.h; sourceTree = ""; }; 26C637DB0C71334A0024798E /* DNBDataRef.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DNBDataRef.cpp; sourceTree = ""; }; @@ -143,42 +177,14 @@ 26C637E10C71334A0024798E /* DNBLog.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNBLog.h; sourceTree = ""; }; 26C637E20C71334A0024798E /* DNBRegisterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DNBRegisterInfo.cpp; sourceTree = ""; }; 26C637E30C71334A0024798E /* DNBRegisterInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNBRegisterInfo.h; sourceTree = ""; }; - 260828DE0CBAF7F400F95054 /* DNBRuntimeAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBRuntimeAction.h; sourceTree = ""; }; - 260E7331114BFFE600D1DFB3 /* DNBThreadResumeActions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBThreadResumeActions.cpp; sourceTree = ""; }; - 260E7332114BFFE600D1DFB3 /* DNBThreadResumeActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBThreadResumeActions.h; sourceTree = ""; }; - 26A8FE1E0D11A77B00203048 /* DNBTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBTimer.h; sourceTree = ""; }; - 23AE72E21D25DECF00945BCE /* DarwinLogCollector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DarwinLogCollector.cpp; sourceTree = ""; }; - 23AE72E31D25DECF00945BCE /* DarwinLogCollector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DarwinLogCollector.h; sourceTree = ""; }; - 23CF6F5E1D28A3760088ADC9 /* DarwinLogEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DarwinLogEvent.h; sourceTree = ""; }; - 23AC04CC1D2F42F10072351D /* DarwinLogInterfaces.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DarwinLogInterfaces.h; sourceTree = ""; }; - 23562ECF1D34110D00AB2BD4 /* DarwinLogTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DarwinLogTypes.h; sourceTree = ""; }; - 49D404611E39260F00570CDC /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - AFEC3363194A8B0B00FF05C6 /* Genealogy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Genealogy.cpp; sourceTree = ""; }; - AF0934BA18E12B92005A11FD /* Genealogy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Genealogy.h; sourceTree = ""; }; - AF0934BB18E12B92005A11FD /* GenealogySPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenealogySPI.h; sourceTree = ""; }; - 233B4EA51D2DB54300E98261 /* JSON.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSON.cpp; sourceTree = ""; }; - 233B4EA61D2DB54300E98261 /* JSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSON.h; sourceTree = ""; }; - 264F679A1B2F9EB200140093 /* JSONGenerator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSONGenerator.h; sourceTree = ""; }; - 23AC04C41D2F41A00072351D /* LogFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogFilter.cpp; sourceTree = ""; }; - 23AC04C51D2F41A00072351D /* LogFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogFilter.h; sourceTree = ""; }; - 23AC04C81D2F42250072351D /* LogFilterChain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogFilterChain.cpp; sourceTree = ""; }; - 23AC04C91D2F42250072351D /* LogFilterChain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogFilterChain.h; sourceTree = ""; }; - 237821AE1D4917D20028B7A1 /* LogFilterExactMatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogFilterExactMatch.cpp; sourceTree = ""; }; - 237821AF1D4917D20028B7A1 /* LogFilterExactMatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogFilterExactMatch.h; sourceTree = ""; }; - 23AC04CD1D2F58AF0072351D /* LogFilterRegex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogFilterRegex.cpp; sourceTree = ""; }; - 23AC04CE1D2F58AF0072351D /* LogFilterRegex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogFilterRegex.h; sourceTree = ""; }; - 23562ED81D342B0000AB2BD4 /* LogMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogMessage.cpp; sourceTree = ""; }; - 23AC04D11D2F60130072351D /* LogMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LogMessage.h; sourceTree = ""; }; - 23562ED01D3424DF00AB2BD4 /* LogMessageOsLog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogMessageOsLog.cpp; sourceTree = ""; }; - 23562ED11D3424DF00AB2BD4 /* LogMessageOsLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogMessageOsLog.h; sourceTree = ""; }; + 26C637E70C71334A0024798E /* CFUtils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CFUtils.h; sourceTree = ""; }; + 26C637E80C71334A0024798E /* dbgnub-mig.defs */ = {isa = PBXFileReference; explicitFileType = sourcecode.mig; fileEncoding = 30; path = "dbgnub-mig.defs"; sourceTree = ""; }; + 26C637EA0C71334A0024798E /* DNBArchImplI386.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArchImplI386.cpp; sourceTree = ""; }; + 26C637EB0C71334A0024798E /* DNBArchImplI386.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNBArchImplI386.h; sourceTree = ""; }; 26C637EE0C71334A0024798E /* MachException.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MachException.cpp; sourceTree = ""; }; 26C637EF0C71334A0024798E /* MachException.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachException.h; sourceTree = ""; }; - 26C637F10C71334A0024798E /* MachProcess.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachProcess.h; sourceTree = ""; }; 26C637F00C71334A0024798E /* MachProcess.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = MachProcess.mm; sourceTree = ""; }; - 49F530111331519C008956F6 /* MachRegisterStatesI386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachRegisterStatesI386.h; sourceTree = ""; }; - 49F5301213316D7F008956F6 /* MachRegisterStatesX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachRegisterStatesX86_64.h; sourceTree = ""; }; - 26B67DE00EE9BC30006C8BC0 /* MachTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachTask.h; sourceTree = ""; }; - 26B67DE10EE9BC30006C8BC0 /* MachTask.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MachTask.mm; sourceTree = ""; }; + 26C637F10C71334A0024798E /* MachProcess.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachProcess.h; sourceTree = ""; }; 26C637F20C71334A0024798E /* MachThread.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MachThread.cpp; sourceTree = ""; }; 26C637F30C71334A0024798E /* MachThread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachThread.h; sourceTree = ""; }; 26C637F40C71334A0024798E /* MachThreadList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MachThreadList.cpp; sourceTree = ""; }; @@ -187,45 +193,35 @@ 26C637F70C71334A0024798E /* MachVMMemory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachVMMemory.h; sourceTree = ""; }; 26C637F80C71334A0024798E /* MachVMRegion.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MachVMRegion.cpp; sourceTree = ""; }; 26C637F90C71334A0024798E /* MachVMRegion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachVMRegion.h; sourceTree = ""; }; - 23D1B0271D497E8B00FF831B /* OsLogger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OsLogger.cpp; sourceTree = ""; }; - 23D1B0281D497E8B00FF831B /* OsLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OsLogger.h; sourceTree = ""; }; 26C637FD0C71334A0024798E /* PThreadCondition.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PThreadCondition.h; sourceTree = ""; }; 26C637FE0C71334A0024798E /* PThreadEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PThreadEvent.cpp; sourceTree = ""; }; 26C637FF0C71334A0024798E /* PThreadEvent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PThreadEvent.h; sourceTree = ""; }; - 2672DBEE0EEF446700E92059 /* PThreadMutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PThreadMutex.cpp; sourceTree = ""; }; 26C638000C71334A0024798E /* PThreadMutex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PThreadMutex.h; sourceTree = ""; }; - AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PseudoTerminal.cpp; sourceTree = ""; }; - AF67AC000D34604D0022D128 /* PseudoTerminal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PseudoTerminal.h; sourceTree = ""; }; - 26A68F7E0D104EC800665A9E /* RNBContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RNBContext.cpp; sourceTree = ""; }; - 26A68F7D0D104EC800665A9E /* RNBContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBContext.h; sourceTree = ""; }; - 26E6B9DA0D1329010037ECDD /* RNBDefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBDefs.h; sourceTree = ""; }; - 26A68FD60D10574500665A9E /* RNBRemote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RNBRemote.cpp; sourceTree = ""; }; - 26A68FD50D10574500665A9E /* RNBRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBRemote.h; sourceTree = ""; }; - EF8878A00D9C797C001831DA /* RNBServices.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RNBServices.cpp; sourceTree = ""; }; - EF88789F0D9C797C001831DA /* RNBServices.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBServices.h; sourceTree = ""; }; - 26A68FB00D1054DA00665A9E /* RNBSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RNBSocket.cpp; sourceTree = ""; }; - 26A68FAF0D1054DA00665A9E /* RNBSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBSocket.h; sourceTree = ""; }; - D6631CA81E848FE9006A7B11 /* SocketAddress.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SocketAddress.cpp; path = ../../source/Host/common/SocketAddress.cpp; sourceTree = ""; }; - AF48558B1D75126800D19C07 /* StdStringExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StdStringExtractor.cpp; sourceTree = ""; }; - 233B4EA81D2DB96A00E98261 /* StringConvert.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringConvert.cpp; path = ../../../source/Host/common/StringConvert.cpp; sourceTree = ""; }; 26C638010C71334A0024798E /* SysSignal.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SysSignal.cpp; sourceTree = ""; }; 26C638020C71334A0024798E /* SysSignal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SysSignal.h; sourceTree = ""; }; 26C638050C71334A0024798E /* TTYState.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TTYState.cpp; sourceTree = ""; }; 26C638060C71334A0024798E /* TTYState.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TTYState.h; sourceTree = ""; }; - 26203D1C1641EFB200A662F7 /* com.apple.debugserver.applist.internal.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.applist.internal.plist; sourceTree = ""; }; - EF88788B0D9C7558001831DA /* com.apple.debugserver.applist.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.applist.plist; sourceTree = ""; }; - 26203D1D1641EFB200A662F7 /* com.apple.debugserver.internal.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.internal.plist; sourceTree = ""; }; - 26A4BAED0D498B7D00A9BEAB /* com.apple.debugserver.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.plist; sourceTree = ""; }; - 269E8DF8164B2ED200AD65F6 /* com.apple.debugserver.posix.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.posix.plist; sourceTree = ""; }; - AF949ED620605DC2002A91F9 /* com.apple.internal.xpc.remote.debugserver.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = com.apple.internal.xpc.remote.debugserver.plist; sourceTree = ""; }; - 26C637E80C71334A0024798E /* dbgnub-mig.defs */ = {isa = PBXFileReference; explicitFileType = sourcecode.mig; fileEncoding = 30; path = "dbgnub-mig.defs"; sourceTree = ""; }; - 260FC7320E5B290400043FC9 /* debugnub-exports */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "debugnub-exports"; sourceTree = SOURCE_ROOT; }; 26CE0594115C31C20022F371 /* debugserver */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = debugserver; sourceTree = BUILT_PRODUCTS_DIR; }; - 26242C390DDBD33C0054A4CC /* debugserver-entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "debugserver-entitlements.plist"; sourceTree = ""; }; - AF61C60418F75ABC00B48D9D /* debugserver-macosx-entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "debugserver-macosx-entitlements.plist"; sourceTree = ""; }; + 26CF99A21142EB7400011AAB /* DNBArchImplX86_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArchImplX86_64.cpp; sourceTree = ""; }; + 26CF99A31142EB7400011AAB /* DNBArchImplX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBArchImplX86_64.h; sourceTree = ""; }; + 26E6B9DA0D1329010037ECDD /* RNBDefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBDefs.h; sourceTree = ""; }; 456F67721AD46CE9002850C2 /* debugserver-nonui */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "debugserver-nonui"; sourceTree = BUILT_PRODUCTS_DIR; }; - 26A02918114AB9240029C479 /* debugserver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debugserver.cpp; sourceTree = ""; }; + 49D404611E39260F00570CDC /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 49F530111331519C008956F6 /* MachRegisterStatesI386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachRegisterStatesI386.h; sourceTree = ""; }; + 49F5301213316D7F008956F6 /* MachRegisterStatesX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachRegisterStatesX86_64.h; sourceTree = ""; }; 9457ECF61419864100DFE7D8 /* stack_logging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stack_logging.h; sourceTree = ""; }; + AF0934BA18E12B92005A11FD /* Genealogy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Genealogy.h; sourceTree = ""; }; + AF0934BB18E12B92005A11FD /* GenealogySPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenealogySPI.h; sourceTree = ""; }; + AF48558B1D75126800D19C07 /* StdStringExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StdStringExtractor.cpp; sourceTree = ""; }; + AF61C60418F75ABC00B48D9D /* debugserver-macosx-entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "debugserver-macosx-entitlements.plist"; sourceTree = ""; }; + AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PseudoTerminal.cpp; sourceTree = ""; }; + AF67AC000D34604D0022D128 /* PseudoTerminal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PseudoTerminal.h; sourceTree = ""; }; + AF949ED620605DC2002A91F9 /* com.apple.internal.xpc.remote.debugserver.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = com.apple.internal.xpc.remote.debugserver.plist; sourceTree = ""; }; + AFEC3363194A8B0B00FF05C6 /* Genealogy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Genealogy.cpp; sourceTree = ""; }; + D6631CA81E848FE9006A7B11 /* SocketAddress.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SocketAddress.cpp; path = ../../source/Host/common/SocketAddress.cpp; sourceTree = ""; }; + EF88788B0D9C7558001831DA /* com.apple.debugserver.applist.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.applist.plist; sourceTree = ""; }; + EF88789F0D9C797C001831DA /* RNBServices.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBServices.h; sourceTree = ""; }; + EF8878A00D9C797C001831DA /* RNBServices.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RNBServices.cpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -409,7 +405,6 @@ 2675D41C0CCEB6CF000F49AF /* arm */, 266B5ECE1460A68200E43F0A /* arm64 */, 26C637E90C71334A0024798E /* i386 */, - 26C637FA0C71334A0024798E /* ppc */, 26CF99A11142EB7400011AAB /* x86_64 */, 26C637E80C71334A0024798E /* dbgnub-mig.defs */, AFEC3363194A8B0B00FF05C6 /* Genealogy.cpp */, @@ -446,15 +441,6 @@ path = i386; sourceTree = ""; }; - 26C637FA0C71334A0024798E /* ppc */ = { - isa = PBXGroup; - children = ( - 26C637FB0C71334A0024798E /* DNBArchImpl.cpp */, - 26C637FC0C71334A0024798E /* DNBArchImpl.h */, - ); - path = ppc; - sourceTree = ""; - }; 26CF99A11142EB7400011AAB /* x86_64 */ = { isa = PBXGroup; children = ( @@ -617,7 +603,6 @@ 26CE05BF115C364D0022F371 /* DNBArchImplX86_64.cpp in Sources */, 26CE05C0115C364F0022F371 /* DNBArchImplI386.cpp in Sources */, 26CE05C1115C36510022F371 /* DNBArchImpl.cpp in Sources */, - 26CE05C2115C36550022F371 /* DNBArchImpl.cpp in Sources */, 26CE05C5115C36590022F371 /* CFBundle.cpp in Sources */, 26CE05C3115C36580022F371 /* CFString.cpp in Sources */, 23562ED91D342B0000AB2BD4 /* LogMessage.cpp in Sources */, @@ -668,7 +653,6 @@ 456F67601AD46CE9002850C2 /* DNBArchImpl.cpp in Sources */, 23AC04C71D2F41A00072351D /* LogFilter.cpp in Sources */, 23043C9E1D35DBFA00FC25CA /* StringConvert.cpp in Sources */, - 456F67611AD46CE9002850C2 /* DNBArchImpl.cpp in Sources */, AF588449206077BD00A0CB5A /* SocketAddress.cpp in Sources */, 456F67621AD46CE9002850C2 /* CFString.cpp in Sources */, 23AC04CB1D2F42250072351D /* LogFilterChain.cpp in Sources */, @@ -863,6 +847,8 @@ "$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist", "$(LLDB_ENERGY_LDFLAGS)", "$(LLDB_COMPRESSION_LDFLAGS)", + "-framework", + Security, ); OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)"; PRODUCT_NAME = debugserver; @@ -942,6 +928,8 @@ "$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist", "$(LLDB_ENERGY_LDFLAGS)", "$(LLDB_COMPRESSION_LDFLAGS)", + "-framework", + Security, ); OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)"; PRODUCT_NAME = debugserver; @@ -1020,6 +1008,8 @@ "$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist", "$(LLDB_ENERGY_LDFLAGS)", "$(LLDB_COMPRESSION_LDFLAGS)", + "-framework", + Security, ); OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)"; PRODUCT_NAME = debugserver; @@ -1147,9 +1137,7 @@ LLDB_ENERGY_CFLAGS = ""; "LLDB_ENERGY_CFLAGS[sdk=*.internal]" = "-DLLDB_ENERGY"; LLDB_ENERGY_LDFLAGS = "-lpmenergy -lpmsample"; - OTHER_CFLAGS = ( - "$(LLDB_ENERGY_CFLAGS)", - ); + OTHER_CFLAGS = "$(LLDB_ENERGY_CFLAGS)"; "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = ( "-Wparentheses", "-DOS_OBJECT_USE_OBJC=0", diff --git a/gnu/llvm/lldb/tools/debugserver/resources/lldb-debugserver-Info.plist b/gnu/llvm/lldb/tools/debugserver/resources/lldb-debugserver-Info.plist index 343325c2765..ddaf0644f2c 100644 --- a/gnu/llvm/lldb/tools/debugserver/resources/lldb-debugserver-Info.plist +++ b/gnu/llvm/lldb/tools/debugserver/resources/lldb-debugserver-Info.plist @@ -12,10 +12,5 @@ debugserver CFBundleVersion 2 - SecTaskAccess - - allowed - debug - diff --git a/gnu/llvm/lldb/tools/debugserver/source/CMakeLists.txt b/gnu/llvm/lldb/tools/debugserver/source/CMakeLists.txt index a7d789dd9e1..b29b3ddc305 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/CMakeLists.txt +++ b/gnu/llvm/lldb/tools/debugserver/source/CMakeLists.txt @@ -41,7 +41,7 @@ function(get_debugserver_codesign_identity result) return() endif() - message(WARNING "Development code sign identiy not found: 'lldb_codesign' ${not_found_help}") + message(WARNING "Development code sign identity not found: 'lldb_codesign' ${not_found_help}") # LLVM pendant: fallback if available if(LLVM_CODESIGNING_IDENTITY) @@ -56,6 +56,10 @@ function(get_debugserver_codesign_identity result) set(${result} "-" PARENT_SCOPE) endfunction() +# debugserver does not depend on intrinsics_gen, or on llvm. Set the common +# llvm dependencies in the current scope to the empty set. +set(LLVM_COMMON_DEPENDS) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -Wl,-sectcreate,__TEXT,__info_plist,${CMAKE_CURRENT_SOURCE_DIR}/../resources/lldb-debugserver-Info.plist") check_cxx_compiler_flag("-Wno-gnu-zero-variadic-macro-arguments" @@ -78,6 +82,8 @@ endif () check_library_exists(compression compression_encode_buffer "" HAVE_LIBCOMPRESSION) +find_library(SECURITY_LIBRARY Security) + add_subdirectory(MacOSX) set(LLDB_CODESIGN_IDENTITY "" CACHE STRING @@ -123,13 +129,30 @@ if(LLDB_USE_ENTITLEMENTS) endif() endif() +if(${CMAKE_OSX_SYSROOT} MATCHES ".Internal.sdk$") + message(STATUS "LLDB debugserver energy support is enabled") + add_definitions(-DLLDB_ENERGY) + set(ENERGY_LIBRARY -lpmenergy -lpmsample) +else() + message(STATUS "LLDB debugserver energy support is disabled") +endif() + set(generated_mach_interfaces ${CMAKE_CURRENT_BINARY_DIR}/mach_exc.h ${CMAKE_CURRENT_BINARY_DIR}/mach_excServer.c ${CMAKE_CURRENT_BINARY_DIR}/mach_excUser.c ) + +set(MIG_ARCH_FLAGS "") +if (DEFINED MIG_ARCHS) + foreach(ARCH ${MIG_ARCHS}) + set(MIG_ARCH_FLAGS "${MIG_ARCH_FLAGS} -arch ${ARCH}") + endforeach() +endif() +separate_arguments(MIG_ARCH_FLAGS_SEPARTED NATIVE_COMMAND "${MIG_ARCH_FLAGS}") + add_custom_command(OUTPUT ${generated_mach_interfaces} - COMMAND mig ${CMAKE_CURRENT_SOURCE_DIR}/MacOSX/dbgnub-mig.defs + VERBATIM COMMAND mig ${MIG_ARCH_FLAGS_SEPARTED} -isysroot ${CMAKE_OSX_SYSROOT} ${CMAKE_CURRENT_SOURCE_DIR}/MacOSX/dbgnub-mig.defs DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/MacOSX/dbgnub-mig.defs ) @@ -191,7 +214,10 @@ target_link_libraries(lldbDebugserverCommon ${LOCKDOWN_LIBRARY} lldbDebugserverArchSupport lldbDebugserverDarwin_DarwinLog - ${LIBCOMPRESSION}) + ${FOUNDATION_LIBRARY} + ${SECURITY_LIBRARY} + ${LIBCOMPRESSION} + ${ENERGY_LIBRARY}) if(HAVE_LIBCOMPRESSION) set_property(TARGET lldbDebugserverCommon APPEND PROPERTY COMPILE_DEFINITIONS HAVE_LIBCOMPRESSION) @@ -254,6 +280,7 @@ if(IOS) ${FOUNDATION_LIBRARY} lldbDebugserverArchSupport lldbDebugserverDarwin_DarwinLog + ${SECURITY_LIBRARY} ${LIBCOMPRESSION}) if(HAVE_LIBCOMPRESSION) set_property(TARGET lldbDebugserverCommon_NonUI APPEND PROPERTY diff --git a/gnu/llvm/lldb/tools/debugserver/source/ChangeLog b/gnu/llvm/lldb/tools/debugserver/source/ChangeLog index 898f2fba7b0..a969e3e2429 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/ChangeLog +++ b/gnu/llvm/lldb/tools/debugserver/source/ChangeLog @@ -113,7 +113,7 @@ (RNBRemote::HandleReceivedPacket): Ditto. (RNBRemote::CommDataReceived): Ditto. * DNB.cpp (DNBProcessLaunch): Changed to take a eror string pointer with - size for more desciptive error reporting (instead of a uint32_t pointer). + size for more descriptive error reporting (instead of a uint32_t pointer). * DNB.h (DNBProcessLaunch): Ditto. * DNBError.cpp (DNBError::AsString): Now returns NULL if there is no error. * DNBError.h (DNBError::SetErrorString): New accessor to allow custom error @@ -268,10 +268,10 @@ qualifier to allow arches to auto detect how many hardware watchpoints they have. * DNBArchImpl.h (DNBArchMachARM::NumSupportedHardwareBreakpoints()): Auto - detect how many BRP pairs are avialable and disable for armv7 for the time + detect how many BRP pairs are available and disable for armv7 for the time being (rdar://problem/6372672). (DNBArchMachARM::NumSupportedHardwareWatchpoints()): Auto detect how many - WRP pairs are avialable and disable for armv7 for the time being + WRP pairs are available and disable for armv7 for the time being (rdar://problem/6372672). 2009-01-09 Greg Clayton @@ -692,7 +692,7 @@ 2008-10-17 Greg Clayton * test-remotenub.cpp (RNBRunLoopLaunchInferior): Don't listen for - the qLaunchSuccess if we aren't doing a lockdown connnection. + the qLaunchSuccess if we aren't doing a lockdown connection. 2008-10-13 Greg Clayton @@ -1154,7 +1154,7 @@ 2008-02-14 Jason Molenda (jmolenda@apple.com) * MachProcess.cpp: (MachProcess::SBForkChildForPTraceDebugging): - Set mode bits on slave side of pty. + Set mode bits on secondary side of pty. 2008-02-12 Greg Clayton diff --git a/gnu/llvm/lldb/tools/debugserver/source/DNB.cpp b/gnu/llvm/lldb/tools/debugserver/source/DNB.cpp index 8d9c691f9d3..af13a8f8208 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/DNB.cpp +++ b/gnu/llvm/lldb/tools/debugserver/source/DNB.cpp @@ -57,7 +57,6 @@ typedef std::map ProcessMap; typedef ProcessMap::iterator ProcessMapIter; typedef ProcessMap::const_iterator ProcessMapConstIter; -size_t GetAllInfos(std::vector &proc_infos); static size_t GetAllInfosMatchingName(const char *process_name, std::vector &matching_proc_infos); @@ -422,7 +421,8 @@ nub_process_t DNBProcessAttachByName(const char *name, struct timespec *timeout, if (num_matching_proc_infos == 0) { DNBLogError("error: no processes match '%s'\n", name); return INVALID_NUB_PROCESS; - } else if (num_matching_proc_infos > 1) { + } + if (num_matching_proc_infos > 1) { DNBLogError("error: %llu processes match '%s':\n", (uint64_t)num_matching_proc_infos, name); size_t i; @@ -520,7 +520,7 @@ nub_process_t DNBProcessAttach(nub_process_t attach_pid, return INVALID_NUB_PROCESS; } -size_t GetAllInfos(std::vector &proc_infos) { +size_t DNBGetAllInfos(std::vector &proc_infos) { size_t size = 0; int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL}; u_int namelen = sizeof(name) / sizeof(int); @@ -573,7 +573,7 @@ GetAllInfosMatchingName(const char *full_process_name, const size_t process_name_len = strlen(process_name); std::vector proc_infos; - const size_t num_proc_infos = GetAllInfos(proc_infos); + const size_t num_proc_infos = DNBGetAllInfos(proc_infos); if (num_proc_infos > 0) { uint32_t i; for (i = 0; i < num_proc_infos; i++) { @@ -1392,10 +1392,14 @@ const char *DNBGetDeploymentInfo(nub_process_t pid, uint32_t& minor_version, uint32_t& patch_version) { MachProcessSP procSP; - if (GetProcessSP(pid, procSP)) - return procSP->GetDeploymentInfo(lc, load_command_address, - major_version, minor_version, - patch_version); + if (GetProcessSP(pid, procSP)) { + // FIXME: This doesn't correct for older ios simulator and macCatalyst. + auto info = procSP->GetDeploymentInfo(lc, load_command_address); + major_version = info.major_version; + minor_version = info.minor_version; + patch_version = info.patch_version; + return procSP->GetPlatformString(info.platform); + } return nullptr; } diff --git a/gnu/llvm/lldb/tools/debugserver/source/DNB.h b/gnu/llvm/lldb/tools/debugserver/source/DNB.h index e29fa0fa636..e0e1cdd6d8b 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/DNB.h +++ b/gnu/llvm/lldb/tools/debugserver/source/DNB.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __DNB_h__ -#define __DNB_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_DNB_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_DNB_H #include "DNBDefs.h" #include "JSONGenerator.h" @@ -150,6 +150,7 @@ nub_size_t DNBProcessGetAvailableProfileData(nub_process_t pid, char *buf, nub_size_t buf_size) DNB_EXPORT; nub_size_t DNBProcessGetStopCount(nub_process_t pid) DNB_EXPORT; uint32_t DNBProcessGetCPUType(nub_process_t pid) DNB_EXPORT; +size_t DNBGetAllInfos(std::vector &proc_infos); // Process executable and arguments const char *DNBProcessGetExecutablePath(nub_process_t pid); diff --git a/gnu/llvm/lldb/tools/debugserver/source/DNBArch.h b/gnu/llvm/lldb/tools/debugserver/source/DNBArch.h index b5e2e25ef47..0f65df75a38 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/DNBArch.h +++ b/gnu/llvm/lldb/tools/debugserver/source/DNBArch.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __DebugNubArch_h__ -#define __DebugNubArch_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBARCH_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBARCH_H #include "DNBDefs.h" #include "MacOSX/MachException.h" @@ -78,7 +78,8 @@ public: virtual bool NotifyException(MachException::Data &exc) { return false; } virtual uint32_t NumSupportedHardwareBreakpoints() { return 0; } virtual uint32_t NumSupportedHardwareWatchpoints() { return 0; } - virtual uint32_t EnableHardwareBreakpoint(nub_addr_t addr, nub_size_t size) { + virtual uint32_t EnableHardwareBreakpoint(nub_addr_t addr, nub_size_t size, + bool also_set_on_task) { return INVALID_NUB_HW_INDEX; } virtual uint32_t EnableHardwareWatchpoint(nub_addr_t addr, nub_size_t size, @@ -86,7 +87,10 @@ public: bool also_set_on_task) { return INVALID_NUB_HW_INDEX; } - virtual bool DisableHardwareBreakpoint(uint32_t hw_index) { return false; } + virtual bool DisableHardwareBreakpoint(uint32_t hw_index, + bool also_set_on_task) { + return false; + } virtual bool DisableHardwareWatchpoint(uint32_t hw_index, bool also_set_on_task) { return false; @@ -120,7 +124,6 @@ protected: #include "MacOSX/arm/DNBArchImpl.h" #include "MacOSX/arm64/DNBArchImplARM64.h" #include "MacOSX/i386/DNBArchImplI386.h" -#include "MacOSX/ppc/DNBArchImpl.h" #include "MacOSX/x86_64/DNBArchImplX86_64.h" #endif diff --git a/gnu/llvm/lldb/tools/debugserver/source/DNBBreakpoint.h b/gnu/llvm/lldb/tools/debugserver/source/DNBBreakpoint.h index 0b4e077ae8a..318ee69043b 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/DNBBreakpoint.h +++ b/gnu/llvm/lldb/tools/debugserver/source/DNBBreakpoint.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __DNBBreakpoint_h__ -#define __DNBBreakpoint_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBBREAKPOINT_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBBREAKPOINT_H #include diff --git a/gnu/llvm/lldb/tools/debugserver/source/DNBDataRef.h b/gnu/llvm/lldb/tools/debugserver/source/DNBDataRef.h index d521700d151..4a79dc442be 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/DNBDataRef.h +++ b/gnu/llvm/lldb/tools/debugserver/source/DNBDataRef.h @@ -19,8 +19,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __DNBDataRef_h__ -#define __DNBDataRef_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBDATAREF_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBDATAREF_H #include "DNBDefs.h" #include @@ -121,4 +121,4 @@ protected: addr_t m_addrDATA; }; -#endif // #ifndef __DNBDataRef_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBDATAREF_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/DNBDefs.h b/gnu/llvm/lldb/tools/debugserver/source/DNBDefs.h index 22cfce1757f..49f8d6decb3 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/DNBDefs.h +++ b/gnu/llvm/lldb/tools/debugserver/source/DNBDefs.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __DNBDefs_h__ -#define __DNBDefs_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBDEFS_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBDEFS_H #include #include @@ -20,15 +20,13 @@ #include // Define nub_addr_t and the invalid address value from the architecture -#if defined(__x86_64__) || defined(__ppc64__) || defined(__arm64__) || \ - defined(__aarch64__) +#if defined(__x86_64__) || defined(__arm64__) || defined(__aarch64__) // 64 bit address architectures typedef uint64_t nub_addr_t; #define INVALID_NUB_ADDRESS ((nub_addr_t)~0ull) -#elif defined(__i386__) || defined(__powerpc__) || defined(__ppc__) || \ - defined(__arm__) +#elif defined(__i386__) || defined(__powerpc__) || defined(__arm__) // 32 bit address architectures @@ -360,4 +358,4 @@ typedef void (*DNBCallbackLog)(void *baton, uint32_t flags, const char *format, #define UNUSED_IF_ASSERT_DISABLED(x) ((void)(x)) -#endif // #ifndef __DNBDefs_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBDEFS_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/DNBError.h b/gnu/llvm/lldb/tools/debugserver/source/DNBError.h index 7e67cf2c553..8da3f6c1e3a 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/DNBError.h +++ b/gnu/llvm/lldb/tools/debugserver/source/DNBError.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __DNBError_h__ -#define __DNBError_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBERROR_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBERROR_H #include #include @@ -94,4 +94,4 @@ protected: mutable std::string m_str; }; -#endif // #ifndef __DNBError_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBERROR_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/DNBLog.h b/gnu/llvm/lldb/tools/debugserver/source/DNBLog.h index 47d8aeb066e..6a3e34c1383 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/DNBLog.h +++ b/gnu/llvm/lldb/tools/debugserver/source/DNBLog.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __DNBLog_h__ -#define __DNBLog_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBLOG_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBLOG_H #include "DNBDefs.h" #include @@ -149,4 +149,4 @@ void DNBLogSetVerbose(int g); } #endif -#endif // #ifndef __DNBLog_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBLOG_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/DNBRegisterInfo.h b/gnu/llvm/lldb/tools/debugserver/source/DNBRegisterInfo.h index 3aa0e03eaa1..c17ce3a7e18 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/DNBRegisterInfo.h +++ b/gnu/llvm/lldb/tools/debugserver/source/DNBRegisterInfo.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __DNBRegisterInfo_h__ -#define __DNBRegisterInfo_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBREGISTERINFO_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBREGISTERINFO_H #include "DNBDefs.h" #include diff --git a/gnu/llvm/lldb/tools/debugserver/source/DNBThreadResumeActions.h b/gnu/llvm/lldb/tools/debugserver/source/DNBThreadResumeActions.h index e2a25abca2a..2970b7636c5 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/DNBThreadResumeActions.h +++ b/gnu/llvm/lldb/tools/debugserver/source/DNBThreadResumeActions.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __DNBThreadResumeActions_h__ -#define __DNBThreadResumeActions_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBTHREADRESUMEACTIONS_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBTHREADRESUMEACTIONS_H #include @@ -62,4 +62,4 @@ protected: mutable std::vector m_signal_handled; }; -#endif // #ifndef __DNBThreadResumeActions_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBTHREADRESUMEACTIONS_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/DNBTimer.h b/gnu/llvm/lldb/tools/debugserver/source/DNBTimer.h index 21ee2351d69..80232494b5f 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/DNBTimer.h +++ b/gnu/llvm/lldb/tools/debugserver/source/DNBTimer.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __DNBTimer_h__ -#define __DNBTimer_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBTIMER_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBTIMER_H #include "DNBDefs.h" #include "PThreadMutex.h" @@ -131,4 +131,4 @@ protected: struct timeval m_timeval; }; -#endif // #ifndef __DNBTimer_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBTIMER_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/JSON.h b/gnu/llvm/lldb/tools/debugserver/source/JSON.h index 70bfdd7259a..5bcc67c18b9 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/JSON.h +++ b/gnu/llvm/lldb/tools/debugserver/source/JSON.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_JSON_h_ -#define utility_JSON_h_ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H #include "StdStringExtractor.h" @@ -299,4 +299,4 @@ protected: JSONValue::SP ParseJSONArray(); }; -#endif // utility_JSON_h_ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/JSONGenerator.h b/gnu/llvm/lldb/tools/debugserver/source/JSONGenerator.h index 70708f9a5ac..fff84946eda 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/JSONGenerator.h +++ b/gnu/llvm/lldb/tools/debugserver/source/JSONGenerator.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __JSONGenerator_h_ -#define __JSONGenerator_h_ - +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_JSONGENERATOR_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_JSONGENERATOR_H #include #include @@ -311,4 +310,4 @@ public: }; // class JSONGenerator -#endif // __JSONGenerator_h_ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_JSONGENERATOR_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/CFBundle.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/CFBundle.h index f49dc30f1f8..7e88d575c69 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/CFBundle.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/CFBundle.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __CFBundle_h__ -#define __CFBundle_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_CFBUNDLE_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_CFBUNDLE_H #include "CFUtils.h" @@ -32,4 +32,4 @@ protected: CFReleaser m_bundle_url; }; -#endif // #ifndef __CFBundle_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_CFBUNDLE_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/CFString.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/CFString.h index d1bd5682689..3cc27eea68e 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/CFString.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/CFString.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __CFString_h__ -#define __CFString_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_CFSTRING_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_CFSTRING_H #include "CFUtils.h" #include @@ -37,4 +37,4 @@ public: static const char *GlobPath(const char *path, std::string &expanded_path); }; -#endif // #ifndef __CFString_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_CFSTRING_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/CFUtils.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/CFUtils.h index b567524ce63..ef295831433 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/CFUtils.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/CFUtils.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __CFUtils_h__ -#define __CFUtils_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_CFUTILS_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_CFUTILS_H #include @@ -22,7 +22,7 @@ // explicitly released using the release() member function. template class CFReleaser { public: - // Type names for the avlue + // Type names for the value typedef T element_type; // Constructors and destructors @@ -72,4 +72,4 @@ private: }; #endif // #ifdef __cplusplus -#endif // #ifndef __CFUtils_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_CFUTILS_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/CMakeLists.txt b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/CMakeLists.txt index 73ba6492a0e..001f861d271 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/CMakeLists.txt +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/CMakeLists.txt @@ -26,11 +26,6 @@ if(NOT LLDB_DEBUGSERVER_ARCH OR "${LLDB_DEBUGSERVER_ARCH}" MATCHES ".*86.*") include_directories(${CURRENT_SOURCE_DIR}/i386 ${CURRENT_SOURCE_DIR}/x86_64) endif() -if("${LLDB_DEBUGSERVER_ARCH}" MATCHES ".*ppc.*") - list(APPEND SOURCES ppc/DNBArchImpl.cpp) - include_directories(${CURRENT_SOURCE_DIR}/ppc) -endif() - add_subdirectory(DarwinLog) include_directories(..) diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/ActivityStore.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/ActivityStore.h index b66a789592c..bc6927e82c4 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/ActivityStore.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/ActivityStore.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef ActivityStore_h -#define ActivityStore_h +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_ACTIVITYSTORE_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_ACTIVITYSTORE_H #include @@ -26,4 +26,4 @@ protected: ActivityStore(); }; -#endif /* ActivityStore_h */ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_ACTIVITYSTORE_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/ActivityStreamSPI.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/ActivityStreamSPI.h index 99721f69a2d..4492f29a341 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/ActivityStreamSPI.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/ActivityStreamSPI.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef ActivityStreamSPI_h -#define ActivityStreamSPI_h +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_ACTIVITYSTREAMSPI_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_ACTIVITYSTREAMSPI_H #include #include @@ -187,4 +187,4 @@ typedef char *(*os_log_copy_formatted_message_t)(os_log_message_t log_message); typedef void (*os_activity_stream_set_event_handler_t)( os_activity_stream_t stream, os_activity_stream_event_block_t block); -#endif /* ActivityStreamSPI_h */ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_ACTIVITYSTREAMSPI_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogCollector.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogCollector.h index 24ab4230e38..7acf9dcb4d3 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogCollector.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogCollector.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef DarwinLogCollector_h -#define DarwinLogCollector_h +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_DARWINLOGCOLLECTOR_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_DARWINLOGCOLLECTOR_H #include @@ -104,4 +104,4 @@ private: ActivityMap m_activity_map; }; -#endif /* LogStreamCollector_h */ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_DARWINLOGCOLLECTOR_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogEvent.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogEvent.h index fb142146bf8..91f8f9fb230 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogEvent.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogEvent.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef DarwinLogEvent_h -#define DarwinLogEvent_h +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_DARWINLOGEVENT_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_DARWINLOGEVENT_H #include #include diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogInterfaces.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogInterfaces.h index 2bfcb50068b..7aca6c2a066 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogInterfaces.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogInterfaces.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef DarwinLogInterfaces_h -#define DarwinLogInterfaces_h +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_DARWINLOGINTERFACES_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_DARWINLOGINTERFACES_H #include @@ -21,4 +21,4 @@ using LogFilterChainSP = std::shared_ptr; class LogMessage; -#endif /* DarwinLogInterfaces_h */ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_DARWINLOGINTERFACES_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogTypes.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogTypes.h index e9d84991a4a..ab8560f1e08 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogTypes.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogTypes.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef DarwinLogTypes_h -#define DarwinLogTypes_h +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_DARWINLOGTYPES_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_DARWINLOGTYPES_H enum FilterTarget { eFilterTargetInvalid, @@ -18,4 +18,4 @@ enum FilterTarget { eFilterTargetSubsystem }; -#endif /* DarwinLogTypes_h */ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_DARWINLOGTYPES_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogFilter.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogFilter.h index 76ab60f1d9f..28c33c15bf0 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogFilter.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogFilter.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LogFilter_h -#define LogFilter_h +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_LOGFILTER_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_LOGFILTER_H #include "DarwinLogInterfaces.h" @@ -26,4 +26,4 @@ private: bool m_matches_accept; }; -#endif /* LogFilter_h */ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_LOGFILTER_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogFilterChain.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogFilterChain.h index f231c308232..67f7d231574 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogFilterChain.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogFilterChain.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LogFilterChain_h -#define LogFilterChain_h +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_LOGFILTERCHAIN_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_LOGFILTERCHAIN_H #include @@ -34,4 +34,4 @@ private: bool m_default_accept; }; -#endif /* LogFilterChain_hpp */ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_LOGFILTERCHAIN_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogFilterExactMatch.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogFilterExactMatch.h index 5c0b9c22356..d7c28baecc5 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogFilterExactMatch.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogFilterExactMatch.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LogFilterExactMatch_h -#define LogFilterExactMatch_h +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_LOGFILTEREXACTMATCH_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_LOGFILTEREXACTMATCH_H #include diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogFilterRegex.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogFilterRegex.h index 5bcc366f077..255679d8b22 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogFilterRegex.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogFilterRegex.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LogFilterRegex_h -#define LogFilterRegex_h +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_LOGFILTERREGEX_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_LOGFILTERREGEX_H // C includes #include @@ -40,4 +40,4 @@ private: std::string m_error_text; }; -#endif /* LogFilterSubsystemRegex_hpp */ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_LOGFILTERREGEX_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogMessage.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogMessage.h index 1f5808c2cd1..af7fca83d19 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogMessage.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogMessage.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LogMessage_h -#define LogMessage_h +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_LOGMESSAGE_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_LOGMESSAGE_H #include @@ -36,4 +36,4 @@ protected: LogMessage(); }; -#endif /* LogMessage_h */ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_LOGMESSAGE_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogMessageOsLog.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogMessageOsLog.h index 39b6adccb1b..3f644097064 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogMessageOsLog.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/DarwinLog/LogMessageOsLog.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LogMessageOsLog_h -#define LogMessageOsLog_h +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_LOGMESSAGEOSLOG_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_LOGMESSAGEOSLOG_H #include "DarwinLogInterfaces.h" @@ -53,4 +53,4 @@ private: mutable std::string m_message; }; -#endif /* LogMessageOsLog_h */ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_LOGMESSAGEOSLOG_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/Genealogy.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/Genealogy.h index 969405a18af..83ea36387a9 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/Genealogy.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/Genealogy.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __Genealogy_h__ -#define __Genealogy_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_GENEALOGY_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_GENEALOGY_H #include #include @@ -116,4 +116,4 @@ private: bool m_diagnosticd_call_timed_out; }; -#endif // __Genealogy_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_GENEALOGY_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/GenealogySPI.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/GenealogySPI.h index 0aea512b369..4a655242602 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/GenealogySPI.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/GenealogySPI.h @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception //===----------------------------------------------------------------------===// -#ifndef __GenealogySPI_h__ -#define __GenealogySPI_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_GENEALOGYSPI_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_GENEALOGYSPI_H #include diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachException.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachException.h index 0a1d34170d6..e6cb317bb51 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachException.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachException.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __MachException_h__ -#define __MachException_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHEXCEPTION_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHEXCEPTION_H #include #include diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachProcess.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachProcess.h index e31486cc39b..c749dd8426c 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachProcess.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachProcess.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __MachProcess_h__ -#define __MachProcess_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHPROCESS_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHPROCESS_H #include #include @@ -230,10 +230,22 @@ public: uint64_t plo_pthread_tsd_base_address_offset, uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size); - const char * - GetDeploymentInfo(const struct load_command&, uint64_t load_command_address, - uint32_t& major_version, uint32_t& minor_version, - uint32_t& patch_version); + + struct DeploymentInfo { + DeploymentInfo() = default; + operator bool() { return platform > 0; } + /// The Mach-O platform type; + unsigned char platform = 0; + /// Pre-LC_BUILD_VERSION files don't disambiguate between ios and ios + /// simulator. + bool maybe_simulator = false; + uint32_t major_version = 0; + uint32_t minor_version = 0; + uint32_t patch_version = 0; + }; + DeploymentInfo GetDeploymentInfo(const struct load_command &, + uint64_t load_command_address); + static const char *GetPlatformString(unsigned char platform); bool GetMachOInformationFromMemory(uint32_t platform, nub_addr_t mach_o_header_addr, int wordsize, @@ -338,9 +350,16 @@ private: eMachProcessFlagsUsingFBS = (1 << 3), // only read via ProcessUsingFrontBoard() eMachProcessFlagsBoardCalculated = (1 << 4) }; + + enum { + eMachProcessProfileNone = 0, + eMachProcessProfileCancel = (1 << 0) + }; + void Clear(bool detaching = false); void ReplyToAllExceptions(); void PrivateResume(); + void StopProfileThread(); uint32_t Flags() const { return m_flags; } nub_state_t DoSIGSTOP(bool clear_bps_and_wps, bool allow_running, @@ -375,7 +394,7 @@ private: m_profile_data_mutex; // Multithreaded protection for profile info data std::vector m_profile_data; // Profile data, must be protected by m_profile_data_mutex - + PThreadEvent m_profile_events; // Used for the profile thread cancellable wait DNBThreadResumeActions m_thread_actions; // The thread actions for the current // MachProcess::Resume() call MachException::Message::collection m_exception_messages; // A collection of @@ -414,7 +433,7 @@ private: // we don't report a spurious stop on the next resume. int m_auto_resume_signo; // If we resume the process and still haven't // received our interrupt signal - // acknownledgement, we will shortly after the next resume. We store the + // acknowledgement, we will shortly after the next resume. We store the // interrupt signal in this variable so when we get the interrupt signal // as the sole reason for the process being stopped, we can auto resume // the process. @@ -430,4 +449,4 @@ private: uint32_t (*m_dyld_process_info_get_platform)(void *info); }; -#endif // __MachProcess_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHPROCESS_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachProcess.mm b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachProcess.mm index 40facdfb5cf..8a35f605daa 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachProcess.mm +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachProcess.mm @@ -25,13 +25,16 @@ #include #include #include +#include #include #include #include #include +#include #include +#include #import #include "DNBDataRef.h" @@ -162,16 +165,18 @@ static bool CallBoardSystemServiceOpenApplication(NSString *bundleIDNSStr, [(NSString *)[bks_error localizedDescription] UTF8String]; if (error_str) { open_app_error_string = error_str; + DNBLogError("In app launch attempt, got error " + "localizedDescription '%s'.", error_str); + const char *obj_desc = + [NSString stringWithFormat:@"%@", bks_error].UTF8String; + DNBLogError("In app launch attempt, got error " + "NSError object description: '%s'.", + obj_desc); } DNBLogThreadedIf(LOG_PROCESS, "In completion handler for send " "event, got error \"%s\"(%ld).", error_str ? error_str : "", open_app_error); - // REMOVE ME - DNBLogError("In completion handler for send event, got error " - "\"%s\"(%ld).", - error_str ? error_str : "", - open_app_error); } [system_service release]; @@ -485,6 +490,7 @@ MachProcess::MachProcess() m_stdio_mutex(PTHREAD_MUTEX_RECURSIVE), m_stdout_data(), m_profile_enabled(false), m_profile_interval_usec(0), m_profile_thread(0), m_profile_data_mutex(PTHREAD_MUTEX_RECURSIVE), m_profile_data(), + m_profile_events(0, eMachProcessProfileCancel), m_thread_actions(), m_exception_messages(), m_exception_messages_mutex(PTHREAD_MUTEX_RECURSIVE), m_thread_list(), m_activities(), m_state(eStateUnloaded), @@ -595,72 +601,77 @@ nub_addr_t MachProcess::GetTSDAddressForThread( plo_pthread_tsd_entry_size); } - -const char *MachProcess::GetDeploymentInfo(const struct load_command& lc, - uint64_t load_command_address, - uint32_t& major_version, - uint32_t& minor_version, - uint32_t& patch_version) { +MachProcess::DeploymentInfo +MachProcess::GetDeploymentInfo(const struct load_command &lc, + uint64_t load_command_address) { + DeploymentInfo info; uint32_t cmd = lc.cmd & ~LC_REQ_DYLD; - bool lc_cmd_known = - cmd == LC_VERSION_MIN_IPHONEOS || cmd == LC_VERSION_MIN_MACOSX || - cmd == LC_VERSION_MIN_TVOS || cmd == LC_VERSION_MIN_WATCHOS; - - if (lc_cmd_known) { + // Handle the older LC_VERSION load commands, which don't + // distinguish between simulator and real hardware. + auto handle_version_min = [&](char platform) { struct version_min_command vers_cmd; if (ReadMemory(load_command_address, sizeof(struct version_min_command), - &vers_cmd) != sizeof(struct version_min_command)) { - return nullptr; - } - major_version = vers_cmd.sdk >> 16; - minor_version = (vers_cmd.sdk >> 8) & 0xffu; - patch_version = vers_cmd.sdk & 0xffu; - - switch (cmd) { - case LC_VERSION_MIN_IPHONEOS: - return "ios"; - case LC_VERSION_MIN_MACOSX: - return "macosx"; - case LC_VERSION_MIN_TVOS: - return "tvos"; - case LC_VERSION_MIN_WATCHOS: - return "watchos"; - default: - return nullptr; - } - } -#if defined (LC_BUILD_VERSION) - if (cmd == LC_BUILD_VERSION) { + &vers_cmd) != sizeof(struct version_min_command)) + return; + info.platform = platform; + info.major_version = vers_cmd.version >> 16; + info.minor_version = (vers_cmd.version >> 8) & 0xffu; + info.patch_version = vers_cmd.version & 0xffu; + info.maybe_simulator = true; + }; + switch (cmd) { + case LC_VERSION_MIN_IPHONEOS: + handle_version_min(PLATFORM_IOS); + break; + case LC_VERSION_MIN_MACOSX: + handle_version_min(PLATFORM_MACOS); + break; + case LC_VERSION_MIN_TVOS: + handle_version_min(PLATFORM_TVOS); + break; + case LC_VERSION_MIN_WATCHOS: + handle_version_min(PLATFORM_WATCHOS); + break; +#if defined(LC_BUILD_VERSION) + case LC_BUILD_VERSION: { struct build_version_command build_vers; if (ReadMemory(load_command_address, sizeof(struct build_version_command), - &build_vers) != sizeof(struct build_version_command)) { - return nullptr; - } - major_version = build_vers.sdk >> 16;; - minor_version = (build_vers.sdk >> 8) & 0xffu; - patch_version = build_vers.sdk & 0xffu; - - switch (build_vers.platform) { - case PLATFORM_MACOS: - return "macosx"; - case PLATFORM_MACCATALYST: - return "maccatalyst"; - case PLATFORM_IOS: - case PLATFORM_IOSSIMULATOR: - return "ios"; - case PLATFORM_TVOS: - case PLATFORM_TVOSSIMULATOR: - return "tvos"; - case PLATFORM_WATCHOS: - case PLATFORM_WATCHOSSIMULATOR: - return "watchos"; - case PLATFORM_BRIDGEOS: - return "bridgeos"; - case PLATFORM_DRIVERKIT: - return "driverkit"; - } + &build_vers) != sizeof(struct build_version_command)) + break; + info.platform = build_vers.platform; + info.major_version = build_vers.minos >> 16; + info.minor_version = (build_vers.minos >> 8) & 0xffu; + info.patch_version = build_vers.minos & 0xffu; + break; } #endif + } + return info; +} + +const char *MachProcess::GetPlatformString(unsigned char platform) { + switch (platform) { + case PLATFORM_MACOS: + return "macosx"; + case PLATFORM_MACCATALYST: + return "maccatalyst"; + case PLATFORM_IOS: + return "ios"; + case PLATFORM_IOSSIMULATOR: + return "iossimulator"; + case PLATFORM_TVOS: + return "tvos"; + case PLATFORM_TVOSSIMULATOR: + return "tvossimulator"; + case PLATFORM_WATCHOS: + return "watchos"; + case PLATFORM_WATCHOSSIMULATOR: + return "watchossimulator"; + case PLATFORM_BRIDGEOS: + return "bridgeos"; + case PLATFORM_DRIVERKIT: + return "driverkit"; + } return nullptr; } @@ -734,6 +745,8 @@ bool MachProcess::GetMachOInformationFromMemory( this_seg.nsects = seg.nsects; this_seg.flags = seg.flags; inf.segments.push_back(this_seg); + if (this_seg.name == "ExecExtraSuspend") + m_task.TaskWillExecProcessesSuspended(); } if (lc.cmd == LC_SEGMENT_64) { struct segment_command_64 seg; @@ -755,6 +768,8 @@ bool MachProcess::GetMachOInformationFromMemory( this_seg.nsects = seg.nsects; this_seg.flags = seg.flags; inf.segments.push_back(this_seg); + if (this_seg.name == "ExecExtraSuspend") + m_task.TaskWillExecProcessesSuspended(); } if (lc.cmd == LC_UUID) { struct uuid_command uuidcmd; @@ -762,10 +777,36 @@ bool MachProcess::GetMachOInformationFromMemory( sizeof(struct uuid_command)) uuid_copy(inf.uuid, uuidcmd.uuid); } - - uint32_t major_version, minor_version, patch_version; - if (const char *lc_platform = GetDeploymentInfo( - lc, load_cmds_p, major_version, minor_version, patch_version)) { + if (DeploymentInfo deployment_info = GetDeploymentInfo(lc, load_cmds_p)) { + // Simulator support. If the platform is ambiguous, use the dyld info. + if (deployment_info.maybe_simulator) { + if (deployment_info.maybe_simulator) { +#if (defined(__x86_64__) || defined(__i386__)) + // If dyld doesn't return a platform, use a heuristic. + // If we are running on Intel macOS, it is safe to assume + // this is really a back-deploying simulator binary. + switch (deployment_info.platform) { + case PLATFORM_IOS: + deployment_info.platform = PLATFORM_IOSSIMULATOR; + break; + case PLATFORM_TVOS: + deployment_info.platform = PLATFORM_TVOSSIMULATOR; + break; + case PLATFORM_WATCHOS: + deployment_info.platform = PLATFORM_WATCHOSSIMULATOR; + break; + } +#else + // On an Apple Silicon macOS host, there is no + // ambiguity. The only binaries that use legacy load + // commands are back-deploying native iOS binaries. All + // simulator binaries use the newer, unambiguous + // LC_BUILD_VERSION load commands. + deployment_info.maybe_simulator = false; +#endif + } + } + const char *lc_platform = GetPlatformString(deployment_info.platform); // macCatalyst support. // // This handles two special cases: @@ -799,12 +840,15 @@ bool MachProcess::GetMachOInformationFromMemory( } else { inf.min_version_os_name = lc_platform; inf.min_version_os_version = ""; - inf.min_version_os_version += std::to_string(major_version); + inf.min_version_os_version += + std::to_string(deployment_info.major_version); inf.min_version_os_version += "."; - inf.min_version_os_version += std::to_string(minor_version); - if (patch_version != 0) { + inf.min_version_os_version += + std::to_string(deployment_info.minor_version); + if (deployment_info.patch_version != 0) { inf.min_version_os_version += "."; - inf.min_version_os_version += std::to_string(patch_version); + inf.min_version_os_version += + std::to_string(deployment_info.patch_version); } } } @@ -1290,10 +1334,7 @@ void MachProcess::Clear(bool detaching) { m_exception_messages.clear(); } m_activities.Clear(); - if (m_profile_thread) { - pthread_join(m_profile_thread, NULL); - m_profile_thread = NULL; - } + StopProfileThread(); } bool MachProcess::StartSTDIOThread() { @@ -1312,11 +1353,19 @@ void MachProcess::SetEnableAsyncProfiling(bool enable, uint64_t interval_usec, if (m_profile_enabled && (m_profile_thread == NULL)) { StartProfileThread(); } else if (!m_profile_enabled && m_profile_thread) { - pthread_join(m_profile_thread, NULL); - m_profile_thread = NULL; + StopProfileThread(); } } +void MachProcess::StopProfileThread() { + if (m_profile_thread == NULL) + return; + m_profile_events.SetEvents(eMachProcessProfileCancel); + pthread_join(m_profile_thread, NULL); + m_profile_thread = NULL; + m_profile_events.ResetEvents(eMachProcessProfileCancel); +} + bool MachProcess::StartProfileThread() { DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s ( )", __FUNCTION__); // Create the thread that profiles the inferior and reports back if enabled @@ -2509,10 +2558,20 @@ void *MachProcess::ProfileThread(void *arg) { // Done. Get out of this thread. break; } - - // A simple way to set up the profile interval. We can also use select() or - // dispatch timer source if necessary. - usleep(proc->ProfileInterval()); + timespec ts; + { + using namespace std::chrono; + std::chrono::microseconds dur(proc->ProfileInterval()); + const auto dur_secs = duration_cast(dur); + const auto dur_usecs = dur % std::chrono::seconds(1); + DNBTimer::OffsetTimeOfDay(&ts, dur_secs.count(), + dur_usecs.count()); + } + uint32_t bits_set = + proc->m_profile_events.WaitForSetEvents(eMachProcessProfileCancel, &ts); + // If we got bits back, we were told to exit. Do so. + if (bits_set & eMachProcessProfileCancel) + break; } return NULL; } @@ -3215,9 +3274,9 @@ pid_t MachProcess::PosixSpawnChildForPTraceDebugging( if (file_actions_valid) { if (stdin_path == NULL && stdout_path == NULL && stderr_path == NULL && !no_stdio) { - pty_error = pty.OpenFirstAvailableMaster(O_RDWR | O_NOCTTY); + pty_error = pty.OpenFirstAvailablePrimary(O_RDWR | O_NOCTTY); if (pty_error == PseudoTerminal::success) { - stdin_path = stdout_path = stderr_path = pty.SlaveName(); + stdin_path = stdout_path = stderr_path = pty.SecondaryName(); } } @@ -3292,8 +3351,8 @@ pid_t MachProcess::PosixSpawnChildForPTraceDebugging( if (pty_error == 0) { if (process != NULL) { - int master_fd = pty.ReleaseMasterFD(); - process->SetChildFileDescriptors(master_fd, master_fd, master_fd); + int primary_fd = pty.ReleasePrimaryFD(); + process->SetChildFileDescriptors(primary_fd, primary_fd, primary_fd); } } ::posix_spawnattr_destroy(&attr); @@ -3390,10 +3449,10 @@ pid_t MachProcess::ForkChildForPTraceDebugging(const char *path, ::setpgid(pid, pid); // Set the child process group to match its pid if (process != NULL) { - // Release our master pty file descriptor so the pty class doesn't + // Release our primary pty file descriptor so the pty class doesn't // close it and so we can continue to use it in our STDIO thread - int master_fd = pty.ReleaseMasterFD(); - process->SetChildFileDescriptors(master_fd, master_fd, master_fd); + int primary_fd = pty.ReleasePrimaryFD(); + process->SetChildFileDescriptors(primary_fd, primary_fd, primary_fd); } } return pid; @@ -3566,15 +3625,15 @@ pid_t MachProcess::SBForkChildForPTraceDebugging( PseudoTerminal pty; if (!no_stdio) { PseudoTerminal::Status pty_err = - pty.OpenFirstAvailableMaster(O_RDWR | O_NOCTTY); + pty.OpenFirstAvailablePrimary(O_RDWR | O_NOCTTY); if (pty_err == PseudoTerminal::success) { - const char *slave_name = pty.SlaveName(); + const char *secondary_name = pty.SecondaryName(); DNBLogThreadedIf(LOG_PROCESS, - "%s() successfully opened master pty, slave is %s", - __FUNCTION__, slave_name); - if (slave_name && slave_name[0]) { - ::chmod(slave_name, S_IRWXU | S_IRWXG | S_IRWXO); - stdio_path.SetFileSystemRepresentation(slave_name); + "%s() successfully opened primary pty, secondary is %s", + __FUNCTION__, secondary_name); + if (secondary_name && secondary_name[0]) { + ::chmod(secondary_name, S_IRWXU | S_IRWXG | S_IRWXO); + stdio_path.SetFileSystemRepresentation(secondary_name); } } } @@ -3631,10 +3690,10 @@ pid_t MachProcess::SBForkChildForPTraceDebugging( CFRelease(bundleIDCFStr); if (pid_found) { if (process != NULL) { - // Release our master pty file descriptor so the pty class doesn't + // Release our primary pty file descriptor so the pty class doesn't // close it and so we can continue to use it in our STDIO thread - int master_fd = pty.ReleaseMasterFD(); - process->SetChildFileDescriptors(master_fd, master_fd, master_fd); + int primary_fd = pty.ReleasePrimaryFD(); + process->SetChildFileDescriptors(primary_fd, primary_fd, primary_fd); } DNBLogThreadedIf(LOG_PROCESS, "%s() => pid = %4.4x", __FUNCTION__, pid); } else { @@ -3767,17 +3826,17 @@ pid_t MachProcess::BoardServiceForkChildForPTraceDebugging( PseudoTerminal pty; if (!no_stdio) { PseudoTerminal::Status pty_err = - pty.OpenFirstAvailableMaster(O_RDWR | O_NOCTTY); + pty.OpenFirstAvailablePrimary(O_RDWR | O_NOCTTY); if (pty_err == PseudoTerminal::success) { - const char *slave_name = pty.SlaveName(); + const char *secondary_name = pty.SecondaryName(); DNBLogThreadedIf(LOG_PROCESS, - "%s() successfully opened master pty, slave is %s", - __FUNCTION__, slave_name); - if (slave_name && slave_name[0]) { - ::chmod(slave_name, S_IRWXU | S_IRWXG | S_IRWXO); + "%s() successfully opened primary pty, secondary is %s", + __FUNCTION__, secondary_name); + if (secondary_name && secondary_name[0]) { + ::chmod(secondary_name, S_IRWXU | S_IRWXG | S_IRWXO); stdio_path = [file_manager - stringWithFileSystemRepresentation:slave_name - length:strlen(slave_name)]; + stringWithFileSystemRepresentation:secondary_name + length:strlen(secondary_name)]; } } } @@ -3826,8 +3885,8 @@ pid_t MachProcess::BoardServiceForkChildForPTraceDebugging( #endif if (success) { - int master_fd = pty.ReleaseMasterFD(); - SetChildFileDescriptors(master_fd, master_fd, master_fd); + int primary_fd = pty.ReleasePrimaryFD(); + SetChildFileDescriptors(primary_fd, primary_fd, primary_fd); CFString::UTF8(bundleIDCFStr, m_bundle_id); } diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachTask.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachTask.h index c975e15a555..36e31dddd45 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachTask.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachTask.h @@ -13,8 +13,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __MachTask_h__ -#define __MachTask_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHTASK_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHTASK_H #include #include @@ -85,6 +85,7 @@ public: const MachProcess *Process() const { return m_process; } nub_size_t PageSize(); + void TaskWillExecProcessesSuspended() { m_exec_will_be_suspended = true; } protected: MachProcess *m_process; // The mach process that owns this MachTask @@ -97,6 +98,12 @@ protected: // need it mach_port_t m_exception_port; // Exception port on which we will receive child // exceptions + bool m_exec_will_be_suspended; // If this task exec's another process, that + // process will be launched suspended and we will + // need to execute one extra Resume to get it + // to progress from dyld_start. + bool m_do_double_resume; // next time we task_resume(), do it twice to + // fix a too-high suspend count. typedef std::map allocation_collection; allocation_collection m_allocations; @@ -106,4 +113,4 @@ private: MachTask &operator=(const MachTask &rhs) = delete; }; -#endif // __MachTask_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHTASK_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachTask.mm b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachTask.mm index 0d5a63a28f2..fcbe6e71389 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachTask.mm +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachTask.mm @@ -64,12 +64,17 @@ extern "C" { #include #endif +extern "C" int +proc_get_cpumon_params(pid_t pid, int *percentage, + int *interval); // SPI + //---------------------------------------------------------------------- // MachTask constructor //---------------------------------------------------------------------- MachTask::MachTask(MachProcess *process) : m_process(process), m_task(TASK_NULL), m_vm_memory(), - m_exception_thread(0), m_exception_port(MACH_PORT_NULL) { + m_exception_thread(0), m_exception_port(MACH_PORT_NULL), + m_exec_will_be_suspended(false), m_do_double_resume(false) { memset(&m_exc_port_info, 0, sizeof(m_exc_port_info)); } @@ -103,6 +108,14 @@ kern_return_t MachTask::Resume() { err = BasicInfo(task, &task_info); if (err.Success()) { + if (m_do_double_resume && task_info.suspend_count == 2) { + err = ::task_resume(task); + if (DNBLogCheckLogBit(LOG_TASK) || err.Fail()) + err.LogThreaded("::task_resume double-resume after exec-start-stopped " + "( target_task = 0x%4.4x )", task); + } + m_do_double_resume = false; + // task_resume isn't counted like task_suspend calls are, are, so if the // task is not suspended, don't try and resume it since it is already // running @@ -135,6 +148,8 @@ void MachTask::Clear() { m_task = TASK_NULL; m_exception_thread = 0; m_exception_port = MACH_PORT_NULL; + m_exec_will_be_suspended = false; + m_do_double_resume = false; } //---------------------------------------------------------------------- @@ -459,6 +474,16 @@ std::string MachTask::GetProfileData(DNBProfileDataScanType scanType) { } #endif + if (scanType & eProfileEnergyCPUCap) { + int percentage = -1; + int interval = -1; + int result = proc_get_cpumon_params(pid, &percentage, &interval); + if ((result == 0) && (percentage >= 0) && (interval >= 0)) { + profile_data_stream << "cpu_cap_p:" << percentage << ';'; + profile_data_stream << "cpu_cap_t:" << interval << ';'; + } + } + profile_data_stream << "--end--;"; result = profile_data_stream.str(); @@ -651,6 +676,9 @@ kern_return_t MachTask::ShutDownExcecptionThread() { err.LogThreaded("::mach_port_deallocate ( task = 0x%4.4x, name = 0x%4.4x )", task_self, exception_port); + m_exec_will_be_suspended = false; + m_do_double_resume = false; + return err.Status(); } @@ -960,4 +988,14 @@ nub_bool_t MachTask::DeallocateMemory(nub_addr_t addr) { void MachTask::TaskPortChanged(task_t task) { m_task = task; + + // If we've just exec'd to a new process, and it + // is started suspended, we'll need to do two + // task_resume's to get the inferior process to + // continue. + if (m_exec_will_be_suspended) + m_do_double_resume = true; + else + m_do_double_resume = false; + m_exec_will_be_suspended = false; } diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachThread.cpp b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachThread.cpp index 80d6042caa5..d2423a5deca 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachThread.cpp +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachThread.cpp @@ -534,9 +534,12 @@ bool MachThread::RestoreRegisterState(uint32_t save_id) { return m_arch_up->RestoreRegisterState(save_id); } -uint32_t MachThread::EnableHardwareBreakpoint(const DNBBreakpoint *bp) { - if (bp != NULL && bp->IsBreakpoint()) - return m_arch_up->EnableHardwareBreakpoint(bp->Address(), bp->ByteSize()); +uint32_t MachThread::EnableHardwareBreakpoint(const DNBBreakpoint *bp, + bool also_set_on_task) { + if (bp != NULL && bp->IsBreakpoint()) { + return m_arch_up->EnableHardwareBreakpoint(bp->Address(), bp->ByteSize(), + also_set_on_task); + } return INVALID_NUB_HW_INDEX; } @@ -555,9 +558,12 @@ bool MachThread::RollbackTransForHWP() { bool MachThread::FinishTransForHWP() { return m_arch_up->FinishTransForHWP(); } -bool MachThread::DisableHardwareBreakpoint(const DNBBreakpoint *bp) { - if (bp != NULL && bp->IsHardware()) - return m_arch_up->DisableHardwareBreakpoint(bp->GetHardwareIndex()); +bool MachThread::DisableHardwareBreakpoint(const DNBBreakpoint *bp, + bool also_set_on_task) { + if (bp != NULL && bp->IsHardware()) { + return m_arch_up->DisableHardwareBreakpoint(bp->GetHardwareIndex(), + also_set_on_task); + } return false; } diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachThread.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachThread.h index 1634522fde4..5466c6f9f95 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachThread.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachThread.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __MachThread_h__ -#define __MachThread_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHTHREAD_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHTHREAD_H #include #include @@ -66,10 +66,12 @@ public: uint64_t GetSP(uint64_t failValue = INVALID_NUB_ADDRESS); // Get stack pointer DNBBreakpoint *CurrentBreakpoint(); - uint32_t EnableHardwareBreakpoint(const DNBBreakpoint *breakpoint); + uint32_t EnableHardwareBreakpoint(const DNBBreakpoint *breakpoint, + bool also_set_on_task); uint32_t EnableHardwareWatchpoint(const DNBBreakpoint *watchpoint, bool also_set_on_task); - bool DisableHardwareBreakpoint(const DNBBreakpoint *breakpoint); + bool DisableHardwareBreakpoint(const DNBBreakpoint *breakpoint, + bool also_set_on_task); bool DisableHardwareWatchpoint(const DNBBreakpoint *watchpoint, bool also_set_on_task); uint32_t NumSupportedHardwareWatchpoints() const; diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp index d2aae9da0c4..ce63b0fd634 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp @@ -483,23 +483,48 @@ void MachThreadList::NotifyBreakpointChanged(const DNBBreakpoint *bp) { } } -uint32_t -MachThreadList::EnableHardwareBreakpoint(const DNBBreakpoint *bp) const { - if (bp != NULL) { - const size_t num_threads = m_threads.size(); - for (uint32_t idx = 0; idx < num_threads; ++idx) - m_threads[idx]->EnableHardwareBreakpoint(bp); - } - return INVALID_NUB_HW_INDEX; -} +uint32_t MachThreadList::DoHardwareBreakpointAction( + const DNBBreakpoint *bp, HardwareBreakpointAction action) const { + if (bp == NULL) + return INVALID_NUB_HW_INDEX; -bool MachThreadList::DisableHardwareBreakpoint(const DNBBreakpoint *bp) const { - if (bp != NULL) { - const size_t num_threads = m_threads.size(); - for (uint32_t idx = 0; idx < num_threads; ++idx) - m_threads[idx]->DisableHardwareBreakpoint(bp); + uint32_t hw_index = INVALID_NUB_HW_INDEX; + PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex); + const size_t num_threads = m_threads.size(); + // On Mac OS X we have to prime the control registers for new threads. We do + // this using the control register data for the first thread, for lack of a + // better way of choosing. + bool also_set_on_task = true; + for (uint32_t idx = 0; idx < num_threads; ++idx) { + switch (action) { + case HardwareBreakpointAction::EnableWatchpoint: + hw_index = m_threads[idx]->EnableHardwareWatchpoint(bp, also_set_on_task); + break; + case HardwareBreakpointAction::DisableWatchpoint: + hw_index = + m_threads[idx]->DisableHardwareWatchpoint(bp, also_set_on_task); + break; + case HardwareBreakpointAction::EnableBreakpoint: + hw_index = m_threads[idx]->EnableHardwareBreakpoint(bp, also_set_on_task); + break; + case HardwareBreakpointAction::DisableBreakpoint: + hw_index = + m_threads[idx]->DisableHardwareBreakpoint(bp, also_set_on_task); + break; + } + if (hw_index == INVALID_NUB_HW_INDEX) { + // We know that idx failed for some reason. Let's rollback the + // transaction for [0, idx). + for (uint32_t i = 0; i < idx; ++i) + m_threads[i]->RollbackTransForHWP(); + return INVALID_NUB_HW_INDEX; + } + also_set_on_task = false; } - return false; + // Notify each thread to commit the pending transaction. + for (uint32_t idx = 0; idx < num_threads; ++idx) + m_threads[idx]->FinishTransForHWP(); + return hw_index; } // DNBWatchpointSet() -> MachProcess::CreateWatchpoint() -> @@ -507,60 +532,26 @@ bool MachThreadList::DisableHardwareBreakpoint(const DNBBreakpoint *bp) const { // -> MachThreadList::EnableHardwareWatchpoint(). uint32_t MachThreadList::EnableHardwareWatchpoint(const DNBBreakpoint *wp) const { - uint32_t hw_index = INVALID_NUB_HW_INDEX; - if (wp != NULL) { - PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex); - const size_t num_threads = m_threads.size(); - // On Mac OS X we have to prime the control registers for new threads. We - // do this - // using the control register data for the first thread, for lack of a - // better way of choosing. - bool also_set_on_task = true; - for (uint32_t idx = 0; idx < num_threads; ++idx) { - if ((hw_index = m_threads[idx]->EnableHardwareWatchpoint( - wp, also_set_on_task)) == INVALID_NUB_HW_INDEX) { - // We know that idx failed for some reason. Let's rollback the - // transaction for [0, idx). - for (uint32_t i = 0; i < idx; ++i) - m_threads[i]->RollbackTransForHWP(); - return INVALID_NUB_HW_INDEX; - } - also_set_on_task = false; - } - // Notify each thread to commit the pending transaction. - for (uint32_t idx = 0; idx < num_threads; ++idx) - m_threads[idx]->FinishTransForHWP(); - } - return hw_index; + return DoHardwareBreakpointAction(wp, + HardwareBreakpointAction::EnableWatchpoint); } bool MachThreadList::DisableHardwareWatchpoint(const DNBBreakpoint *wp) const { - if (wp != NULL) { - PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex); - const size_t num_threads = m_threads.size(); + return DoHardwareBreakpointAction( + wp, HardwareBreakpointAction::DisableWatchpoint) != + INVALID_NUB_HW_INDEX; +} - // On Mac OS X we have to prime the control registers for new threads. We - // do this - // using the control register data for the first thread, for lack of a - // better way of choosing. - bool also_set_on_task = true; - for (uint32_t idx = 0; idx < num_threads; ++idx) { - if (!m_threads[idx]->DisableHardwareWatchpoint(wp, also_set_on_task)) { - // We know that idx failed for some reason. Let's rollback the - // transaction for [0, idx). - for (uint32_t i = 0; i < idx; ++i) - m_threads[i]->RollbackTransForHWP(); - return false; - } - also_set_on_task = false; - } - // Notify each thread to commit the pending transaction. - for (uint32_t idx = 0; idx < num_threads; ++idx) - m_threads[idx]->FinishTransForHWP(); +uint32_t +MachThreadList::EnableHardwareBreakpoint(const DNBBreakpoint *bp) const { + return DoHardwareBreakpointAction(bp, + HardwareBreakpointAction::EnableBreakpoint); +} - return true; - } - return false; +bool MachThreadList::DisableHardwareBreakpoint(const DNBBreakpoint *bp) const { + return DoHardwareBreakpointAction( + bp, HardwareBreakpointAction::DisableBreakpoint) != + INVALID_NUB_HW_INDEX; } uint32_t MachThreadList::NumSupportedHardwareWatchpoints() const { diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachThreadList.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachThreadList.h index b9b7aa8c4c9..8544c3ab731 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachThreadList.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachThreadList.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __MachThreadList_h__ -#define __MachThreadList_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHTHREADLIST_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHTHREADLIST_H #include "MachThread.h" #include "ThreadInfo.h" @@ -83,6 +83,16 @@ protected: typedef collection::iterator iterator; typedef collection::const_iterator const_iterator; + enum class HardwareBreakpointAction { + EnableWatchpoint, + DisableWatchpoint, + EnableBreakpoint, + DisableBreakpoint, + }; + + uint32_t DoHardwareBreakpointAction(const DNBBreakpoint *bp, + HardwareBreakpointAction action) const; + uint32_t UpdateThreadList(MachProcess *process, bool update, collection *num_threads = NULL); // const_iterator FindThreadByID (thread_t tid) const; @@ -93,4 +103,4 @@ protected: bool m_is_64_bit; }; -#endif // #ifndef __MachThreadList_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHTHREADLIST_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h index 538e11232a8..05d2c029b99 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __MachVMMemory_h__ -#define __MachVMMemory_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHVMMEMORY_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHVMMEMORY_H #include "DNBDefs.h" #include "DNBError.h" @@ -44,4 +44,4 @@ protected: DNBError m_err; }; -#endif // #ifndef __MachVMMemory_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHVMMEMORY_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h index 2e6303c4b39..210b1c9ef86 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __MachVMRegion_h__ -#define __MachVMRegion_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHVMREGION_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHVMREGION_H #include "DNBDefs.h" #include "DNBError.h" @@ -69,4 +69,4 @@ protected: m_protection_size; // The size of memory that had its protections changed }; -#endif // #ifndef __MachVMRegion_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHVMREGION_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/OsLogger.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/OsLogger.h index 5a173c42b83..0c81a84d7c4 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/OsLogger.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/OsLogger.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef OsLogger_h -#define OsLogger_h +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_OSLOGGER_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_OSLOGGER_H #include "DNBDefs.h" @@ -16,4 +16,4 @@ public: static DNBCallbackLog GetLogFunction(); }; -#endif /* OsLogger_h */ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_OSLOGGER_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/ThreadInfo.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/ThreadInfo.h index 00c368c6ab0..a114a47eaab 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/ThreadInfo.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/ThreadInfo.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __ThreadInfo_h__ -#define __ThreadInfo_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_THREADINFO_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_THREADINFO_H namespace ThreadInfo { @@ -22,4 +22,4 @@ public: }; }; -#endif // __ThreadInfo_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_THREADINFO_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp index 45d05d6e0bd..90cc25650e3 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp @@ -980,7 +980,8 @@ uint32_t DNBArchMachARM::NumSupportedHardwareWatchpoints() { } uint32_t DNBArchMachARM::EnableHardwareBreakpoint(nub_addr_t addr, - nub_size_t size) { + nub_size_t size, + bool also_set_on_task) { // Make sure our address isn't bogus if (addr & 1) return INVALID_NUB_HW_INDEX; @@ -1052,7 +1053,8 @@ uint32_t DNBArchMachARM::EnableHardwareBreakpoint(nub_addr_t addr, return INVALID_NUB_HW_INDEX; } -bool DNBArchMachARM::DisableHardwareBreakpoint(uint32_t hw_index) { +bool DNBArchMachARM::DisableHardwareBreakpoint(uint32_t hw_index, + bool also_set_on_task) { kern_return_t kret = GetDBGState(false); const uint32_t num_hw_points = NumSupportedHardwareBreakpoints(); diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h index 4bb899b4503..29cd3e5ef27 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __DebugNubArchMachARM_h__ -#define __DebugNubArchMachARM_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_ARM_DNBARCHIMPL_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_ARM_DNBARCHIMPL_H #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) @@ -70,8 +70,10 @@ public: virtual uint32_t NumSupportedHardwareBreakpoints(); virtual uint32_t NumSupportedHardwareWatchpoints(); - virtual uint32_t EnableHardwareBreakpoint(nub_addr_t addr, nub_size_t size); - virtual bool DisableHardwareBreakpoint(uint32_t hw_break_index); + virtual uint32_t EnableHardwareBreakpoint(nub_addr_t addr, nub_size_t size, + bool also_set_on_task); + virtual bool DisableHardwareBreakpoint(uint32_t hw_break_index, + bool also_set_on_task); virtual uint32_t EnableHardwareWatchpoint(nub_addr_t addr, nub_size_t size, bool read, bool write, @@ -271,4 +273,4 @@ protected: }; #endif // #if defined (__arm__) -#endif // #ifndef __DebugNubArchMachARM_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_ARM_DNBARCHIMPL_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp index f99dbc48b12..7e1af7a7502 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp @@ -590,23 +590,21 @@ kern_return_t DNBArchMachARM64::EnableHardwareSingleStep(bool enable) { return err.Status(); } - if (enable) { - DNBLogThreadedIf(LOG_STEP, - "%s: Setting MDSCR_EL1 Single Step bit at pc 0x%llx", #if defined(__LP64__) - __FUNCTION__, (uint64_t)arm_thread_state64_get_pc (m_state.context.gpr)); + uint64_t pc = arm_thread_state64_get_pc (m_state.context.gpr); #else - __FUNCTION__, (uint64_t)m_state.context.gpr.__pc); + uint64_t pc = m_state.context.gpr.__pc; #endif + + if (enable) { + DNBLogThreadedIf(LOG_STEP, + "%s: Setting MDSCR_EL1 Single Step bit at pc 0x%llx", + __FUNCTION__, pc); m_state.dbg.__mdscr_el1 |= SS_ENABLE; } else { DNBLogThreadedIf(LOG_STEP, "%s: Clearing MDSCR_EL1 Single Step bit at pc 0x%llx", -#if defined(__LP64__) - __FUNCTION__, (uint64_t)arm_thread_state64_get_pc (m_state.context.gpr)); -#else - __FUNCTION__, (uint64_t)m_state.context.gpr.__pc); -#endif + __FUNCTION__, pc); m_state.dbg.__mdscr_el1 &= ~(SS_ENABLE); } @@ -666,6 +664,112 @@ uint32_t DNBArchMachARM64::NumSupportedHardwareWatchpoints() { return g_num_supported_hw_watchpoints; } +uint32_t DNBArchMachARM64::NumSupportedHardwareBreakpoints() { + // Set the init value to something that will let us know that we need to + // autodetect how many breakpoints are supported dynamically... + static uint32_t g_num_supported_hw_breakpoints = UINT_MAX; + if (g_num_supported_hw_breakpoints == UINT_MAX) { + // Set this to zero in case we can't tell if there are any HW breakpoints + g_num_supported_hw_breakpoints = 0; + + size_t len; + uint32_t n = 0; + len = sizeof(n); + if (::sysctlbyname("hw.optional.breakpoint", &n, &len, NULL, 0) == 0) { + g_num_supported_hw_breakpoints = n; + DNBLogThreadedIf(LOG_THREAD, "hw.optional.breakpoint=%u", n); + } else { +// For AArch64 we would need to look at ID_AA64DFR0_EL1 but debugserver runs in +// EL0 so it can't access that reg. The kernel should have filled in the +// sysctls based on it though. +#if defined(__arm__) + uint32_t register_DBGDIDR; + + asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR)); + uint32_t numWRPs = bits(register_DBGDIDR, 31, 28); + // Zero is reserved for the WRP count, so don't increment it if it is zero + if (numWRPs > 0) + numWRPs++; + g_num_supported_hw_breakpoints = numWRPs; + DNBLogThreadedIf(LOG_THREAD, + "Number of supported hw breakpoint via asm(): %d", + g_num_supported_hw_breakpoints); +#endif + } + } + return g_num_supported_hw_breakpoints; +} + +uint32_t DNBArchMachARM64::EnableHardwareBreakpoint(nub_addr_t addr, + nub_size_t size, + bool also_set_on_task) { + DNBLogThreadedIf(LOG_WATCHPOINTS, + "DNBArchMachARM64::EnableHardwareBreakpoint(addr = " + "0x%8.8llx, size = %zu)", + (uint64_t)addr, size); + + const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints(); + + nub_addr_t aligned_bp_address = addr; + uint32_t control_value = 0; + + switch (size) { + case 2: + control_value = (0x3 << 5) | 7; + aligned_bp_address &= ~1; + break; + case 4: + control_value = (0xfu << 5) | 7; + aligned_bp_address &= ~3; + break; + }; + + // Read the debug state + kern_return_t kret = GetDBGState(false); + if (kret == KERN_SUCCESS) { + // Check to make sure we have the needed hardware support + uint32_t i = 0; + + for (i = 0; i < num_hw_breakpoints; ++i) { + if ((m_state.dbg.__bcr[i] & BCR_ENABLE) == 0) + break; // We found an available hw breakpoint slot (in i) + } + + // See if we found an available hw breakpoint slot above + if (i < num_hw_breakpoints) { + m_state.dbg.__bvr[i] = aligned_bp_address; + m_state.dbg.__bcr[i] = control_value; + + DNBLogThreadedIf(LOG_WATCHPOINTS, + "DNBArchMachARM64::EnableHardwareBreakpoint() " + "adding breakpoint on address 0x%llx with control " + "register value 0x%x", + (uint64_t)m_state.dbg.__bvr[i], + (uint32_t)m_state.dbg.__bcr[i]); + + // The kernel will set the MDE_ENABLE bit in the MDSCR_EL1 for us + // automatically, don't need to do it here. + kret = SetDBGState(also_set_on_task); + + DNBLogThreadedIf(LOG_WATCHPOINTS, + "DNBArchMachARM64::" + "EnableHardwareBreakpoint() " + "SetDBGState() => 0x%8.8x.", + kret); + + if (kret == KERN_SUCCESS) + return i; + } else { + DNBLogThreadedIf(LOG_WATCHPOINTS, + "DNBArchMachARM64::" + "EnableHardwareBreakpoint(): All " + "hardware resources (%u) are in use.", + num_hw_breakpoints); + } + } + return INVALID_NUB_HW_INDEX; +} + uint32_t DNBArchMachARM64::EnableHardwareWatchpoint(nub_addr_t addr, nub_size_t size, bool read, bool write, @@ -905,6 +1009,32 @@ bool DNBArchMachARM64::DisableHardwareWatchpoint_helper(uint32_t hw_index, return (kret == KERN_SUCCESS); } +bool DNBArchMachARM64::DisableHardwareBreakpoint(uint32_t hw_index, + bool also_set_on_task) { + kern_return_t kret = GetDBGState(false); + if (kret != KERN_SUCCESS) + return false; + + const uint32_t num_hw_points = NumSupportedHardwareBreakpoints(); + if (hw_index >= num_hw_points) + return false; + + m_disabled_breakpoints[hw_index].addr = m_state.dbg.__bvr[hw_index]; + m_disabled_breakpoints[hw_index].control = m_state.dbg.__bcr[hw_index]; + + m_state.dbg.__bcr[hw_index] = 0; + DNBLogThreadedIf(LOG_WATCHPOINTS, + "DNBArchMachARM64::" + "DisableHardwareBreakpoint( %u ) - WVR%u = " + "0x%8.8llx BCR%u = 0x%8.8llx", + hw_index, hw_index, (uint64_t)m_state.dbg.__bvr[hw_index], + hw_index, (uint64_t)m_state.dbg.__bcr[hw_index]); + + kret = SetDBGState(also_set_on_task); + + return (kret == KERN_SUCCESS); +} + // This is for checking the Byte Address Select bits in the DBRWCRn_EL1 control // register. // Returns -1 if the trailing bit patterns are not one of: @@ -935,31 +1065,34 @@ uint32_t DNBArchMachARM64::GetHardwareWatchpointHit(nub_addr_t &addr) { "DNBArchMachARM64::GetHardwareWatchpointHit() addr = 0x%llx", (uint64_t)addr); - // This is the watchpoint value to match against, i.e., word address. - nub_addr_t wp_val = addr & ~((nub_addr_t)3); if (kret == KERN_SUCCESS) { DBG &debug_state = m_state.dbg; uint32_t i, num = NumSupportedHardwareWatchpoints(); for (i = 0; i < num; ++i) { nub_addr_t wp_addr = GetWatchAddress(debug_state, i); - DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM64::" - "GetHardwareWatchpointHit() slot: %u " - "(addr = 0x%llx).", - i, (uint64_t)wp_addr); - if (wp_val == wp_addr) { - uint32_t byte_mask = bits(debug_state.__wcr[i], 12, 5); - - // Sanity check the byte_mask, first. - if (LowestBitSet(byte_mask) < 0) - continue; - - // Check that the watchpoint is enabled. - if (!IsWatchpointEnabled(debug_state, i)) - continue; - - // Compute the starting address (from the point of view of the - // debugger). - addr = wp_addr + LowestBitSet(byte_mask); + uint32_t byte_mask = bits(debug_state.__wcr[i], 12, 5); + + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::" + "GetHardwareWatchpointHit() slot: %u " + "(addr = 0x%llx; byte_mask = 0x%x)", + i, static_cast(wp_addr), + byte_mask); + + if (!IsWatchpointEnabled(debug_state, i)) + continue; + + if (bits(wp_addr, 48, 3) != bits(addr, 48, 3)) + continue; + + // Sanity check the byte_mask + uint32_t lsb = LowestBitSet(byte_mask); + if (lsb < 0) + continue; + + uint64_t byte_to_match = bits(addr, 2, 0); + + if (byte_mask & (1 << byte_to_match)) { + addr = wp_addr + lsb; return i; } } diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.h index 2c59a0ceb5d..fafcb73837b 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __DNBArchImplARM64_h__ -#define __DNBArchImplARM64_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_ARM64_DNBARCHIMPLARM64_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_ARM64_DNBARCHIMPLARM64_H #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) @@ -26,10 +26,12 @@ public: DNBArchMachARM64(MachThread *thread) : m_thread(thread), m_state(), m_disabled_watchpoints(), - m_watchpoint_hw_index(-1), m_watchpoint_did_occur(false), + m_disabled_breakpoints(), m_watchpoint_hw_index(-1), + m_watchpoint_did_occur(false), m_watchpoint_resume_single_step_enabled(false), m_saved_register_states() { m_disabled_watchpoints.resize(16); + m_disabled_breakpoints.resize(16); memset(&m_dbg_save, 0, sizeof(m_dbg_save)); } @@ -62,7 +64,13 @@ public: static const uint8_t *SoftwareBreakpointOpcode(nub_size_t byte_size); static uint32_t GetCPUType(); + virtual uint32_t NumSupportedHardwareBreakpoints(); virtual uint32_t NumSupportedHardwareWatchpoints(); + + virtual uint32_t EnableHardwareBreakpoint(nub_addr_t addr, nub_size_t size, + bool also_set_on_task); + virtual bool DisableHardwareBreakpoint(uint32_t hw_break_index, + bool also_set_on_task); virtual uint32_t EnableHardwareWatchpoint(nub_addr_t addr, nub_size_t size, bool read, bool write, bool also_set_on_task); @@ -229,10 +237,11 @@ protected: State m_state; arm_debug_state64_t m_dbg_save; - // arm64 doesn't keep the disabled watchpoint values in the debug register - // context like armv7; + // arm64 doesn't keep the disabled watchpoint and breakpoint values in the + // debug register context like armv7; // we need to save them aside when we disable them temporarily. std::vector m_disabled_watchpoints; + std::vector m_disabled_breakpoints; // The following member variables should be updated atomically. int32_t m_watchpoint_hw_index; @@ -245,4 +254,4 @@ protected: #endif // #if defined (ARM_THREAD_STATE64_COUNT) #endif // #if defined (__arm__) -#endif // #ifndef __DNBArchImplARM64_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_ARM64_DNBARCHIMPLARM64_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp index 7d2d0c2ef1b..27bc7511062 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp @@ -718,6 +718,11 @@ bool DNBArchImplI386::NotifyException(MachException::Data &exc) { return false; } +uint32_t DNBArchImplI386::NumSupportedHardwareBreakpoints() { + // Available debug address registers: dr0, dr1, dr2, dr3. + return 4; +} + uint32_t DNBArchImplI386::NumSupportedHardwareWatchpoints() { // Available debug address registers: dr0, dr1, dr2, dr3. return 4; @@ -797,6 +802,151 @@ void DNBArchImplI386::SetWatchpoint(DBG &debug_state, uint32_t hw_index, return; } +void DNBArchImplI386::SetHardwareBreakpoint(DBG &debug_state, uint32_t hw_index, + nub_addr_t addr, nub_size_t size) { + // Set both dr7 (debug control register) and dri (debug address register). + + // dr7{7-0} encodes the local/gloabl enable bits: + // global enable --. .-- local enable + // | | + // v v + // dr0 -> bits{1-0} + // dr1 -> bits{3-2} + // dr2 -> bits{5-4} + // dr3 -> bits{7-6} + // + // dr7{31-16} encodes the rw/len bits: + // b_x+3, b_x+2, b_x+1, b_x + // where bits{x+1, x} => rw + // 0b00: execute, 0b01: write, 0b11: read-or-write, 0b10: io + // read-or-write (unused) + // and bits{x+3, x+2} => len + // 0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte + // + // dr0 -> bits{19-16} + // dr1 -> bits{23-20} + // dr2 -> bits{27-24} + // dr3 -> bits{31-28} + debug_state.__dr7 |= (1 << (2 * hw_index) | 0 << (16 + 4 * hw_index)); + uint32_t addr_32 = addr & 0xffffffff; + switch (hw_index) { + case 0: + debug_state.__dr0 = addr_32; + break; + case 1: + debug_state.__dr1 = addr_32; + break; + case 2: + debug_state.__dr2 = addr_32; + break; + case 3: + debug_state.__dr3 = addr_32; + break; + default: + assert(0 && + "invalid hardware register index, must be one of 0, 1, 2, or 3"); + } + return; +} + +uint32_t DNBArchImplI386::EnableHardwareBreakpoint(nub_addr_t addr, + nub_size_t size, + bool also_set_on_task) { + DNBLogThreadedIf(LOG_BREAKPOINTS, + "DNBArchImplI386::EnableHardwareBreakpoint( addr = " + "0x%8.8llx, size = %llu )", + (uint64_t)addr, (uint64_t)size); + + const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints(); + // Read the debug state + kern_return_t kret = GetDBGState(false); + + if (kret != KERN_SUCCESS) { + return INVALID_NUB_HW_INDEX; + } + + // Check to make sure we have the needed hardware support + uint32_t i = 0; + + DBG &debug_state = m_state.context.dbg; + for (i = 0; i < num_hw_breakpoints; ++i) { + if (IsWatchpointVacant(debug_state, i)) { + break; + } + } + + // See if we found an available hw breakpoint slot above + if (i < num_hw_breakpoints) { + DNBLogThreadedIf( + LOG_BREAKPOINTS, + "DNBArchImplI386::EnableHardwareBreakpoint( free slot = %u )", i); + + StartTransForHWP(); + + // Modify our local copy of the debug state, first. + SetHardwareBreakpoint(debug_state, i, addr, size); + // Now set the watch point in the inferior. + kret = SetDBGState(also_set_on_task); + + DNBLogThreadedIf(LOG_BREAKPOINTS, + "DNBArchImplI386::" + "EnableHardwareBreakpoint() " + "SetDBGState() => 0x%8.8x.", + kret); + + if (kret == KERN_SUCCESS) { + DNBLogThreadedIf( + LOG_BREAKPOINTS, + "DNBArchImplI386::EnableHardwareBreakpoint( enabled at slot = %u)", + i); + return i; + } + // Revert to the previous debug state voluntarily. The transaction + // coordinator knows that we have failed. + else { + m_state.context.dbg = GetDBGCheckpoint(); + } + } else { + DNBLogThreadedIf(LOG_BREAKPOINTS, + "DNBArchImplI386::EnableHardwareBreakpoint(addr = " + "0x%8.8llx, size = %llu) => all hardware breakpoint " + "resources are being used.", + (uint64_t)addr, (uint64_t)size); + } + + return INVALID_NUB_HW_INDEX; +} + +bool DNBArchImplI386::DisableHardwareBreakpoint(uint32_t hw_index, + bool also_set_on_task) { + kern_return_t kret = GetDBGState(false); + + const uint32_t num_hw_points = NumSupportedHardwareBreakpoints(); + if (kret == KERN_SUCCESS) { + DBG &debug_state = m_state.context.dbg; + if (hw_index < num_hw_points && + !IsWatchpointVacant(debug_state, hw_index)) { + + StartTransForHWP(); + + // Modify our local copy of the debug state, first. + ClearWatchpoint(debug_state, hw_index); + // Now disable the watch point in the inferior. + kret = SetDBGState(true); + DNBLogThreadedIf(LOG_WATCHPOINTS, + "DNBArchImplI386::DisableHardwareBreakpoint( %u )", + hw_index); + + if (kret == KERN_SUCCESS) + return true; + else // Revert to the previous debug state voluntarily. The transaction + // coordinator knows that we have failed. + m_state.context.dbg = GetDBGCheckpoint(); + } + } + return false; +} + void DNBArchImplI386::ClearWatchpoint(DBG &debug_state, uint32_t hw_index) { debug_state.__dr7 &= ~(3 << (2 * hw_index)); switch (hw_index) { diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h index 12b515a2957..43594e890f5 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __DNBArchImplI386_h__ -#define __DNBArchImplI386_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_I386_DNBARCHIMPLI386_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_I386_DNBARCHIMPLI386_H #if defined(__i386__) || defined(__x86_64__) @@ -51,7 +51,12 @@ public: virtual bool ThreadDidStop(); virtual bool NotifyException(MachException::Data &exc); + virtual uint32_t NumSupportedHardwareBreakpoints(); virtual uint32_t NumSupportedHardwareWatchpoints(); + virtual uint32_t EnableHardwareBreakpoint(nub_addr_t addr, nub_size_t size, + bool also_set_on_task); + virtual bool DisableHardwareBreakpoint(uint32_t hw_index, + bool also_set_on_task); virtual uint32_t EnableHardwareWatchpoint(nub_addr_t addr, nub_size_t size, bool read, bool write, bool also_set_on_task); @@ -210,6 +215,9 @@ protected: static uint32_t GetRegisterContextSize(); + static void SetHardwareBreakpoint(DBG &debug_state, uint32_t hw_index, + nub_addr_t addr, nub_size_t size); + // Helper functions for watchpoint manipulations. static void SetWatchpoint(DBG &debug_state, uint32_t hw_index, nub_addr_t addr, nub_size_t size, bool read, @@ -235,4 +243,4 @@ protected: }; #endif // #if defined (__i386__) || defined (__x86_64__) -#endif // #ifndef __DNBArchImplI386_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_I386_DNBARCHIMPLI386_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/i386/MachRegisterStatesI386.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/i386/MachRegisterStatesI386.h index 6eab0ad7a5a..8458a283e84 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/i386/MachRegisterStatesI386.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/i386/MachRegisterStatesI386.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __MachRegisterStatesI386_h__ -#define __MachRegisterStatesI386_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_I386_MACHREGISTERSTATESI386_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_I386_MACHREGISTERSTATESI386_H #include diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp index 319215e8a7f..519b6277fd0 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp @@ -679,6 +679,12 @@ uint32_t DNBArchImplX86_64::NumSupportedHardwareWatchpoints() { return 4; } +uint32_t DNBArchImplX86_64::NumSupportedHardwareBreakpoints() { + DNBLogThreadedIf(LOG_BREAKPOINTS, + "DNBArchImplX86_64::NumSupportedHardwareBreakpoints"); + return 4; +} + static uint32_t size_and_rw_bits(nub_size_t size, bool read, bool write) { uint32_t rw; if (read) { @@ -853,6 +859,153 @@ DNBArchImplX86_64::DBG DNBArchImplX86_64::GetDBGCheckpoint() { return m_2pc_dbg_checkpoint; } +void DNBArchImplX86_64::SetHardwareBreakpoint(DBG &debug_state, + uint32_t hw_index, + nub_addr_t addr, + nub_size_t size) { + // Set both dr7 (debug control register) and dri (debug address register). + + // dr7{7-0} encodes the local/gloabl enable bits: + // global enable --. .-- local enable + // | | + // v v + // dr0 -> bits{1-0} + // dr1 -> bits{3-2} + // dr2 -> bits{5-4} + // dr3 -> bits{7-6} + // + // dr7{31-16} encodes the rw/len bits: + // b_x+3, b_x+2, b_x+1, b_x + // where bits{x+1, x} => rw + // 0b00: execute, 0b01: write, 0b11: read-or-write, 0b10: io + // read-or-write (unused) + // and bits{x+3, x+2} => len + // 0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte + // + // dr0 -> bits{19-16} + // dr1 -> bits{23-20} + // dr2 -> bits{27-24} + // dr3 -> bits{31-28} + debug_state.__dr7 |= (1 << (2 * hw_index) | 0 << (16 + 4 * hw_index)); + + switch (hw_index) { + case 0: + debug_state.__dr0 = addr; + break; + case 1: + debug_state.__dr1 = addr; + break; + case 2: + debug_state.__dr2 = addr; + break; + case 3: + debug_state.__dr3 = addr; + break; + default: + assert(0 && + "invalid hardware register index, must be one of 0, 1, 2, or 3"); + } + return; +} + +uint32_t DNBArchImplX86_64::EnableHardwareBreakpoint(nub_addr_t addr, + nub_size_t size, + bool also_set_on_task) { + DNBLogThreadedIf(LOG_BREAKPOINTS, + "DNBArchImplX86_64::EnableHardwareBreakpoint( addr = " + "0x%8.8llx, size = %llu )", + (uint64_t)addr, (uint64_t)size); + + const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints(); + // Read the debug state + kern_return_t kret = GetDBGState(false); + + if (kret != KERN_SUCCESS) { + return INVALID_NUB_HW_INDEX; + } + + // Check to make sure we have the needed hardware support + uint32_t i = 0; + + DBG &debug_state = m_state.context.dbg; + for (i = 0; i < num_hw_breakpoints; ++i) { + if (IsWatchpointVacant(debug_state, i)) { + break; + } + } + + // See if we found an available hw breakpoint slot above + if (i < num_hw_breakpoints) { + DNBLogThreadedIf( + LOG_BREAKPOINTS, + "DNBArchImplX86_64::EnableHardwareBreakpoint( free slot = %u )", i); + + StartTransForHWP(); + + // Modify our local copy of the debug state, first. + SetHardwareBreakpoint(debug_state, i, addr, size); + // Now set the watch point in the inferior. + kret = SetDBGState(also_set_on_task); + + DNBLogThreadedIf(LOG_BREAKPOINTS, + "DNBArchImplX86_64::" + "EnableHardwareBreakpoint() " + "SetDBGState() => 0x%8.8x.", + kret); + + if (kret == KERN_SUCCESS) { + DNBLogThreadedIf( + LOG_BREAKPOINTS, + "DNBArchImplX86_64::EnableHardwareBreakpoint( enabled at slot = %u)", + i); + return i; + } + // Revert to the previous debug state voluntarily. The transaction + // coordinator knows that we have failed. + else { + m_state.context.dbg = GetDBGCheckpoint(); + } + } else { + DNBLogThreadedIf(LOG_BREAKPOINTS, + "DNBArchImplX86_64::EnableHardwareBreakpoint(addr = " + "0x%8.8llx, size = %llu) => all hardware breakpoint " + "resources are being used.", + (uint64_t)addr, (uint64_t)size); + } + + return INVALID_NUB_HW_INDEX; +} + +bool DNBArchImplX86_64::DisableHardwareBreakpoint(uint32_t hw_index, + bool also_set_on_task) { + kern_return_t kret = GetDBGState(false); + + const uint32_t num_hw_points = NumSupportedHardwareBreakpoints(); + if (kret == KERN_SUCCESS) { + DBG &debug_state = m_state.context.dbg; + if (hw_index < num_hw_points && + !IsWatchpointVacant(debug_state, hw_index)) { + + StartTransForHWP(); + + // Modify our local copy of the debug state, first. + ClearWatchpoint(debug_state, hw_index); + // Now disable the watch point in the inferior. + kret = SetDBGState(true); + DNBLogThreadedIf(LOG_WATCHPOINTS, + "DNBArchImplX86_64::DisableHardwareBreakpoint( %u )", + hw_index); + + if (kret == KERN_SUCCESS) + return true; + else // Revert to the previous debug state voluntarily. The transaction + // coordinator knows that we have failed. + m_state.context.dbg = GetDBGCheckpoint(); + } + } + return false; +} + uint32_t DNBArchImplX86_64::EnableHardwareWatchpoint(nub_addr_t addr, nub_size_t size, bool read, bool write, diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h index 62ce37d4c04..0ed433f7f3a 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __DNBArchImplX86_64_h__ -#define __DNBArchImplX86_64_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_X86_64_DNBARCHIMPLX86_64_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_X86_64_DNBARCHIMPLX86_64_H #if defined(__i386__) || defined(__x86_64__) #include "DNBArch.h" @@ -50,7 +50,13 @@ public: virtual bool ThreadDidStop(); virtual bool NotifyException(MachException::Data &exc); + virtual uint32_t NumSupportedHardwareBreakpoints(); virtual uint32_t NumSupportedHardwareWatchpoints(); + + virtual uint32_t EnableHardwareBreakpoint(nub_addr_t addr, nub_size_t size, + bool also_set_on_task); + virtual bool DisableHardwareBreakpoint(uint32_t hw_break_index, + bool also_set_on_task); virtual uint32_t EnableHardwareWatchpoint(nub_addr_t addr, nub_size_t size, bool read, bool write, bool also_set_on_task); @@ -213,6 +219,9 @@ protected: static uint32_t GetRegisterContextSize(); + static void SetHardwareBreakpoint(DBG &debug_state, uint32_t hw_index, + nub_addr_t addr, nub_size_t size); + // Helper functions for watchpoint manipulations. static void SetWatchpoint(DBG &debug_state, uint32_t hw_index, nub_addr_t addr, nub_size_t size, bool read, @@ -238,4 +247,4 @@ protected: }; #endif // #if defined (__i386__) || defined (__x86_64__) -#endif // #ifndef __DNBArchImplX86_64_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_X86_64_DNBARCHIMPLX86_64_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/x86_64/MachRegisterStatesX86_64.h b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/x86_64/MachRegisterStatesX86_64.h index 81839666837..f53e0a753c3 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/MacOSX/x86_64/MachRegisterStatesX86_64.h +++ b/gnu/llvm/lldb/tools/debugserver/source/MacOSX/x86_64/MachRegisterStatesX86_64.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __MachRegisterStatesX86_64_h__ -#define __MachRegisterStatesX86_64_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_X86_64_MACHREGISTERSTATESX86_64_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_X86_64_MACHREGISTERSTATESX86_64_H #include diff --git a/gnu/llvm/lldb/tools/debugserver/source/PThreadCondition.h b/gnu/llvm/lldb/tools/debugserver/source/PThreadCondition.h index 2f9060da028..d77d1621976 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/PThreadCondition.h +++ b/gnu/llvm/lldb/tools/debugserver/source/PThreadCondition.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __PThreadCondition_h__ -#define __PThreadCondition_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_PTHREADCONDITION_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_PTHREADCONDITION_H #include diff --git a/gnu/llvm/lldb/tools/debugserver/source/PThreadEvent.h b/gnu/llvm/lldb/tools/debugserver/source/PThreadEvent.h index f81798de5c7..da3d9d47677 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/PThreadEvent.h +++ b/gnu/llvm/lldb/tools/debugserver/source/PThreadEvent.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __PThreadEvent_h__ -#define __PThreadEvent_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_PTHREADEVENT_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_PTHREADEVENT_H #include "PThreadCondition.h" #include "PThreadMutex.h" #include @@ -58,4 +58,4 @@ private: PThreadEvent &operator=(const PThreadEvent &rhs) = delete; }; -#endif // #ifndef __PThreadEvent_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_PTHREADEVENT_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/PThreadMutex.h b/gnu/llvm/lldb/tools/debugserver/source/PThreadMutex.h index 075fdc9114f..dce2e561b93 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/PThreadMutex.h +++ b/gnu/llvm/lldb/tools/debugserver/source/PThreadMutex.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __PThreadMutex_h__ -#define __PThreadMutex_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_PTHREADMUTEX_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_PTHREADMUTEX_H #include #include diff --git a/gnu/llvm/lldb/tools/debugserver/source/PseudoTerminal.cpp b/gnu/llvm/lldb/tools/debugserver/source/PseudoTerminal.cpp index cac8bda6248..fb91d74a6cc 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/PseudoTerminal.cpp +++ b/gnu/llvm/lldb/tools/debugserver/source/PseudoTerminal.cpp @@ -17,119 +17,119 @@ // PseudoTerminal constructor PseudoTerminal::PseudoTerminal() - : m_master_fd(invalid_fd), m_slave_fd(invalid_fd) {} + : m_primary_fd(invalid_fd), m_secondary_fd(invalid_fd) {} // Destructor -// The master and slave file descriptors will get closed if they are -// valid. Call the ReleaseMasterFD()/ReleaseSlaveFD() member functions +// The primary and secondary file descriptors will get closed if they are +// valid. Call the ReleasePrimaryFD()/ReleaseSecondaryFD() member functions // to release any file descriptors that are needed beyond the lifespan // of this object. PseudoTerminal::~PseudoTerminal() { - CloseMaster(); - CloseSlave(); + ClosePrimary(); + CloseSecondary(); } -// Close the master file descriptor if it is valid. -void PseudoTerminal::CloseMaster() { - if (m_master_fd > 0) { - ::close(m_master_fd); - m_master_fd = invalid_fd; +// Close the primary file descriptor if it is valid. +void PseudoTerminal::ClosePrimary() { + if (m_primary_fd > 0) { + ::close(m_primary_fd); + m_primary_fd = invalid_fd; } } -// Close the slave file descriptor if it is valid. -void PseudoTerminal::CloseSlave() { - if (m_slave_fd > 0) { - ::close(m_slave_fd); - m_slave_fd = invalid_fd; +// Close the secondary file descriptor if it is valid. +void PseudoTerminal::CloseSecondary() { + if (m_secondary_fd > 0) { + ::close(m_secondary_fd); + m_secondary_fd = invalid_fd; } } // Open the first available pseudo terminal with OFLAG as the -// permissions. The file descriptor is store in the m_master_fd member -// variable and can be accessed via the MasterFD() or ReleaseMasterFD() +// permissions. The file descriptor is store in the m_primary_fd member +// variable and can be accessed via the PrimaryFD() or ReleasePrimaryFD() // accessors. // // Suggested value for oflag is O_RDWR|O_NOCTTY // // RETURNS: // Zero when successful, non-zero indicating an error occurred. -PseudoTerminal::Status PseudoTerminal::OpenFirstAvailableMaster(int oflag) { - // Open the master side of a pseudo terminal - m_master_fd = ::posix_openpt(oflag); - if (m_master_fd < 0) { +PseudoTerminal::Status PseudoTerminal::OpenFirstAvailablePrimary(int oflag) { + // Open the primary side of a pseudo terminal + m_primary_fd = ::posix_openpt(oflag); + if (m_primary_fd < 0) { return err_posix_openpt_failed; } - // Grant access to the slave pseudo terminal - if (::grantpt(m_master_fd) < 0) { - CloseMaster(); + // Grant access to the secondary pseudo terminal + if (::grantpt(m_primary_fd) < 0) { + ClosePrimary(); return err_grantpt_failed; } - // Clear the lock flag on the slave pseudo terminal - if (::unlockpt(m_master_fd) < 0) { - CloseMaster(); + // Clear the lock flag on the secondary pseudo terminal + if (::unlockpt(m_primary_fd) < 0) { + ClosePrimary(); return err_unlockpt_failed; } return success; } -// Open the slave pseudo terminal for the current master pseudo -// terminal. A master pseudo terminal should already be valid prior to -// calling this function (see PseudoTerminal::OpenFirstAvailableMaster()). -// The file descriptor is stored in the m_slave_fd member variable and -// can be accessed via the SlaveFD() or ReleaseSlaveFD() accessors. +// Open the secondary pseudo terminal for the current primary pseudo +// terminal. A primary pseudo terminal should already be valid prior to +// calling this function (see PseudoTerminal::OpenFirstAvailablePrimary()). +// The file descriptor is stored in the m_secondary_fd member variable and +// can be accessed via the SecondaryFD() or ReleaseSecondaryFD() accessors. // // RETURNS: // Zero when successful, non-zero indicating an error occurred. -PseudoTerminal::Status PseudoTerminal::OpenSlave(int oflag) { - CloseSlave(); +PseudoTerminal::Status PseudoTerminal::OpenSecondary(int oflag) { + CloseSecondary(); - // Open the master side of a pseudo terminal - const char *slave_name = SlaveName(); + // Open the primary side of a pseudo terminal + const char *secondary_name = SecondaryName(); - if (slave_name == NULL) + if (secondary_name == NULL) return err_ptsname_failed; - m_slave_fd = ::open(slave_name, oflag); + m_secondary_fd = ::open(secondary_name, oflag); - if (m_slave_fd < 0) - return err_open_slave_failed; + if (m_secondary_fd < 0) + return err_open_secondary_failed; return success; } -// Get the name of the slave pseudo terminal. A master pseudo terminal +// Get the name of the secondary pseudo terminal. A primary pseudo terminal // should already be valid prior to calling this function (see -// PseudoTerminal::OpenFirstAvailableMaster()). +// PseudoTerminal::OpenFirstAvailablePrimary()). // // RETURNS: -// NULL if no valid master pseudo terminal or if ptsname() fails. -// The name of the slave pseudo terminal as a NULL terminated C string +// NULL if no valid primary pseudo terminal or if ptsname() fails. +// The name of the secondary pseudo terminal as a NULL terminated C string // that comes from static memory, so a copy of the string should be // made as subsequent calls can change this value. -const char *PseudoTerminal::SlaveName() const { - if (m_master_fd < 0) +const char *PseudoTerminal::SecondaryName() const { + if (m_primary_fd < 0) return NULL; - return ::ptsname(m_master_fd); + return ::ptsname(m_primary_fd); } // Fork a child process that and have its stdio routed to a pseudo // terminal. // -// In the parent process when a valid pid is returned, the master file +// In the parent process when a valid pid is returned, the primary file // descriptor can be used as a read/write access to stdio of the // child process. // // In the child process the stdin/stdout/stderr will already be routed -// to the slave pseudo terminal and the master file descriptor will be +// to the secondary pseudo terminal and the primary file descriptor will be // closed as it is no longer needed by the child process. // -// This class will close the file descriptors for the master/slave -// when the destructor is called, so be sure to call ReleaseMasterFD() -// or ReleaseSlaveFD() if any file descriptors are going to be used +// This class will close the file descriptors for the primary/secondary +// when the destructor is called, so be sure to call ReleasePrimaryFD() +// or ReleaseSecondaryFD() if any file descriptors are going to be used // past the lifespan of this object. // // RETURNS: @@ -138,10 +138,10 @@ const char *PseudoTerminal::SlaveName() const { pid_t PseudoTerminal::Fork(PseudoTerminal::Status &error) { pid_t pid = invalid_pid; - error = OpenFirstAvailableMaster(O_RDWR | O_NOCTTY); + error = OpenFirstAvailablePrimary(O_RDWR | O_NOCTTY); if (error == 0) { - // Successfully opened our master pseudo terminal + // Successfully opened our primary pseudo terminal pid = ::fork(); if (pid < 0) { @@ -151,23 +151,23 @@ pid_t PseudoTerminal::Fork(PseudoTerminal::Status &error) { // Child Process ::setsid(); - error = OpenSlave(O_RDWR); + error = OpenSecondary(O_RDWR); if (error == 0) { - // Successfully opened slave - // We are done with the master in the child process so lets close it - CloseMaster(); + // Successfully opened secondary + // We are done with the primary in the child process so lets close it + ClosePrimary(); #if defined(TIOCSCTTY) // Acquire the controlling terminal - if (::ioctl(m_slave_fd, TIOCSCTTY, (char *)0) < 0) + if (::ioctl(m_secondary_fd, TIOCSCTTY, (char *)0) < 0) error = err_failed_to_acquire_controlling_terminal; #endif - // Duplicate all stdio file descriptors to the slave pseudo terminal - if (::dup2(m_slave_fd, STDIN_FILENO) != STDIN_FILENO) + // Duplicate all stdio file descriptors to the secondary pseudo terminal + if (::dup2(m_secondary_fd, STDIN_FILENO) != STDIN_FILENO) error = error ? error : err_dup2_failed_on_stdin; - if (::dup2(m_slave_fd, STDOUT_FILENO) != STDOUT_FILENO) + if (::dup2(m_secondary_fd, STDOUT_FILENO) != STDOUT_FILENO) error = error ? error : err_dup2_failed_on_stdout; - if (::dup2(m_slave_fd, STDERR_FILENO) != STDERR_FILENO) + if (::dup2(m_secondary_fd, STDERR_FILENO) != STDERR_FILENO) error = error ? error : err_dup2_failed_on_stderr; } } else { diff --git a/gnu/llvm/lldb/tools/debugserver/source/PseudoTerminal.h b/gnu/llvm/lldb/tools/debugserver/source/PseudoTerminal.h index e3324c1c358..1f49bd2c4fe 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/PseudoTerminal.h +++ b/gnu/llvm/lldb/tools/debugserver/source/PseudoTerminal.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __PseudoTerminal_h__ -#define __PseudoTerminal_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_PSEUDOTERMINAL_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_PSEUDOTERMINAL_H #include #include @@ -27,7 +27,7 @@ public: err_grantpt_failed = -3, err_unlockpt_failed = -4, err_ptsname_failed = -5, - err_open_slave_failed = -6, + err_open_secondary_failed = -6, err_fork_failed = -7, err_setsid_failed = -8, err_failed_to_acquire_controlling_terminal = -9, @@ -39,41 +39,41 @@ public: PseudoTerminal(); ~PseudoTerminal(); - void CloseMaster(); - void CloseSlave(); - Status OpenFirstAvailableMaster(int oflag); - Status OpenSlave(int oflag); - int MasterFD() const { return m_master_fd; } - int SlaveFD() const { return m_slave_fd; } - int ReleaseMasterFD() { - // Release ownership of the master pseudo terminal file + void ClosePrimary(); + void CloseSecondary(); + Status OpenFirstAvailablePrimary(int oflag); + Status OpenSecondary(int oflag); + int PrimaryFD() const { return m_primary_fd; } + int SecondaryFD() const { return m_secondary_fd; } + int ReleasePrimaryFD() { + // Release ownership of the primary pseudo terminal file // descriptor without closing it. (the destructor for this // class will close it otherwise!) - int fd = m_master_fd; - m_master_fd = invalid_fd; + int fd = m_primary_fd; + m_primary_fd = invalid_fd; return fd; } - int ReleaseSlaveFD() { - // Release ownership of the slave pseudo terminal file + int ReleaseSecondaryFD() { + // Release ownership of the secondary pseudo terminal file // descriptor without closing it (the destructor for this // class will close it otherwise!) - int fd = m_slave_fd; - m_slave_fd = invalid_fd; + int fd = m_secondary_fd; + m_secondary_fd = invalid_fd; return fd; } - const char *SlaveName() const; + const char *SecondaryName() const; pid_t Fork(Status &error); protected: // Classes that inherit from PseudoTerminal can see and modify these - int m_master_fd; - int m_slave_fd; + int m_primary_fd; + int m_secondary_fd; private: PseudoTerminal(const PseudoTerminal &rhs) = delete; PseudoTerminal &operator=(const PseudoTerminal &rhs) = delete; }; -#endif // #ifndef __PseudoTerminal_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_PSEUDOTERMINAL_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/RNBContext.h b/gnu/llvm/lldb/tools/debugserver/source/RNBContext.h index 946dfb2eb10..7d8f458ce0f 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/RNBContext.h +++ b/gnu/llvm/lldb/tools/debugserver/source/RNBContext.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __RNBContext_h__ -#define __RNBContext_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBCONTEXT_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBCONTEXT_H #include "DNBError.h" #include "PThreadEvent.h" @@ -153,4 +153,4 @@ private: RNBContext &operator=(const RNBContext &rhs) = delete; }; -#endif // #ifndef __RNBContext_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBCONTEXT_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/RNBDefs.h b/gnu/llvm/lldb/tools/debugserver/source/RNBDefs.h index 4cc7c220b7f..a5322ae25f8 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/RNBDefs.h +++ b/gnu/llvm/lldb/tools/debugserver/source/RNBDefs.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __RNBDefs_h__ -#define __RNBDefs_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBDEFS_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBDEFS_H #include "DNBDefs.h" #include @@ -50,14 +50,6 @@ extern "C" const double CONCAT(DEBUGSERVER_PROGRAM_SYMBOL, VersionNumber); #define RNB_ARCH "x86_64" -#elif defined(__ppc64__) - -#define RNB_ARCH "ppc64" - -#elif defined(__powerpc__) || defined(__ppc__) - -#define RNB_ARCH "ppc" - #elif defined(__arm64__) || defined(__aarch64__) #define RNB_ARCH "arm64" @@ -95,4 +87,4 @@ enum rnb_err_t { rnb_success = 0, rnb_err = 1, rnb_not_connected = 2 }; extern RNBRemoteSP g_remoteSP; -#endif // #ifndef __RNBDefs_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBDEFS_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/RNBRemote.cpp b/gnu/llvm/lldb/tools/debugserver/source/RNBRemote.cpp index 64e3bc49abc..8a3045564aa 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/gnu/llvm/lldb/tools/debugserver/source/RNBRemote.cpp @@ -12,9 +12,14 @@ #include "RNBRemote.h" +#include +#include #include +#include #include #include +#include +#include #include #include #include @@ -49,6 +54,9 @@ #include #include +#include +#include + // constants static const std::string OS_LOG_EVENTS_KEY_NAME("events"); @@ -279,12 +287,10 @@ void RNBRemote::CreatePacketTable() { "x", "Read data from memory")); t.push_back(Packet(write_data_to_memory, &RNBRemote::HandlePacket_X, NULL, "X", "Write data to memory")); - // t.push_back (Packet (insert_hardware_bp, - // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "Z1", "Insert hardware - // breakpoint")); - // t.push_back (Packet (remove_hardware_bp, - // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "z1", "Remove hardware - // breakpoint")); + t.push_back(Packet(insert_hardware_bp, &RNBRemote::HandlePacket_z, NULL, "Z1", + "Insert hardware breakpoint")); + t.push_back(Packet(remove_hardware_bp, &RNBRemote::HandlePacket_z, NULL, "z1", + "Remove hardware breakpoint")); t.push_back(Packet(insert_write_watch_bp, &RNBRemote::HandlePacket_z, NULL, "Z2", "Insert write watchpoint")); t.push_back(Packet(remove_write_watch_bp, &RNBRemote::HandlePacket_z, NULL, @@ -1637,7 +1643,9 @@ rnb_err_t RNBRemote::HandlePacket_qLaunchSuccess(const char *p) { return SendPacket("OK"); std::ostringstream ret_str; std::string status_str; - ret_str << "E" << m_ctx.LaunchStatusAsString(status_str); + std::string error_quoted = binary_encode_string + (m_ctx.LaunchStatusAsString(status_str)); + ret_str << "E" << error_quoted; return SendPacket(ret_str.str()); } @@ -2671,8 +2679,9 @@ std::string cstring_to_asciihex_string(const char *str) { std::string hex_str; hex_str.reserve (strlen (str) * 2); while (str && *str) { + uint8_t c = *str++; char hexbuf[5]; - snprintf (hexbuf, sizeof(hexbuf), "%02x", *str++); + snprintf (hexbuf, sizeof(hexbuf), "%02x", c); hex_str += hexbuf; } return hex_str; @@ -3646,6 +3655,173 @@ rnb_err_t RNBRemote::HandlePacket_qSupported(const char *p) { return SendPacket(buf); } +static bool process_does_not_exist (nub_process_t pid) { + std::vector proc_infos; + DNBGetAllInfos (proc_infos); + const size_t infos_size = proc_infos.size(); + for (size_t i = 0; i < infos_size; i++) + if (proc_infos[i].kp_proc.p_pid == pid) + return false; + + return true; // process does not exist +} + +// my_uid and process_uid are only initialized if this function +// returns true -- that there was a uid mismatch -- and those +// id's may want to be used in the error message. +// +// NOTE: this should only be called after process_does_not_exist(). +// This sysctl will return uninitialized data if we ask for a pid +// that doesn't exist. The alternative would be to fetch all +// processes and step through to find the one we're looking for +// (as process_does_not_exist() does). +static bool attach_failed_due_to_uid_mismatch (nub_process_t pid, + uid_t &my_uid, + uid_t &process_uid) { + struct kinfo_proc kinfo; + int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; + size_t len = sizeof(struct kinfo_proc); + if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &kinfo, &len, NULL, 0) != 0) { + return false; // pid doesn't exist? can't check uid mismatch - it was fine + } + my_uid = geteuid(); + if (my_uid == 0) + return false; // if we're root, attach didn't fail because of uid mismatch + process_uid = kinfo.kp_eproc.e_ucred.cr_uid; + + // If my uid != the process' uid, then the attach probably failed because + // of that. + if (my_uid != process_uid) + return true; + else + return false; +} + +// NOTE: this should only be called after process_does_not_exist(). +// This sysctl will return uninitialized data if we ask for a pid +// that doesn't exist. The alternative would be to fetch all +// processes and step through to find the one we're looking for +// (as process_does_not_exist() does). +static bool process_is_already_being_debugged (nub_process_t pid) { + struct kinfo_proc kinfo; + int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; + size_t len = sizeof(struct kinfo_proc); + if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &kinfo, &len, NULL, 0) != 0) { + return false; // pid doesn't exist? well, it's not being debugged... + } + if (kinfo.kp_proc.p_flag & P_TRACED) + return true; // is being debugged already + else + return false; +} + +// Test if this current login session has a connection to the +// window server (if it does not have that access, it cannot ask +// for debug permission by popping up a dialog box and attach +// may fail outright). +static bool login_session_has_gui_access () { + // I believe this API only works on macOS. +#if TARGET_OS_OSX == 0 + return true; +#else + auditinfo_addr_t info; + getaudit_addr(&info, sizeof(info)); + if (info.ai_flags & AU_SESSION_FLAG_HAS_GRAPHIC_ACCESS) + return true; + else + return false; +#endif +} + +// Checking for +// +// { +// 'class' : 'rule', +// 'comment' : 'For use by Apple. WARNING: administrators are advised +// not to modify this right.', +// 'k-of-n' : '1', +// 'rule' : [ +// 'is-admin', +// 'is-developer', +// 'authenticate-developer' +// ] +// } +// +// $ security authorizationdb read system.privilege.taskport.debug + +static bool developer_mode_enabled () { + // This API only exists on macOS. +#if TARGET_OS_OSX == 0 + return true; +#else + CFDictionaryRef currentRightDict = NULL; + const char *debug_right = "system.privilege.taskport.debug"; + // caller must free dictionary initialized by the following + OSStatus status = AuthorizationRightGet(debug_right, ¤tRightDict); + if (status != errAuthorizationSuccess) { + // could not check authorization + return true; + } + + bool devmode_enabled = true; + + if (!CFDictionaryContainsKey(currentRightDict, CFSTR("k-of-n"))) { + devmode_enabled = false; + } else { + CFNumberRef item = (CFNumberRef) CFDictionaryGetValue(currentRightDict, CFSTR("k-of-n")); + if (item && CFGetTypeID(item) == CFNumberGetTypeID()) { + int64_t num = 0; + ::CFNumberGetValue(item, kCFNumberSInt64Type, &num); + if (num != 1) { + devmode_enabled = false; + } + } else { + devmode_enabled = false; + } + } + + if (!CFDictionaryContainsKey(currentRightDict, CFSTR("class"))) { + devmode_enabled = false; + } else { + CFStringRef item = (CFStringRef) CFDictionaryGetValue(currentRightDict, CFSTR("class")); + if (item && CFGetTypeID(item) == CFStringGetTypeID()) { + char tmpbuf[128]; + if (CFStringGetCString (item, tmpbuf, sizeof(tmpbuf), CFStringGetSystemEncoding())) { + tmpbuf[sizeof (tmpbuf) - 1] = '\0'; + if (strcmp (tmpbuf, "rule") != 0) { + devmode_enabled = false; + } + } else { + devmode_enabled = false; + } + } else { + devmode_enabled = false; + } + } + + if (!CFDictionaryContainsKey(currentRightDict, CFSTR("rule"))) { + devmode_enabled = false; + } else { + CFArrayRef item = (CFArrayRef) CFDictionaryGetValue(currentRightDict, CFSTR("rule")); + if (item && CFGetTypeID(item) == CFArrayGetTypeID()) { + int count = ::CFArrayGetCount(item); + CFRange range = CFRangeMake (0, count); + if (!::CFArrayContainsValue (item, range, CFSTR("is-admin"))) + devmode_enabled = false; + if (!::CFArrayContainsValue (item, range, CFSTR("is-developer"))) + devmode_enabled = false; + if (!::CFArrayContainsValue (item, range, CFSTR("authenticate-developer"))) + devmode_enabled = false; + } else { + devmode_enabled = false; + } + } + ::CFRelease(currentRightDict); + + return devmode_enabled; +#endif // TARGET_OS_OSX +} + /* vAttach;pid @@ -3804,49 +3980,92 @@ rnb_err_t RNBRemote::HandlePacket_v(const char *p) { else m_ctx.LaunchStatus().SetErrorString("attach failed"); -#if defined(__APPLE__) && \ - (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101000) if (pid_attaching_to == INVALID_NUB_PROCESS && !attach_name.empty()) { pid_attaching_to = DNBProcessGetPIDByName(attach_name.c_str()); } - if (pid_attaching_to != INVALID_NUB_PROCESS && - strcmp(err_str, "No such process") != 0) { - // csr_check(CSR_ALLOW_TASK_FOR_PID) will be nonzero if System Integrity - // Protection is in effect. - if (csr_check(CSR_ALLOW_TASK_FOR_PID) != 0) { - bool attach_failed_due_to_sip = false; - - if (rootless_allows_task_for_pid(pid_attaching_to) == 0) { - attach_failed_due_to_sip = true; - } - if (!attach_failed_due_to_sip) { - int csops_flags = 0; - int retval = ::csops(pid_attaching_to, CS_OPS_STATUS, &csops_flags, - sizeof(csops_flags)); - if (retval != -1 && (csops_flags & CS_RESTRICT)) { - attach_failed_due_to_sip = true; - } + // attach_pid is INVALID_NUB_PROCESS - we did not succeed in attaching + // if the original request, pid_attaching_to, is available, see if we + // can figure out why we couldn't attach. Return an informative error + // string to lldb. + + if (pid_attaching_to != INVALID_NUB_PROCESS) { + // The order of these checks is important. + if (process_does_not_exist (pid_attaching_to)) { + DNBLogError("Tried to attach to pid that doesn't exist"); + std::string return_message = "E96;"; + return_message += cstring_to_asciihex_string("no such process."); + return SendPacket(return_message.c_str()); + } + if (process_is_already_being_debugged (pid_attaching_to)) { + DNBLogError("Tried to attach to process already being debugged"); + std::string return_message = "E96;"; + return_message += cstring_to_asciihex_string("tried to attach to " + "process already being debugged"); + return SendPacket(return_message.c_str()); + } + uid_t my_uid, process_uid; + if (attach_failed_due_to_uid_mismatch (pid_attaching_to, + my_uid, process_uid)) { + std::string my_username = "uid " + std::to_string (my_uid); + std::string process_username = "uid " + std::to_string (process_uid); + struct passwd *pw = getpwuid (my_uid); + if (pw && pw->pw_name) { + my_username = pw->pw_name; } - if (attach_failed_due_to_sip) { - std::string return_message = "E96;"; - return_message += cstring_to_asciihex_string( - "Process attach denied, possibly because " - "System Integrity Protection is enabled and " - "process does not allow attaching."); - - SendPacket(return_message.c_str()); - DNBLogError("Attach failed because process does not allow " - "attaching: \"%s\".", - err_str); - return rnb_err; + pw = getpwuid (process_uid); + if (pw && pw->pw_name) { + process_username = pw->pw_name; } + DNBLogError("Tried to attach to process with uid mismatch"); + std::string return_message = "E96;"; + std::string msg = "tried to attach to process as user '" + + my_username + "' and process is running " + "as user '" + process_username + "'"; + return_message += cstring_to_asciihex_string(msg.c_str()); + return SendPacket(return_message.c_str()); + } + if (!login_session_has_gui_access() && !developer_mode_enabled()) { + DNBLogError("Developer mode is not enabled and this is a " + "non-interactive session"); + std::string return_message = "E96;"; + return_message += cstring_to_asciihex_string("developer mode is " + "not enabled on this machine " + "and this is a non-interactive " + "debug session."); + return SendPacket(return_message.c_str()); + } + if (!login_session_has_gui_access()) { + DNBLogError("This is a non-interactive session"); + std::string return_message = "E96;"; + return_message += cstring_to_asciihex_string("this is a " + "non-interactive debug session, " + "cannot get permission to debug " + "processes."); + return SendPacket(return_message.c_str()); } } -#endif - - SendPacket("E01"); // E01 is our magic error value for attach failed. + std::string error_explainer = "attach failed"; + if (err_str[0] != '\0') { + // This is not a super helpful message for end users + if (strcmp (err_str, "unable to start the exception thread") == 0) { + snprintf (err_str, sizeof (err_str) - 1, + "Not allowed to attach to process. Look in the console " + "messages (Console.app), near the debugserver entries " + "when the attached failed. The subsystem that denied " + "the attach permission will likely have logged an " + "informative message about why it was denied."); + err_str[sizeof (err_str) - 1] = '\0'; + } + error_explainer += " ("; + error_explainer += err_str; + error_explainer += ")"; + } + std::string default_return_msg = "E96;"; + default_return_msg += cstring_to_asciihex_string + (error_explainer.c_str()); + SendPacket (default_return_msg.c_str()); DNBLogError("Attach failed: \"%s\".", err_str); return rnb_err; } @@ -4689,6 +4908,8 @@ rnb_err_t RNBRemote::HandlePacket_qHostInfo(const char *p) { strm << "ostype:watchos;"; #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 strm << "ostype:bridgeos;"; +#elif defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1 + strm << "ostype:macosx;"; #else strm << "ostype:ios;"; #endif @@ -6117,7 +6338,7 @@ rnb_err_t RNBRemote::HandlePacket_qProcessInfo(const char *p) { if (addr_size > 0) { rep << "ptrsize:" << std::dec << addr_size << ';'; -#if (defined(__x86_64__) || defined(__i386__)) +#if defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1 // Try and get the OS type by looking at the load commands in the main // executable and looking for a LC_VERSION_MIN load command. This is the // most reliable way to determine the "ostype" value when on desktop. @@ -6147,7 +6368,7 @@ rnb_err_t RNBRemote::HandlePacket_qProcessInfo(const char *p) { load_command_addr = load_command_addr + lc.cmdsize; } } -#endif // when compiling this on x86 targets +#endif // TARGET_OS_OSX } // If we weren't able to find the OS in a LC_VERSION_MIN load command, try @@ -6164,6 +6385,8 @@ rnb_err_t RNBRemote::HandlePacket_qProcessInfo(const char *p) { rep << "ostype:watchos;"; #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 rep << "ostype:bridgeos;"; +#elif defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1 + rep << "ostype:macosx;"; #else rep << "ostype:ios;"; #endif diff --git a/gnu/llvm/lldb/tools/debugserver/source/RNBRemote.h b/gnu/llvm/lldb/tools/debugserver/source/RNBRemote.h index 88d82091130..b0535372a32 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/RNBRemote.h +++ b/gnu/llvm/lldb/tools/debugserver/source/RNBRemote.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __RNBRemote_h__ -#define __RNBRemote_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBREMOTE_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBREMOTE_H #include "DNB.h" #include "PThreadMutex.h" @@ -428,4 +428,4 @@ protected: about how many bytes gdb might try to send in a single packet. */ #define DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE 399 -#endif // #ifndef __RNBRemote_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBREMOTE_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/RNBServices.cpp b/gnu/llvm/lldb/tools/debugserver/source/RNBServices.cpp index 085aaddfaf1..6e4b55e3e64 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/RNBServices.cpp +++ b/gnu/llvm/lldb/tools/debugserver/source/RNBServices.cpp @@ -12,6 +12,7 @@ #include "RNBServices.h" +#include "DNB.h" #include "CFString.h" #include "DNBLog.h" #include "MacOSX/CFUtils.h" @@ -28,16 +29,13 @@ #include #endif -// From DNB.cpp -size_t GetAllInfos(std::vector &proc_infos); - int GetProcesses(CFMutableArrayRef plistMutableArray, bool all_users) { if (plistMutableArray == NULL) return -1; // Running as root, get all processes std::vector proc_infos; - const size_t num_proc_infos = GetAllInfos(proc_infos); + const size_t num_proc_infos = DNBGetAllInfos(proc_infos); if (num_proc_infos > 0) { const pid_t our_pid = getpid(); const uid_t our_uid = getuid(); @@ -62,9 +60,8 @@ int GetProcesses(CFMutableArrayRef plistMutableArray, bool all_users) { proc_info.kp_proc.p_stat == SZOMB || // Zombies are bad, they like brains... proc_info.kp_proc.p_flag & P_TRACED || // Being debugged? - proc_info.kp_proc.p_flag & P_WEXIT || // Working on exiting? - proc_info.kp_proc.p_flag & - P_TRANSLATED) // Skip translated ppc (Rosetta) + proc_info.kp_proc.p_flag & P_WEXIT // Working on exiting? + ) continue; // Create a new mutable dictionary for each application diff --git a/gnu/llvm/lldb/tools/debugserver/source/RNBServices.h b/gnu/llvm/lldb/tools/debugserver/source/RNBServices.h index b7514f31b21..b4a18630708 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/RNBServices.h +++ b/gnu/llvm/lldb/tools/debugserver/source/RNBServices.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __RNBServices_h__ -#define __RNBServices_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBSERVICES_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBSERVICES_H #include "RNBDefs.h" #include @@ -25,4 +25,4 @@ int ListApplications(std::string &plist, bool opt_runningApps, bool opt_debuggable); -#endif // __RNBServices_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBSERVICES_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/RNBSocket.h b/gnu/llvm/lldb/tools/debugserver/source/RNBSocket.h index 2f68eb00f37..6e13b79506b 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/RNBSocket.h +++ b/gnu/llvm/lldb/tools/debugserver/source/RNBSocket.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __RNBSocket_h__ -#define __RNBSocket_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBSOCKET_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBSOCKET_H #include "DNBTimer.h" #include "RNBDefs.h" @@ -74,4 +74,4 @@ protected: DNBTimer m_timer; }; -#endif // #ifndef __RNBSocket_h__ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBSOCKET_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/StdStringExtractor.h b/gnu/llvm/lldb/tools/debugserver/source/StdStringExtractor.h index 5165240bd20..88544dc6638 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/StdStringExtractor.h +++ b/gnu/llvm/lldb/tools/debugserver/source/StdStringExtractor.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_StdStringExtractor_h_ -#define utility_StdStringExtractor_h_ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_STDSTRINGEXTRACTOR_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_STDSTRINGEXTRACTOR_H #include #include @@ -102,4 +102,4 @@ protected: // reached when decoding information }; -#endif // utility_StringExtractor_h_ +#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_STDSTRINGEXTRACTOR_H diff --git a/gnu/llvm/lldb/tools/debugserver/source/SysSignal.h b/gnu/llvm/lldb/tools/debugserver/source/SysSignal.h index b6fc67f9be7..bc7753ea5a7 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/SysSignal.h +++ b/gnu/llvm/lldb/tools/debugserver/source/SysSignal.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __SysSignal_h__ -#define __SysSignal_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_SYSSIGNAL_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_SYSSIGNAL_H class SysSignal { public: diff --git a/gnu/llvm/lldb/tools/debugserver/source/TTYState.h b/gnu/llvm/lldb/tools/debugserver/source/TTYState.h index 01ef579cc6c..ac70417c3a2 100644 --- a/gnu/llvm/lldb/tools/debugserver/source/TTYState.h +++ b/gnu/llvm/lldb/tools/debugserver/source/TTYState.h @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __TTYState_h__ -#define __TTYState_h__ +#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_TTYSTATE_H +#define LLDB_TOOLS_DEBUGSERVER_SOURCE_TTYSTATE_H #include #include diff --git a/gnu/llvm/lldb/tools/debugserver/source/com.apple.debugserver.posix.internal.plist b/gnu/llvm/lldb/tools/debugserver/source/com.apple.debugserver.posix.internal.plist new file mode 100644 index 00000000000..0ca9f5be68e --- /dev/null +++ b/gnu/llvm/lldb/tools/debugserver/source/com.apple.debugserver.posix.internal.plist @@ -0,0 +1,16 @@ + + + + + Label + com.apple.debugserver.posix.internal + ProgramArguments + + /Developer/usr/bin/debugserver + --lockdown + --launch=posix + + AllowByProxy + + + diff --git a/gnu/llvm/lldb/tools/driver/Driver.cpp b/gnu/llvm/lldb/tools/driver/Driver.cpp index 73874389aa1..cea9e5a44aa 100644 --- a/gnu/llvm/lldb/tools/driver/Driver.cpp +++ b/gnu/llvm/lldb/tools/driver/Driver.cpp @@ -9,6 +9,7 @@ #include "Driver.h" #include "lldb/API/SBCommandInterpreter.h" +#include "lldb/API/SBCommandInterpreterRunOptions.h" #include "lldb/API/SBCommandReturnObject.h" #include "lldb/API/SBDebugger.h" #include "lldb/API/SBFile.h" @@ -360,13 +361,8 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { if (m_option_data.m_process_name.empty() && m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID) { - // If the option data args array is empty that means the file was not - // specified with -f and we need to get it from the input args. - if (m_option_data.m_args.empty()) { - if (auto *arg = args.getLastArgNoClaim(OPT_INPUT)) { - m_option_data.m_args.push_back(arg->getAsString((args))); - } - } + for (auto *arg : args.filtered(OPT_INPUT)) + m_option_data.m_args.push_back(arg->getAsString((args))); // Any argument following -- is an argument for the inferior. if (auto *arg = args.getLastArgNoClaim(OPT_REM)) { @@ -587,74 +583,75 @@ int Driver::MainLoop() { const char *commands_data = commands_stream.GetData(); const size_t commands_size = commands_stream.GetSize(); - // The command file might have requested that we quit, this variable will - // track that. - bool quit_requested = false; - bool stopped_for_crash = false; + bool go_interactive = true; if ((commands_data != nullptr) && (commands_size != 0u)) { - bool success = true; FILE *commands_file = PrepareCommandsForSourcing(commands_data, commands_size); - if (commands_file != nullptr) { - m_debugger.SetInputFileHandle(commands_file, true); - - // Set the debugger into Sync mode when running the command file. - // Otherwise command files - // that run the target won't run in a sensible way. - bool old_async = m_debugger.GetAsync(); - m_debugger.SetAsync(false); - int num_errors = 0; - - SBCommandInterpreterRunOptions options; - options.SetStopOnError(true); - if (m_option_data.m_batch) - options.SetStopOnCrash(true); - - m_debugger.RunCommandInterpreter(handle_events, spawn_thread, options, - num_errors, quit_requested, - stopped_for_crash); - - if (m_option_data.m_batch && stopped_for_crash && - !m_option_data.m_after_crash_commands.empty()) { - SBStream crash_commands_stream; - WriteCommandsForSourcing(eCommandPlacementAfterCrash, - crash_commands_stream); - const char *crash_commands_data = crash_commands_stream.GetData(); - const size_t crash_commands_size = crash_commands_stream.GetSize(); - commands_file = PrepareCommandsForSourcing(crash_commands_data, - crash_commands_size); - if (commands_file != nullptr) { - bool local_quit_requested; - bool local_stopped_for_crash; - m_debugger.SetInputFileHandle(commands_file, true); - - m_debugger.RunCommandInterpreter(handle_events, spawn_thread, options, - num_errors, local_quit_requested, - local_stopped_for_crash); - if (local_quit_requested) - quit_requested = true; - } - } - m_debugger.SetAsync(old_async); - } else - success = false; - // Something went wrong with command pipe - if (!success) { + if (commands_file == nullptr) { + // We should have already printed an error in PrepareCommandsForSourcing. exit(1); } - } - // Now set the input file handle to STDIN and run the command - // interpreter again in interactive mode or repl mode and let the debugger - // take ownership of stdin + m_debugger.SetInputFileHandle(commands_file, true); + + // Set the debugger into Sync mode when running the command file. Otherwise + // command files that run the target won't run in a sensible way. + bool old_async = m_debugger.GetAsync(); + m_debugger.SetAsync(false); + + SBCommandInterpreterRunOptions options; + options.SetAutoHandleEvents(true); + options.SetSpawnThread(false); + options.SetStopOnError(true); + options.SetStopOnCrash(m_option_data.m_batch); + + SBCommandInterpreterRunResult results = + m_debugger.RunCommandInterpreter(options); + if (results.GetResult() == lldb::eCommandInterpreterResultQuitRequested) + go_interactive = false; + if (m_option_data.m_batch && + results.GetResult() != lldb::eCommandInterpreterResultInferiorCrash) + go_interactive = false; + + // When running in batch mode and stopped because of an error, exit with a + // non-zero exit status. + if (m_option_data.m_batch && + results.GetResult() == lldb::eCommandInterpreterResultCommandError) + exit(1); - bool go_interactive = true; - if (quit_requested) - go_interactive = false; - else if (m_option_data.m_batch && !stopped_for_crash) - go_interactive = false; + if (m_option_data.m_batch && + results.GetResult() == lldb::eCommandInterpreterResultInferiorCrash && + !m_option_data.m_after_crash_commands.empty()) { + SBStream crash_commands_stream; + WriteCommandsForSourcing(eCommandPlacementAfterCrash, + crash_commands_stream); + const char *crash_commands_data = crash_commands_stream.GetData(); + const size_t crash_commands_size = crash_commands_stream.GetSize(); + commands_file = + PrepareCommandsForSourcing(crash_commands_data, crash_commands_size); + if (commands_file != nullptr) { + m_debugger.SetInputFileHandle(commands_file, true); + SBCommandInterpreterRunResult local_results = + m_debugger.RunCommandInterpreter(options); + if (local_results.GetResult() == + lldb::eCommandInterpreterResultQuitRequested) + go_interactive = false; + + // When running in batch mode and an error occurred while sourcing + // the crash commands, exit with a non-zero exit status. + if (m_option_data.m_batch && + local_results.GetResult() == + lldb::eCommandInterpreterResultCommandError) + exit(1); + } + } + m_debugger.SetAsync(old_async); + } + // Now set the input file handle to STDIN and run the command interpreter + // again in interactive mode or repl mode and let the debugger take ownership + // of stdin. if (go_interactive) { m_debugger.SetInputFileHandle(stdin, true); @@ -763,10 +760,15 @@ EXAMPLES: The debugger can be started in several modes. Passing an executable as a positional argument prepares lldb to debug the - given executable. Arguments passed after -- are considered arguments to the - debugged executable. + given executable. To disambiguate between arguments passed to lldb and + arguments passed to the debugged executable, arguments starting with a - must + be passed after --. + + lldb --arch x86_64 /path/to/program program argument -- --arch arvm7 + + For convenience, passing the executable after -- is also supported. - lldb --arch x86_64 /path/to/program -- --arch arvm7 + lldb --arch x86_64 -- /path/to/program program argument --arch arvm7 Passing one of the attach options causes lldb to immediately attach to the given process. @@ -795,11 +797,12 @@ EXAMPLES: llvm::outs() << examples << '\n'; } -llvm::Optional InitializeReproducer(opt::InputArgList &input_args) { +llvm::Optional InitializeReproducer(llvm::StringRef argv0, + opt::InputArgList &input_args) { if (auto *replay_path = input_args.getLastArg(OPT_replay)) { - const bool skip_version_check = input_args.hasArg(OPT_skip_version_check); + const bool no_version_check = input_args.hasArg(OPT_no_version_check); if (const char *error = - SBReproducer::Replay(replay_path->getValue(), skip_version_check)) { + SBReproducer::Replay(replay_path->getValue(), no_version_check)) { WithColor::error() << "reproducer replay failed: " << error << '\n'; return 1; } @@ -807,9 +810,21 @@ llvm::Optional InitializeReproducer(opt::InputArgList &input_args) { } bool capture = input_args.hasArg(OPT_capture); + bool generate_on_exit = input_args.hasArg(OPT_generate_on_exit); auto *capture_path = input_args.getLastArg(OPT_capture_path); + if (generate_on_exit && !capture) { + WithColor::warning() + << "-reproducer-generate-on-exit specified without -capture\n"; + } + if (capture || capture_path) { + // Register the reproducer signal handler. + if (!input_args.hasArg(OPT_no_generate_on_signal)) { + llvm::sys::AddSignalHandler(reproducer_handler, + const_cast(argv0.data())); + } + if (capture_path) { if (!capture) WithColor::warning() << "-capture-path specified without -capture\n"; @@ -824,6 +839,8 @@ llvm::Optional InitializeReproducer(opt::InputArgList &input_args) { return 1; } } + if (generate_on_exit) + SBReproducer::SetAutoGenerate(true); } return llvm::None; @@ -840,24 +857,27 @@ int main(int argc, char const *argv[]) { unsigned MAC; ArrayRef arg_arr = makeArrayRef(argv + 1, argc - 1); opt::InputArgList input_args = T.ParseArgs(arg_arr, MAI, MAC); + llvm::StringRef argv0 = llvm::sys::path::filename(argv[0]); if (input_args.hasArg(OPT_help)) { - printHelp(T, llvm::sys::path::filename(argv[0])); + printHelp(T, argv0); return 0; } - for (auto *arg : input_args.filtered(OPT_UNKNOWN)) { - WithColor::warning() << "ignoring unknown option: " << arg->getSpelling() - << '\n'; + // Error out on unknown options. + if (input_args.hasArg(OPT_UNKNOWN)) { + for (auto *arg : input_args.filtered(OPT_UNKNOWN)) { + WithColor::error() << "unknown option: " << arg->getSpelling() << '\n'; + } + llvm::errs() << "Use '" << argv0 + << " --help' for a complete list of options.\n"; + return 1; } - if (auto exit_code = InitializeReproducer(input_args)) { + if (auto exit_code = InitializeReproducer(argv[0], input_args)) { return *exit_code; } - // Register the reproducer signal handler. - llvm::sys::AddSignalHandler(reproducer_handler, const_cast(argv[0])); - SBError error = SBDebugger::InitializeWithErrorHandling(); if (error.Fail()) { WithColor::error() << "initialization failed: " << error.GetCString() diff --git a/gnu/llvm/lldb/tools/driver/Driver.h b/gnu/llvm/lldb/tools/driver/Driver.h index f442458ae40..2d91491a254 100644 --- a/gnu/llvm/lldb/tools/driver/Driver.h +++ b/gnu/llvm/lldb/tools/driver/Driver.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Driver_h_ -#define lldb_Driver_h_ +#ifndef LLDB_TOOLS_DRIVER_DRIVER_H +#define LLDB_TOOLS_DRIVER_DRIVER_H #include "Platform.h" @@ -99,4 +99,4 @@ private: OptionData m_option_data; }; -#endif // lldb_Driver_h_ +#endif // LLDB_TOOLS_DRIVER_DRIVER_H diff --git a/gnu/llvm/lldb/tools/driver/Options.td b/gnu/llvm/lldb/tools/driver/Options.td index c237f568f64..96f696ec3ca 100644 --- a/gnu/llvm/lldb/tools/driver/Options.td +++ b/gnu/llvm/lldb/tools/driver/Options.td @@ -232,7 +232,11 @@ def capture_path: Separate<["--", "-"], "capture-path">, def replay: Separate<["--", "-"], "replay">, MetaVarName<"">, HelpText<"Tells the debugger to replay a reproducer from .">; -def skip_version_check: F<"reproducer-skip-version-check">, - HelpText<"Skip the reproducer version check.">; +def no_version_check: F<"reproducer-no-version-check">, + HelpText<"Disable the reproducer version check.">; +def no_generate_on_signal: F<"reproducer-no-generate-on-signal">, + HelpText<"Don't generate reproducer when a signal is received.">; +def generate_on_exit: F<"reproducer-generate-on-exit">, + HelpText<"Generate reproducer on exit.">; def REM : R<["--"], "">; diff --git a/gnu/llvm/lldb/tools/driver/Platform.h b/gnu/llvm/lldb/tools/driver/Platform.h index cf6c4ec8e14..6b893f91f44 100644 --- a/gnu/llvm/lldb/tools/driver/Platform.h +++ b/gnu/llvm/lldb/tools/driver/Platform.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_Platform_h_ -#define lldb_Platform_h_ +#ifndef LLDB_TOOLS_DRIVER_PLATFORM_H +#define LLDB_TOOLS_DRIVER_PLATFORM_H #include "lldb/Host/Config.h" @@ -87,4 +87,4 @@ extern int tcgetattr(int fildes, struct termios *termios_p); #include #endif -#endif // lldb_Platform_h_ +#endif // LLDB_TOOLS_DRIVER_PLATFORM_H diff --git a/gnu/llvm/lldb/tools/intel-features/CMakeLists.txt b/gnu/llvm/lldb/tools/intel-features/CMakeLists.txt index aff75d7db33..efba2f74904 100644 --- a/gnu/llvm/lldb/tools/intel-features/CMakeLists.txt +++ b/gnu/llvm/lldb/tools/intel-features/CMakeLists.txt @@ -56,6 +56,7 @@ add_lldb_library(lldbIntelFeatures SHARED LINK_LIBS ${FEATURE_LIBS} + ${PYTHON_LIBRARY} ) # Add link dependencies for python wrapper diff --git a/gnu/llvm/lldb/tools/intel-features/intel-mpx/cli-wrapper-mpxtable.cpp b/gnu/llvm/lldb/tools/intel-features/intel-mpx/cli-wrapper-mpxtable.cpp index 5bffd27409e..d2ef0445bc6 100644 --- a/gnu/llvm/lldb/tools/intel-features/intel-mpx/cli-wrapper-mpxtable.cpp +++ b/gnu/llvm/lldb/tools/intel-features/intel-mpx/cli-wrapper-mpxtable.cpp @@ -19,6 +19,7 @@ #include "lldb/API/SBThread.h" #include "llvm/ADT/Triple.h" +#include "llvm/ADT/Twine.h" static bool GetPtr(char *cptr, uint64_t &ptr, lldb::SBFrame &frame, lldb::SBCommandReturnObject &result) { diff --git a/gnu/llvm/lldb/tools/intel-features/intel-mpx/test/main.cpp b/gnu/llvm/lldb/tools/intel-features/intel-mpx/test/main.cpp index 2f5253ed860..ecc292866ff 100644 --- a/gnu/llvm/lldb/tools/intel-features/intel-mpx/test/main.cpp +++ b/gnu/llvm/lldb/tools/intel-features/intel-mpx/test/main.cpp @@ -1,12 +1,3 @@ -//===-- main.cpp ------------------------------------------------*- C++ -*-===// -//// -//// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -//// See https://llvm.org/LICENSE.txt for license information. -//// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -//// -////===----------------------------------------------------------------------===// -// - const int size = 5; #include diff --git a/gnu/llvm/lldb/tools/intel-features/intel-pt/Decoder.cpp b/gnu/llvm/lldb/tools/intel-features/intel-pt/Decoder.cpp index 2ce5c985c54..21642c75327 100644 --- a/gnu/llvm/lldb/tools/intel-features/intel-pt/Decoder.cpp +++ b/gnu/llvm/lldb/tools/intel-features/intel-pt/Decoder.cpp @@ -564,6 +564,61 @@ void Decoder::InitializePTInstDecoder( } } +void Decoder::AppendErrorWithOffsetToInstructionList( + int errcode, uint64_t decoder_offset, Instructions &instruction_list, + lldb::SBError &sberror) { + sberror.SetErrorStringWithFormat( + "processor trace decoding library: \"%s\" [decoder_offset] => " + "[0x%" PRIu64 "]", + pt_errstr(pt_errcode(errcode)), decoder_offset); + instruction_list.emplace_back(sberror.GetCString()); +} + +void Decoder::AppendErrorWithoutOffsetToInstructionList( + int errcode, Instructions &instruction_list, lldb::SBError &sberror) { + sberror.SetErrorStringWithFormat("processor trace decoding library: \"%s\"", + pt_errstr(pt_errcode(errcode))); + instruction_list.emplace_back(sberror.GetCString()); +} + +int Decoder::AppendErrorToInstructionList(int errcode, pt_insn_decoder *decoder, + Instructions &instruction_list, + lldb::SBError &sberror) { + uint64_t decoder_offset = 0; + int errcode_off = pt_insn_get_offset(decoder, &decoder_offset); + if (errcode_off < 0) { + AppendErrorWithoutOffsetToInstructionList(errcode, instruction_list, + sberror); + return errcode_off; + } + AppendErrorWithOffsetToInstructionList(errcode, decoder_offset, + instruction_list, sberror); + return 0; +} + +int Decoder::HandlePTInstructionEvents(pt_insn_decoder *decoder, int errcode, + Instructions &instruction_list, + lldb::SBError &sberror) { + while (errcode & pts_event_pending) { + pt_event event; + errcode = pt_insn_event(decoder, &event, sizeof(event)); + if (errcode < 0) + return errcode; + + // The list of events are in + // https://github.com/intel/libipt/blob/master/doc/man/pt_qry_event.3.md + if (event.type == ptev_overflow) { + int append_errcode = AppendErrorToInstructionList( + errcode, decoder, instruction_list, sberror); + if (append_errcode < 0) + return append_errcode; + } + // Other events don't signal stream errors + } + + return 0; +} + // Start actual decoding of raw trace void Decoder::DecodeTrace(struct pt_insn_decoder *decoder, Instructions &instruction_list, @@ -585,10 +640,8 @@ void Decoder::DecodeTrace(struct pt_insn_decoder *decoder, int errcode_off = pt_insn_get_offset(decoder, &decoder_offset); if (errcode_off < 0) { - sberror.SetErrorStringWithFormat( - "processor trace decoding library: \"%s\"", - pt_errstr(pt_errcode(errcode))); - instruction_list.emplace_back(sberror.GetCString()); + AppendErrorWithoutOffsetToInstructionList(errcode, instruction_list, + sberror); return; } @@ -619,16 +672,22 @@ void Decoder::DecodeTrace(struct pt_insn_decoder *decoder, // progress further. Hence, returning in this situation. return; } - sberror.SetErrorStringWithFormat( - "processor trace decoding library: \"%s\" [decoder_offset] => " - "[0x%" PRIu64 "]", - pt_errstr(pt_errcode(errcode)), new_decoder_offset); - instruction_list.emplace_back(sberror.GetCString()); + AppendErrorWithOffsetToInstructionList(errcode, new_decoder_offset, + instruction_list, sberror); decoder_offset = new_decoder_offset; } } while (1) { + errcode = HandlePTInstructionEvents(decoder, errcode, instruction_list, + sberror); + if (errcode < 0) { + int append_errcode = AppendErrorToInstructionList( + errcode, decoder, instruction_list, sberror); + if (append_errcode < 0) + return; + break; + } errcode = pt_insn_next(decoder, &insn, sizeof(insn)); if (errcode < 0) { if (insn.iclass == ptic_error) diff --git a/gnu/llvm/lldb/tools/intel-features/intel-pt/Decoder.h b/gnu/llvm/lldb/tools/intel-features/intel-pt/Decoder.h index 2ae89653df5..ff3e6f34b6a 100644 --- a/gnu/llvm/lldb/tools/intel-features/intel-pt/Decoder.h +++ b/gnu/llvm/lldb/tools/intel-features/intel-pt/Decoder.h @@ -245,6 +245,22 @@ private: lldb::SBError &sberror) const; void DecodeTrace(struct pt_insn_decoder *decoder, Instructions &instruction_list, lldb::SBError &sberror); + int HandlePTInstructionEvents(pt_insn_decoder *decoder, int errcode, + Instructions &instruction_list, + lldb::SBError &sberror); + + int AppendErrorToInstructionList(int errcode, pt_insn_decoder *decoder, + Instructions &instruction_list, + lldb::SBError &sberror); + + void AppendErrorWithOffsetToInstructionList(int errcode, + uint64_t decoder_offset, + Instructions &instruction_list, + lldb::SBError &sberror); + + void AppendErrorWithoutOffsetToInstructionList(int errcode, + Instructions &instruction_list, + lldb::SBError &sberror); // Function to diagnose and indicate errors during raw trace decoding void Diagnose(struct pt_insn_decoder *decoder, int errcode, diff --git a/gnu/llvm/lldb/tools/intel-features/intel-pt/cli-wrapper-pt.cpp b/gnu/llvm/lldb/tools/intel-features/intel-pt/cli-wrapper-pt.cpp index 8db1c0f82d6..5e409a269fa 100644 --- a/gnu/llvm/lldb/tools/intel-features/intel-pt/cli-wrapper-pt.cpp +++ b/gnu/llvm/lldb/tools/intel-features/intel-pt/cli-wrapper-pt.cpp @@ -191,6 +191,7 @@ public: result.SetStatus(lldb::eReturnStatusFailed); return false; } + result.SetStatus(lldb::eReturnStatusSuccessFinishResult); return true; } @@ -290,6 +291,7 @@ public: s.GetData()); result.AppendMessage(res.GetOutput()); } + result.SetStatus(lldb::eReturnStatusSuccessFinishResult); return true; } @@ -428,6 +430,7 @@ public: } result.AppendMessage(res.GetOutput()); } + result.SetStatus(lldb::eReturnStatusSuccessFinishResult); return true; } @@ -480,6 +483,7 @@ public: result.SetStatus(lldb::eReturnStatusFailed); return false; } + result.SetStatus(lldb::eReturnStatusSuccessFinishResult); return true; } diff --git a/gnu/llvm/lldb/tools/lldb-instr/Instrument.cpp b/gnu/llvm/lldb/tools/lldb-instr/Instrument.cpp index 9b2970030cb..8ec01304891 100644 --- a/gnu/llvm/lldb/tools/lldb-instr/Instrument.cpp +++ b/gnu/llvm/lldb/tools/lldb-instr/Instrument.cpp @@ -194,10 +194,9 @@ public: ParamTypes.push_back(T.getAsString(Policy)); ParamNames.push_back(P->getNameAsString()); - // Currently we don't support functions that have void pointers or - // function pointers as an argument, in which case we insert a dummy - // macro. - ShouldInsertDummy |= T->isFunctionPointerType() || T->isVoidPointerType(); + // Currently we don't support functions that have function pointers as an + // argument, in which case we insert a dummy macro. + ShouldInsertDummy |= T->isFunctionPointerType(); } // Convert the two lists to string for the macros. diff --git a/gnu/llvm/lldb/tools/lldb-server/Acceptor.cpp b/gnu/llvm/lldb/tools/lldb-server/Acceptor.cpp index 2cfb34d215c..b8be9c5c266 100644 --- a/gnu/llvm/lldb/tools/lldb-server/Acceptor.cpp +++ b/gnu/llvm/lldb/tools/lldb-server/Acceptor.cpp @@ -118,7 +118,7 @@ std::unique_ptr Acceptor::Create(StringRef name, return (local_port != 0) ? llvm::to_string(local_port) : ""; }; } else { - const std::string socket_name = name; + const std::string socket_name = std::string(name); local_socket_id = [socket_name]() { return socket_name; }; } diff --git a/gnu/llvm/lldb/tools/lldb-server/Acceptor.h b/gnu/llvm/lldb/tools/lldb-server/Acceptor.h index 1e7337f1411..b441e92dcd2 100644 --- a/gnu/llvm/lldb/tools/lldb-server/Acceptor.h +++ b/gnu/llvm/lldb/tools/lldb-server/Acceptor.h @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -#ifndef lldb_server_Acceptor_h_ -#define lldb_server_Acceptor_h_ +#ifndef LLDB_TOOLS_LLDB_SERVER_ACCEPTOR_H +#define LLDB_TOOLS_LLDB_SERVER_ACCEPTOR_H #include "lldb/Host/Socket.h" #include "lldb/Utility/Connection.h" @@ -57,4 +57,4 @@ private: } // namespace lldb_server } // namespace lldb_private -#endif // lldb_server_Acceptor_h_ +#endif // LLDB_TOOLS_LLDB_SERVER_ACCEPTOR_H diff --git a/gnu/llvm/lldb/tools/lldb-server/CMakeLists.txt b/gnu/llvm/lldb/tools/lldb-server/CMakeLists.txt index 739bdc3c422..7443c6c90e8 100644 --- a/gnu/llvm/lldb/tools/lldb-server/CMakeLists.txt +++ b/gnu/llvm/lldb/tools/lldb-server/CMakeLists.txt @@ -8,10 +8,6 @@ if(CMAKE_SYSTEM_NAME MATCHES "NetBSD") list(APPEND LLDB_PLUGINS lldbPluginProcessNetBSD) endif() -if(CMAKE_SYSTEM_NAME MATCHES "OpenBSD") - list(APPEND LLDB_PLUGINS lldbPluginProcessOpenBSD) -endif() - if(CMAKE_SYSTEM_NAME MATCHES "Darwin") list(APPEND LLDB_PLUGINS lldbPluginObjectFileMachO) elseif(CMAKE_SYSTEM_NAME MATCHES "Windows") diff --git a/gnu/llvm/lldb/tools/lldb-server/LLDBServerUtilities.h b/gnu/llvm/lldb/tools/lldb-server/LLDBServerUtilities.h index 3ade1f9f5b8..b59d1e41154 100644 --- a/gnu/llvm/lldb/tools/lldb-server/LLDBServerUtilities.h +++ b/gnu/llvm/lldb/tools/lldb-server/LLDBServerUtilities.h @@ -1,3 +1,7 @@ +#ifndef LLDB_TOOLS_LLDB_SERVER_LLDBSERVERUTILITIES_H + +#define LLDB_TOOLS_LLDB_SERVER_LLDBSERVERUTILITIES_H + //===-- LLDBServerUtilities.h -----------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -21,3 +25,5 @@ public: }; } } + +#endif diff --git a/gnu/llvm/lldb/tools/lldb-server/SystemInitializerLLGS.h b/gnu/llvm/lldb/tools/lldb-server/SystemInitializerLLGS.h index 59a1fa14e81..f3d015e94f8 100644 --- a/gnu/llvm/lldb/tools/lldb-server/SystemInitializerLLGS.h +++ b/gnu/llvm/lldb/tools/lldb-server/SystemInitializerLLGS.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SYSTEMINITIALIZERLLGS_H -#define LLDB_SYSTEMINITIALIZERLLGS_H +#ifndef LLDB_TOOLS_LLDB_SERVER_SYSTEMINITIALIZERLLGS_H +#define LLDB_TOOLS_LLDB_SERVER_SYSTEMINITIALIZERLLGS_H #include "lldb/Initialization/SystemInitializer.h" #include "lldb/Initialization/SystemInitializerCommon.h" @@ -18,4 +18,4 @@ public: void Terminate() override; }; -#endif // LLDB_SYSTEMINITIALIZERLLGS_H +#endif // LLDB_TOOLS_LLDB_SERVER_SYSTEMINITIALIZERLLGS_H diff --git a/gnu/llvm/lldb/tools/lldb-server/lldb-gdbserver.cpp b/gnu/llvm/lldb/tools/lldb-server/lldb-gdbserver.cpp index 9648a6a4426..5f06503d642 100644 --- a/gnu/llvm/lldb/tools/lldb-server/lldb-gdbserver.cpp +++ b/gnu/llvm/lldb/tools/lldb-server/lldb-gdbserver.cpp @@ -40,8 +40,6 @@ #include "Plugins/Process/Linux/NativeProcessLinux.h" #elif defined(__NetBSD__) #include "Plugins/Process/NetBSD/NativeProcessNetBSD.h" -#elif defined(__OpenBSD__) -#include "Plugins/Process/OpenBSD/NativeProcessOpenBSD.h" #elif defined(_WIN32) #include "Plugins/Process/Windows/Common/NativeProcessWindows.h" #endif @@ -65,8 +63,6 @@ namespace { typedef process_linux::NativeProcessLinux::Factory NativeProcessFactory; #elif defined(__NetBSD__) typedef process_netbsd::NativeProcessNetBSD::Factory NativeProcessFactory; -#elif defined(__OpenBSD__) -typedef process_openbsd::NativeProcessOpenBSD::Factory NativeProcessFactory; #elif defined(_WIN32) typedef NativeProcessWindows::Factory NativeProcessFactory; #else diff --git a/gnu/llvm/lldb/tools/lldb-server/lldb-platform.cpp b/gnu/llvm/lldb/tools/lldb-server/lldb-platform.cpp index a6fb5639d64..33f918ffc2a 100644 --- a/gnu/llvm/lldb/tools/lldb-server/lldb-platform.cpp +++ b/gnu/llvm/lldb/tools/lldb-server/lldb-platform.cpp @@ -96,7 +96,7 @@ static void display_usage(const char *progname, const char *subcommand) { static Status save_socket_id_to_file(const std::string &socket_id, const FileSpec &file_spec) { - FileSpec temp_file_spec(file_spec.GetDirectory().AsCString()); + FileSpec temp_file_spec(file_spec.GetDirectory().GetStringRef()); Status error(llvm::sys::fs::create_directory(temp_file_spec.GetPath())); if (error.Fail()) return Status("Failed to create directory %s: %s", @@ -343,7 +343,7 @@ int main_platform(int argc, char *argv[]) { // connections while a connection is active. acceptor_up.reset(); } - platform.SetConnection(conn); + platform.SetConnection(std::unique_ptr(conn)); if (platform.IsConnected()) { if (inferior_arguments.GetArgumentCount() > 0) { diff --git a/gnu/llvm/lldb/tools/lldb-test/CMakeLists.txt b/gnu/llvm/lldb/tools/lldb-test/CMakeLists.txt index 2ab1ceacdcd..2edbd8e56d6 100644 --- a/gnu/llvm/lldb/tools/lldb-test/CMakeLists.txt +++ b/gnu/llvm/lldb/tools/lldb-test/CMakeLists.txt @@ -23,5 +23,11 @@ add_lldb_tool(lldb-test LINK_COMPONENTS Support ) - -include_directories(${LLDB_SOURCE_DIR}/source) + +if(PYTHON_RPATH) + set_property(TARGET lldb-test APPEND PROPERTY INSTALL_RPATH "${PYTHON_RPATH}") + set_property(TARGET lldb-test APPEND PROPERTY BUILD_RPATH "${PYTHON_RPATH}") +endif() + +target_include_directories(lldb-test PRIVATE ${LLDB_SOURCE_DIR}/source) +target_include_directories(lldb-test PRIVATE ${LLDB_BINARY_DIR}/source) diff --git a/gnu/llvm/lldb/tools/lldb-test/FormatUtil.h b/gnu/llvm/lldb/tools/lldb-test/FormatUtil.h index 91b3c085b60..2b2266e8dfb 100644 --- a/gnu/llvm/lldb/tools/lldb-test/FormatUtil.h +++ b/gnu/llvm/lldb/tools/lldb-test/FormatUtil.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_LLDBTEST_FORMATUTIL_H -#define LLVM_TOOLS_LLDBTEST_FORMATUTIL_H +#ifndef LLDB_TOOLS_LLDB_TEST_FORMATUTIL_H +#define LLDB_TOOLS_LLDB_TEST_FORMATUTIL_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" diff --git a/gnu/llvm/lldb/tools/lldb-test/SystemInitializerTest.cpp b/gnu/llvm/lldb/tools/lldb-test/SystemInitializerTest.cpp index 8841e4d6583..10b90cdc640 100644 --- a/gnu/llvm/lldb/tools/lldb-test/SystemInitializerTest.cpp +++ b/gnu/llvm/lldb/tools/lldb-test/SystemInitializerTest.cpp @@ -7,251 +7,47 @@ //===----------------------------------------------------------------------===// #include "SystemInitializerTest.h" - #include "lldb/Core/Debugger.h" +#include "lldb/Core/PluginManager.h" #include "lldb/Host/Host.h" #include "lldb/Initialization/SystemInitializerCommon.h" #include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Utility/Timer.h" - -#include "Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h" -#include "Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h" -#include "Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h" -#include "Plugins/ABI/SysV-arm/ABISysV_arm.h" -#include "Plugins/ABI/SysV-arm64/ABISysV_arm64.h" -#include "Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h" -#include "Plugins/ABI/SysV-i386/ABISysV_i386.h" -#include "Plugins/ABI/SysV-mips/ABISysV_mips.h" -#include "Plugins/ABI/SysV-mips64/ABISysV_mips64.h" -#include "Plugins/ABI/SysV-ppc/ABISysV_ppc.h" -#include "Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h" -#include "Plugins/ABI/SysV-s390x/ABISysV_s390x.h" -#include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h" -#include "Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h" -#include "Plugins/Architecture/Arm/ArchitectureArm.h" -#include "Plugins/Architecture/PPC64/ArchitecturePPC64.h" -#include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h" -#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h" -#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h" -#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h" -#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h" -#include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h" -#include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h" -#include "Plugins/Instruction/PPC64/EmulateInstructionPPC64.h" -#include "Plugins/InstrumentationRuntime/ASan/ASanRuntime.h" -#include "Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.h" -#include "Plugins/InstrumentationRuntime/TSan/TSanRuntime.h" -#include "Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.h" -#include "Plugins/JITLoader/GDB/JITLoaderGDB.h" -#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" -#include "Plugins/Language/ObjC/ObjCLanguage.h" -#include "Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h" -#include "Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h" -#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h" -#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h" -#include "Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h" -#include "Plugins/MemoryHistory/asan/MemoryHistoryASan.h" -#include "Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h" -#include "Plugins/ObjectFile/ELF/ObjectFileELF.h" -#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h" -#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h" -#include "Plugins/Platform/Android/PlatformAndroid.h" -#include "Plugins/Platform/FreeBSD/PlatformFreeBSD.h" -#include "Plugins/Platform/Linux/PlatformLinux.h" -#include "Plugins/Platform/MacOSX/PlatformMacOSX.h" -#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h" -#include "Plugins/Platform/NetBSD/PlatformNetBSD.h" -#include "Plugins/Platform/OpenBSD/PlatformOpenBSD.h" -#include "Plugins/Platform/Windows/PlatformWindows.h" -#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h" -#include "Plugins/Process/elf-core/ProcessElfCore.h" -#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h" -#include "Plugins/Process/minidump/ProcessMinidump.h" -#include "Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h" -#include "Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h" -#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" -#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h" -#include "Plugins/SymbolFile/PDB/SymbolFilePDB.h" -#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h" -#include "Plugins/SymbolVendor/ELF/SymbolVendorELF.h" -#include "Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h" -#include "Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h" -#include "Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h" - -#if defined(__APPLE__) -#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h" -#include "Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h" -#include "Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h" -#include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h" -#include "Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h" -#include "Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h" -#include "Plugins/Platform/MacOSX/PlatformiOSSimulator.h" -#include "Plugins/Process/MacOSX-Kernel/ProcessKDP.h" -#include "Plugins/Process/mach-core/ProcessMachCore.h" -#include "Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h" -#endif -#include "Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h" - -#if defined(__FreeBSD__) -#include "Plugins/Process/FreeBSD/ProcessFreeBSD.h" -#endif - -#if defined(_WIN32) -#include "Plugins/Process/Windows/Common/ProcessWindows.h" -#include "lldb/Host/windows/windows.h" -#endif - #include "llvm/Support/TargetSelect.h" #include -using namespace lldb_private; - -SystemInitializerTest::SystemInitializerTest() {} - -SystemInitializerTest::~SystemInitializerTest() {} +#define LLDB_PLUGIN(p) LLDB_PLUGIN_DECLARE(p) +#include "Plugins/Plugins.def" -#define LLDB_PROCESS_AArch64(op) \ - ABIMacOSX_arm64::op(); \ - ABISysV_arm64::op(); -#define LLDB_PROCESS_ARM(op) \ - ABIMacOSX_arm::op(); \ - ABISysV_arm::op(); -#define LLDB_PROCESS_Hexagon(op) ABISysV_hexagon::op(); -#define LLDB_PROCESS_Mips(op) \ - ABISysV_mips::op(); \ - ABISysV_mips64::op(); -#define LLDB_PROCESS_PowerPC(op) \ - ABISysV_ppc::op(); \ - ABISysV_ppc64::op(); -#define LLDB_PROCESS_SystemZ(op) ABISysV_s390x::op(); -#define LLDB_PROCESS_X86(op) \ - ABIMacOSX_i386::op(); \ - ABISysV_i386::op(); \ - ABISysV_x86_64::op(); \ - ABIWindows_x86_64::op(); +using namespace lldb_private; -#define LLDB_PROCESS_AMDGPU(op) -#define LLDB_PROCESS_ARC(op) -#define LLDB_PROCESS_AVR(op) -#define LLDB_PROCESS_BPF(op) -#define LLDB_PROCESS_Lanai(op) -#define LLDB_PROCESS_MSP430(op) -#define LLDB_PROCESS_NVPTX(op) -#define LLDB_PROCESS_RISCV(op) -#define LLDB_PROCESS_Sparc(op) -#define LLDB_PROCESS_WebAssembly(op) -#define LLDB_PROCESS_XCore(op) +SystemInitializerTest::SystemInitializerTest() = default; +SystemInitializerTest::~SystemInitializerTest() = default; llvm::Error SystemInitializerTest::Initialize() { if (auto e = SystemInitializerCommon::Initialize()) return e; - breakpad::ObjectFileBreakpad::Initialize(); - ObjectFileELF::Initialize(); - ObjectFileMachO::Initialize(); - ObjectFilePECOFF::Initialize(); - - ScriptInterpreterNone::Initialize(); - - - platform_freebsd::PlatformFreeBSD::Initialize(); - platform_linux::PlatformLinux::Initialize(); - platform_netbsd::PlatformNetBSD::Initialize(); - platform_openbsd::PlatformOpenBSD::Initialize(); - PlatformWindows::Initialize(); - platform_android::PlatformAndroid::Initialize(); - PlatformRemoteiOS::Initialize(); - PlatformMacOSX::Initialize(); -#if defined(__APPLE__) - PlatformiOSSimulator::Initialize(); - PlatformDarwinKernel::Initialize(); -#endif - // Initialize LLVM and Clang llvm::InitializeAllTargets(); llvm::InitializeAllAsmPrinters(); llvm::InitializeAllTargetMCs(); llvm::InitializeAllDisassemblers(); - ClangASTContext::Initialize(); - -#define LLVM_TARGET(t) LLDB_PROCESS_ ## t(Initialize) -#include "llvm/Config/Targets.def" - - ArchitectureArm::Initialize(); - ArchitecturePPC64::Initialize(); - - DisassemblerLLVMC::Initialize(); - - JITLoaderGDB::Initialize(); - ProcessElfCore::Initialize(); - minidump::ProcessMinidump::Initialize(); - MemoryHistoryASan::Initialize(); - AddressSanitizerRuntime::Initialize(); - ThreadSanitizerRuntime::Initialize(); - UndefinedBehaviorSanitizerRuntime::Initialize(); - MainThreadCheckerRuntime::Initialize(); +#define LLDB_SCRIPT_PLUGIN(p) +#define LLDB_PLUGIN(p) LLDB_PLUGIN_INITIALIZE(p); +#include "Plugins/Plugins.def" - SymbolVendorELF::Initialize(); - breakpad::SymbolFileBreakpad::Initialize(); - SymbolFileDWARF::Initialize(); - SymbolFilePDB::Initialize(); - SymbolFileSymtab::Initialize(); - UnwindAssemblyInstEmulation::Initialize(); - UnwindAssembly_x86::Initialize(); - EmulateInstructionARM64::Initialize(); - EmulateInstructionPPC64::Initialize(); - SymbolFileDWARFDebugMap::Initialize(); - ItaniumABILanguageRuntime::Initialize(); - AppleObjCRuntimeV2::Initialize(); - AppleObjCRuntimeV1::Initialize(); - SystemRuntimeMacOSX::Initialize(); - RenderScriptRuntime::Initialize(); - - CPlusPlusLanguage::Initialize(); - ObjCLanguage::Initialize(); - ObjCPlusPlusLanguage::Initialize(); - -#if defined(_WIN32) - ProcessWindows::Initialize(); -#endif -#if defined(__FreeBSD__) - ProcessFreeBSD::Initialize(); -#endif -#if defined(__APPLE__) - SymbolVendorMacOSX::Initialize(); - ProcessKDP::Initialize(); - ProcessMachCore::Initialize(); - PlatformAppleTVSimulator::Initialize(); - PlatformAppleWatchSimulator::Initialize(); - PlatformRemoteAppleTV::Initialize(); - PlatformRemoteAppleWatch::Initialize(); - DynamicLoaderDarwinKernel::Initialize(); -#endif - - // This plugin is valid on any host that talks to a Darwin remote. - // It shouldn't be limited to __APPLE__. - StructuredDataDarwinLog::Initialize(); - - // Platform agnostic plugins - platform_gdb_server::PlatformRemoteGDBServer::Initialize(); - - process_gdb_remote::ProcessGDBRemote::Initialize(); - DynamicLoaderMacOSXDYLD::Initialize(); - DynamicLoaderMacOS::Initialize(); - DynamicLoaderPOSIXDYLD::Initialize(); - DynamicLoaderStatic::Initialize(); - DynamicLoaderWindowsDYLD::Initialize(); + // We ignored all the script interpreter earlier, so initialize + // ScriptInterpreterNone explicitly. + LLDB_PLUGIN_INITIALIZE(ScriptInterpreterNone); // Scan for any system or user LLDB plug-ins PluginManager::Initialize(); - // The process settings need to know about installed plug-ins, so the Settings - // must be initialized - // AFTER PluginManager::Initialize is called. - + // The process settings need to know about installed plug-ins, so the + // Settings must be initialized AFTER PluginManager::Initialize is called. Debugger::SettingsInitialize(); return llvm::Error::success(); @@ -266,85 +62,13 @@ void SystemInitializerTest::Terminate() { // Terminate and unload and loaded system or user LLDB plug-ins PluginManager::Terminate(); - ClangASTContext::Terminate(); - -#define LLVM_TARGET(t) LLDB_PROCESS_ ## t(Terminate) -#include "llvm/Config/Targets.def" - - DisassemblerLLVMC::Terminate(); - - JITLoaderGDB::Terminate(); - ProcessElfCore::Terminate(); - minidump::ProcessMinidump::Terminate(); - MemoryHistoryASan::Terminate(); - AddressSanitizerRuntime::Terminate(); - ThreadSanitizerRuntime::Terminate(); - UndefinedBehaviorSanitizerRuntime::Terminate(); - MainThreadCheckerRuntime::Terminate(); - SymbolVendorELF::Terminate(); - breakpad::SymbolFileBreakpad::Terminate(); - SymbolFileDWARF::Terminate(); - SymbolFilePDB::Terminate(); - SymbolFileSymtab::Terminate(); - UnwindAssembly_x86::Terminate(); - UnwindAssemblyInstEmulation::Terminate(); - EmulateInstructionARM64::Terminate(); - EmulateInstructionPPC64::Terminate(); - SymbolFileDWARFDebugMap::Terminate(); - ItaniumABILanguageRuntime::Terminate(); - AppleObjCRuntimeV2::Terminate(); - AppleObjCRuntimeV1::Terminate(); - SystemRuntimeMacOSX::Terminate(); - RenderScriptRuntime::Terminate(); - - CPlusPlusLanguage::Terminate(); - ObjCLanguage::Terminate(); - ObjCPlusPlusLanguage::Terminate(); - -#if defined(__APPLE__) - DynamicLoaderDarwinKernel::Terminate(); - ProcessMachCore::Terminate(); - ProcessKDP::Terminate(); - SymbolVendorMacOSX::Terminate(); - PlatformAppleTVSimulator::Terminate(); - PlatformAppleWatchSimulator::Terminate(); - PlatformRemoteAppleTV::Terminate(); - PlatformRemoteAppleWatch::Terminate(); -#endif - -#if defined(__FreeBSD__) - ProcessFreeBSD::Terminate(); -#endif - Debugger::SettingsTerminate(); - - platform_gdb_server::PlatformRemoteGDBServer::Terminate(); - process_gdb_remote::ProcessGDBRemote::Terminate(); - StructuredDataDarwinLog::Terminate(); - - DynamicLoaderMacOSXDYLD::Terminate(); - DynamicLoaderMacOS::Terminate(); - DynamicLoaderPOSIXDYLD::Terminate(); - DynamicLoaderStatic::Terminate(); - DynamicLoaderWindowsDYLD::Terminate(); - - - platform_freebsd::PlatformFreeBSD::Terminate(); - platform_linux::PlatformLinux::Terminate(); - platform_netbsd::PlatformNetBSD::Terminate(); - platform_openbsd::PlatformOpenBSD::Terminate(); - PlatformWindows::Terminate(); - platform_android::PlatformAndroid::Terminate(); - PlatformMacOSX::Terminate(); - PlatformRemoteiOS::Terminate(); -#if defined(__APPLE__) - PlatformiOSSimulator::Terminate(); - PlatformDarwinKernel::Terminate(); -#endif +#define LLDB_SCRIPT_PLUGIN(p) +#define LLDB_PLUGIN(p) LLDB_PLUGIN_TERMINATE(p); +#include "Plugins/Plugins.def" - breakpad::ObjectFileBreakpad::Terminate(); - ObjectFileELF::Terminate(); - ObjectFileMachO::Terminate(); - ObjectFilePECOFF::Terminate(); + // We ignored all the script interpreter earlier, so terminate + // ScriptInterpreterNone explicitly. + LLDB_PLUGIN_INITIALIZE(ScriptInterpreterNone); // Now shutdown the common parts, in reverse order. SystemInitializerCommon::Terminate(); diff --git a/gnu/llvm/lldb/tools/lldb-test/SystemInitializerTest.h b/gnu/llvm/lldb/tools/lldb-test/SystemInitializerTest.h index 4f58d2a64a6..a9f2111e688 100644 --- a/gnu/llvm/lldb/tools/lldb-test/SystemInitializerTest.h +++ b/gnu/llvm/lldb/tools/lldb-test/SystemInitializerTest.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_API_SYSTEM_INITIALIZER_TEST_H -#define LLDB_API_SYSTEM_INITIALIZER_TEST_H +#ifndef LLDB_TOOLS_LLDB_TEST_SYSTEMINITIALIZERTEST_H +#define LLDB_TOOLS_LLDB_TEST_SYSTEMINITIALIZERTEST_H #include "lldb/Initialization/SystemInitializerCommon.h" @@ -29,4 +29,4 @@ public: } // namespace lldb_private -#endif // LLDB_API_SYSTEM_INITIALIZER_FULL_H +#endif // LLDB_TOOLS_LLDB_TEST_SYSTEMINITIALIZERTEST_H diff --git a/gnu/llvm/lldb/tools/lldb-test/lldb-test.cpp b/gnu/llvm/lldb/tools/lldb-test/lldb-test.cpp index 66c9a87301e..8625d448527 100644 --- a/gnu/llvm/lldb/tools/lldb-test/lldb-test.cpp +++ b/gnu/llvm/lldb/tools/lldb-test/lldb-test.cpp @@ -10,6 +10,7 @@ #include "SystemInitializerTest.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" @@ -18,7 +19,6 @@ #include "lldb/Initialization/SystemLifetimeManager.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/LineTable.h" #include "lldb/Symbol/SymbolFile.h" @@ -132,7 +132,7 @@ static cl::opt Name("name", cl::desc("Name to find."), cl::sub(SymbolsSubcommand)); static cl::opt Regex("regex", - cl::desc("Search using regular expressions (avaliable for variables " + cl::desc("Search using regular expressions (available for variables " "and functions only)."), cl::sub(SymbolsSubcommand)); static cl::opt @@ -169,10 +169,13 @@ static FunctionNameType getFunctionNameFlags() { static cl::opt DumpAST("dump-ast", cl::desc("Dump AST restored from symbols."), cl::sub(SymbolsSubcommand)); -static cl::opt - DumpClangAST("dump-clang-ast", - cl::desc("Dump clang AST restored from symbols."), - cl::sub(SymbolsSubcommand)); +static cl::opt DumpClangAST( + "dump-clang-ast", + cl::desc("Dump clang AST restored from symbols. When used on its own this " + "will dump the entire AST of all loaded symbols. When combined " + "with -find, it changes the presentation of the search results " + "from pretty-printing the types to an AST dump."), + cl::sub(SymbolsSubcommand)); static cl::opt Verify("verify", cl::desc("Verify symbol information."), cl::sub(SymbolsSubcommand)); @@ -192,7 +195,7 @@ static Error findTypes(lldb_private::Module &Module); static Error findVariables(lldb_private::Module &Module); static Error dumpModule(lldb_private::Module &Module); static Error dumpAST(lldb_private::Module &Module); -static Error dumpClangAST(lldb_private::Module &Module); +static Error dumpEntireClangAST(lldb_private::Module &Module); static Error verify(lldb_private::Module &Module); static Expected getAction(); @@ -377,7 +380,7 @@ int opts::breakpoint::evaluateBreakpoints(Debugger &Dbg) { std::string Command = substitute(Line); P.formatLine("Command: {0}", Command); - CommandReturnObject Result; + CommandReturnObject Result(/*colors*/ false); if (!Dbg.GetCommandInterpreter().HandleCommand( Command.c_str(), /*add_to_history*/ eLazyBoolNo, Result)) { P.formatLine("Failed: {0}", Result.GetErrorData()); @@ -395,7 +398,8 @@ opts::symbols::getDeclContext(SymbolFile &Symfile) { if (Context.empty()) return CompilerDeclContext(); VariableList List; - Symfile.FindGlobalVariables(ConstString(Context), nullptr, UINT32_MAX, List); + Symfile.FindGlobalVariables(ConstString(Context), CompilerDeclContext(), + UINT32_MAX, List); if (List.Empty()) return make_string_error("Context search didn't find a match."); if (List.GetSize() > 1) @@ -403,6 +407,10 @@ opts::symbols::getDeclContext(SymbolFile &Symfile) { return List.GetVariableAtIndex(0)->GetDeclContext(); } +static lldb::DescriptionLevel GetDescriptionLevel() { + return opts::symbols::DumpClangAST ? eDescriptionLevelVerbose : eDescriptionLevelFull; +} + Error opts::symbols::findFunctions(lldb_private::Module &Module) { SymbolFile &Symfile = *Module.GetSymbolFile(); SymbolContextList List; @@ -442,8 +450,8 @@ Error opts::symbols::findFunctions(lldb_private::Module &Module) { Expected ContextOr = getDeclContext(Symfile); if (!ContextOr) return ContextOr.takeError(); - CompilerDeclContext *ContextPtr = - ContextOr->IsValid() ? &*ContextOr : nullptr; + const CompilerDeclContext &ContextPtr = + ContextOr->IsValid() ? *ContextOr : CompilerDeclContext(); List.Clear(); Symfile.FindFunctions(ConstString(Name), ContextPtr, getFunctionNameFlags(), @@ -498,8 +506,8 @@ Error opts::symbols::findNamespaces(lldb_private::Module &Module) { Expected ContextOr = getDeclContext(Symfile); if (!ContextOr) return ContextOr.takeError(); - CompilerDeclContext *ContextPtr = - ContextOr->IsValid() ? &*ContextOr : nullptr; + const CompilerDeclContext &ContextPtr = + ContextOr->IsValid() ? *ContextOr : CompilerDeclContext(); CompilerDeclContext Result = Symfile.FindNamespace(ConstString(Name), ContextPtr); @@ -516,13 +524,13 @@ Error opts::symbols::findTypes(lldb_private::Module &Module) { Expected ContextOr = getDeclContext(Symfile); if (!ContextOr) return ContextOr.takeError(); - CompilerDeclContext *ContextPtr = - ContextOr->IsValid() ? &*ContextOr : nullptr; + const CompilerDeclContext &ContextPtr = + ContextOr->IsValid() ? *ContextOr : CompilerDeclContext(); LanguageSet languages; if (!Language.empty()) languages.Insert(Language::GetLanguageTypeFromString(Language)); - + DenseSet SearchedFiles; TypeMap Map; if (!Name.empty()) @@ -533,7 +541,12 @@ Error opts::symbols::findTypes(lldb_private::Module &Module) { outs() << formatv("Found {0} types:\n", Map.GetSize()); StreamString Stream; - Map.Dump(&Stream, false); + // Resolve types to force-materialize typedef types. + Map.ForEach([&](TypeSP &type) { + type->GetFullCompilerType(); + return false; + }); + Map.Dump(&Stream, false, GetDescriptionLevel()); outs() << Stream.GetData() << "\n"; return Error::success(); } @@ -566,8 +579,8 @@ Error opts::symbols::findVariables(lldb_private::Module &Module) { Expected ContextOr = getDeclContext(Symfile); if (!ContextOr) return ContextOr.takeError(); - CompilerDeclContext *ContextPtr = - ContextOr->IsValid() ? &*ContextOr : nullptr; + const CompilerDeclContext &ContextPtr = + ContextOr->IsValid() ? *ContextOr : CompilerDeclContext(); Symfile.FindGlobalVariables(ConstString(Name), ContextPtr, UINT32_MAX, List); } @@ -596,12 +609,12 @@ Error opts::symbols::dumpAST(lldb_private::Module &Module) { llvm::Expected type_system_or_err = symfile->GetTypeSystemForLanguage(eLanguageTypeC_plus_plus); if (!type_system_or_err) - return make_string_error("Can't retrieve ClangASTContext"); + return make_string_error("Can't retrieve TypeSystemClang"); auto *clang_ast_ctx = - llvm::dyn_cast_or_null(&type_system_or_err.get()); + llvm::dyn_cast_or_null(&type_system_or_err.get()); if (!clang_ast_ctx) - return make_string_error("Retrieved TypeSystem was not a ClangASTContext"); + return make_string_error("Retrieved TypeSystem was not a TypeSystemClang"); clang::ASTContext &ast_ctx = clang_ast_ctx->getASTContext(); @@ -614,7 +627,7 @@ Error opts::symbols::dumpAST(lldb_private::Module &Module) { return Error::success(); } -Error opts::symbols::dumpClangAST(lldb_private::Module &Module) { +Error opts::symbols::dumpEntireClangAST(lldb_private::Module &Module) { Module.ParseAllDebugSymbols(); SymbolFile *symfile = Module.GetSymbolFile(); @@ -624,12 +637,12 @@ Error opts::symbols::dumpClangAST(lldb_private::Module &Module) { llvm::Expected type_system_or_err = symfile->GetTypeSystemForLanguage(eLanguageTypeObjC_plus_plus); if (!type_system_or_err) - return make_string_error("Can't retrieve ClangASTContext"); + return make_string_error("Can't retrieve TypeSystemClang"); auto *clang_ast_ctx = - llvm::dyn_cast_or_null(&type_system_or_err.get()); + llvm::dyn_cast_or_null(&type_system_or_err.get()); if (!clang_ast_ctx) - return make_string_error("Retrieved TypeSystem was not a ClangASTContext"); + return make_string_error("Retrieved TypeSystem was not a TypeSystemClang"); StreamString Stream; clang_ast_ctx->DumpFromSymbolFile(Stream, Name); @@ -650,7 +663,7 @@ Error opts::symbols::verify(lldb_private::Module &Module) { for (uint32_t i = 0; i < comp_units_count; i++) { lldb::CompUnitSP comp_unit = symfile->GetCompileUnitAtIndex(i); if (!comp_unit) - return make_string_error("Connot parse compile unit {0}.", i); + return make_string_error("Cannot parse compile unit {0}.", i); outs() << "Processing '" << comp_unit->GetPrimaryFile().GetFilename().AsCString() @@ -718,13 +731,17 @@ Expected opts::symbols::getAction() { } if (DumpClangAST) { - if (Find != FindType::None) - return make_string_error("Cannot both search and dump clang AST."); - if (Regex || !Context.empty() || !File.empty() || Line != 0) - return make_string_error( - "-regex, -context, -name, -file and -line options are not " - "applicable for dumping clang AST."); - return dumpClangAST; + if (Find == FindType::None) { + if (Regex || !Context.empty() || !File.empty() || Line != 0) + return make_string_error( + "-regex, -context, -name, -file and -line options are not " + "applicable for dumping the entire clang AST. Either combine with " + "-find, or use -dump-clang-ast as a standalone option."); + return dumpEntireClangAST; + } + if (Find != FindType::Type) + return make_string_error("This combination of -dump-clang-ast and -find " + " is not yet implemented."); } if (Regex && !Context.empty()) @@ -845,7 +862,7 @@ static void dumpSectionList(LinePrinter &Printer, const SectionList &List, bool if (opts::object::SectionContents) { lldb_private::DataExtractor Data; S->GetSectionData(Data); - ArrayRef Bytes = {Data.GetDataStart(), Data.GetDataEnd()}; + ArrayRef Bytes(Data.GetDataStart(), Data.GetDataEnd()); Printer.formatBinary("Data: ", Bytes, 0); } @@ -1017,7 +1034,7 @@ int opts::irmemorymap::evaluateMemoryMapCommands(Debugger &Dbg) { // Set up a Process. In order to allocate memory within a target, this // process must be alive and must support JIT'ing. - CommandReturnObject Result; + CommandReturnObject Result(/*colors*/ false); Dbg.SetAsyncExecution(false); CommandInterpreter &CI = Dbg.GetCommandInterpreter(); auto IssueCmd = [&](const char *Cmd) -> bool { @@ -1081,7 +1098,7 @@ int main(int argc, const char *argv[]) { auto Dbg = lldb_private::Debugger::CreateInstance(); ModuleList::GetGlobalModuleListProperties().SetEnableExternalLookup(false); - CommandReturnObject Result; + CommandReturnObject Result(/*colors*/ false); Dbg->GetCommandInterpreter().HandleCommand( "settings set plugin.process.gdb-remote.packet-timeout 60", /*add_to_history*/ eLazyBoolNo, Result); diff --git a/gnu/llvm/lldb/tools/lldb-vscode/BreakpointBase.cpp b/gnu/llvm/lldb/tools/lldb-vscode/BreakpointBase.cpp index af775250cb9..5013fcbb792 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/BreakpointBase.cpp +++ b/gnu/llvm/lldb/tools/lldb-vscode/BreakpointBase.cpp @@ -12,13 +12,13 @@ using namespace lldb_vscode; BreakpointBase::BreakpointBase(const llvm::json::Object &obj) - : condition(GetString(obj, "condition")), - hitCondition(GetString(obj, "hitCondition")), - logMessage(GetString(obj, "logMessage")) {} + : condition(std::string(GetString(obj, "condition"))), + hitCondition(std::string(GetString(obj, "hitCondition"))), + logMessage(std::string(GetString(obj, "logMessage"))) {} void BreakpointBase::SetCondition() { bp.SetCondition(condition.c_str()); } -void BreakpointBase::SetHitCondition() { +void BreakpointBase::SetHitCondition() { uint64_t hitCount = 0; if (llvm::to_integer(hitCondition, hitCount)) bp.SetIgnoreCount(hitCount - 1); @@ -34,3 +34,19 @@ void BreakpointBase::UpdateBreakpoint(const BreakpointBase &request_bp) { SetHitCondition(); } } + +const char *BreakpointBase::GetBreakpointLabel() { + // Breakpoints in LLDB can have names added to them which are kind of like + // labels or categories. All breakpoints that are set through the IDE UI get + // sent through the various VS code DAP set*Breakpoint packets, and these + // breakpoints will be labeled with this name so if breakpoint update events + // come in for breakpoints that the IDE doesn't know about, like if a + // breakpoint is set manually using the debugger console, we won't report any + // updates on them and confused the IDE. This function gets called by all of + // the breakpoint classes after they set breakpoints to mark a breakpoint as + // a UI breakpoint. We can later check a lldb::SBBreakpoint object that comes + // in via LLDB breakpoint changed events and check the breakpoint by calling + // "bool lldb::SBBreakpoint::MatchesName(const char *)" to check if a + // breakpoint in one of the UI breakpoints that we should report changes for. + return "vscode"; +} diff --git a/gnu/llvm/lldb/tools/lldb-vscode/BreakpointBase.h b/gnu/llvm/lldb/tools/lldb-vscode/BreakpointBase.h index ee241a9713a..eb1e466e244 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/BreakpointBase.h +++ b/gnu/llvm/lldb/tools/lldb-vscode/BreakpointBase.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDBVSCODE_BREAKPOINTBASE_H_ -#define LLDBVSCODE_BREAKPOINTBASE_H_ +#ifndef LLDB_TOOLS_LLDB_VSCODE_BREAKPOINTBASE_H +#define LLDB_TOOLS_LLDB_VSCODE_BREAKPOINTBASE_H #include "JSONUtils.h" #include "lldb/API/SBBreakpoint.h" @@ -15,7 +15,7 @@ #include namespace lldb_vscode { - + struct BreakpointBase { // An optional expression for conditional breakpoints. @@ -36,6 +36,7 @@ struct BreakpointBase { void SetCondition(); void SetHitCondition(); void UpdateBreakpoint(const BreakpointBase &request_bp); + static const char *GetBreakpointLabel(); }; } // namespace lldb_vscode diff --git a/gnu/llvm/lldb/tools/lldb-vscode/CMakeLists.txt b/gnu/llvm/lldb/tools/lldb-vscode/CMakeLists.txt index b527addb6ba..edf0aaa78d9 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/CMakeLists.txt +++ b/gnu/llvm/lldb/tools/lldb-vscode/CMakeLists.txt @@ -20,6 +20,9 @@ endif() # We need to include the llvm components we depend on manually, as liblldb does # not re-export those. set(LLVM_LINK_COMPONENTS Support) +set(LLVM_TARGET_DEFINITIONS Options.td) +tablegen(LLVM Options.inc -gen-opt-parser-defs) +add_public_tablegen_target(LLDBVSCodeOptionsTableGen) add_lldb_tool(lldb-vscode lldb-vscode.cpp BreakpointBase.cpp @@ -37,6 +40,7 @@ add_lldb_tool(lldb-vscode ${extra_libs} LINK_COMPONENTS + Option Support ) diff --git a/gnu/llvm/lldb/tools/lldb-vscode/ExceptionBreakpoint.cpp b/gnu/llvm/lldb/tools/lldb-vscode/ExceptionBreakpoint.cpp index 090463ff60c..9324e66d8bd 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/ExceptionBreakpoint.cpp +++ b/gnu/llvm/lldb/tools/lldb-vscode/ExceptionBreakpoint.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "ExceptionBreakpoint.h" +#include "BreakpointBase.h" #include "VSCode.h" namespace lldb_vscode { @@ -18,6 +19,9 @@ void ExceptionBreakpoint::SetBreakpoint() { bool throw_value = filter.find("_throw") != std::string::npos; bp = g_vsc.target.BreakpointCreateForException(language, catch_value, throw_value); + // See comments in BreakpointBase::GetBreakpointLabel() for details of why + // we add a label to our breakpoints. + bp.AddName(BreakpointBase::GetBreakpointLabel()); } void ExceptionBreakpoint::ClearBreakpoint() { @@ -28,4 +32,3 @@ void ExceptionBreakpoint::ClearBreakpoint() { } } // namespace lldb_vscode - diff --git a/gnu/llvm/lldb/tools/lldb-vscode/ExceptionBreakpoint.h b/gnu/llvm/lldb/tools/lldb-vscode/ExceptionBreakpoint.h index fd9f8efe237..75c617832e0 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/ExceptionBreakpoint.h +++ b/gnu/llvm/lldb/tools/lldb-vscode/ExceptionBreakpoint.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDBVSCODE_EXCEPTIONBREAKPOINT_H_ -#define LLDBVSCODE_EXCEPTIONBREAKPOINT_H_ +#ifndef LLDB_TOOLS_LLDB_VSCODE_EXCEPTIONBREAKPOINT_H +#define LLDB_TOOLS_LLDB_VSCODE_EXCEPTIONBREAKPOINT_H #include diff --git a/gnu/llvm/lldb/tools/lldb-vscode/FunctionBreakpoint.cpp b/gnu/llvm/lldb/tools/lldb-vscode/FunctionBreakpoint.cpp index 1ac2e856f16..9dd97e7b79e 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/FunctionBreakpoint.cpp +++ b/gnu/llvm/lldb/tools/lldb-vscode/FunctionBreakpoint.cpp @@ -12,12 +12,15 @@ namespace lldb_vscode { FunctionBreakpoint::FunctionBreakpoint(const llvm::json::Object &obj) - : BreakpointBase(obj), functionName(GetString(obj, "name")) {} + : BreakpointBase(obj), functionName(std::string(GetString(obj, "name"))) {} void FunctionBreakpoint::SetBreakpoint() { if (functionName.empty()) return; bp = g_vsc.target.BreakpointCreateByName(functionName.c_str()); + // See comments in BreakpointBase::GetBreakpointLabel() for details of why + // we add a label to our breakpoints. + bp.AddName(GetBreakpointLabel()); if (!condition.empty()) SetCondition(); if (!hitCondition.empty()) diff --git a/gnu/llvm/lldb/tools/lldb-vscode/FunctionBreakpoint.h b/gnu/llvm/lldb/tools/lldb-vscode/FunctionBreakpoint.h index dbc184914f0..82eec89cd18 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/FunctionBreakpoint.h +++ b/gnu/llvm/lldb/tools/lldb-vscode/FunctionBreakpoint.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDBVSCODE_FUNCTIONBREAKPOINT_H_ -#define LLDBVSCODE_FUNCTIONBREAKPOINT_H_ +#ifndef LLDB_TOOLS_LLDB_VSCODE_FUNCTIONBREAKPOINT_H +#define LLDB_TOOLS_LLDB_VSCODE_FUNCTIONBREAKPOINT_H #include "BreakpointBase.h" diff --git a/gnu/llvm/lldb/tools/lldb-vscode/IOStream.h b/gnu/llvm/lldb/tools/lldb-vscode/IOStream.h index 8414c09e9fe..603ae9adcc2 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/IOStream.h +++ b/gnu/llvm/lldb/tools/lldb-vscode/IOStream.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDBVSCODE_IOSTREAM_H_ -#define LLDBVSCODE_IOSTREAM_H_ +#ifndef LLDB_TOOLS_LLDB_VSCODE_IOSTREAM_H +#define LLDB_TOOLS_LLDB_VSCODE_IOSTREAM_H #if defined(_WIN32) // We need to #define NOMINMAX in order to skip `min()` and `max()` macro diff --git a/gnu/llvm/lldb/tools/lldb-vscode/JSONUtils.cpp b/gnu/llvm/lldb/tools/lldb-vscode/JSONUtils.cpp index b83f56445e2..1ebaa5c3771 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/JSONUtils.cpp +++ b/gnu/llvm/lldb/tools/lldb-vscode/JSONUtils.cpp @@ -8,7 +8,10 @@ #include +#include "llvm/ADT/Optional.h" #include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/ScopedPrinter.h" #include "lldb/API/SBBreakpoint.h" #include "lldb/API/SBBreakpointLocation.h" @@ -38,8 +41,8 @@ llvm::StringRef GetAsString(const llvm::json::Value &value) { // Gets a string from a JSON object using the key, or returns an empty string. llvm::StringRef GetString(const llvm::json::Object &obj, llvm::StringRef key) { - if (auto value = obj.getString(key)) - return GetAsString(*value); + if (llvm::Optional value = obj.getString(key)) + return *value; return llvm::StringRef(); } @@ -111,13 +114,9 @@ std::vector GetStrings(const llvm::json::Object *obj, strs.push_back(value.getAsString()->str()); break; case llvm::json::Value::Number: - case llvm::json::Value::Boolean: { - std::string s; - llvm::raw_string_ostream strm(s); - strm << value; - strs.push_back(strm.str()); + case llvm::json::Value::Boolean: + strs.push_back(llvm::to_string(value)); break; - } case llvm::json::Value::Null: case llvm::json::Value::Object: case llvm::json::Value::Array: @@ -281,17 +280,40 @@ llvm::json::Value CreateScope(const llvm::StringRef name, // }, // "required": [ "verified" ] // } -llvm::json::Value CreateBreakpoint(lldb::SBBreakpointLocation &bp_loc) { +llvm::json::Value CreateBreakpoint(lldb::SBBreakpoint &bp, + llvm::Optional request_path, + llvm::Optional request_line) { // Each breakpoint location is treated as a separate breakpoint for VS code. // They don't have the notion of a single breakpoint with multiple locations. llvm::json::Object object; - if (!bp_loc.IsValid()) + if (!bp.IsValid()) return llvm::json::Value(std::move(object)); - object.try_emplace("verified", true); - const auto vs_id = MakeVSCodeBreakpointID(bp_loc); - object.try_emplace("id", vs_id); + object.try_emplace("verified", bp.GetNumResolvedLocations() > 0); + object.try_emplace("id", bp.GetID()); + // VS Code DAP doesn't currently allow one breakpoint to have multiple + // locations so we just report the first one. If we report all locations + // then the IDE starts showing the wrong line numbers and locations for + // other source file and line breakpoints in the same file. + + // Below we search for the first resolved location in a breakpoint and report + // this as the breakpoint location since it will have a complete location + // that is at least loaded in the current process. + lldb::SBBreakpointLocation bp_loc; + const auto num_locs = bp.GetNumLocations(); + for (size_t i = 0; i < num_locs; ++i) { + bp_loc = bp.GetLocationAtIndex(i); + if (bp_loc.IsResolved()) + break; + } + // If not locations are resolved, use the first location. + if (!bp_loc.IsResolved()) + bp_loc = bp.GetLocationAtIndex(0); auto bp_addr = bp_loc.GetAddress(); + + if (request_path) + object.try_emplace("source", CreateSource(*request_path)); + if (bp_addr.IsValid()) { auto line_entry = bp_addr.GetLineEntry(); const auto line = line_entry.GetLine(); @@ -299,19 +321,52 @@ llvm::json::Value CreateBreakpoint(lldb::SBBreakpointLocation &bp_loc) { object.try_emplace("line", line); object.try_emplace("source", CreateSource(line_entry)); } + // We try to add request_line as a fallback + if (request_line) + object.try_emplace("line", *request_line); return llvm::json::Value(std::move(object)); } -void AppendBreakpoint(lldb::SBBreakpoint &bp, llvm::json::Array &breakpoints) { - if (!bp.IsValid()) - return; - const auto num_locations = bp.GetNumLocations(); - if (num_locations == 0) - return; - for (size_t i = 0; i < num_locations; ++i) { - auto bp_loc = bp.GetLocationAtIndex(i); - breakpoints.emplace_back(CreateBreakpoint(bp_loc)); +llvm::json::Value CreateModule(lldb::SBModule &module) { + llvm::json::Object object; + if (!module.IsValid()) + return llvm::json::Value(std::move(object)); + const char *uuid = module.GetUUIDString(); + object.try_emplace("id", uuid ? std::string(uuid) : std::string("")); + object.try_emplace("name", std::string(module.GetFileSpec().GetFilename())); + char module_path_arr[PATH_MAX]; + module.GetFileSpec().GetPath(module_path_arr, sizeof(module_path_arr)); + std::string module_path(module_path_arr); + object.try_emplace("path", module_path); + if (module.GetNumCompileUnits() > 0) { + object.try_emplace("symbolStatus", "Symbols loaded."); + char symbol_path_arr[PATH_MAX]; + module.GetSymbolFileSpec().GetPath(symbol_path_arr, sizeof(symbol_path_arr)); + std::string symbol_path(symbol_path_arr); + object.try_emplace("symbolFilePath", symbol_path); + } else { + object.try_emplace("symbolStatus", "Symbols not found."); } + std::string loaded_addr = std::to_string( + module.GetObjectFileHeaderAddress().GetLoadAddress(g_vsc.target)); + object.try_emplace("addressRange", loaded_addr); + std::string version_str; + uint32_t version_nums[3]; + uint32_t num_versions = module.GetVersion(version_nums, sizeof(version_nums)/sizeof(uint32_t)); + for (uint32_t i=0; i request_path, + llvm::Optional request_line) { + breakpoints.emplace_back(CreateBreakpoint(bp, request_path, request_line)); } // "Event": { @@ -472,6 +527,14 @@ llvm::json::Value CreateSource(lldb::SBLineEntry &line_entry) { return llvm::json::Value(std::move(object)); } +llvm::json::Value CreateSource(llvm::StringRef source_path) { + llvm::json::Object source; + llvm::StringRef name = llvm::sys::path::filename(source_path); + EmplaceSafeString(source, "name", name); + EmplaceSafeString(source, "path", source_path); + return llvm::json::Value(std::move(source)); +} + llvm::json::Value CreateSource(lldb::SBFrame &frame, int64_t &disasm_line) { disasm_line = 0; auto line_entry = frame.GetLineEntry(); @@ -741,6 +804,12 @@ llvm::json::Value CreateThreadStopped(lldb::SBThread &thread, EmplaceSafeString(body, "description", exc_bp->label); } else { body.try_emplace("reason", "breakpoint"); + char desc_str[64]; + uint64_t bp_id = thread.GetStopReasonDataAtIndex(0); + uint64_t bp_loc_id = thread.GetStopReasonDataAtIndex(1); + snprintf(desc_str, sizeof(desc_str), "breakpoint %" PRIu64 ".%" PRIu64, + bp_id, bp_loc_id); + EmplaceSafeString(body, "description", desc_str); } } break; case lldb::eStopReasonWatchpoint: @@ -869,5 +938,13 @@ llvm::json::Value CreateVariable(lldb::SBValue v, int64_t variablesReference, return llvm::json::Value(std::move(object)); } -} // namespace lldb_vscode +llvm::json::Value CreateCompileUnit(lldb::SBCompileUnit unit) { + llvm::json::Object object; + char unit_path_arr[PATH_MAX]; + unit.GetFileSpec().GetPath(unit_path_arr, sizeof(unit_path_arr)); + std::string unit_path(unit_path_arr); + object.try_emplace("compileUnitPath", unit_path); + return llvm::json::Value(std::move(object)); +} +} // namespace lldb_vscode diff --git a/gnu/llvm/lldb/tools/lldb-vscode/JSONUtils.h b/gnu/llvm/lldb/tools/lldb-vscode/JSONUtils.h index 2391ac32b5c..e2ccfdb1fb2 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/JSONUtils.h +++ b/gnu/llvm/lldb/tools/lldb-vscode/JSONUtils.h @@ -6,13 +6,14 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDBVSCODE_JSONUTILS_H_ -#define LLDBVSCODE_JSONUTILS_H_ +#ifndef LLDB_TOOLS_LLDB_VSCODE_JSONUTILS_H +#define LLDB_TOOLS_LLDB_VSCODE_JSONUTILS_H #include #include "llvm/ADT/StringRef.h" #include "llvm/Support/JSON.h" #include "VSCodeForward.h" +#include "lldb/API/SBModule.h" namespace lldb_vscode { @@ -184,28 +185,68 @@ void FillResponse(const llvm::json::Object &request, void SetValueForKey(lldb::SBValue &v, llvm::json::Object &object, llvm::StringRef key); -/// Converts \a bp to a JSON value and appends all locations to the +/// Converts \a bp to a JSON value and appends the first valid location to the /// \a breakpoints array. /// /// \param[in] bp -/// A LLDB breakpoint object which will get all locations extracted -/// and converted into a JSON objects in the \a breakpoints array +/// A LLDB breakpoint object which will get the first valid location +/// extracted and converted into a JSON object in the \a breakpoints array /// /// \param[in] breakpoints /// A JSON array that will get a llvm::json::Value for \a bp /// appended to it. -void AppendBreakpoint(lldb::SBBreakpoint &bp, llvm::json::Array &breakpoints); +/// +/// \param[in] request_path +/// An optional source path to use when creating the "Source" object of this +/// breakpoint. If not specified, the "Source" object is created from the +/// breakpoint's address' LineEntry. It is useful to ensure the same source +/// paths provided by the setBreakpoints request are returned to the IDE. +/// +/// \param[in] request_line +/// An optional line to use when creating the "Breakpoint" object to append. +/// It is used if the breakpoint has no valid locations. +/// It is useful to ensure the same line +/// provided by the setBreakpoints request are returned to the IDE as a +/// fallback. +void AppendBreakpoint(lldb::SBBreakpoint &bp, llvm::json::Array &breakpoints, + llvm::Optional request_path = llvm::None, + llvm::Optional request_line = llvm::None); /// Converts breakpoint location to a Visual Studio Code "Breakpoint" -/// JSON object and appends it to the \a breakpoints array. /// -/// \param[in] bp_loc -/// A LLDB breakpoint location object to convert into a JSON value +/// \param[in] bp +/// A LLDB breakpoint object to convert into a JSON value +/// +/// \param[in] request_path +/// An optional source path to use when creating the "Source" object of this +/// breakpoint. If not specified, the "Source" object is created from the +/// breakpoint's address' LineEntry. It is useful to ensure the same source +/// paths provided by the setBreakpoints request are returned to the IDE. +/// +/// \param[in] request_line +/// An optional line to use when creating the resulting "Breakpoint" object. +/// It is used if the breakpoint has no valid locations. +/// It is useful to ensure the same line +/// provided by the setBreakpoints request are returned to the IDE as a +/// fallback. /// /// \return /// A "Breakpoint" JSON object with that follows the formal JSON /// definition outlined by Microsoft. -llvm::json::Value CreateBreakpoint(lldb::SBBreakpointLocation &bp_loc); +llvm::json::Value +CreateBreakpoint(lldb::SBBreakpoint &bp, + llvm::Optional request_path = llvm::None, + llvm::Optional request_line = llvm::None); + +/// Converts a LLDB module to a VS Code DAP module for use in "modules" events. +/// +/// \param[in] module +/// A LLDB module object to convert into a JSON value +/// +/// \return +/// A "Module" JSON object with that follows the formal JSON +/// definition outlined by Microsoft. +llvm::json::Value CreateModule(lldb::SBModule &module); /// Create a "Event" JSON object using \a event_name as the event name /// @@ -221,7 +262,7 @@ llvm::json::Object CreateEventObject(const llvm::StringRef event_name); /// the Visual Studio Code debug adaptor definition. /// /// \param[in] bp -/// The exception breakppoint object to use +/// The exception breakpoint object to use /// /// \return /// A "ExceptionBreakpointsFilter" JSON object with that follows @@ -263,6 +304,16 @@ llvm::json::Value CreateScope(const llvm::StringRef name, /// definition outlined by Microsoft. llvm::json::Value CreateSource(lldb::SBLineEntry &line_entry); +/// Create a "Source" object for a given source path. +/// +/// \param[in] source_path +/// The path to the source to use when creating the "Source" object. +/// +/// \return +/// A "Source" JSON object that follows the formal JSON +/// definition outlined by Microsoft. +llvm::json::Value CreateSource(llvm::StringRef source_path); + /// Create a "Source" object for a given frame. /// /// When there is no source file information for a stack frame, we will @@ -390,6 +441,8 @@ llvm::json::Value CreateThreadStopped(lldb::SBThread &thread, uint32_t stop_id); llvm::json::Value CreateVariable(lldb::SBValue v, int64_t variablesReference, int64_t varID, bool format_hex); +llvm::json::Value CreateCompileUnit(lldb::SBCompileUnit unit); + } // namespace lldb_vscode #endif diff --git a/gnu/llvm/lldb/tools/lldb-vscode/LLDBUtils.cpp b/gnu/llvm/lldb/tools/lldb-vscode/LLDBUtils.cpp index 5be293dab4e..81b5a789d1d 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/LLDBUtils.cpp +++ b/gnu/llvm/lldb/tools/lldb-vscode/LLDBUtils.cpp @@ -79,19 +79,4 @@ int64_t MakeVSCodeFrameID(lldb::SBFrame &frame) { frame.GetFrameID()); } -static uint32_t constexpr BREAKPOINT_ID_SHIFT = 22; - -uint32_t GetLLDBBreakpointID(uint64_t dap_breakpoint_id) { - return dap_breakpoint_id >> BREAKPOINT_ID_SHIFT; -} - -uint32_t GetLLDBBreakpointLocationID(uint64_t dap_breakpoint_id) { - return dap_breakpoint_id & ((1u << BREAKPOINT_ID_SHIFT) - 1); -} - -int64_t MakeVSCodeBreakpointID(lldb::SBBreakpointLocation &bp_loc) { - return (int64_t)(bp_loc.GetBreakpoint().GetID() << BREAKPOINT_ID_SHIFT | - bp_loc.GetID()); -} - } // namespace lldb_vscode diff --git a/gnu/llvm/lldb/tools/lldb-vscode/LLDBUtils.h b/gnu/llvm/lldb/tools/lldb-vscode/LLDBUtils.h index 82c17eb3cdc..8867589b18a 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/LLDBUtils.h +++ b/gnu/llvm/lldb/tools/lldb-vscode/LLDBUtils.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDBVSCODE_LLDBUTILS_H_ -#define LLDBVSCODE_LLDBUTILS_H_ +#ifndef LLDB_TOOLS_LLDB_VSCODE_LLDBUTILS_H +#define LLDB_TOOLS_LLDB_VSCODE_LLDBUTILS_H #include "VSCodeForward.h" #include "llvm/ADT/ArrayRef.h" @@ -106,46 +106,6 @@ uint32_t GetLLDBThreadIndexID(uint64_t dap_frame_id); /// The LLDB frame index ID. uint32_t GetLLDBFrameID(uint64_t dap_frame_id); -/// Given a LLDB breakpoint, make a breakpoint ID that is unique to a -/// specific breakpoint and breakpoint location. -/// -/// VSCode requires a Breakpoint "id" to be unique, so we use the -/// breakpoint ID in the lower BREAKPOINT_ID_SHIFT bits and the -/// breakpoint location ID in the upper BREAKPOINT_ID_SHIFT bits. -/// -/// \param[in] bp_loc -/// The LLDB break point location. -/// -/// \return -/// A unique integer that allows us to easily find the right -/// stack frame within a thread on subsequent VS code requests. -int64_t MakeVSCodeBreakpointID(lldb::SBBreakpointLocation &bp_loc); - -/// Given a VSCode breakpoint ID, convert to a LLDB breakpoint ID. -/// -/// VSCode requires a Breakpoint "id" to be unique, so we use the -/// breakpoint ID in the lower BREAKPOINT_ID_SHIFT bits and the -/// breakpoint location ID in the upper BREAKPOINT_ID_SHIFT bits. -/// -/// \param[in] dap_breakpoint_id -/// The VSCode breakpoint ID to convert to an LLDB breakpoint ID. -/// -/// \return -/// The LLDB breakpoint ID. -uint32_t GetLLDBBreakpointID(uint64_t dap_breakpoint_id); - -/// Given a VSCode breakpoint ID, convert to a LLDB breakpoint location ID. -/// -/// VSCode requires a Breakpoint "id" to be unique, so we use the -/// breakpoint ID in the lower BREAKPOINT_ID_SHIFT bits and the -/// breakpoint location ID in the upper BREAKPOINT_ID_SHIFT bits. -/// -/// \param[in] dap_breakpoint_id -/// The VSCode frame ID to convert to a breakpoint location ID. -/// -/// \return -/// The LLDB breakpoint location ID. -uint32_t GetLLDBBreakpointLocationID(uint64_t dap_breakpoint_id); } // namespace lldb_vscode #endif diff --git a/gnu/llvm/lldb/tools/lldb-vscode/Options.td b/gnu/llvm/lldb/tools/lldb-vscode/Options.td new file mode 100644 index 00000000000..87cfb5199b4 --- /dev/null +++ b/gnu/llvm/lldb/tools/lldb-vscode/Options.td @@ -0,0 +1,25 @@ +include "llvm/Option/OptParser.td" + +class F: Flag<["--", "-"], name>; +class S: Separate<["--", "-"], name>; +class R prefixes, string name> + : Option; + +def help: F<"help">, + HelpText<"Prints out the usage information for the LLDB VSCode tool.">; +def: Flag<["-"], "h">, + Alias, + HelpText<"Alias for --help">; + +def wait_for_debugger: F<"wait-for-debugger">, + HelpText<"Pause the program at startup.">; +def: Flag<["-"], "g">, + Alias, + HelpText<"Alias for --wait-for-debugger">; + +def port: Separate<["--", "-"], "port">, + MetaVarName<"">, + HelpText<"Communicate with the lldb-vscode tool over the defined port.">; +def: Separate<["-"], "p">, + Alias, + HelpText<"Alias for --port">; diff --git a/gnu/llvm/lldb/tools/lldb-vscode/README.md b/gnu/llvm/lldb/tools/lldb-vscode/README.md index 2294659fc29..70ca245f85b 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/README.md +++ b/gnu/llvm/lldb/tools/lldb-vscode/README.md @@ -16,14 +16,14 @@ The `lldb-vscode` tool creates a command line tool that implements the [Visual Studio Code Debug API](https://code.visualstudio.com/docs/extensionAPI/api-debugging). -It can be installed as an extension for the Visual Studio Code and Nuclide IDE. +It can be installed as an extension for the Visual Studio Code and Nuclide IDE. The protocol is easy to run remotely and also can allow other tools and IDEs to -get a full featured debugger with a well defined protocol. +get a full featured debugger with a well defined protocol. # Installation for Visual Studio Code Installing the plug-in involves creating a directory in the `~/.vscode/extensions` folder and copying the package.json file that is in the same directory as this -documentation into it, and copying to symlinking a lldb-vscode binary into +documentation into it, and copying to symlinking a lldb-vscode binary into the `bin` directory inside the plug-in directory. If you want to make a stand alone plug-in that you can send to others on unix systems: @@ -86,6 +86,7 @@ file that defines how your program will be run. The JSON configuration file can |**preRunCommands** |[string]| | LLDB commands executed just before launching after the LLDB target has been created. Commands and command output will be sent to the debugger console when they are executed. |**stopCommands** |[string]| | LLDB commands executed just after each stop. Commands and command output will be sent to the debugger console when they are executed. |**exitCommands** |[string]| | LLDB commands executed when the program exits. Commands and command output will be sent to the debugger console when they are executed. +|**terminateCommands** |[string]| | LLDB commands executed when the debugging session ends. Commands and command output will be sent to the debugger console when they are executed. |**sourceMap** |[string[2]]| | Specify an array of path re-mappings. Each element in the array must be a two element array containing a source and destination pathname. |**debuggerRoot** | string| |Specify a working directory to use when launching lldb-vscode. If the debug information in your executable contains relative paths, this option can be used so that `lldb-vscode` can find source files and object files that have relative paths. @@ -112,6 +113,7 @@ The JSON configuration file can contain the following `lldb-vscode` specific lau |**preRunCommands** |[string]| | LLDB commands executed just before launching after the LLDB target has been created. Commands and command output will be sent to the debugger console when they are executed. |**stopCommands** |[string]| | LLDB commands executed just after each stop. Commands and command output will be sent to the debugger console when they are executed. |**exitCommands** |[string]| | LLDB commands executed when the program exits. Commands and command output will be sent to the debugger console when they are executed. +|**terminateCommands** |[string]| | LLDB commands executed when the debugging session ends. Commands and command output will be sent to the debugger console when they are executed. |**attachCommands** |[string]| | LLDB commands that will be executed after **preRunCommands** which take place of the code that normally does the attach. The commands can create a new target and attach or launch it however desired. This allows custom launch and attach configurations. Core files can use `target create --core /path/to/core` to attach to core files. @@ -181,15 +183,15 @@ for processes. Currently MacOS is the only platform that supports this. ### Loading a Core File -Loading a core file can use the `"attach"` request along with the -`"attachCommands"` to implement a custom attach: +This loads the coredump file `/cores/123.core` associated with the program +`/tmp/a.out`: ```javascript { - "name": "Attach to Name (wait)", + "name": "Load coredump", "type": "lldb-vscode", "request": "attach", - "attachCommands": ["target create -c /path/to/123.core /path/to/executable"], - "stopOnEntry": false + "coreFile": "/cores/123.core", + "program": "/tmp/a.out" } ``` diff --git a/gnu/llvm/lldb/tools/lldb-vscode/SourceBreakpoint.cpp b/gnu/llvm/lldb/tools/lldb-vscode/SourceBreakpoint.cpp index 91d1ad70ecd..be93c2e21ea 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/SourceBreakpoint.cpp +++ b/gnu/llvm/lldb/tools/lldb-vscode/SourceBreakpoint.cpp @@ -17,6 +17,9 @@ SourceBreakpoint::SourceBreakpoint(const llvm::json::Object &obj) void SourceBreakpoint::SetBreakpoint(const llvm::StringRef source_path) { bp = g_vsc.target.BreakpointCreateByLocation(source_path.str().c_str(), line); + // See comments in BreakpointBase::GetBreakpointLabel() for details of why + // we add a label to our breakpoints. + bp.AddName(GetBreakpointLabel()); if (!condition.empty()) SetCondition(); if (!hitCondition.empty()) diff --git a/gnu/llvm/lldb/tools/lldb-vscode/SourceBreakpoint.h b/gnu/llvm/lldb/tools/lldb-vscode/SourceBreakpoint.h index f17557ef1f8..95f192beff8 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/SourceBreakpoint.h +++ b/gnu/llvm/lldb/tools/lldb-vscode/SourceBreakpoint.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDBVSCODE_SOURCEBREAKPOINT_H_ -#define LLDBVSCODE_SOURCEBREAKPOINT_H_ +#ifndef LLDB_TOOLS_LLDB_VSCODE_SOURCEBREAKPOINT_H +#define LLDB_TOOLS_LLDB_VSCODE_SOURCEBREAKPOINT_H #include "llvm/ADT/StringRef.h" #include "BreakpointBase.h" diff --git a/gnu/llvm/lldb/tools/lldb-vscode/SourceReference.h b/gnu/llvm/lldb/tools/lldb-vscode/SourceReference.h index 55f5b9b9c40..cf62fb6680e 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/SourceReference.h +++ b/gnu/llvm/lldb/tools/lldb-vscode/SourceReference.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDBVSCODE_SOURCEREFERENCE_H_ -#define LLDBVSCODE_SOURCEREFERENCE_H_ +#ifndef LLDB_TOOLS_LLDB_VSCODE_SOURCEREFERENCE_H +#define LLDB_TOOLS_LLDB_VSCODE_SOURCEREFERENCE_H #include "lldb/lldb-types.h" #include "llvm/ADT/DenseMap.h" diff --git a/gnu/llvm/lldb/tools/lldb-vscode/VSCode.cpp b/gnu/llvm/lldb/tools/lldb-vscode/VSCode.cpp index 2f85627da4b..4a30aef3a6d 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/VSCode.cpp +++ b/gnu/llvm/lldb/tools/lldb-vscode/VSCode.cpp @@ -28,8 +28,8 @@ namespace lldb_vscode { VSCode g_vsc; VSCode::VSCode() - : launch_info(nullptr), variables(), broadcaster("lldb-vscode"), - num_regs(0), num_locals(0), num_globals(0), log(), + : variables(), broadcaster("lldb-vscode"), num_regs(0), num_locals(0), + num_globals(0), log(), exception_breakpoints( {{"cpp_catch", "C++ Catch", lldb::eLanguageTypeC_plus_plus}, {"cpp_throw", "C++ Throw", lldb::eLanguageTypeC_plus_plus}, @@ -38,7 +38,7 @@ VSCode::VSCode() {"swift_catch", "Swift Catch", lldb::eLanguageTypeSwift}, {"swift_throw", "Swift Throw", lldb::eLanguageTypeSwift}}), focus_tid(LLDB_INVALID_THREAD_ID), sent_terminated_event(false), - stop_at_entry(false) { + stop_at_entry(false), is_attach(false) { const char *log_file_path = getenv("LLDBVSCODE_LOG"); #if defined(_WIN32) // Windows opens stdout and stdin in text mode which converts \n to 13,10 @@ -129,6 +129,12 @@ std::string VSCode::ReadJSON() { if (!input.read_full(log.get(), length, json_str)) return json_str; + if (log) { + *log << "--> " << std::endl + << "Content-Length: " << length << "\r\n\r\n" + << json_str << std::endl; + } + return json_str; } @@ -303,4 +309,61 @@ void VSCode::RunExitCommands() { RunLLDBCommands("Running exitCommands:", exit_commands); } +void VSCode::RunTerminateCommands() { + RunLLDBCommands("Running terminateCommands:", terminate_commands); +} + +lldb::SBTarget VSCode::CreateTargetFromArguments( + const llvm::json::Object &arguments, + lldb::SBError &error) { + // Grab the name of the program we need to debug and create a target using + // the given program as an argument. Executable file can be a source of target + // architecture and platform, if they differ from the host. Setting exe path + // in launch info is useless because Target.Launch() will not change + // architecture and platform, therefore they should be known at the target + // creation. We also use target triple and platform from the launch + // configuration, if given, since in some cases ELF file doesn't contain + // enough information to determine correct arch and platform (or ELF can be + // omitted at all), so it is good to leave the user an apportunity to specify + // those. Any of those three can be left empty. + llvm::StringRef target_triple = GetString(arguments, "targetTriple"); + llvm::StringRef platform_name = GetString(arguments, "platformName"); + llvm::StringRef program = GetString(arguments, "program"); + auto target = this->debugger.CreateTarget( + program.data(), + target_triple.data(), + platform_name.data(), + true, // Add dependent modules. + error + ); + + if (error.Fail()) { + // Update message if there was an error. + error.SetErrorStringWithFormat( + "Could not create a target for a program '%s': %s.", + program.data(), error.GetCString()); + } + + return target; +} + +void VSCode::SetTarget(const lldb::SBTarget target) { + this->target = target; + + if (target.IsValid()) { + // Configure breakpoint event listeners for the target. + lldb::SBListener listener = this->debugger.GetListener(); + listener.StartListeningForEvents( + this->target.GetBroadcaster(), + lldb::SBTarget::eBroadcastBitBreakpointChanged); + listener.StartListeningForEvents(this->broadcaster, + eBroadcastBitStopEventThread); + listener.StartListeningForEvents( + this->target.GetBroadcaster(), + lldb::SBTarget::eBroadcastBitModulesLoaded | + lldb::SBTarget::eBroadcastBitModulesUnloaded | + lldb::SBTarget::eBroadcastBitSymbolsLoaded); + } +} + } // namespace lldb_vscode diff --git a/gnu/llvm/lldb/tools/lldb-vscode/VSCode.h b/gnu/llvm/lldb/tools/lldb-vscode/VSCode.h index be8b22806a4..ddb4c09a417 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/VSCode.h +++ b/gnu/llvm/lldb/tools/lldb-vscode/VSCode.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDBVSCODE_VSCODE_H_ -#define LLDBVSCODE_VSCODE_H_ +#ifndef LLDB_TOOLS_LLDB_VSCODE_VSCODE_H +#define LLDB_TOOLS_LLDB_VSCODE_VSCODE_H #include #include @@ -63,13 +63,13 @@ typedef llvm::DenseMap SourceBreakpointMap; typedef llvm::StringMap FunctionBreakpointMap; enum class OutputType { Console, Stdout, Stderr, Telemetry }; +enum VSCodeBroadcasterBits { eBroadcastBitStopEventThread = 1u << 0 }; + struct VSCode { InputStream input; OutputStream output; lldb::SBDebugger debugger; lldb::SBTarget target; - lldb::SBAttachInfo attach_info; - lldb::SBLaunchInfo launch_info; lldb::SBValueList variables; lldb::SBBroadcaster broadcaster; int64_t num_regs; @@ -86,9 +86,11 @@ struct VSCode { std::vector pre_run_commands; std::vector exit_commands; std::vector stop_commands; + std::vector terminate_commands; lldb::tid_t focus_tid; bool sent_terminated_event; bool stop_at_entry; + bool is_attach; // Keep track of the last stop thread index IDs as threads won't go away // unless we send a "thread" event to indicate the thread exited. llvm::DenseSet thread_ids; @@ -132,6 +134,25 @@ struct VSCode { void RunPreRunCommands(); void RunStopCommands(); void RunExitCommands(); + void RunTerminateCommands(); + + /// Create a new SBTarget object from the given request arguments. + /// \param[in] arguments + /// Launch configuration arguments. + /// + /// \param[out] error + /// An SBError object that will contain an error description if + /// function failed to create the target. + /// + /// \return + /// An SBTarget object. + lldb::SBTarget CreateTargetFromArguments( + const llvm::json::Object &arguments, + lldb::SBError &error); + + /// Set given target object as a current target for lldb-vscode and start + /// listeing for its breakpoint events. + void SetTarget(const lldb::SBTarget target); }; extern VSCode g_vsc; diff --git a/gnu/llvm/lldb/tools/lldb-vscode/VSCodeForward.h b/gnu/llvm/lldb/tools/lldb-vscode/VSCodeForward.h index 4a89120d1ec..6be5a9635e7 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/VSCodeForward.h +++ b/gnu/llvm/lldb/tools/lldb-vscode/VSCodeForward.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDBVSCODE_VSCODEFORWARD_H_ -#define LLDBVSCODE_VSCODEFORWARD_H_ - +#ifndef LLDB_TOOLS_LLDB_VSCODE_VSCODEFORWARD_H +#define LLDB_TOOLS_LLDB_VSCODE_VSCODEFORWARD_H namespace lldb_vscode { struct BreakpointBase; diff --git a/gnu/llvm/lldb/tools/lldb-vscode/lldb-vscode.cpp b/gnu/llvm/lldb/tools/lldb-vscode/lldb-vscode.cpp index 6d638a6a8f8..27ee832677d 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/lldb-vscode.cpp +++ b/gnu/llvm/lldb/tools/lldb-vscode/lldb-vscode.cpp @@ -39,10 +39,15 @@ #include #include #include +#include #include "llvm/ADT/ArrayRef.h" +#include "llvm/Option/Arg.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Option/Option.h" #include "llvm/Support/Errno.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include "JSONUtils.h" @@ -64,13 +69,38 @@ constexpr const char *dev_null_path = "/dev/null"; using namespace lldb_vscode; namespace { +enum ID { + OPT_INVALID = 0, // This is not an option ID. +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES) \ + OPT_##ID, +#include "Options.inc" +#undef OPTION +}; + +#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; +#include "Options.inc" +#undef PREFIX + +static const llvm::opt::OptTable::Info InfoTable[] = { +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES) \ + {PREFIX, NAME, HELPTEXT, \ + METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \ + PARAM, FLAGS, OPT_##GROUP, \ + OPT_##ALIAS, ALIASARGS, VALUES}, +#include "Options.inc" +#undef OPTION +}; +class LLDBVSCodeOptTable : public llvm::opt::OptTable { +public: + LLDBVSCodeOptTable() : OptTable(InfoTable, true) {} +}; typedef void (*RequestCallback)(const llvm::json::Object &command); enum LaunchMethod { Launch, Attach, AttachForSuspendedLaunch }; -enum VSCodeBroadcasterBits { eBroadcastBitStopEventThread = 1u << 0 }; - SOCKET AcceptConnection(int portno) { // Accept a socket connection from any host on "portno". SOCKET newsockfd = -1; @@ -145,6 +175,7 @@ void SendThreadExitedEvent(lldb::tid_t tid) { void SendTerminatedEvent() { if (!g_vsc.sent_terminated_event) { g_vsc.sent_terminated_event = true; + g_vsc.RunTerminateCommands(); // Send a "terminated" event llvm::json::Object event(CreateEventObject("terminated")); g_vsc.SendJSON(llvm::json::Value(std::move(event))); @@ -379,27 +410,53 @@ void EventThreadFunction() { if (event_mask & lldb::SBTarget::eBroadcastBitBreakpointChanged) { auto event_type = lldb::SBBreakpoint::GetBreakpointEventTypeFromEvent(event); - const auto num_locs = - lldb::SBBreakpoint::GetNumBreakpointLocationsFromEvent(event); auto bp = lldb::SBBreakpoint::GetBreakpointFromEvent(event); - bool added = event_type & lldb::eBreakpointEventTypeLocationsAdded; - bool removed = - event_type & lldb::eBreakpointEventTypeLocationsRemoved; - if (added || removed) { - for (size_t i = 0; i < num_locs; ++i) { - auto bp_loc = - lldb::SBBreakpoint::GetBreakpointLocationAtIndexFromEvent( - event, i); - auto bp_event = CreateEventObject("breakpoint"); - llvm::json::Object body; - body.try_emplace("breakpoint", CreateBreakpoint(bp_loc)); - if (added) - body.try_emplace("reason", "new"); - else - body.try_emplace("reason", "removed"); - bp_event.try_emplace("body", std::move(body)); - g_vsc.SendJSON(llvm::json::Value(std::move(bp_event))); + // If the breakpoint was originated from the IDE, it will have the + // BreakpointBase::GetBreakpointLabel() label attached. Regardless + // of wether the locations were added or removed, the breakpoint + // ins't going away, so we the reason is always "changed". + if ((event_type & lldb::eBreakpointEventTypeLocationsAdded || + event_type & lldb::eBreakpointEventTypeLocationsRemoved) && + bp.MatchesName(BreakpointBase::GetBreakpointLabel())) { + auto bp_event = CreateEventObject("breakpoint"); + llvm::json::Object body; + // As VSCode already knows the path of this breakpoint, we don't + // need to send it back as part of a "changed" event. This + // prevent us from sending to VSCode paths that should be source + // mapped. Note that CreateBreakpoint doesn't apply source mapping. + // Besides, the current implementation of VSCode ignores the + // "source" element of breakpoint events. + llvm::json::Value source_bp = CreateBreakpoint(bp); + source_bp.getAsObject()->erase("source"); + + body.try_emplace("breakpoint", source_bp); + body.try_emplace("reason", "changed"); + bp_event.try_emplace("body", std::move(body)); + g_vsc.SendJSON(llvm::json::Value(std::move(bp_event))); + } + } + } else if (lldb::SBTarget::EventIsTargetEvent(event)) { + if (event_mask & lldb::SBTarget::eBroadcastBitModulesLoaded || + event_mask & lldb::SBTarget::eBroadcastBitModulesUnloaded || + event_mask & lldb::SBTarget::eBroadcastBitSymbolsLoaded) { + int num_modules = lldb::SBTarget::GetNumModulesFromEvent(event); + for (int i = 0; i < num_modules; i++) { + auto module = lldb::SBTarget::GetModuleAtIndexFromEvent(i, event); + auto module_event = CreateEventObject("module"); + llvm::json::Value module_value = CreateModule(module); + llvm::json::Object body; + if (event_mask & lldb::SBTarget::eBroadcastBitModulesLoaded) { + body.try_emplace("reason", "new"); + } else if (event_mask & + lldb::SBTarget::eBroadcastBitModulesUnloaded) { + body.try_emplace("reason", "removed"); + } else if (event_mask & + lldb::SBTarget::eBroadcastBitSymbolsLoaded) { + body.try_emplace("reason", "changed"); } + body.try_emplace("module", module_value); + module_event.try_emplace("body", std::move(body)); + g_vsc.SendJSON(llvm::json::Value(std::move(module_event))); } } } else if (event.BroadcasterMatchesRef(g_vsc.broadcaster)) { @@ -483,76 +540,68 @@ void SetSourceMapFromArguments(const llvm::json::Object &arguments) { // }] // } void request_attach(const llvm::json::Object &request) { + g_vsc.is_attach = true; llvm::json::Object response; lldb::SBError error; FillResponse(request, response); + lldb::SBAttachInfo attach_info; auto arguments = request.getObject("arguments"); const lldb::pid_t pid = GetUnsigned(arguments, "pid", LLDB_INVALID_PROCESS_ID); if (pid != LLDB_INVALID_PROCESS_ID) - g_vsc.attach_info.SetProcessID(pid); + attach_info.SetProcessID(pid); const auto wait_for = GetBoolean(arguments, "waitFor", false); - g_vsc.attach_info.SetWaitForLaunch(wait_for, false /*async*/); + attach_info.SetWaitForLaunch(wait_for, false /*async*/); g_vsc.init_commands = GetStrings(arguments, "initCommands"); g_vsc.pre_run_commands = GetStrings(arguments, "preRunCommands"); g_vsc.stop_commands = GetStrings(arguments, "stopCommands"); g_vsc.exit_commands = GetStrings(arguments, "exitCommands"); + g_vsc.terminate_commands = GetStrings(arguments, "terminateCommands"); auto attachCommands = GetStrings(arguments, "attachCommands"); - g_vsc.stop_at_entry = GetBoolean(arguments, "stopOnEntry", false); - const auto debuggerRoot = GetString(arguments, "debuggerRoot"); + llvm::StringRef core_file = GetString(arguments, "coreFile"); + g_vsc.stop_at_entry = + core_file.empty() ? GetBoolean(arguments, "stopOnEntry", false) : true; + const llvm::StringRef debuggerRoot = GetString(arguments, "debuggerRoot"); // This is a hack for loading DWARF in .o files on Mac where the .o files // in the debug map of the main executable have relative paths which require // the lldb-vscode binary to have its working directory set to that relative // root for the .o files in order to be able to load debug info. - if (!debuggerRoot.empty()) { - llvm::sys::fs::set_current_path(debuggerRoot.data()); - } + if (!debuggerRoot.empty()) + llvm::sys::fs::set_current_path(debuggerRoot); // Run any initialize LLDB commands the user specified in the launch.json g_vsc.RunInitCommands(); - // Grab the name of the program we need to debug and set it as the first - // argument that will be passed to the program we will debug. - const auto program = GetString(arguments, "program"); - if (!program.empty()) { - lldb::SBFileSpec program_fspec(program.data(), true /*resolve_path*/); - - g_vsc.launch_info.SetExecutableFile(program_fspec, - false /*add_as_first_arg*/); - const char *target_triple = nullptr; - const char *uuid_cstr = nullptr; - // Stand alone debug info file if different from executable - const char *symfile = nullptr; - g_vsc.target.AddModule(program.data(), target_triple, uuid_cstr, symfile); - if (error.Fail()) { - response["success"] = llvm::json::Value(false); - EmplaceSafeString(response, "message", std::string(error.GetCString())); - g_vsc.SendJSON(llvm::json::Value(std::move(response))); - return; - } + lldb::SBError status; + g_vsc.SetTarget(g_vsc.CreateTargetFromArguments(*arguments, status)); + if (status.Fail()) { + response["success"] = llvm::json::Value(false); + EmplaceSafeString(response, "message", status.GetCString()); + g_vsc.SendJSON(llvm::json::Value(std::move(response))); + return; } - const bool detatchOnError = GetBoolean(arguments, "detachOnError", false); - g_vsc.launch_info.SetDetachOnError(detatchOnError); - // Run any pre run LLDB commands the user specified in the launch.json g_vsc.RunPreRunCommands(); if (pid == LLDB_INVALID_PROCESS_ID && wait_for) { - char attach_info[256]; - auto attach_info_len = - snprintf(attach_info, sizeof(attach_info), - "Waiting to attach to \"%s\"...", program.data()); - g_vsc.SendOutput(OutputType::Console, llvm::StringRef(attach_info, - attach_info_len)); + char attach_msg[256]; + auto attach_msg_len = snprintf(attach_msg, sizeof(attach_msg), + "Waiting to attach to \"%s\"...", + g_vsc.target.GetExecutable().GetFilename()); + g_vsc.SendOutput(OutputType::Console, + llvm::StringRef(attach_msg, attach_msg_len)); } if (attachCommands.empty()) { // No "attachCommands", just attach normally. // Disable async events so the attach will be successful when we return from // the launch call and the launch will happen synchronously g_vsc.debugger.SetAsync(false); - g_vsc.target.Attach(g_vsc.attach_info, error); + if (core_file.empty()) + g_vsc.target.Attach(attach_info, error); + else + g_vsc.target.LoadCore(core_file.data(), error); // Reenable async events g_vsc.debugger.SetAsync(true); } else { @@ -567,7 +616,7 @@ void request_attach(const llvm::json::Object &request) { SetSourceMapFromArguments(*arguments); - if (error.Success()) { + if (error.Success() && core_file.empty()) { auto attached_pid = g_vsc.target.GetProcess().GetProcessID(); if (attached_pid == LLDB_INVALID_PROCESS_ID) { if (attachCommands.empty()) @@ -748,10 +797,11 @@ void request_disconnect(const llvm::json::Object &request) { FillResponse(request, response); auto arguments = request.getObject("arguments"); - bool terminateDebuggee = GetBoolean(arguments, "terminateDebuggee", false); + bool defaultTerminateDebuggee = g_vsc.is_attach ? false : true; + bool terminateDebuggee = + GetBoolean(arguments, "terminateDebuggee", defaultTerminateDebuggee); lldb::SBProcess process = g_vsc.target.GetProcess(); auto state = process.GetState(); - switch (state) { case lldb::eStateInvalid: case lldb::eStateUnloaded: @@ -767,15 +817,14 @@ void request_disconnect(const llvm::json::Object &request) { case lldb::eStateStopped: case lldb::eStateRunning: g_vsc.debugger.SetAsync(false); - if (terminateDebuggee) - process.Kill(); - else - process.Detach(); + lldb::SBError error = terminateDebuggee ? process.Kill() : process.Detach(); + if (!error.Success()) + response.try_emplace("error", error.GetCString()); g_vsc.debugger.SetAsync(true); break; } - g_vsc.SendJSON(llvm::json::Value(std::move(response))); SendTerminatedEvent(); + g_vsc.SendJSON(llvm::json::Value(std::move(response))); if (g_vsc.event_thread.joinable()) { g_vsc.broadcaster.BroadcastEventByType(eBroadcastBitStopEventThread); g_vsc.event_thread.join(); @@ -923,7 +972,7 @@ void request_completions(const llvm::json::Object &request) { FillResponse(request, response); llvm::json::Object body; auto arguments = request.getObject("arguments"); - std::string text = GetString(arguments, "text"); + std::string text = std::string(GetString(arguments, "text")); auto original_column = GetSigned(arguments, "column", text.size()); auto actual_column = original_column - 1; llvm::json::Array targets; @@ -946,14 +995,22 @@ void request_completions(const llvm::json::Object &request) { text.c_str(), actual_column, 0, -1, matches, descriptions); - size_t count = std::min((uint32_t)50, matches.GetSize()); + size_t count = std::min((uint32_t)100, matches.GetSize()); targets.reserve(count); for (size_t i = 0; i < count; i++) { std::string match = matches.GetStringAtIndex(i); std::string description = descriptions.GetStringAtIndex(i); llvm::json::Object item; - EmplaceSafeString(item, "text", match); + + llvm::StringRef match_ref = match; + for(llvm::StringRef commit_point: {".", "->"}) { + if (match_ref.contains(commit_point)){ + match_ref = match_ref.rsplit(commit_point).second; + } + } + EmplaceSafeString(item, "text", match_ref); + if (description.empty()) EmplaceSafeString(item, "label", match); else @@ -1077,8 +1134,8 @@ void request_evaluate(const llvm::json::Object &request) { const auto expression = GetString(arguments, "expression"); if (!expression.empty() && expression[0] == '`') { - auto result = RunLLDBCommands(llvm::StringRef(), - {expression.substr(1)}); + auto result = + RunLLDBCommands(llvm::StringRef(), {std::string(expression.substr(1))}); EmplaceSafeString(body, "result", result); body.try_emplace("variablesReference", (int64_t)0); } else { @@ -1117,6 +1174,72 @@ void request_evaluate(const llvm::json::Object &request) { g_vsc.SendJSON(llvm::json::Value(std::move(response))); } +// "getCompileUnitsRequest": { +// "allOf": [ { "$ref": "#/definitions/Request" }, { +// "type": "object", +// "description": "Compile Unit request; value of command field is +// 'getCompileUnits'.", +// "properties": { +// "command": { +// "type": "string", +// "enum": [ "getCompileUnits" ] +// }, +// "arguments": { +// "$ref": "#/definitions/getCompileUnitRequestArguments" +// } +// }, +// "required": [ "command", "arguments" ] +// }] +// }, +// "getCompileUnitsRequestArguments": { +// "type": "object", +// "description": "Arguments for 'getCompileUnits' request.", +// "properties": { +// "moduleId": { +// "type": "string", +// "description": "The ID of the module." +// } +// }, +// "required": [ "moduleId" ] +// }, +// "getCompileUnitsResponse": { +// "allOf": [ { "$ref": "#/definitions/Response" }, { +// "type": "object", +// "description": "Response to 'getCompileUnits' request.", +// "properties": { +// "body": { +// "description": "Response to 'getCompileUnits' request. Array of +// paths of compile units." +// } +// } +// }] +// } + +void request_getCompileUnits(const llvm::json::Object &request) { + llvm::json::Object response; + FillResponse(request, response); + lldb::SBProcess process = g_vsc.target.GetProcess(); + llvm::json::Object body; + llvm::json::Array units; + auto arguments = request.getObject("arguments"); + std::string module_id = std::string(GetString(arguments, "moduleId")); + int num_modules = g_vsc.target.GetNumModules(); + for (int i = 0; i < num_modules; i++) { + auto curr_module = g_vsc.target.GetModuleAtIndex(i); + if (module_id == curr_module.GetUUIDString()) { + int num_units = curr_module.GetNumCompileUnits(); + for (int j = 0; j < num_units; j++) { + auto curr_unit = curr_module.GetCompileUnitAtIndex(j);\ + units.emplace_back(CreateCompileUnit(curr_unit));\ + } + body.try_emplace("compileUnits", std::move(units)); + break; + } + } + response.try_emplace("body", std::move(body)); + g_vsc.SendJSON(llvm::json::Value(std::move(response))); +} + // "InitializeRequest": { // "allOf": [ { "$ref": "#/definitions/Request" }, { // "type": "object", @@ -1209,13 +1332,6 @@ void request_initialize(const llvm::json::Object &request) { g_vsc.debugger.SetErrorFileHandle(out, false); } - g_vsc.target = g_vsc.debugger.CreateTarget(nullptr); - lldb::SBListener listener = g_vsc.debugger.GetListener(); - listener.StartListeningForEvents( - g_vsc.target.GetBroadcaster(), - lldb::SBTarget::eBroadcastBitBreakpointChanged); - listener.StartListeningForEvents(g_vsc.broadcaster, - eBroadcastBitStopEventThread); // Start our event thread so we can receive events from the debugger, target, // process and more. g_vsc.event_thread = std::thread(EventThreadFunction); @@ -1252,8 +1368,22 @@ void request_initialize(const llvm::json::Object &request) { body.try_emplace("supportsGotoTargetsRequest", false); // The debug adapter supports the stepInTargetsRequest. body.try_emplace("supportsStepInTargetsRequest", false); - // The debug adapter supports the completionsRequest. - body.try_emplace("supportsCompletionsRequest", true); + // We need to improve the current implementation of completions in order to + // enable it again. For some context, this is how VSCode works: + // - VSCode sends a completion request whenever chars are added, the user + // triggers completion manually via CTRL-space or similar mechanisms, but + // not when there's a deletion. Besides, VSCode doesn't let us know which + // of these events we are handling. What is more, the use can paste or cut + // sections of the text arbitrarily. + // https://github.com/microsoft/vscode/issues/89531 tracks part of the + // issue just mentioned. + // This behavior causes many problems with the current way completion is + // implemented in lldb-vscode, as these requests could be really expensive, + // blocking the debugger, and there could be many concurrent requests unless + // the user types very slowly... We need to address this specific issue, or + // at least trigger completion only when the user explicitly wants it, which + // is the behavior of LLDB CLI, that expects a TAB. + body.try_emplace("supportsCompletionsRequest", false); // The debug adapter supports the modules request. body.try_emplace("supportsModulesRequest", false); // The set of additional module information exposed by the debug adapter. @@ -1321,6 +1451,7 @@ void request_initialize(const llvm::json::Object &request) { // }] // } void request_launch(const llvm::json::Object &request) { + g_vsc.is_attach = false; llvm::json::Object response; lldb::SBError error; FillResponse(request, response); @@ -1329,65 +1460,55 @@ void request_launch(const llvm::json::Object &request) { g_vsc.pre_run_commands = GetStrings(arguments, "preRunCommands"); g_vsc.stop_commands = GetStrings(arguments, "stopCommands"); g_vsc.exit_commands = GetStrings(arguments, "exitCommands"); + g_vsc.terminate_commands = GetStrings(arguments, "terminateCommands"); auto launchCommands = GetStrings(arguments, "launchCommands"); g_vsc.stop_at_entry = GetBoolean(arguments, "stopOnEntry", false); - const auto debuggerRoot = GetString(arguments, "debuggerRoot"); + const llvm::StringRef debuggerRoot = GetString(arguments, "debuggerRoot"); // This is a hack for loading DWARF in .o files on Mac where the .o files // in the debug map of the main executable have relative paths which require // the lldb-vscode binary to have its working directory set to that relative // root for the .o files in order to be able to load debug info. - if (!debuggerRoot.empty()) { - llvm::sys::fs::set_current_path(debuggerRoot.data()); - } + if (!debuggerRoot.empty()) + llvm::sys::fs::set_current_path(debuggerRoot); + + // Run any initialize LLDB commands the user specified in the launch.json. + // This is run before target is created, so commands can't do anything with + // the targets - preRunCommands are run with the target. + g_vsc.RunInitCommands(); SetSourceMapFromArguments(*arguments); - // Run any initialize LLDB commands the user specified in the launch.json - g_vsc.RunInitCommands(); + lldb::SBError status; + g_vsc.SetTarget(g_vsc.CreateTargetFromArguments(*arguments, status)); + if (status.Fail()) { + response["success"] = llvm::json::Value(false); + EmplaceSafeString(response, "message", status.GetCString()); + g_vsc.SendJSON(llvm::json::Value(std::move(response))); + return; + } + + // Instantiate a launch info instance for the target. + auto launch_info = g_vsc.target.GetLaunchInfo(); // Grab the current working directory if there is one and set it in the // launch info. const auto cwd = GetString(arguments, "cwd"); if (!cwd.empty()) - g_vsc.launch_info.SetWorkingDirectory(cwd.data()); - - // Grab the name of the program we need to debug and set it as the first - // argument that will be passed to the program we will debug. - llvm::StringRef program = GetString(arguments, "program"); - if (!program.empty()) { - lldb::SBFileSpec program_fspec(program.data(), true /*resolve_path*/); - g_vsc.launch_info.SetExecutableFile(program_fspec, - true /*add_as_first_arg*/); - const char *target_triple = nullptr; - const char *uuid_cstr = nullptr; - // Stand alone debug info file if different from executable - const char *symfile = nullptr; - lldb::SBModule module = g_vsc.target.AddModule( - program.data(), target_triple, uuid_cstr, symfile); - if (!module.IsValid()) { - response["success"] = llvm::json::Value(false); - - EmplaceSafeString( - response, "message", - llvm::formatv("Could not load program '{0}'.", program).str()); - g_vsc.SendJSON(llvm::json::Value(std::move(response))); - return; - } - } + launch_info.SetWorkingDirectory(cwd.data()); // Extract any extra arguments and append them to our program arguments for // when we launch auto args = GetStrings(arguments, "args"); if (!args.empty()) - g_vsc.launch_info.SetArguments(MakeArgv(args).data(), true); + launch_info.SetArguments(MakeArgv(args).data(), true); // Pass any environment variables along that the user specified. auto envs = GetStrings(arguments, "env"); if (!envs.empty()) - g_vsc.launch_info.SetEnvironmentEntries(MakeArgv(envs).data(), true); + launch_info.SetEnvironmentEntries(MakeArgv(envs).data(), true); - auto flags = g_vsc.launch_info.GetLaunchFlags(); + auto flags = launch_info.GetLaunchFlags(); if (GetBoolean(arguments, "disableASLR", true)) flags |= lldb::eLaunchFlagDisableASLR; @@ -1396,9 +1517,9 @@ void request_launch(const llvm::json::Object &request) { if (GetBoolean(arguments, "shellExpandArguments", false)) flags |= lldb::eLaunchFlagShellExpandArguments; const bool detatchOnError = GetBoolean(arguments, "detachOnError", false); - g_vsc.launch_info.SetDetachOnError(detatchOnError); - g_vsc.launch_info.SetLaunchFlags(flags | lldb::eLaunchFlagDebug | - lldb::eLaunchFlagStopAtEntry); + launch_info.SetDetachOnError(detatchOnError); + launch_info.SetLaunchFlags(flags | lldb::eLaunchFlagDebug | + lldb::eLaunchFlagStopAtEntry); // Run any pre run LLDB commands the user specified in the launch.json g_vsc.RunPreRunCommands(); @@ -1406,7 +1527,7 @@ void request_launch(const llvm::json::Object &request) { // Disable async events so the launch will be successful when we return from // the launch call and the launch will happen synchronously g_vsc.debugger.SetAsync(false); - g_vsc.target.Launch(g_vsc.launch_info, error); + g_vsc.target.Launch(launch_info, error); g_vsc.debugger.SetAsync(true); } else { g_vsc.RunLLDBCommands("Running launchCommands:", launchCommands); @@ -1582,6 +1703,24 @@ void request_scopes(const llvm::json::Object &request) { llvm::json::Object body; auto arguments = request.getObject("arguments"); lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments); + // As the user selects different stack frames in the GUI, a "scopes" request + // will be sent to the DAP. This is the only way we know that the user has + // selected a frame in a thread. There are no other notifications that are + // sent and VS code doesn't allow multiple frames to show variables + // concurrently. If we select the thread and frame as the "scopes" requests + // are sent, this allows users to type commands in the debugger console + // with a backtick character to run lldb commands and these lldb commands + // will now have the right context selected as they are run. If the user + // types "`bt" into the debugger console and we had another thread selected + // in the LLDB library, we would show the wrong thing to the user. If the + // users switches threads with a lldb command like "`thread select 14", the + // GUI will not update as there are no "event" notification packets that + // allow us to change the currently selected thread or frame in the GUI that + // I am aware of. + if (frame.IsValid()) { + frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread()); + frame.GetThread().SetSelectedFrame(frame.GetFrameID()); + } g_vsc.variables.Clear(); g_vsc.variables.Append(frame.GetVariables(true, // arguments true, // locals @@ -1720,70 +1859,46 @@ void request_setBreakpoints(const llvm::json::Object &request) { const auto path = GetString(source, "path"); auto breakpoints = arguments->getArray("breakpoints"); llvm::json::Array response_breakpoints; + // Decode the source breakpoint infos for this "setBreakpoints" request SourceBreakpointMap request_bps; for (const auto &bp : *breakpoints) { auto bp_obj = bp.getAsObject(); if (bp_obj) { SourceBreakpoint src_bp(*bp_obj); - request_bps[src_bp.line] = std::move(src_bp); + request_bps[src_bp.line] = src_bp; + + // We check if this breakpoint already exists to update it + auto existing_source_bps = g_vsc.source_breakpoints.find(path); + if (existing_source_bps != g_vsc.source_breakpoints.end()) { + const auto &existing_bp = existing_source_bps->second.find(src_bp.line); + if (existing_bp != existing_source_bps->second.end()) { + existing_bp->second.UpdateBreakpoint(src_bp); + AppendBreakpoint(existing_bp->second.bp, response_breakpoints, path, + src_bp.line); + continue; + } + } + // At this point the breakpoint is new + src_bp.SetBreakpoint(path.data()); + AppendBreakpoint(src_bp.bp, response_breakpoints, path, src_bp.line); + g_vsc.source_breakpoints[path][src_bp.line] = std::move(src_bp); } } - // See if we already have breakpoints set for this source file from a - // previous "setBreakpoints" request + // Delete any breakpoints in this source file that aren't in the + // request_bps set. There is no call to remove breakpoints other than + // calling this function with a smaller or empty "breakpoints" list. auto old_src_bp_pos = g_vsc.source_breakpoints.find(path); if (old_src_bp_pos != g_vsc.source_breakpoints.end()) { - - // We have already set breakpoints in this source file and they are giving - // use a new list of lines to set breakpoints on. Some breakpoints might - // already be set, and some might not. We need to remove any breakpoints - // whose lines are not contained in the any breakpoints lines in in the - // "breakpoints" array. - - // Delete any breakpoints in this source file that aren't in the - // request_bps set. There is no call to remove breakpoints other than - // calling this function with a smaller or empty "breakpoints" list. - std::vector remove_lines; - for (auto &pair: old_src_bp_pos->second) { - auto request_pos = request_bps.find(pair.first); + for (auto &old_bp : old_src_bp_pos->second) { + auto request_pos = request_bps.find(old_bp.first); if (request_pos == request_bps.end()) { // This breakpoint no longer exists in this source file, delete it - g_vsc.target.BreakpointDelete(pair.second.bp.GetID()); - remove_lines.push_back(pair.first); - } else { - pair.second.UpdateBreakpoint(request_pos->second); - // Remove this breakpoint from the request breakpoints since we have - // handled it here and we don't need to set a new breakpoint below. - request_bps.erase(request_pos); - // Add this breakpoint info to the response - AppendBreakpoint(pair.second.bp, response_breakpoints); + g_vsc.target.BreakpointDelete(old_bp.second.bp.GetID()); + old_src_bp_pos->second.erase(old_bp.first); } } - // Remove any lines from this existing source breakpoint map - for (auto line: remove_lines) - old_src_bp_pos->second.erase(line); - - // Now add any breakpoint infos left over in request_bps are the - // breakpoints that weren't set in this source file yet. We need to update - // thread source breakpoint info for the source file in the variable - // "old_src_bp_pos->second" so the info for this source file is up to date. - for (auto &pair : request_bps) { - pair.second.SetBreakpoint(path.data()); - // Add this breakpoint info to the response - AppendBreakpoint(pair.second.bp, response_breakpoints); - old_src_bp_pos->second[pair.first] = std::move(pair.second); - } - } else { - // No breakpoints were set for this source file yet. Set all breakpoints - // for each line and add them to the response and create an entry in - // g_vsc.source_breakpoints for this source file. - for (auto &pair : request_bps) { - pair.second.SetBreakpoint(path.data()); - // Add this breakpoint info to the response - AppendBreakpoint(pair.second.bp, response_breakpoints); - } - g_vsc.source_breakpoints[path] = std::move(request_bps); } llvm::json::Object body; @@ -1853,10 +1968,10 @@ void request_setExceptionBreakpoints(const llvm::json::Object &request) { for (const auto &value : *filters) { const auto filter = GetAsString(value); - auto exc_bp = g_vsc.GetExceptionBreakpoint(filter); + auto exc_bp = g_vsc.GetExceptionBreakpoint(std::string(filter)); if (exc_bp) { exc_bp->SetBreakpoint(); - unset_filters.erase(filter); + unset_filters.erase(std::string(filter)); } } for (const auto &filter : unset_filters) { @@ -2710,6 +2825,7 @@ const std::map &GetRequestHandlers() { REQUEST_CALLBACK(disconnect), REQUEST_CALLBACK(evaluate), REQUEST_CALLBACK(exceptionInfo), + REQUEST_CALLBACK(getCompileUnits), REQUEST_CALLBACK(initialize), REQUEST_CALLBACK(launch), REQUEST_CALLBACK(next), @@ -2734,31 +2850,69 @@ const std::map &GetRequestHandlers() { } // anonymous namespace +static void printHelp(LLDBVSCodeOptTable &table, llvm::StringRef tool_name) { + std::string usage_str = tool_name.str() + "options"; + table.PrintHelp(llvm::outs(), usage_str.c_str(), "LLDB VSCode", false); + + std::string examples = R"___( +EXAMPLES: + The debug adapter can be started in two modes. + + Running lldb-vscode without any arguments will start communicating with the + parent over stdio. Passing a port number causes lldb-vscode to start listening + for connections on that port. + + lldb-vscode -p + + Passing --wait-for-debugger will pause the process at startup and wait for a + debugger to attach to the process. + + lldb-vscode -g + )___"; + llvm::outs() << examples; +} + int main(int argc, char *argv[]) { // Initialize LLDB first before we do anything. lldb::SBDebugger::Initialize(); - if (argc == 2) { - const char *arg = argv[1]; + int portno = -1; + + LLDBVSCodeOptTable T; + unsigned MAI, MAC; + llvm::ArrayRef ArgsArr = llvm::makeArrayRef(argv + 1, argc); + llvm::opt::InputArgList input_args = T.ParseArgs(ArgsArr, MAI, MAC); + + if (input_args.hasArg(OPT_help)) { + printHelp(T, llvm::sys::path::filename(argv[0])); + return 0; + } + + if (auto *arg = input_args.getLastArg(OPT_port)) { + auto optarg = arg->getValue(); + char *remainder; + portno = strtol(optarg, &remainder, 0); + if (remainder == optarg || *remainder != '\0') { + fprintf(stderr, "'%s' is not a valid port number.\n", optarg); + exit(1); + } + } + #if !defined(_WIN32) - if (strcmp(arg, "-g") == 0) { - printf("Paused waiting for debugger to attach (pid = %i)...\n", getpid()); - pause(); - } else { -#else - { + if (input_args.hasArg(OPT_wait_for_debugger)) { + printf("Paused waiting for debugger to attach (pid = %i)...\n", getpid()); + pause(); + } #endif - int portno = atoi(arg); - printf("Listening on port %i...\n", portno); - SOCKET socket_fd = AcceptConnection(portno); - if (socket_fd >= 0) { - g_vsc.input.descriptor = StreamDescriptor::from_socket(socket_fd, true); - g_vsc.output.descriptor = - StreamDescriptor::from_socket(socket_fd, false); - } else { - exit(1); - } + if (portno != -1) { + printf("Listening on port %i...\n", portno); + SOCKET socket_fd = AcceptConnection(portno); + if (socket_fd >= 0) { + g_vsc.input.descriptor = StreamDescriptor::from_socket(socket_fd, true); + g_vsc.output.descriptor = StreamDescriptor::from_socket(socket_fd, false); + } else { + exit(1); } } else { g_vsc.input.descriptor = StreamDescriptor::from_file(fileno(stdin), false); @@ -2767,7 +2921,7 @@ int main(int argc, char *argv[]) { } auto request_handlers = GetRequestHandlers(); uint32_t packet_idx = 0; - while (true) { + while (!g_vsc.sent_terminated_event) { std::string json = g_vsc.ReadJSON(); if (json.empty()) break; @@ -2798,7 +2952,7 @@ int main(int argc, char *argv[]) { const auto packet_type = GetString(object, "type"); if (packet_type == "request") { const auto command = GetString(object, "command"); - auto handler_pos = request_handlers.find(command); + auto handler_pos = request_handlers.find(std::string(command)); if (handler_pos != request_handlers.end()) { handler_pos->second(*object); } else { diff --git a/gnu/llvm/lldb/tools/lldb-vscode/package.json b/gnu/llvm/lldb/tools/lldb-vscode/package.json index 847a219fbb5..f4408d3607d 100644 --- a/gnu/llvm/lldb/tools/lldb-vscode/package.json +++ b/gnu/llvm/lldb/tools/lldb-vscode/package.json @@ -2,7 +2,8 @@ "name": "lldb-vscode", "displayName": "LLDB native Debug stub", "version": "0.1.0", - "publisher": "llvm.org", + "publisher": "llvm", + "repository": "llvm.org", "description": "Debug adapter for LLDB which uses a C++ tool to interface directly with LLDB.", "author": { "name": "Greg Clayton", @@ -16,7 +17,6 @@ "vscode": "^1.18.0", "node": "^7.9.0" }, - "icon": "images/lldb.png", "categories": [ "Debuggers" ], @@ -29,7 +29,7 @@ "vscode": "1.1.10", "vscode-debugadapter-testsupport": "1.25.0", "tslint": "5.8.0", - "vsce": "1.35.0" + "vsce": "^1.36.3" }, "contributes": { "debuggers": [ @@ -70,7 +70,10 @@ "description": "Path to the program to debug." }, "args": { - "type": [ "array", "string" ], + "type": [ + "array", + "string" + ], "description": "Program arguments.", "default": [] }, @@ -109,43 +112,51 @@ "description": "Detach from the program.", "default": false }, - "trace": { - "type": "boolean", - "description": "Enable logging of the Debug Adapter Protocol.", - "default": true - }, "sourcePath": { "type": "string", "description": "Specify a source path to remap \"./\" to allow full paths to be used when setting breakpoints in binaries that have relative source paths." }, "sourceMap": { "type": "array", - "description": "Specify an array of path remappings; each element must itself be a two element array containing a source and desination pathname. Overrides sourcePath.", + "description": "Specify an array of path remappings; each element must itself be a two element array containing a source and destination pathname. Overrides sourcePath.", "default": [] }, "debuggerRoot": { "type": "string", "description": "Specify a working directory to set the debug adaptor to so relative object files can be located." }, + "targetTriple": { + "type": "string", + "description": "Triplet of the target architecture to override value derived from the program file." + }, + "platformName": { + "type": "string", + "description": "Name of the execution platform to override value derived from the program file." + }, "initCommands": { - "type": "array", - "description": "Initialization commands executed upon debugger startup.", - "default": [] + "type": "array", + "description": "Initialization commands executed upon debugger startup.", + "default": [] }, "preRunCommands": { - "type": "array", - "description": "Commands executed just before the program is launched.", - "default": [] + "type": "array", + "description": "Commands executed just before the program is launched.", + "default": [] + }, + "launchCommands": { + "type": "array", + "description": "Custom commands that are executed instead of launching a process. A target will be created with the launch arguments prior to executing these commands. The commands may optionally create a new target and must perform a launch. A valid process must exist after these commands complete or the \"launch\" will fail.", + "default": [] }, "stopCommands": { - "type": "array", - "description": "Commands executed each time the program stops.", - "default": [] + "type": "array", + "description": "Commands executed each time the program stops.", + "default": [] }, "exitCommands": { - "type": "array", - "description": "Commands executed at the end of debugging session.", - "default": [] + "type": "array", + "description": "Commands executed at the end of debugging session.", + "default": [] } } }, @@ -153,12 +164,12 @@ "properties": { "program": { "type": "string", - "description": "Path to the program to attach to." + "description": "Path to the program to attach to." }, "pid": { "type": [ - "number", - "string" + "number", + "string" ], "description": "System process ID to attach to." }, @@ -167,24 +178,27 @@ "description": "If set to true, then wait for the process to launch by looking for a process with a basename that matches `program`. No process ID needs to be specified when using this flag.", "default": true }, - "trace": { - "type": "boolean", - "description": "Enable logging of the Debug Adapter Protocol.", - "default": true - }, "sourcePath": { "type": "string", "description": "Specify a source path to remap \"./\" to allow full paths to be used when setting breakpoints in binaries that have relative source paths." }, "sourceMap": { "type": "array", - "description": "Specify an array of path remappings; each element must itself be a two element array containing a source and desination pathname. Overrides sourcePath.", + "description": "Specify an array of path remappings; each element must itself be a two element array containing a source and destination pathname. Overrides sourcePath.", "default": [] }, "debuggerRoot": { "type": "string", "description": "Specify a working directory to set the debug adaptor to so relative object files can be located." }, + "targetTriple": { + "type": "string", + "description": "Triplet of the target architecture to override value derived from the program file." + }, + "platformName": { + "type": "string", + "description": "Name of the execution platform to override value derived from the program file." + }, "attachCommands": { "type": "array", "description": "Custom commands that are executed instead of attaching to a process ID or to a process by name. These commands may optionally create a new target and must perform an attach. A valid process must exist after these commands complete or the \"attach\" will fail.", @@ -207,8 +221,12 @@ }, "exitCommands": { "type": "array", - "description": "Commands executed at the end of debugging session.", - "default": [] + "description": "Commands executed at the end of debugging session.", + "default": [] + }, + "coreFile": { + "type": "string", + "description": "Path to the core file to debug." } } } diff --git a/gnu/llvm/lldb/unittests/API/CMakeLists.txt b/gnu/llvm/lldb/unittests/API/CMakeLists.txt new file mode 100644 index 00000000000..308249b63ad --- /dev/null +++ b/gnu/llvm/lldb/unittests/API/CMakeLists.txt @@ -0,0 +1,10 @@ +add_lldb_unittest(APITests + SBCommandInterpreterTest.cpp + + LINK_LIBS + liblldb + ) + +if(PYTHON_RPATH) + set_property(TARGET APITests APPEND PROPERTY BUILD_RPATH "${PYTHON_RPATH}") +endif() diff --git a/gnu/llvm/lldb/unittests/API/SBCommandInterpreterTest.cpp b/gnu/llvm/lldb/unittests/API/SBCommandInterpreterTest.cpp new file mode 100644 index 00000000000..d117c08c0bf --- /dev/null +++ b/gnu/llvm/lldb/unittests/API/SBCommandInterpreterTest.cpp @@ -0,0 +1,138 @@ +//===-- SBCommandInterpreterTest.cpp ------------------------===----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===/ + +#include "gtest/gtest.h" + +#include "lldb/API/SBCommandInterpreter.h" +#include "lldb/API/SBCommandReturnObject.h" +#include "lldb/API/SBDebugger.h" + +#include +#include + +using namespace lldb; + +class SBCommandInterpreterTest : public testing::Test { +protected: + void SetUp() override { + SBDebugger::Initialize(); + m_dbg = SBDebugger::Create(/*source_init_files=*/false); + m_interp = m_dbg.GetCommandInterpreter(); + } + + SBDebugger m_dbg; + SBCommandInterpreter m_interp; +}; + +class DummyCommand : public SBCommandPluginInterface { +public: + DummyCommand(const char *message) : m_message(message) {} + + bool DoExecute(SBDebugger dbg, char **command, + SBCommandReturnObject &result) { + result.PutCString(m_message.c_str()); + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } + +private: + std::string m_message; +}; + +TEST_F(SBCommandInterpreterTest, SingleWordCommand) { + // We first test a command without autorepeat + DummyCommand dummy("It worked"); + m_interp.AddCommand("dummy", &dummy, /*help=*/nullptr); + { + SBCommandReturnObject result; + m_interp.HandleCommand("dummy", result, /*add_to_history=*/true); + EXPECT_TRUE(result.Succeeded()); + EXPECT_STREQ(result.GetOutput(), "It worked\n"); + } + { + SBCommandReturnObject result; + m_interp.HandleCommand("", result); + EXPECT_FALSE(result.Succeeded()); + EXPECT_STREQ(result.GetError(), "error: No auto repeat.\n"); + } + + // Now we test a command with autorepeat + m_interp.AddCommand("dummy_with_autorepeat", &dummy, /*help=*/nullptr, + /*syntax=*/nullptr, /*auto_repeat_command=*/nullptr); + { + SBCommandReturnObject result; + m_interp.HandleCommand("dummy_with_autorepeat", result, + /*add_to_history=*/true); + EXPECT_TRUE(result.Succeeded()); + EXPECT_STREQ(result.GetOutput(), "It worked\n"); + } + { + SBCommandReturnObject result; + m_interp.HandleCommand("", result); + EXPECT_TRUE(result.Succeeded()); + EXPECT_STREQ(result.GetOutput(), "It worked\n"); + } +} + +TEST_F(SBCommandInterpreterTest, MultiWordCommand) { + auto command = m_interp.AddMultiwordCommand("multicommand", /*help=*/nullptr); + // We first test a subcommand without autorepeat + DummyCommand subcommand("It worked again"); + command.AddCommand("subcommand", &subcommand, /*help=*/nullptr); + { + SBCommandReturnObject result; + m_interp.HandleCommand("multicommand subcommand", result, + /*add_to_history=*/true); + EXPECT_TRUE(result.Succeeded()); + EXPECT_STREQ(result.GetOutput(), "It worked again\n"); + } + { + SBCommandReturnObject result; + m_interp.HandleCommand("", result); + EXPECT_FALSE(result.Succeeded()); + EXPECT_STREQ(result.GetError(), "error: No auto repeat.\n"); + } + + // We first test a subcommand with autorepeat + command.AddCommand("subcommand_with_autorepeat", &subcommand, + /*help=*/nullptr, /*syntax=*/nullptr, + /*auto_repeat_command=*/nullptr); + { + SBCommandReturnObject result; + m_interp.HandleCommand("multicommand subcommand_with_autorepeat", result, + /*add_to_history=*/true); + EXPECT_TRUE(result.Succeeded()); + EXPECT_STREQ(result.GetOutput(), "It worked again\n"); + } + { + SBCommandReturnObject result; + m_interp.HandleCommand("", result); + EXPECT_TRUE(result.Succeeded()); + EXPECT_STREQ(result.GetOutput(), "It worked again\n"); + } + + DummyCommand subcommand2("It worked again 2"); + // We now test a subcommand with autorepeat of the command name + command.AddCommand( + "subcommand_with_custom_autorepeat", &subcommand2, /*help=*/nullptr, + /*syntax=*/nullptr, + /*auto_repeat_command=*/"multicommand subcommand_with_autorepeat"); + { + SBCommandReturnObject result; + m_interp.HandleCommand("multicommand subcommand_with_custom_autorepeat", + result, /*add_to_history=*/true); + EXPECT_TRUE(result.Succeeded()); + EXPECT_STREQ(result.GetOutput(), "It worked again 2\n"); + } + { + SBCommandReturnObject result; + m_interp.HandleCommand("", result); + EXPECT_TRUE(result.Succeeded()); + EXPECT_STREQ(result.GetOutput(), "It worked again\n"); + } +} diff --git a/gnu/llvm/lldb/unittests/Breakpoint/BreakpointIDTest.cpp b/gnu/llvm/lldb/unittests/Breakpoint/BreakpointIDTest.cpp index a96b2b1fb1e..7d1695e6e3c 100644 --- a/gnu/llvm/lldb/unittests/Breakpoint/BreakpointIDTest.cpp +++ b/gnu/llvm/lldb/unittests/Breakpoint/BreakpointIDTest.cpp @@ -1,4 +1,4 @@ -//===-- BreakpointIDTest.cpp ------------------------------------*- C++ -*-===// +//===-- BreakpointIDTest.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/CMakeLists.txt b/gnu/llvm/lldb/unittests/CMakeLists.txt index bf117030dd4..6422b726ca6 100644 --- a/gnu/llvm/lldb/unittests/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/CMakeLists.txt @@ -33,6 +33,10 @@ function(add_lldb_unittest test_name) "LINK_LIBS;LINK_COMPONENTS" ${ARGN}) + if (NOT ${test_name} MATCHES "Tests$") + message(FATAL_ERROR "Unit test name must end with 'Tests' for lit to find it.") + endif() + list(APPEND LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS}) add_unittest(LLDBUnitTests @@ -59,6 +63,10 @@ function(add_unittest_inputs test_name inputs) endfunction() add_subdirectory(TestingSupport) +if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows") + # FIXME: APITests.exe is not a valid googletest binary. + add_subdirectory(API) +endif() add_subdirectory(Breakpoint) add_subdirectory(Core) add_subdirectory(DataFormatter) @@ -67,6 +75,7 @@ add_subdirectory(Editline) add_subdirectory(Expression) add_subdirectory(Host) add_subdirectory(Interpreter) +add_subdirectory(Instruction) add_subdirectory(Language) add_subdirectory(ObjectFile) add_subdirectory(Platform) @@ -79,6 +88,7 @@ add_subdirectory(Target) add_subdirectory(tools) add_subdirectory(UnwindAssembly) add_subdirectory(Utility) +add_subdirectory(Thread) if(LLDB_CAN_USE_DEBUGSERVER AND LLDB_TOOL_DEBUGSERVER_BUILD AND NOT LLDB_USE_SYSTEM_DEBUGSERVER) add_subdirectory(debugserver) diff --git a/gnu/llvm/lldb/unittests/Core/CMakeLists.txt b/gnu/llvm/lldb/unittests/Core/CMakeLists.txt index 688a39d9a10..de99856486f 100644 --- a/gnu/llvm/lldb/unittests/Core/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/Core/CMakeLists.txt @@ -1,6 +1,9 @@ add_lldb_unittest(LLDBCoreTests + CommunicationTest.cpp MangledTest.cpp + ModuleSpecTest.cpp RichManglingContextTest.cpp + SourceManagerTest.cpp StreamCallbackTest.cpp UniqueCStringMapTest.cpp @@ -9,6 +12,8 @@ add_lldb_unittest(LLDBCoreTests lldbHost lldbSymbol lldbPluginObjectFileELF + lldbPluginObjectFileMachO + lldbPluginObjectFilePECOFF lldbPluginSymbolFileSymtab lldbUtilityHelpers LLVMTestingSupport diff --git a/gnu/llvm/lldb/unittests/Core/CommunicationTest.cpp b/gnu/llvm/lldb/unittests/Core/CommunicationTest.cpp new file mode 100644 index 00000000000..3ddc78d4a5a --- /dev/null +++ b/gnu/llvm/lldb/unittests/Core/CommunicationTest.cpp @@ -0,0 +1,37 @@ +//===-- CommunicationTest.cpp ---------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/Communication.h" +#include "lldb/Host/ConnectionFileDescriptor.h" +#include "lldb/Host/Pipe.h" +#include "llvm/Testing/Support/Error.h" +#include "gtest/gtest.h" + +using namespace lldb_private; + +#ifndef _WIN32 +TEST(CommunicationTest, SynchronizeWhileClosing) { + // Set up a communication object reading from a pipe. + Pipe pipe; + ASSERT_THAT_ERROR(pipe.CreateNew(/*child_process_inherit=*/false).ToError(), + llvm::Succeeded()); + + Communication comm("test"); + comm.SetConnection(std::make_unique( + pipe.ReleaseReadFileDescriptor(), /*owns_fd=*/true)); + comm.SetCloseOnEOF(true); + ASSERT_TRUE(comm.StartReadThread()); + + // Ensure that we can safely synchronize with the read thread while it is + // closing the read end (in response to us closing the write end). + pipe.CloseWriteFileDescriptor(); + comm.SynchronizeWithReadThread(); + + ASSERT_TRUE(comm.StopReadThread()); +} +#endif diff --git a/gnu/llvm/lldb/unittests/Core/MangledTest.cpp b/gnu/llvm/lldb/unittests/Core/MangledTest.cpp index ffa7b1e5852..6e1bdd59978 100644 --- a/gnu/llvm/lldb/unittests/Core/MangledTest.cpp +++ b/gnu/llvm/lldb/unittests/Core/MangledTest.cpp @@ -1,4 +1,4 @@ -//===-- MangledTest.cpp -----------------------------------------*- C++ -*-===// +//===-- MangledTest.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -31,8 +31,7 @@ using namespace lldb_private; TEST(MangledTest, ResultForValidName) { ConstString MangledName("_ZN1a1b1cIiiiEEvm"); Mangled TheMangled(MangledName); - ConstString TheDemangled = - TheMangled.GetDemangledName(eLanguageTypeC_plus_plus); + ConstString TheDemangled = TheMangled.GetDemangledName(); ConstString ExpectedResult("void a::b::c(unsigned long)"); EXPECT_STREQ(ExpectedResult.GetCString(), TheDemangled.GetCString()); @@ -41,8 +40,7 @@ TEST(MangledTest, ResultForValidName) { TEST(MangledTest, ResultForBlockInvocation) { ConstString MangledName("___Z1fU13block_pointerFviE_block_invoke"); Mangled TheMangled(MangledName); - ConstString TheDemangled = - TheMangled.GetDemangledName(eLanguageTypeC_plus_plus); + ConstString TheDemangled = TheMangled.GetDemangledName(); ConstString ExpectedResult( "invocation function for block in f(void (int) block_pointer)"); @@ -52,8 +50,7 @@ TEST(MangledTest, ResultForBlockInvocation) { TEST(MangledTest, EmptyForInvalidName) { ConstString MangledName("_ZN1a1b1cmxktpEEvm"); Mangled TheMangled(MangledName); - ConstString TheDemangled = - TheMangled.GetDemangledName(eLanguageTypeC_plus_plus); + ConstString TheDemangled = TheMangled.GetDemangledName(); EXPECT_STREQ("", TheDemangled.GetCString()); } @@ -168,8 +165,7 @@ Symbols: )"); ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); - ModuleSpec Spec{FileSpec(ExpectedFile->name())}; - auto M = std::make_shared(Spec); + auto M = std::make_shared(ExpectedFile->moduleSpec()); auto Count = [M](const char *Name, FunctionNameType Type) -> int { SymbolContextList SymList; diff --git a/gnu/llvm/lldb/unittests/Core/ModuleSpecTest.cpp b/gnu/llvm/lldb/unittests/Core/ModuleSpecTest.cpp new file mode 100644 index 00000000000..f9e19ed35ac --- /dev/null +++ b/gnu/llvm/lldb/unittests/Core/ModuleSpecTest.cpp @@ -0,0 +1,166 @@ +//===-- ModuleSpecTest.cpp ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "TestingSupport/SubsystemRAII.h" +#include "TestingSupport/TestUtilities.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Utility/DataBuffer.h" + +#include "Plugins/ObjectFile/ELF/ObjectFileELF.h" +#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h" +#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h" + +#include "gtest/gtest.h" + +using namespace lldb; +using namespace lldb_private; + +extern const char *TestMainArgv0; + +// This test file intentionally doesn't initialize the FileSystem. +// Everything in this file should be able to run without requiring +// any interaction with the FileSystem class; by keeping it +// uninitialized, it will assert if anything tries to interact with +// it. + +TEST(ModuleSpecTest, InvalidInMemoryBuffer) { + uint8_t Invalid[] = "This is not a binary file."; + DataBufferSP InvalidBufferSP = + std::make_shared(Invalid, sizeof(Invalid)); + ModuleSpec Spec(FileSpec(), UUID(), InvalidBufferSP); + + auto InvalidModuleSP = std::make_shared(Spec); + ASSERT_EQ(InvalidModuleSP->GetObjectFile(), nullptr); +} + +TEST(ModuleSpecTest, InvalidInMemoryBufferValidFile) { + uint8_t Invalid[] = "This is not a binary file."; + DataBufferSP InvalidBufferSP = + std::make_shared(Invalid, sizeof(Invalid)); + ModuleSpec Spec(FileSpec(TestMainArgv0), UUID(), InvalidBufferSP); + + auto InvalidModuleSP = std::make_shared(Spec); + ASSERT_EQ(InvalidModuleSP->GetObjectFile(), nullptr); +} + +TEST(ModuleSpecTest, TestELFFile) { + SubsystemRAII subsystems; + + auto ExpectedFile = TestFile::fromYaml(R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000010 +... +)"); + ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); + + auto M = std::make_shared(ExpectedFile->moduleSpec()); + ObjectFile *OF = M->GetObjectFile(); + + ASSERT_EQ(llvm::isa(OF), true); +} + +TEST(ModuleSpecTest, TestCOFFFile) { + SubsystemRAII subsystems; + + auto ExpectedFile = TestFile::fromYaml(R"( +--- !COFF +OptionalHeader: + AddressOfEntryPoint: 0 + ImageBase: 16777216 + SectionAlignment: 4096 + FileAlignment: 512 + MajorOperatingSystemVersion: 6 + MinorOperatingSystemVersion: 0 + MajorImageVersion: 0 + MinorImageVersion: 0 + MajorSubsystemVersion: 6 + MinorSubsystemVersion: 0 + Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI + DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT ] + SizeOfStackReserve: 1048576 + SizeOfStackCommit: 4096 + SizeOfHeapReserve: 1048576 + SizeOfHeapCommit: 4096 +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + VirtualAddress: 4096 + VirtualSize: 4096 +symbols: [] +... +)"); + ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); + + auto M = std::make_shared(ExpectedFile->moduleSpec()); + ObjectFile *OF = M->GetObjectFile(); + + ASSERT_EQ(llvm::isa(OF), true); +} + +TEST(ModuleSpecTest, TestMachOFile) { + SubsystemRAII subsystems; + + auto ExpectedFile = TestFile::fromYaml(R"( +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x0100000C + cpusubtype: 0x00000000 + filetype: 0x00000001 + ncmds: 1 + sizeofcmds: 232 + flags: 0x00002000 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 232 + segname: '' + vmaddr: 0 + vmsize: 56 + fileoff: 392 + filesize: 56 + maxprot: 7 + initprot: 7 + nsects: 1 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x0000000000000000 + size: 24 + offset: 0x00000188 + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 +... +)"); + ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); + + auto M = std::make_shared(ExpectedFile->moduleSpec()); + ObjectFile *OF = M->GetObjectFile(); + + ASSERT_EQ(llvm::isa(OF), true); +} diff --git a/gnu/llvm/lldb/unittests/Core/RichManglingContextTest.cpp b/gnu/llvm/lldb/unittests/Core/RichManglingContextTest.cpp index 2055a51f992..f8a0bbf9102 100644 --- a/gnu/llvm/lldb/unittests/Core/RichManglingContextTest.cpp +++ b/gnu/llvm/lldb/unittests/Core/RichManglingContextTest.cpp @@ -1,4 +1,4 @@ -//===-- RichManglingContextTest.cpp -----------------------------*- C++ -*-===// +//===-- RichManglingContextTest.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Core/SourceManagerTest.cpp b/gnu/llvm/lldb/unittests/Core/SourceManagerTest.cpp new file mode 100644 index 00000000000..9dcd048ce3f --- /dev/null +++ b/gnu/llvm/lldb/unittests/Core/SourceManagerTest.cpp @@ -0,0 +1,48 @@ +//===-- SourceManagerTest.cpp ---------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/SourceManager.h" +#include "lldb/Host/FileSystem.h" +#include "gtest/gtest.h" + +using namespace lldb; +using namespace lldb_private; + +class SourceFileCache : public ::testing::Test { +public: + void SetUp() override { FileSystem::Initialize(); } + void TearDown() override { FileSystem::Terminate(); } +}; + +TEST_F(SourceFileCache, FindSourceFileFound) { + SourceManager::SourceFileCache cache; + + // Insert: foo + FileSpec foo_file_spec("foo"); + auto foo_file_sp = + std::make_shared(foo_file_spec, nullptr); + cache.AddSourceFile(foo_file_sp); + + // Query: foo, expect found. + FileSpec another_foo_file_spec("foo"); + ASSERT_EQ(cache.FindSourceFile(another_foo_file_spec), foo_file_sp); +} + +TEST_F(SourceFileCache, FindSourceFileNotFound) { + SourceManager::SourceFileCache cache; + + // Insert: foo + FileSpec foo_file_spec("foo"); + auto foo_file_sp = + std::make_shared(foo_file_spec, nullptr); + cache.AddSourceFile(foo_file_sp); + + // Query: bar, expect not found. + FileSpec bar_file_spec("bar"); + ASSERT_EQ(cache.FindSourceFile(bar_file_spec), nullptr); +} diff --git a/gnu/llvm/lldb/unittests/Core/StreamCallbackTest.cpp b/gnu/llvm/lldb/unittests/Core/StreamCallbackTest.cpp index d9ae3543033..d0e50b6864d 100644 --- a/gnu/llvm/lldb/unittests/Core/StreamCallbackTest.cpp +++ b/gnu/llvm/lldb/unittests/Core/StreamCallbackTest.cpp @@ -1,4 +1,4 @@ -//===-- StreamCallbackTest.cpp ----------------------------------*- C++ -*-===// +//===-- StreamCallbackTest.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Core/UniqueCStringMapTest.cpp b/gnu/llvm/lldb/unittests/Core/UniqueCStringMapTest.cpp index 26d2b152191..25bc28538e6 100644 --- a/gnu/llvm/lldb/unittests/Core/UniqueCStringMapTest.cpp +++ b/gnu/llvm/lldb/unittests/Core/UniqueCStringMapTest.cpp @@ -1,4 +1,4 @@ -//===-- UniqueCStringMapTest.cpp --------------------------------*- C++ -*-===// +//===-- UniqueCStringMapTest.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/DataFormatter/CMakeLists.txt b/gnu/llvm/lldb/unittests/DataFormatter/CMakeLists.txt index fc60bff0587..45011c56b0b 100644 --- a/gnu/llvm/lldb/unittests/DataFormatter/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/DataFormatter/CMakeLists.txt @@ -1,5 +1,6 @@ add_lldb_unittest(LLDBFormatterTests FormatManagerTests.cpp + StringPrinterTests.cpp LINK_LIBS lldbCore diff --git a/gnu/llvm/lldb/unittests/DataFormatter/FormatManagerTests.cpp b/gnu/llvm/lldb/unittests/DataFormatter/FormatManagerTests.cpp index acfafdbd293..e9dd4af610d 100644 --- a/gnu/llvm/lldb/unittests/DataFormatter/FormatManagerTests.cpp +++ b/gnu/llvm/lldb/unittests/DataFormatter/FormatManagerTests.cpp @@ -1,4 +1,4 @@ -//===-- FormatManagerTests.cpp ----------------------------------*- C++ -*-===// +//===-- FormatManagerTests.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/DataFormatter/StringPrinterTests.cpp b/gnu/llvm/lldb/unittests/DataFormatter/StringPrinterTests.cpp new file mode 100644 index 00000000000..84a9372408b --- /dev/null +++ b/gnu/llvm/lldb/unittests/DataFormatter/StringPrinterTests.cpp @@ -0,0 +1,150 @@ +//===-- StringPrinterTests.cpp --------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/DataFormatters/StringPrinter.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/StreamString.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/raw_ostream.h" +#include "gtest/gtest.h" +#include + +using namespace lldb; +using namespace lldb_private; +using lldb_private::formatters::StringPrinter; +using llvm::Optional; +using llvm::StringRef; + +#define QUOTE(x) std::string("\"" x "\"") + +/// Format \p input according to the specified string encoding and special char +/// escape style. +template +static Optional format(StringRef input, + StringPrinter::EscapeStyle escape_style) { + StreamString out; + StringPrinter::ReadBufferAndDumpToStreamOptions opts; + opts.SetStream(&out); + opts.SetSourceSize(input.size()); + opts.SetNeedsZeroTermination(true); + opts.SetEscapeNonPrintables(true); + opts.SetIgnoreMaxLength(false); + opts.SetEscapeStyle(escape_style); + DataExtractor extractor(input.data(), input.size(), + endian::InlHostByteOrder(), sizeof(void *)); + opts.SetData(extractor); + const bool success = StringPrinter::ReadBufferAndDumpToStream(opts); + if (!success) + return llvm::None; + return out.GetString().str(); +} + +// Test ASCII formatting for C++. This behaves exactly like UTF8 formatting for +// C++, although that's questionable (see FIXME in StringPrinter.cpp). +TEST(StringPrinterTests, CxxASCII) { + auto fmt = [](StringRef str) { + return format( + str, StringPrinter::EscapeStyle::CXX); + }; + + // Special escapes. + EXPECT_EQ(fmt({"\0", 1}), QUOTE("")); + EXPECT_EQ(fmt("\a"), QUOTE(R"(\a)")); + EXPECT_EQ(fmt("\b"), QUOTE(R"(\b)")); + EXPECT_EQ(fmt("\f"), QUOTE(R"(\f)")); + EXPECT_EQ(fmt("\n"), QUOTE(R"(\n)")); + EXPECT_EQ(fmt("\r"), QUOTE(R"(\r)")); + EXPECT_EQ(fmt("\t"), QUOTE(R"(\t)")); + EXPECT_EQ(fmt("\v"), QUOTE(R"(\v)")); + EXPECT_EQ(fmt("\""), QUOTE(R"(\")")); + EXPECT_EQ(fmt("\'"), QUOTE(R"(')")); + EXPECT_EQ(fmt("\\"), QUOTE(R"(\\)")); + + // Printable characters. + EXPECT_EQ(fmt("'"), QUOTE("'")); + EXPECT_EQ(fmt("a"), QUOTE("a")); + EXPECT_EQ(fmt("Z"), QUOTE("Z")); + EXPECT_EQ(fmt("🥑"), QUOTE("🥑")); + + // Octal (\nnn), hex (\xnn), extended octal (\unnnn or \Unnnnnnnn). + EXPECT_EQ(fmt("\uD55C"), QUOTE("\uD55C")); + EXPECT_EQ(fmt("\U00010348"), QUOTE("\U00010348")); + + EXPECT_EQ(fmt("\376"), QUOTE(R"(\xfe)")); // \376 is 254 in decimal. + EXPECT_EQ(fmt("\xfe"), QUOTE(R"(\xfe)")); // \xfe is 254 in decimal. +} + +// Test UTF8 formatting for C++. +TEST(StringPrinterTests, CxxUTF8) { + auto fmt = [](StringRef str) { + return format( + str, StringPrinter::EscapeStyle::CXX); + }; + + // Special escapes. + EXPECT_EQ(fmt({"\0", 1}), QUOTE("")); + EXPECT_EQ(fmt("\a"), QUOTE(R"(\a)")); + EXPECT_EQ(fmt("\b"), QUOTE(R"(\b)")); + EXPECT_EQ(fmt("\f"), QUOTE(R"(\f)")); + EXPECT_EQ(fmt("\n"), QUOTE(R"(\n)")); + EXPECT_EQ(fmt("\r"), QUOTE(R"(\r)")); + EXPECT_EQ(fmt("\t"), QUOTE(R"(\t)")); + EXPECT_EQ(fmt("\v"), QUOTE(R"(\v)")); + EXPECT_EQ(fmt("\""), QUOTE(R"(\")")); + EXPECT_EQ(fmt("\'"), QUOTE(R"(')")); + EXPECT_EQ(fmt("\\"), QUOTE(R"(\\)")); + + // Printable characters. + EXPECT_EQ(fmt("'"), QUOTE("'")); + EXPECT_EQ(fmt("a"), QUOTE("a")); + EXPECT_EQ(fmt("Z"), QUOTE("Z")); + EXPECT_EQ(fmt("🥑"), QUOTE("🥑")); + + // Octal (\nnn), hex (\xnn), extended octal (\unnnn or \Unnnnnnnn). + EXPECT_EQ(fmt("\uD55C"), QUOTE("\uD55C")); + EXPECT_EQ(fmt("\U00010348"), QUOTE("\U00010348")); + + EXPECT_EQ(fmt("\376"), QUOTE(R"(\xfe)")); // \376 is 254 in decimal. + EXPECT_EQ(fmt("\xfe"), QUOTE(R"(\xfe)")); // \xfe is 254 in decimal. +} + +// Test UTF8 formatting for Swift. +TEST(StringPrinterTests, SwiftUTF8) { + auto fmt = [](StringRef str) { + return format( + str, StringPrinter::EscapeStyle::Swift); + }; + + // Special escapes. + EXPECT_EQ(fmt({"\0", 1}), QUOTE("")); + EXPECT_EQ(fmt("\a"), QUOTE(R"(\a)")); + EXPECT_EQ(fmt("\b"), QUOTE(R"(\u{8})")); + EXPECT_EQ(fmt("\f"), QUOTE(R"(\u{c})")); + EXPECT_EQ(fmt("\n"), QUOTE(R"(\n)")); + EXPECT_EQ(fmt("\r"), QUOTE(R"(\r)")); + EXPECT_EQ(fmt("\t"), QUOTE(R"(\t)")); + EXPECT_EQ(fmt("\v"), QUOTE(R"(\u{b})")); + EXPECT_EQ(fmt("\""), QUOTE(R"(\")")); + EXPECT_EQ(fmt("\'"), QUOTE(R"(\')")); + EXPECT_EQ(fmt("\\"), QUOTE(R"(\\)")); + + // Printable characters. + EXPECT_EQ(fmt("'"), QUOTE(R"(\')")); + EXPECT_EQ(fmt("a"), QUOTE("a")); + EXPECT_EQ(fmt("Z"), QUOTE("Z")); + EXPECT_EQ(fmt("🥑"), QUOTE("🥑")); + + // Octal (\nnn), hex (\xnn), extended octal (\unnnn or \Unnnnnnnn). + EXPECT_EQ(fmt("\uD55C"), QUOTE("\uD55C")); + EXPECT_EQ(fmt("\U00010348"), QUOTE("\U00010348")); + + EXPECT_EQ(fmt("\376"), QUOTE(R"(\u{fe})")); // \376 is 254 in decimal. + EXPECT_EQ(fmt("\xfe"), QUOTE(R"(\u{fe})")); // \xfe is 254 in decimal. +} diff --git a/gnu/llvm/lldb/unittests/Disassembler/CMakeLists.txt b/gnu/llvm/lldb/unittests/Disassembler/CMakeLists.txt index de78d12fa2f..a0a3c264f16 100644 --- a/gnu/llvm/lldb/unittests/Disassembler/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/Disassembler/CMakeLists.txt @@ -6,7 +6,7 @@ if("ARM" IN_LIST LLVM_TARGETS_TO_BUILD) lldbCore lldbSymbol lldbTarget - lldbPluginDisassemblerLLVM + lldbPluginDisassemblerLLVMC lldbPluginProcessUtility LINK_COMPONENTS Support diff --git a/gnu/llvm/lldb/unittests/Disassembler/TestArm64Disassembly.cpp b/gnu/llvm/lldb/unittests/Disassembler/TestArm64Disassembly.cpp index 2f631a64a0c..12975683397 100644 --- a/gnu/llvm/lldb/unittests/Disassembler/TestArm64Disassembly.cpp +++ b/gnu/llvm/lldb/unittests/Disassembler/TestArm64Disassembly.cpp @@ -1,5 +1,4 @@ -//===-- TestArm64Disassembly.cpp ------------------------------------*- C++ -//-*-===// +//===-- TestArm64Disassembly.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -15,7 +14,7 @@ #include "lldb/Utility/ArchSpec.h" #include "lldb/Target/ExecutionContext.h" -#include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h" +#include "Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h" #include "llvm/Support/TargetSelect.h" using namespace lldb; diff --git a/gnu/llvm/lldb/unittests/Disassembler/TestArmv7Disassembly.cpp b/gnu/llvm/lldb/unittests/Disassembler/TestArmv7Disassembly.cpp index 2acf818ff01..92b6d07f48e 100644 --- a/gnu/llvm/lldb/unittests/Disassembler/TestArmv7Disassembly.cpp +++ b/gnu/llvm/lldb/unittests/Disassembler/TestArmv7Disassembly.cpp @@ -1,5 +1,4 @@ -//===-- TestArmv7Disassembly.cpp ------------------------------------*- C++ -//-*-===// +//===-- TestArmv7Disassembly.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -15,7 +14,7 @@ #include "lldb/Utility/ArchSpec.h" #include "lldb/Target/ExecutionContext.h" -#include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h" +#include "Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h" #include "llvm/Support/TargetSelect.h" using namespace lldb; diff --git a/gnu/llvm/lldb/unittests/Editline/EditlineTest.cpp b/gnu/llvm/lldb/unittests/Editline/EditlineTest.cpp index 41f8e471256..291ab3cb368 100644 --- a/gnu/llvm/lldb/unittests/Editline/EditlineTest.cpp +++ b/gnu/llvm/lldb/unittests/Editline/EditlineTest.cpp @@ -1,4 +1,4 @@ -//===-- EditlineTest.cpp ----------------------------------------*- C++ -*-===// +//===-- EditlineTest.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -88,21 +88,21 @@ private: PseudoTerminal _pty; int _pty_master_fd; - int _pty_slave_fd; + int _pty_secondary_fd; - std::unique_ptr _el_slave_file; + std::unique_ptr _el_secondary_file; }; EditlineAdapter::EditlineAdapter() - : _editline_sp(), _pty(), _pty_master_fd(-1), _pty_slave_fd(-1), - _el_slave_file() { + : _editline_sp(), _pty(), _pty_master_fd(-1), _pty_secondary_fd(-1), + _el_secondary_file() { lldb_private::Status error; // Open the first master pty available. char error_string[256]; error_string[0] = '\0'; - if (!_pty.OpenFirstAvailableMaster(O_RDWR, error_string, - sizeof(error_string))) { + if (!_pty.OpenFirstAvailablePrimary(O_RDWR, error_string, + sizeof(error_string))) { fprintf(stderr, "failed to open first available master pty: '%s'\n", error_string); return; @@ -111,24 +111,24 @@ EditlineAdapter::EditlineAdapter() // Grab the master fd. This is a file descriptor we will: // (1) write to when we want to send input to editline. // (2) read from when we want to see what editline sends back. - _pty_master_fd = _pty.GetMasterFileDescriptor(); + _pty_master_fd = _pty.GetPrimaryFileDescriptor(); - // Open the corresponding slave pty. - if (!_pty.OpenSlave(O_RDWR, error_string, sizeof(error_string))) { - fprintf(stderr, "failed to open slave pty: '%s'\n", error_string); + // Open the corresponding secondary pty. + if (!_pty.OpenSecondary(O_RDWR, error_string, sizeof(error_string))) { + fprintf(stderr, "failed to open secondary pty: '%s'\n", error_string); return; } - _pty_slave_fd = _pty.GetSlaveFileDescriptor(); + _pty_secondary_fd = _pty.GetSecondaryFileDescriptor(); - _el_slave_file.reset(new FilePointer(fdopen(_pty_slave_fd, "rw"))); - EXPECT_FALSE(nullptr == *_el_slave_file); - if (*_el_slave_file == nullptr) + _el_secondary_file.reset(new FilePointer(fdopen(_pty_secondary_fd, "rw"))); + EXPECT_FALSE(nullptr == *_el_secondary_file); + if (*_el_secondary_file == nullptr) return; // Create an Editline instance. - _editline_sp.reset(new lldb_private::Editline("gtest editor", *_el_slave_file, - *_el_slave_file, - *_el_slave_file, false)); + _editline_sp.reset(new lldb_private::Editline( + "gtest editor", *_el_secondary_file, *_el_secondary_file, + *_el_secondary_file, false)); _editline_sp->SetPrompt("> "); // Hookup our input complete callback. @@ -136,8 +136,8 @@ EditlineAdapter::EditlineAdapter() } void EditlineAdapter::CloseInput() { - if (_el_slave_file != nullptr) - _el_slave_file.reset(nullptr); + if (_el_secondary_file != nullptr) + _el_secondary_file.reset(nullptr); } bool EditlineAdapter::SendLine(const std::string &line) { diff --git a/gnu/llvm/lldb/unittests/Expression/CMakeLists.txt b/gnu/llvm/lldb/unittests/Expression/CMakeLists.txt index 25e94f4d88f..2f5304ab212 100644 --- a/gnu/llvm/lldb/unittests/Expression/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/Expression/CMakeLists.txt @@ -8,6 +8,7 @@ add_lldb_unittest(ExpressionTests LINK_LIBS lldbCore lldbPluginExpressionParserClang + lldbPluginTypeSystemClang lldbUtility lldbUtilityHelpers LLVMTestingSupport diff --git a/gnu/llvm/lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp b/gnu/llvm/lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp index 582aed0378a..ecee35ff46e 100644 --- a/gnu/llvm/lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp +++ b/gnu/llvm/lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp @@ -7,12 +7,12 @@ //===----------------------------------------------------------------------===// #include "Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "TestingSupport/SubsystemRAII.h" #include "TestingSupport/Symbol/ClangTestUtils.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangUtil.h" #include "lldb/lldb-defines.h" #include "gtest/gtest.h" @@ -21,12 +21,12 @@ using namespace lldb; namespace { struct FakeClangExpressionDeclMap : public ClangExpressionDeclMap { - FakeClangExpressionDeclMap(const ClangASTImporterSP &importer) + FakeClangExpressionDeclMap(const std::shared_ptr &importer) : ClangExpressionDeclMap(false, nullptr, lldb::TargetSP(), importer, nullptr) { m_scratch_context = clang_utils::createAST(); } - std::unique_ptr m_scratch_context; + std::unique_ptr m_scratch_context; /// Adds a persistent decl that can be found by the ClangExpressionDeclMap /// via GetPersistentDecl. void AddPersistentDeclForTest(clang::NamedDecl *d) { @@ -58,12 +58,12 @@ struct ClangExpressionDeclMapTest : public testing::Test { SubsystemRAII subsystems; /// The ClangASTImporter used during the test. - ClangASTImporterSP importer; + std::shared_ptr importer; /// The ExpressionDeclMap for the current test case. std::unique_ptr decl_map; /// The target AST that lookup results should be imported to. - std::unique_ptr target_ast; + std::unique_ptr target_ast; void SetUp() override { importer = std::make_shared(); @@ -88,7 +88,7 @@ TEST_F(ClangExpressionDeclMapTest, TestUnknownIdentifierLookup) { clang::DeclarationName name = clang_utils::getDeclarationName(*target_ast, "foo"); const clang::DeclContext *dc = target_ast->GetTranslationUnitDecl(); - NameSearchContext search(*decl_map, decls, name, dc); + NameSearchContext search(*target_ast, decls, name, dc); decl_map->FindExternalVisibleDecls(search); @@ -111,7 +111,7 @@ TEST_F(ClangExpressionDeclMapTest, TestPersistentDeclLookup) { clang::DeclarationName name = clang_utils::getDeclarationName(*target_ast, decl_name); const clang::DeclContext *dc = target_ast->GetTranslationUnitDecl(); - NameSearchContext search(*decl_map, decls, name, dc); + NameSearchContext search(*target_ast, decls, name, dc); // Search and check that we found $persistent_class. decl_map->FindExternalVisibleDecls(search); diff --git a/gnu/llvm/lldb/unittests/Expression/ClangParserTest.cpp b/gnu/llvm/lldb/unittests/Expression/ClangParserTest.cpp index ade0f5387c0..81f9ed839fc 100644 --- a/gnu/llvm/lldb/unittests/Expression/ClangParserTest.cpp +++ b/gnu/llvm/lldb/unittests/Expression/ClangParserTest.cpp @@ -1,4 +1,4 @@ -//===-- ClangParserTest.cpp --------------------------------------*- C++-*-===// +//===-- ClangParserTest.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Expression/CppModuleConfigurationTest.cpp b/gnu/llvm/lldb/unittests/Expression/CppModuleConfigurationTest.cpp index 7ef66f60cfb..c3cc134bd5a 100644 --- a/gnu/llvm/lldb/unittests/Expression/CppModuleConfigurationTest.cpp +++ b/gnu/llvm/lldb/unittests/Expression/CppModuleConfigurationTest.cpp @@ -1,4 +1,4 @@ -//===-- CppModuleConfigurationTest.cpp ---------------------------*- C++-*-===// +//===-- CppModuleConfigurationTest.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -28,7 +28,7 @@ static std::string ResourceInc() { llvm::SmallString<256> resource_dir; llvm::sys::path::append(resource_dir, GetClangResourceDir().GetPath(), "include"); - return resource_dir.str().str(); + return std::string(resource_dir); } /// Utility function turningn a list of paths into a FileSpecList. diff --git a/gnu/llvm/lldb/unittests/Expression/DWARFExpressionTest.cpp b/gnu/llvm/lldb/unittests/Expression/DWARFExpressionTest.cpp index 45876152f02..78c400c33d4 100644 --- a/gnu/llvm/lldb/unittests/Expression/DWARFExpressionTest.cpp +++ b/gnu/llvm/lldb/unittests/Expression/DWARFExpressionTest.cpp @@ -1,4 +1,4 @@ -//===-- DWARFExpressionTest.cpp ----------------------------------*- C++-*-===// +//===-- DWARFExpressionTest.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,17 +7,13 @@ //===----------------------------------------------------------------------===// #include "lldb/Expression/DWARFExpression.h" -#include "../../source/Plugins/SymbolFile/DWARF/DWARFUnit.h" -#include "../../source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" -#include "TestingSupport/SubsystemRAII.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/Section.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" +#include "TestingSupport/Symbol/YAMLModuleTester.h" #include "lldb/Core/Value.h" #include "lldb/Core/dwarf.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/StreamString.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/ObjectYAML/DWARFEmitter.h" #include "llvm/Testing/Support/Error.h" #include "gtest/gtest.h" @@ -55,122 +51,9 @@ static llvm::Expected Evaluate(llvm::ArrayRef expr, } } -/// A mock module holding an object file parsed from YAML. -class YAMLModule : public lldb_private::Module { +class DWARFExpressionTester : public YAMLModuleTester { public: - YAMLModule(ArchSpec &arch) : Module(FileSpec("test"), arch) {} - void SetObjectFile(lldb::ObjectFileSP obj_file) { m_objfile_sp = obj_file; } - ObjectFile *GetObjectFile() override { return m_objfile_sp.get(); } -}; - -/// A mock object file that can be parsed from YAML. -class YAMLObjectFile : public lldb_private::ObjectFile { - const lldb::ModuleSP m_module_sp; - llvm::StringMap> &m_section_map; - /// Because there is only one DataExtractor in the ObjectFile - /// interface, all sections are copied into a contiguous buffer. - std::vector m_buffer; - -public: - YAMLObjectFile(const lldb::ModuleSP &module_sp, - llvm::StringMap> &map) - : ObjectFile(module_sp, &module_sp->GetFileSpec(), /*file_offset*/ 0, - /*length*/ 0, /*data_sp*/ nullptr, /*data_offset*/ 0), - m_module_sp(module_sp), m_section_map(map) {} - - /// Callback for initializing the module's list of sections. - void CreateSections(SectionList &unified_section_list) override { - lldb::offset_t total_bytes = 0; - for (auto &entry : m_section_map) - total_bytes += entry.getValue()->getBufferSize(); - m_buffer.reserve(total_bytes); - m_data = - DataExtractor(m_buffer.data(), total_bytes, lldb::eByteOrderLittle, 4); - - lldb::user_id_t sect_id = 1; - for (auto &entry : m_section_map) { - llvm::StringRef name = entry.getKey(); - lldb::SectionType sect_type = - llvm::StringSwitch(name) - .Case("debug_info", lldb::eSectionTypeDWARFDebugInfo) - .Case("debug_abbrev", lldb::eSectionTypeDWARFDebugAbbrev); - auto &membuf = entry.getValue(); - lldb::addr_t file_vm_addr = 0; - lldb::addr_t vm_size = 0; - lldb::offset_t file_offset = m_buffer.size(); - lldb::offset_t file_size = membuf->getBufferSize(); - m_buffer.resize(file_offset + file_size); - memcpy(m_buffer.data() + file_offset, membuf->getBufferStart(), - file_size); - uint32_t log2align = 0; - uint32_t flags = 0; - auto section_sp = std::make_shared( - m_module_sp, this, sect_id++, ConstString(name), sect_type, - file_vm_addr, vm_size, file_offset, file_size, log2align, flags); - unified_section_list.AddSection(section_sp); - } - } - - /// \{ - /// Stub methods that aren't needed here. - ConstString GetPluginName() override { return ConstString("YAMLObjectFile"); } - uint32_t GetPluginVersion() override { return 0; } - void Dump(Stream *s) override {} - uint32_t GetAddressByteSize() const override { return 8; } - uint32_t GetDependentModules(FileSpecList &file_list) override { return 0; } - bool IsExecutable() const override { return 0; } - ArchSpec GetArchitecture() override { return {}; } - Symtab *GetSymtab() override { return nullptr; } - bool IsStripped() override { return false; } - UUID GetUUID() override { return {}; } - lldb::ByteOrder GetByteOrder() const override { - return lldb::eByteOrderLittle; - } - bool ParseHeader() override { return false; } - Type CalculateType() override { return {}; } - Strata CalculateStrata() override { return {}; } - /// \} -}; - -/// Helper class that can construct a module from YAML and evaluate -/// DWARF expressions on it. -class YAMLModuleTester { - SubsystemRAII subsystems; - llvm::StringMap> m_sections_map; - lldb::ModuleSP m_module_sp; - lldb::ObjectFileSP m_objfile_sp; - DWARFUnitSP m_dwarf_unit; - std::unique_ptr m_symfile_dwarf; - -public: - /// Parse the debug info sections from the YAML description. - YAMLModuleTester(llvm::StringRef yaml_data, llvm::StringRef triple) { - auto sections_map = llvm::DWARFYAML::EmitDebugSections(yaml_data, true); - if (!sections_map) - return; - m_sections_map = std::move(*sections_map); - ArchSpec arch(triple); - m_module_sp = std::make_shared(arch); - m_objfile_sp = std::make_shared(m_module_sp, m_sections_map); - static_cast(m_module_sp.get())->SetObjectFile(m_objfile_sp); - - lldb::user_id_t uid = 0; - llvm::StringRef raw_debug_info = m_sections_map["debug_info"]->getBuffer(); - lldb_private::DataExtractor debug_info( - raw_debug_info.data(), raw_debug_info.size(), - m_objfile_sp->GetByteOrder(), m_objfile_sp->GetAddressByteSize()); - lldb::offset_t offset_ptr = 0; - m_symfile_dwarf = std::make_unique(m_objfile_sp, nullptr); - llvm::Expected dwarf_unit = DWARFUnit::extract( - *m_symfile_dwarf, uid, - *static_cast(&debug_info), - DIERef::DebugInfo, &offset_ptr); - if (dwarf_unit) - m_dwarf_unit = dwarf_unit.get(); - } - DWARFUnitSP GetDwarfUnit() { return m_dwarf_unit; } - - // Evaluate a raw DWARF expression. + using YAMLModuleTester::YAMLModuleTester; llvm::Expected Eval(llvm::ArrayRef expr) { return ::Evaluate(expr, m_module_sp, m_dwarf_unit.get()); } @@ -178,35 +61,8 @@ public: /// Unfortunately Scalar's operator==() is really picky. static Scalar GetScalar(unsigned bits, uint64_t value, bool sign) { - Scalar scalar; - auto type = Scalar::GetBestTypeForBitSize(bits, sign); - switch (type) { - case Scalar::e_sint: - scalar = Scalar((int)value); - break; - case Scalar::e_slong: - scalar = Scalar((long)value); - break; - case Scalar::e_slonglong: - scalar = Scalar((long long)value); - break; - case Scalar::e_uint: - scalar = Scalar((unsigned int)value); - break; - case Scalar::e_ulong: - scalar = Scalar((unsigned long)value); - break; - case Scalar::e_ulonglong: - scalar = Scalar((unsigned long long)value); - break; - default: - llvm_unreachable("not implemented"); - } - scalar.TruncOrExtendTo(type, bits); - if (sign) - scalar.MakeSigned(); - else - scalar.MakeUnsigned(); + Scalar scalar(value); + scalar.TruncOrExtendTo(bits, sign); return scalar; } @@ -238,8 +94,7 @@ TEST(DWARFExpression, DW_OP_convert) { " - Attribute: DW_AT_byte_size\n" " Form: DW_FORM_data1\n" "debug_info:\n" - " - Length:\n" - " TotalLength: 0\n" + " - Length: 0\n" " Version: 4\n" " AbbrOffset: 0\n" " AddrSize: 8\n" @@ -286,7 +141,7 @@ TEST(DWARFExpression, DW_OP_convert) { uint8_t offs_uchar = 0x00000017; uint8_t offs_schar = 0x0000001a; - YAMLModuleTester t(yamldata, "i386-unknown-linux"); + DWARFExpressionTester t(yamldata, "i386-unknown-linux"); ASSERT_TRUE((bool)t.GetDwarfUnit()); // Constant is given as little-endian. @@ -321,14 +176,14 @@ TEST(DWARFExpression, DW_OP_convert) { llvm::HasValue(GetScalar(64, 0xffffffffffeeddcc, is_signed))); // Truncate to 8 bits. - EXPECT_THAT_EXPECTED(t.Eval({DW_OP_const4s, 'A', 'B', 'C', 'D', 0xee, 0xff, // - DW_OP_convert, offs_uchar}), - llvm::HasValue(GetScalar(8, 'A', not_signed))); + EXPECT_THAT_EXPECTED( + t.Eval({DW_OP_const4s, 'A', 'B', 'C', 'D', DW_OP_convert, offs_uchar}), + llvm::HasValue(GetScalar(8, 'A', not_signed))); // Also truncate to 8 bits. - EXPECT_THAT_EXPECTED(t.Eval({DW_OP_const4s, 'A', 'B', 'C', 'D', 0xee, 0xff, // - DW_OP_convert, offs_schar}), - llvm::HasValue(GetScalar(8, 'A', is_signed))); + EXPECT_THAT_EXPECTED( + t.Eval({DW_OP_const4s, 'A', 'B', 'C', 'D', DW_OP_convert, offs_schar}), + llvm::HasValue(GetScalar(8, 'A', is_signed))); // // Errors. @@ -351,6 +206,10 @@ TEST(DWARFExpression, DW_OP_convert) { llvm::Failed()); } +TEST(DWARFExpression, DW_OP_stack_value) { + EXPECT_THAT_EXPECTED(Evaluate({DW_OP_stack_value}), llvm::Failed()); +} + TEST(DWARFExpression, DW_OP_piece) { EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const2u, 0x11, 0x22, DW_OP_piece, 2, DW_OP_const2u, 0x33, 0x44, DW_OP_piece, 2}), @@ -361,3 +220,10 @@ TEST(DWARFExpression, DW_OP_piece) { // represent that yet. llvm::HasValue(GetScalar(16, 0xff00, true))); } + +TEST(DWARFExpression, DW_OP_unknown) { + EXPECT_THAT_EXPECTED( + Evaluate({0xff}), + llvm::FailedWithMessage( + "Unhandled opcode DW_OP_unknown_ff in DWARFExpression")); +} diff --git a/gnu/llvm/lldb/unittests/Expression/DiagnosticManagerTest.cpp b/gnu/llvm/lldb/unittests/Expression/DiagnosticManagerTest.cpp index f012632e63b..3cfb5ed0b66 100644 --- a/gnu/llvm/lldb/unittests/Expression/DiagnosticManagerTest.cpp +++ b/gnu/llvm/lldb/unittests/Expression/DiagnosticManagerTest.cpp @@ -1,4 +1,4 @@ -//===-- DiagnosticManagerTest.cpp --------------------------------*- C++-*-===// +//===-- DiagnosticManagerTest.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Host/CMakeLists.txt b/gnu/llvm/lldb/unittests/Host/CMakeLists.txt index b88aa97a900..663645c986f 100644 --- a/gnu/llvm/lldb/unittests/Host/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/Host/CMakeLists.txt @@ -11,7 +11,6 @@ set (FILES SocketAddressTest.cpp SocketTest.cpp SocketTestUtilities.cpp - TaskPoolTest.cpp ) if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android") diff --git a/gnu/llvm/lldb/unittests/Host/ConnectionFileDescriptorTest.cpp b/gnu/llvm/lldb/unittests/Host/ConnectionFileDescriptorTest.cpp index a5930f29702..76c54a96b22 100644 --- a/gnu/llvm/lldb/unittests/Host/ConnectionFileDescriptorTest.cpp +++ b/gnu/llvm/lldb/unittests/Host/ConnectionFileDescriptorTest.cpp @@ -1,4 +1,4 @@ -//===-- ConnectionFileDescriptorTest.cpp ------------------------*- C++ -*-===// +//===-- ConnectionFileDescriptorTest.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -22,11 +22,6 @@ public: void TestGetURI(std::string ip) { std::unique_ptr socket_a_up; std::unique_ptr socket_b_up; - if (!IsAddressFamilySupported(ip)) { - GTEST_LOG_(WARNING) << "Skipping test due to missing IPv" - << (IsIPv4(ip) ? "4" : "6") << " support."; - return; - } CreateTCPConnectedSockets(ip, &socket_a_up, &socket_b_up); auto socket = socket_a_up.release(); ConnectionFileDescriptor connection_file_descriptor(socket); @@ -42,6 +37,14 @@ public: } }; -TEST_F(ConnectionFileDescriptorTest, TCPGetURIv4) { TestGetURI("127.0.0.1"); } - -TEST_F(ConnectionFileDescriptorTest, TCPGetURIv6) { TestGetURI("::1"); } +TEST_F(ConnectionFileDescriptorTest, TCPGetURIv4) { + if (!HostSupportsIPv4()) + return; + TestGetURI("127.0.0.1"); +} + +TEST_F(ConnectionFileDescriptorTest, TCPGetURIv6) { + if (!HostSupportsIPv6()) + return; + TestGetURI("::1"); +} diff --git a/gnu/llvm/lldb/unittests/Host/FileActionTest.cpp b/gnu/llvm/lldb/unittests/Host/FileActionTest.cpp index ee1c0a39755..b208169aac2 100644 --- a/gnu/llvm/lldb/unittests/Host/FileActionTest.cpp +++ b/gnu/llvm/lldb/unittests/Host/FileActionTest.cpp @@ -1,4 +1,4 @@ -//===-- FileActionTest.cpp --------------------------------------*- C++ -*-===// +//===-- FileActionTest.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Host/FileSystemTest.cpp b/gnu/llvm/lldb/unittests/Host/FileSystemTest.cpp index 31184d9ad53..f31c5c42a1e 100644 --- a/gnu/llvm/lldb/unittests/Host/FileSystemTest.cpp +++ b/gnu/llvm/lldb/unittests/Host/FileSystemTest.cpp @@ -1,4 +1,4 @@ -//===-- FileSystemTest.cpp --------------------------------------*- C++ -*-===// +//===-- FileSystemTest.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -101,8 +101,8 @@ public: Path(_Path.str()) { for (; I != FilesAndDirs.end(); ++I) { if (isInPath(I->first)) { - CurrentEntry = - vfs::directory_entry(I->second.getName(), I->second.getType()); + CurrentEntry = vfs::directory_entry(std::string(I->second.getName()), + I->second.getType()); break; } } @@ -111,8 +111,8 @@ public: ++I; for (; I != FilesAndDirs.end(); ++I) { if (isInPath(I->first)) { - CurrentEntry = - vfs::directory_entry(I->second.getName(), I->second.getType()); + CurrentEntry = vfs::directory_entry(std::string(I->second.getName()), + I->second.getType()); break; } } @@ -129,7 +129,7 @@ public: } void addEntry(StringRef Path, const vfs::Status &Status) { - FilesAndDirs[Path] = Status; + FilesAndDirs[std::string(Path)] = Status; } void addRegularFile(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) { @@ -303,3 +303,29 @@ TEST(FileSystemTest, OpenErrno) { EXPECT_EQ(code.value(), ENOENT); } +TEST(FileSystemTest, EmptyTest) { + FileSpec spec; + FileSystem fs; + + { + std::error_code ec; + fs.DirBegin(spec, ec); + EXPECT_EQ(ec.category(), std::system_category()); + EXPECT_EQ(ec.value(), ENOENT); + } + + { + llvm::ErrorOr status = fs.GetStatus(spec); + ASSERT_FALSE(status); + EXPECT_EQ(status.getError().category(), std::system_category()); + EXPECT_EQ(status.getError().value(), ENOENT); + } + + EXPECT_EQ(sys::TimePoint<>(), fs.GetModificationTime(spec)); + EXPECT_EQ(static_cast(0), fs.GetByteSize(spec)); + EXPECT_EQ(llvm::sys::fs::perms::perms_not_known, fs.GetPermissions(spec)); + EXPECT_FALSE(fs.Exists(spec)); + EXPECT_FALSE(fs.Readable(spec)); + EXPECT_FALSE(fs.IsDirectory(spec)); + EXPECT_FALSE(fs.IsLocal(spec)); +} diff --git a/gnu/llvm/lldb/unittests/Host/FileTest.cpp b/gnu/llvm/lldb/unittests/Host/FileTest.cpp index 6a0434327f3..126d5e31486 100644 --- a/gnu/llvm/lldb/unittests/Host/FileTest.cpp +++ b/gnu/llvm/lldb/unittests/Host/FileTest.cpp @@ -1,4 +1,4 @@ -//===-- FileTest.cpp --------------------------------------------*- C++ -*-===// +//===-- FileTest.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Host/HostInfoTest.cpp b/gnu/llvm/lldb/unittests/Host/HostInfoTest.cpp index c332606a4da..96d47d75794 100644 --- a/gnu/llvm/lldb/unittests/Host/HostInfoTest.cpp +++ b/gnu/llvm/lldb/unittests/Host/HostInfoTest.cpp @@ -1,4 +1,4 @@ -//===-- HostInfoTest.cpp ----------------------------------------*- C++ -*-===// +//===-- HostInfoTest.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -11,6 +11,7 @@ #include "TestingSupport/TestUtilities.h" #include "lldb/Host/FileSystem.h" #include "lldb/lldb-defines.h" +#include "llvm/Support/Host.h" #include "gtest/gtest.h" using namespace lldb_private; @@ -49,3 +50,13 @@ TEST_F(HostInfoTest, GetHostname) { std::string s("abc"); EXPECT_TRUE(HostInfo::GetHostname(s)); } + +#if defined(__APPLE__) +TEST_F(HostInfoTest, GetXcodeSDK) { + EXPECT_FALSE(HostInfo::GetXcodeSDKPath(XcodeSDK("MacOSX.sdk")).empty()); + // These are expected to fall back to an available version. + EXPECT_FALSE(HostInfo::GetXcodeSDKPath(XcodeSDK("MacOSX9999.sdk")).empty()); + // This is expected to fail. + EXPECT_TRUE(HostInfo::GetXcodeSDKPath(XcodeSDK("CeciNestPasUnOS.sdk")).empty()); +} +#endif diff --git a/gnu/llvm/lldb/unittests/Host/HostTest.cpp b/gnu/llvm/lldb/unittests/Host/HostTest.cpp index ac149d81283..5e01a6835c0 100644 --- a/gnu/llvm/lldb/unittests/Host/HostTest.cpp +++ b/gnu/llvm/lldb/unittests/Host/HostTest.cpp @@ -1,4 +1,4 @@ -//===-- HostTest.cpp --------------------------------------------*- C++ -*-===// +//===-- HostTest.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Host/MainLoopTest.cpp b/gnu/llvm/lldb/unittests/Host/MainLoopTest.cpp index da509b940a1..9c9b6ae196c 100644 --- a/gnu/llvm/lldb/unittests/Host/MainLoopTest.cpp +++ b/gnu/llvm/lldb/unittests/Host/MainLoopTest.cpp @@ -1,4 +1,4 @@ -//===-- MainLoopTest.cpp ----------------------------------------*- C++ -*-===// +//===-- MainLoopTest.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -102,17 +102,17 @@ TEST_F(MainLoopTest, TerminatesImmediately) { TEST_F(MainLoopTest, DetectsEOF) { PseudoTerminal term; - ASSERT_TRUE(term.OpenFirstAvailableMaster(O_RDWR, nullptr, 0)); - ASSERT_TRUE(term.OpenSlave(O_RDWR | O_NOCTTY, nullptr, 0)); + ASSERT_TRUE(term.OpenFirstAvailablePrimary(O_RDWR, nullptr, 0)); + ASSERT_TRUE(term.OpenSecondary(O_RDWR | O_NOCTTY, nullptr, 0)); auto conn = std::make_unique( - term.ReleaseMasterFileDescriptor(), true); + term.ReleasePrimaryFileDescriptor(), true); Status error; MainLoop loop; auto handle = loop.RegisterReadObject(conn->GetReadObject(), make_callback(), error); ASSERT_TRUE(error.Success()); - term.CloseSlaveFileDescriptor(); + term.CloseSecondaryFileDescriptor(); ASSERT_TRUE(loop.Run().Success()); ASSERT_EQ(1u, callback_count); diff --git a/gnu/llvm/lldb/unittests/Host/NativeProcessProtocolTest.cpp b/gnu/llvm/lldb/unittests/Host/NativeProcessProtocolTest.cpp index c5516b1b1d3..a48e67c9213 100644 --- a/gnu/llvm/lldb/unittests/Host/NativeProcessProtocolTest.cpp +++ b/gnu/llvm/lldb/unittests/Host/NativeProcessProtocolTest.cpp @@ -1,4 +1,4 @@ -//===-- NativeProcessProtocolTest.cpp ---------------------------*- C++ -*-===// +//===-- NativeProcessProtocolTest.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Host/ProcessLaunchInfoTest.cpp b/gnu/llvm/lldb/unittests/Host/ProcessLaunchInfoTest.cpp index 40b45c559f0..0b3607092e8 100644 --- a/gnu/llvm/lldb/unittests/Host/ProcessLaunchInfoTest.cpp +++ b/gnu/llvm/lldb/unittests/Host/ProcessLaunchInfoTest.cpp @@ -1,4 +1,4 @@ -//===-- ProcessLaunchInfoTest.cpp -------------------------------*- C++ -*-===// +//===-- ProcessLaunchInfoTest.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Host/SocketAddressTest.cpp b/gnu/llvm/lldb/unittests/Host/SocketAddressTest.cpp index 8abf9c3376e..dc5f55253f6 100644 --- a/gnu/llvm/lldb/unittests/Host/SocketAddressTest.cpp +++ b/gnu/llvm/lldb/unittests/Host/SocketAddressTest.cpp @@ -1,4 +1,4 @@ -//===-- SocketAddressTest.cpp -----------------------------------*- C++ -*-===// +//===-- SocketAddressTest.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Host/SocketTest.cpp b/gnu/llvm/lldb/unittests/Host/SocketTest.cpp index d4e8917bf94..c53d2660f0c 100644 --- a/gnu/llvm/lldb/unittests/Host/SocketTest.cpp +++ b/gnu/llvm/lldb/unittests/Host/SocketTest.cpp @@ -1,4 +1,4 @@ -//===-- SocketTest.cpp ------------------------------------------*- C++ -*-===// +//===-- SocketTest.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -111,10 +111,8 @@ TEST_F(SocketTest, TCPListen0ConnectAccept) { TEST_F(SocketTest, TCPGetAddress) { std::unique_ptr socket_a_up; std::unique_ptr socket_b_up; - if (!IsAddressFamilySupported("127.0.0.1")) { - GTEST_LOG_(WARNING) << "Skipping test due to missing IPv4 support."; + if (!HostSupportsIPv4()) return; - } CreateTCPConnectedSockets("127.0.0.1", &socket_a_up, &socket_b_up); EXPECT_EQ(socket_a_up->GetLocalPortNumber(), @@ -128,36 +126,28 @@ TEST_F(SocketTest, TCPGetAddress) { } TEST_F(SocketTest, UDPConnect) { - Socket *socket; + llvm::Expected> socket = + UDPSocket::Connect("127.0.0.1:0", /*child_processes_inherit=*/false); - bool child_processes_inherit = false; - auto error = UDPSocket::Connect("127.0.0.1:0", child_processes_inherit, - socket); - - std::unique_ptr socket_up(socket); - - EXPECT_TRUE(error.Success()); - EXPECT_TRUE(socket_up->IsValid()); + ASSERT_THAT_EXPECTED(socket, llvm::Succeeded()); + EXPECT_TRUE(socket.get()->IsValid()); } TEST_F(SocketTest, TCPListen0GetPort) { - Socket *server_socket; Predicate port_predicate; port_predicate.SetValue(0, eBroadcastNever); - Status err = - Socket::TcpListen("10.10.12.3:0", false, server_socket, &port_predicate); - std::unique_ptr socket_up((TCPSocket*)server_socket); - EXPECT_TRUE(socket_up->IsValid()); - EXPECT_NE(socket_up->GetLocalPortNumber(), 0); + llvm::Expected> sock = + Socket::TcpListen("10.10.12.3:0", false, &port_predicate); + ASSERT_THAT_EXPECTED(sock, llvm::Succeeded()); + ASSERT_TRUE(sock.get()->IsValid()); + EXPECT_NE(sock.get()->GetLocalPortNumber(), 0); } TEST_F(SocketTest, TCPGetConnectURI) { std::unique_ptr socket_a_up; std::unique_ptr socket_b_up; - if (!IsAddressFamilySupported("127.0.0.1")) { - GTEST_LOG_(WARNING) << "Skipping test due to missing IPv4 support."; + if (!HostSupportsIPv4()) return; - } CreateTCPConnectedSockets("127.0.0.1", &socket_a_up, &socket_b_up); llvm::StringRef scheme; @@ -171,20 +161,17 @@ TEST_F(SocketTest, TCPGetConnectURI) { } TEST_F(SocketTest, UDPGetConnectURI) { - if (!IsAddressFamilySupported("127.0.0.1")) { - GTEST_LOG_(WARNING) << "Skipping test due to missing IPv4 support."; + if (!HostSupportsIPv4()) return; - } - Socket *socket; - bool child_processes_inherit = false; - auto error = - UDPSocket::Connect("127.0.0.1:0", child_processes_inherit, socket); + llvm::Expected> socket = + UDPSocket::Connect("127.0.0.1:0", /*child_processes_inherit=*/false); + ASSERT_THAT_EXPECTED(socket, llvm::Succeeded()); llvm::StringRef scheme; llvm::StringRef hostname; int port; llvm::StringRef path; - std::string uri(socket->GetRemoteConnectionURI()); + std::string uri = socket.get()->GetRemoteConnectionURI(); EXPECT_TRUE(UriParser::Parse(uri, scheme, hostname, port, path)); EXPECT_EQ(scheme, "udp"); } diff --git a/gnu/llvm/lldb/unittests/Host/SocketTestUtilities.cpp b/gnu/llvm/lldb/unittests/Host/SocketTestUtilities.cpp index 6e7345bc917..e2006b85115 100644 --- a/gnu/llvm/lldb/unittests/Host/SocketTestUtilities.cpp +++ b/gnu/llvm/lldb/unittests/Host/SocketTestUtilities.cpp @@ -1,4 +1,4 @@ -//===----------------- SocketTestUtilities.cpp ------------------*- C++ -*-===// +//===-- SocketTestUtilities.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -33,10 +33,10 @@ void lldb_private::CreateConnectedSockets( Status error; std::unique_ptr listen_socket_up( new SocketType(true, child_processes_inherit)); - EXPECT_FALSE(error.Fail()); + ASSERT_THAT_ERROR(error.ToError(), llvm::Succeeded()); error = listen_socket_up->Listen(listen_remote_address, 5); - EXPECT_FALSE(error.Fail()); - EXPECT_TRUE(listen_socket_up->IsValid()); + ASSERT_THAT_ERROR(error.ToError(), llvm::Succeeded()); + ASSERT_TRUE(listen_socket_up->IsValid()); Status accept_error; Socket *accept_socket; @@ -47,21 +47,19 @@ void lldb_private::CreateConnectedSockets( std::string connect_remote_address = get_connect_addr(*listen_socket_up); std::unique_ptr connect_socket_up( new SocketType(true, child_processes_inherit)); - EXPECT_FALSE(error.Fail()); + ASSERT_THAT_ERROR(error.ToError(), llvm::Succeeded()); error = connect_socket_up->Connect(connect_remote_address); - EXPECT_FALSE(error.Fail()); - EXPECT_TRUE(connect_socket_up->IsValid()); + ASSERT_THAT_ERROR(error.ToError(), llvm::Succeeded()); + ASSERT_TRUE(connect_socket_up->IsValid()); a_up->swap(connect_socket_up); - EXPECT_TRUE(error.Success()); - EXPECT_NE(nullptr, a_up->get()); - EXPECT_TRUE((*a_up)->IsValid()); + ASSERT_TRUE((*a_up)->IsValid()); accept_thread.join(); b_up->reset(static_cast(accept_socket)); - EXPECT_TRUE(accept_error.Success()); - EXPECT_NE(nullptr, b_up->get()); - EXPECT_TRUE((*b_up)->IsValid()); + ASSERT_THAT_ERROR(accept_error.ToError(), llvm::Succeeded()); + ASSERT_NE(nullptr, b_up->get()); + ASSERT_TRUE((*b_up)->IsValid()); listen_socket_up.reset(); } @@ -93,13 +91,37 @@ void lldb_private::CreateDomainConnectedSockets( } #endif -bool lldb_private::IsAddressFamilySupported(std::string ip) { - auto addresses = lldb_private::SocketAddress::GetAddressInfo( - ip.c_str(), NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP); - return addresses.size() > 0; +static bool CheckIPSupport(llvm::StringRef Proto, llvm::StringRef Addr) { + llvm::Expected> Sock = Socket::TcpListen( + Addr, /*child_processes_inherit=*/false, /*predicate=*/nullptr); + if (Sock) + return true; + llvm::Error Err = Sock.takeError(); + GTEST_LOG_(WARNING) << llvm::formatv( + "Creating a canary {0} TCP socket failed: {1}.", + Proto, Err) + .str(); + bool HasAddrNotAvail = false; + handleAllErrors(std::move(Err), [&](std::unique_ptr ECErr) { + if (ECErr->convertToErrorCode() == + std::make_error_code(std::errc::address_not_available)) + HasAddrNotAvail = true; + }); + if (HasAddrNotAvail) { + GTEST_LOG_(WARNING) + << llvm::formatv( + "Assuming the host does not support {0}. Skipping test.", Proto) + .str(); + return false; + } + GTEST_LOG_(WARNING) << "Continuing anyway. The test will probably fail."; + return true; +} + +bool lldb_private::HostSupportsIPv4() { + return CheckIPSupport("IPv4", "127.0.0.1:0"); } -bool lldb_private::IsIPv4(std::string ip) { - struct sockaddr_in sock_addr; - return inet_pton(AF_INET, ip.c_str(), &(sock_addr.sin_addr)) != 0; +bool lldb_private::HostSupportsIPv6() { + return CheckIPSupport("IPv6", "[::1]:0"); } diff --git a/gnu/llvm/lldb/unittests/Host/SocketTestUtilities.h b/gnu/llvm/lldb/unittests/Host/SocketTestUtilities.h index 35627824754..943d98a96be 100644 --- a/gnu/llvm/lldb/unittests/Host/SocketTestUtilities.h +++ b/gnu/llvm/lldb/unittests/Host/SocketTestUtilities.h @@ -40,8 +40,8 @@ void CreateDomainConnectedSockets(llvm::StringRef path, std::unique_ptr *b_up); #endif -bool IsAddressFamilySupported(std::string ip); -bool IsIPv4(std::string ip); +bool HostSupportsIPv6(); +bool HostSupportsIPv4(); } // namespace lldb_private -#endif \ No newline at end of file +#endif diff --git a/gnu/llvm/lldb/unittests/Host/linux/HostTest.cpp b/gnu/llvm/lldb/unittests/Host/linux/HostTest.cpp index d7676c24ce9..699ccba0a98 100644 --- a/gnu/llvm/lldb/unittests/Host/linux/HostTest.cpp +++ b/gnu/llvm/lldb/unittests/Host/linux/HostTest.cpp @@ -1,4 +1,4 @@ -//===-- HostTest.cpp --------------------------------------------*- C++ -*-===// +//===-- HostTest.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Host/linux/SupportTest.cpp b/gnu/llvm/lldb/unittests/Host/linux/SupportTest.cpp index f0687431979..680893c03d0 100644 --- a/gnu/llvm/lldb/unittests/Host/linux/SupportTest.cpp +++ b/gnu/llvm/lldb/unittests/Host/linux/SupportTest.cpp @@ -1,4 +1,4 @@ -//===-- SupportTest.cpp -----------------------------------------*- C++ -*-===// +//===-- SupportTest.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Instruction/CMakeLists.txt b/gnu/llvm/lldb/unittests/Instruction/CMakeLists.txt new file mode 100644 index 00000000000..63d82983102 --- /dev/null +++ b/gnu/llvm/lldb/unittests/Instruction/CMakeLists.txt @@ -0,0 +1,12 @@ +if("ARM" IN_LIST LLVM_TARGETS_TO_BUILD) + add_lldb_unittest(EmulatorTests + TestAArch64Emulator.cpp + LINK_LIBS + lldbCore + lldbSymbol + lldbTarget + lldbPluginInstructionARM64 + LINK_COMPONENTS + Support + ${LLVM_TARGETS_TO_BUILD}) +endif() diff --git a/gnu/llvm/lldb/unittests/Instruction/TestAArch64Emulator.cpp b/gnu/llvm/lldb/unittests/Instruction/TestAArch64Emulator.cpp new file mode 100644 index 00000000000..4506c200dee --- /dev/null +++ b/gnu/llvm/lldb/unittests/Instruction/TestAArch64Emulator.cpp @@ -0,0 +1,62 @@ +//===-- TestAArch64Emulator.cpp ------------------------------------------===// + +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" + +#include "lldb/Core/Address.h" +#include "lldb/Core/Disassembler.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Utility/ArchSpec.h" + +#include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h" + +using namespace lldb; +using namespace lldb_private; + +struct Arch64EmulatorTester : public EmulateInstructionARM64 { + Arch64EmulatorTester() + : EmulateInstructionARM64(ArchSpec("arm64-apple-ios")) {} + + static uint64_t AddWithCarry(uint32_t N, uint64_t x, uint64_t y, bool carry_in, + EmulateInstructionARM64::ProcState &proc_state) { + return EmulateInstructionARM64::AddWithCarry(N, x, y, carry_in, proc_state); + } +}; + +class TestAArch64Emulator : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + +protected: +}; + +void TestAArch64Emulator::SetUpTestCase() { + EmulateInstructionARM64::Initialize(); +} + +void TestAArch64Emulator::TearDownTestCase() { + EmulateInstructionARM64::Terminate(); +} + +TEST_F(TestAArch64Emulator, TestOverflow) { + EmulateInstructionARM64::ProcState pstate; + memset(&pstate, 0, sizeof(pstate)); + uint64_t ll_max = std::numeric_limits::max(); + Arch64EmulatorTester emu; + ASSERT_EQ(emu.AddWithCarry(64, ll_max, 0, 0, pstate), ll_max); + ASSERT_EQ(pstate.V, 0ULL); + ASSERT_EQ(pstate.C, 0ULL); + ASSERT_EQ(emu.AddWithCarry(64, ll_max, 1, 0, pstate), (uint64_t)(ll_max + 1)); + ASSERT_EQ(pstate.V, 1ULL); + ASSERT_EQ(pstate.C, 0ULL); + ASSERT_EQ(emu.AddWithCarry(64, ll_max, 0, 1, pstate), (uint64_t)(ll_max + 1)); + ASSERT_EQ(pstate.V, 1ULL); + ASSERT_EQ(pstate.C, 0ULL); +} diff --git a/gnu/llvm/lldb/unittests/Interpreter/TestCompletion.cpp b/gnu/llvm/lldb/unittests/Interpreter/TestCompletion.cpp index 838a7a9e54d..361b31e1068 100644 --- a/gnu/llvm/lldb/unittests/Interpreter/TestCompletion.cpp +++ b/gnu/llvm/lldb/unittests/Interpreter/TestCompletion.cpp @@ -1,4 +1,4 @@ -//===-- TestCompletion.cpp --------------------------------------*- C++ -*-===// +//===-- TestCompletion.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -233,7 +233,7 @@ TEST_F(CompletionTest, DirCompletionUsername) { Resolver.AddKnownUser("Lars", DirFooC); Resolver.AddKnownUser("Jason", DirFoo); Resolver.AddKnownUser("Larry", DirFooA); - std::string sep = path::get_separator(); + std::string sep = std::string(path::get_separator()); // Just resolving current user's home directory by itself should return the // directory. diff --git a/gnu/llvm/lldb/unittests/Interpreter/TestOptionArgParser.cpp b/gnu/llvm/lldb/unittests/Interpreter/TestOptionArgParser.cpp index 921a5461f65..e173febcfa8 100644 --- a/gnu/llvm/lldb/unittests/Interpreter/TestOptionArgParser.cpp +++ b/gnu/llvm/lldb/unittests/Interpreter/TestOptionArgParser.cpp @@ -1,4 +1,4 @@ -//===-- ArgsTest.cpp --------------------------------------------*- C++ -*-===// +//===-- ArgsTest.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Language/CLanguages/CLanguagesTest.cpp b/gnu/llvm/lldb/unittests/Language/CLanguages/CLanguagesTest.cpp new file mode 100644 index 00000000000..c68bd56c337 --- /dev/null +++ b/gnu/llvm/lldb/unittests/Language/CLanguages/CLanguagesTest.cpp @@ -0,0 +1,46 @@ +//===-- CLanguagesTest.cpp ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" +#include "Plugins/Language/ObjC/ObjCLanguage.h" +#include "Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h" +#include "TestingSupport/SubsystemRAII.h" +#include "lldb/lldb-enumerations.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using namespace lldb_private; + +/// Returns the name of the LLDB plugin for the given language or a null +/// ConstString if there is no fitting plugin. +static ConstString GetPluginName(lldb::LanguageType language) { + Language *language_plugin = Language::FindPlugin(language); + if (language_plugin) + return language_plugin->GetPluginName(); + return ConstString(); +} + +TEST(CLanguages, LookupCLanguagesByLanguageType) { + SubsystemRAII langs; + + // There is no plugin to find for C. + EXPECT_EQ(Language::FindPlugin(lldb::eLanguageTypeC), nullptr); + EXPECT_EQ(Language::FindPlugin(lldb::eLanguageTypeC89), nullptr); + EXPECT_EQ(Language::FindPlugin(lldb::eLanguageTypeC99), nullptr); + EXPECT_EQ(Language::FindPlugin(lldb::eLanguageTypeC11), nullptr); + + EXPECT_EQ(GetPluginName(lldb::eLanguageTypeC_plus_plus), "cplusplus"); + EXPECT_EQ(GetPluginName(lldb::eLanguageTypeC_plus_plus_03), "cplusplus"); + EXPECT_EQ(GetPluginName(lldb::eLanguageTypeC_plus_plus_11), "cplusplus"); + EXPECT_EQ(GetPluginName(lldb::eLanguageTypeC_plus_plus_14), "cplusplus"); + + EXPECT_EQ(GetPluginName(lldb::eLanguageTypeObjC), "objc"); + + EXPECT_EQ(GetPluginName(lldb::eLanguageTypeObjC_plus_plus), "objcplusplus"); +} diff --git a/gnu/llvm/lldb/unittests/Language/CLanguages/CMakeLists.txt b/gnu/llvm/lldb/unittests/Language/CLanguages/CMakeLists.txt new file mode 100644 index 00000000000..136140487da --- /dev/null +++ b/gnu/llvm/lldb/unittests/Language/CLanguages/CMakeLists.txt @@ -0,0 +1,8 @@ +add_lldb_unittest(LanguageCLanguagesTests + CLanguagesTest.cpp + + LINK_LIBS + lldbPluginCPlusPlusLanguage + lldbPluginObjCLanguage + lldbPluginObjCPlusPlusLanguage +) diff --git a/gnu/llvm/lldb/unittests/Language/CMakeLists.txt b/gnu/llvm/lldb/unittests/Language/CMakeLists.txt index 3a6e5de785e..3cca831956a 100644 --- a/gnu/llvm/lldb/unittests/Language/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/Language/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(CPlusPlus) +add_subdirectory(CLanguages) add_subdirectory(Highlighting) diff --git a/gnu/llvm/lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp b/gnu/llvm/lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp index deb6c7d54ea..e8e6a4c0da0 100644 --- a/gnu/llvm/lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp +++ b/gnu/llvm/lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp @@ -1,4 +1,4 @@ -//===-- CPlusPlusLanguageTest.cpp -------------------------------*- C++ -*-===// +//===-- CPlusPlusLanguageTest.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -140,12 +140,20 @@ TEST(CPlusPlusLanguage, ExtractContextAndIdentifier) { "std::vector>", "_M_emplace_back_aux"}, {"`anonymous namespace'::foo", "`anonymous namespace'", "foo"}, - {"`operator<'::`2'::B<0>::operator>", - "`operator<'::`2'::B<0>", + {"`operator<'::`2'::B<0>::operator>", "`operator<'::`2'::B<0>", "operator>"}, {"`anonymous namespace'::S::<<::__l2::Foo", - "`anonymous namespace'::S::<<::__l2", - "Foo"}}; + "`anonymous namespace'::S::<<::__l2", "Foo"}, + // These cases are idiosyncratic in how clang generates debug info for + // names when we have template parameters. They are not valid C++ names + // but if we fix this we need to support them for older compilers. + {"A::operator>", "A", "operator>"}, + {"operator>", "", "operator>"}, + {"A::operator<", "A", "operator<"}, + {"operator<", "", "operator<"}, + {"A::operator<<", "A", "operator<<"}, + {"operator<<", "", "operator<<"}, + }; llvm::StringRef context, basename; for (const auto &test : test_cases) { @@ -169,6 +177,12 @@ TEST(CPlusPlusLanguage, ExtractContextAndIdentifier) { "abc::", context, basename)); EXPECT_FALSE(CPlusPlusLanguage::ExtractContextAndIdentifier( "f>", context, basename)); + + // We expect these cases to fail until we turn on C++2a + EXPECT_FALSE(CPlusPlusLanguage::ExtractContextAndIdentifier( + "A::operator<=>", context, basename)); + EXPECT_FALSE(CPlusPlusLanguage::ExtractContextAndIdentifier( + "operator<=>", context, basename)); } static std::set FindAlternate(llvm::StringRef Name) { @@ -178,7 +192,7 @@ static std::set FindAlternate(llvm::StringRef Name) { EXPECT_EQ(Count, Results.size()); std::set Strings; for (ConstString Str : Results) - Strings.insert(Str.GetStringRef()); + Strings.insert(std::string(Str.GetStringRef())); return Strings; } diff --git a/gnu/llvm/lldb/unittests/Language/Highlighting/HighlighterTest.cpp b/gnu/llvm/lldb/unittests/Language/Highlighting/HighlighterTest.cpp index 5d155ffdd0d..7a2d7160e94 100644 --- a/gnu/llvm/lldb/unittests/Language/Highlighting/HighlighterTest.cpp +++ b/gnu/llvm/lldb/unittests/Language/Highlighting/HighlighterTest.cpp @@ -1,4 +1,4 @@ -//===-- HighlighterTest.cpp -------------------------------------*- C++ -*-===// +//===-- HighlighterTest.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -58,6 +58,8 @@ TEST_F(HighlighterTest, HighlighterSelectionPath) { EXPECT_EQ(getName("a/dir.CC"), "clang"); EXPECT_EQ(getName("/a/dir.hpp"), "clang"); EXPECT_EQ(getName("header.h"), "clang"); + EXPECT_EQ(getName("foo.m"), "clang"); + EXPECT_EQ(getName("foo.mm"), "clang"); EXPECT_EQ(getName(""), "none"); EXPECT_EQ(getName("/dev/null"), "none"); diff --git a/gnu/llvm/lldb/unittests/ObjectFile/Breakpad/BreakpadRecordsTest.cpp b/gnu/llvm/lldb/unittests/ObjectFile/Breakpad/BreakpadRecordsTest.cpp index b27d2b720a9..b621ad233e6 100644 --- a/gnu/llvm/lldb/unittests/ObjectFile/Breakpad/BreakpadRecordsTest.cpp +++ b/gnu/llvm/lldb/unittests/ObjectFile/Breakpad/BreakpadRecordsTest.cpp @@ -1,4 +1,4 @@ -//===-- BreakpadRecordsTest.cpp ---------------------------------*- C++ -*-===// +//===-- BreakpadRecordsTest.cpp -------------------------------------------===// // // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. diff --git a/gnu/llvm/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp b/gnu/llvm/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp index 01ad2ab4d19..9718ad3d27e 100644 --- a/gnu/llvm/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp +++ b/gnu/llvm/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp @@ -1,4 +1,4 @@ -//===-- TestObjectFileELF.cpp -----------------------------------*- C++ -*-===// +//===-- TestObjectFileELF.cpp ---------------------------------------------===// // // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -91,10 +91,7 @@ Symbols: )"); ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); - ModuleSpec spec{FileSpec(ExpectedFile->name())}; - spec.GetSymbolFileSpec().SetFile(ExpectedFile->name(), - FileSpec::Style::native); - auto module_sp = std::make_shared(spec); + auto module_sp = std::make_shared(ExpectedFile->moduleSpec()); SectionList *list = module_sp->GetSectionList(); ASSERT_NE(nullptr, list); @@ -156,7 +153,7 @@ TEST_F(ObjectFileELFTest, GetModuleSpecifications_EarlySectionHeaders) { ModuleSpec Spec; ASSERT_TRUE(Specs.GetModuleSpecAtIndex(0, Spec)) ; UUID Uuid; - Uuid.SetFromStringRef("1b8a73ac238390e32a7ff4ac8ebe4d6a41ecf5c9", 20); + Uuid.SetFromStringRef("1b8a73ac238390e32a7ff4ac8ebe4d6a41ecf5c9"); EXPECT_EQ(Spec.GetUUID(), Uuid); } @@ -212,10 +209,7 @@ Sections: )"); ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); - ModuleSpec spec{FileSpec(ExpectedFile->name())}; - spec.GetSymbolFileSpec().SetFile(ExpectedFile->name(), - FileSpec::Style::native); - auto module_sp = std::make_shared(spec); + auto module_sp = std::make_shared(ExpectedFile->moduleSpec()); auto entry_point_addr = module_sp->GetObjectFile()->GetEntryPointAddress(); ASSERT_TRUE(entry_point_addr.GetOffset() & 1); @@ -277,11 +271,8 @@ Sections: )"); ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); - ModuleSpec spec{FileSpec(ExpectedFile->name())}; - spec.GetSymbolFileSpec().SetFile(ExpectedFile->name(), - FileSpec::Style::native); - auto module_sp = std::make_shared(spec); + auto module_sp = std::make_shared(ExpectedFile->moduleSpec()); auto entry_point_addr = module_sp->GetObjectFile()->GetEntryPointAddress(); ASSERT_EQ(entry_point_addr.GetAddressClass(), AddressClass::eCode); -} \ No newline at end of file +} diff --git a/gnu/llvm/lldb/unittests/ObjectFile/PECOFF/TestPECallFrameInfo.cpp b/gnu/llvm/lldb/unittests/ObjectFile/PECOFF/TestPECallFrameInfo.cpp index 4e9182ec6a2..e842df59888 100644 --- a/gnu/llvm/lldb/unittests/ObjectFile/PECOFF/TestPECallFrameInfo.cpp +++ b/gnu/llvm/lldb/unittests/ObjectFile/PECOFF/TestPECallFrameInfo.cpp @@ -1,4 +1,4 @@ -//===-- TestPECallFrameInfo.cpp ------------------------------*- C++ -*-===// +//===-- TestPECallFrameInfo.cpp -------------------------------------------===// // // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -119,12 +119,12 @@ sections: # 03 60 UOP_PushNonVol(0) RSI(6), offset in prolog is 3 # 02 30 UOP_PushNonVol(0) RBX(3), offset in prolog is 2 # Corresponding prolog: -# 00 push rbx -# 02 push rsi -# 03 push rdi -# 04 push r14 -# 06 push r15 -# 08 sub rsp, 20h +# 00 push rbx +# 02 push rsi +# 03 push rdi +# 04 push r14 +# 06 push r15 +# 08 sub rsp, 20h # Unwind info at 0x2010: # 21 05 02 00 Has chained info, prolog size = 5, unwind codes size is 2 words, no frame register @@ -149,17 +149,17 @@ sections: # 08 C0 UOP_PushNonVol(0) R12(0xC), offset in prolog is 8 # 06 50 UOP_PushNonVol(0) RBP(5), offset in prolog is 6 # Corresponding prolog: -# 00 mov [rsp+8], rcx -# 05 push rbp -# 06 push r12 -# 08 push r13 -# 0A push r14 -# 0C push r15 -# 0E sub rsp, 2F0h -# 15 lea rbp, [rsp+30h] -# 1A mov [rbp+2F8h], rbx -# 21 mov [rbp+300h], rsi -# 28 mov [rbp+308h], rdi +# 00 mov [rsp+8], rcx +# 05 push rbp +# 06 push r12 +# 08 push r13 +# 0A push r14 +# 0C push r15 +# 0E sub rsp, 2F0h +# 15 lea rbp, [rsp+30h] +# 1A mov [rbp+2F8h], rbx +# 21 mov [rbp+300h], rsi +# 28 mov [rbp+308h], rdi - Name: .pdata Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] @@ -192,7 +192,7 @@ symbols: [] )"); ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); - ModuleSP module_sp = std::make_shared(ModuleSpec(FileSpec(ExpectedFile->name()))); + ModuleSP module_sp = std::make_shared(ExpectedFile->moduleSpec()); ObjectFile *object_file = module_sp->GetObjectFile(); ASSERT_NE(object_file, nullptr); diff --git a/gnu/llvm/lldb/unittests/Platform/Android/AdbClientTest.cpp b/gnu/llvm/lldb/unittests/Platform/Android/AdbClientTest.cpp new file mode 100644 index 00000000000..0808b96f69f --- /dev/null +++ b/gnu/llvm/lldb/unittests/Platform/Android/AdbClientTest.cpp @@ -0,0 +1,51 @@ +//===-- AdbClientTest.cpp -------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" +#include "Plugins/Platform/Android/AdbClient.h" +#include + +static void set_env(const char *var, const char *value) { +#ifdef _WIN32 + _putenv_s(var, value); +#else + setenv(var, value, true); +#endif +} + +using namespace lldb; +using namespace lldb_private; + +namespace lldb_private { +namespace platform_android { + +class AdbClientTest : public ::testing::Test { +public: + void SetUp() override { set_env("ANDROID_SERIAL", ""); } + + void TearDown() override { set_env("ANDROID_SERIAL", ""); } +}; + +TEST(AdbClientTest, CreateByDeviceId) { + AdbClient adb; + Status error = AdbClient::CreateByDeviceID("device1", adb); + EXPECT_TRUE(error.Success()); + EXPECT_EQ("device1", adb.GetDeviceID()); +} + +TEST(AdbClientTest, CreateByDeviceId_ByEnvVar) { + set_env("ANDROID_SERIAL", "device2"); + + AdbClient adb; + Status error = AdbClient::CreateByDeviceID("", adb); + EXPECT_TRUE(error.Success()); + EXPECT_EQ("device2", adb.GetDeviceID()); +} + +} // end namespace platform_android +} // end namespace lldb_private diff --git a/gnu/llvm/lldb/unittests/Platform/Android/CMakeLists.txt b/gnu/llvm/lldb/unittests/Platform/Android/CMakeLists.txt new file mode 100644 index 00000000000..489fdab7036 --- /dev/null +++ b/gnu/llvm/lldb/unittests/Platform/Android/CMakeLists.txt @@ -0,0 +1,8 @@ +include_directories(${LLDB_SOURCE_DIR}/source/Plugins/Platform/Android) + +add_lldb_unittest(AdbClientTests + AdbClientTest.cpp + + LINK_LIBS + lldbPluginPlatformAndroid + ) diff --git a/gnu/llvm/lldb/unittests/Platform/CMakeLists.txt b/gnu/llvm/lldb/unittests/Platform/CMakeLists.txt index 3362ca08d60..eb7f0a6ca3c 100644 --- a/gnu/llvm/lldb/unittests/Platform/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/Platform/CMakeLists.txt @@ -6,3 +6,5 @@ add_lldb_unittest(LLDBPlatformTests LINK_COMPONENTS Support ) + +add_subdirectory(Android) diff --git a/gnu/llvm/lldb/unittests/Platform/PlatformDarwinTest.cpp b/gnu/llvm/lldb/unittests/Platform/PlatformDarwinTest.cpp index 476848d6881..285dc2ee3db 100644 --- a/gnu/llvm/lldb/unittests/Platform/PlatformDarwinTest.cpp +++ b/gnu/llvm/lldb/unittests/Platform/PlatformDarwinTest.cpp @@ -1,4 +1,4 @@ -//===-- PlatformDarwinTest.cpp ----------------------------------*- C++ -*-===// +//===-- PlatformDarwinTest.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,10 +18,8 @@ using namespace lldb; using namespace lldb_private; struct PlatformDarwinTester : public PlatformDarwin { - static bool SDKSupportsModules(SDKType desired_type, - const lldb_private::FileSpec &sdk_path) { - return PlatformDarwin::SDKSupportsModules(desired_type, sdk_path); - } +public: + using PlatformDarwin::FindComponentInPath; }; TEST(PlatformDarwinTest, TestParseVersionBuildDir) { @@ -50,22 +48,21 @@ TEST(PlatformDarwinTest, TestParseVersionBuildDir) { std::tie(V, D) = PlatformDarwin::ParseVersionBuildDir("3.4.5"); EXPECT_EQ(llvm::VersionTuple(3, 4, 5), V); +} + +TEST(PlatformDarwinTest, FindComponentInPath) { + EXPECT_EQ("/path/to/foo", + PlatformDarwinTester::FindComponentInPath("/path/to/foo/", "foo")); + + EXPECT_EQ("/path/to/foo", + PlatformDarwinTester::FindComponentInPath("/path/to/foo", "foo")); + + EXPECT_EQ("/path/to/foobar", PlatformDarwinTester::FindComponentInPath( + "/path/to/foobar", "foo")); + + EXPECT_EQ("/path/to/foobar", PlatformDarwinTester::FindComponentInPath( + "/path/to/foobar", "bar")); - std::string base = "/Applications/Xcode.app/Contents/Developer/Platforms/"; - EXPECT_TRUE(PlatformDarwinTester::SDKSupportsModules( - PlatformDarwin::SDKType::iPhoneSimulator, - FileSpec( - base + - "iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator12.0.sdk"))); - EXPECT_FALSE(PlatformDarwinTester::SDKSupportsModules( - PlatformDarwin::SDKType::iPhoneSimulator, - FileSpec( - base + - "iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.2.sdk"))); - EXPECT_TRUE(PlatformDarwinTester::SDKSupportsModules( - PlatformDarwin::SDKType::MacOSX, - FileSpec(base + "MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk"))); - EXPECT_FALSE(PlatformDarwinTester::SDKSupportsModules( - PlatformDarwin::SDKType::MacOSX, - FileSpec(base + "MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk"))); + EXPECT_EQ("", + PlatformDarwinTester::FindComponentInPath("/path/to/foo", "bar")); } diff --git a/gnu/llvm/lldb/unittests/Process/CMakeLists.txt b/gnu/llvm/lldb/unittests/Process/CMakeLists.txt index a4045692eb5..e068908d09f 100644 --- a/gnu/llvm/lldb/unittests/Process/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/Process/CMakeLists.txt @@ -4,3 +4,17 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android") add_subdirectory(POSIX) endif() add_subdirectory(minidump) + +add_lldb_unittest(ProcessEventDataTests + ProcessEventDataTest.cpp + + LINK_LIBS + lldbCore + lldbHost + lldbTarget + lldbSymbol + lldbUtility + lldbUtilityHelpers + lldbInterpreter + lldbPluginPlatformMacOSX + ) diff --git a/gnu/llvm/lldb/unittests/Process/Linux/CMakeLists.txt b/gnu/llvm/lldb/unittests/Process/Linux/CMakeLists.txt index 3b55b5c8430..31e9a57a4e4 100644 --- a/gnu/llvm/lldb/unittests/Process/Linux/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/Process/Linux/CMakeLists.txt @@ -1,6 +1,6 @@ include_directories(${LLDB_SOURCE_DIR}/source/Plugins/Process/Linux) -add_lldb_unittest(ProcessorTraceTest +add_lldb_unittest(ProcessorTraceTests ProcessorTraceTest.cpp LINK_LIBS diff --git a/gnu/llvm/lldb/unittests/Process/Linux/ProcessorTraceTest.cpp b/gnu/llvm/lldb/unittests/Process/Linux/ProcessorTraceTest.cpp index d3165a1db9c..3615135cccb 100644 --- a/gnu/llvm/lldb/unittests/Process/Linux/ProcessorTraceTest.cpp +++ b/gnu/llvm/lldb/unittests/Process/Linux/ProcessorTraceTest.cpp @@ -1,4 +1,4 @@ -//===-- ProcessorTraceMonitorTest.cpp ------------------------- -*- C++ -*-===// +//===-- ProcessorTraceMonitorTest.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -31,7 +31,7 @@ TEST(CyclicBuffer, EdgeCases) { uint8_t cyclic_buffer[6] = {'l', 'i', 'c', 'c', 'y', 'c'}; // We will always leave the last bytes untouched - // so that string comparisions work. + // so that string comparisons work. char smaller_buffer[4] = {}; // empty buffer to read into @@ -70,7 +70,7 @@ TEST(CyclicBuffer, EqualSizeBuffer) { char cyclic[] = "cyclic"; for (size_t i = 0; i < sizeof(cyclic); i++) { // We will always leave the last bytes untouched - // so that string comparisions work. + // so that string comparisons work. char equal_size_buffer[7] = {}; bytes_read = ReadCylicBufferWrapper(equal_size_buffer, sizeof(cyclic_buffer), @@ -85,7 +85,7 @@ TEST(CyclicBuffer, SmallerSizeBuffer) { uint8_t cyclic_buffer[6] = {'l', 'i', 'c', 'c', 'y', 'c'}; // We will always leave the last bytes untouched - // so that string comparisions work. + // so that string comparisons work. char smaller_buffer[4] = {}; bytes_read = ReadCylicBufferWrapper(smaller_buffer, (sizeof(smaller_buffer) - 1), @@ -136,7 +136,7 @@ TEST(CyclicBuffer, BiggerSizeBuffer) { char cyclic[] = "cyclic"; for (size_t i = 0; i < sizeof(cyclic); i++) { // We will always leave the last bytes untouched - // so that string comparisions work. + // so that string comparisons work. char bigger_buffer[10] = {}; bytes_read = ReadCylicBufferWrapper(bigger_buffer, (sizeof(bigger_buffer) - 1), diff --git a/gnu/llvm/lldb/unittests/Process/POSIX/CMakeLists.txt b/gnu/llvm/lldb/unittests/Process/POSIX/CMakeLists.txt index 53318d908da..eabfb58d46f 100644 --- a/gnu/llvm/lldb/unittests/Process/POSIX/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/Process/POSIX/CMakeLists.txt @@ -1,6 +1,6 @@ include_directories(${LLDB_SOURCE_DIR}/source/Plugins/Process/POSIX) -add_lldb_unittest(ProcessPOSIXTest +add_lldb_unittest(ProcessPOSIXTests NativeProcessELFTest.cpp LINK_LIBS diff --git a/gnu/llvm/lldb/unittests/Process/POSIX/NativeProcessELFTest.cpp b/gnu/llvm/lldb/unittests/Process/POSIX/NativeProcessELFTest.cpp index 9e91464c441..19163aeac69 100644 --- a/gnu/llvm/lldb/unittests/Process/POSIX/NativeProcessELFTest.cpp +++ b/gnu/llvm/lldb/unittests/Process/POSIX/NativeProcessELFTest.cpp @@ -1,4 +1,4 @@ -//===-- NativeProcessELFTest.cpp --------------------------------*- C++ -*-===// +//===-- NativeProcessELFTest.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Process/ProcessEventDataTest.cpp b/gnu/llvm/lldb/unittests/Process/ProcessEventDataTest.cpp new file mode 100644 index 00000000000..0f032a78611 --- /dev/null +++ b/gnu/llvm/lldb/unittests/Process/ProcessEventDataTest.cpp @@ -0,0 +1,256 @@ +//===-- ProcessEventDataTest.cpp ------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "Plugins/Platform/MacOSX/PlatformMacOSX.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/StopInfo.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/Event.h" +#include "lldb/Utility/Reproducer.h" +#include "gtest/gtest.h" + +using namespace lldb_private; +using namespace lldb_private::repro; +using namespace lldb; + +namespace { +class ProcessEventDataTest : public ::testing::Test { +public: + void SetUp() override { + llvm::cantFail(Reproducer::Initialize(ReproducerMode::Off, llvm::None)); + FileSystem::Initialize(); + HostInfo::Initialize(); + PlatformMacOSX::Initialize(); + } + void TearDown() override { + PlatformMacOSX::Terminate(); + HostInfo::Terminate(); + FileSystem::Terminate(); + Reproducer::Terminate(); + } +}; + +class DummyProcess : public Process { +public: + using Process::Process; + + virtual bool CanDebug(lldb::TargetSP target, bool plugin_specified_by_name) { + return true; + } + virtual Status DoDestroy() { return {}; } + virtual void RefreshStateAfterStop() {} + virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, + Status &error) { + return 0; + } + virtual bool UpdateThreadList(ThreadList &old_thread_list, + ThreadList &new_thread_list) { + return false; + } + virtual ConstString GetPluginName() { return ConstString("Dummy"); } + virtual uint32_t GetPluginVersion() { return 0; } + + ProcessModID &GetModIDNonConstRef() { return m_mod_id; } +}; + +class DummyThread : public Thread { +public: + using Thread::Thread; + + ~DummyThread() override { DestroyThread(); } + + void RefreshStateAfterStop() override {} + + lldb::RegisterContextSP GetRegisterContext() override { return nullptr; } + + lldb::RegisterContextSP + CreateRegisterContextForFrame(StackFrame *frame) override { + return nullptr; + } + + bool CalculateStopInfo() override { return false; } +}; + +class DummyStopInfo : public StopInfo { +public: + DummyStopInfo(Thread &thread, uint64_t value) + : StopInfo(thread, value), m_should_stop(true), + m_stop_reason(eStopReasonBreakpoint) {} + + bool ShouldStop(Event *event_ptr) override { return m_should_stop; } + + StopReason GetStopReason() const override { return m_stop_reason; } + + bool m_should_stop; + StopReason m_stop_reason; +}; + +class DummyProcessEventData : public Process::ProcessEventData { +public: + DummyProcessEventData(ProcessSP &process_sp, StateType state) + : ProcessEventData(process_sp, state), m_should_stop_hit_count(0) {} + bool ShouldStop(Event *event_ptr, bool &found_valid_stopinfo) override { + m_should_stop_hit_count++; + return false; + } + + int m_should_stop_hit_count; +}; +} // namespace + +typedef std::shared_ptr ProcessEventDataSP; +typedef std::shared_ptr EventSP; + +TargetSP CreateTarget(DebuggerSP &debugger_sp, ArchSpec &arch) { + Status error; + PlatformSP platform_sp; + TargetSP target_sp; + error = debugger_sp->GetTargetList().CreateTarget( + *debugger_sp, "", arch, eLoadDependentsNo, platform_sp, target_sp); + + if (target_sp) { + debugger_sp->GetTargetList().SetSelectedTarget(target_sp.get()); + } + + return target_sp; +} + +ThreadSP CreateThread(ProcessSP &process_sp, bool should_stop, + bool has_valid_stopinfo) { + ThreadSP thread_sp = std::make_shared(*process_sp.get(), 0); + if (thread_sp == nullptr) { + return nullptr; + } + + if (has_valid_stopinfo) { + StopInfoSP stopinfo_sp = + std::make_shared(*thread_sp.get(), 0); + static_cast(stopinfo_sp.get())->m_should_stop = + should_stop; + if (stopinfo_sp == nullptr) { + return nullptr; + } + + thread_sp->SetStopInfo(stopinfo_sp); + } + + process_sp->GetThreadList().AddThread(thread_sp); + + return thread_sp; +} + +TEST_F(ProcessEventDataTest, DoOnRemoval) { + ArchSpec arch("x86_64-apple-macosx-"); + + Platform::SetHostPlatform(PlatformMacOSX::CreateInstance(true, &arch)); + + DebuggerSP debugger_sp = Debugger::CreateInstance(); + ASSERT_TRUE(debugger_sp); + + TargetSP target_sp = CreateTarget(debugger_sp, arch); + ASSERT_TRUE(target_sp); + + ListenerSP listener_sp(Listener::MakeListener("dummy")); + ProcessSP process_sp = std::make_shared(target_sp, listener_sp); + ASSERT_TRUE(process_sp); + + /* + Should hit ShouldStop if state is eStateStopped + */ + ProcessEventDataSP event_data_sp = + std::make_shared(process_sp, eStateStopped); + EventSP event_sp = std::make_shared(0, event_data_sp); + event_data_sp->SetUpdateStateOnRemoval(event_sp.get()); + event_data_sp->DoOnRemoval(event_sp.get()); + bool result = static_cast(event_data_sp.get()) + ->m_should_stop_hit_count == 1; + ASSERT_TRUE(result); + + /* + Should not hit ShouldStop if state is not eStateStopped + */ + event_data_sp = + std::make_shared(process_sp, eStateStepping); + event_sp = std::make_shared(0, event_data_sp); + event_data_sp->SetUpdateStateOnRemoval(event_sp.get()); + event_data_sp->DoOnRemoval(event_sp.get()); + result = static_cast(event_data_sp.get()) + ->m_should_stop_hit_count == 0; + ASSERT_TRUE(result); +} + +TEST_F(ProcessEventDataTest, ShouldStop) { + ArchSpec arch("x86_64-apple-macosx-"); + + Platform::SetHostPlatform(PlatformMacOSX::CreateInstance(true, &arch)); + + DebuggerSP debugger_sp = Debugger::CreateInstance(); + ASSERT_TRUE(debugger_sp); + + TargetSP target_sp = CreateTarget(debugger_sp, arch); + ASSERT_TRUE(target_sp); + + ListenerSP listener_sp(Listener::MakeListener("dummy")); + ProcessSP process_sp = std::make_shared(target_sp, listener_sp); + ASSERT_TRUE(process_sp); + + // wants to stop and has valid StopInfo + ThreadSP thread_sp = CreateThread(process_sp, true, true); + + ProcessEventDataSP event_data_sp = + std::make_shared(process_sp, eStateStopped); + EventSP event_sp = std::make_shared(0, event_data_sp); + /* + Should stop if thread has valid StopInfo and not suspended + */ + bool found_valid_stopinfo = false; + bool should_stop = + event_data_sp->ShouldStop(event_sp.get(), found_valid_stopinfo); + ASSERT_TRUE(should_stop == true && found_valid_stopinfo == true); + + /* + Should not stop if thread has valid StopInfo but was suspended + */ + found_valid_stopinfo = false; + thread_sp->SetResumeState(eStateSuspended); + should_stop = event_data_sp->ShouldStop(event_sp.get(), found_valid_stopinfo); + ASSERT_TRUE(should_stop == false && found_valid_stopinfo == false); + + /* + Should not stop, thread-reason of stop does not want to stop in its + callback and suspended thread who wants to (from previous stop) + must be ignored. + */ + event_data_sp = + std::make_shared(process_sp, eStateStopped); + event_sp = std::make_shared(0, event_data_sp); + process_sp->GetThreadList().Clear(); + + for (int i = 0; i < 6; i++) { + if (i == 2) { + // Does not want to stop but has valid StopInfo + thread_sp = CreateThread(process_sp, false, true); + } else if (i == 5) { + // Wants to stop and has valid StopInfo + thread_sp = CreateThread(process_sp, true, true); + thread_sp->SetResumeState(eStateSuspended); + } else { + // Thread has no StopInfo i.e is not the reason of stop + thread_sp = CreateThread(process_sp, false, false); + } + } + ASSERT_TRUE(process_sp->GetThreadList().GetSize() == 6); + + found_valid_stopinfo = false; + should_stop = event_data_sp->ShouldStop(event_sp.get(), found_valid_stopinfo); + ASSERT_TRUE(should_stop == false && found_valid_stopinfo == true); +} diff --git a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp b/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp index d56e9cf81bc..5bbcfdff473 100644 --- a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp +++ b/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteClientBaseTest.cpp -----------------------------*- C++ -*-===// +//===-- GDBRemoteClientBaseTest.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -34,7 +34,7 @@ struct MockDelegate : public GDBRemoteClientBase::ContinueDelegate { void HandleStopReply() override { ++stop_reply_called; } void HandleAsyncStructuredDataPacket(llvm::StringRef data) override { - structured_data_packets.push_back(data); + structured_data_packets.push_back(std::string(data)); } }; diff --git a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp b/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp index e52f3782437..6fba1cbb53b 100644 --- a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp +++ b/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunicationClientTest.cpp --------------------*- C++ -*-===// +//===-- GDBRemoteCommunicationClientTest.cpp ------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -47,7 +47,7 @@ void HandlePacket(MockServer &server, StringRef response) { StringExtractorGDBRemote request; ASSERT_EQ(PacketResult::Success, server.GetPacket(request)); - ASSERT_THAT(request.GetStringRef(), expected); + ASSERT_THAT(std::string(request.GetStringRef()), expected); ASSERT_EQ(PacketResult::Success, server.SendPacket(response)); } @@ -288,7 +288,7 @@ TEST_F(GDBRemoteCommunicationClientTest, TestPacketSpeedJSON) { server_thread.join(); GTEST_LOG_(INFO) << "Formatted output: " << ss.GetData(); - auto object_sp = StructuredData::ParseJSON(ss.GetString()); + auto object_sp = StructuredData::ParseJSON(std::string(ss.GetString())); ASSERT_TRUE(bool(object_sp)); auto dict_sp = object_sp->GetAsDictionary(); ASSERT_TRUE(bool(dict_sp)); @@ -552,3 +552,29 @@ TEST_F(GDBRemoteCommunicationClientTest, SendGetTraceConfigPacket) { incorrect_custom_params2); ASSERT_FALSE(result4.get().Success()); } + +TEST_F(GDBRemoteCommunicationClientTest, GetQOffsets) { + const auto &GetQOffsets = [&](llvm::StringRef response) { + std::future> result = std::async( + std::launch::async, [&] { return client.GetQOffsets(); }); + + HandlePacket(server, "qOffsets", response); + return result.get(); + }; + EXPECT_EQ((QOffsets{false, {0x1234, 0x1234}}), + GetQOffsets("Text=1234;Data=1234")); + EXPECT_EQ((QOffsets{false, {0x1234, 0x1234, 0x1234}}), + GetQOffsets("Text=1234;Data=1234;Bss=1234")); + EXPECT_EQ((QOffsets{true, {0x1234}}), GetQOffsets("TextSeg=1234")); + EXPECT_EQ((QOffsets{true, {0x1234, 0x2345}}), + GetQOffsets("TextSeg=1234;DataSeg=2345")); + + EXPECT_EQ(llvm::None, GetQOffsets("E05")); + EXPECT_EQ(llvm::None, GetQOffsets("Text=bogus")); + EXPECT_EQ(llvm::None, GetQOffsets("Text=1234")); + EXPECT_EQ(llvm::None, GetQOffsets("Text=1234;Data=1234;")); + EXPECT_EQ(llvm::None, GetQOffsets("Text=1234;Data=1234;Bss=1234;")); + EXPECT_EQ(llvm::None, GetQOffsets("TEXTSEG=1234")); + EXPECT_EQ(llvm::None, GetQOffsets("TextSeg=0x1234")); + EXPECT_EQ(llvm::None, GetQOffsets("TextSeg=12345678123456789")); +} diff --git a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationServerTest.cpp b/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationServerTest.cpp index a73f7b462a8..4c4916e3668 100644 --- a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationServerTest.cpp +++ b/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationServerTest.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunicationServerTest.cpp --------------------*- C++ -*-===// +//===-- GDBRemoteCommunicationServerTest.cpp ------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationTest.cpp b/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationTest.cpp index 2039b9e6d8d..3150477c4e9 100644 --- a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationTest.cpp +++ b/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationTest.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunicationTest.cpp --------------------------*- C++ -*-===// +//===-- GDBRemoteCommunicationTest.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp b/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp index 92e16d981fe..6718d0c1ed9 100644 --- a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp +++ b/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteTestUtils.cpp ----------------------------------*- C++ -*-===// +//===-- GDBRemoteTestUtils.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.h b/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.h index 53e94a39e8b..27ce6b9b26f 100644 --- a/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.h +++ b/gnu/llvm/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.h @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -#ifndef lldb_unittests_Process_gdb_remote_GDBRemoteTestUtils_h -#define lldb_unittests_Process_gdb_remote_GDBRemoteTestUtils_h +#ifndef LLDB_UNITTESTS_PROCESS_GDB_REMOTE_GDBREMOTETESTUTILS_H +#define LLDB_UNITTESTS_PROCESS_GDB_REMOTE_GDBREMOTETESTUTILS_H #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -77,7 +77,7 @@ public: class MockServerWithMockConnection : public MockServer { public: MockServerWithMockConnection() : MockServer() { - SetConnection(new MockConnection(m_packets)); + SetConnection(std::make_unique(m_packets)); } llvm::ArrayRef GetPackets() { return m_packets; }; @@ -88,4 +88,4 @@ public: } // namespace process_gdb_remote } // namespace lldb_private -#endif // lldb_unittests_Process_gdb_remote_GDBRemoteTestUtils_h +#endif // LLDB_UNITTESTS_PROCESS_GDB_REMOTE_GDBREMOTETESTUTILS_H diff --git a/gnu/llvm/lldb/unittests/Process/minidump/MinidumpParserTest.cpp b/gnu/llvm/lldb/unittests/Process/minidump/MinidumpParserTest.cpp index 94bb1b395f0..8f4b45b056b 100644 --- a/gnu/llvm/lldb/unittests/Process/minidump/MinidumpParserTest.cpp +++ b/gnu/llvm/lldb/unittests/Process/minidump/MinidumpParserTest.cpp @@ -1,4 +1,4 @@ -//===-- MinidumpTypesTest.cpp -----------------------------------*- C++ -*-===// +//===-- MinidumpTypesTest.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Process/minidump/RegisterContextMinidumpTest.cpp b/gnu/llvm/lldb/unittests/Process/minidump/RegisterContextMinidumpTest.cpp index 265da63d33a..b7d25b2d4f0 100644 --- a/gnu/llvm/lldb/unittests/Process/minidump/RegisterContextMinidumpTest.cpp +++ b/gnu/llvm/lldb/unittests/Process/minidump/RegisterContextMinidumpTest.cpp @@ -1,4 +1,4 @@ -//===-- RegisterContextMinidumpTest.cpp -------------------------*- C++ -*-===// +//===-- RegisterContextMinidumpTest.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/ScriptInterpreter/Lua/ScriptInterpreterTests.cpp b/gnu/llvm/lldb/unittests/ScriptInterpreter/Lua/ScriptInterpreterTests.cpp index b5324f6ba9a..3b7fbebdd98 100644 --- a/gnu/llvm/lldb/unittests/ScriptInterpreter/Lua/ScriptInterpreterTests.cpp +++ b/gnu/llvm/lldb/unittests/ScriptInterpreter/Lua/ScriptInterpreterTests.cpp @@ -54,7 +54,7 @@ TEST_F(ScriptInterpreterTest, ExecuteOneLine) { ASSERT_TRUE(debugger_sp); ScriptInterpreterLua script_interpreter(*debugger_sp); - CommandReturnObject result; + CommandReturnObject result(/*colors*/ false); EXPECT_TRUE(script_interpreter.ExecuteOneLine("foo = 1", &result)); EXPECT_FALSE(script_interpreter.ExecuteOneLine("nil = foo", &result)); EXPECT_TRUE(result.GetErrorData().startswith( diff --git a/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/CMakeLists.txt b/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/CMakeLists.txt index 471f4c6dbc3..913bd629526 100644 --- a/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/CMakeLists.txt @@ -8,4 +8,8 @@ add_lldb_unittest(ScriptInterpreterPythonTests LLVMTestingSupport LINK_COMPONENTS Support - ) \ No newline at end of file + ) + +if(PYTHON_RPATH) + set_property(TARGET ScriptInterpreterPythonTests APPEND PROPERTY BUILD_RPATH "${PYTHON_RPATH}") +endif() \ No newline at end of file diff --git a/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp b/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp index ec5d02ee04d..75a1f5e67d3 100644 --- a/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp +++ b/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp @@ -1,4 +1,4 @@ -//===-- PythonDataObjectsTests.cpp ------------------------------*- C++ -*-===// +//===-- PythonDataObjectsTests.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -123,13 +123,11 @@ TEST_F(PythonDataObjectsTest, TestInstanceNameResolutionNoDot) { EXPECT_TRUE(major_version_field.IsAllocated()); EXPECT_TRUE(minor_version_field.IsAllocated()); - PythonInteger major_version_value = - major_version_field.AsType(); - PythonInteger minor_version_value = - minor_version_field.AsType(); + auto major_version_value = As(major_version_field); + auto minor_version_value = As(minor_version_field); - EXPECT_EQ(PY_MAJOR_VERSION, major_version_value.GetInteger()); - EXPECT_EQ(PY_MINOR_VERSION, minor_version_value.GetInteger()); + EXPECT_THAT_EXPECTED(major_version_value, llvm::HasValue(PY_MAJOR_VERSION)); + EXPECT_THAT_EXPECTED(minor_version_value, llvm::HasValue(PY_MINOR_VERSION)); } TEST_F(PythonDataObjectsTest, TestGlobalNameResolutionWithDot) { @@ -137,16 +135,14 @@ TEST_F(PythonDataObjectsTest, TestGlobalNameResolutionWithDot) { EXPECT_TRUE(sys_path.IsAllocated()); EXPECT_TRUE(PythonList::Check(sys_path.get())); - PythonInteger version_major = - m_main_module.ResolveName("sys.version_info.major") - .AsType(); - PythonInteger version_minor = - m_main_module.ResolveName("sys.version_info.minor") - .AsType(); - EXPECT_TRUE(version_major.IsAllocated()); - EXPECT_TRUE(version_minor.IsAllocated()); - EXPECT_EQ(PY_MAJOR_VERSION, version_major.GetInteger()); - EXPECT_EQ(PY_MINOR_VERSION, version_minor.GetInteger()); + auto version_major = + As(m_main_module.ResolveName("sys.version_info.major")); + + auto version_minor = + As(m_main_module.ResolveName("sys.version_info.minor")); + + EXPECT_THAT_EXPECTED(version_major, llvm::HasValue(PY_MAJOR_VERSION)); + EXPECT_THAT_EXPECTED(version_minor, llvm::HasValue(PY_MINOR_VERSION)); } TEST_F(PythonDataObjectsTest, TestDictionaryResolutionWithDot) { @@ -155,14 +151,14 @@ TEST_F(PythonDataObjectsTest, TestDictionaryResolutionWithDot) { dict.SetItemForKey(PythonString("sys"), m_sys_module); // Now use that dictionary to resolve `sys.version_info.major` - PythonInteger version_major = - PythonObject::ResolveNameWithDictionary("sys.version_info.major", dict) - .AsType(); - PythonInteger version_minor = - PythonObject::ResolveNameWithDictionary("sys.version_info.minor", dict) - .AsType(); - EXPECT_EQ(PY_MAJOR_VERSION, version_major.GetInteger()); - EXPECT_EQ(PY_MINOR_VERSION, version_minor.GetInteger()); + auto version_major = As( + PythonObject::ResolveNameWithDictionary("sys.version_info.major", dict)); + + auto version_minor = As( + PythonObject::ResolveNameWithDictionary("sys.version_info.minor", dict)); + + EXPECT_THAT_EXPECTED(version_major, llvm::HasValue(PY_MAJOR_VERSION)); + EXPECT_THAT_EXPECTED(version_minor, llvm::HasValue(PY_MINOR_VERSION)); } TEST_F(PythonDataObjectsTest, TestPythonInteger) { @@ -176,7 +172,8 @@ TEST_F(PythonDataObjectsTest, TestPythonInteger) { PythonInteger python_int(PyRefType::Owned, py_int); EXPECT_EQ(PyObjectType::Integer, python_int.GetObjectType()); - EXPECT_EQ(12, python_int.GetInteger()); + auto python_int_value = As(python_int); + EXPECT_THAT_EXPECTED(python_int_value, llvm::HasValue(12)); #endif // Verify that `PythonInteger` works correctly when given a PyLong object. @@ -187,12 +184,14 @@ TEST_F(PythonDataObjectsTest, TestPythonInteger) { // Verify that you can reset the value and that it is reflected properly. python_long.SetInteger(40); - EXPECT_EQ(40, python_long.GetInteger()); + auto e = As(python_long); + EXPECT_THAT_EXPECTED(e, llvm::HasValue(40)); // Test that creating a `PythonInteger` object works correctly with the // int constructor. PythonInteger constructed_int(7); - EXPECT_EQ(7, constructed_int.GetInteger()); + auto value = As(constructed_int); + EXPECT_THAT_EXPECTED(value, llvm::HasValue(7)); } TEST_F(PythonDataObjectsTest, TestPythonBoolean) { @@ -339,7 +338,8 @@ TEST_F(PythonDataObjectsTest, TestPythonListValueEquality) { PythonInteger chk_int(PyRefType::Borrowed, chk_value1.get()); PythonString chk_str(PyRefType::Borrowed, chk_value2.get()); - EXPECT_EQ(long_value0, chk_int.GetInteger()); + auto chkint = As(chk_value1); + ASSERT_THAT_EXPECTED(chkint, llvm::HasValue(long_value0)); EXPECT_EQ(string_value1, chk_str.GetString()); } @@ -367,7 +367,8 @@ TEST_F(PythonDataObjectsTest, TestPythonListManipulation) { PythonInteger chk_int(PyRefType::Borrowed, chk_value1.get()); PythonString chk_str(PyRefType::Borrowed, chk_value2.get()); - EXPECT_EQ(long_value0, chk_int.GetInteger()); + auto e = As(chk_int); + EXPECT_THAT_EXPECTED(e, llvm::HasValue(long_value0)); EXPECT_EQ(string_value1, chk_str.GetString()); } @@ -487,10 +488,10 @@ TEST_F(PythonDataObjectsTest, TestPythonDictionaryValueEquality) { EXPECT_TRUE(PythonInteger::Check(chk_value1.get())); EXPECT_TRUE(PythonString::Check(chk_value2.get())); - PythonInteger chk_int(PyRefType::Borrowed, chk_value1.get()); PythonString chk_str(PyRefType::Borrowed, chk_value2.get()); + auto chkint = As(chk_value1); - EXPECT_EQ(value_0, chk_int.GetInteger()); + EXPECT_THAT_EXPECTED(chkint, llvm::HasValue(value_0)); EXPECT_EQ(value_1, chk_str.GetString()); } @@ -524,10 +525,10 @@ TEST_F(PythonDataObjectsTest, TestPythonDictionaryManipulation) { EXPECT_TRUE(PythonInteger::Check(chk_value1.get())); EXPECT_TRUE(PythonString::Check(chk_value2.get())); - PythonInteger chk_int(PyRefType::Borrowed, chk_value1.get()); + auto chkint = As(chk_value1); PythonString chk_str(PyRefType::Borrowed, chk_value2.get()); - EXPECT_EQ(value_0, chk_int.GetInteger()); + EXPECT_THAT_EXPECTED(chkint, llvm::HasValue(value_0)); EXPECT_EQ(value_1, chk_str.GetString()); } @@ -594,10 +595,9 @@ TEST_F(PythonDataObjectsTest, TestObjectAttributes) { EXPECT_TRUE(py_int.HasAttribute("numerator")); EXPECT_FALSE(py_int.HasAttribute("this_should_not_exist")); - PythonInteger numerator_attr = - py_int.GetAttributeValue("numerator").AsType(); - EXPECT_TRUE(numerator_attr.IsAllocated()); - EXPECT_EQ(42, numerator_attr.GetInteger()); + auto numerator_attr = As(py_int.GetAttributeValue("numerator")); + + EXPECT_THAT_EXPECTED(numerator_attr, llvm::HasValue(42)); } TEST_F(PythonDataObjectsTest, TestExtractingUInt64ThroughStructuredData) { diff --git a/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp b/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp index 8bc510bd989..f661835d191 100644 --- a/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp +++ b/gnu/llvm/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp @@ -1,4 +1,4 @@ -//===-- PythonTestSuite.cpp -------------------------------------*- C++ -*-===// +//===-- PythonTestSuite.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,9 +8,10 @@ #include "gtest/gtest.h" +#include "Plugins/ScriptInterpreter/Python/lldb-python.h" + #include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h" #include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h" -#include "Plugins/ScriptInterpreter/Python/lldb-python.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" diff --git a/gnu/llvm/lldb/unittests/Signals/UnixSignalsTest.cpp b/gnu/llvm/lldb/unittests/Signals/UnixSignalsTest.cpp index 709b100c291..1a53f0a2495 100644 --- a/gnu/llvm/lldb/unittests/Signals/UnixSignalsTest.cpp +++ b/gnu/llvm/lldb/unittests/Signals/UnixSignalsTest.cpp @@ -1,4 +1,4 @@ -//===-- UnixSignalsTest.cpp -------------------------------------*- C++ -*-===// +//===-- UnixSignalsTest.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Symbol/CMakeLists.txt b/gnu/llvm/lldb/unittests/Symbol/CMakeLists.txt index 02875b8b53c..76c7b645f27 100644 --- a/gnu/llvm/lldb/unittests/Symbol/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/Symbol/CMakeLists.txt @@ -1,7 +1,7 @@ add_lldb_unittest(SymbolTests LocateSymbolFileTest.cpp PostfixExpressionTest.cpp - TestClangASTContext.cpp + TestTypeSystemClang.cpp TestClangASTImporter.cpp TestDWARFCallFrameInfo.cpp TestType.cpp @@ -15,6 +15,7 @@ add_lldb_unittest(SymbolTests lldbPluginObjectFileMachO lldbPluginSymbolFileDWARF lldbPluginSymbolFileSymtab + lldbPluginTypeSystemClang LLVMTestingSupport ) diff --git a/gnu/llvm/lldb/unittests/Symbol/Inputs/inlined-functions.yaml b/gnu/llvm/lldb/unittests/Symbol/Inputs/inlined-functions.yaml index 16e437c48bf..8ce92115a0b 100644 --- a/gnu/llvm/lldb/unittests/Symbol/Inputs/inlined-functions.yaml +++ b/gnu/llvm/lldb/unittests/Symbol/Inputs/inlined-functions.yaml @@ -342,8 +342,7 @@ DWARF: - Attribute: DW_AT_type Form: DW_FORM_ref4 debug_info: - - Length: - TotalLength: 579 + - Length: 579 Version: 4 AbbrOffset: 0 AddrSize: 8 @@ -713,8 +712,7 @@ DWARF: - AbbrCode: 0x00000000 Values: [] debug_line: - - Length: - TotalLength: 202 + - Length: 202 Version: 4 PrologueLength: 45 MinInstLength: 1 diff --git a/gnu/llvm/lldb/unittests/Symbol/LocateSymbolFileTest.cpp b/gnu/llvm/lldb/unittests/Symbol/LocateSymbolFileTest.cpp index 58a0eeba158..268faeaf1db 100644 --- a/gnu/llvm/lldb/unittests/Symbol/LocateSymbolFileTest.cpp +++ b/gnu/llvm/lldb/unittests/Symbol/LocateSymbolFileTest.cpp @@ -1,4 +1,4 @@ -//===-- SymbolsTest.cpp -----------------------------------------*- C++ -*-===// +//===-- SymbolsTest.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Symbol/PostfixExpressionTest.cpp b/gnu/llvm/lldb/unittests/Symbol/PostfixExpressionTest.cpp index b7fa73cacf4..7def709a609 100644 --- a/gnu/llvm/lldb/unittests/Symbol/PostfixExpressionTest.cpp +++ b/gnu/llvm/lldb/unittests/Symbol/PostfixExpressionTest.cpp @@ -1,4 +1,4 @@ -//===-- PostfixExpressionTest.cpp -------------------------------*- C++ -*-===// +//===-- PostfixExpressionTest.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,9 +7,9 @@ //===----------------------------------------------------------------------===// #include "lldb/Symbol/PostfixExpression.h" -#include "lldb/Expression/DWARFExpression.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/StreamString.h" +#include "llvm/DebugInfo/DWARF/DWARFExpression.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/raw_ostream.h" #include "gmock/gmock.h" @@ -41,27 +41,28 @@ static std::string ToString(UnaryOpNode::OpType type) { struct ASTPrinter : public Visitor { protected: std::string Visit(BinaryOpNode &binary, Node *&) override { - return llvm::formatv("{0}({1}, {2})", ToString(binary.GetOpType()), - Dispatch(binary.Left()), Dispatch(binary.Right())); + return std::string( + llvm::formatv("{0}({1}, {2})", ToString(binary.GetOpType()), + Dispatch(binary.Left()), Dispatch(binary.Right()))); } std::string Visit(InitialValueNode &, Node *&) override { return "InitialValue"; } std::string Visit(IntegerNode &integer, Node *&) override { - return llvm::formatv("int({0})", integer.GetValue()); + return std::string(llvm::formatv("int({0})", integer.GetValue())); } std::string Visit(RegisterNode ®, Node *&) override { - return llvm::formatv("reg({0})", reg.GetRegNum()); + return std::string(llvm::formatv("reg({0})", reg.GetRegNum())); } std::string Visit(SymbolNode &symbol, Node *&) override { - return symbol.GetName(); + return std::string(symbol.GetName()); } std::string Visit(UnaryOpNode &unary, Node *&) override { - return llvm::formatv("{0}({1})", ToString(unary.GetOpType()), - Dispatch(unary.Operand())); + return std::string(llvm::formatv("{0}({1})", ToString(unary.GetOpType()), + Dispatch(unary.Operand()))); } public: @@ -151,17 +152,14 @@ static std::string ParseAndGenerateDWARF(llvm::StringRef expr) { ToDWARF(*ast, dwarf); // print dwarf expression to comparable textual representation - DataExtractor extractor(dwarf.GetData(), dwarf.GetSize(), - lldb::eByteOrderLittle, addr_size); - - StreamString result; - if (!DWARFExpression::PrintDWARFExpression(result, extractor, addr_size, - /*dwarf_ref_size*/ 4, - /*location_expression*/ false)) { - return "DWARF printing failed."; - } - - return result.GetString(); + llvm::DataExtractor extractor(dwarf.GetString(), /*IsLittleEndian=*/true, + addr_size); + + std::string result; + llvm::raw_string_ostream os(result); + llvm::DWARFExpression(extractor, addr_size, llvm::dwarf::DWARF32) + .print(os, nullptr, nullptr); + return std::move(os.str()); } TEST(PostfixExpression, ToDWARF) { @@ -169,28 +167,28 @@ TEST(PostfixExpression, ToDWARF) { EXPECT_EQ("DW_OP_breg1 +0", ParseAndGenerateDWARF("R1")); - EXPECT_EQ("DW_OP_bregx 65 0", ParseAndGenerateDWARF("R65")); + EXPECT_EQ("DW_OP_bregx 0x41 +0", ParseAndGenerateDWARF("R65")); - EXPECT_EQ("DW_OP_pick 0x00", ParseAndGenerateDWARF("INIT")); + EXPECT_EQ("DW_OP_pick 0x0", ParseAndGenerateDWARF("INIT")); - EXPECT_EQ("DW_OP_pick 0x00, DW_OP_pick 0x01, DW_OP_plus ", + EXPECT_EQ("DW_OP_pick 0x0, DW_OP_pick 0x1, DW_OP_plus", ParseAndGenerateDWARF("INIT INIT +")); - EXPECT_EQ("DW_OP_breg1 +0, DW_OP_pick 0x01, DW_OP_plus ", + EXPECT_EQ("DW_OP_breg1 +0, DW_OP_pick 0x1, DW_OP_plus", ParseAndGenerateDWARF("R1 INIT +")); - EXPECT_EQ("DW_OP_consts +1, DW_OP_pick 0x01, DW_OP_deref , DW_OP_plus ", + EXPECT_EQ("DW_OP_consts +1, DW_OP_pick 0x1, DW_OP_deref, DW_OP_plus", ParseAndGenerateDWARF("1 INIT ^ +")); - EXPECT_EQ("DW_OP_consts +4, DW_OP_consts +5, DW_OP_plus ", + EXPECT_EQ("DW_OP_consts +4, DW_OP_consts +5, DW_OP_plus", ParseAndGenerateDWARF("4 5 +")); - EXPECT_EQ("DW_OP_consts +4, DW_OP_consts +5, DW_OP_minus ", + EXPECT_EQ("DW_OP_consts +4, DW_OP_consts +5, DW_OP_minus", ParseAndGenerateDWARF("4 5 -")); - EXPECT_EQ("DW_OP_consts +4, DW_OP_deref ", ParseAndGenerateDWARF("4 ^")); + EXPECT_EQ("DW_OP_consts +4, DW_OP_deref", ParseAndGenerateDWARF("4 ^")); - EXPECT_EQ("DW_OP_breg6 +0, DW_OP_consts +128, DW_OP_lit1 " - ", DW_OP_minus , DW_OP_not , DW_OP_and ", + EXPECT_EQ("DW_OP_breg6 +0, DW_OP_consts +128, DW_OP_lit1, DW_OP_minus, " + "DW_OP_not, DW_OP_and", ParseAndGenerateDWARF("R6 128 @")); } diff --git a/gnu/llvm/lldb/unittests/Symbol/TestClangASTImporter.cpp b/gnu/llvm/lldb/unittests/Symbol/TestClangASTImporter.cpp index 4f99d40d946..02151a20a20 100644 --- a/gnu/llvm/lldb/unittests/Symbol/TestClangASTImporter.cpp +++ b/gnu/llvm/lldb/unittests/Symbol/TestClangASTImporter.cpp @@ -1,4 +1,4 @@ -//===-- TestClangASTImporter.cpp --------------------------------*- C++ -*-===// +//===-- TestClangASTImporter.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,14 +8,14 @@ #include "gtest/gtest.h" +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "TestingSupport/SubsystemRAII.h" #include "TestingSupport/Symbol/ClangTestUtils.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangASTImporter.h" -#include "lldb/Symbol/ClangASTMetadata.h" -#include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/Declaration.h" #include "clang/AST/DeclCXX.h" @@ -42,7 +42,7 @@ TEST_F(TestClangASTImporter, CopyDeclTagDecl) { // Tests that the ClangASTImporter::CopyDecl can copy TagDecls. clang_utils::SourceASTWithRecord source; - std::unique_ptr target_ast = clang_utils::createAST(); + std::unique_ptr target_ast = clang_utils::createAST(); ClangASTImporter importer; clang::Decl *imported = @@ -67,7 +67,7 @@ TEST_F(TestClangASTImporter, CopyTypeTagDecl) { // Tests that the ClangASTImporter::CopyType can copy TagDecls types. clang_utils::SourceASTWithRecord source; - std::unique_ptr target_ast = clang_utils::createAST(); + std::unique_ptr target_ast = clang_utils::createAST(); ClangASTImporter importer; CompilerType imported = importer.CopyType(*target_ast, source.record_type); @@ -88,11 +88,38 @@ TEST_F(TestClangASTImporter, CopyTypeTagDecl) { EXPECT_EQ(origin.decl, source.record_decl); } +TEST_F(TestClangASTImporter, CompleteFwdDeclWithOtherOrigin) { + // Create an AST with a full type that is defined. + clang_utils::SourceASTWithRecord source_with_definition; + + // Create an AST with a type thst is only a forward declaration with the + // same name as the one in the the other source. + std::unique_ptr fwd_decl_source = clang_utils::createAST(); + CompilerType fwd_decl_type = clang_utils::createRecord( + *fwd_decl_source, source_with_definition.record_decl->getName()); + + // Create a target and import the forward decl. + std::unique_ptr target = clang_utils::createAST(); + ClangASTImporter importer; + CompilerType imported = importer.CopyType(*target, fwd_decl_type); + ASSERT_TRUE(imported.IsValid()); + EXPECT_FALSE(imported.IsDefined()); + + // Now complete the forward decl with the definition from the other source. + // This should define the decl and give it the fields of the other origin. + clang::TagDecl *imported_tag_decl = ClangUtil::GetAsTagDecl(imported); + importer.CompleteTagDeclWithOrigin(imported_tag_decl, + source_with_definition.record_decl); + ASSERT_TRUE(imported.IsValid()); + EXPECT_TRUE(imported.IsDefined()); + EXPECT_EQ(1U, imported.GetNumFields()); +} + TEST_F(TestClangASTImporter, DeportDeclTagDecl) { // Tests that the ClangASTImporter::DeportDecl completely copies TagDecls. clang_utils::SourceASTWithRecord source; - std::unique_ptr target_ast = clang_utils::createAST(); + std::unique_ptr target_ast = clang_utils::createAST(); ClangASTImporter importer; clang::Decl *imported = @@ -114,7 +141,7 @@ TEST_F(TestClangASTImporter, DeportTypeTagDecl) { // Tests that the ClangASTImporter::CopyType can deport TagDecl types. clang_utils::SourceASTWithRecord source; - std::unique_ptr target_ast = clang_utils::createAST(); + std::unique_ptr target_ast = clang_utils::createAST(); ClangASTImporter importer; CompilerType imported = importer.DeportType(*target_ast, source.record_type); @@ -139,7 +166,7 @@ TEST_F(TestClangASTImporter, MetadataPropagation) { const lldb::user_id_t metadata = 123456; source.ast->SetMetadataAsUserID(source.record_decl, metadata); - std::unique_ptr target_ast = clang_utils::createAST(); + std::unique_ptr target_ast = clang_utils::createAST(); ClangASTImporter importer; clang::Decl *imported = @@ -161,14 +188,14 @@ TEST_F(TestClangASTImporter, MetadataPropagationIndirectImport) { const lldb::user_id_t metadata = 123456; source.ast->SetMetadataAsUserID(source.record_decl, metadata); - std::unique_ptr temporary_ast = clang_utils::createAST(); + std::unique_ptr temporary_ast = clang_utils::createAST(); ClangASTImporter importer; clang::Decl *temporary_imported = importer.CopyDecl(&temporary_ast->getASTContext(), source.record_decl); ASSERT_NE(nullptr, temporary_imported); - std::unique_ptr target_ast = clang_utils::createAST(); + std::unique_ptr target_ast = clang_utils::createAST(); clang::Decl *imported = importer.CopyDecl(&target_ast->getASTContext(), temporary_imported); ASSERT_NE(nullptr, imported); @@ -185,7 +212,7 @@ TEST_F(TestClangASTImporter, MetadataPropagationAfterCopying) { clang_utils::SourceASTWithRecord source; const lldb::user_id_t metadata = 123456; - std::unique_ptr target_ast = clang_utils::createAST(); + std::unique_ptr target_ast = clang_utils::createAST(); ClangASTImporter importer; clang::Decl *imported = diff --git a/gnu/llvm/lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp b/gnu/llvm/lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp index f7180a16fac..86a6cf0cacb 100644 --- a/gnu/llvm/lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp +++ b/gnu/llvm/lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp @@ -1,4 +1,4 @@ -//===-- TestDWARFCallFrameInfo.cpp ------------------------------*- C++ -*-===// +//===-- TestDWARFCallFrameInfo.cpp ----------------------------------------===// // // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -220,8 +220,7 @@ Symbols: )"); ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); - auto module_sp = - std::make_shared(ModuleSpec(FileSpec(ExpectedFile->name()))); + auto module_sp = std::make_shared(ExpectedFile->moduleSpec()); SectionList *list = module_sp->GetSectionList(); ASSERT_NE(nullptr, list); diff --git a/gnu/llvm/lldb/unittests/Symbol/TestLineEntry.cpp b/gnu/llvm/lldb/unittests/Symbol/TestLineEntry.cpp index cb2adba3ece..d32ec9b1e7c 100644 --- a/gnu/llvm/lldb/unittests/Symbol/TestLineEntry.cpp +++ b/gnu/llvm/lldb/unittests/Symbol/TestLineEntry.cpp @@ -1,4 +1,4 @@ -//===-- TestLineEntry.cpp ------------------------------*- C++ -*-===// +//===-- TestLineEntry.cpp -------------------------------------------------===// // // // The LLVM Compiler Infrastructure @@ -14,9 +14,9 @@ #include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h" #include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "TestingSupport/SubsystemRAII.h" #include "TestingSupport/TestUtilities.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Core/Module.h" #include "lldb/Host/FileSystem.h" @@ -33,7 +33,7 @@ using namespace lldb; class LineEntryTest : public testing::Test { SubsystemRAII + TypeSystemClang> subsystem; public: @@ -49,7 +49,7 @@ void LineEntryTest::SetUp() { auto ExpectedFile = TestFile::fromYamlFile("inlined-functions.yaml"); ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); m_file.emplace(std::move(*ExpectedFile)); - m_module_sp = std::make_shared(ModuleSpec(FileSpec(m_file->name()))); + m_module_sp = std::make_shared(m_file->moduleSpec()); } llvm::Expected LineEntryTest::GetLineEntryForLine(uint32_t line) { diff --git a/gnu/llvm/lldb/unittests/Symbol/TestType.cpp b/gnu/llvm/lldb/unittests/Symbol/TestType.cpp index d23d7a53e03..73f5811434f 100644 --- a/gnu/llvm/lldb/unittests/Symbol/TestType.cpp +++ b/gnu/llvm/lldb/unittests/Symbol/TestType.cpp @@ -1,4 +1,4 @@ -//===-- TestType.cpp --------------------------------------------*- C++ -*-===// +//===-- TestType.cpp ------------------------------------------------------===// // // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. diff --git a/gnu/llvm/lldb/unittests/Symbol/TestTypeSystemClang.cpp b/gnu/llvm/lldb/unittests/Symbol/TestTypeSystemClang.cpp new file mode 100644 index 00000000000..bd7eb14d453 --- /dev/null +++ b/gnu/llvm/lldb/unittests/Symbol/TestTypeSystemClang.cpp @@ -0,0 +1,724 @@ +//===-- TestTypeSystemClang.cpp -------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" +#include "TestingSupport/SubsystemRAII.h" +#include "TestingSupport/Symbol/ClangTestUtils.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Symbol/Declaration.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/ExprCXX.h" +#include "gtest/gtest.h" + +using namespace clang; +using namespace lldb; +using namespace lldb_private; + +class TestTypeSystemClang : public testing::Test { +public: + SubsystemRAII subsystems; + + void SetUp() override { + m_ast.reset( + new TypeSystemClang("test ASTContext", HostInfo::GetTargetTriple())); + } + + void TearDown() override { m_ast.reset(); } + +protected: + std::unique_ptr m_ast; + + QualType GetBasicQualType(BasicType type) const { + return ClangUtil::GetQualType(m_ast->GetBasicTypeFromAST(type)); + } + + QualType GetBasicQualType(const char *name) const { + return ClangUtil::GetQualType( + m_ast->GetBuiltinTypeByName(ConstString(name))); + } +}; + +TEST_F(TestTypeSystemClang, TestGetBasicTypeFromEnum) { + clang::ASTContext &context = m_ast->getASTContext(); + + EXPECT_TRUE( + context.hasSameType(GetBasicQualType(eBasicTypeBool), context.BoolTy)); + EXPECT_TRUE( + context.hasSameType(GetBasicQualType(eBasicTypeChar), context.CharTy)); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeChar16), + context.Char16Ty)); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeChar32), + context.Char32Ty)); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeDouble), + context.DoubleTy)); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeDoubleComplex), + context.DoubleComplexTy)); + EXPECT_TRUE( + context.hasSameType(GetBasicQualType(eBasicTypeFloat), context.FloatTy)); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeFloatComplex), + context.FloatComplexTy)); + EXPECT_TRUE( + context.hasSameType(GetBasicQualType(eBasicTypeHalf), context.HalfTy)); + EXPECT_TRUE( + context.hasSameType(GetBasicQualType(eBasicTypeInt), context.IntTy)); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeInt128), + context.Int128Ty)); + EXPECT_TRUE( + context.hasSameType(GetBasicQualType(eBasicTypeLong), context.LongTy)); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeLongDouble), + context.LongDoubleTy)); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeLongDoubleComplex), + context.LongDoubleComplexTy)); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeLongLong), + context.LongLongTy)); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeNullPtr), + context.NullPtrTy)); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCClass), + context.getObjCClassType())); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCID), + context.getObjCIdType())); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCSel), + context.getObjCSelType())); + EXPECT_TRUE( + context.hasSameType(GetBasicQualType(eBasicTypeShort), context.ShortTy)); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeSignedChar), + context.SignedCharTy)); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedChar), + context.UnsignedCharTy)); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedInt), + context.UnsignedIntTy)); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedInt128), + context.UnsignedInt128Ty)); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedLong), + context.UnsignedLongTy)); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedLongLong), + context.UnsignedLongLongTy)); + EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedShort), + context.UnsignedShortTy)); + EXPECT_TRUE( + context.hasSameType(GetBasicQualType(eBasicTypeVoid), context.VoidTy)); + EXPECT_TRUE( + context.hasSameType(GetBasicQualType(eBasicTypeWChar), context.WCharTy)); +} + +TEST_F(TestTypeSystemClang, TestGetBasicTypeFromName) { + EXPECT_EQ(GetBasicQualType(eBasicTypeChar), GetBasicQualType("char")); + EXPECT_EQ(GetBasicQualType(eBasicTypeSignedChar), + GetBasicQualType("signed char")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedChar), + GetBasicQualType("unsigned char")); + EXPECT_EQ(GetBasicQualType(eBasicTypeWChar), GetBasicQualType("wchar_t")); + EXPECT_EQ(GetBasicQualType(eBasicTypeSignedWChar), + GetBasicQualType("signed wchar_t")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedWChar), + GetBasicQualType("unsigned wchar_t")); + EXPECT_EQ(GetBasicQualType(eBasicTypeShort), GetBasicQualType("short")); + EXPECT_EQ(GetBasicQualType(eBasicTypeShort), GetBasicQualType("short int")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort), + GetBasicQualType("unsigned short")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort), + GetBasicQualType("unsigned short int")); + EXPECT_EQ(GetBasicQualType(eBasicTypeInt), GetBasicQualType("int")); + EXPECT_EQ(GetBasicQualType(eBasicTypeInt), GetBasicQualType("signed int")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt), + GetBasicQualType("unsigned int")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt), + GetBasicQualType("unsigned")); + EXPECT_EQ(GetBasicQualType(eBasicTypeLong), GetBasicQualType("long")); + EXPECT_EQ(GetBasicQualType(eBasicTypeLong), GetBasicQualType("long int")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong), + GetBasicQualType("unsigned long")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong), + GetBasicQualType("unsigned long int")); + EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong), + GetBasicQualType("long long")); + EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong), + GetBasicQualType("long long int")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong), + GetBasicQualType("unsigned long long")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong), + GetBasicQualType("unsigned long long int")); + EXPECT_EQ(GetBasicQualType(eBasicTypeInt128), GetBasicQualType("__int128_t")); + EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt128), + GetBasicQualType("__uint128_t")); + EXPECT_EQ(GetBasicQualType(eBasicTypeVoid), GetBasicQualType("void")); + EXPECT_EQ(GetBasicQualType(eBasicTypeBool), GetBasicQualType("bool")); + EXPECT_EQ(GetBasicQualType(eBasicTypeFloat), GetBasicQualType("float")); + EXPECT_EQ(GetBasicQualType(eBasicTypeDouble), GetBasicQualType("double")); + EXPECT_EQ(GetBasicQualType(eBasicTypeLongDouble), + GetBasicQualType("long double")); + EXPECT_EQ(GetBasicQualType(eBasicTypeObjCID), GetBasicQualType("id")); + EXPECT_EQ(GetBasicQualType(eBasicTypeObjCSel), GetBasicQualType("SEL")); + EXPECT_EQ(GetBasicQualType(eBasicTypeNullPtr), GetBasicQualType("nullptr")); +} + +void VerifyEncodingAndBitSize(TypeSystemClang &clang_context, + lldb::Encoding encoding, unsigned int bit_size) { + clang::ASTContext &context = clang_context.getASTContext(); + + CompilerType type = + clang_context.GetBuiltinTypeForEncodingAndBitSize(encoding, bit_size); + EXPECT_TRUE(type.IsValid()); + + QualType qtype = ClangUtil::GetQualType(type); + EXPECT_FALSE(qtype.isNull()); + if (qtype.isNull()) + return; + + uint64_t actual_size = context.getTypeSize(qtype); + EXPECT_EQ(bit_size, actual_size); + + const clang::Type *type_ptr = qtype.getTypePtr(); + EXPECT_NE(nullptr, type_ptr); + if (!type_ptr) + return; + + EXPECT_TRUE(type_ptr->isBuiltinType()); + switch (encoding) { + case eEncodingSint: + EXPECT_TRUE(type_ptr->isSignedIntegerType()); + break; + case eEncodingUint: + EXPECT_TRUE(type_ptr->isUnsignedIntegerType()); + break; + case eEncodingIEEE754: + EXPECT_TRUE(type_ptr->isFloatingType()); + break; + default: + FAIL() << "Unexpected encoding"; + break; + } +} + +TEST_F(TestTypeSystemClang, TestBuiltinTypeForEncodingAndBitSize) { + // Make sure we can get types of every possible size in every possible + // encoding. + // We can't make any guarantee about which specific type we get, because the + // standard + // isn't that specific. We only need to make sure the compiler hands us some + // type that + // is both a builtin type and matches the requested bit size. + VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 8); + VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 16); + VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 32); + VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 64); + VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 128); + + VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 8); + VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 16); + VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 32); + VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 64); + VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 128); + + VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 32); + VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 64); +} + +TEST_F(TestTypeSystemClang, TestDisplayName) { + TypeSystemClang ast("some name", llvm::Triple()); + EXPECT_EQ("some name", ast.getDisplayName()); +} + +TEST_F(TestTypeSystemClang, TestDisplayNameEmpty) { + TypeSystemClang ast("", llvm::Triple()); + EXPECT_EQ("", ast.getDisplayName()); +} + +TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeInvalid) { + EXPECT_FALSE(m_ast->GetEnumerationIntegerType(CompilerType()).IsValid()); +} + +TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeUnexpectedType) { + CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt); + CompilerType t = m_ast->GetEnumerationIntegerType(int_type); + EXPECT_FALSE(t.IsValid()); +} + +TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeBasicTypes) { + // All possible underlying integer types of enums. + const std::vector types_to_test = { + eBasicTypeInt, eBasicTypeUnsignedInt, eBasicTypeLong, + eBasicTypeUnsignedLong, eBasicTypeLongLong, eBasicTypeUnsignedLongLong, + }; + + for (bool scoped : {true, false}) { + SCOPED_TRACE("scoped: " + std::to_string(scoped)); + for (lldb::BasicType basic_type : types_to_test) { + SCOPED_TRACE(std::to_string(basic_type)); + + TypeSystemClang ast("enum_ast", HostInfo::GetTargetTriple()); + CompilerType basic_compiler_type = ast.GetBasicType(basic_type); + EXPECT_TRUE(basic_compiler_type.IsValid()); + + CompilerType enum_type = ast.CreateEnumerationType( + "my_enum", ast.GetTranslationUnitDecl(), OptionalClangModuleID(), + Declaration(), basic_compiler_type, scoped); + + CompilerType t = ast.GetEnumerationIntegerType(enum_type); + // Check that the type we put in at the start is found again. + EXPECT_EQ(basic_compiler_type.GetTypeName(), t.GetTypeName()); + } + } +} + +TEST_F(TestTypeSystemClang, TestOwningModule) { + TypeSystemClang ast("module_ast", HostInfo::GetTargetTriple()); + CompilerType basic_compiler_type = ast.GetBasicType(BasicType::eBasicTypeInt); + CompilerType enum_type = ast.CreateEnumerationType( + "my_enum", ast.GetTranslationUnitDecl(), OptionalClangModuleID(100), + Declaration(), basic_compiler_type, false); + auto *ed = TypeSystemClang::GetAsEnumDecl(enum_type); + EXPECT_FALSE(!ed); + EXPECT_EQ(ed->getOwningModuleID(), 100u); + + CompilerType record_type = ast.CreateRecordType( + nullptr, OptionalClangModuleID(200), lldb::eAccessPublic, "FooRecord", + clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); + auto *rd = TypeSystemClang::GetAsRecordDecl(record_type); + EXPECT_FALSE(!rd); + EXPECT_EQ(rd->getOwningModuleID(), 200u); + + CompilerType class_type = + ast.CreateObjCClass("objc_class", ast.GetTranslationUnitDecl(), + OptionalClangModuleID(300), false, false); + auto *cd = TypeSystemClang::GetAsObjCInterfaceDecl(class_type); + EXPECT_FALSE(!cd); + EXPECT_EQ(cd->getOwningModuleID(), 300u); +} + +TEST_F(TestTypeSystemClang, TestIsClangType) { + clang::ASTContext &context = m_ast->getASTContext(); + lldb::opaque_compiler_type_t bool_ctype = + TypeSystemClang::GetOpaqueCompilerType(&context, lldb::eBasicTypeBool); + CompilerType bool_type(m_ast.get(), bool_ctype); + CompilerType record_type = m_ast->CreateRecordType( + nullptr, OptionalClangModuleID(100), lldb::eAccessPublic, "FooRecord", + clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); + // Clang builtin type and record type should pass + EXPECT_TRUE(ClangUtil::IsClangType(bool_type)); + EXPECT_TRUE(ClangUtil::IsClangType(record_type)); + + // Default constructed type should fail + EXPECT_FALSE(ClangUtil::IsClangType(CompilerType())); +} + +TEST_F(TestTypeSystemClang, TestRemoveFastQualifiers) { + CompilerType record_type = m_ast->CreateRecordType( + nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "FooRecord", + clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); + QualType qt; + + qt = ClangUtil::GetQualType(record_type); + EXPECT_EQ(0u, qt.getLocalFastQualifiers()); + record_type = record_type.AddConstModifier(); + record_type = record_type.AddVolatileModifier(); + record_type = record_type.AddRestrictModifier(); + qt = ClangUtil::GetQualType(record_type); + EXPECT_NE(0u, qt.getLocalFastQualifiers()); + record_type = ClangUtil::RemoveFastQualifiers(record_type); + qt = ClangUtil::GetQualType(record_type); + EXPECT_EQ(0u, qt.getLocalFastQualifiers()); +} + +TEST_F(TestTypeSystemClang, TestConvertAccessTypeToAccessSpecifier) { + EXPECT_EQ(AS_none, + TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessNone)); + EXPECT_EQ(AS_none, TypeSystemClang::ConvertAccessTypeToAccessSpecifier( + eAccessPackage)); + EXPECT_EQ(AS_public, + TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessPublic)); + EXPECT_EQ(AS_private, TypeSystemClang::ConvertAccessTypeToAccessSpecifier( + eAccessPrivate)); + EXPECT_EQ(AS_protected, TypeSystemClang::ConvertAccessTypeToAccessSpecifier( + eAccessProtected)); +} + +TEST_F(TestTypeSystemClang, TestUnifyAccessSpecifiers) { + // Unifying two of the same type should return the same type + EXPECT_EQ(AS_public, + TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_public)); + EXPECT_EQ(AS_private, + TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_private)); + EXPECT_EQ(AS_protected, + TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_protected)); + + // Otherwise the result should be the strictest of the two. + EXPECT_EQ(AS_private, + TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_public)); + EXPECT_EQ(AS_private, + TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_protected)); + EXPECT_EQ(AS_private, + TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_private)); + EXPECT_EQ(AS_private, + TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_private)); + EXPECT_EQ(AS_protected, + TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_public)); + EXPECT_EQ(AS_protected, + TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_protected)); + + // None is stricter than everything (by convention) + EXPECT_EQ(AS_none, + TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_public)); + EXPECT_EQ(AS_none, + TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_protected)); + EXPECT_EQ(AS_none, + TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_private)); + EXPECT_EQ(AS_none, + TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_none)); + EXPECT_EQ(AS_none, + TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_none)); + EXPECT_EQ(AS_none, + TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_none)); +} + +TEST_F(TestTypeSystemClang, TestRecordHasFields) { + CompilerType int_type = m_ast->GetBasicType(eBasicTypeInt); + + // Test that a record with no fields returns false + CompilerType empty_base = m_ast->CreateRecordType( + nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyBase", + clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); + TypeSystemClang::StartTagDeclarationDefinition(empty_base); + TypeSystemClang::CompleteTagDeclarationDefinition(empty_base); + + RecordDecl *empty_base_decl = TypeSystemClang::GetAsRecordDecl(empty_base); + EXPECT_NE(nullptr, empty_base_decl); + EXPECT_FALSE(TypeSystemClang::RecordHasFields(empty_base_decl)); + + // Test that a record with direct fields returns true + CompilerType non_empty_base = m_ast->CreateRecordType( + nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "NonEmptyBase", + clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); + TypeSystemClang::StartTagDeclarationDefinition(non_empty_base); + FieldDecl *non_empty_base_field_decl = m_ast->AddFieldToRecordType( + non_empty_base, "MyField", int_type, eAccessPublic, 0); + TypeSystemClang::CompleteTagDeclarationDefinition(non_empty_base); + RecordDecl *non_empty_base_decl = + TypeSystemClang::GetAsRecordDecl(non_empty_base); + EXPECT_NE(nullptr, non_empty_base_decl); + EXPECT_NE(nullptr, non_empty_base_field_decl); + EXPECT_TRUE(TypeSystemClang::RecordHasFields(non_empty_base_decl)); + + std::vector> bases; + + // Test that a record with no direct fields, but fields in a base returns true + CompilerType empty_derived = m_ast->CreateRecordType( + nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyDerived", + clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); + TypeSystemClang::StartTagDeclarationDefinition(empty_derived); + std::unique_ptr non_empty_base_spec = + m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(), + lldb::eAccessPublic, false, false); + bases.push_back(std::move(non_empty_base_spec)); + bool result = m_ast->TransferBaseClasses(empty_derived.GetOpaqueQualType(), + std::move(bases)); + TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived); + EXPECT_TRUE(result); + CXXRecordDecl *empty_derived_non_empty_base_cxx_decl = + m_ast->GetAsCXXRecordDecl(empty_derived.GetOpaqueQualType()); + RecordDecl *empty_derived_non_empty_base_decl = + TypeSystemClang::GetAsRecordDecl(empty_derived); + EXPECT_EQ(1u, TypeSystemClang::GetNumBaseClasses( + empty_derived_non_empty_base_cxx_decl, false)); + EXPECT_TRUE( + TypeSystemClang::RecordHasFields(empty_derived_non_empty_base_decl)); + + // Test that a record with no direct fields, but fields in a virtual base + // returns true + CompilerType empty_derived2 = m_ast->CreateRecordType( + nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyDerived2", + clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); + TypeSystemClang::StartTagDeclarationDefinition(empty_derived2); + std::unique_ptr non_empty_vbase_spec = + m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(), + lldb::eAccessPublic, true, false); + bases.push_back(std::move(non_empty_vbase_spec)); + result = m_ast->TransferBaseClasses(empty_derived2.GetOpaqueQualType(), + std::move(bases)); + TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived2); + EXPECT_TRUE(result); + CXXRecordDecl *empty_derived_non_empty_vbase_cxx_decl = + m_ast->GetAsCXXRecordDecl(empty_derived2.GetOpaqueQualType()); + RecordDecl *empty_derived_non_empty_vbase_decl = + TypeSystemClang::GetAsRecordDecl(empty_derived2); + EXPECT_EQ(1u, TypeSystemClang::GetNumBaseClasses( + empty_derived_non_empty_vbase_cxx_decl, false)); + EXPECT_TRUE( + TypeSystemClang::RecordHasFields(empty_derived_non_empty_vbase_decl)); +} + +TEST_F(TestTypeSystemClang, TemplateArguments) { + TypeSystemClang::TemplateParameterInfos infos; + infos.names.push_back("T"); + infos.args.push_back(TemplateArgument(m_ast->getASTContext().IntTy)); + infos.names.push_back("I"); + llvm::APSInt arg(llvm::APInt(8, 47)); + infos.args.push_back(TemplateArgument(m_ast->getASTContext(), arg, + m_ast->getASTContext().IntTy)); + + // template struct foo; + ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl( + m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic, + "foo", TTK_Struct, infos); + ASSERT_NE(decl, nullptr); + + // foo + ClassTemplateSpecializationDecl *spec_decl = + m_ast->CreateClassTemplateSpecializationDecl( + m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), decl, + TTK_Struct, infos); + ASSERT_NE(spec_decl, nullptr); + CompilerType type = m_ast->CreateClassTemplateSpecializationType(spec_decl); + ASSERT_TRUE(type); + m_ast->StartTagDeclarationDefinition(type); + m_ast->CompleteTagDeclarationDefinition(type); + + // typedef foo foo_def; + CompilerType typedef_type = m_ast->CreateTypedefType( + type, "foo_def", + m_ast->CreateDeclContext(m_ast->GetTranslationUnitDecl()), 0); + + CompilerType auto_type( + m_ast.get(), + m_ast->getASTContext() + .getAutoType(ClangUtil::GetCanonicalQualType(typedef_type), + clang::AutoTypeKeyword::Auto, false) + .getAsOpaquePtr()); + + CompilerType int_type(m_ast.get(), + m_ast->getASTContext().IntTy.getAsOpaquePtr()); + for (CompilerType t : {type, typedef_type, auto_type}) { + SCOPED_TRACE(t.GetTypeName().AsCString()); + + EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 0), + eTemplateArgumentKindType); + EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 0), + int_type); + EXPECT_EQ(llvm::None, + m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 0)); + + EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 1), + eTemplateArgumentKindIntegral); + EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 1), + CompilerType()); + auto result = m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 1); + ASSERT_NE(llvm::None, result); + EXPECT_EQ(arg, result->value); + EXPECT_EQ(int_type, result->type); + } +} + +static QualType makeConstInt(clang::ASTContext &ctxt) { + QualType result(ctxt.IntTy); + result.addConst(); + return result; +} + +TEST_F(TestTypeSystemClang, TestGetTypeClassDeclType) { + clang::ASTContext &ctxt = m_ast->getASTContext(); + auto *nullptr_expr = new (ctxt) CXXNullPtrLiteralExpr(ctxt.NullPtrTy, SourceLocation()); + QualType t = ctxt.getDecltypeType(nullptr_expr, makeConstInt(ctxt)); + EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr())); +} + +TEST_F(TestTypeSystemClang, TestGetTypeClassTypeOf) { + clang::ASTContext &ctxt = m_ast->getASTContext(); + QualType t = ctxt.getTypeOfType(makeConstInt(ctxt)); + EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr())); +} + +TEST_F(TestTypeSystemClang, TestGetTypeClassTypeOfExpr) { + clang::ASTContext &ctxt = m_ast->getASTContext(); + auto *nullptr_expr = new (ctxt) CXXNullPtrLiteralExpr(ctxt.NullPtrTy, SourceLocation()); + QualType t = ctxt.getTypeOfExprType(nullptr_expr); + EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr())); +} + +TEST_F(TestTypeSystemClang, TestGetTypeClassNested) { + clang::ASTContext &ctxt = m_ast->getASTContext(); + QualType t_base = ctxt.getTypeOfType(makeConstInt(ctxt)); + QualType t = ctxt.getTypeOfType(t_base); + EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr())); +} + +TEST_F(TestTypeSystemClang, TestFunctionTemplateConstruction) { + // Tests creating a function template. + + CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt); + clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl(); + + // Prepare the declarations/types we need for the template. + CompilerType clang_type = + m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U); + FunctionDecl *func = m_ast->CreateFunctionDeclaration( + TU, OptionalClangModuleID(), "foo", clang_type, 0, false); + TypeSystemClang::TemplateParameterInfos empty_params; + + // Create the actual function template. + clang::FunctionTemplateDecl *func_template = + m_ast->CreateFunctionTemplateDecl(TU, OptionalClangModuleID(), func, + "foo", empty_params); + + EXPECT_EQ(TU, func_template->getDeclContext()); + EXPECT_EQ("foo", func_template->getName()); + EXPECT_EQ(clang::AccessSpecifier::AS_none, func_template->getAccess()); +} + +TEST_F(TestTypeSystemClang, TestFunctionTemplateInRecordConstruction) { + // Tests creating a function template inside a record. + + CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt); + clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl(); + + // Create a record we can put the function template int. + CompilerType record_type = + clang_utils::createRecordWithField(*m_ast, "record", int_type, "field"); + clang::TagDecl *record = ClangUtil::GetAsTagDecl(record_type); + + // Prepare the declarations/types we need for the template. + CompilerType clang_type = + m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U); + // We create the FunctionDecl for the template in the TU DeclContext because: + // 1. FunctionDecls can't be in a Record (only CXXMethodDecls can). + // 2. It is mirroring the behavior of DWARFASTParserClang::ParseSubroutine. + FunctionDecl *func = m_ast->CreateFunctionDeclaration( + TU, OptionalClangModuleID(), "foo", clang_type, 0, false); + TypeSystemClang::TemplateParameterInfos empty_params; + + // Create the actual function template. + clang::FunctionTemplateDecl *func_template = + m_ast->CreateFunctionTemplateDecl(record, OptionalClangModuleID(), func, + "foo", empty_params); + + EXPECT_EQ(record, func_template->getDeclContext()); + EXPECT_EQ("foo", func_template->getName()); + EXPECT_EQ(clang::AccessSpecifier::AS_public, func_template->getAccess()); +} + +TEST_F(TestTypeSystemClang, TestDeletingImplicitCopyCstrDueToMoveCStr) { + // We need to simulate this behavior in our AST that we construct as we don't + // have a Sema instance that can do this for us: + // C++11 [class.copy]p7, p18: + // If the class definition declares a move constructor or move assignment + // operator, an implicitly declared copy constructor or copy assignment + // operator is defined as deleted. + + // Create a record and start defining it. + llvm::StringRef class_name = "S"; + CompilerType t = clang_utils::createRecord(*m_ast, class_name); + m_ast->StartTagDeclarationDefinition(t); + + // Create a move constructor that will delete the implicit copy constructor. + CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid); + CompilerType param_type = t.GetRValueReferenceType(); + CompilerType function_type = + m_ast->CreateFunctionType(return_type, ¶m_type, /*num_params*/ 1, + /*variadic=*/false, /*quals*/ 0U); + bool is_virtual = false; + bool is_static = false; + bool is_inline = false; + bool is_explicit = true; + bool is_attr_used = false; + bool is_artificial = false; + m_ast->AddMethodToCXXRecordType( + t.GetOpaqueQualType(), class_name, nullptr, function_type, + lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline, + is_explicit, is_attr_used, is_artificial); + + // Complete the definition and check the created record. + m_ast->CompleteTagDeclarationDefinition(t); + auto *record = llvm::cast(ClangUtil::GetAsTagDecl(t)); + // We can't call defaultedCopyConstructorIsDeleted() as this requires that + // the Decl passes through Sema which will actually compute this field. + // Instead we check that there is no copy constructor declared by the user + // which only leaves a non-deleted defaulted copy constructor as an option + // that our record will have no simple copy constructor. + EXPECT_FALSE(record->hasUserDeclaredCopyConstructor()); + EXPECT_FALSE(record->hasSimpleCopyConstructor()); +} + +TEST_F(TestTypeSystemClang, TestNotDeletingUserCopyCstrDueToMoveCStr) { + // Tests that we don't delete the a user-defined copy constructor when + // a move constructor is provided. + // See also the TestDeletingImplicitCopyCstrDueToMoveCStr test. + llvm::StringRef class_name = "S"; + CompilerType t = clang_utils::createRecord(*m_ast, class_name); + m_ast->StartTagDeclarationDefinition(t); + + CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid); + bool is_virtual = false; + bool is_static = false; + bool is_inline = false; + bool is_explicit = true; + bool is_attr_used = false; + bool is_artificial = false; + // Create a move constructor. + { + CompilerType param_type = t.GetRValueReferenceType(); + CompilerType function_type = + m_ast->CreateFunctionType(return_type, ¶m_type, /*num_params*/ 1, + /*variadic=*/false, /*quals*/ 0U); + m_ast->AddMethodToCXXRecordType( + t.GetOpaqueQualType(), class_name, nullptr, function_type, + lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline, + is_explicit, is_attr_used, is_artificial); + } + // Create a copy constructor. + { + CompilerType param_type = t.GetLValueReferenceType().AddConstModifier(); + CompilerType function_type = + m_ast->CreateFunctionType(return_type, ¶m_type, /*num_params*/ 1, + /*variadic=*/false, /*quals*/ 0U); + m_ast->AddMethodToCXXRecordType( + t.GetOpaqueQualType(), class_name, nullptr, function_type, + lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline, + is_explicit, is_attr_used, is_artificial); + } + + // Complete the definition and check the created record. + m_ast->CompleteTagDeclarationDefinition(t); + auto *record = llvm::cast(ClangUtil::GetAsTagDecl(t)); + EXPECT_TRUE(record->hasUserDeclaredCopyConstructor()); +} + +TEST_F(TestTypeSystemClang, AddMethodToObjCObjectType) { + // Create an interface decl and mark it as having external storage. + CompilerType c = m_ast->CreateObjCClass("A", m_ast->GetTranslationUnitDecl(), + OptionalClangModuleID(), + /*IsForwardDecl*/ false, + /*IsInternal*/ false); + ObjCInterfaceDecl *interface = m_ast->GetAsObjCInterfaceDecl(c); + m_ast->SetHasExternalStorage(c.GetOpaqueQualType(), true); + EXPECT_TRUE(interface->hasExternalLexicalStorage()); + + // Add a method to the interface. + std::vector args; + CompilerType func_type = + m_ast->CreateFunctionType(m_ast->GetBasicType(lldb::eBasicTypeInt), + args.data(), args.size(), /*variadic*/ false, + /*quals*/ 0, clang::CallingConv::CC_C); + bool variadic = false; + bool artificial = false; + bool objc_direct = false; + clang::ObjCMethodDecl *method = TypeSystemClang::AddMethodToObjCObjectType( + c, "-[A foo]", func_type, lldb::eAccessPublic, artificial, variadic, + objc_direct); + ASSERT_NE(method, nullptr); + + // The interface decl should still have external lexical storage. + EXPECT_TRUE(interface->hasExternalLexicalStorage()); + + // Test some properties of the created ObjCMethodDecl. + EXPECT_FALSE(method->isVariadic()); + EXPECT_TRUE(method->isImplicit()); + EXPECT_FALSE(method->isDirectMethod()); + EXPECT_EQ(method->getDeclName().getObjCSelector().getAsString(), "foo"); +} diff --git a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt b/gnu/llvm/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt index 57ee46316e0..64a7b78c478 100644 --- a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt @@ -1,6 +1,7 @@ add_lldb_unittest(SymbolFileDWARFTests DWARFASTParserClangTests.cpp SymbolFileDWARFTests.cpp + XcodeSDKModuleTests.cpp LINK_LIBS lldbCore @@ -9,7 +10,9 @@ add_lldb_unittest(SymbolFileDWARFTests lldbPluginObjectFilePECOFF lldbPluginSymbolFileDWARF lldbPluginSymbolFilePDB + lldbPluginTypeSystemClang lldbUtilityHelpers + lldbPluginPlatformMacOSX LINK_COMPONENTS Support DebugInfoPDB diff --git a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp b/gnu/llvm/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp index 8f0368d11ed..858aa61b19b 100644 --- a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp +++ b/gnu/llvm/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp @@ -1,4 +1,4 @@ -//===-- DWARFASTParserClangTests.cpp ----------------------------*- C++ -*-===// +//===-- DWARFASTParserClangTests.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,20 +7,18 @@ //===----------------------------------------------------------------------===// #include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h" +#include "Plugins/SymbolFile/DWARF/DWARFCompileUnit.h" #include "Plugins/SymbolFile/DWARF/DWARFDIE.h" -#include "TestingSupport/SubsystemRAII.h" -#include "lldb/Host/HostInfo.h" +#include "TestingSupport/Symbol/YAMLModuleTester.h" #include "gmock/gmock.h" #include "gtest/gtest.h" using namespace lldb; using namespace lldb_private; -class DWARFASTParserClangTests : public testing::Test { - SubsystemRAII subsystems; -}; - namespace { +class DWARFASTParserClangTests : public testing::Test {}; + class DWARFASTParserClangStub : public DWARFASTParserClang { public: using DWARFASTParserClang::DWARFASTParserClang; @@ -39,14 +37,72 @@ public: // defining here, causing this test to fail, feel free to delete it. TEST_F(DWARFASTParserClangTests, EnsureAllDIEsInDeclContextHaveBeenParsedParsesOnlyMatchingEntries) { - ClangASTContext ast_ctx(HostInfoBase::GetTargetTriple()); + + /// Auxiliary debug info. + const char *yamldata = + "debug_abbrev:\n" + " - Code: 0x00000001\n" + " Tag: DW_TAG_compile_unit\n" + " Children: DW_CHILDREN_yes\n" + " Attributes:\n" + " - Attribute: DW_AT_language\n" + " Form: DW_FORM_data2\n" + " - Code: 0x00000002\n" + " Tag: DW_TAG_base_type\n" + " Children: DW_CHILDREN_no\n" + " Attributes:\n" + " - Attribute: DW_AT_encoding\n" + " Form: DW_FORM_data1\n" + " - Attribute: DW_AT_byte_size\n" + " Form: DW_FORM_data1\n" + "debug_info:\n" + " - Length: 0\n" + " Version: 4\n" + " AbbrOffset: 0\n" + " AddrSize: 8\n" + " Entries:\n" + " - AbbrCode: 0x00000001\n" + " Values:\n" + " - Value: 0x000000000000000C\n" + // 0x0000000e: + " - AbbrCode: 0x00000002\n" + " Values:\n" + " - Value: 0x0000000000000007\n" // DW_ATE_unsigned + " - Value: 0x0000000000000004\n" + // 0x00000011: + " - AbbrCode: 0x00000002\n" + " Values:\n" + " - Value: 0x0000000000000007\n" // DW_ATE_unsigned + " - Value: 0x0000000000000008\n" + // 0x00000014: + " - AbbrCode: 0x00000002\n" + " Values:\n" + " - Value: 0x0000000000000005\n" // DW_ATE_signed + " - Value: 0x0000000000000008\n" + // 0x00000017: + " - AbbrCode: 0x00000002\n" + " Values:\n" + " - Value: 0x0000000000000008\n" // DW_ATE_unsigned_char + " - Value: 0x0000000000000001\n" + "" + " - AbbrCode: 0x00000000\n" + " Values: []\n"; + + YAMLModuleTester t(yamldata, "i386-unknown-linux"); + ASSERT_TRUE((bool)t.GetDwarfUnit()); + + TypeSystemClang ast_ctx("dummy ASTContext", HostInfoBase::GetTargetTriple()); DWARFASTParserClangStub ast_parser(ast_ctx); - DWARFUnit *unit = nullptr; - std::vector dies = {DWARFDIE(unit, (DWARFDebugInfoEntry *)1LL), - DWARFDIE(unit, (DWARFDebugInfoEntry *)2LL), - DWARFDIE(unit, (DWARFDebugInfoEntry *)3LL), - DWARFDIE(unit, (DWARFDebugInfoEntry *)4LL)}; + DWARFUnit *unit = t.GetDwarfUnit().get(); + const DWARFDebugInfoEntry *die_first = unit->DIE().GetDIE(); + const DWARFDebugInfoEntry *die_child0 = die_first->GetFirstChild(); + const DWARFDebugInfoEntry *die_child1 = die_child0->GetSibling(); + const DWARFDebugInfoEntry *die_child2 = die_child1->GetSibling(); + const DWARFDebugInfoEntry *die_child3 = die_child2->GetSibling(); + std::vector dies = { + DWARFDIE(unit, die_child0), DWARFDIE(unit, die_child1), + DWARFDIE(unit, die_child2), DWARFDIE(unit, die_child3)}; std::vector decl_ctxs = { (clang::DeclContext *)1LL, (clang::DeclContext *)2LL, (clang::DeclContext *)2LL, (clang::DeclContext *)3LL}; @@ -58,3 +114,4 @@ TEST_F(DWARFASTParserClangTests, EXPECT_THAT(ast_parser.GetDeclContextToDIEMapKeys(), testing::UnorderedElementsAre(decl_ctxs[0], decl_ctxs[3])); } + diff --git a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp b/gnu/llvm/lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp index e971439a8bd..8bf019ea9ed 100644 --- a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp +++ b/gnu/llvm/lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp @@ -1,4 +1,4 @@ -//===-- SymbolFileDWARFTests.cpp --------------------------------*- C++ -*-===// +//===-- SymbolFileDWARFTests.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,8 +18,10 @@ #include "Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h" #include "Plugins/SymbolFile/DWARF/DWARFDataExtractor.h" #include "Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h" +#include "Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" #include "Plugins/SymbolFile/PDB/SymbolFilePDB.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "TestingSupport/SubsystemRAII.h" #include "TestingSupport/TestUtilities.h" #include "lldb/Core/Address.h" @@ -27,7 +29,6 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/LineTable.h" #include "lldb/Utility/ArchSpec.h" @@ -35,14 +36,12 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/StreamString.h" - - using namespace lldb; using namespace lldb_private; class SymbolFileDWARFTests : public testing::Test { SubsystemRAII + TypeSystemClang, SymbolFilePDB> subsystems; public: @@ -312,3 +311,38 @@ TEST_F(SymbolFileDWARFTests, TestAbbrevMissingTerminator) { EXPECT_EQ("abbreviation declaration attribute list not terminated with a " "null entry", llvm::toString(std::move(error))); } + +TEST_F(SymbolFileDWARFTests, ParseArangesNonzeroSegmentSize) { + // This `.debug_aranges` table header is a valid 32bit big-endian section + // according to the DWARFv5 spec:6.2.1, but contains segment selectors which + // are not supported by lldb, and should be gracefully rejected + const unsigned char binary_data[] = { + 0, 0, 0, 41, // unit_length (length field not including this field itself) + 0, 2, // DWARF version number (half) + 0, 0, 0, 0, // offset into the .debug_info_table (ignored for the purposes + // of this test + 4, // address size + 1, // segment size + // alignment for the first tuple which "begins at an offset that is a + // multiple of the size of a single tuple". Tuples are nine bytes in this + // example. + 0, 0, 0, 0, 0, 0, + // BEGIN TUPLES + 1, 0, 0, 0, 4, 0, 0, 0, + 1, // a 1byte object starting at address 4 in segment 1 + 0, 0, 0, 0, 4, 0, 0, 0, + 1, // a 1byte object starting at address 4 in segment 0 + // END TUPLES + 0, 0, 0, 0, 0, 0, 0, 0, 0 // terminator + }; + DWARFDataExtractor data; + data.SetData(static_cast(binary_data), sizeof binary_data, + lldb::ByteOrder::eByteOrderBig); + DWARFDebugArangeSet debug_aranges; + offset_t off = 0; + llvm::Error error = debug_aranges.extract(data, &off); + EXPECT_TRUE(bool(error)); + EXPECT_EQ("segmented arange entries are not supported", + llvm::toString(std::move(error))); + EXPECT_EQ(off, 12U); // Parser should read no further than the segment size +} diff --git a/gnu/llvm/lldb/unittests/SymbolFile/DWARF/XcodeSDKModuleTests.cpp b/gnu/llvm/lldb/unittests/SymbolFile/DWARF/XcodeSDKModuleTests.cpp new file mode 100644 index 00000000000..399eaf7aa64 --- /dev/null +++ b/gnu/llvm/lldb/unittests/SymbolFile/DWARF/XcodeSDKModuleTests.cpp @@ -0,0 +1,78 @@ +//===-- XcodeSDKModuleTests.cpp -------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "Plugins/Platform/MacOSX/PlatformMacOSX.h" +#include "Plugins/SymbolFile/DWARF/DWARFCompileUnit.h" +#include "Plugins/SymbolFile/DWARF/DWARFDIE.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" +#include "TestingSupport/Symbol/YAMLModuleTester.h" +#include "lldb/Core/PluginManager.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using namespace lldb; +using namespace lldb_private; + +#ifdef __APPLE__ +namespace { +class XcodeSDKModuleTests : public testing::Test { + void SetUp() override { + HostInfoBase::Initialize(); + PlatformMacOSX::Initialize(); + } + void TearDown() override { + PlatformMacOSX::Terminate(); + HostInfoBase::Terminate(); + } +}; +} // namespace + + +TEST_F(XcodeSDKModuleTests, TestModuleGetXcodeSDK) { + const char *yamldata = R"( +debug_str: + - MacOSX10.9.sdk +debug_abbrev: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_APPLE_sdk + Form: DW_FORM_strp +debug_info: + - Length: 8 + Version: 2 + AbbrOffset: 0 + AddrSize: 8 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x000000000000000C + - Value: 0x0000000000000000 + - AbbrCode: 0x00000000 + Values: [] +... +)"; + + auto triple = "x86_64-apple-macosx"; + YAMLModuleTester t(yamldata, triple); + auto dwarf_unit_sp = t.GetDwarfUnit(); + auto *dwarf_cu = llvm::cast(dwarf_unit_sp.get()); + ASSERT_TRUE((bool)dwarf_cu); + SymbolFileDWARF &sym_file = dwarf_cu->GetSymbolFileDWARF(); + CompUnitSP comp_unit = sym_file.GetCompileUnitAtIndex(0); + ASSERT_TRUE((bool)comp_unit.get()); + ModuleSP module = t.GetModule(); + ASSERT_EQ(module->GetSourceMappingList().GetSize(), 0u); + XcodeSDK sdk = sym_file.ParseXcodeSDK(*comp_unit); + ASSERT_EQ(sdk.GetType(), XcodeSDK::Type::MacOSX); + ASSERT_EQ(module->GetSourceMappingList().GetSize(), 1u); +} +#endif diff --git a/gnu/llvm/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp b/gnu/llvm/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp index 411889536f5..334a08f9203 100644 --- a/gnu/llvm/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp +++ b/gnu/llvm/lldb/unittests/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpressionTests.cpp @@ -1,4 +1,4 @@ -//===-- PDBFPOProgramToDWARFExpressionTests.cpp -----------------*- C++ -*-===// +//===-- PDBFPOProgramToDWARFExpressionTests.cpp ---------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -11,11 +11,11 @@ #include "Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h" #include "lldb/Core/StreamBuffer.h" -#include "lldb/Expression/DWARFExpression.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/StreamString.h" +#include "llvm/DebugInfo/DWARF/DWARFExpression.h" using namespace lldb; using namespace lldb_private; @@ -27,30 +27,22 @@ static void CheckValidProgramTranslation(llvm::StringRef fpo_program, llvm::StringRef target_register_name, llvm::StringRef expected_dwarf_expression) { - // initial setup - ArchSpec arch_spec("i686-pc-windows"); - llvm::Triple::ArchType arch_type = arch_spec.GetMachine(); - ByteOrder byte_order = arch_spec.GetByteOrder(); - uint32_t address_size = arch_spec.GetAddressByteSize(); - uint32_t byte_size = arch_spec.GetDataByteSize(); - // program translation - StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order); + StreamBuffer<32> stream(Stream::eBinary, 4, eByteOrderLittle); ASSERT_TRUE(TranslateFPOProgramToDWARFExpression( - fpo_program, target_register_name, arch_type, stream)); + fpo_program, target_register_name, llvm::Triple::x86, stream)); // print dwarf expression to comparable textual representation - DataBufferSP buffer = - std::make_shared(stream.GetData(), stream.GetSize()); - DataExtractor extractor(buffer, byte_order, address_size, byte_size); + llvm::DataExtractor extractor({stream.GetData(), stream.GetSize()}, + /*IsLittleEndian=*/true, /*AddressSize=*/4); - StreamString result_dwarf_expression; - ASSERT_TRUE(DWARFExpression::PrintDWARFExpression( - result_dwarf_expression, extractor, address_size, 4, false)); + std::string result; + llvm::raw_string_ostream os(result); + llvm::DWARFExpression(extractor, /*AddressSize=*/4, llvm::dwarf::DWARF32) + .print(os, nullptr, nullptr); // actual check - ASSERT_STREQ(expected_dwarf_expression.data(), - result_dwarf_expression.GetString().data()); + ASSERT_EQ(expected_dwarf_expression, os.str()); } TEST(PDBFPOProgramToDWARFExpressionTests, SingleAssignmentRegisterRef) { @@ -64,9 +56,9 @@ TEST(PDBFPOProgramToDWARFExpressionTests, MultipleIndependentAssignments) { TEST(PDBFPOProgramToDWARFExpressionTests, MultipleDependentAssignments) { CheckValidProgramTranslation( "$T1 $ebp 4 + = $T0 $T1 8 - 128 @ = ", "$T0", - "DW_OP_breg6 +0, DW_OP_consts +4, DW_OP_plus , DW_OP_consts +8, " - "DW_OP_minus , DW_OP_consts +128, DW_OP_lit1 , DW_OP_minus , DW_OP_not , " - "DW_OP_and "); + "DW_OP_breg6 +0, DW_OP_consts +4, DW_OP_plus, DW_OP_consts +8, " + "DW_OP_minus, DW_OP_consts +128, DW_OP_lit1, DW_OP_minus, DW_OP_not, " + "DW_OP_and"); } TEST(PDBFPOProgramToDWARFExpressionTests, DependencyChain) { diff --git a/gnu/llvm/lldb/unittests/SymbolFile/PDB/CMakeLists.txt b/gnu/llvm/lldb/unittests/SymbolFile/PDB/CMakeLists.txt index 75e4b504249..8fc2167ee6b 100644 --- a/gnu/llvm/lldb/unittests/SymbolFile/PDB/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/SymbolFile/PDB/CMakeLists.txt @@ -8,6 +8,7 @@ add_lldb_unittest(SymbolFilePDBTests lldbPluginObjectFilePECOFF lldbPluginSymbolFileDWARF lldbPluginSymbolFilePDB + lldbPluginTypeSystemClang lldbUtilityHelpers LLVMTestingSupport LINK_COMPONENTS diff --git a/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb-types.cpp b/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb-types.cpp index 1b4f2c49721..363be7b3c49 100644 --- a/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb-types.cpp +++ b/gnu/llvm/lldb/unittests/SymbolFile/PDB/Inputs/test-pdb-types.cpp @@ -1,79 +1,79 @@ -// Compile with "cl /c /Zi /GR- /EHsc test-pdb-types.cpp" -// Link with "link test-pdb-types.obj /debug /nodefaultlib /entry:main -// /out:test-pdb-types.exe" - -using namespace std; - -// Sizes of builtin types -static const int sizeof_char = sizeof(char); -static const int sizeof_uchar = sizeof(unsigned char); -static const int sizeof_short = sizeof(short); -static const int sizeof_ushort = sizeof(unsigned short); -static const int sizeof_int = sizeof(int); -static const int sizeof_uint = sizeof(unsigned int); -static const int sizeof_long = sizeof(long); -static const int sizeof_ulong = sizeof(unsigned long); -static const int sizeof_longlong = sizeof(long long); -static const int sizeof_ulonglong = sizeof(unsigned long long); -static const int sizeof_int64 = sizeof(__int64); -static const int sizeof_uint64 = sizeof(unsigned __int64); -static const int sizeof_float = sizeof(float); -static const int sizeof_double = sizeof(double); -static const int sizeof_bool = sizeof(bool); -static const int sizeof_wchar = sizeof(wchar_t); - -enum Enum { - EValue1 = 1, - EValue2 = 2, -}; - -enum ShortEnum : short { ESValue1 = 1, ESValue2 = 2 }; - -namespace NS { -class NSClass { - float f; - double d; -}; -} // namespace NS - -class Class { -public: - class NestedClass { - Enum e; - }; - ShortEnum se; -}; - -int test_func(int a, int b) { return a + b; } - -typedef Class ClassTypedef; -typedef NS::NSClass NSClassTypedef; -typedef int (*FuncPointerTypedef)(); -typedef int (*VariadicFuncPointerTypedef)(char, ...); -FuncPointerTypedef GlobalFunc; -VariadicFuncPointerTypedef GlobalVariadicFunc; -int GlobalArray[10]; - -static const int sizeof_NSClass = sizeof(NS::NSClass); -static const int sizeof_Class = sizeof(Class); -static const int sizeof_NestedClass = sizeof(Class::NestedClass); -static const int sizeof_Enum = sizeof(Enum); -static const int sizeof_ShortEnum = sizeof(ShortEnum); -static const int sizeof_ClassTypedef = sizeof(ClassTypedef); -static const int sizeof_NSClassTypedef = sizeof(NSClassTypedef); -static const int sizeof_FuncPointerTypedef = sizeof(FuncPointerTypedef); -static const int sizeof_VariadicFuncPointerTypedef = - sizeof(VariadicFuncPointerTypedef); -static const int sizeof_GlobalArray = sizeof(GlobalArray); - -int main(int argc, char **argv) { - ShortEnum e1; - Enum e2; - Class c1; - Class::NestedClass c2; - NS::NSClass c3; - - ClassTypedef t1; - NSClassTypedef t2; - return test_func(1, 2); -} +// Compile with "cl /c /Zi /GR- /EHsc test-pdb-types.cpp" +// Link with "link test-pdb-types.obj /debug /nodefaultlib /entry:main +// /out:test-pdb-types.exe" + +using namespace std; + +// Sizes of builtin types +static const int sizeof_char = sizeof(char); +static const int sizeof_uchar = sizeof(unsigned char); +static const int sizeof_short = sizeof(short); +static const int sizeof_ushort = sizeof(unsigned short); +static const int sizeof_int = sizeof(int); +static const int sizeof_uint = sizeof(unsigned int); +static const int sizeof_long = sizeof(long); +static const int sizeof_ulong = sizeof(unsigned long); +static const int sizeof_longlong = sizeof(long long); +static const int sizeof_ulonglong = sizeof(unsigned long long); +static const int sizeof_int64 = sizeof(__int64); +static const int sizeof_uint64 = sizeof(unsigned __int64); +static const int sizeof_float = sizeof(float); +static const int sizeof_double = sizeof(double); +static const int sizeof_bool = sizeof(bool); +static const int sizeof_wchar = sizeof(wchar_t); + +enum Enum { + EValue1 = 1, + EValue2 = 2, +}; + +enum ShortEnum : short { ESValue1 = 1, ESValue2 = 2 }; + +namespace NS { +class NSClass { + float f; + double d; +}; +} // namespace NS + +class Class { +public: + class NestedClass { + Enum e; + }; + ShortEnum se; +}; + +int test_func(int a, int b) { return a + b; } + +typedef Class ClassTypedef; +typedef NS::NSClass NSClassTypedef; +typedef int (*FuncPointerTypedef)(); +typedef int (*VariadicFuncPointerTypedef)(char, ...); +FuncPointerTypedef GlobalFunc; +VariadicFuncPointerTypedef GlobalVariadicFunc; +int GlobalArray[10]; + +static const int sizeof_NSClass = sizeof(NS::NSClass); +static const int sizeof_Class = sizeof(Class); +static const int sizeof_NestedClass = sizeof(Class::NestedClass); +static const int sizeof_Enum = sizeof(Enum); +static const int sizeof_ShortEnum = sizeof(ShortEnum); +static const int sizeof_ClassTypedef = sizeof(ClassTypedef); +static const int sizeof_NSClassTypedef = sizeof(NSClassTypedef); +static const int sizeof_FuncPointerTypedef = sizeof(FuncPointerTypedef); +static const int sizeof_VariadicFuncPointerTypedef = + sizeof(VariadicFuncPointerTypedef); +static const int sizeof_GlobalArray = sizeof(GlobalArray); + +int main(int argc, char **argv) { + ShortEnum e1; + Enum e2; + Class c1; + Class::NestedClass c2; + NS::NSClass c3; + + ClassTypedef t1; + NSClassTypedef t2; + return test_func(1, 2); +} diff --git a/gnu/llvm/lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp b/gnu/llvm/lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp index c0163f64726..072fe6aaf0f 100644 --- a/gnu/llvm/lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp +++ b/gnu/llvm/lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp @@ -1,4 +1,4 @@ -//===-- PythonDataObjectsTests.cpp ------------------------------*- C++ -*-===// +//===-- PythonDataObjectsTests.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,13 +18,13 @@ #include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" #include "Plugins/SymbolFile/PDB/SymbolFilePDB.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "TestingSupport/TestUtilities.h" #include "lldb/Core/Address.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/LineTable.h" #include "lldb/Symbol/TypeMap.h" @@ -54,7 +54,7 @@ public: HostInfo::Initialize(); ObjectFilePECOFF::Initialize(); SymbolFileDWARF::Initialize(); - ClangASTContext::Initialize(); + TypeSystemClang::Initialize(); SymbolFilePDB::Initialize(); m_pdb_test_exe = GetInputFilePath("test-pdb.exe"); @@ -63,7 +63,7 @@ public: void TearDown() override { SymbolFilePDB::Terminate(); - ClangASTContext::Initialize(); + TypeSystemClang::Initialize(); SymbolFileDWARF::Terminate(); ObjectFilePECOFF::Terminate(); HostInfo::Terminate(); @@ -355,12 +355,13 @@ TEST_F(SymbolFilePDBTests, TestSimpleClassTypes) { llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); llvm::DenseSet searched_files; TypeMap results; - symfile->FindTypes(ConstString("Class"), nullptr, 0, searched_files, results); + symfile->FindTypes(ConstString("Class"), CompilerDeclContext(), 0, + searched_files, results); EXPECT_EQ(1u, results.GetSize()); lldb::TypeSP udt_type = results.GetTypeAtIndex(0); EXPECT_EQ(ConstString("Class"), udt_type->GetName()); CompilerType compiler_type = udt_type->GetForwardCompilerType(); - EXPECT_TRUE(ClangASTContext::IsClassType(compiler_type.GetOpaqueQualType())); + EXPECT_TRUE(TypeSystemClang::IsClassType(compiler_type.GetOpaqueQualType())); EXPECT_EQ(GetGlobalConstantInteger(session, "sizeof_Class"), udt_type->GetByteSize()); } @@ -381,10 +382,11 @@ TEST_F(SymbolFilePDBTests, TestNestedClassTypes) { ASSERT_THAT_EXPECTED(clang_ast_ctx_or_err, llvm::Succeeded()); auto clang_ast_ctx = - llvm::dyn_cast_or_null(&clang_ast_ctx_or_err.get()); + llvm::dyn_cast_or_null(&clang_ast_ctx_or_err.get()); EXPECT_NE(nullptr, clang_ast_ctx); - symfile->FindTypes(ConstString("Class"), nullptr, 0, searched_files, results); + symfile->FindTypes(ConstString("Class"), CompilerDeclContext(), 0, + searched_files, results); EXPECT_EQ(1u, results.GetSize()); auto Class = results.GetTypeAtIndex(0); @@ -404,7 +406,7 @@ TEST_F(SymbolFilePDBTests, TestNestedClassTypes) { TypeMap more_results; auto ClassCompilerDeclCtx = CompilerDeclContext(clang_ast_ctx, ClassDeclCtx); - symfile->FindTypes(ConstString("NestedClass"), &ClassCompilerDeclCtx, 0, + symfile->FindTypes(ConstString("NestedClass"), ClassCompilerDeclCtx, 0, searched_files, more_results); EXPECT_LE(1u, more_results.GetSize()); @@ -412,7 +414,7 @@ TEST_F(SymbolFilePDBTests, TestNestedClassTypes) { EXPECT_EQ(ConstString("NestedClass"), udt_type->GetName()); CompilerType compiler_type = udt_type->GetForwardCompilerType(); - EXPECT_TRUE(ClangASTContext::IsClassType(compiler_type.GetOpaqueQualType())); + EXPECT_TRUE(TypeSystemClang::IsClassType(compiler_type.GetOpaqueQualType())); EXPECT_EQ(GetGlobalConstantInteger(session, "sizeof_NestedClass"), udt_type->GetByteSize()); @@ -434,7 +436,7 @@ TEST_F(SymbolFilePDBTests, TestClassInNamespace) { ASSERT_THAT_EXPECTED(clang_ast_ctx_or_err, llvm::Succeeded()); auto clang_ast_ctx = - llvm::dyn_cast_or_null(&clang_ast_ctx_or_err.get()); + llvm::dyn_cast_or_null(&clang_ast_ctx_or_err.get()); EXPECT_NE(nullptr, clang_ast_ctx); clang::ASTContext &ast_ctx = clang_ast_ctx->getASTContext(); @@ -445,10 +447,10 @@ TEST_F(SymbolFilePDBTests, TestClassInNamespace) { symfile->ParseDeclsForContext(CompilerDeclContext( clang_ast_ctx, static_cast(tu))); - auto ns_namespace = symfile->FindNamespace(ConstString("NS"), nullptr); + auto ns_namespace = symfile->FindNamespace(ConstString("NS"), CompilerDeclContext()); EXPECT_TRUE(ns_namespace.IsValid()); - symfile->FindTypes(ConstString("NSClass"), &ns_namespace, 0, searched_files, + symfile->FindTypes(ConstString("NSClass"), ns_namespace, 0, searched_files, results); EXPECT_EQ(1u, results.GetSize()); @@ -456,7 +458,7 @@ TEST_F(SymbolFilePDBTests, TestClassInNamespace) { EXPECT_EQ(ConstString("NSClass"), udt_type->GetName()); CompilerType compiler_type = udt_type->GetForwardCompilerType(); - EXPECT_TRUE(ClangASTContext::IsClassType(compiler_type.GetOpaqueQualType())); + EXPECT_TRUE(TypeSystemClang::IsClassType(compiler_type.GetOpaqueQualType())); EXPECT_EQ(GetGlobalConstantInteger(session, "sizeof_NSClass"), udt_type->GetByteSize()); @@ -474,13 +476,14 @@ TEST_F(SymbolFilePDBTests, TestEnumTypes) { const char *EnumsToCheck[] = {"Enum", "ShortEnum"}; for (auto Enum : EnumsToCheck) { TypeMap results; - symfile->FindTypes(ConstString(Enum), nullptr, 0, searched_files, results); + symfile->FindTypes(ConstString(Enum), CompilerDeclContext(), 0, + searched_files, results); EXPECT_EQ(1u, results.GetSize()); lldb::TypeSP enum_type = results.GetTypeAtIndex(0); EXPECT_EQ(ConstString(Enum), enum_type->GetName()); CompilerType compiler_type = enum_type->GetFullCompilerType(); - EXPECT_TRUE(ClangASTContext::IsEnumType(compiler_type.GetOpaqueQualType())); - clang::EnumDecl *enum_decl = ClangASTContext::GetAsEnumDecl(compiler_type); + EXPECT_TRUE(TypeSystemClang::IsEnumType(compiler_type.GetOpaqueQualType())); + clang::EnumDecl *enum_decl = TypeSystemClang::GetAsEnumDecl(compiler_type); EXPECT_NE(nullptr, enum_decl); EXPECT_EQ(2, std::distance(enum_decl->enumerator_begin(), enum_decl->enumerator_end())); @@ -522,14 +525,14 @@ TEST_F(SymbolFilePDBTests, TestTypedefs) { "VariadicFuncPointerTypedef"}; for (auto Typedef : TypedefsToCheck) { TypeMap results; - symfile->FindTypes(ConstString(Typedef), nullptr, 0, searched_files, - results); + symfile->FindTypes(ConstString(Typedef), CompilerDeclContext(), 0, + searched_files, results); EXPECT_EQ(1u, results.GetSize()); lldb::TypeSP typedef_type = results.GetTypeAtIndex(0); EXPECT_EQ(ConstString(Typedef), typedef_type->GetName()); CompilerType compiler_type = typedef_type->GetFullCompilerType(); - ClangASTContext *clang_type_system = - llvm::dyn_cast_or_null(compiler_type.GetTypeSystem()); + TypeSystemClang *clang_type_system = + llvm::dyn_cast_or_null(compiler_type.GetTypeSystem()); EXPECT_TRUE( clang_type_system->IsTypedefType(compiler_type.GetOpaqueQualType())); @@ -568,7 +571,7 @@ TEST_F(SymbolFilePDBTests, TestMaxMatches) { llvm::DenseSet searched_files; TypeMap results; const ConstString name("ClassTypedef"); - symfile->FindTypes(name, nullptr, 0, searched_files, results); + symfile->FindTypes(name, CompilerDeclContext(), 0, searched_files, results); // Try to limit ourselves from 1 to 10 results, otherwise we could // be doing this thousands of times. The idea is just to make sure // that for a variety of values, the number of limited results @@ -577,7 +580,8 @@ TEST_F(SymbolFilePDBTests, TestMaxMatches) { uint32_t iterations = std::min(num_results, 10u); for (uint32_t i = 1; i <= iterations; ++i) { TypeMap more_results; - symfile->FindTypes(name, nullptr, i, searched_files, more_results); + symfile->FindTypes(name, CompilerDeclContext(), i, searched_files, + more_results); uint32_t num_limited_results = more_results.GetSize(); EXPECT_EQ(i, num_limited_results); } @@ -592,7 +596,8 @@ TEST_F(SymbolFilePDBTests, TestNullName) { static_cast(module->GetSymbolFile()); llvm::DenseSet searched_files; TypeMap results; - symfile->FindTypes(ConstString(), nullptr, 0, searched_files, results); + symfile->FindTypes(ConstString(), CompilerDeclContext(), 0, searched_files, + results); EXPECT_EQ(0u, results.GetSize()); } diff --git a/gnu/llvm/lldb/unittests/Target/ABITest.cpp b/gnu/llvm/lldb/unittests/Target/ABITest.cpp new file mode 100644 index 00000000000..6ac34c872f2 --- /dev/null +++ b/gnu/llvm/lldb/unittests/Target/ABITest.cpp @@ -0,0 +1,26 @@ +//===-- ABITest.cpp -------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/ABI.h" +#include "gtest/gtest.h" + +using namespace lldb_private; + +TEST(MCBasedABI, MapRegisterName) { + auto map = [](std::string name) { + MCBasedABI::MapRegisterName(name, "foo", "bar"); + return name; + }; + EXPECT_EQ("bar", map("foo")); + EXPECT_EQ("bar0", map("foo0")); + EXPECT_EQ("bar47", map("foo47")); + EXPECT_EQ("foo47x", map("foo47x")); + EXPECT_EQ("fooo47", map("fooo47")); + EXPECT_EQ("bar47", map("bar47")); +} + diff --git a/gnu/llvm/lldb/unittests/Target/CMakeLists.txt b/gnu/llvm/lldb/unittests/Target/CMakeLists.txt index e63b1d077de..2c3ba699b0e 100644 --- a/gnu/llvm/lldb/unittests/Target/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/Target/CMakeLists.txt @@ -1,8 +1,11 @@ add_lldb_unittest(TargetTests + ABITest.cpp ExecutionContextTest.cpp MemoryRegionInfoTest.cpp ModuleCacheTest.cpp PathMappingListTest.cpp + RemoteAwarePlatformTest.cpp + StackFrameRecognizerTest.cpp LINK_LIBS lldbCore @@ -10,6 +13,7 @@ add_lldb_unittest(TargetTests lldbPluginObjectFileELF lldbPluginPlatformLinux lldbPluginSymbolFileSymtab + lldbTarget lldbSymbol lldbUtility lldbUtilityHelpers diff --git a/gnu/llvm/lldb/unittests/Target/ExecutionContextTest.cpp b/gnu/llvm/lldb/unittests/Target/ExecutionContextTest.cpp index 587ce2ec341..5662fda7ea8 100644 --- a/gnu/llvm/lldb/unittests/Target/ExecutionContextTest.cpp +++ b/gnu/llvm/lldb/unittests/Target/ExecutionContextTest.cpp @@ -1,4 +1,4 @@ -//===-- ExecutionContextTest.cpp --------------------------------*- C++ -*-===// +//===-- ExecutionContextTest.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Target/MemoryRegionInfoTest.cpp b/gnu/llvm/lldb/unittests/Target/MemoryRegionInfoTest.cpp index 8baf50d9e10..c272b23b233 100644 --- a/gnu/llvm/lldb/unittests/Target/MemoryRegionInfoTest.cpp +++ b/gnu/llvm/lldb/unittests/Target/MemoryRegionInfoTest.cpp @@ -1,4 +1,4 @@ -//===-- MemoryRegionInfoTest.cpp --------------------------------*- C++ -*-===// +//===-- MemoryRegionInfoTest.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Target/ModuleCacheTest.cpp b/gnu/llvm/lldb/unittests/Target/ModuleCacheTest.cpp index 60e05379dee..273338c8369 100644 --- a/gnu/llvm/lldb/unittests/Target/ModuleCacheTest.cpp +++ b/gnu/llvm/lldb/unittests/Target/ModuleCacheTest.cpp @@ -41,7 +41,6 @@ static const char dummy_remote_dir[] = "bin"; static const char module_name[] = "TestModule.so"; static const char module_uuid[] = "F4E7E991-9B61-6AD4-0073-561AC3D9FA10-C043A476"; -static const uint32_t uuid_bytes = 20; static const size_t module_size = 5602; static FileSpec GetDummyRemotePath() { @@ -87,7 +86,7 @@ void ModuleCacheTest::TryGetAndPut(const FileSpec &cache_dir, ModuleCache mc; ModuleSpec module_spec; module_spec.GetFileSpec() = GetDummyRemotePath(); - module_spec.GetUUID().SetFromStringRef(module_uuid, uuid_bytes); + module_spec.GetUUID().SetFromStringRef(module_uuid); module_spec.SetObjectSize(module_size); ModuleSP module_sp; bool did_create; diff --git a/gnu/llvm/lldb/unittests/Target/PathMappingListTest.cpp b/gnu/llvm/lldb/unittests/Target/PathMappingListTest.cpp index 09d2efdf97f..66fd97c17f6 100644 --- a/gnu/llvm/lldb/unittests/Target/PathMappingListTest.cpp +++ b/gnu/llvm/lldb/unittests/Target/PathMappingListTest.cpp @@ -1,4 +1,4 @@ -//===-- PathMappingListTest.cpp ---------------------------------*- C++ -*-===// +//===-- PathMappingListTest.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Target/RemoteAwarePlatformTest.cpp b/gnu/llvm/lldb/unittests/Target/RemoteAwarePlatformTest.cpp new file mode 100644 index 00000000000..be9fbc347a2 --- /dev/null +++ b/gnu/llvm/lldb/unittests/Target/RemoteAwarePlatformTest.cpp @@ -0,0 +1,94 @@ +//===-- RemoteAwarePlatformTest.cpp ---------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/RemoteAwarePlatform.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Target/Platform.h" +#include "lldb/Target/Process.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using namespace lldb_private; +using namespace lldb; +using namespace testing; + +class RemoteAwarePlatformTester : public RemoteAwarePlatform { +public: + using RemoteAwarePlatform::RemoteAwarePlatform; + + MOCK_METHOD0(GetDescription, const char *()); + MOCK_METHOD0(GetPluginVersion, uint32_t()); + MOCK_METHOD0(GetPluginName, ConstString()); + MOCK_METHOD2(GetSupportedArchitectureAtIndex, bool(uint32_t, ArchSpec &)); + MOCK_METHOD4(Attach, + ProcessSP(ProcessAttachInfo &, Debugger &, Target *, Status &)); + MOCK_METHOD0(CalculateTrapHandlerSymbolNames, void()); + + void SetRemotePlatform(lldb::PlatformSP platform) { + m_remote_platform_sp = platform; + } +}; + +class TargetPlatformTester : public Platform { +public: + using Platform::Platform; + + MOCK_METHOD0(GetDescription, const char *()); + MOCK_METHOD0(GetPluginVersion, uint32_t()); + MOCK_METHOD0(GetPluginName, ConstString()); + MOCK_METHOD2(GetSupportedArchitectureAtIndex, bool(uint32_t, ArchSpec &)); + MOCK_METHOD4(Attach, + ProcessSP(ProcessAttachInfo &, Debugger &, Target *, Status &)); + MOCK_METHOD0(CalculateTrapHandlerSymbolNames, void()); + MOCK_METHOD0(GetUserIDResolver, UserIDResolver &()); + + MOCK_METHOD2(ResolveExecutable, + std::pair(const ModuleSpec &, + const FileSpecList *)); + Status + ResolveExecutable(const ModuleSpec &module_spec, + lldb::ModuleSP &exe_module_sp, + const FileSpecList *module_search_paths_ptr) /*override*/ { + auto pair = ResolveExecutable(module_spec, module_search_paths_ptr); + exe_module_sp = pair.second; + return pair.first; + } +}; + +namespace { +class RemoteAwarePlatformTest : public testing::Test { +public: + static void SetUpTestCase() { FileSystem::Initialize(); } + static void TearDownTestCase() { FileSystem::Terminate(); } +}; +} // namespace + +TEST_F(RemoteAwarePlatformTest, TestResolveExecutabelOnClientByPlatform) { + ModuleSpec executable_spec; + ModuleSP expected_executable(new Module(executable_spec)); + + auto platform_sp = std::make_shared(false); + EXPECT_CALL(*platform_sp, ResolveExecutable(_, _)) + .WillRepeatedly(Return(std::make_pair(Status(), expected_executable))); + + RemoteAwarePlatformTester platform(false); + EXPECT_CALL(platform, GetSupportedArchitectureAtIndex(_, _)) + .WillRepeatedly(Return(false)); + + platform.SetRemotePlatform(platform_sp); + + ModuleSP resolved_sp; + lldb_private::Status status = + platform.ResolveExecutable(executable_spec, resolved_sp, nullptr); + + ASSERT_TRUE(status.Success()); + EXPECT_EQ(expected_executable.get(), resolved_sp.get()); +} diff --git a/gnu/llvm/lldb/unittests/Target/StackFrameRecognizerTest.cpp b/gnu/llvm/lldb/unittests/Target/StackFrameRecognizerTest.cpp new file mode 100644 index 00000000000..067a56a1990 --- /dev/null +++ b/gnu/llvm/lldb/unittests/Target/StackFrameRecognizerTest.cpp @@ -0,0 +1,83 @@ +//===-- StackFrameRecognizerTest.cpp --------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/StackFrameRecognizer.h" +#include "Plugins/Platform/Linux/PlatformLinux.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Utility/Reproducer.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-private.h" +#include "llvm/Support/FormatVariadic.h" +#include "gtest/gtest.h" + +using namespace lldb_private; +using namespace lldb_private::repro; +using namespace lldb; + +namespace { +class StackFrameRecognizerTest : public ::testing::Test { +public: + void SetUp() override { + llvm::cantFail(Reproducer::Initialize(ReproducerMode::Off, llvm::None)); + FileSystem::Initialize(); + HostInfo::Initialize(); + + // Pretend Linux is the host platform. + platform_linux::PlatformLinux::Initialize(); + ArchSpec arch("powerpc64-pc-linux"); + Platform::SetHostPlatform( + platform_linux::PlatformLinux::CreateInstance(true, &arch)); + } + + void TearDown() override { + platform_linux::PlatformLinux::Terminate(); + HostInfo::Terminate(); + FileSystem::Terminate(); + Reproducer::Terminate(); + } +}; + +class DummyStackFrameRecognizer : public StackFrameRecognizer { +public: + std::string GetName() override { return "Dummy StackFrame Recognizer"; } +}; + +void RegisterDummyStackFrameRecognizer() { + static llvm::once_flag g_once_flag; + + llvm::call_once(g_once_flag, []() { + RegularExpressionSP module_regex_sp = nullptr; + RegularExpressionSP symbol_regex_sp(new RegularExpression("boom")); + + StackFrameRecognizerSP dummy_recognizer_sp(new DummyStackFrameRecognizer()); + + StackFrameRecognizerManager::AddRecognizer( + dummy_recognizer_sp, module_regex_sp, symbol_regex_sp, false); + }); +} + +} // namespace + +TEST_F(StackFrameRecognizerTest, NullModuleRegex) { + DebuggerSP debugger_sp = Debugger::CreateInstance(); + ASSERT_TRUE(debugger_sp); + + RegisterDummyStackFrameRecognizer(); + + bool any_printed = false; + StackFrameRecognizerManager::ForEach( + [&any_printed](uint32_t recognizer_id, std::string name, + std::string function, llvm::ArrayRef symbols, + bool regexp) { any_printed = true; }); + + EXPECT_TRUE(any_printed); +} diff --git a/gnu/llvm/lldb/unittests/TestingSupport/CMakeLists.txt b/gnu/llvm/lldb/unittests/TestingSupport/CMakeLists.txt index 7efe6f57d98..3b5662a16e3 100644 --- a/gnu/llvm/lldb/unittests/TestingSupport/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/TestingSupport/CMakeLists.txt @@ -5,9 +5,12 @@ add_lldb_library(lldbUtilityHelpers LINK_LIBS lldbUtility + lldbSymbolHelpers LINK_COMPONENTS Support ObjectYAML ) include_directories(${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include) + +add_subdirectory(Symbol) diff --git a/gnu/llvm/lldb/unittests/TestingSupport/Host/NativeProcessTestUtils.h b/gnu/llvm/lldb/unittests/TestingSupport/Host/NativeProcessTestUtils.h index c72aacd880f..dcd8b092b2e 100644 --- a/gnu/llvm/lldb/unittests/TestingSupport/Host/NativeProcessTestUtils.h +++ b/gnu/llvm/lldb/unittests/TestingSupport/Host/NativeProcessTestUtils.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_unittests_Host_NativeProcessTestUtils_h_ -#define lldb_unittests_Host_NativeProcessTestUtils_h_ +#ifndef LLDB_UNITTESTS_TESTINGSUPPORT_HOST_NATIVEPROCESSTESTUTILS_H +#define LLDB_UNITTESTS_TESTINGSUPPORT_HOST_NATIVEPROCESSTESTUTILS_H #include "lldb/Host/common/NativeProcessProtocol.h" #include "llvm/Testing/Support/Error.h" diff --git a/gnu/llvm/lldb/unittests/TestingSupport/MockTildeExpressionResolver.cpp b/gnu/llvm/lldb/unittests/TestingSupport/MockTildeExpressionResolver.cpp index 032a831b0aa..2e103b9e61f 100644 --- a/gnu/llvm/lldb/unittests/TestingSupport/MockTildeExpressionResolver.cpp +++ b/gnu/llvm/lldb/unittests/TestingSupport/MockTildeExpressionResolver.cpp @@ -1,4 +1,4 @@ -//===----------------- MockTildeExpressionResolver.cpp ----------*- C++ -*-===// +//===-- MockTildeExpressionResolver.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/TestingSupport/MockTildeExpressionResolver.h b/gnu/llvm/lldb/unittests/TestingSupport/MockTildeExpressionResolver.h index 449181fac85..c96e2d248bf 100644 --- a/gnu/llvm/lldb/unittests/TestingSupport/MockTildeExpressionResolver.h +++ b/gnu/llvm/lldb/unittests/TestingSupport/MockTildeExpressionResolver.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_UNITTESTS_UTILITY_MOCKS_MOCK_TILDE_EXPRESSION_RESOLVER_H -#define LLDB_UNITTESTS_UTILITY_MOCKS_MOCK_TILDE_EXPRESSION_RESOLVER_H +#ifndef LLDB_UNITTESTS_TESTINGSUPPORT_MOCKTILDEEXPRESSIONRESOLVER_H +#define LLDB_UNITTESTS_TESTINGSUPPORT_MOCKTILDEEXPRESSIONRESOLVER_H #include "lldb/Utility/TildeExpressionResolver.h" diff --git a/gnu/llvm/lldb/unittests/TestingSupport/Symbol/CMakeLists.txt b/gnu/llvm/lldb/unittests/TestingSupport/Symbol/CMakeLists.txt new file mode 100644 index 00000000000..3f93b941137 --- /dev/null +++ b/gnu/llvm/lldb/unittests/TestingSupport/Symbol/CMakeLists.txt @@ -0,0 +1,13 @@ +set_property(DIRECTORY PROPERTY EXCLUDE_FROM_ALL ON) +add_lldb_library(lldbSymbolHelpers + YAMLModuleTester.cpp + ) + +# Our current version of gtest does not properly recognize C++11 support +# with MSVC, so it falls back to tr1 / experimental classes. Since LLVM +# itself requires C++11, we can safely force it on unconditionally so that +# we don't have to fight with the buggy gtest check. +add_definitions(-DGTEST_LANG_CXX11=1) +add_definitions(-DGTEST_HAS_TR1_TUPLE=0) +include_directories(${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include) +include_directories(${LLVM_MAIN_SRC_DIR}/utils/unittest/googlemock/include) diff --git a/gnu/llvm/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h b/gnu/llvm/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h index 2c94aa5d01c..6524f093ab9 100644 --- a/gnu/llvm/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h +++ b/gnu/llvm/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h @@ -9,49 +9,51 @@ #ifndef LLDB_UNITTESTS_TESTINGSUPPORT_SYMBOL_CLANGTESTUTILS_H #define LLDB_UNITTESTS_TESTINGSUPPORT_SYMBOL_CLANGTESTUTILS_H +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Host/HostInfo.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangUtil.h" namespace lldb_private { namespace clang_utils { -inline clang::DeclarationName getDeclarationName(ClangASTContext &ast, +inline clang::DeclarationName getDeclarationName(TypeSystemClang &ast, llvm::StringRef name) { clang::IdentifierInfo &II = ast.getASTContext().Idents.get(name); return ast.getASTContext().DeclarationNames.getIdentifier(&II); } -inline std::unique_ptr createAST() { - return std::make_unique(HostInfo::GetTargetTriple()); +inline std::unique_ptr createAST() { + return std::make_unique("test ASTContext", + HostInfo::GetTargetTriple()); } -inline CompilerType createRecord(ClangASTContext &ast, llvm::StringRef name) { +inline CompilerType createRecord(TypeSystemClang &ast, llvm::StringRef name) { return ast.CreateRecordType(ast.getASTContext().getTranslationUnitDecl(), + OptionalClangModuleID(), lldb::AccessType::eAccessPublic, name, 0, lldb::LanguageType::eLanguageTypeC); } /// Create a record with the given name and a field with the given type /// and name. -inline CompilerType createRecordWithField(ClangASTContext &ast, +inline CompilerType createRecordWithField(TypeSystemClang &ast, llvm::StringRef record_name, CompilerType field_type, llvm::StringRef field_name) { CompilerType t = createRecord(ast, record_name); - ClangASTContext::StartTagDeclarationDefinition(t); + TypeSystemClang::StartTagDeclarationDefinition(t); ast.AddFieldToRecordType(t, field_name, field_type, lldb::AccessType::eAccessPublic, 7); - ClangASTContext::CompleteTagDeclarationDefinition(t); + TypeSystemClang::CompleteTagDeclarationDefinition(t); return t; } -/// Constructs a ClangASTContext that contains a single RecordDecl that contains +/// Constructs a TypeSystemClang that contains a single RecordDecl that contains /// a single FieldDecl. Utility class as this setup is a common starting point /// for unit test that exercise the ASTImporter. struct SourceASTWithRecord { - std::unique_ptr ast; + std::unique_ptr ast; CompilerType record_type; clang::RecordDecl *record_decl = nullptr; clang::FieldDecl *field_decl = nullptr; diff --git a/gnu/llvm/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp b/gnu/llvm/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp new file mode 100644 index 00000000000..54c2c9441e5 --- /dev/null +++ b/gnu/llvm/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp @@ -0,0 +1,118 @@ +//===-- YAMLModuleTester.cpp ----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "TestingSupport/Symbol/YAMLModuleTester.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" +#include "lldb/Core/Section.h" +#include "llvm/ObjectYAML/DWARFEmitter.h" + +using namespace lldb_private; + +/// A mock module holding an object file parsed from YAML. +class YAMLModule : public lldb_private::Module { +public: + YAMLModule(ArchSpec &arch) : Module(FileSpec("test"), arch) {} + void SetObjectFile(lldb::ObjectFileSP obj_file) { m_objfile_sp = obj_file; } + ObjectFile *GetObjectFile() override { return m_objfile_sp.get(); } +}; + +/// A mock object file that can be parsed from YAML. +class YAMLObjectFile : public lldb_private::ObjectFile { + const lldb::ModuleSP m_module_sp; + llvm::StringMap> &m_section_map; + /// Because there is only one DataExtractor in the ObjectFile + /// interface, all sections are copied into a contiguous buffer. + std::vector m_buffer; + +public: + YAMLObjectFile(const lldb::ModuleSP &module_sp, + llvm::StringMap> &map) + : ObjectFile(module_sp, &module_sp->GetFileSpec(), /*file_offset*/ 0, + /*length*/ 0, /*data_sp*/ nullptr, /*data_offset*/ 0), + m_module_sp(module_sp), m_section_map(map) {} + + /// Callback for initializing the module's list of sections. + void CreateSections(SectionList &unified_section_list) override { + lldb::offset_t total_bytes = 0; + for (auto &entry : m_section_map) + total_bytes += entry.getValue()->getBufferSize(); + m_buffer.reserve(total_bytes); + m_data = + DataExtractor(m_buffer.data(), total_bytes, lldb::eByteOrderLittle, 4); + + lldb::user_id_t sect_id = 1; + for (auto &entry : m_section_map) { + llvm::StringRef name = entry.getKey(); + lldb::SectionType sect_type = + llvm::StringSwitch(name) + .Case("debug_info", lldb::eSectionTypeDWARFDebugInfo) + .Case("debug_abbrev", lldb::eSectionTypeDWARFDebugAbbrev) + .Case("debug_str", lldb::eSectionTypeDWARFDebugStr); + auto &membuf = entry.getValue(); + lldb::addr_t file_vm_addr = 0; + lldb::addr_t vm_size = 0; + lldb::offset_t file_offset = m_buffer.size(); + lldb::offset_t file_size = membuf->getBufferSize(); + m_buffer.resize(file_offset + file_size); + memcpy(m_buffer.data() + file_offset, membuf->getBufferStart(), + file_size); + uint32_t log2align = 0; + uint32_t flags = 0; + auto section_sp = std::make_shared( + m_module_sp, this, sect_id++, ConstString(name), sect_type, + file_vm_addr, vm_size, file_offset, file_size, log2align, flags); + unified_section_list.AddSection(section_sp); + } + } + + /// \{ + /// Stub methods that aren't needed here. + ConstString GetPluginName() override { return ConstString("YAMLObjectFile"); } + uint32_t GetPluginVersion() override { return 0; } + void Dump(Stream *s) override {} + uint32_t GetAddressByteSize() const override { return 8; } + uint32_t GetDependentModules(FileSpecList &file_list) override { return 0; } + bool IsExecutable() const override { return 0; } + ArchSpec GetArchitecture() override { return {}; } + Symtab *GetSymtab() override { return nullptr; } + bool IsStripped() override { return false; } + UUID GetUUID() override { return {}; } + lldb::ByteOrder GetByteOrder() const override { + return lldb::eByteOrderLittle; + } + bool ParseHeader() override { return false; } + Type CalculateType() override { return {}; } + Strata CalculateStrata() override { return {}; } + /// \} +}; + +YAMLModuleTester::YAMLModuleTester(llvm::StringRef yaml_data, + llvm::StringRef triple) { + auto sections_map = llvm::DWARFYAML::emitDebugSections(yaml_data, true); + if (!sections_map) + return; + m_sections_map = std::move(*sections_map); + ArchSpec arch(triple); + m_module_sp = std::make_shared(arch); + m_objfile_sp = std::make_shared(m_module_sp, m_sections_map); + static_cast(m_module_sp.get())->SetObjectFile(m_objfile_sp); + + lldb::user_id_t uid = 0; + llvm::StringRef raw_debug_info = m_sections_map["debug_info"]->getBuffer(); + lldb_private::DataExtractor debug_info( + raw_debug_info.data(), raw_debug_info.size(), + m_objfile_sp->GetByteOrder(), m_objfile_sp->GetAddressByteSize()); + lldb::offset_t offset_ptr = 0; + m_symfile_dwarf = std::make_unique(m_objfile_sp, nullptr); + llvm::Expected dwarf_unit = DWARFUnit::extract( + *m_symfile_dwarf, uid, + *static_cast(&debug_info), + DIERef::DebugInfo, &offset_ptr, nullptr); + if (dwarf_unit) + m_dwarf_unit = dwarf_unit.get(); +} diff --git a/gnu/llvm/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.h b/gnu/llvm/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.h new file mode 100644 index 00000000000..7a638b56e87 --- /dev/null +++ b/gnu/llvm/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.h @@ -0,0 +1,41 @@ +//===- YAMLModuleTester.h ---------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_UNITTESTS_TESTINGSUPPORT_SYMBOL_YAMLMODULETESTER_H +#define LLDB_UNITTESTS_TESTINGSUPPORT_SYMBOL_YAMLMODULETESTER_H + +#include "Plugins/SymbolFile/DWARF/DWARFUnit.h" +#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" +#include "TestingSupport/SubsystemRAII.h" +#include "lldb/Core/Module.h" +#include "lldb/Host/HostInfo.h" + +namespace lldb_private { + +/// Helper class that can construct a module from YAML and evaluate +/// DWARF expressions on it. +class YAMLModuleTester { +protected: + SubsystemRAII subsystems; + llvm::StringMap> m_sections_map; + lldb::ModuleSP m_module_sp; + lldb::ObjectFileSP m_objfile_sp; + DWARFUnitSP m_dwarf_unit; + std::unique_ptr m_symfile_dwarf; + +public: + /// Parse the debug info sections from the YAML description. + YAMLModuleTester(llvm::StringRef yaml_data, llvm::StringRef triple); + DWARFUnitSP GetDwarfUnit() const { return m_dwarf_unit; } + lldb::ModuleSP GetModule() const { return m_module_sp; } +}; + +} // namespace lldb_private + +#endif // LLDB_UNITTESTS_TESTINGSUPPORT_SYMBOL_YAMLMODULETESTER_H diff --git a/gnu/llvm/lldb/unittests/TestingSupport/TestUtilities.cpp b/gnu/llvm/lldb/unittests/TestingSupport/TestUtilities.cpp index f4f6f79bac1..4d369bd0968 100644 --- a/gnu/llvm/lldb/unittests/TestingSupport/TestUtilities.cpp +++ b/gnu/llvm/lldb/unittests/TestingSupport/TestUtilities.cpp @@ -1,4 +1,4 @@ -//===- TestUtilities.cpp ----------------------------------------*- C++ -*-===// +//===-- TestUtilities.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -23,27 +23,19 @@ std::string lldb_private::GetInputFilePath(const llvm::Twine &name) { llvm::SmallString<128> result = llvm::sys::path::parent_path(TestMainArgv0); llvm::sys::fs::make_absolute(result); llvm::sys::path::append(result, "Inputs", name); - return result.str(); + return std::string(result.str()); } llvm::Expected TestFile::fromYaml(llvm::StringRef Yaml) { - const auto *Info = testing::UnitTest::GetInstance()->current_test_info(); - assert(Info); - llvm::SmallString<128> Name; - int FD; - if (std::error_code EC = llvm::sys::fs::createTemporaryFile( - llvm::Twine(Info->test_case_name()) + "-" + Info->name(), "test", FD, - Name)) - return llvm::errorCodeToError(EC); - llvm::FileRemover Remover(Name); - { - llvm::raw_fd_ostream OS(FD, /*shouldClose*/ true); - llvm::yaml::Input YIn(Yaml); - if (!llvm::yaml::convertYAML(YIn, OS, [](const llvm::Twine &Msg) {})) - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "convertYAML() failed"); - } - return TestFile(Name, std::move(Remover)); + assert(testing::UnitTest::GetInstance()->current_test_info()); + + std::string Buffer; + llvm::raw_string_ostream OS(Buffer); + llvm::yaml::Input YIn(Yaml); + if (!llvm::yaml::convertYAML(YIn, OS, [](const llvm::Twine &Msg) {})) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "convertYAML() failed"); + return TestFile(std::move(Buffer)); } llvm::Expected TestFile::fromYamlFile(const llvm::Twine &Name) { @@ -54,12 +46,3 @@ llvm::Expected TestFile::fromYamlFile(const llvm::Twine &Name) { return llvm::errorCodeToError(BufferOrError.getError()); return fromYaml(BufferOrError.get()->getBuffer()); } - -TestFile::~TestFile() { - if (!Name) - return; - if (std::error_code EC = - llvm::sys::fs::remove(*Name, /*IgnoreNonExisting*/ false)) - GTEST_LOG_(WARNING) << "Failed to delete `" << Name->c_str() - << "`: " << EC.message(); -} diff --git a/gnu/llvm/lldb/unittests/TestingSupport/TestUtilities.h b/gnu/llvm/lldb/unittests/TestingSupport/TestUtilities.h index 407ff4a9b54..60a07119e92 100644 --- a/gnu/llvm/lldb/unittests/TestingSupport/TestUtilities.h +++ b/gnu/llvm/lldb/unittests/TestingSupport/TestUtilities.h @@ -6,9 +6,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_UNITTESTS_UTILITY_HELPERS_TESTUTILITIES_H -#define LLDB_UNITTESTS_UTILITY_HELPERS_TESTUTILITIES_H +#ifndef LLDB_UNITTESTS_TESTINGSUPPORT_TESTUTILITIES_H +#define LLDB_UNITTESTS_TESTINGSUPPORT_TESTUTILITIES_H +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Utility/DataBuffer.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Error.h" @@ -34,21 +36,24 @@ public: static llvm::Expected fromYaml(llvm::StringRef Yaml); static llvm::Expected fromYamlFile(const llvm::Twine &Name); - TestFile(TestFile &&RHS) : Name(std::move(RHS.Name)) { - RHS.Name = llvm::None; + ~TestFile() = default; + + ModuleSpec moduleSpec() { + return ModuleSpec(FileSpec(), UUID(), dataBuffer()); } - ~TestFile(); +private: + TestFile(std::string &&Buffer) : Buffer(std::move(Buffer)) {} - llvm::StringRef name() { return *Name; } + void operator=(const TestFile &) = delete; -private: - TestFile(llvm::StringRef Name, llvm::FileRemover &&Remover) : Name(Name) { - Remover.releaseFile(); + lldb::DataBufferSP dataBuffer() { + auto *Data = reinterpret_cast(Buffer.data()); + return std::make_shared(const_cast(Data), + Buffer.size()); } - void operator=(const TestFile &) = delete; - llvm::Optional Name; + std::string Buffer; }; } diff --git a/gnu/llvm/lldb/unittests/TestingSupport/module.modulemap b/gnu/llvm/lldb/unittests/TestingSupport/module.modulemap index b73ac279327..81d2b988875 100644 --- a/gnu/llvm/lldb/unittests/TestingSupport/module.modulemap +++ b/gnu/llvm/lldb/unittests/TestingSupport/module.modulemap @@ -13,4 +13,5 @@ module lldb_TestingSupport_Host { module lldb_TestingSupport_Symbol { requires cplusplus module ClangTestUtils { header "Symbol/ClangTestUtils.h" export * } + module YAMLModuleTester { header "Symbol/YAMLModuleTester.h" export * } } diff --git a/gnu/llvm/lldb/unittests/Thread/CMakeLists.txt b/gnu/llvm/lldb/unittests/Thread/CMakeLists.txt new file mode 100644 index 00000000000..d6e365adac5 --- /dev/null +++ b/gnu/llvm/lldb/unittests/Thread/CMakeLists.txt @@ -0,0 +1,15 @@ +add_lldb_unittest(ThreadTests + ThreadTest.cpp + + LINK_LIBS + lldbCore + lldbHost + lldbTarget + lldbSymbol + lldbUtility + lldbUtilityHelpers + lldbInterpreter + lldbBreakpoint + lldbPluginPlatformLinux + ) + diff --git a/gnu/llvm/lldb/unittests/Thread/ThreadTest.cpp b/gnu/llvm/lldb/unittests/Thread/ThreadTest.cpp new file mode 100644 index 00000000000..9a79bbc12ca --- /dev/null +++ b/gnu/llvm/lldb/unittests/Thread/ThreadTest.cpp @@ -0,0 +1,168 @@ +//===-- ThreadTest.cpp ------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/Thread.h" +#include "Plugins/Platform/Linux/PlatformLinux.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/StopInfo.h" +#include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/Reproducer.h" +#include "gtest/gtest.h" + +using namespace lldb_private; +using namespace lldb_private::repro; +using namespace lldb; + +namespace { +class ThreadTest : public ::testing::Test { +public: + void SetUp() override { + llvm::cantFail(Reproducer::Initialize(ReproducerMode::Off, llvm::None)); + FileSystem::Initialize(); + HostInfo::Initialize(); + platform_linux::PlatformLinux::Initialize(); + } + void TearDown() override { + platform_linux::PlatformLinux::Terminate(); + HostInfo::Terminate(); + FileSystem::Terminate(); + Reproducer::Terminate(); + } +}; + +class DummyProcess : public Process { +public: + using Process::Process; + + virtual bool CanDebug(lldb::TargetSP target, bool plugin_specified_by_name) { + return true; + } + virtual Status DoDestroy() { return {}; } + virtual void RefreshStateAfterStop() {} + virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, + Status &error) { + return 0; + } + virtual bool UpdateThreadList(ThreadList &old_thread_list, + ThreadList &new_thread_list) { + return false; + } + virtual ConstString GetPluginName() { return ConstString("Dummy"); } + virtual uint32_t GetPluginVersion() { return 0; } + + ProcessModID &GetModIDNonConstRef() { return m_mod_id; } +}; + +class DummyThread : public Thread { +public: + using Thread::Thread; + + ~DummyThread() override { DestroyThread(); } + + void RefreshStateAfterStop() override {} + + lldb::RegisterContextSP GetRegisterContext() override { return nullptr; } + + lldb::RegisterContextSP + CreateRegisterContextForFrame(StackFrame *frame) override { + return nullptr; + } + + bool CalculateStopInfo() override { return false; } + + bool IsStillAtLastBreakpointHit() override { return true; } +}; +} // namespace + +TargetSP CreateTarget(DebuggerSP &debugger_sp, ArchSpec &arch) { + Status error; + PlatformSP platform_sp; + TargetSP target_sp; + error = debugger_sp->GetTargetList().CreateTarget( + *debugger_sp, "", arch, eLoadDependentsNo, platform_sp, target_sp); + + if (target_sp) { + debugger_sp->GetTargetList().SetSelectedTarget(target_sp.get()); + } + + return target_sp; +} + +TEST_F(ThreadTest, SetStopInfo) { + ArchSpec arch("powerpc64-pc-linux"); + + Platform::SetHostPlatform( + platform_linux::PlatformLinux::CreateInstance(true, &arch)); + + DebuggerSP debugger_sp = Debugger::CreateInstance(); + ASSERT_TRUE(debugger_sp); + + TargetSP target_sp = CreateTarget(debugger_sp, arch); + ASSERT_TRUE(target_sp); + + ListenerSP listener_sp(Listener::MakeListener("dummy")); + ProcessSP process_sp = std::make_shared(target_sp, listener_sp); + ASSERT_TRUE(process_sp); + + DummyProcess *process = static_cast(process_sp.get()); + + ThreadSP thread_sp = std::make_shared(*process_sp.get(), 0); + ASSERT_TRUE(thread_sp); + + StopInfoSP stopinfo_sp = + StopInfo::CreateStopReasonWithBreakpointSiteID(*thread_sp.get(), 0); + ASSERT_TRUE(stopinfo_sp->IsValid() == true); + + /* + Should make stopinfo valid. + */ + process->GetModIDNonConstRef().BumpStopID(); + ASSERT_TRUE(stopinfo_sp->IsValid() == false); + + thread_sp->SetStopInfo(stopinfo_sp); + ASSERT_TRUE(stopinfo_sp->IsValid() == true); +} + +TEST_F(ThreadTest, GetPrivateStopInfo) { + ArchSpec arch("powerpc64-pc-linux"); + + Platform::SetHostPlatform( + platform_linux::PlatformLinux::CreateInstance(true, &arch)); + + DebuggerSP debugger_sp = Debugger::CreateInstance(); + ASSERT_TRUE(debugger_sp); + + TargetSP target_sp = CreateTarget(debugger_sp, arch); + ASSERT_TRUE(target_sp); + + ListenerSP listener_sp(Listener::MakeListener("dummy")); + ProcessSP process_sp = std::make_shared(target_sp, listener_sp); + ASSERT_TRUE(process_sp); + + DummyProcess *process = static_cast(process_sp.get()); + + ThreadSP thread_sp = std::make_shared(*process_sp.get(), 0); + ASSERT_TRUE(thread_sp); + + StopInfoSP stopinfo_sp = + StopInfo::CreateStopReasonWithBreakpointSiteID(*thread_sp.get(), 0); + ASSERT_TRUE(stopinfo_sp); + + thread_sp->SetStopInfo(stopinfo_sp); + + /* + Should make stopinfo valid if thread is at last breakpoint hit. + */ + process->GetModIDNonConstRef().BumpStopID(); + ASSERT_TRUE(stopinfo_sp->IsValid() == false); + StopInfoSP new_stopinfo_sp = thread_sp->GetPrivateStopInfo(); + ASSERT_TRUE(new_stopinfo_sp && stopinfo_sp->IsValid() == true); +} diff --git a/gnu/llvm/lldb/unittests/UnwindAssembly/ARM64/CMakeLists.txt b/gnu/llvm/lldb/unittests/UnwindAssembly/ARM64/CMakeLists.txt index 77924792fe5..f3bbd71df32 100644 --- a/gnu/llvm/lldb/unittests/UnwindAssembly/ARM64/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/UnwindAssembly/ARM64/CMakeLists.txt @@ -5,7 +5,7 @@ add_lldb_unittest(Arm64InstEmulationTests lldbSymbol lldbTarget lldbPluginUnwindAssemblyInstEmulation - lldbPluginDisassemblerLLVM + lldbPluginDisassemblerLLVMC lldbPluginInstructionARM64 lldbPluginProcessUtility LINK_COMPONENTS diff --git a/gnu/llvm/lldb/unittests/UnwindAssembly/ARM64/TestArm64InstEmulation.cpp b/gnu/llvm/lldb/unittests/UnwindAssembly/ARM64/TestArm64InstEmulation.cpp index ffa94356417..6c8bfa1a57f 100644 --- a/gnu/llvm/lldb/unittests/UnwindAssembly/ARM64/TestArm64InstEmulation.cpp +++ b/gnu/llvm/lldb/unittests/UnwindAssembly/ARM64/TestArm64InstEmulation.cpp @@ -1,5 +1,4 @@ -//===-- TestArm64InstEmulation.cpp ------------------------------------*- C++ -//-*-===// +//===-- TestArm64InstEmulation.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -20,7 +19,7 @@ #include "lldb/Target/UnwindAssembly.h" #include "lldb/Utility/ArchSpec.h" -#include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h" +#include "Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h" #include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h" #include "Plugins/Process/Utility/lldb-arm64-register-enums.h" #include "llvm/Support/TargetSelect.h" @@ -680,8 +679,8 @@ TEST_F(TestArm64InstEmulation, TestRegisterDoubleSpills) { } } -TEST_F(TestArm64InstEmulation, TestRetguardEmptyFunction) { - ArchSpec arch("arm64-unknown-openbsd6.4"); +TEST_F(TestArm64InstEmulation, TestCFARegisterTrackedAcrossJumps) { + ArchSpec arch("arm64-apple-ios10"); std::unique_ptr engine( static_cast( UnwindAssemblyInstEmulation::CreateInstance(arch))); @@ -692,67 +691,90 @@ TEST_F(TestArm64InstEmulation, TestRetguardEmptyFunction) { UnwindPlan unwind_plan(eRegisterKindLLDB); UnwindPlan::Row::RegisterLocation regloc; - // void main() { } compiled on arm64-unknown-openbsd6.4 with -fret-protector uint8_t data[] = { - 0x2f, 0x37, 0x00, 0xf0, // 0: adrp x15, #7237632 - 0xef, 0x35, 0x43, 0xf9, // 4: ldr x15, [x15, #1640] - 0xef, 0x01, 0x1e, 0xca, // 8: eor x15, x15, x30 - 0xef, 0x0f, 0x1f, 0xf8, // 12: str x15, [sp, #-16]! - 0xef, 0x07, 0x41, 0xf8, // 16: ldr x15, [sp], #16 - 0x29, 0x37, 0x00, 0xf0, // 20: adrp x9, #7237632 - 0x29, 0x35, 0x43, 0xf9, // 24: ldr x9, [x9, #1640] - 0xef, 0x01, 0x1e, 0xca, // 28: eor x15, x15, x30 - 0xef, 0x01, 0x09, 0xeb, // 32: subs x15, x15, x9 - 0x4f, 0x00, 0x00, 0xb4, // 36: cbz x15, #8 - 0x20, 0x00, 0x20, 0xd4, // 40: brk #0x1 - 0xc0, 0x03, 0x5f, 0xd6, // 44: ret + // prologue + 0xf4, 0x4f, 0xbe, 0xa9, // 0: 0xa9be4ff4 stp x20, x19, [sp, #-0x20]! + 0xfd, 0x7b, 0x01, 0xa9, // 4: 0xa9017bfd stp x29, x30, [sp, #0x10] + 0xfd, 0x43, 0x00, 0x91, // 8: 0x910043fd add x29, sp, #0x10 + 0xff, 0x43, 0x00, 0xd1, // 12: 0xd10043ff sub sp, sp, #0x10 + // conditional branch over a mid-function epilogue + 0xeb, 0x00, 0x00, 0x54, // 16: 0x540000eb b.lt <+44> + // mid-function epilogue + 0x1f, 0x20, 0x03, 0xd5, // 20: 0xd503201f nop + 0xe0, 0x03, 0x13, 0xaa, // 24: 0xaa1303e0 mov x0, x19 + 0xbf, 0x43, 0x00, 0xd1, // 28: 0xd10043bf sub sp, x29, #0x10 + 0xfd, 0x7b, 0x41, 0xa9, // 32: 0xa9417bfd ldp x29, x30, [sp, #0x10] + 0xf4, 0x4f, 0xc2, 0xa8, // 36: 0xa8c24ff4 ldp x20, x19, [sp], #0x20 + 0xc0, 0x03, 0x5f, 0xd6, // 40: 0xd65f03c0 ret + // unwind state restored, we're using a frame pointer, let's change the + // stack pointer and see no change in how the CFA is computed + 0x1f, 0x20, 0x03, 0xd5, // 44: 0xd503201f nop + 0xff, 0x43, 0x00, 0xd1, // 48: 0xd10043ff sub sp, sp, #0x10 + 0x1f, 0x20, 0x03, 0xd5, // 52: 0xd503201f nop + // final epilogue + 0xe0, 0x03, 0x13, 0xaa, // 56: 0xaa1303e0 mov x0, x19 + 0xbf, 0x43, 0x00, 0xd1, // 60: 0xd10043bf sub sp, x29, #0x10 + 0xfd, 0x7b, 0x41, 0xa9, // 64: 0xa9417bfd ldp x29, x30, [sp, #0x10] + 0xf4, 0x4f, 0xc2, 0xa8, // 68: 0xa8c24ff4 ldp x20, x19, [sp], #0x20 + 0xc0, 0x03, 0x5f, 0xd6, // 72: 0xd65f03c0 ret + + 0x1f, 0x20, 0x03, 0xd5, // 52: 0xd503201f nop }; - // UnwindPlan we expect - // 0: CFA=sp+0 - // 16: CFA=sp+16 - // 20: CFA=sp+0 + // UnwindPlan we expect: + // row[0]: 0: CFA=sp +0 => + // row[1]: 4: CFA=sp+32 => x19=[CFA-24] x20=[CFA-32] + // row[2]: 8: CFA=sp+32 => x19=[CFA-24] x20=[CFA-32] fp=[CFA-16] lr=[CFA-8] + // row[3]: 12: CFA=fp+16 => x19=[CFA-24] x20=[CFA-32] fp=[CFA-16] lr=[CFA-8] + // row[4]: 32: CFA=sp+32 => x19=[CFA-24] x20=[CFA-32] fp=[CFA-16] lr=[CFA-8] + // row[5]: 36: CFA=sp+32 => x19=[CFA-24] x20=[CFA-32] fp= lr= + // row[6]: 40: CFA=sp +0 => x19= x20= fp= lr= + // row[7]: 44: CFA=fp+16 => x19=[CFA-24] x20=[CFA-32] fp=[CFA-16] lr=[CFA-8] + // row[8]: 64: CFA=sp+32 => x19=[CFA-24] x20=[CFA-32] fp=[CFA-16] lr=[CFA-8] + // row[9]: 68: CFA=sp+32 => x19=[CFA-24] x20=[CFA-32] fp= lr= + // row[10]: 72: CFA=sp +0 => x19= x20= fp= lr= + + // The specific bug we're looking for is this incorrect CFA definition, + // where the InstEmulation is using the $sp value mixed in with $fp, + // it looks like this: + // + // row[7]: 44: CFA=fp+16 => x19=[CFA-24] x20=[CFA-32] fp=[CFA-16] lr=[CFA-8] + // row[8]: 52: CFA=fp+64 => x19=[CFA-24] x20=[CFA-32] fp=[CFA-16] lr=[CFA-8] + // row[9]: 68: CFA=fp+64 => x19=[CFA-24] x20=[CFA-32] fp= lr= + sample_range = AddressRange(0x1000, sizeof(data)); EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( sample_range, data, sizeof(data), unwind_plan)); - // 0: CFA=sp+0 - row_sp = unwind_plan.GetRowForFunctionOffset(0); - EXPECT_EQ(0ull, row_sp->GetOffset()); + // Confirm CFA at mid-func epilogue 'ret' is $sp+0 + row_sp = unwind_plan.GetRowForFunctionOffset(40); + EXPECT_EQ(40ull, row_sp->GetOffset()); EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(4); - EXPECT_EQ(0ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(8); - EXPECT_EQ(0ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(12); - EXPECT_EQ(0ull, row_sp->GetOffset()); + // After the 'ret', confirm we're back to the correct CFA of $fp+16 + row_sp = unwind_plan.GetRowForFunctionOffset(44); + EXPECT_EQ(44ull, row_sp->GetOffset()); + EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_fp_arm64); + EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); + EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - // 16: CFA=sp+16 - row_sp = unwind_plan.GetRowForFunctionOffset(16); - EXPECT_EQ(16ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); + // Confirm that we have no additional UnwindPlan rows before the + // real epilogue -- we still get the Row at offset 44. + row_sp = unwind_plan.GetRowForFunctionOffset(60); + EXPECT_EQ(44ull, row_sp->GetOffset()); + EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_fp_arm64); EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - // 20: CFA=sp+0 - row_sp = unwind_plan.GetRowForFunctionOffset(20); - EXPECT_EQ(20ull, row_sp->GetOffset()); + // And in the epilogue, confirm that we start by switching back to + // defining the CFA in terms of $sp. + row_sp = unwind_plan.GetRowForFunctionOffset(64); + EXPECT_EQ(64ull, row_sp->GetOffset()); EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == gpr_sp_arm64); EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(0, row_sp->GetCFAValue().GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(24); - EXPECT_EQ(20ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(28); - EXPECT_EQ(20ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(32); - EXPECT_EQ(20ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(36); - EXPECT_EQ(20ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(40); - EXPECT_EQ(20ull, row_sp->GetOffset()); + EXPECT_EQ(32, row_sp->GetCFAValue().GetOffset()); } + diff --git a/gnu/llvm/lldb/unittests/UnwindAssembly/PPC64/CMakeLists.txt b/gnu/llvm/lldb/unittests/UnwindAssembly/PPC64/CMakeLists.txt index d803f459363..679f7664cb8 100644 --- a/gnu/llvm/lldb/unittests/UnwindAssembly/PPC64/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/UnwindAssembly/PPC64/CMakeLists.txt @@ -5,7 +5,7 @@ add_lldb_unittest(PPC64InstEmulationTests lldbSymbol lldbTarget lldbPluginUnwindAssemblyInstEmulation - lldbPluginDisassemblerLLVM + lldbPluginDisassemblerLLVMC lldbPluginInstructionPPC64 lldbPluginProcessUtility LINK_COMPONENTS diff --git a/gnu/llvm/lldb/unittests/UnwindAssembly/PPC64/TestPPC64InstEmulation.cpp b/gnu/llvm/lldb/unittests/UnwindAssembly/PPC64/TestPPC64InstEmulation.cpp index faae6063841..9892e18d99c 100644 --- a/gnu/llvm/lldb/unittests/UnwindAssembly/PPC64/TestPPC64InstEmulation.cpp +++ b/gnu/llvm/lldb/unittests/UnwindAssembly/PPC64/TestPPC64InstEmulation.cpp @@ -1,4 +1,4 @@ -//===-- TestPPC64InstEmulation.cpp ------------------------------*- C++ -*-===// +//===-- TestPPC64InstEmulation.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,7 +18,7 @@ #include "lldb/Target/UnwindAssembly.h" #include "lldb/Utility/ArchSpec.h" -#include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h" +#include "Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h" #include "Plugins/Instruction/PPC64/EmulateInstructionPPC64.h" #include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h" #include "llvm/Support/TargetSelect.h" diff --git a/gnu/llvm/lldb/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp b/gnu/llvm/lldb/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp index b06dfb6bfb7..277cc14ce50 100644 --- a/gnu/llvm/lldb/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp +++ b/gnu/llvm/lldb/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp @@ -1,5 +1,4 @@ -//===-- Testx86AssemblyInspectionEngine.cpp ---------------------------*- C++ -//-*-===// +//===-- Testx86AssemblyInspectionEngine.cpp -------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -2644,181 +2643,6 @@ TEST_F(Testx86AssemblyInspectionEngine, TestDisassemblyJunkBytes) { } -TEST_F(Testx86AssemblyInspectionEngine, TestRetguard64bitFrameFunction) { - std::unique_ptr engine = Getx86_64Inspector(); - - // 'int main() { }' compiled for amd64-unknown-openbsd6.4 with -fret-protector - uint8_t data[] = { - 0x4c, 0x8b, 0x1d, 0xf1, 0x0c, 0x00, 0x00, // offset 0 -- movq 3313(%rip), %r11 - 0x4c, 0x33, 0x1c, 0x24, // offset 7 -- xorq (%rsp), %r11 - 0x55, // offset 11 -- pushq %rbp - 0x48, 0x89, 0xe5, // offset 12 -- movq %rsp, %rbp - 0x41, 0x53, // offset 15 -- pushq %r11 - 0x31, 0xc0, // offset 17 -- xorl %eax, %eax - 0x41, 0x5b, // offset 19 -- popq %r11 - 0x5d, // offset 21 -- popq %rbp - 0x4c, 0x33, 0x1c, 0x24, // offset 22 -- xorq (%rsp), %r11 - 0x4c, 0x3b, 0x1d, 0xd7, 0x0c, 0x00, 0x00, // offset 26 -- cmp 3287(%rsp), %r11 - 0x0f, 0x84, 0x02, 0x00, 0x00, 0x00, // offset 33 -- je +2 - 0xcc, // offset 39 -- int3 - 0xcc, // offset 40 -- int3 - 0xc3 // offset 41 -- retq - }; - - AddressRange sample_range(0x1000, sizeof(data)); - - UnwindPlan unwind_plan(eRegisterKindLLDB); - EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - data, sizeof(data), sample_range, unwind_plan)); - - // We expect 4 rows in the unwind plan, corresponding to offsets - // 0: CFA=rsp+8 => rsp=CFA+0, rip=[CFA-8] - // 12: CFA=rsp+16 => rsp=CFA+0, rip=[CFA-8], rbp=[CFA-16] - // 15: CFA=rbp+16 => rsp=CFA+0, rip=[CFA-8], rbp=[CFA-16] - // 22: CFA=rsp+8 => rsp=CFA+0, rip=[CFA-8] - - EXPECT_TRUE(unwind_plan.GetInitialCFARegister() == k_rsp); - EXPECT_TRUE(unwind_plan.GetUnwindPlanValidAtAllInstructions() == - eLazyBoolYes); - EXPECT_TRUE(unwind_plan.GetSourcedFromCompiler() == eLazyBoolNo); - - UnwindPlan::Row::RegisterLocation regloc; - - // 0: CFA=rsp+8 => rsp=CFA+0, rip=[CFA-8] - UnwindPlan::RowSP row_sp = unwind_plan.GetRowForFunctionOffset(0); - EXPECT_EQ(0ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rsp, regloc)); - EXPECT_TRUE(regloc.IsCFAPlusOffset()); - EXPECT_EQ(0, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(7); - EXPECT_EQ(0ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(11); - EXPECT_EQ(0ull, row_sp->GetOffset()); - - // 12: CFA=rsp+16 => rsp=CFA+0, rip=[CFA-8], rbp=[CFA-16] - row_sp = unwind_plan.GetRowForFunctionOffset(12); - EXPECT_EQ(12ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rsp, regloc)); - EXPECT_TRUE(regloc.IsCFAPlusOffset()); - EXPECT_EQ(0, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rbp, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-16, regloc.GetOffset()); - - // 15: CFA=rbp+16 => rsp=CFA+0, rip=[CFA-8], rbp=[CFA-16] - row_sp = unwind_plan.GetRowForFunctionOffset(15); - EXPECT_EQ(15ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rbp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(16, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rsp, regloc)); - EXPECT_TRUE(regloc.IsCFAPlusOffset()); - EXPECT_EQ(0, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rbp, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-16, regloc.GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(17); - EXPECT_EQ(15ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(19); - EXPECT_EQ(15ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(21); - EXPECT_EQ(15ull, row_sp->GetOffset()); - - // 22: CFA=rsp+8 => rsp=CFA+0, rip=[CFA-8] - row_sp = unwind_plan.GetRowForFunctionOffset(22); - EXPECT_EQ(22ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rsp, regloc)); - EXPECT_TRUE(regloc.IsCFAPlusOffset()); - EXPECT_EQ(0, regloc.GetOffset()); - - EXPECT_TRUE(row_sp->GetRegisterInfo(k_rip, regloc)); - EXPECT_TRUE(regloc.IsAtCFAPlusOffset()); - EXPECT_EQ(-8, regloc.GetOffset()); - - row_sp = unwind_plan.GetRowForFunctionOffset(26); - EXPECT_EQ(22ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(33); - EXPECT_EQ(22ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(39); - EXPECT_EQ(22ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(40); - EXPECT_EQ(22ull, row_sp->GetOffset()); - row_sp = unwind_plan.GetRowForFunctionOffset(41); - EXPECT_EQ(22ull, row_sp->GetOffset()); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestSimple64bitPrologueDetection) { - std::unique_ptr engine = Getx86_64Inspector(); - - // 'int main() { }' compiled for x86_64-apple-macosx with clang - uint8_t data[] = { - 0x55, // offset 0 -- pushq %rbp - 0x48, 0x89, 0xe5, // offset 1 -- movq %rsp, %rbp - 0x31, 0xc0, // offset 4 -- xorl %eax, %eax - 0x5d, // offset 6 -- popq %rbp - 0xc3 // offset 7 -- retq - }; - - size_t offset = 0; - EXPECT_TRUE(engine->FindFirstNonPrologueInstruction(data, sizeof(data), offset)); - EXPECT_EQ(4ull, offset); -} - -TEST_F(Testx86AssemblyInspectionEngine, TestRetguard64bitPrologueDetection) { - std::unique_ptr engine = Getx86_64Inspector(); - - // 'int main() { }' compiled for amd64-unknown-openbsd6.4 with -fret-protector - uint8_t data[] = { - 0x4c, 0x8b, 0x1d, 0xf1, 0x0c, 0x00, 0x00, // offset 0 -- movq 3313(%rip), %r11 - 0x4c, 0x33, 0x1c, 0x24, // offset 7 -- xorq (%rsp), %r11 - 0x55, // offset 11 -- pushq %rbp - 0x48, 0x89, 0xe5, // offset 12 -- movq %rsp, %rbp - 0x41, 0x53, // offset 15 -- pushq %r11 - 0x31, 0xc0, // offset 17 -- xorl %eax, %eax - 0x41, 0x5b, // offset 19 -- popq %r11 - 0x5d, // offset 21 -- popq %rbp - 0x4c, 0x33, 0x1c, 0x24, // offset 22 -- xorq (%rsp), %r11 - 0x4c, 0x3b, 0x1d, 0xd7, 0x0c, 0x00, 0x00, // offset 26 -- cmp 3287(%rsp), %r11 - 0x0f, 0x84, 0x02, 0x00, 0x00, 0x00, // offset 33 -- je +2 - 0xcc, // offset 39 -- int3 - 0xcc, // offset 40 -- int3 - 0xc3 // offset 41 -- retq - }; - - size_t offset = 0; - EXPECT_TRUE(engine->FindFirstNonPrologueInstruction(data, sizeof(data), offset)); - EXPECT_EQ(17ull, offset); -} - TEST_F(Testx86AssemblyInspectionEngine, TestReturnDetect) { std::unique_ptr engine = Getx86_64Inspector(); @@ -2846,11 +2670,6 @@ TEST_F(Testx86AssemblyInspectionEngine, TestReturnDetect) { UnwindPlan unwind_plan(eRegisterKindLLDB); EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( - UnwindPlan::RowSP row_sp = unwind_plan.GetRowForFunctionOffset(0); - EXPECT_EQ(0ull, row_sp->GetOffset()); - EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); - EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); - EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); data, sizeof(data), sample_range, unwind_plan)); // Expect following unwind rows: diff --git a/gnu/llvm/lldb/unittests/Utility/AnsiTerminalTest.cpp b/gnu/llvm/lldb/unittests/Utility/AnsiTerminalTest.cpp index 5361b0b9590..a6dbfd61061 100644 --- a/gnu/llvm/lldb/unittests/Utility/AnsiTerminalTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/AnsiTerminalTest.cpp @@ -1,4 +1,4 @@ -//===-- AnsiTerminalTest.cpp ------------------------------------*- C++ -*-===// +//===-- AnsiTerminalTest.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/ArchSpecTest.cpp b/gnu/llvm/lldb/unittests/Utility/ArchSpecTest.cpp index 9115808c125..4e8e2f3c34d 100644 --- a/gnu/llvm/lldb/unittests/Utility/ArchSpecTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/ArchSpecTest.cpp @@ -1,4 +1,4 @@ -//===-- ArchSpecTest.cpp ----------------------------------------*- C++ -*-===// +//===-- ArchSpecTest.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,8 +9,9 @@ #include "gtest/gtest.h" #include "lldb/Utility/ArchSpec.h" -#include "llvm/BinaryFormat/MachO.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/BinaryFormat/MachO.h" +#include "llvm/Support/YAMLParser.h" using namespace lldb; using namespace lldb_private; @@ -200,14 +201,14 @@ TEST(ArchSpecTest, MergeFrom) { EXPECT_TRUE(A.IsValid()); EXPECT_TRUE(B.IsValid()); - + EXPECT_EQ(llvm::Triple::ArchType::arm, B.GetTriple().getArch()); EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor, B.GetTriple().getVendor()); EXPECT_EQ(llvm::Triple::OSType::Linux, B.GetTriple().getOS()); EXPECT_EQ(llvm::Triple::EnvironmentType::UnknownEnvironment, B.GetTriple().getEnvironment()); - + A.MergeFrom(B); EXPECT_EQ(llvm::Triple::ArchType::arm, A.GetTriple().getArch()); EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor, @@ -280,7 +281,7 @@ TEST(ArchSpecTest, Compatibility) { ASSERT_TRUE(A.IsCompatibleMatch(B)); } { - // The version information is auxiliary to support availablity but + // The version information is auxiliary to support availability but // doesn't affect compatibility. ArchSpec A("x86_64-apple-macosx10.11"); ArchSpec B("x86_64-apple-macosx10.12"); @@ -406,3 +407,23 @@ TEST(ArchSpecTest, TripleComponentsWereSpecified) { ASSERT_TRUE(D.TripleEnvironmentWasSpecified()); } } + +TEST(ArchSpecTest, YAML) { + std::string buffer; + llvm::raw_string_ostream os(buffer); + + // Serialize. + llvm::yaml::Output yout(os); + std::vector archs = {ArchSpec("x86_64-pc-linux"), + ArchSpec("x86_64-apple-macosx10.12"), + ArchSpec("i686-pc-windows")}; + yout << archs; + os.flush(); + + // Deserialize. + std::vector deserialized; + llvm::yaml::Input yin(buffer); + yin >> deserialized; + + EXPECT_EQ(archs, deserialized); +} diff --git a/gnu/llvm/lldb/unittests/Utility/ArgsTest.cpp b/gnu/llvm/lldb/unittests/Utility/ArgsTest.cpp index ec352cda7a0..ed1235f99c7 100644 --- a/gnu/llvm/lldb/unittests/Utility/ArgsTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/ArgsTest.cpp @@ -1,4 +1,4 @@ -//===-- ArgsTest.cpp --------------------------------------------*- C++ -*-===// +//===-- ArgsTest.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -282,3 +282,34 @@ TEST(ArgsTest, ReplaceArgumentAtIndexFarOutOfRange) { EXPECT_EQ(3u, args.GetArgumentCount()); EXPECT_STREQ(args.GetArgumentAtIndex(2), "b"); } + +TEST(ArgsTest, Yaml) { + std::string buffer; + llvm::raw_string_ostream os(buffer); + + // Serialize. + Args args; + args.SetCommandString("this 'has' \"multiple\" args"); + llvm::yaml::Output yout(os); + yout << args; + os.flush(); + + llvm::outs() << buffer; + + // Deserialize. + Args deserialized; + llvm::yaml::Input yin(buffer); + yin >> deserialized; + + EXPECT_EQ(4u, deserialized.GetArgumentCount()); + EXPECT_STREQ(deserialized.GetArgumentAtIndex(0), "this"); + EXPECT_STREQ(deserialized.GetArgumentAtIndex(1), "has"); + EXPECT_STREQ(deserialized.GetArgumentAtIndex(2), "multiple"); + EXPECT_STREQ(deserialized.GetArgumentAtIndex(3), "args"); + + llvm::ArrayRef entries = deserialized.entries(); + EXPECT_EQ(entries[0].GetQuoteChar(), '\0'); + EXPECT_EQ(entries[1].GetQuoteChar(), '\''); + EXPECT_EQ(entries[2].GetQuoteChar(), '"'); + EXPECT_EQ(entries[3].GetQuoteChar(), '\0'); +} diff --git a/gnu/llvm/lldb/unittests/Utility/BroadcasterTest.cpp b/gnu/llvm/lldb/unittests/Utility/BroadcasterTest.cpp index 72bfd18a75e..8ff45399893 100644 --- a/gnu/llvm/lldb/unittests/Utility/BroadcasterTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/BroadcasterTest.cpp @@ -1,4 +1,4 @@ -//===-- BroadcasterTest.cpp -------------------------------------*- C++ -*-===// +//===-- BroadcasterTest.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/CMakeLists.txt b/gnu/llvm/lldb/unittests/Utility/CMakeLists.txt index 8dc13327b9b..c624c367492 100644 --- a/gnu/llvm/lldb/unittests/Utility/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/Utility/CMakeLists.txt @@ -24,6 +24,7 @@ add_lldb_unittest(UtilityTests ReproducerInstrumentationTest.cpp ReproducerTest.cpp ScalarTest.cpp + SharedClusterTest.cpp StateTest.cpp StatusTest.cpp StreamTeeTest.cpp @@ -41,6 +42,7 @@ add_lldb_unittest(UtilityTests UUIDTest.cpp VASprintfTest.cpp VMRangeTest.cpp + XcodeSDKTest.cpp LINK_LIBS lldbUtility diff --git a/gnu/llvm/lldb/unittests/Utility/CompletionRequestTest.cpp b/gnu/llvm/lldb/unittests/Utility/CompletionRequestTest.cpp index f1971711a50..02a5f5366a4 100644 --- a/gnu/llvm/lldb/unittests/Utility/CompletionRequestTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/CompletionRequestTest.cpp @@ -1,4 +1,4 @@ -//===-- CompletionRequestTest.cpp -------------------------------*- C++ -*-===// +//===-- CompletionRequestTest.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -21,7 +21,8 @@ TEST(CompletionRequest, Constructor) { CompletionRequest request(command, cursor_pos, result); result.GetMatches(matches); - EXPECT_STREQ(request.GetRawLine().str().c_str(), command.c_str()); + EXPECT_EQ(request.GetRawLine(), "a b"); + EXPECT_EQ(request.GetRawLineWithUnusedSuffix(), command); EXPECT_EQ(request.GetRawCursorPos(), cursor_pos); EXPECT_EQ(request.GetCursorIndex(), arg_index); @@ -38,7 +39,8 @@ TEST(CompletionRequest, FakeLastArg) { CompletionRequest request(command, cursor_pos, result); - EXPECT_STREQ(request.GetRawLine().str().c_str(), command.c_str()); + EXPECT_EQ(request.GetRawLine(), command); + EXPECT_EQ(request.GetRawLineWithUnusedSuffix(), command); EXPECT_EQ(request.GetRawCursorPos(), cursor_pos); EXPECT_EQ(request.GetCursorIndex(), 3U); @@ -93,7 +95,8 @@ TEST(CompletionRequest, ShiftArguments) { CompletionRequest request(command, cursor_pos, result); result.GetMatches(matches); - EXPECT_STREQ(request.GetRawLine().str().c_str(), command.c_str()); + EXPECT_EQ(request.GetRawLine(), "a b"); + EXPECT_EQ(request.GetRawLineWithUnusedSuffix(), command); EXPECT_EQ(request.GetRawCursorPos(), cursor_pos); EXPECT_EQ(request.GetCursorIndex(), arg_index); @@ -104,7 +107,8 @@ TEST(CompletionRequest, ShiftArguments) { request.ShiftArguments(); // The raw line/cursor stays identical. - EXPECT_STREQ(request.GetRawLine().str().c_str(), command.c_str()); + EXPECT_EQ(request.GetRawLine(), "a b"); + EXPECT_EQ(request.GetRawLineWithUnusedSuffix(), command); EXPECT_EQ(request.GetRawCursorPos(), cursor_pos); // Partially parsed line and cursor should be updated. diff --git a/gnu/llvm/lldb/unittests/Utility/ConstStringTest.cpp b/gnu/llvm/lldb/unittests/Utility/ConstStringTest.cpp index 74753b90317..96624b39130 100644 --- a/gnu/llvm/lldb/unittests/Utility/ConstStringTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/ConstStringTest.cpp @@ -1,4 +1,4 @@ -//===-- ConstStringTest.cpp -------------------------------------*- C++ -*-===// +//===-- ConstStringTest.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,6 +8,7 @@ #include "lldb/Utility/ConstString.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/YAMLParser.h" #include "gtest/gtest.h" using namespace lldb_private; @@ -137,3 +138,22 @@ TEST(ConstStringTest, CompareStringRef) { EXPECT_TRUE(null == static_cast(nullptr)); EXPECT_TRUE(null != "bar"); } + +TEST(ConstStringTest, YAML) { + std::string buffer; + llvm::raw_string_ostream os(buffer); + + // Serialize. + std::vector strings = {ConstString("foo"), ConstString("bar"), + ConstString("")}; + llvm::yaml::Output yout(os); + yout << strings; + os.flush(); + + // Deserialize. + std::vector deserialized; + llvm::yaml::Input yin(buffer); + yin >> deserialized; + + EXPECT_EQ(strings, deserialized); +} diff --git a/gnu/llvm/lldb/unittests/Utility/DataExtractorTest.cpp b/gnu/llvm/lldb/unittests/Utility/DataExtractorTest.cpp index 4dfa9511ac7..536e69755d1 100644 --- a/gnu/llvm/lldb/unittests/Utility/DataExtractorTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/DataExtractorTest.cpp @@ -1,4 +1,4 @@ -//===-- DataExtractorTest.cpp -----------------------------------*- C++ -*-===// +//===-- DataExtractorTest.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,6 +25,9 @@ TEST(DataExtractorTest, GetBitfield) { offset = 0; ASSERT_EQ(buffer[1], BE.GetMaxU64Bitfield(&offset, sizeof(buffer), 8, 8)); offset = 0; + ASSERT_EQ(static_cast(0xEFCDAB8967452301), + LE.GetMaxU64Bitfield(&offset, sizeof(buffer), 64, 0)); + offset = 0; ASSERT_EQ(static_cast(0x0123456789ABCDEF), BE.GetMaxU64Bitfield(&offset, sizeof(buffer), 64, 0)); offset = 0; @@ -40,6 +43,12 @@ TEST(DataExtractorTest, GetBitfield) { offset = 0; ASSERT_EQ(int8_t(buffer[1]), BE.GetMaxS64Bitfield(&offset, sizeof(buffer), 8, 8)); + offset = 0; + ASSERT_EQ(static_cast(0xEFCDAB8967452301), + LE.GetMaxS64Bitfield(&offset, sizeof(buffer), 64, 0)); + offset = 0; + ASSERT_EQ(static_cast(0x0123456789ABCDEF), + BE.GetMaxS64Bitfield(&offset, sizeof(buffer), 64, 0)); } TEST(DataExtractorTest, PeekData) { @@ -103,6 +112,39 @@ TEST(DataExtractorTest, GetCStrAtNullOffset) { EXPECT_EQ(4U, offset); } +TEST(DataExtractorTest, UncommonAddressSize) { + uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; + DataExtractor E2(buffer, sizeof buffer, lldb::eByteOrderLittle, 2); + DataExtractor E5(buffer, sizeof buffer, lldb::eByteOrderLittle, 5); + DataExtractor E7(buffer, sizeof buffer, lldb::eByteOrderLittle, 7); + + lldb::offset_t offset; + + // Test 2-byte addresses (for AVR). + offset = 0; + EXPECT_EQ(0x0201U, E2.GetMaxU64(&offset, 2)); + EXPECT_EQ(2U, offset); + offset = 0; + EXPECT_EQ(0x0201U, E2.GetAddress(&offset)); + EXPECT_EQ(2U, offset); + + // Test 5-byte addresses. + offset = 0; + EXPECT_EQ(0x030201U, E5.GetMaxU64(&offset, 3)); + EXPECT_EQ(3U, offset); + offset = 3; + EXPECT_EQ(0x0807060504U, E5.GetAddress(&offset)); + EXPECT_EQ(8U, offset); + + // Test 7-byte addresses. + offset = 0; + EXPECT_EQ(0x0504030201U, E7.GetMaxU64(&offset, 5)); + EXPECT_EQ(5U, offset); + offset = 0; + EXPECT_EQ(0x07060504030201U, E7.GetAddress(&offset)); + EXPECT_EQ(7U, offset); +} + TEST(DataExtractorTest, GetMaxU64) { uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, @@ -219,3 +261,143 @@ TEST(DataExtractorTest, GetMaxU64_unchecked) { EXPECT_EQ(0x0102030405060708U, BE.GetMaxU64_unchecked(&offset, 8)); EXPECT_EQ(8U, offset); } + +TEST(DataExtractorTest, GetSLEB128_bit63) { + uint8_t buffer[] = {0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0x7f}; + + DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, + sizeof(void *)); + DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *)); + + lldb::offset_t offset; + + int64_t expected = + 0b1111111100000001111111000000011111110000000111111100000001111111; + offset = 0; + EXPECT_EQ(expected, LE.GetSLEB128(&offset)); + EXPECT_EQ(9U, offset); + offset = 0; + EXPECT_EQ(expected, BE.GetSLEB128(&offset)); + EXPECT_EQ(9U, offset); +} + +TEST(DataExtractorTest, GetULEB128_bit63) { + uint8_t buffer[] = {0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0x7f}; + + DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, + sizeof(void *)); + DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *)); + + lldb::offset_t offset; + + uint64_t expected = + 0b0111111100000001111111000000011111110000000111111100000001111111; + offset = 0; + EXPECT_EQ(expected, LE.GetULEB128(&offset)); + EXPECT_EQ(9U, offset); + offset = 0; + EXPECT_EQ(expected, BE.GetULEB128(&offset)); + EXPECT_EQ(9U, offset); +} + +TEST(DataExtractorTest, GetFloat) { + float expected = 4.0f; + lldb::offset_t offset; + + { + uint8_t buffer[] = {0x00, 0x00, 0x80, 0x40}; + DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, + sizeof(void *)); + + offset = 0; + EXPECT_DOUBLE_EQ(expected, LE.GetFloat(&offset)); + EXPECT_EQ(4U, offset); + } + + { + uint8_t buffer[] = {0x40, 0x80, 0x00, 0x00}; + DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, + sizeof(void *)); + offset = 0; + EXPECT_DOUBLE_EQ(expected, BE.GetFloat(&offset)); + EXPECT_EQ(4U, offset); + } +} + +TEST(DataExtractorTest, GetFloatUnaligned) { + float expected = 4.0f; + lldb::offset_t offset; + + { + uint8_t buffer[] = {0x00, 0x00, 0x00, 0x80, 0x40}; + DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, + sizeof(void *)); + + offset = 1; + EXPECT_DOUBLE_EQ(expected, LE.GetFloat(&offset)); + EXPECT_EQ(5U, offset); + } + + { + uint8_t buffer[] = {0x00, 0x40, 0x80, 0x00, 0x00}; + DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, + sizeof(void *)); + offset = 1; + EXPECT_DOUBLE_EQ(expected, BE.GetFloat(&offset)); + EXPECT_EQ(5U, offset); + } +} + +TEST(DataExtractorTest, GetDouble) { + if (sizeof(double) != 8) + return; + + double expected = 4.0f; + lldb::offset_t offset; + + { + uint8_t buffer[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40}; + DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, + sizeof(void *)); + + offset = 0; + EXPECT_DOUBLE_EQ(expected, LE.GetDouble(&offset)); + EXPECT_EQ(8U, offset); + } + + { + uint8_t buffer[] = {0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, + sizeof(void *)); + offset = 0; + EXPECT_DOUBLE_EQ(expected, BE.GetDouble(&offset)); + EXPECT_EQ(8U, offset); + } +} + +TEST(DataExtractorTest, GetDoubleUnaligned) { + if (sizeof(double) != 8) + return; + + float expected = 4.0f; + lldb::offset_t offset; + + { + uint8_t buffer[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40}; + DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, + sizeof(void *)); + + offset = 1; + EXPECT_DOUBLE_EQ(expected, LE.GetDouble(&offset)); + EXPECT_EQ(9U, offset); + } + + { + uint8_t buffer[] = {0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, + sizeof(void *)); + offset = 1; + EXPECT_DOUBLE_EQ(expected, BE.GetDouble(&offset)); + EXPECT_EQ(9U, offset); + } +} diff --git a/gnu/llvm/lldb/unittests/Utility/EnvironmentTest.cpp b/gnu/llvm/lldb/unittests/Utility/EnvironmentTest.cpp index 7a16a294677..bbc9b124564 100644 --- a/gnu/llvm/lldb/unittests/Utility/EnvironmentTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/EnvironmentTest.cpp @@ -1,4 +1,4 @@ -//===-- EnvironmentTest.cpp -------------------------------------*- C++ -*-===// +//===-- EnvironmentTest.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/EventTest.cpp b/gnu/llvm/lldb/unittests/Utility/EventTest.cpp index a374350c947..5f8f2b5ec89 100644 --- a/gnu/llvm/lldb/unittests/Utility/EventTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/EventTest.cpp @@ -1,4 +1,4 @@ -//===-- EventTest.cpp -------------------------------------------*- C++ -*-===// +//===-- EventTest.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -15,7 +15,7 @@ using namespace lldb_private; static std::string to_string(const EventDataBytes &E) { StreamString S; E.Dump(&S); - return S.GetString(); + return std::string(S.GetString()); } TEST(EventTest, DumpEventDataBytes) { diff --git a/gnu/llvm/lldb/unittests/Utility/FileSpecTest.cpp b/gnu/llvm/lldb/unittests/Utility/FileSpecTest.cpp index d5f1091d5d4..ad2e328ce82 100644 --- a/gnu/llvm/lldb/unittests/Utility/FileSpecTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/FileSpecTest.cpp @@ -1,4 +1,4 @@ -//===-- FileSpecTest.cpp ----------------------------------------*- C++ -*-===// +//===-- FileSpecTest.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -246,13 +246,11 @@ TEST(FileSpecTest, GetPath) { {R"(\\net)", R"(\\net)"}, {R"(c:\..)", R"(c:\)"}, {R"(c:\.)", R"(c:\)"}, - // TODO: fix llvm::sys::path::remove_dots() to return "\" below. - {R"(\..)", R"(\..)"}, + {R"(\..)", R"(\)"}, // {R"(c:..)", R"(c:..)"}, {R"(..)", R"(..)"}, {R"(.)", R"(.)"}, - // TODO: fix llvm::sys::path::remove_dots() to return "c:\" below. - {R"(c:..\..)", R"(c:\..\..)"}, + {R"(c:..\..)", R"(c:)"}, {R"(..\..)", R"(..\..)"}, {R"(foo\..)", R"(.)"}, {R"(foo\..\bar)", R"(bar)"}, @@ -420,3 +418,30 @@ TEST(FileSpecTest, Match) { EXPECT_TRUE(Match("", "")); } + +TEST(FileSpecTest, Yaml) { + std::string buffer; + llvm::raw_string_ostream os(buffer); + + // Serialize. + FileSpec fs_windows("F:\\bar", FileSpec::Style::windows); + llvm::yaml::Output yout(os); + yout << fs_windows; + os.flush(); + + // Deserialize. + FileSpec deserialized; + llvm::yaml::Input yin(buffer); + yin >> deserialized; + + EXPECT_EQ(deserialized.GetPathStyle(), fs_windows.GetPathStyle()); + EXPECT_EQ(deserialized.GetFilename(), fs_windows.GetFilename()); + EXPECT_EQ(deserialized.GetDirectory(), fs_windows.GetDirectory()); + EXPECT_EQ(deserialized, fs_windows); +} + +TEST(FileSpecTest, OperatorBool) { + EXPECT_FALSE(FileSpec()); + EXPECT_FALSE(FileSpec("")); + EXPECT_TRUE(FileSpec("/foo/bar")); +} diff --git a/gnu/llvm/lldb/unittests/Utility/FlagsTest.cpp b/gnu/llvm/lldb/unittests/Utility/FlagsTest.cpp index 6a46bcc2d6f..c33a19547a6 100644 --- a/gnu/llvm/lldb/unittests/Utility/FlagsTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/FlagsTest.cpp @@ -1,4 +1,4 @@ -//===-- FlagsTest.cpp -------------------===---------------------*- C++ -*-===// +//===-- FlagsTest.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/ListenerTest.cpp b/gnu/llvm/lldb/unittests/Utility/ListenerTest.cpp index f9fa1efa3a4..bf38955a8e7 100644 --- a/gnu/llvm/lldb/unittests/Utility/ListenerTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/ListenerTest.cpp @@ -1,4 +1,4 @@ -//===-- ListenerTest.cpp ----------------------------------------*- C++ -*-===// +//===-- ListenerTest.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/LogTest.cpp b/gnu/llvm/lldb/unittests/Utility/LogTest.cpp index 511724b6a1b..dfbb1f09214 100644 --- a/gnu/llvm/lldb/unittests/Utility/LogTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/LogTest.cpp @@ -1,4 +1,4 @@ -//===-- LogTest.cpp ---------------------------------------------*- C++ -*-===// +//===-- LogTest.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/NameMatchesTest.cpp b/gnu/llvm/lldb/unittests/Utility/NameMatchesTest.cpp index 7b09018ef07..9992f2ff8c3 100644 --- a/gnu/llvm/lldb/unittests/Utility/NameMatchesTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/NameMatchesTest.cpp @@ -1,4 +1,4 @@ -//===-- NameMatchesTest.cpp -------------------------------------*- C++ -*-===// +//===-- NameMatchesTest.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/OptionsWithRawTest.cpp b/gnu/llvm/lldb/unittests/Utility/OptionsWithRawTest.cpp index e3541580d78..e7b159b8d40 100644 --- a/gnu/llvm/lldb/unittests/Utility/OptionsWithRawTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/OptionsWithRawTest.cpp @@ -1,4 +1,4 @@ -//===-- OptionsWithRawTest.cpp ----------------------------------*- C++ -*-===// +//===-- OptionsWithRawTest.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/PredicateTest.cpp b/gnu/llvm/lldb/unittests/Utility/PredicateTest.cpp index 45b20c601d6..8752e9361ca 100644 --- a/gnu/llvm/lldb/unittests/Utility/PredicateTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/PredicateTest.cpp @@ -1,4 +1,4 @@ -//===-- PredicateTest.cpp ---------------------------------------*- C++ -*-===// +//===-- PredicateTest.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/ProcessInfoTest.cpp b/gnu/llvm/lldb/unittests/Utility/ProcessInfoTest.cpp index 3a8e0010475..b2fdbde70da 100644 --- a/gnu/llvm/lldb/unittests/Utility/ProcessInfoTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/ProcessInfoTest.cpp @@ -1,4 +1,4 @@ -//===-- ProcessInfoTest.cpp -------------------------------------*- C++ -*-===// +//===-- ProcessInfoTest.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/ProcessInstanceInfoTest.cpp b/gnu/llvm/lldb/unittests/Utility/ProcessInstanceInfoTest.cpp index 1d363ac80a3..a3f850cfb9b 100644 --- a/gnu/llvm/lldb/unittests/Utility/ProcessInstanceInfoTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/ProcessInstanceInfoTest.cpp @@ -1,4 +1,4 @@ -//===-- ProcessInstanceInfoTest.cpp -----------------------------*- C++ -*-===// +//===-- ProcessInstanceInfoTest.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -108,3 +108,60 @@ TEST(ProcessInstanceInfoMatch, Name) { EXPECT_TRUE(match.Matches(info_bar)); EXPECT_TRUE(match.Matches(info_empty)); } + +TEST(ProcessInstanceInfo, Yaml) { + std::string buffer; + llvm::raw_string_ostream os(buffer); + + // Serialize. + ProcessInstanceInfo info("a.out", ArchSpec("x86_64-pc-linux"), 47); + info.SetUserID(1); + info.SetEffectiveUserID(2); + info.SetGroupID(3); + info.SetEffectiveGroupID(4); + llvm::yaml::Output yout(os); + yout << info; + os.flush(); + + // Deserialize. + ProcessInstanceInfo deserialized; + llvm::yaml::Input yin(buffer); + yin >> deserialized; + + EXPECT_EQ(deserialized.GetNameAsStringRef(), info.GetNameAsStringRef()); + EXPECT_EQ(deserialized.GetArchitecture(), info.GetArchitecture()); + EXPECT_EQ(deserialized.GetUserID(), info.GetUserID()); + EXPECT_EQ(deserialized.GetGroupID(), info.GetGroupID()); + EXPECT_EQ(deserialized.GetEffectiveUserID(), info.GetEffectiveUserID()); + EXPECT_EQ(deserialized.GetEffectiveGroupID(), info.GetEffectiveGroupID()); +} + +TEST(ProcessInstanceInfoList, Yaml) { + std::string buffer; + llvm::raw_string_ostream os(buffer); + + // Serialize. + ProcessInstanceInfo info("a.out", ArchSpec("x86_64-pc-linux"), 47); + info.SetUserID(1); + info.SetEffectiveUserID(2); + info.SetGroupID(3); + info.SetEffectiveGroupID(4); + ProcessInstanceInfoList list; + list.push_back(info); + llvm::yaml::Output yout(os); + yout << list; + os.flush(); + + // Deserialize. + ProcessInstanceInfoList deserialized; + llvm::yaml::Input yin(buffer); + yin >> deserialized; + + ASSERT_EQ(deserialized.size(), static_cast(1)); + EXPECT_EQ(deserialized[0].GetNameAsStringRef(), info.GetNameAsStringRef()); + EXPECT_EQ(deserialized[0].GetArchitecture(), info.GetArchitecture()); + EXPECT_EQ(deserialized[0].GetUserID(), info.GetUserID()); + EXPECT_EQ(deserialized[0].GetGroupID(), info.GetGroupID()); + EXPECT_EQ(deserialized[0].GetEffectiveUserID(), info.GetEffectiveUserID()); + EXPECT_EQ(deserialized[0].GetEffectiveGroupID(), info.GetEffectiveGroupID()); +} diff --git a/gnu/llvm/lldb/unittests/Utility/RangeMapTest.cpp b/gnu/llvm/lldb/unittests/Utility/RangeMapTest.cpp index 9f9b96559a4..8a243b65621 100644 --- a/gnu/llvm/lldb/unittests/Utility/RangeMapTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/RangeMapTest.cpp @@ -1,4 +1,4 @@ -//===-- RangeTest.cpp ----------------------------------------*- C++ -*-===// +//===-- RangeTest.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -19,6 +19,12 @@ static testing::Matcher EntryIs(uint32_t ID) { return testing::Pointee(testing::Field(&EntryT::data, ID)); } +std::vector FindEntryIndexes(uint32_t address, RangeDataVectorT map) { + std::vector result; + map.FindEntryIndexesThatContain(address, result); + return result; +} + TEST(RangeDataVector, FindEntryThatContains) { RangeDataVectorT Map; uint32_t NextID = 0; @@ -94,3 +100,37 @@ TEST(RangeDataVector, CustomSort) { EXPECT_THAT(MapC.GetEntryRef(2).data, 51); EXPECT_THAT(MapC.GetEntryRef(3).data, 50); } + +TEST(RangeDataVector, FindEntryIndexesThatContain) { + RangeDataVectorT Map; + Map.Append(EntryT(0, 10, 10)); + Map.Append(EntryT(10, 10, 11)); + Map.Append(EntryT(20, 10, 12)); + Map.Sort(); + + EXPECT_THAT(FindEntryIndexes(0, Map), testing::ElementsAre(10)); + EXPECT_THAT(FindEntryIndexes(9, Map), testing::ElementsAre(10)); + EXPECT_THAT(FindEntryIndexes(10, Map), testing::ElementsAre(11)); + EXPECT_THAT(FindEntryIndexes(19, Map), testing::ElementsAre(11)); + EXPECT_THAT(FindEntryIndexes(20, Map), testing::ElementsAre(12)); + EXPECT_THAT(FindEntryIndexes(29, Map), testing::ElementsAre(12)); + EXPECT_THAT(FindEntryIndexes(30, Map), testing::ElementsAre()); +} + +TEST(RangeDataVector, FindEntryIndexesThatContain_Overlap) { + RangeDataVectorT Map; + Map.Append(EntryT(0, 40, 10)); + Map.Append(EntryT(10, 20, 11)); + Map.Append(EntryT(20, 10, 12)); + Map.Sort(); + + EXPECT_THAT(FindEntryIndexes(0, Map), testing::ElementsAre(10)); + EXPECT_THAT(FindEntryIndexes(9, Map), testing::ElementsAre(10)); + EXPECT_THAT(FindEntryIndexes(10, Map), testing::ElementsAre(10, 11)); + EXPECT_THAT(FindEntryIndexes(19, Map), testing::ElementsAre(10, 11)); + EXPECT_THAT(FindEntryIndexes(20, Map), testing::ElementsAre(10, 11, 12)); + EXPECT_THAT(FindEntryIndexes(29, Map), testing::ElementsAre(10, 11, 12)); + EXPECT_THAT(FindEntryIndexes(30, Map), testing::ElementsAre(10)); + EXPECT_THAT(FindEntryIndexes(39, Map), testing::ElementsAre(10)); + EXPECT_THAT(FindEntryIndexes(40, Map), testing::ElementsAre()); +} diff --git a/gnu/llvm/lldb/unittests/Utility/RangeTest.cpp b/gnu/llvm/lldb/unittests/Utility/RangeTest.cpp index 40662201992..cfc281c8fd6 100644 --- a/gnu/llvm/lldb/unittests/Utility/RangeTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/RangeTest.cpp @@ -1,4 +1,4 @@ -//===-- RangeTest.cpp ----------------------------------------*- C++ -*-===// +//===-- RangeTest.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/RegisterValueTest.cpp b/gnu/llvm/lldb/unittests/Utility/RegisterValueTest.cpp index d7ed2976bae..70d79ea0024 100644 --- a/gnu/llvm/lldb/unittests/Utility/RegisterValueTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/RegisterValueTest.cpp @@ -1,4 +1,4 @@ -//===-- RegisterValueTest.cpp -----------------------------------*- C++ -*-===// +//===-- RegisterValueTest.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/ReproducerInstrumentationTest.cpp b/gnu/llvm/lldb/unittests/Utility/ReproducerInstrumentationTest.cpp index 2a4ebac2df9..1ed00a77249 100644 --- a/gnu/llvm/lldb/unittests/Utility/ReproducerInstrumentationTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/ReproducerInstrumentationTest.cpp @@ -1,4 +1,4 @@ -//===-- ReproducerInstrumentationTest.cpp -----------------------*- C++ -*-===// +//===-- ReproducerInstrumentationTest.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -50,13 +50,76 @@ public: TestingRegistry(); }; -static llvm::Optional g_serializer; static llvm::Optional g_registry; +static llvm::Optional g_serializer; +static llvm::Optional g_deserializer; + +class TestInstrumentationData : public InstrumentationData { +public: + TestInstrumentationData() : InstrumentationData() {} + TestInstrumentationData(Serializer &serializer, Registry ®istry) + : InstrumentationData(serializer, registry) {} + TestInstrumentationData(Deserializer &deserializer, Registry ®istry) + : InstrumentationData(deserializer, registry) {} +}; + +inline TestInstrumentationData GetTestInstrumentationData() { + assert(!(g_serializer && g_deserializer)); + if (g_serializer) + return TestInstrumentationData(*g_serializer, *g_registry); + if (g_deserializer) + return TestInstrumentationData(*g_deserializer, *g_registry); + return TestInstrumentationData(); +} + +class TestInstrumentationDataRAII { +public: + TestInstrumentationDataRAII(llvm::raw_string_ostream &os) { + g_registry.emplace(); + g_serializer.emplace(os); + g_deserializer.reset(); + } + + TestInstrumentationDataRAII(llvm::StringRef buffer) { + g_registry.emplace(); + g_serializer.reset(); + g_deserializer.emplace(buffer); + } + + ~TestInstrumentationDataRAII() { Reset(); } + + void Reset() { + g_registry.reset(); + g_serializer.reset(); + g_deserializer.reset(); + } + + static std::unique_ptr + GetRecordingData(llvm::raw_string_ostream &os) { + return std::make_unique(os); + } + + static std::unique_ptr + GetReplayData(llvm::StringRef buffer) { + return std::make_unique(buffer); + } +}; -#define LLDB_GET_INSTRUMENTATION_DATA() \ - g_serializer ? InstrumentationData(*g_serializer, *g_registry) : InstrumentationData() +#define LLDB_GET_INSTRUMENTATION_DATA() GetTestInstrumentationData() -class InstrumentedFoo { +enum class Class { + Foo, + Bar, +}; + +class Instrumented { +public: + virtual ~Instrumented() = default; + virtual void Validate() = 0; + virtual bool IsA(Class c) = 0; +}; + +class InstrumentedFoo : public Instrumented { public: InstrumentedFoo() = default; /// Instrumented methods. @@ -65,13 +128,20 @@ public: InstrumentedFoo(const InstrumentedFoo &foo); InstrumentedFoo &operator=(const InstrumentedFoo &foo); void A(int a); + int GetA(); void B(int &b) const; + int &GetB(); int C(float *c); + float GetC(); int D(const char *d) const; + size_t GetD(char *buffer, size_t length); static void E(double e); + double GetE(); static int F(); - void Validate(); + bool GetF(); + void Validate() override; //// } + virtual bool IsA(Class c) override { return c == Class::Foo; } private: int m_a = 0; @@ -83,7 +153,7 @@ private: mutable int m_called = 0; }; -class InstrumentedBar { +class InstrumentedBar : public Instrumented { public: /// Instrumented methods. /// { @@ -93,8 +163,9 @@ public: InstrumentedFoo *GetInstrumentedFooPtr(); void SetInstrumentedFoo(InstrumentedFoo *foo); void SetInstrumentedFoo(InstrumentedFoo &foo); - void Validate(); + void Validate() override; /// } + virtual bool IsA(Class c) override { return c == Class::Bar; } private: bool m_get_instrumend_foo_called = false; @@ -105,45 +176,42 @@ private: double InstrumentedFoo::g_e = 0; bool InstrumentedFoo::g_f = false; -static std::vector g_foos; -static std::vector g_bars; - -void ClearObjects() { - g_registry.reset(); - g_serializer.reset(); - g_foos.clear(); - g_bars.clear(); -} - -void ValidateObjects(size_t expected_foos, size_t expected_bars) { - EXPECT_EQ(expected_foos, g_foos.size()); - EXPECT_EQ(expected_bars, g_bars.size()); - - for (auto *foo : g_foos) { - foo->Validate(); - } +struct Validator { + enum Validation { valid, invalid }; + Validator(Class clazz, Validation validation) + : clazz(clazz), validation(validation) {} + Class clazz; + Validation validation; +}; - for (auto *bar : g_bars) { - bar->Validate(); +void ValidateObjects(std::vector objects, + std::vector validators) { + ASSERT_EQ(validators.size(), objects.size()); + for (size_t i = 0; i < validators.size(); ++i) { + Validator &validator = validators[i]; + Instrumented *instrumented = static_cast(objects[i]); + EXPECT_TRUE(instrumented->IsA(validator.clazz)); + switch (validator.validation) { + case Validator::valid: + instrumented->Validate(); + break; + case Validator::invalid: + break; + } } } InstrumentedFoo::InstrumentedFoo(int i) { LLDB_RECORD_CONSTRUCTOR(InstrumentedFoo, (int), i); - g_foos.push_back(this); } InstrumentedFoo::InstrumentedFoo(const InstrumentedFoo &foo) { LLDB_RECORD_CONSTRUCTOR(InstrumentedFoo, (const InstrumentedFoo &), foo); - g_foos.erase(std::remove(g_foos.begin(), g_foos.end(), &foo)); - g_foos.push_back(this); } InstrumentedFoo &InstrumentedFoo::operator=(const InstrumentedFoo &foo) { LLDB_RECORD_METHOD(InstrumentedFoo &, InstrumentedFoo, operator=,(const InstrumentedFoo &), foo); - g_foos.erase(std::remove(g_foos.begin(), g_foos.end(), &foo)); - g_foos.push_back(this); return *this; } @@ -153,35 +221,72 @@ void InstrumentedFoo::A(int a) { m_a = a; } +int InstrumentedFoo::GetA() { + LLDB_RECORD_METHOD_NO_ARGS(int, InstrumentedFoo, GetA); + + return m_a; +} + void InstrumentedFoo::B(int &b) const { LLDB_RECORD_METHOD_CONST(void, InstrumentedFoo, B, (int &), b); m_called++; m_b = b; } +int &InstrumentedFoo::GetB() { + LLDB_RECORD_METHOD_NO_ARGS(int &, InstrumentedFoo, GetB); + + return m_b; +} + int InstrumentedFoo::C(float *c) { LLDB_RECORD_METHOD(int, InstrumentedFoo, C, (float *), c); m_c = *c; return 1; } +float InstrumentedFoo::GetC() { + LLDB_RECORD_METHOD_NO_ARGS(float, InstrumentedFoo, GetC); + + return m_c; +} + int InstrumentedFoo::D(const char *d) const { LLDB_RECORD_METHOD_CONST(int, InstrumentedFoo, D, (const char *), d); m_d = std::string(d); return 2; } +size_t InstrumentedFoo::GetD(char *buffer, size_t length) { + LLDB_RECORD_CHAR_PTR_METHOD(size_t, InstrumentedFoo, GetD, (char *, size_t), + buffer, "", length); + ::snprintf(buffer, length, "%s", m_d.c_str()); + return m_d.size(); +} + void InstrumentedFoo::E(double e) { LLDB_RECORD_STATIC_METHOD(void, InstrumentedFoo, E, (double), e); g_e = e; } +double InstrumentedFoo::GetE() { + LLDB_RECORD_METHOD_NO_ARGS(double, InstrumentedFoo, GetE); + + return g_e; +} + int InstrumentedFoo::F() { LLDB_RECORD_STATIC_METHOD_NO_ARGS(int, InstrumentedFoo, F); g_f = true; return 3; } +bool InstrumentedFoo::GetF() { + LLDB_RECORD_METHOD_NO_ARGS(bool, InstrumentedFoo, GetF); + + return g_f; +} + void InstrumentedFoo::Validate() { LLDB_RECORD_METHOD_NO_ARGS(void, InstrumentedFoo, Validate); EXPECT_EQ(m_a, 100); @@ -195,7 +300,6 @@ void InstrumentedFoo::Validate() { InstrumentedBar::InstrumentedBar() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(InstrumentedBar); - g_bars.push_back(this); } InstrumentedFoo InstrumentedBar::GetInstrumentedFoo() { @@ -242,7 +346,7 @@ void InstrumentedBar::Validate() { } TestingRegistry::TestingRegistry() { - Registry& R = *this; + Registry &R = *this; LLDB_REGISTER_CONSTRUCTOR(InstrumentedFoo, (int i)); LLDB_REGISTER_CONSTRUCTOR(InstrumentedFoo, (const InstrumentedFoo &)); @@ -268,6 +372,12 @@ TestingRegistry::TestingRegistry() { LLDB_REGISTER_METHOD(void, InstrumentedBar, SetInstrumentedFoo, (InstrumentedFoo &)); LLDB_REGISTER_METHOD(void, InstrumentedBar, Validate, ()); + LLDB_REGISTER_METHOD(int, InstrumentedFoo, GetA, ()); + LLDB_REGISTER_METHOD(int &, InstrumentedFoo, GetB, ()); + LLDB_REGISTER_METHOD(float, InstrumentedFoo, GetC, ()); + LLDB_REGISTER_METHOD(size_t, InstrumentedFoo, GetD, (char *, size_t)); + LLDB_REGISTER_METHOD(double, InstrumentedFoo, GetE, ()); + LLDB_REGISTER_METHOD(bool, InstrumentedFoo, GetF, ()); } static const Pod p; @@ -393,6 +503,72 @@ TEST(SerializationRountripTest, SerializeDeserializeCString) { EXPECT_STREQ(cstr, deserializer.Deserialize()); } +TEST(SerializationRountripTest, SerializeDeserializeCStringNull) { + const char *cstr = nullptr; + + std::string str; + llvm::raw_string_ostream os(str); + + Serializer serializer(os); + serializer.SerializeAll(cstr); + + llvm::StringRef buffer(os.str()); + Deserializer deserializer(buffer); + + EXPECT_EQ(nullptr, deserializer.Deserialize()); +} + +TEST(SerializationRountripTest, SerializeDeserializeCStringArray) { + const char *foo = "foo"; + const char *bar = "bar"; + const char *baz = "baz"; + const char *arr[4] = {foo, bar, baz, nullptr}; + + std::string str; + llvm::raw_string_ostream os(str); + + Serializer serializer(os); + serializer.SerializeAll(static_cast(arr)); + + llvm::StringRef buffer(os.str()); + Deserializer deserializer(buffer); + + const char **deserialized = deserializer.Deserialize(); + EXPECT_STREQ("foo", deserialized[0]); + EXPECT_STREQ("bar", deserialized[1]); + EXPECT_STREQ("baz", deserialized[2]); +} + +TEST(SerializationRountripTest, SerializeDeserializeCStringArrayNullptrElem) { + const char *arr[1] = {nullptr}; + + std::string str; + llvm::raw_string_ostream os(str); + + Serializer serializer(os); + serializer.SerializeAll(static_cast(arr)); + + llvm::StringRef buffer(os.str()); + Deserializer deserializer(buffer); + + const char **deserialized = deserializer.Deserialize(); + EXPECT_EQ(nullptr, deserialized); +} + +TEST(SerializationRountripTest, SerializeDeserializeCStringArrayNullptr) { + std::string str; + llvm::raw_string_ostream os(str); + + Serializer serializer(os); + serializer.SerializeAll(static_cast(nullptr)); + + llvm::StringRef buffer(os.str()); + Deserializer deserializer(buffer); + + const char **deserialized = deserializer.Deserialize(); + EXPECT_EQ(nullptr, deserialized); +} + TEST(SerializationRountripTest, SerializeDeserializeObjectPointer) { Foo foo; Bar bar; @@ -438,10 +614,10 @@ TEST(SerializationRountripTest, SerializeDeserializeObjectReference) { TEST(RecordReplayTest, InstrumentedFoo) { std::string str; llvm::raw_string_ostream os(str); - g_registry.emplace(); - g_serializer.emplace(os); { + auto data = TestInstrumentationDataRAII::GetRecordingData(os); + int b = 200; float c = 300.3f; double e = 400.4; @@ -456,65 +632,63 @@ TEST(RecordReplayTest, InstrumentedFoo) { foo.Validate(); } - ClearObjects(); - TestingRegistry registry; - registry.Replay(os.str()); + Deserializer deserializer(os.str()); + registry.Replay(deserializer); - ValidateObjects(1, 0); + ValidateObjects(deserializer.GetAllObjects(), + {{Class::Foo, Validator::valid}}); } TEST(RecordReplayTest, InstrumentedFooSameThis) { std::string str; llvm::raw_string_ostream os(str); - g_registry.emplace(); - g_serializer.emplace(os); - int b = 200; - float c = 300.3f; - double e = 400.4; + { + auto data = TestInstrumentationDataRAII::GetRecordingData(os); - InstrumentedFoo *foo = new InstrumentedFoo(0); - foo->A(100); - foo->B(b); - foo->C(&c); - foo->D("bar"); - InstrumentedFoo::E(e); - InstrumentedFoo::F(); - foo->Validate(); - foo->~InstrumentedFoo(); - - InstrumentedFoo *foo2 = new (foo) InstrumentedFoo(0); - foo2->A(100); - foo2->B(b); - foo2->C(&c); - foo2->D("bar"); - InstrumentedFoo::E(e); - InstrumentedFoo::F(); - foo2->Validate(); - delete foo2; - - ClearObjects(); + int b = 200; + float c = 300.3f; + double e = 400.4; + + InstrumentedFoo *foo = new InstrumentedFoo(0); + foo->A(100); + foo->B(b); + foo->C(&c); + foo->D("bar"); + InstrumentedFoo::E(e); + InstrumentedFoo::F(); + foo->Validate(); + foo->~InstrumentedFoo(); + + InstrumentedFoo *foo2 = new (foo) InstrumentedFoo(0); + foo2->A(100); + foo2->B(b); + foo2->C(&c); + foo2->D("bar"); + InstrumentedFoo::E(e); + InstrumentedFoo::F(); + foo2->Validate(); + delete foo2; + } TestingRegistry registry; - registry.Replay(os.str()); + Deserializer deserializer(os.str()); + registry.Replay(deserializer); - ValidateObjects(2, 0); + ValidateObjects(deserializer.GetAllObjects(), + {{Class::Foo, Validator::valid}}); } TEST(RecordReplayTest, InstrumentedBar) { std::string str; llvm::raw_string_ostream os(str); - g_registry.emplace(); - g_serializer.emplace(os); { + auto data = TestInstrumentationDataRAII::GetRecordingData(os); + InstrumentedBar bar; InstrumentedFoo foo = bar.GetInstrumentedFoo(); -#if 0 - InstrumentedFoo& foo_ref = bar.GetInstrumentedFooRef(); - InstrumentedFoo* foo_ptr = bar.GetInstrumentedFooPtr(); -#endif int b = 200; float c = 300.3f; @@ -533,21 +707,26 @@ TEST(RecordReplayTest, InstrumentedBar) { bar.Validate(); } - ClearObjects(); - TestingRegistry registry; - registry.Replay(os.str()); - - ValidateObjects(1, 1); + Deserializer deserializer(os.str()); + registry.Replay(deserializer); + + ValidateObjects( + deserializer.GetAllObjects(), + { + {Class::Bar, Validator::valid}, // bar + {Class::Foo, Validator::invalid}, // bar.GetInstrumentedFoo() + {Class::Foo, Validator::valid}, // foo + }); } TEST(RecordReplayTest, InstrumentedBarRef) { std::string str; llvm::raw_string_ostream os(str); - g_registry.emplace(); - g_serializer.emplace(os); { + auto data = TestInstrumentationDataRAII::GetRecordingData(os); + InstrumentedBar bar; InstrumentedFoo &foo = bar.GetInstrumentedFooRef(); @@ -568,21 +747,22 @@ TEST(RecordReplayTest, InstrumentedBarRef) { bar.Validate(); } - ClearObjects(); - TestingRegistry registry; - registry.Replay(os.str()); + Deserializer deserializer(os.str()); + registry.Replay(deserializer); - ValidateObjects(1, 1); + ValidateObjects( + deserializer.GetAllObjects(), + {{Class::Bar, Validator::valid}, {Class::Foo, Validator::valid}}); } TEST(RecordReplayTest, InstrumentedBarPtr) { std::string str; llvm::raw_string_ostream os(str); - g_registry.emplace(); - g_serializer.emplace(os); { + auto data = TestInstrumentationDataRAII::GetRecordingData(os); + InstrumentedBar bar; InstrumentedFoo &foo = *(bar.GetInstrumentedFooPtr()); @@ -603,10 +783,334 @@ TEST(RecordReplayTest, InstrumentedBarPtr) { bar.Validate(); } - ClearObjects(); - TestingRegistry registry; - registry.Replay(os.str()); + Deserializer deserializer(os.str()); + registry.Replay(deserializer); + + ValidateObjects( + deserializer.GetAllObjects(), + {{Class::Bar, Validator::valid}, {Class::Foo, Validator::valid}}); +} + +TEST(PassiveReplayTest, InstrumentedFoo) { + std::string str; + llvm::raw_string_ostream os(str); - ValidateObjects(1, 1); + { + auto data = TestInstrumentationDataRAII::GetRecordingData(os); + + int b = 200; + float c = 300.3f; + double e = 400.4; + + InstrumentedFoo foo(0); + foo.A(100); + foo.B(b); + foo.C(&c); + foo.D("bar"); + InstrumentedFoo::E(e); + InstrumentedFoo::F(); + foo.Validate(); + + EXPECT_EQ(foo.GetA(), 100); + EXPECT_EQ(foo.GetB(), 200); + EXPECT_NEAR(foo.GetC(), 300.3, 0.01); + char buffer[100]; + foo.GetD(buffer, 100); + EXPECT_STREQ(buffer, "bar"); + EXPECT_NEAR(foo.GetE(), 400.4, 0.01); + EXPECT_EQ(foo.GetF(), true); + } + + std::string buffer = os.str(); + + { + auto data = TestInstrumentationDataRAII::GetReplayData(buffer); + + int b = 999; + float c = 999.9f; + double e = 999.9; + + InstrumentedFoo foo(9); + foo.A(999); + foo.B(b); + foo.C(&c); + foo.D("999"); + InstrumentedFoo::E(e); + InstrumentedFoo::F(); + foo.Validate(); + + EXPECT_EQ(foo.GetA(), 100); + EXPECT_EQ(foo.GetB(), 200); + EXPECT_NEAR(foo.GetC(), 300.3, 0.01); + char buffer[100]; + foo.GetD(buffer, 100); + EXPECT_STREQ(buffer, "bar"); + EXPECT_NEAR(foo.GetE(), 400.4, 0.01); + EXPECT_EQ(foo.GetF(), true); + } +} + +TEST(PassiveReplayTest, InstrumentedFooInvalid) { + std::string str; + llvm::raw_string_ostream os(str); + + { + auto data = TestInstrumentationDataRAII::GetRecordingData(os); + + int b = 200; + float c = 300.3f; + double e = 400.4; + + InstrumentedFoo foo(0); + foo.A(100); + foo.B(b); + foo.C(&c); + foo.D("bar"); + InstrumentedFoo::E(e); + InstrumentedFoo::F(); + foo.Validate(); + + EXPECT_EQ(foo.GetA(), 100); + EXPECT_EQ(foo.GetB(), 200); + EXPECT_NEAR(foo.GetC(), 300.3, 0.01); + EXPECT_NEAR(foo.GetE(), 400.4, 0.01); + EXPECT_EQ(foo.GetF(), true); + } + + std::string buffer = os.str(); + + { + auto data = TestInstrumentationDataRAII::GetReplayData(buffer); + + int b = 999; + float c = 999.9f; + double e = 999.9; + + InstrumentedFoo foo(9); + foo.A(999); + foo.B(b); + foo.C(&c); + foo.D("999"); + InstrumentedFoo::E(e); + InstrumentedFoo::F(); + foo.Validate(); + + EXPECT_EQ(foo.GetA(), 100); + // Detect divergence. + EXPECT_DEATH(foo.GetA(), ""); + } +} + +TEST(PassiveReplayTest, InstrumentedBar) { + std::string str; + llvm::raw_string_ostream os(str); + + { + auto data = TestInstrumentationDataRAII::GetRecordingData(os); + + InstrumentedBar bar; + InstrumentedFoo foo = bar.GetInstrumentedFoo(); + + int b = 200; + float c = 300.3f; + double e = 400.4; + + foo.A(100); + foo.B(b); + foo.C(&c); + foo.D("bar"); + InstrumentedFoo::E(e); + InstrumentedFoo::F(); + foo.Validate(); + + EXPECT_EQ(foo.GetA(), 100); + EXPECT_EQ(foo.GetB(), 200); + EXPECT_NEAR(foo.GetC(), 300.3, 0.01); + char buffer[100]; + foo.GetD(buffer, 100); + EXPECT_STREQ(buffer, "bar"); + EXPECT_NEAR(foo.GetE(), 400.4, 0.01); + EXPECT_EQ(foo.GetF(), true); + + bar.SetInstrumentedFoo(foo); + bar.SetInstrumentedFoo(&foo); + bar.Validate(); + } + + std::string buffer = os.str(); + + { + auto data = TestInstrumentationDataRAII::GetReplayData(buffer); + + InstrumentedBar bar; + InstrumentedFoo foo = bar.GetInstrumentedFoo(); + + int b = 99; + float c = 999.9f; + double e = 999.9; + + foo.A(999); + foo.B(b); + foo.C(&c); + foo.D("999"); + InstrumentedFoo::E(e); + InstrumentedFoo::F(); + foo.Validate(); + + EXPECT_EQ(foo.GetA(), 100); + EXPECT_EQ(foo.GetB(), 200); + EXPECT_NEAR(foo.GetC(), 300.3, 0.01); + char buffer[100]; + foo.GetD(buffer, 100); + EXPECT_STREQ(buffer, "bar"); + EXPECT_NEAR(foo.GetE(), 400.4, 0.01); + EXPECT_EQ(foo.GetF(), true); + + bar.SetInstrumentedFoo(foo); + bar.SetInstrumentedFoo(&foo); + bar.Validate(); + } +} + +TEST(PassiveReplayTest, InstrumentedBarRef) { + std::string str; + llvm::raw_string_ostream os(str); + + { + auto data = TestInstrumentationDataRAII::GetRecordingData(os); + + InstrumentedBar bar; + InstrumentedFoo &foo = bar.GetInstrumentedFooRef(); + + int b = 200; + float c = 300.3f; + double e = 400.4; + + foo.A(100); + foo.B(b); + foo.C(&c); + foo.D("bar"); + InstrumentedFoo::E(e); + InstrumentedFoo::F(); + foo.Validate(); + + EXPECT_EQ(foo.GetA(), 100); + EXPECT_EQ(foo.GetB(), 200); + EXPECT_NEAR(foo.GetC(), 300.3, 0.01); + char buffer[100]; + foo.GetD(buffer, 100); + EXPECT_STREQ(buffer, "bar"); + EXPECT_NEAR(foo.GetE(), 400.4, 0.01); + EXPECT_EQ(foo.GetF(), true); + + bar.SetInstrumentedFoo(foo); + bar.SetInstrumentedFoo(&foo); + bar.Validate(); + } + + std::string buffer = os.str(); + + { + auto data = TestInstrumentationDataRAII::GetReplayData(buffer); + + InstrumentedBar bar; + InstrumentedFoo &foo = bar.GetInstrumentedFooRef(); + + int b = 99; + float c = 999.9f; + double e = 999.9; + + foo.A(999); + foo.B(b); + foo.C(&c); + foo.D("999"); + InstrumentedFoo::E(e); + InstrumentedFoo::F(); + foo.Validate(); + + EXPECT_EQ(foo.GetA(), 100); + EXPECT_EQ(foo.GetB(), 200); + EXPECT_NEAR(foo.GetC(), 300.3, 0.01); + char buffer[100]; + foo.GetD(buffer, 100); + EXPECT_STREQ(buffer, "bar"); + EXPECT_NEAR(foo.GetE(), 400.4, 0.01); + EXPECT_EQ(foo.GetF(), true); + + bar.SetInstrumentedFoo(foo); + bar.SetInstrumentedFoo(&foo); + bar.Validate(); + } +} + +TEST(PassiveReplayTest, InstrumentedBarPtr) { + std::string str; + llvm::raw_string_ostream os(str); + + { + auto data = TestInstrumentationDataRAII::GetRecordingData(os); + + InstrumentedBar bar; + InstrumentedFoo &foo = *(bar.GetInstrumentedFooPtr()); + + int b = 200; + float c = 300.3f; + double e = 400.4; + + foo.A(100); + foo.B(b); + foo.C(&c); + foo.D("bar"); + InstrumentedFoo::E(e); + InstrumentedFoo::F(); + foo.Validate(); + + EXPECT_EQ(foo.GetA(), 100); + EXPECT_EQ(foo.GetB(), 200); + EXPECT_NEAR(foo.GetC(), 300.3, 0.01); + char buffer[100]; + foo.GetD(buffer, 100); + EXPECT_STREQ(buffer, "bar"); + EXPECT_NEAR(foo.GetE(), 400.4, 0.01); + EXPECT_EQ(foo.GetF(), true); + + bar.SetInstrumentedFoo(foo); + bar.SetInstrumentedFoo(&foo); + bar.Validate(); + } + + std::string buffer = os.str(); + + { + auto data = TestInstrumentationDataRAII::GetReplayData(buffer); + + InstrumentedBar bar; + InstrumentedFoo &foo = *(bar.GetInstrumentedFooPtr()); + + int b = 99; + float c = 999.9f; + double e = 999.9; + + foo.A(999); + foo.B(b); + foo.C(&c); + foo.D("999"); + InstrumentedFoo::E(e); + InstrumentedFoo::F(); + foo.Validate(); + + EXPECT_EQ(foo.GetA(), 100); + EXPECT_EQ(foo.GetB(), 200); + EXPECT_NEAR(foo.GetC(), 300.3, 0.01); + char buffer[100]; + foo.GetD(buffer, 100); + EXPECT_STREQ(buffer, "bar"); + EXPECT_NEAR(foo.GetE(), 400.4, 0.01); + EXPECT_EQ(foo.GetF(), true); + + bar.SetInstrumentedFoo(foo); + bar.SetInstrumentedFoo(&foo); + bar.Validate(); + } } diff --git a/gnu/llvm/lldb/unittests/Utility/ReproducerTest.cpp b/gnu/llvm/lldb/unittests/Utility/ReproducerTest.cpp index e4ac030350c..5a9dea3450f 100644 --- a/gnu/llvm/lldb/unittests/Utility/ReproducerTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/ReproducerTest.cpp @@ -1,4 +1,4 @@ -//===-- ReproducerTest.cpp --------------------------------------*- C++ -*-===// +//===-- ReproducerTest.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,6 +9,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/Support/Error.h" #include "llvm/Testing/Support/Error.h" @@ -31,8 +32,25 @@ public: static char ID; }; +class YamlMultiProvider + : public MultiProvider { +public: + struct Info { + static const char *name; + static const char *file; + }; + + YamlMultiProvider(const FileSpec &directory) : MultiProvider(directory) {} + + static char ID; +}; + const char *DummyProvider::Info::name = "dummy"; const char *DummyProvider::Info::file = "dummy.yaml"; +const char *YamlMultiProvider::Info::name = "mutli"; +const char *YamlMultiProvider::Info::file = "mutli.yaml"; +char DummyProvider::ID = 0; +char YamlMultiProvider::ID = 0; class DummyReproducer : public Reproducer { public: @@ -42,7 +60,25 @@ public: using Reproducer::SetReplay; }; -char DummyProvider::ID = 0; +struct YamlData { + YamlData() : i(-1) {} + YamlData(int i) : i(i) {} + int i; +}; + +inline bool operator==(const YamlData &LHS, const YamlData &RHS) { + return LHS.i == RHS.i; +} + +LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(YamlData) + +namespace llvm { +namespace yaml { +template <> struct MappingTraits { + static void mapping(IO &io, YamlData &Y) { io.mapRequired("i", Y.i); }; +}; +} // namespace yaml +} // namespace llvm TEST(ReproducerTest, SetCapture) { DummyReproducer reproducer; @@ -144,3 +180,83 @@ TEST(GeneratorTest, GetOrCreate) { auto &provider_alt = generator.GetOrCreate(); EXPECT_EQ(&provider, &provider_alt); } + +TEST(GeneratorTest, YamlMultiProvider) { + SmallString<128> root; + std::error_code ec = llvm::sys::fs::createUniqueDirectory("reproducer", root); + ASSERT_FALSE(static_cast(ec)); + + auto cleanup = llvm::make_scope_exit( + [&] { EXPECT_FALSE(llvm::sys::fs::remove_directories(root.str())); }); + + YamlData data0(0); + YamlData data1(1); + YamlData data2(2); + YamlData data3(3); + + { + DummyReproducer reproducer; + EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec(root.str())), Succeeded()); + + auto &generator = *reproducer.GetGenerator(); + auto *provider = generator.Create(); + ASSERT_NE(nullptr, provider); + + auto *recorder = provider->GetNewRecorder(); + ASSERT_NE(nullptr, recorder); + recorder->Record(data0); + recorder->Record(data1); + + recorder = provider->GetNewRecorder(); + ASSERT_NE(nullptr, recorder); + recorder->Record(data2); + recorder->Record(data3); + + generator.Keep(); + } + + { + DummyReproducer reproducer; + EXPECT_THAT_ERROR(reproducer.SetReplay(FileSpec(root.str())), Succeeded()); + + auto &loader = *reproducer.GetLoader(); + std::unique_ptr> multi_loader = + repro::MultiLoader::Create(&loader); + + // Read the first file. + { + llvm::Optional file = multi_loader->GetNextFile(); + EXPECT_TRUE(static_cast(file)); + + auto buffer = llvm::MemoryBuffer::getFile(*file); + EXPECT_TRUE(static_cast(buffer)); + + yaml::Input yin((*buffer)->getBuffer()); + std::vector data; + yin >> data; + + ASSERT_EQ(data.size(), 2U); + EXPECT_THAT(data, testing::ElementsAre(data0, data1)); + } + + // Read the second file. + { + llvm::Optional file = multi_loader->GetNextFile(); + EXPECT_TRUE(static_cast(file)); + + auto buffer = llvm::MemoryBuffer::getFile(*file); + EXPECT_TRUE(static_cast(buffer)); + + yaml::Input yin((*buffer)->getBuffer()); + std::vector data; + yin >> data; + + ASSERT_EQ(data.size(), 2U); + EXPECT_THAT(data, testing::ElementsAre(data2, data3)); + } + + // There is no third file. + llvm::Optional file = multi_loader->GetNextFile(); + EXPECT_FALSE(static_cast(file)); + } +} diff --git a/gnu/llvm/lldb/unittests/Utility/ScalarTest.cpp b/gnu/llvm/lldb/unittests/Utility/ScalarTest.cpp index 3a955e9a668..dd4683145b9 100644 --- a/gnu/llvm/lldb/unittests/Utility/ScalarTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/ScalarTest.cpp @@ -1,4 +1,4 @@ -//===-- ScalarTest.cpp ------------------------------------------*- C++ -*-===// +//===-- ScalarTest.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -66,6 +66,47 @@ TEST(ScalarTest, ComparisonFloat) { ASSERT_TRUE(s2 >= s1); } +template static void CheckConversion(T val) { + SCOPED_TRACE("val = " + std::to_string(val)); + EXPECT_EQ((signed char)val, Scalar(val).SChar()); + EXPECT_EQ((unsigned char)val, Scalar(val).UChar()); + EXPECT_EQ((short)val, Scalar(val).SShort()); + EXPECT_EQ((unsigned short)val, Scalar(val).UShort()); + EXPECT_EQ((int)val, Scalar(val).SInt()); + EXPECT_EQ((unsigned)val, Scalar(val).UInt()); + EXPECT_EQ((long)val, Scalar(val).SLong()); + EXPECT_EQ((unsigned long)val, Scalar(val).ULong()); + EXPECT_EQ((long long)val, Scalar(val).SLongLong()); + EXPECT_EQ((unsigned long long)val, Scalar(val).ULongLong()); + EXPECT_NEAR((float)val, Scalar(val).Float(), std::abs(val / 1e6)); + EXPECT_NEAR((double)val, Scalar(val).Double(), std::abs(val / 1e12)); + EXPECT_NEAR((long double)val, Scalar(val).LongDouble(), std::abs(val / 1e12)); +} + +TEST(ScalarTest, Getters) { + CheckConversion(0x87654321); + CheckConversion(0x87654321u); + CheckConversion(0x87654321l); + CheckConversion(0x87654321ul); + CheckConversion(0x8765432112345678ll); + CheckConversion(0x8765432112345678ull); + CheckConversion(42.25f); + CheckConversion(42.25); + + EXPECT_EQ(APInt(128, 1) << 70, Scalar(std::pow(2.0f, 70.0f)).SInt128(APInt())); + EXPECT_EQ(APInt(128, -1, true) << 70, + Scalar(-std::pow(2.0f, 70.0f)).SInt128(APInt())); + EXPECT_EQ(APInt(128, 1) << 70, + Scalar(std::pow(2.0f, 70.0f)).UInt128(APInt())); + EXPECT_EQ(APInt(128, 0), Scalar(-std::pow(2.0f, 70.0f)).UInt128(APInt())); + + EXPECT_EQ(APInt(128, 1) << 70, Scalar(std::pow(2.0, 70.0)).SInt128(APInt())); + EXPECT_EQ(APInt(128, -1, true) << 70, + Scalar(-std::pow(2.0, 70.0)).SInt128(APInt())); + EXPECT_EQ(APInt(128, 1) << 70, Scalar(std::pow(2.0, 70.0)).UInt128(APInt())); + EXPECT_EQ(APInt(128, 0), Scalar(-std::pow(2.0, 70.0)).UInt128(APInt())); +} + TEST(ScalarTest, RightShiftOperator) { int a = 0x00001000; int b = 0xFFFFFFFF; @@ -78,6 +119,7 @@ TEST(ScalarTest, RightShiftOperator) { } TEST(ScalarTest, GetBytes) { + uint8_t Storage[256]; int a = 0x01020304; long long b = 0x0102030405060708LL; float c = 1234567.89e32f; @@ -99,35 +141,53 @@ TEST(ScalarTest, GetBytes) { sizeof(void *)); Status f_error = f_scalar.SetValueFromData(f_data, lldb::eEncodingUint, sizeof(f)); - ASSERT_EQ(0, memcmp(&a, a_scalar.GetBytes(), sizeof(a))); - ASSERT_EQ(0, memcmp(&b, b_scalar.GetBytes(), sizeof(b))); - ASSERT_EQ(0, memcmp(&c, c_scalar.GetBytes(), sizeof(c))); - ASSERT_EQ(0, memcmp(&d, d_scalar.GetBytes(), sizeof(d))); + a_scalar.GetBytes(Storage); + ASSERT_EQ(0, memcmp(&a, Storage, sizeof(a))); + b_scalar.GetBytes(Storage); + ASSERT_EQ(0, memcmp(&b, Storage, sizeof(b))); + c_scalar.GetBytes(Storage); + ASSERT_EQ(0, memcmp(&c, Storage, sizeof(c))); + d_scalar.GetBytes(Storage); + ASSERT_EQ(0, memcmp(&d, Storage, sizeof(d))); ASSERT_EQ(0, e_error.Fail()); - ASSERT_EQ(0, memcmp(e, e_scalar.GetBytes(), sizeof(e))); + e_scalar.GetBytes(Storage); + ASSERT_EQ(0, memcmp(e, Storage, sizeof(e))); ASSERT_EQ(0, f_error.Fail()); - ASSERT_EQ(0, memcmp(f, f_scalar.GetBytes(), sizeof(f))); + f_scalar.GetBytes(Storage); + ASSERT_EQ(0, memcmp(f, Storage, sizeof(f))); } TEST(ScalarTest, CastOperations) { long long a = 0xf1f2f3f4f5f6f7f8LL; Scalar a_scalar(a); - ASSERT_EQ((signed char)a, a_scalar.SChar()); - ASSERT_EQ((unsigned char)a, a_scalar.UChar()); - ASSERT_EQ((signed short)a, a_scalar.SShort()); - ASSERT_EQ((unsigned short)a, a_scalar.UShort()); - ASSERT_EQ((signed int)a, a_scalar.SInt()); - ASSERT_EQ((unsigned int)a, a_scalar.UInt()); - ASSERT_EQ((signed long)a, a_scalar.SLong()); - ASSERT_EQ((unsigned long)a, a_scalar.ULong()); - ASSERT_EQ((signed long long)a, a_scalar.SLongLong()); - ASSERT_EQ((unsigned long long)a, a_scalar.ULongLong()); + EXPECT_EQ((signed char)a, a_scalar.SChar()); + EXPECT_EQ((unsigned char)a, a_scalar.UChar()); + EXPECT_EQ((signed short)a, a_scalar.SShort()); + EXPECT_EQ((unsigned short)a, a_scalar.UShort()); + EXPECT_EQ((signed int)a, a_scalar.SInt()); + EXPECT_EQ((unsigned int)a, a_scalar.UInt()); + EXPECT_EQ((signed long)a, a_scalar.SLong()); + EXPECT_EQ((unsigned long)a, a_scalar.ULong()); + EXPECT_EQ((signed long long)a, a_scalar.SLongLong()); + EXPECT_EQ((unsigned long long)a, a_scalar.ULongLong()); int a2 = 23; Scalar a2_scalar(a2); - ASSERT_EQ((float)a2, a2_scalar.Float()); - ASSERT_EQ((double)a2, a2_scalar.Double()); - ASSERT_EQ((long double)a2, a2_scalar.LongDouble()); + EXPECT_EQ((float)a2, a2_scalar.Float()); + EXPECT_EQ((double)a2, a2_scalar.Double()); + EXPECT_EQ((long double)a2, a2_scalar.LongDouble()); + + EXPECT_EQ(std::numeric_limits::min(), Scalar(-1.0f).UInt()); + EXPECT_EQ(std::numeric_limits::max(), Scalar(1e11f).UInt()); + EXPECT_EQ(std::numeric_limits::min(), + Scalar(-1.0).ULongLong()); + EXPECT_EQ(std::numeric_limits::max(), + Scalar(1e22).ULongLong()); + + EXPECT_EQ(std::numeric_limits::min(), Scalar(-1e11f).SInt()); + EXPECT_EQ(std::numeric_limits::max(), Scalar(1e11f).SInt()); + EXPECT_EQ(std::numeric_limits::min(), Scalar(-1e22).SLongLong()); + EXPECT_EQ(std::numeric_limits::max(), Scalar(1e22).SLongLong()); } TEST(ScalarTest, ExtractBitfield) { @@ -137,27 +197,27 @@ TEST(ScalarTest, ExtractBitfield) { long long b1 = 0xff1f2f3f4f5f6f7fLL; Scalar s_scalar(a1); ASSERT_TRUE(s_scalar.ExtractBitfield(0, 0)); - ASSERT_EQ(0, memcmp(&a1, s_scalar.GetBytes(), sizeof(a1))); + EXPECT_EQ(s_scalar, a1); ASSERT_TRUE(s_scalar.ExtractBitfield(len, 0)); - ASSERT_EQ(0, memcmp(&a1, s_scalar.GetBytes(), sizeof(a1))); + EXPECT_EQ(s_scalar, a1); ASSERT_TRUE(s_scalar.ExtractBitfield(len - 4, 4)); - ASSERT_EQ(0, memcmp(&b1, s_scalar.GetBytes(), sizeof(b1))); + EXPECT_EQ(s_scalar, b1); unsigned long long a2 = 0xf1f2f3f4f5f6f7f8ULL; unsigned long long b2 = 0x0f1f2f3f4f5f6f7fULL; Scalar u_scalar(a2); ASSERT_TRUE(u_scalar.ExtractBitfield(0, 0)); - ASSERT_EQ(0, memcmp(&a2, u_scalar.GetBytes(), sizeof(a2))); + EXPECT_EQ(u_scalar, a2); ASSERT_TRUE(u_scalar.ExtractBitfield(len, 0)); - ASSERT_EQ(0, memcmp(&a2, u_scalar.GetBytes(), sizeof(a2))); + EXPECT_EQ(u_scalar, a2); ASSERT_TRUE(u_scalar.ExtractBitfield(len - 4, 4)); - ASSERT_EQ(0, memcmp(&b2, u_scalar.GetBytes(), sizeof(b2))); + EXPECT_EQ(u_scalar, b2); } template static std::string ScalarGetValue(T value) { StreamString stream; Scalar(value).GetValue(&stream, false); - return stream.GetString(); + return std::string(stream.GetString()); } TEST(ScalarTest, GetValue) { @@ -188,6 +248,16 @@ TEST(ScalarTest, GetValue) { ScalarGetValue(std::numeric_limits::max())); } +TEST(ScalarTest, LongLongAssigmentOperator) { + Scalar ull; + ull = std::numeric_limits::max(); + EXPECT_EQ(std::numeric_limits::max(), ull.ULongLong()); + + Scalar sll; + sll = std::numeric_limits::max(); + EXPECT_EQ(std::numeric_limits::max(), sll.SLongLong()); +} + TEST(ScalarTest, Division) { Scalar lhs(5.0); Scalar rhs(2.0); @@ -264,6 +334,20 @@ TEST(ScalarTest, SetValueFromCString) { EXPECT_THAT_ERROR( a.SetValueFromCString("-123", lldb::eEncodingUint, 8).ToError(), Failed()); + EXPECT_THAT_ERROR( + a.SetValueFromCString("-2147483648", lldb::eEncodingSint, 4).ToError(), + Succeeded()); + EXPECT_EQ(-2147483648, a); + EXPECT_THAT_ERROR( + a.SetValueFromCString("-2147483649", lldb::eEncodingSint, 4).ToError(), + Failed()); + EXPECT_THAT_ERROR( + a.SetValueFromCString("47.25", lldb::eEncodingIEEE754, 4).ToError(), + Succeeded()); + EXPECT_EQ(47.25f, a); + EXPECT_THAT_ERROR( + a.SetValueFromCString("asdf", lldb::eEncodingIEEE754, 4).ToError(), + Failed()); } TEST(ScalarTest, APIntConstructor) { @@ -295,7 +379,7 @@ TEST(ScalarTest, Scalar_512) { ASSERT_TRUE(S.MakeUnsigned()); EXPECT_EQ(S.GetType(), Scalar::e_uint512); - ASSERT_STREQ(S.GetTypeAsCString(), "unsigned int512_t"); + ASSERT_STREQ(S.GetTypeAsCString(), "uint512_t"); ASSERT_STREQ(S.GetValueTypeAsCString(Scalar::e_uint512), "uint512_t"); EXPECT_EQ(S.GetByteSize(), 64U); @@ -303,3 +387,15 @@ TEST(ScalarTest, Scalar_512) { EXPECT_EQ(S.GetType(), Scalar::e_sint512); EXPECT_EQ(S.GetByteSize(), 64U); } + +TEST(ScalarTest, TruncOrExtendTo) { + Scalar S(0xffff); + S.TruncOrExtendTo(12, true); + EXPECT_EQ(S.UInt128(APInt()), APInt(12, 0xfffu)); + S.TruncOrExtendTo(20, true); + EXPECT_EQ(S.UInt128(APInt()), APInt(20, 0xfffffu)); + S.TruncOrExtendTo(24, false); + EXPECT_EQ(S.UInt128(APInt()), APInt(24, 0x0fffffu)); + S.TruncOrExtendTo(16, false); + EXPECT_EQ(S.UInt128(APInt()), APInt(16, 0xffffu)); +} diff --git a/gnu/llvm/lldb/unittests/Utility/SharedClusterTest.cpp b/gnu/llvm/lldb/unittests/Utility/SharedClusterTest.cpp new file mode 100644 index 00000000000..56dd4da2ed9 --- /dev/null +++ b/gnu/llvm/lldb/unittests/Utility/SharedClusterTest.cpp @@ -0,0 +1,58 @@ +//===-- SharedClusterTest.cpp ---------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/SharedCluster.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using namespace lldb_private; + +namespace { +class DestructNotifier { +public: + DestructNotifier(std::vector &Queue, int Key) : Queue(Queue), Key(Key) {} + ~DestructNotifier() { Queue.push_back(Key); } + + std::vector &Queue; + const int Key; +}; +} // namespace + +TEST(SharedCluster, ClusterManager) { + std::vector Queue; + { + auto CM = ClusterManager::Create(); + auto *One = new DestructNotifier(Queue, 1); + auto *Two = new DestructNotifier(Queue, 2); + CM->ManageObject(One); + CM->ManageObject(Two); + + ASSERT_THAT(Queue, testing::IsEmpty()); + { + std::shared_ptr OnePtr = CM->GetSharedPointer(One); + ASSERT_EQ(OnePtr->Key, 1); + ASSERT_THAT(Queue, testing::IsEmpty()); + + { + std::shared_ptr OnePtrCopy = OnePtr; + ASSERT_EQ(OnePtrCopy->Key, 1); + ASSERT_THAT(Queue, testing::IsEmpty()); + } + + { + std::shared_ptr TwoPtr = CM->GetSharedPointer(Two); + ASSERT_EQ(TwoPtr->Key, 2); + ASSERT_THAT(Queue, testing::IsEmpty()); + } + + ASSERT_THAT(Queue, testing::IsEmpty()); + } + ASSERT_THAT(Queue, testing::IsEmpty()); + } + ASSERT_THAT(Queue, testing::ElementsAre(1, 2)); +} diff --git a/gnu/llvm/lldb/unittests/Utility/StateTest.cpp b/gnu/llvm/lldb/unittests/Utility/StateTest.cpp index 5560aa5631f..d91a23123b0 100644 --- a/gnu/llvm/lldb/unittests/Utility/StateTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/StateTest.cpp @@ -1,4 +1,4 @@ -//===-- StateTest.cpp -------------------------------------------*- C++ -*-===// +//===-- StateTest.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/StatusTest.cpp b/gnu/llvm/lldb/unittests/Utility/StatusTest.cpp index 46e2c8e1170..862c063b2e0 100644 --- a/gnu/llvm/lldb/unittests/Utility/StatusTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/StatusTest.cpp @@ -1,4 +1,4 @@ -//===-- StatusTest.cpp ------------------------------------------*- C++ -*-===// +//===-- StatusTest.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -41,6 +41,15 @@ TEST(StatusTest, ErrorConstructor) { EXPECT_TRUE(foo.Success()); } +TEST(StatusTest, ErrorCodeConstructor) { + EXPECT_TRUE(Status(std::error_code()).Success()); + + Status eagain = std::error_code(EAGAIN, std::generic_category()); + EXPECT_TRUE(eagain.Fail()); + EXPECT_EQ(eErrorTypePOSIX, eagain.GetType()); + EXPECT_EQ(Status::ValueType(EAGAIN), eagain.GetError()); +} + TEST(StatusTest, ErrorConversion) { EXPECT_FALSE(bool(Status().ToError())); diff --git a/gnu/llvm/lldb/unittests/Utility/StreamTeeTest.cpp b/gnu/llvm/lldb/unittests/Utility/StreamTeeTest.cpp index c55006bfb85..e92ee3eb022 100644 --- a/gnu/llvm/lldb/unittests/Utility/StreamTeeTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/StreamTeeTest.cpp @@ -1,4 +1,4 @@ -//===-- StreamTeeTest.cpp ---------------------------------------*- C++ -*-===// +//===-- StreamTeeTest.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/StreamTest.cpp b/gnu/llvm/lldb/unittests/Utility/StreamTest.cpp index c740c27467a..940d49fdfdb 100644 --- a/gnu/llvm/lldb/unittests/Utility/StreamTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/StreamTest.cpp @@ -1,4 +1,4 @@ -//===-- StreamTest.cpp ------------------------------------------*- C++ -*-===// +//===-- StreamTest.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -129,6 +129,39 @@ TEST_F(StreamTest, ChangingByteOrder) { EXPECT_EQ(lldb::eByteOrderPDP, s.GetByteOrder()); } +TEST_F(StreamTest, SetIndentLevel) { + s.Indent("a"); + EXPECT_EQ("a", TakeValue()); + + s.SetIndentLevel(3); + s.Indent("a"); + EXPECT_EQ(" a", TakeValue()); + + s.SetIndentLevel(2); + s.Indent("a"); + EXPECT_EQ(" a", TakeValue()); + + s.SetIndentLevel(0); + s.Indent("a"); + EXPECT_EQ("a", TakeValue()); +} + +TEST_F(StreamTest, Indent) { + s.SetIndentLevel(2); + const char *nullptr_cstring = nullptr; + s.Indent(nullptr_cstring); + EXPECT_EQ(" ", TakeValue()); + + s.Indent(""); + EXPECT_EQ(" ", TakeValue()); + + s.Indent(" "); + EXPECT_EQ(" ", TakeValue()); + + s.Indent(" aa"); + EXPECT_EQ(" aa", TakeValue()); +} + TEST_F(StreamTest, PutChar) { s.PutChar('a'); EXPECT_EQ(1U, s.GetWrittenBytes()); diff --git a/gnu/llvm/lldb/unittests/Utility/StringLexerTest.cpp b/gnu/llvm/lldb/unittests/Utility/StringLexerTest.cpp index 1d8c918a1bf..f7a81bddcea 100644 --- a/gnu/llvm/lldb/unittests/Utility/StringLexerTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/StringLexerTest.cpp @@ -1,4 +1,4 @@ -//===-- StringLexerTest.cpp -------------------------------------*- C++ -*-===// +//===-- StringLexerTest.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/StringListTest.cpp b/gnu/llvm/lldb/unittests/Utility/StringListTest.cpp index 926f75fb4f3..08d55a51c70 100644 --- a/gnu/llvm/lldb/unittests/Utility/StringListTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/StringListTest.cpp @@ -1,4 +1,4 @@ -//===-- StringListTest.cpp ---------------------------------------*- C++ -*-===// +//===-- StringListTest.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/StructuredDataTest.cpp b/gnu/llvm/lldb/unittests/Utility/StructuredDataTest.cpp index 44bf6af1bf6..cb5e418cd95 100644 --- a/gnu/llvm/lldb/unittests/Utility/StructuredDataTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/StructuredDataTest.cpp @@ -1,4 +1,4 @@ -//===-- StructuredDataTest.cpp ----------------------------------*- C++ -*-===// +//===-- StructuredDataTest.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/SubsystemRAIITest.cpp b/gnu/llvm/lldb/unittests/Utility/SubsystemRAIITest.cpp index 38cb2470c64..1a23bfc716f 100644 --- a/gnu/llvm/lldb/unittests/Utility/SubsystemRAIITest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/SubsystemRAIITest.cpp @@ -1,4 +1,4 @@ -//===-- SubsystemRAIITest.cpp -----------------------------------*- C++ -*-===// +//===-- SubsystemRAIITest.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/TimeoutTest.cpp b/gnu/llvm/lldb/unittests/Utility/TimeoutTest.cpp index 79d070b1003..222ee5db177 100644 --- a/gnu/llvm/lldb/unittests/Utility/TimeoutTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/TimeoutTest.cpp @@ -1,4 +1,4 @@ -//===-- TimeoutTest.cpp -----------------------------------------*- C++ -*-===// +//===-- TimeoutTest.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/TimerTest.cpp b/gnu/llvm/lldb/unittests/Utility/TimerTest.cpp index 9e3dc8a0391..2d323c0dc2a 100644 --- a/gnu/llvm/lldb/unittests/Utility/TimerTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/TimerTest.cpp @@ -1,4 +1,4 @@ -//===-- TimerTest.cpp -------------------------------------------*- C++ -*-===// +//===-- TimerTest.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/UUIDTest.cpp b/gnu/llvm/lldb/unittests/Utility/UUIDTest.cpp index 94f46fd9e00..1c84315d402 100644 --- a/gnu/llvm/lldb/unittests/Utility/UUIDTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/UUIDTest.cpp @@ -1,4 +1,4 @@ -//===-- UUIDTest.cpp --------------------------------------------*- C++ -*-===// +//===-- UUIDTest.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -45,7 +45,7 @@ TEST(UUIDTest, Validity) { from_str.SetFromStringRef("00000000-0000-0000-0000-000000000000"); UUID opt_from_str; opt_from_str.SetFromOptionalStringRef("00000000-0000-0000-0000-000000000000"); - + EXPECT_FALSE(empty); EXPECT_TRUE(a16); EXPECT_TRUE(a20); @@ -57,25 +57,30 @@ TEST(UUIDTest, Validity) { TEST(UUIDTest, SetFromStringRef) { UUID u; - EXPECT_EQ(32u, u.SetFromStringRef("404142434445464748494a4b4c4d4e4f")); + EXPECT_TRUE(u.SetFromStringRef("404142434445464748494a4b4c4d4e4f")); EXPECT_EQ(UUID::fromData("@ABCDEFGHIJKLMNO", 16), u); - EXPECT_EQ(36u, u.SetFromStringRef("40-41-42-43-4445464748494a4b4c4d4e4f")); + EXPECT_TRUE(u.SetFromStringRef("40-41-42-43-4445464748494a4b4c4d4e4f")); EXPECT_EQ(UUID::fromData("@ABCDEFGHIJKLMNO", 16), u); - EXPECT_EQ(45u, u.SetFromStringRef( - "40-41-42-43-4445464748494a4b4c4d4e4f-50515253", 20)); + EXPECT_TRUE( + u.SetFromStringRef("40-41-42-43-4445464748494a4b4c4d4e4f-50515253")); EXPECT_EQ(UUID::fromData("@ABCDEFGHIJKLMNOPQRS", 20), u); - EXPECT_EQ(0u, u.SetFromStringRef("40-41-42-43-4445464748494a4b4c4d4e4f", 20)); - EXPECT_EQ(0u, u.SetFromStringRef("40xxxxx")); - EXPECT_EQ(0u, u.SetFromStringRef("")); - EXPECT_EQ(UUID::fromData("@ABCDEFGHIJKLMNOPQRS", 20), u) + EXPECT_TRUE(u.SetFromStringRef("40-41-42-43-4445464748494a4b4c4d4e4f")); + + EXPECT_FALSE(u.SetFromStringRef("40xxxxx")); + EXPECT_FALSE(u.SetFromStringRef("")); + EXPECT_EQ(UUID::fromData("@ABCDEFGHIJKLMNO", 16), u) << "uuid was changed by failed parse calls"; - EXPECT_EQ( - 32u, u.SetFromStringRef("404142434445464748494a4b4c4d4e4f-50515253", 16)); - EXPECT_EQ(UUID::fromData("@ABCDEFGHIJKLMNO", 16), u); + EXPECT_TRUE(u.SetFromStringRef("404142434445464748494a4b4c4d4e4f-50515253")); + EXPECT_EQ(UUID::fromData("@ABCDEFGHIJKLMNOPQRS", 20), u); + + EXPECT_TRUE(u.SetFromStringRef("40414243")); + EXPECT_EQ(UUID::fromData("@ABCD", 4), u); + + EXPECT_FALSE(u.SetFromStringRef("4")); } TEST(UUIDTest, StringConverion) { diff --git a/gnu/llvm/lldb/unittests/Utility/UriParserTest.cpp b/gnu/llvm/lldb/unittests/Utility/UriParserTest.cpp index c07d59a55e0..c88a647ef93 100644 --- a/gnu/llvm/lldb/unittests/Utility/UriParserTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/UriParserTest.cpp @@ -74,12 +74,19 @@ TEST(UriParserTest, LongPath) { VALIDATE } -TEST(UriParserTest, TypicalPortPath) { +TEST(UriParserTest, TypicalPortPathIPv4) { const UriTestCase testCase("connect://192.168.100.132:5432/", "connect", "192.168.100.132", 5432, "/"); VALIDATE; } +TEST(UriParserTest, TypicalPortPathIPv6) { + const UriTestCase testCase( + "connect://[2601:600:107f:db64:a42b:4faa:284:3082]:5432/", "connect", + "2601:600:107f:db64:a42b:4faa:284:3082", 5432, "/"); + VALIDATE; +} + TEST(UriParserTest, BracketedHostnamePort) { const UriTestCase testCase("connect://[192.168.100.132]:5432/", "connect", "192.168.100.132", 5432, "/"); @@ -102,6 +109,21 @@ TEST(UriParserTest, BracketedHostname) { VALIDATE } +TEST(UriParserTest, BracketedHostnameWithPortIPv4) { + // Android device over IPv4: port is a part of the hostname. + const UriTestCase testCase("connect://[192.168.100.132:1234]", "connect", + "192.168.100.132:1234", -1, "/"); + VALIDATE +} + +TEST(UriParserTest, BracketedHostnameWithPortIPv6) { + // Android device over IPv6: port is a part of the hostname. + const UriTestCase testCase( + "connect://[[2601:600:107f:db64:a42b:4faa:284]:1234]", "connect", + "[2601:600:107f:db64:a42b:4faa:284]:1234", -1, "/"); + VALIDATE +} + TEST(UriParserTest, BracketedHostnameWithColon) { const UriTestCase testCase("connect://[192.168.100.132:5555]:1234", "connect", "192.168.100.132:5555", 1234, "/"); diff --git a/gnu/llvm/lldb/unittests/Utility/UserIDResolverTest.cpp b/gnu/llvm/lldb/unittests/Utility/UserIDResolverTest.cpp index 4709b342ddb..7cd89609b35 100644 --- a/gnu/llvm/lldb/unittests/Utility/UserIDResolverTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/UserIDResolverTest.cpp @@ -1,4 +1,4 @@ -//===-- UserIDResolverTest.cpp ----------------------------------*- C++ -*-===// +//===-- UserIDResolverTest.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/VASprintfTest.cpp b/gnu/llvm/lldb/unittests/Utility/VASprintfTest.cpp index a7c146b7286..a04cd27362d 100644 --- a/gnu/llvm/lldb/unittests/Utility/VASprintfTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/VASprintfTest.cpp @@ -1,4 +1,4 @@ -//===-- VASprintfTest.cpp ---------------------------------------*- C++ -*-===// +//===-- VASprintfTest.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/VMRangeTest.cpp b/gnu/llvm/lldb/unittests/Utility/VMRangeTest.cpp index 54180c3c626..064f12090b9 100644 --- a/gnu/llvm/lldb/unittests/Utility/VMRangeTest.cpp +++ b/gnu/llvm/lldb/unittests/Utility/VMRangeTest.cpp @@ -1,4 +1,4 @@ -//===-- VMRangeTest.cpp -----------------------------------------*- C++ -*-===// +//===-- VMRangeTest.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/Utility/XcodeSDKTest.cpp b/gnu/llvm/lldb/unittests/Utility/XcodeSDKTest.cpp new file mode 100644 index 00000000000..69e4d2caa01 --- /dev/null +++ b/gnu/llvm/lldb/unittests/Utility/XcodeSDKTest.cpp @@ -0,0 +1,241 @@ +//===-- XcodeSDKTest.cpp --------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" + +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/XcodeSDK.h" + +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Triple.h" + +#include + +using namespace lldb_private; + +TEST(XcodeSDKTest, ParseTest) { + EXPECT_EQ(XcodeSDK::GetAnyMacOS().GetType(), XcodeSDK::MacOSX); + EXPECT_EQ(XcodeSDK("MacOSX.sdk").GetType(), XcodeSDK::MacOSX); + EXPECT_EQ(XcodeSDK("iPhoneSimulator.sdk").GetType(), XcodeSDK::iPhoneSimulator); + EXPECT_EQ(XcodeSDK("iPhoneOS.sdk").GetType(), XcodeSDK::iPhoneOS); + EXPECT_EQ(XcodeSDK("AppleTVSimulator.sdk").GetType(), XcodeSDK::AppleTVSimulator); + EXPECT_EQ(XcodeSDK("AppleTVOS.sdk").GetType(), XcodeSDK::AppleTVOS); + EXPECT_EQ(XcodeSDK("WatchSimulator.sdk").GetType(), XcodeSDK::WatchSimulator); + EXPECT_EQ(XcodeSDK("WatchOS.sdk").GetType(), XcodeSDK::watchOS); + EXPECT_EQ(XcodeSDK("Linux.sdk").GetType(), XcodeSDK::Linux); + EXPECT_EQ(XcodeSDK("MacOSX.sdk").GetVersion(), llvm::VersionTuple()); + EXPECT_EQ(XcodeSDK("MacOSX10.9.sdk").GetVersion(), llvm::VersionTuple(10, 9)); + EXPECT_EQ(XcodeSDK("MacOSX10.15.4.sdk").GetVersion(), llvm::VersionTuple(10, 15)); + EXPECT_EQ(XcodeSDK("MacOSX.sdk").IsAppleInternalSDK(), false); + EXPECT_EQ(XcodeSDK("MacOSX10.15.Internal.sdk").GetType(), XcodeSDK::MacOSX); + EXPECT_EQ(XcodeSDK("MacOSX10.15.Internal.sdk").GetVersion(), + llvm::VersionTuple(10, 15)); + EXPECT_EQ(XcodeSDK("MacOSX10.15.Internal.sdk").IsAppleInternalSDK(), true); + EXPECT_EQ(XcodeSDK().GetType(), XcodeSDK::unknown); + EXPECT_EQ(XcodeSDK().GetVersion(), llvm::VersionTuple()); +} + +TEST(XcodeSDKTest, MergeTest) { + XcodeSDK sdk("MacOSX.sdk"); + sdk.Merge(XcodeSDK("WatchOS.sdk")); + // This doesn't make any particular sense and shouldn't happen in practice, we + // just want to guarantee a well-defined behavior when choosing one + // SDK to fit all CUs in an lldb::Module. + // -> The higher number wins. + EXPECT_EQ(sdk.GetType(), XcodeSDK::watchOS); + sdk.Merge(XcodeSDK("WatchOS1.1.sdk")); + EXPECT_EQ(sdk.GetVersion(), llvm::VersionTuple(1, 1)); + sdk.Merge(XcodeSDK("WatchOS2.0.sdk")); + EXPECT_EQ(sdk.GetVersion(), llvm::VersionTuple(2, 0)); + sdk.Merge(XcodeSDK("WatchOS1.1.Internal.sdk")); + EXPECT_EQ(sdk.GetVersion(), llvm::VersionTuple(2, 0)); + EXPECT_EQ(sdk.IsAppleInternalSDK(), true); + XcodeSDK empty; + empty.Merge(XcodeSDK("MacOSX10.14.Internal.sdk")); + EXPECT_EQ(empty.GetString(), llvm::StringRef("MacOSX10.14.Internal.sdk")); +} + +#ifndef _WIN32 +TEST(XcodeSDKTest, SDKSupportsModules) { + std::string base = "/Applications/Xcode.app/Contents/Developer/Platforms/"; + EXPECT_TRUE(XcodeSDK::SDKSupportsModules( + XcodeSDK::Type::iPhoneSimulator, + FileSpec( + base + + "iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator12.0.sdk"))); + EXPECT_TRUE(XcodeSDK::SDKSupportsModules( + XcodeSDK::Type::iPhoneSimulator, + FileSpec(base + "iPhoneSimulator.platform/Developer/SDKs/" + "iPhoneSimulator12.0.Internal.sdk"))); + EXPECT_FALSE(XcodeSDK::SDKSupportsModules( + XcodeSDK::Type::iPhoneSimulator, + FileSpec( + base + + "iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.2.sdk"))); + EXPECT_TRUE(XcodeSDK::SDKSupportsModules( + XcodeSDK::Type::MacOSX, + FileSpec(base + "MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk"))); + EXPECT_FALSE(XcodeSDK::SDKSupportsModules( + XcodeSDK::Type::MacOSX, + FileSpec(base + "MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk"))); +} +#endif + +TEST(XcodeSDKTest, SDKSupportsSwift) { + EXPECT_TRUE(XcodeSDK("iPhoneSimulator12.0.sdk").SupportsSwift()); + EXPECT_TRUE(XcodeSDK("iPhoneSimulator12.0.Internal.sdk").SupportsSwift()); + EXPECT_FALSE(XcodeSDK("iPhoneSimulator7.2.sdk").SupportsSwift()); + EXPECT_TRUE(XcodeSDK("MacOSX10.10.sdk").SupportsSwift()); + EXPECT_FALSE(XcodeSDK("MacOSX10.9.sdk").SupportsSwift()); + EXPECT_TRUE(XcodeSDK("Linux.sdk").SupportsSwift()); + EXPECT_TRUE(XcodeSDK("MacOSX.sdk").SupportsSwift()); + EXPECT_FALSE(XcodeSDK("EverythingElse.sdk").SupportsSwift()); +} + +TEST(XcodeSDKTest, GetCanonicalNameAndConstruct) { + XcodeSDK::Info info; + info.type = XcodeSDK::Type::MacOSX; + EXPECT_EQ("macosx", XcodeSDK::GetCanonicalName(info)); + EXPECT_EQ(XcodeSDK(info).Parse(), info); + + info.type = XcodeSDK::Type::iPhoneSimulator; + EXPECT_EQ("iphonesimulator", XcodeSDK::GetCanonicalName(info)); + EXPECT_EQ(XcodeSDK(info).Parse(), info); + + info.type = XcodeSDK::Type::iPhoneOS; + EXPECT_EQ("iphoneos", XcodeSDK::GetCanonicalName(info)); + EXPECT_EQ(XcodeSDK(info).Parse(), info); + + info.type = XcodeSDK::Type::AppleTVSimulator; + EXPECT_EQ("appletvsimulator", XcodeSDK::GetCanonicalName(info)); + EXPECT_EQ(XcodeSDK(info).Parse(), info); + + info.type = XcodeSDK::Type::AppleTVOS; + EXPECT_EQ("appletvos", XcodeSDK::GetCanonicalName(info)); + EXPECT_EQ(XcodeSDK(info).Parse(), info); + + info.type = XcodeSDK::Type::WatchSimulator; + EXPECT_EQ("watchsimulator", XcodeSDK::GetCanonicalName(info)); + EXPECT_EQ(XcodeSDK(info).Parse(), info); + + info.type = XcodeSDK::Type::watchOS; + EXPECT_EQ("watchos", XcodeSDK::GetCanonicalName(info)); + EXPECT_EQ(XcodeSDK(info).Parse(), info); + + info.type = XcodeSDK::Type::Linux; + EXPECT_EQ("linux", XcodeSDK::GetCanonicalName(info)); + EXPECT_EQ(XcodeSDK(info).Parse(), info); + + info.type = XcodeSDK::Type::unknown; + EXPECT_EQ("", XcodeSDK::GetCanonicalName(info)); + EXPECT_EQ(XcodeSDK(info).Parse(), info); + + info.internal = true; + info.type = XcodeSDK::Type::MacOSX; + EXPECT_EQ("macosx.internal", XcodeSDK::GetCanonicalName(info)); + EXPECT_EQ(XcodeSDK(info).Parse(), info); + + info.type = XcodeSDK::Type::iPhoneSimulator; + EXPECT_EQ("iphonesimulator.internal", XcodeSDK::GetCanonicalName(info)); + EXPECT_EQ(XcodeSDK(info).Parse(), info); + + info.type = XcodeSDK::Type::iPhoneOS; + EXPECT_EQ("iphoneos.internal", XcodeSDK::GetCanonicalName(info)); + EXPECT_EQ(XcodeSDK(info).Parse(), info); + + info.type = XcodeSDK::Type::AppleTVSimulator; + EXPECT_EQ("appletvsimulator.internal", XcodeSDK::GetCanonicalName(info)); + EXPECT_EQ(XcodeSDK(info).Parse(), info); + + info.type = XcodeSDK::Type::AppleTVOS; + EXPECT_EQ("appletvos.internal", XcodeSDK::GetCanonicalName(info)); + EXPECT_EQ(XcodeSDK(info).Parse(), info); + + info.type = XcodeSDK::Type::WatchSimulator; + EXPECT_EQ("watchsimulator.internal", XcodeSDK::GetCanonicalName(info)); + EXPECT_EQ(XcodeSDK(info).Parse(), info); + + info.type = XcodeSDK::Type::watchOS; + EXPECT_EQ("watchos.internal", XcodeSDK::GetCanonicalName(info)); + EXPECT_EQ(XcodeSDK(info).Parse(), info); + + info.type = XcodeSDK::Type::MacOSX; + info.version = llvm::VersionTuple(10, 9); + EXPECT_EQ("macosx10.9.internal", XcodeSDK::GetCanonicalName(info)); + EXPECT_EQ(XcodeSDK(info).Parse(), info); + + info.type = XcodeSDK::Type::iPhoneOS; + info.version = llvm::VersionTuple(7, 0); + EXPECT_EQ("iphoneos7.0.internal", XcodeSDK::GetCanonicalName(info)); + EXPECT_EQ(XcodeSDK(info).Parse(), info); +} + +TEST(XcodeSDKTest, GetSDKTypeForTriple) { + EXPECT_EQ( + XcodeSDK::GetSDKTypeForTriple(llvm::Triple("x86_64-apple-macosx10.14")), + XcodeSDK::Type::MacOSX); + EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("x86_64-apple-darwin")), + XcodeSDK::Type::MacOSX); + EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple( + llvm::Triple("x86_64-apple-ios13.4-simulator")), + XcodeSDK::Type::iPhoneSimulator); + EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("arm64-apple-ios13.4")), + XcodeSDK::Type::iPhoneOS); + EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple( + llvm::Triple("x86_64-apple-ios13.4-macabi")), + XcodeSDK::Type::MacOSX); + EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple( + llvm::Triple("x86_64-apple-tvos-simulator")), + XcodeSDK::Type::AppleTVSimulator); + EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("arm64-apple-tvos")), + XcodeSDK::Type::AppleTVOS); + EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple( + llvm::Triple("x86_64-apple-watchos-simulator")), + XcodeSDK::Type::WatchSimulator); + EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("arm64-apple-watchos")), + XcodeSDK::Type::watchOS); + EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("x86_64-unknown-linux")), + XcodeSDK::Type::Linux); + EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("i386-unknown-netbsd")), + XcodeSDK::Type::unknown); +} + +TEST(XcodeSDKTest, FindXcodeContentsDirectoryInPath) { + std::string standard = + "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/" + "Developer/SDKs/MacOSX.sdk"; + EXPECT_EQ("/Applications/Xcode.app/Contents", + XcodeSDK::FindXcodeContentsDirectoryInPath(standard)); + + std::string standard_version = + "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/" + "Developer/SDKs/MacOSX10.15.sdk"; + EXPECT_EQ("/Applications/Xcode.app/Contents", + XcodeSDK::FindXcodeContentsDirectoryInPath(standard_version)); + + std::string beta = "/Applications/Xcode-beta.app/Contents/Developer/" + "Platforms/MacOSX.platform/" + "Developer/SDKs/MacOSX10.15.sdk"; + EXPECT_EQ("/Applications/Xcode-beta.app/Contents", + XcodeSDK::FindXcodeContentsDirectoryInPath(beta)); + + std::string no_app = + "/Applications/Xcode/Contents/Developer/Platforms/MacOSX.platform/" + "Developer/SDKs/MacOSX10.15.sdk"; + EXPECT_EQ("", XcodeSDK::FindXcodeContentsDirectoryInPath(no_app)); + + std::string no_contents = + "/Applications/Xcode.app/Developer/Platforms/MacOSX.platform/" + "Developer/SDKs/MacOSX10.15.sdk"; + EXPECT_EQ("", XcodeSDK::FindXcodeContentsDirectoryInPath(no_contents)); + + std::string no_capitalization = + "/Applications/Xcode.app/contents/Developer/Platforms/MacOSX.platform/" + "Developer/SDKs/MacOSX10.15.sdk"; + EXPECT_EQ("", XcodeSDK::FindXcodeContentsDirectoryInPath(no_capitalization)); +} diff --git a/gnu/llvm/lldb/unittests/debugserver/CMakeLists.txt b/gnu/llvm/lldb/unittests/debugserver/CMakeLists.txt index a72b805c65b..c216eecd7d8 100644 --- a/gnu/llvm/lldb/unittests/debugserver/CMakeLists.txt +++ b/gnu/llvm/lldb/unittests/debugserver/CMakeLists.txt @@ -1,6 +1,6 @@ # Note: debugserver is a Darwin-only implementation of a remote debugging # server. It is not intended to be used on other platforms. The tests are here -# because using the LLDB Host API is convienent and allows testing of both parts +# because using the LLDB Host API is convenient and allows testing of both parts # of the debugserver communication path. If you are looking for a non-darwin # remote debugging server, please use lldb-server. @@ -15,6 +15,7 @@ add_lldb_unittest(debugserverTests LINK_LIBS lldbDebugserverCommon lldbHost + LLVMTestingSupport LINK_COMPONENTS Support ) diff --git a/gnu/llvm/lldb/unittests/debugserver/JSONTest.cpp b/gnu/llvm/lldb/unittests/debugserver/JSONTest.cpp index 54f6f96068e..ee359cc341d 100644 --- a/gnu/llvm/lldb/unittests/debugserver/JSONTest.cpp +++ b/gnu/llvm/lldb/unittests/debugserver/JSONTest.cpp @@ -1,4 +1,4 @@ -//===-- JSONTest.cpp --------------------------------------------*- C++ -*-===// +//===-- JSONTest.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/debugserver/RNBSocketTest.cpp b/gnu/llvm/lldb/unittests/debugserver/RNBSocketTest.cpp index 80d73c1175c..7840c48f82b 100644 --- a/gnu/llvm/lldb/unittests/debugserver/RNBSocketTest.cpp +++ b/gnu/llvm/lldb/unittests/debugserver/RNBSocketTest.cpp @@ -1,4 +1,4 @@ -//===-- RNBSocketTest.cpp ---------------------------------------*- C++ -*-===// +//===-- RNBSocketTest.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -17,6 +17,7 @@ #include "lldb/Host/Socket.h" #include "lldb/Host/StringConvert.h" #include "lldb/Host/common/TCPSocket.h" +#include "llvm/Testing/Support/Error.h" using namespace lldb_private; @@ -26,15 +27,16 @@ std::string goodbye = "Goodbye!"; static void ServerCallbackv4(const void *baton, in_port_t port) { auto child_pid = fork(); if (child_pid == 0) { - Socket *client_socket; char addr_buffer[256]; sprintf(addr_buffer, "%s:%d", baton, port); - Status err = Socket::TcpConnect(addr_buffer, false, client_socket); - if (err.Fail()) - abort(); + llvm::Expected> socket_or_err = + Socket::TcpConnect(addr_buffer, false); + ASSERT_THAT_EXPECTED(socket_or_err, llvm::Succeeded()); + Socket *client_socket = socket_or_err->get(); + char buffer[32]; size_t read_size = 32; - err = client_socket->Read((void *)&buffer[0], read_size); + Status err = client_socket->Read((void *)&buffer[0], read_size); if (err.Fail()) abort(); std::string Recv(&buffer[0], read_size); @@ -102,9 +104,10 @@ void TestSocketConnect(const char *addr) { Socket *server_socket; Predicate port_predicate; port_predicate.SetValue(0, eBroadcastNever); - Status err = - Socket::TcpListen(addr_wrap, false, server_socket, &port_predicate); - ASSERT_FALSE(err.Fail()); + llvm::Expected> socket_or_err = + Socket::TcpListen(addr_wrap, false, &port_predicate); + ASSERT_THAT_EXPECTED(socket_or_err, llvm::Succeeded()); + server_socket = socket_or_err->get(); auto port = ((TCPSocket *)server_socket)->GetLocalPortNumber(); auto child_pid = fork(); @@ -120,7 +123,7 @@ void TestSocketConnect(const char *addr) { ASSERT_EQ(bye, goodbye); } else { Socket *connected_socket; - err = server_socket->Accept(connected_socket); + Status err = server_socket->Accept(connected_socket); if (err.Fail()) { llvm::errs() << err.AsCString(); abort(); diff --git a/gnu/llvm/lldb/unittests/debugserver/debugserver_LogCallback.cpp b/gnu/llvm/lldb/unittests/debugserver/debugserver_LogCallback.cpp index 45a502f80df..2c7da2d127c 100644 --- a/gnu/llvm/lldb/unittests/debugserver/debugserver_LogCallback.cpp +++ b/gnu/llvm/lldb/unittests/debugserver/debugserver_LogCallback.cpp @@ -1,4 +1,4 @@ -//===-- debugserver_LogCallback.cpp -----------------------------*- C++ -*-===// +//===-- debugserver_LogCallback.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/gtest_common.h b/gnu/llvm/lldb/unittests/gtest_common.h index 00253f58f1d..3a92123a949 100644 --- a/gnu/llvm/lldb/unittests/gtest_common.h +++ b/gnu/llvm/lldb/unittests/gtest_common.h @@ -1,3 +1,7 @@ +#ifndef LLDB_UNITTESTS_GTEST_COMMON_H + +#define LLDB_UNITTESTS_GTEST_COMMON_H + //===-- gtest_common.h ------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -14,3 +18,5 @@ // This header file is force included by all of LLDB's unittest compilation // units. Be very leary about putting anything in this file. + +#endif diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/inferior/environment_check.cpp b/gnu/llvm/lldb/unittests/tools/lldb-server/inferior/environment_check.cpp index e5753eaa689..7d8063cc8c8 100644 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/inferior/environment_check.cpp +++ b/gnu/llvm/lldb/unittests/tools/lldb-server/inferior/environment_check.cpp @@ -1,4 +1,4 @@ -//===-- thread_inferior.cpp -------------------------------------*- C++ -*-===// +//===-- thread_inferior.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/inferior/thread_inferior.cpp b/gnu/llvm/lldb/unittests/tools/lldb-server/inferior/thread_inferior.cpp index 278b975dd91..43e9b8cbc10 100644 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/inferior/thread_inferior.cpp +++ b/gnu/llvm/lldb/unittests/tools/lldb-server/inferior/thread_inferior.cpp @@ -1,4 +1,4 @@ -//===-- thread_inferior.cpp -------------------------------------*- C++ -*-===// +//===-- thread_inferior.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/LLGSTest.cpp b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/LLGSTest.cpp index 1cd8e0d38b9..92efeffde7f 100644 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/LLGSTest.cpp +++ b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/LLGSTest.cpp @@ -1,4 +1,4 @@ -//===-- LLGSTest.cpp --------------------------------------------*- C++ -*-===// +//===-- LLGSTest.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp index e4f1a92f46a..3d1a153d289 100644 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp +++ b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp @@ -1,4 +1,4 @@ -//===-- MessageObjects.cpp --------------------------------------*- C++ -*-===// +//===-- MessageObjects.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -96,7 +96,8 @@ Expected JThreadsInfo::create(StringRef Response, ArrayRef RegInfos) { JThreadsInfo jthreads_info; - StructuredData::ObjectSP json = StructuredData::ParseJSON(Response); + StructuredData::ObjectSP json = + StructuredData::ParseJSON(std::string(Response)); StructuredData::Array *array = json->GetAsArray(); if (!array) return make_parsing_error("JThreadsInfo: JSON array"); diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/MessageObjects.h b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/MessageObjects.h index 2388f409d70..ff3f76ae3f0 100644 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/MessageObjects.h +++ b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/MessageObjects.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SERVER_TESTS_MESSAGEOBJECTS_H -#define LLDB_SERVER_TESTS_MESSAGEOBJECTS_H +#ifndef LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_MESSAGEOBJECTS_H +#define LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_MESSAGEOBJECTS_H #include "lldb/Host/Host.h" #include "lldb/Utility/RegisterValue.h" @@ -183,4 +183,4 @@ namespace lldb_private { std::ostream &operator<<(std::ostream &OS, const RegisterValue &RegVal); } -#endif // LLDB_SERVER_TESTS_MESSAGEOBJECTS_H +#endif // LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_MESSAGEOBJECTS_H diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestBase.cpp b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestBase.cpp index d14821af2ad..eeb73f05575 100644 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestBase.cpp +++ b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestBase.cpp @@ -1,4 +1,4 @@ -//===-- TestBase.cpp --------------------------------------------*- C++ -*-===// +//===-- TestBase.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -30,6 +30,6 @@ std::string TestBase::getLogFileName() { sys::path::append(DirStr, std::string("server-") + test_info->test_case_name() + "-" + test_info->name() + ".log"); - return DirStr.str(); + return std::string(DirStr.str()); } diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestBase.h b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestBase.h index bfccbd2c94f..6b0a9cdfd7c 100644 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestBase.h +++ b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestBase.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SERVER_TESTS_TESTBASE_H -#define LLDB_SERVER_TESTS_TESTBASE_H +#ifndef LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_TESTBASE_H +#define LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_TESTBASE_H #include "TestClient.h" #include "lldb/Host/FileSystem.h" @@ -36,7 +36,7 @@ public: static std::string getInferiorPath(llvm::StringRef Name) { llvm::SmallString<64> Path(LLDB_TEST_INFERIOR_PATH); llvm::sys::path::append(Path, Name + LLDB_TEST_INFERIOR_SUFFIX); - return Path.str(); + return std::string(Path.str()); } static std::string getLogFileName(); @@ -56,4 +56,4 @@ protected: } // namespace llgs_tests -#endif // LLDB_SERVER_TESTS_TESTBASE_H +#endif // LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_TESTBASE_H diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestClient.cpp b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestClient.cpp index 7e51a3879ab..52428e4afc8 100644 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestClient.cpp +++ b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestClient.cpp @@ -1,4 +1,4 @@ -//===-- TestClient.cpp ------------------------------------------*- C++ -*-===// +//===-- TestClient.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -30,7 +30,7 @@ using namespace llgs_tests; #endif TestClient::TestClient(std::unique_ptr Conn) { - SetConnection(Conn.release()); + SetConnection(std::move(Conn)); SetPacketTimeout(std::chrono::seconds(10)); } diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestClient.h b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestClient.h index 3016d370307..32a21a4411c 100644 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestClient.h +++ b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/TestClient.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SERVER_TESTS_TESTCLIENT_H -#define LLDB_SERVER_TESTS_TESTCLIENT_H +#ifndef LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_TESTCLIENT_H +#define LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_TESTCLIENT_H #include "MessageObjects.h" #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" @@ -109,4 +109,4 @@ TestClient::SendMessage(llvm::StringRef Message, CreateArgs &&... Args) { } // namespace llgs_tests -#endif // LLDB_SERVER_TESTS_TESTCLIENT_H +#endif // LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_TESTCLIENT_H diff --git a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp index acc7084193f..2306b434a6d 100644 --- a/gnu/llvm/lldb/unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp +++ b/gnu/llvm/lldb/unittests/tools/lldb-server/tests/ThreadIdsInJstopinfoTest.cpp @@ -1,4 +1,4 @@ -//===-- ThreadsInJstopinfoTest.cpp ------------------------------*- C++ -*-===// +//===-- ThreadsInJstopinfoTest.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/gnu/llvm/lldb/utils/CMakeLists.txt b/gnu/llvm/lldb/utils/CMakeLists.txt new file mode 100644 index 00000000000..00c81e655b7 --- /dev/null +++ b/gnu/llvm/lldb/utils/CMakeLists.txt @@ -0,0 +1,3 @@ +add_subdirectory(lit-cpuid) +add_subdirectory(lldb-dotest) +add_subdirectory(lldb-repro) diff --git a/gnu/llvm/lldb/utils/TableGen/LLDBOptionDefEmitter.cpp b/gnu/llvm/lldb/utils/TableGen/LLDBOptionDefEmitter.cpp index 6e73d0c53de..ccf48275f42 100644 --- a/gnu/llvm/lldb/utils/TableGen/LLDBOptionDefEmitter.cpp +++ b/gnu/llvm/lldb/utils/TableGen/LLDBOptionDefEmitter.cpp @@ -55,18 +55,18 @@ struct CommandOption { Required = Option->getValue("Required"); // Add the full and short name for this option. - FullName = Option->getValueAsString("FullName"); - ShortName = Option->getValueAsString("ShortName"); + FullName = std::string(Option->getValueAsString("FullName")); + ShortName = std::string(Option->getValueAsString("ShortName")); if (auto A = Option->getValue("ArgType")) ArgType = A->getValue()->getAsUnquotedString(); OptionalArg = Option->getValue("OptionalArg") != nullptr; if (Option->getValue("Validator")) - Validator = Option->getValueAsString("Validator"); + Validator = std::string(Option->getValueAsString("Validator")); if (Option->getValue("ArgEnum")) - ArgEnum = Option->getValueAsString("ArgEnum"); + ArgEnum = std::string(Option->getValueAsString("ArgEnum")); if (Option->getValue("Completions")) Completions = Option->getValueAsListOfStrings("Completions"); diff --git a/gnu/llvm/lldb/utils/TableGen/LLDBPropertyDefEmitter.cpp b/gnu/llvm/lldb/utils/TableGen/LLDBPropertyDefEmitter.cpp index f36deeebf90..e3522f2c7b2 100644 --- a/gnu/llvm/lldb/utils/TableGen/LLDBPropertyDefEmitter.cpp +++ b/gnu/llvm/lldb/utils/TableGen/LLDBPropertyDefEmitter.cpp @@ -35,8 +35,9 @@ static void emitProperty(Record *Property, raw_ostream &OS) { OS << ", "; // Emit the property type. + llvm::StringRef type = Property->getValueAsString("Type"); OS << "OptionValue::eType"; - OS << Property->getValueAsString("Type"); + OS << type; OS << ", "; // Emit the property's global value. @@ -46,11 +47,12 @@ static void emitProperty(Record *Property, raw_ostream &OS) { bool hasDefaultUnsignedValue = Property->getValue("HasDefaultUnsignedValue"); bool hasDefaultEnumValue = Property->getValue("HasDefaultEnumValue"); bool hasDefaultStringValue = Property->getValue("HasDefaultStringValue"); + bool hasElementType = Property->getValue("HasElementType"); // Guarantee that every property has a default value. assert((hasDefaultUnsignedValue || hasDefaultEnumValue || - hasDefaultStringValue) && - "Property must have a default value"); + hasDefaultStringValue || hasElementType) && + "Property must have a default value or an element type"); // Guarantee that no property has both a default unsigned value and a default // enum value, since they're bothed stored in the same field. @@ -72,11 +74,18 @@ static void emitProperty(Record *Property, raw_ostream &OS) { !(Property->getValueAsString("Type") == "Enum" && !hasDefaultEnumValue) && "Enum property must have a enum default value."); + // Guarantee that only arrays and dictionaries have an element type; + assert(((type != "Array" && type != "Dictionary") || hasElementType) && + "Only dictionaries and arrays can have an element type."); + // Emit the default uint value. if (hasDefaultUnsignedValue) { OS << std::to_string(Property->getValueAsInt("DefaultUnsignedValue")); } else if (hasDefaultEnumValue) { OS << Property->getValueAsString("DefaultEnumValue"); + } else if (hasElementType) { + OS << "OptionValue::eType"; + OS << Property->getValueAsString("ElementType"); } else { OS << "0"; } diff --git a/gnu/llvm/lldb/utils/TableGen/LLDBTableGenBackends.h b/gnu/llvm/lldb/utils/TableGen/LLDBTableGenBackends.h index b424abfce9a..88ae0888c22 100644 --- a/gnu/llvm/lldb/utils/TableGen/LLDBTableGenBackends.h +++ b/gnu/llvm/lldb/utils/TableGen/LLDBTableGenBackends.h @@ -13,8 +13,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LLDB_UTILS_TABLEGEN_TABLEGENBACKENDS_H -#define LLVM_LLDB_UTILS_TABLEGEN_TABLEGENBACKENDS_H +#ifndef LLDB_UTILS_TABLEGEN_LLDBTABLEGENBACKENDS_H +#define LLDB_UTILS_TABLEGEN_LLDBTABLEGENBACKENDS_H #include "llvm/ADT/StringRef.h" diff --git a/gnu/llvm/lldb/utils/TableGen/LLDBTableGenUtils.h b/gnu/llvm/lldb/utils/TableGen/LLDBTableGenUtils.h index 5553cecafb1..76f0df9a23f 100644 --- a/gnu/llvm/lldb/utils/TableGen/LLDBTableGenUtils.h +++ b/gnu/llvm/lldb/utils/TableGen/LLDBTableGenUtils.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LLDB_UTILS_TABLEGEN_TABLEGENUTILS_H -#define LLVM_LLDB_UTILS_TABLEGEN_TABLEGENUTILS_H +#ifndef LLDB_UTILS_TABLEGEN_LLDBTABLEGENUTILS_H +#define LLDB_UTILS_TABLEGEN_LLDBTABLEGENUTILS_H #include "llvm/ADT/StringRef.h" #include diff --git a/gnu/llvm/lldb/utils/lldb-dotest/CMakeLists.txt b/gnu/llvm/lldb/utils/lldb-dotest/CMakeLists.txt index 4f1bd7304ab..0ef60c14276 100644 --- a/gnu/llvm/lldb/utils/lldb-dotest/CMakeLists.txt +++ b/gnu/llvm/lldb/utils/lldb-dotest/CMakeLists.txt @@ -4,6 +4,11 @@ add_dependencies(lldb-dotest lldb-test-deps) set_target_properties(lldb-dotest PROPERTIES FOLDER "lldb utils") get_property(LLDB_DOTEST_ARGS GLOBAL PROPERTY LLDB_DOTEST_ARGS_PROPERTY) +set(LLDB_LIBS_DIR "${LLVM_LIBRARY_OUTPUT_INTDIR}") + +llvm_canonicalize_cmake_booleans( + LLDB_BUILD_INTEL_PT +) # Generate lldb-dotest Python driver script for each build mode. if(LLDB_BUILT_STANDALONE) @@ -14,15 +19,38 @@ if(LLDB_BUILT_STANDALONE) foreach(config_type ${config_types}) # In paths to our build-tree, replace CMAKE_CFG_INTDIR with our actual configuration names. string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} config_runtime_output_dir ${LLVM_RUNTIME_OUTPUT_INTDIR}) - string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_DOTEST_ARGS "${LLDB_DOTEST_ARGS}") + string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_DOTEST_ARGS_CONFIGURED "${LLDB_DOTEST_ARGS}") + string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_SOURCE_DIR_CONFIGURED "${LLDB_SOURCE_DIR}") + string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_BUILD_DIRECTORY_CONFIGURED "${LLDB_TEST_BUILD_DIRECTORY}") + string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_EXECUTABLE_CONFIGURED "${LLDB_TEST_EXECUTABLE}") + string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_COMPILER_CONFIGURED "${LLDB_TEST_COMPILER}") + string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_DSYMUTIL_CONFIGURED "${LLDB_TEST_DSYMUTIL}") + string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_FILECHECK_CONFIGURED "${LLDB_TEST_FILECHECK}") + string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_YAML2OBJ_CONFIGURED "${LLDB_TEST_YAML2OBJ}") # Remaining ones must be paths to the provided LLVM build-tree. if(${config_type} IN_LIST LLVM_CONFIGURATION_TYPES) # Multi-configuration generator like Xcode (with a matching config). - string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_DOTEST_ARGS "${LLDB_DOTEST_ARGS}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_DOTEST_ARGS_CONFIGURED "${LLDB_DOTEST_ARGS}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_SOURCE_DIR_CONFIGURED "${LLDB_SOURCE_DIR}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_TEST_BUILD_DIRECTORY_CONFIGURED "${LLDB_TEST_BUILD_DIRECTORY}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_TEST_EXECUTABLE_CONFIGURED "${LLDB_TEST_EXECUTABLE}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_TEST_COMPILER_CONFIGURED "${LLDB_TEST_COMPILER}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_TEST_DSYMUTIL_CONFIGURED "${LLDB_TEST_DSYMUTIL}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_TEST_FILECHECK_CONFIGURED "${LLDB_TEST_FILECHECK}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_TEST_YAML2OBJ_CONFIGURED "${LLDB_TEST_YAML2OBJ}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_LIBS_DIR_CONFIGURED "${LLDB_LIBS_DIR}") else() # Single-configuration generator like Ninja. - string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_DOTEST_ARGS "${LLDB_DOTEST_ARGS}") + string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_DOTEST_ARGS_CONFIGURED "${LLDB_DOTEST_ARGS}") + string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_SOURCE_DIR_CONFIGURED "${LLDB_SOURCE_DIR}") + string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_BUILD_DIRECTORY_CONFIGURED "${LLDB_TEST_BUILD_DIRECTORY}") + string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_EXECUTABLE_CONFIGURED "${LLDB_TEST_EXECUTABLE}") + string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_COMPILER_CONFIGURED "${LLDB_TEST_COMPILER}") + string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_DSYMUTIL_CONFIGURED "${LLDB_TEST_DSYMUTIL}") + string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_FILECHECK_CONFIGURED "${LLDB_TEST_FILECHECK}") + string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_YAML2OBJ_CONFIGURED "${LLDB_TEST_YAML2OBJ_CONFIGURED}") + string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_LIBS_DIR_CONFIGURED "${LLDB_LIBS_DIR}") endif() configure_file( @@ -33,13 +61,32 @@ if(LLDB_BUILT_STANDALONE) elseif(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") foreach(LLVM_BUILD_MODE ${CMAKE_CONFIGURATION_TYPES}) string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_DOTEST_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR}) - string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_DOTEST_ARGS "${LLDB_DOTEST_ARGS}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_DOTEST_ARGS_CONFIGURED "${LLDB_DOTEST_ARGS}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_SOURCE_DIR_CONFIGURED "${LLDB_SOURCE_DIR}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_BUILD_DIRECTORY_CONFIGURED "${LLDB_TEST_BUILD_DIRECTORY}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_EXECUTABLE_CONFIGURED "${LLDB_TEST_EXECUTABLE}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_COMPILER_CONFIGURED "${LLDB_TEST_COMPILER}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_DSYMUTIL_CONFIGURED "${LLDB_TEST_DSYMUTIL}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_FILECHECK_CONFIGURED "${LLDB_TEST_FILECHECK}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_YAML2OBJ_CONFIGURED "${LLDB_TEST_YAML2OBJ}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_LIBS_DIR_CONFIGURED "${LLDB_LIBS_DIR}") + configure_file( lldb-dotest.in ${LLDB_DOTEST_DIR}/lldb-dotest ) endforeach() else() + set(LLDB_DOTEST_ARGS_CONFIGURED "${LLDB_DOTEST_ARGS}") + set(LLDB_SOURCE_DIR_CONFIGURED "${LLDB_SOURCE_DIR}") + set(LLDB_TEST_BUILD_DIRECTORY_CONFIGURED "${LLDB_TEST_BUILD_DIRECTORY}") + set(LLDB_TEST_EXECUTABLE_CONFIGURED "${LLDB_TEST_EXECUTABLE}") + set(LLDB_TEST_COMPILER_CONFIGURED "${LLDB_TEST_COMPILER}") + set(LLDB_TEST_DSYMUTIL_CONFIGURED "${LLDB_TEST_DSYMUTIL}") + set(LLDB_TEST_FILECHECK_CONFIGURED "${LLDB_TEST_FILECHECK}") + set(LLDB_TEST_YAML2OBJ_CONFIGURED "${LLDB_TEST_YAML2OBJ}") + set(LLDB_LIBS_DIR_CONFIGURED "${LLDB_LIBS_DIR}") + configure_file( lldb-dotest.in ${LLVM_RUNTIME_OUTPUT_INTDIR}/lldb-dotest diff --git a/gnu/llvm/lldb/utils/lldb-dotest/lldb-dotest.in b/gnu/llvm/lldb/utils/lldb-dotest/lldb-dotest.in index bab3f8baa98..ee0ea6dff74 100755 --- a/gnu/llvm/lldb/utils/lldb-dotest/lldb-dotest.in +++ b/gnu/llvm/lldb/utils/lldb-dotest/lldb-dotest.in @@ -1,15 +1,18 @@ -#!/usr/bin/env python +#!@PYTHON_EXECUTABLE@ import subprocess import sys -dotest_path = '@LLDB_SOURCE_DIR@/test/API/dotest.py' -build_dir = '@LLDB_TEST_BUILD_DIRECTORY@' -dotest_args_str = '@LLDB_DOTEST_ARGS@' +dotest_path = '@LLDB_SOURCE_DIR_CONFIGURED@/test/API/dotest.py' +build_dir = '@LLDB_TEST_BUILD_DIRECTORY_CONFIGURED@' +dotest_args_str = '@LLDB_DOTEST_ARGS_CONFIGURED@' arch = '@LLDB_TEST_ARCH@' -executable = '@LLDB_TEST_EXECUTABLE@' -compiler = '@LLDB_TEST_COMPILER@' -dsymutil = '@LLDB_TEST_DSYMUTIL@' -filecheck = '@LLDB_TEST_FILECHECK@' +executable = '@LLDB_TEST_EXECUTABLE_CONFIGURED@' +compiler = '@LLDB_TEST_COMPILER_CONFIGURED@' +dsymutil = '@LLDB_TEST_DSYMUTIL_CONFIGURED@' +filecheck = '@LLDB_TEST_FILECHECK_CONFIGURED@' +yaml2obj = '@LLDB_TEST_YAML2OBJ_CONFIGURED@' +lldb_libs_dir = "@LLDB_LIBS_DIR_CONFIGURED@" +lldb_build_intel_pt = "@LLDB_BUILD_INTEL_PT@" if __name__ == '__main__': wrapper_args = sys.argv[1:] @@ -22,7 +25,11 @@ if __name__ == '__main__': cmd.extend(['--executable', executable]) cmd.extend(['--compiler', compiler]) cmd.extend(['--dsymutil', dsymutil]) + cmd.extend(['--yaml2obj', yaml2obj]) cmd.extend(['--filecheck', filecheck]) + cmd.extend(['--lldb-libs-dir', lldb_libs_dir]) + if lldb_build_intel_pt == "1": + cmd.extend(['--enable-plugin', 'intel-pt']) cmd.extend(wrapper_args) # Invoke dotest.py and return exit code. print(' '.join(cmd)) diff --git a/gnu/llvm/lldb/utils/lldb-repro/CMakeLists.txt b/gnu/llvm/lldb/utils/lldb-repro/CMakeLists.txt new file mode 100644 index 00000000000..a496e998619 --- /dev/null +++ b/gnu/llvm/lldb/utils/lldb-repro/CMakeLists.txt @@ -0,0 +1,23 @@ +add_custom_target(lldb-repro) +add_dependencies(lldb-repro lldb-test-deps) +set_target_properties(lldb-repro PROPERTIES FOLDER "lldb utils") + +# Generate lldb-repro Python script for each build mode. +if(LLDB_BUILT_STANDALONE) + set(config_types ".") + if(CMAKE_CONFIGURATION_TYPES) + set(config_types ${CMAKE_CONFIGURATION_TYPES}) + endif() + + foreach(config_type ${config_types}) + string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} config_runtime_output_dir ${LLVM_RUNTIME_OUTPUT_INTDIR}) + configure_file(lldb-repro.py ${config_runtime_output_dir}/lldb-repro COPYONLY) + endforeach() +elseif(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") + foreach(LLVM_BUILD_MODE ${CMAKE_CONFIGURATION_TYPES}) + string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_REPRO_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR}) + configure_file(lldb-repro.py ${LLDB_REPRO_DIR}/lldb-repro COPYONLY) + endforeach() +else() + configure_file(lldb-repro.py ${LLVM_RUNTIME_OUTPUT_INTDIR}/lldb-repro COPYONLY) +endif() diff --git a/gnu/llvm/lldb/utils/lldb-repro/lldb-repro.py b/gnu/llvm/lldb/utils/lldb-repro/lldb-repro.py new file mode 100755 index 00000000000..2b7b23f8cf2 --- /dev/null +++ b/gnu/llvm/lldb/utils/lldb-repro/lldb-repro.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +"""lldb-repro + +lldb-repro is a utility to transparently capture and replay debugger sessions +through the command line driver. Its used to test the reproducers by running +the test suite twice. + +During the first run, with 'capture' as its first argument, it captures a +reproducer for every lldb invocation and saves it to a well-know location +derived from the arguments and current working directory. + +During the second run, with 'replay' as its first argument, the test suite is +run again but this time every invocation of lldb replays the previously +recorded session. +""" + +import hashlib +import os +import shutil +import subprocess +import sys +import tempfile + + +def help(): + print("usage: {} capture|replay [args]".format(sys.argv[0])) + + +def main(): + if len(sys.argv) < 2: + help() + return 1 + + # Compute an MD5 hash based on the input arguments and the current working + # directory. + h = hashlib.md5() + h.update(' '.join(sys.argv[2:]).encode('utf-8')) + h.update(os.getcwd().encode('utf-8')) + input_hash = h.hexdigest() + + # Use the hash to "uniquely" identify a reproducer path. + reproducer_path = os.path.join(tempfile.gettempdir(), input_hash) + + # Create a new lldb invocation with capture or replay enabled. + lldb = os.path.join(os.path.dirname(sys.argv[0]), 'lldb') + new_args = [lldb] + if sys.argv[1] == "replay": + new_args.extend(['--replay', reproducer_path]) + elif sys.argv[1] == "capture": + new_args.extend([ + '--capture', '--capture-path', reproducer_path, + '--reproducer-generate-on-exit' + ]) + new_args.extend(sys.argv[2:]) + else: + help() + return 1 + + exit_code = subprocess.call(new_args) + + # The driver always exists with a zero exit code during replay. Store the + # exit code and return that for tests that expect a non-zero exit code. + exit_code_path = os.path.join(reproducer_path, 'exit_code.txt') + if sys.argv[1] == "replay": + with open(exit_code_path, 'r') as f: + assert exit_code == 0 + exit_code = int(f.read()) + shutil.rmtree(reproducer_path, True) + elif sys.argv[1] == "capture": + with open(exit_code_path, 'w') as f: + f.write('%d' % exit_code) + + return exit_code + + +if __name__ == '__main__': + exit(main())