summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authormortimer <mortimer@cvs.openbsd.org>2019-11-09 16:45:49 +0000
committermortimer <mortimer@cvs.openbsd.org>2019-11-09 16:45:49 +0000
commit6e03bb45be5d11fe00839093ae0c76a05df73f97 (patch)
tree38e689c5b36d446a72b9feb819ceb31b076b56e8 /gnu
parent9a7461dfc4b75ee86810e2cebc8d87ea1c039d9f (diff)
Add lldb support for debugging running binaries on amd64.
Follows a similar model as NetBSD. Much help from patrick, kettenis and guenther. lldb and lldb-server remain not installed by default. ok patrick@
Diffstat (limited to 'gnu')
-rw-r--r--gnu/llvm/tools/lldb/include/lldb/Utility/ArchSpec.h156
-rw-r--r--gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/api/multithreaded/common.h2
-rw-r--r--gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/tools/lldb-server/thread-name/main.cpp2
-rw-r--r--gnu/llvm/tools/lldb/source/Core/FormatEntity.cpp182
-rw-r--r--gnu/llvm/tools/lldb/source/Host/common/SocketAddress.cpp8
-rw-r--r--gnu/llvm/tools/lldb/source/Host/openbsd/Host.cpp130
-rw-r--r--gnu/llvm/tools/lldb/source/Host/posix/DomainSocket.cpp2
-rw-r--r--gnu/llvm/tools/lldb/source/Host/posix/PipePosix.cpp25
-rw-r--r--gnu/llvm/tools/lldb/source/Initialization/CMakeLists.txt8
-rw-r--r--gnu/llvm/tools/lldb/source/Initialization/SystemInitializerCommon.cpp44
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp54
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp219
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp165
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h9
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/Process/CMakeLists.txt5
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/CMakeLists.txt17
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp576
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.h123
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD.cpp86
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD.h63
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_x86_64.cpp861
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_x86_64.h92
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeThreadOpenBSD.cpp206
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeThreadOpenBSD.h81
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp131
-rw-r--r--gnu/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp465
-rw-r--r--gnu/llvm/tools/lldb/source/Utility/ArchSpec.cpp147
-rw-r--r--gnu/llvm/tools/lldb/tools/lldb-server/CMakeLists.txt60
-rw-r--r--gnu/llvm/tools/lldb/tools/lldb-server/lldb-gdbserver.cpp127
-rw-r--r--gnu/usr.bin/clang/Makefile3
-rw-r--r--gnu/usr.bin/clang/liblldbPluginProcess/Makefile14
-rw-r--r--gnu/usr.bin/clang/lldb-server/Makefile81
32 files changed, 3239 insertions, 905 deletions
diff --git a/gnu/llvm/tools/lldb/include/lldb/Utility/ArchSpec.h b/gnu/llvm/tools/lldb/include/lldb/Utility/ArchSpec.h
index 50f69606e3d..d2d3812b93e 100644
--- a/gnu/llvm/tools/lldb/include/lldb/Utility/ArchSpec.h
+++ b/gnu/llvm/tools/lldb/include/lldb/Utility/ArchSpec.h
@@ -10,26 +10,27 @@
#ifndef LLDB_UTILITY_ARCHSPEC_H
#define LLDB_UTILITY_ARCHSPEC_H
+#include "lldb/Utility/CompletionRequest.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private-enumerations.h"
-#include "llvm/ADT/StringRef.h" // for StringRef
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
-#include <cstddef> // for size_t
-#include <cstdint> // for uint32_t
-#include <string> // for string
+#include <cstddef>
+#include <cstdint>
+#include <string>
namespace lldb_private {
//----------------------------------------------------------------------
-/// @class ArchSpec ArchSpec.h "lldb/Utility/ArchSpec.h"
-/// @brief An architecture specification class.
+/// @class ArchSpec ArchSpec.h "lldb/Utility/ArchSpec.h" An architecture
+/// specification class.
///
/// A class designed to be created from a cpu type and subtype, a
-/// string representation, or an llvm::Triple. Keeping all of the
-/// conversions of strings to architecture enumeration values confined
-/// to this class allows new architecture support to be added easily.
+/// string representation, or an llvm::Triple. Keeping all of the conversions
+/// of strings to architecture enumeration values confined to this class
+/// allows new architecture support to be added easily.
//----------------------------------------------------------------------
class ArchSpec {
public:
@@ -178,6 +179,7 @@ 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,
@@ -245,16 +247,15 @@ public:
//------------------------------------------------------------------
/// Default constructor.
///
- /// Default constructor that initializes the object with invalid
- /// cpu type and subtype values.
+ /// Default constructor that initializes the object with invalid cpu type
+ /// and subtype values.
//------------------------------------------------------------------
ArchSpec();
//------------------------------------------------------------------
/// Constructor over triple.
///
- /// Constructs an ArchSpec with properties consistent with the given
- /// Triple.
+ /// Constructs an ArchSpec with properties consistent with the given Triple.
//------------------------------------------------------------------
explicit ArchSpec(const llvm::Triple &triple);
explicit ArchSpec(const char *triple_cstr);
@@ -262,8 +263,8 @@ public:
//------------------------------------------------------------------
/// Constructor over architecture name.
///
- /// Constructs an ArchSpec with properties consistent with the given
- /// object type and architecture name.
+ /// Constructs an ArchSpec with properties consistent with the given object
+ /// type and architecture name.
//------------------------------------------------------------------
explicit ArchSpec(ArchitectureType arch_type, uint32_t cpu_type,
uint32_t cpu_subtype);
@@ -284,16 +285,18 @@ public:
//---------------------------------------------------------------------------
/// Returns true if the OS, vendor and environment fields of the triple are
- /// unset. The triple is expected to be normalized (llvm::Triple::normalize).
+ /// unset. The triple is expected to be normalized
+ /// (llvm::Triple::normalize).
//---------------------------------------------------------------------------
static bool ContainsOnlyArch(const llvm::Triple &normalized_triple);
- static size_t AutoComplete(llvm::StringRef name, StringList &matches);
+ static void ListSupportedArchNames(StringList &list);
+ static size_t AutoComplete(CompletionRequest &request);
//------------------------------------------------------------------
/// Returns a static string representing the current architecture.
///
- /// @return A static string correcponding to the current
+ /// @return A static string corresponding to the current
/// architecture.
//------------------------------------------------------------------
const char *GetArchitectureName() const;
@@ -306,8 +309,8 @@ public:
bool IsMIPS() const;
//------------------------------------------------------------------
- /// Returns a string representing current architecture as a target CPU
- /// for tools like compiler, disassembler etc.
+ /// Returns a string representing current architecture as a target CPU for
+ /// tools like compiler, disassembler etc.
///
/// @return A string representing target CPU for the current
/// architecture.
@@ -329,8 +332,7 @@ public:
void Clear();
//------------------------------------------------------------------
- /// Returns the size in bytes of an address of the current
- /// architecture.
+ /// Returns the size in bytes of an address of the current architecture.
///
/// @return The byte size of an address of the current architecture.
//------------------------------------------------------------------
@@ -356,9 +358,8 @@ public:
//------------------------------------------------------------------
/// Set the distribution id of the architecture.
///
- /// This will be something like "ubuntu", "fedora", etc. on Linux.
- /// This should be the same value returned by
- /// HostInfo::GetDistributionId ().
+ /// This will be something like "ubuntu", "fedora", etc. on Linux. This
+ /// should be the same value returned by HostInfo::GetDistributionId ().
///------------------------------------------------------------------
void SetDistributionId(const char *distribution_id);
@@ -371,6 +372,7 @@ public:
bool IsValid() const {
return m_core >= eCore_arm_generic && m_core < kNumCores;
}
+ explicit operator bool() const { return IsValid(); }
bool TripleVendorWasSpecified() const {
return !m_triple.getVendorName().empty();
@@ -395,13 +397,12 @@ public:
//------------------------------------------------------------------
/// Merges fields from another ArchSpec into this ArchSpec.
///
- /// This will use the supplied ArchSpec to fill in any fields of
- /// the triple in this ArchSpec which were unspecified. This can
- /// be used to refine a generic ArchSpec with a more specific one.
- /// For example, if this ArchSpec's triple is something like
- /// i386-unknown-unknown-unknown, and we have a triple which is
- /// x64-pc-windows-msvc, then merging that triple into this one
- /// will result in the triple i386-pc-windows-msvc.
+ /// This will use the supplied ArchSpec to fill in any fields of the triple
+ /// in this ArchSpec which were unspecified. This can be used to refine a
+ /// generic ArchSpec with a more specific one. For example, if this
+ /// ArchSpec's triple is something like i386-unknown-unknown-unknown, and we
+ /// have a triple which is x64-pc-windows-msvc, then merging that triple
+ /// into this one will result in the triple i386-pc-windows-msvc.
///
//------------------------------------------------------------------
void MergeFrom(const ArchSpec &other);
@@ -421,16 +422,16 @@ public:
///
/// @return True if the object, and CPU were successfully set.
///
- /// As a side effect, the vendor value is usually set to unknown.
- /// The exections are
+ /// As a side effect, the vendor value is usually set to unknown. The
+ /// exceptions are
/// aarch64-apple-ios
/// arm-apple-ios
/// thumb-apple-ios
/// x86-apple-
/// x86_64-apple-
///
- /// As a side effect, the os value is usually set to unknown
- /// The exceptions are
+ /// As a side effect, the os value is usually set to unknown The exceptions
+ /// are
/// *-*-aix
/// aarch64-apple-ios
/// arm-apple-ios
@@ -456,10 +457,10 @@ public:
//------------------------------------------------------------------
/// Sets this ArchSpec's byte order.
///
- /// In the common case there is no need to call this method as the
- /// byte order can almost always be determined by the architecture.
- /// However, many CPU's are bi-endian (ARM, Alpha, PowerPC, etc)
- /// and the default/assumed byte order may be incorrect.
+ /// In the common case there is no need to call this method as the byte
+ /// order can almost always be determined by the architecture. However, many
+ /// CPU's are bi-endian (ARM, Alpha, PowerPC, etc) and the default/assumed
+ /// byte order may be incorrect.
//------------------------------------------------------------------
void SetByteOrder(lldb::ByteOrder byte_order) { m_byte_order = byte_order; }
@@ -476,28 +477,28 @@ public:
//------------------------------------------------------------------
/// Architecture data byte width accessor
///
- /// @return the size in 8-bit (host) bytes of a minimum addressable
- /// unit from the Architecture's data bus
+ /// @return the size in 8-bit (host) bytes of a minimum addressable unit
+ /// from the Architecture's data bus
//------------------------------------------------------------------
uint32_t GetDataByteSize() const;
//------------------------------------------------------------------
/// Architecture code byte width accessor
///
- /// @return the size in 8-bit (host) bytes of a minimum addressable
- /// unit from the Architecture's code bus
+ /// @return the size in 8-bit (host) bytes of a minimum addressable unit
+ /// from the Architecture's code bus
//------------------------------------------------------------------
uint32_t GetCodeByteSize() const;
//------------------------------------------------------------------
- /// Architecture tripple accessor.
+ /// Architecture triple accessor.
///
/// @return A triple describing this ArchSpec.
//------------------------------------------------------------------
llvm::Triple &GetTriple() { return m_triple; }
//------------------------------------------------------------------
- /// Architecture tripple accessor.
+ /// Architecture triple accessor.
///
/// @return A triple describing this ArchSpec.
//------------------------------------------------------------------
@@ -506,14 +507,14 @@ public:
void DumpTriple(Stream &s) const;
//------------------------------------------------------------------
- /// Architecture tripple setter.
+ /// Architecture triple setter.
///
- /// Configures this ArchSpec according to the given triple. If the
- /// triple has unknown components in all of the vendor, OS, and
- /// the optional environment field (i.e. "i386-unknown-unknown")
- /// then default values are taken from the host. Architecture and
- /// environment components are used to further resolve the CPU type
- /// and subtype, endian characteristics, etc.
+ /// Configures this ArchSpec according to the given triple. If the triple
+ /// has unknown components in all of the vendor, OS, and the optional
+ /// environment field (i.e. "i386-unknown-unknown") then default values are
+ /// taken from the host. Architecture and environment components are used
+ /// to further resolve the CPU type and subtype, endian characteristics,
+ /// etc.
///
/// @return A triple describing this ArchSpec.
//------------------------------------------------------------------
@@ -530,8 +531,8 @@ public:
lldb::ByteOrder GetDefaultEndian() const;
//------------------------------------------------------------------
- /// Returns true if 'char' is a signed type by defualt in the
- /// architecture false otherwise
+ /// Returns true if 'char' is a signed type by default in the architecture
+ /// false otherwise
///
/// @return True if 'char' is a signed type by default on the
/// architecture and false otherwise.
@@ -539,18 +540,18 @@ public:
bool CharIsSignedByDefault() const;
//------------------------------------------------------------------
- /// Compare an ArchSpec to another ArchSpec, requiring an exact cpu
- /// type match between them.
- /// e.g. armv7s is not an exact match with armv7 - this would return false
+ /// Compare an ArchSpec to another ArchSpec, requiring an exact cpu type
+ /// match between them. e.g. armv7s is not an exact match with armv7 - this
+ /// would return false
///
/// @return true if the two ArchSpecs match.
//------------------------------------------------------------------
bool IsExactMatch(const ArchSpec &rhs) const;
//------------------------------------------------------------------
- /// Compare an ArchSpec to another ArchSpec, requiring a compatible
- /// cpu type match between them.
- /// e.g. armv7s is compatible with armv7 - this method would return true
+ /// Compare an ArchSpec to another ArchSpec, requiring a compatible cpu type
+ /// match between them. e.g. armv7s is compatible with armv7 - this method
+ /// would return true
///
/// @return true if the two ArchSpecs are compatible
//------------------------------------------------------------------
@@ -566,12 +567,12 @@ public:
//------------------------------------------------------------------
/// Detect whether this architecture uses thumb code exclusively
///
- /// Some embedded ARM chips (e.g. the ARM Cortex M0-7 line) can
- /// only execute the Thumb instructions, never Arm. We should normally
- /// pick up arm/thumbness from their the processor status bits (cpsr/xpsr)
- /// or hints on each function - but when doing bare-boards low level
- /// debugging (especially common with these embedded processors), we may
- /// not have those things easily accessible.
+ /// Some embedded ARM chips (e.g. the ARM Cortex M0-7 line) can only execute
+ /// the Thumb instructions, never Arm. We should normally pick up
+ /// arm/thumbness from their the processor status bits (cpsr/xpsr) or hints
+ /// on each function - but when doing bare-boards low level debugging
+ /// (especially common with these embedded processors), we may not have
+ /// those things easily accessible.
///
/// @return true if this is an arm ArchSpec which can only execute Thumb
/// instructions
@@ -592,31 +593,30 @@ protected:
Core m_core = kCore_invalid;
lldb::ByteOrder m_byte_order = lldb::eByteOrderInvalid;
- // Additional arch flags which we cannot get from triple and core
- // For MIPS these are application specific extensions like
- // micromips, mips16 etc.
+ // Additional arch flags which we cannot get from triple and core For MIPS
+ // these are application specific extensions like micromips, mips16 etc.
uint32_t m_flags = 0;
ConstString m_distribution_id;
- // Called when m_def or m_entry are changed. Fills in all remaining
- // members with default values.
+ // Called when m_def or m_entry are changed. Fills in all remaining members
+ // with default values.
void CoreUpdated(bool update_triple);
};
//------------------------------------------------------------------
-/// @fn bool operator< (const ArchSpec& lhs, const ArchSpec& rhs)
-/// @brief Less than operator.
+/// @fn bool operator< (const ArchSpec& lhs, const ArchSpec& rhs) Less than
+/// operator.
///
-/// Tests two ArchSpec objects to see if \a lhs is less than \a
-/// rhs.
+/// Tests two ArchSpec objects to see if \a lhs is less than \a rhs.
///
-/// @param[in] lhs The Left Hand Side ArchSpec object to compare.
-/// @param[in] rhs The Left Hand Side ArchSpec object to compare.
+/// @param[in] lhs The Left Hand Side ArchSpec object to compare. @param[in]
+/// rhs The Left Hand Side ArchSpec object to compare.
///
/// @return true if \a lhs is less than \a rhs
//------------------------------------------------------------------
bool operator<(const ArchSpec &lhs, const ArchSpec &rhs);
+bool operator==(const ArchSpec &lhs, const ArchSpec &rhs);
bool ParseMachCPUDashSubtypeTriple(llvm::StringRef triple_str, ArchSpec &arch);
diff --git a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/api/multithreaded/common.h b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/api/multithreaded/common.h
index dad8bba07a3..bd40bdd421a 100644
--- a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/api/multithreaded/common.h
+++ b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/api/multithreaded/common.h
@@ -58,7 +58,7 @@ public:
/// Allocates a char buffer with the current working directory
inline char* get_working_dir() {
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
return getwd(0);
#else
return get_current_dir_name();
diff --git a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/tools/lldb-server/thread-name/main.cpp b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/tools/lldb-server/thread-name/main.cpp
index 0403031143b..c01b7f7007b 100644
--- a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/tools/lldb-server/thread-name/main.cpp
+++ b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/tools/lldb-server/thread-name/main.cpp
@@ -6,6 +6,8 @@ void set_thread_name(const char *name) {
::pthread_setname_np(name);
#elif defined(__FreeBSD__)
::pthread_set_name_np(::pthread_self(), name);
+#elif defined(__OpenBSD__)
+ ::pthread_set_name_np(::pthread_self(), name);
#elif defined(__linux__)
::pthread_setname_np(::pthread_self(), name);
#elif defined(__NetBSD__)
diff --git a/gnu/llvm/tools/lldb/source/Core/FormatEntity.cpp b/gnu/llvm/tools/lldb/source/Core/FormatEntity.cpp
index 6002efe9244..c8c2f4c849e 100644
--- a/gnu/llvm/tools/lldb/source/Core/FormatEntity.cpp
+++ b/gnu/llvm/tools/lldb/source/Core/FormatEntity.cpp
@@ -10,29 +10,28 @@
#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/AddressRange.h" // for AddressRange
-#include "lldb/Core/ArchSpec.h" // for ArchSpec
+#include "lldb/Core/AddressRange.h"
#include "lldb/Core/Debugger.h"
+#include "lldb/Core/DumpRegisterValue.h"
#include "lldb/Core/Module.h"
-#include "lldb/Core/RegisterValue.h" // for RegisterValue
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/DataFormatters/DataVisualization.h"
-#include "lldb/DataFormatters/FormatClasses.h" // for TypeNameSpecifier...
+#include "lldb/DataFormatters/FormatClasses.h"
#include "lldb/DataFormatters/FormatManager.h"
-#include "lldb/DataFormatters/TypeSummary.h" // for TypeSummaryImpl::...
+#include "lldb/DataFormatters/TypeSummary.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/CompileUnit.h"
-#include "lldb/Symbol/CompilerType.h" // for CompilerType
+#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/LineEntry.h"
#include "lldb/Symbol/Symbol.h"
-#include "lldb/Symbol/SymbolContext.h" // for SymbolContext
+#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
-#include "lldb/Target/ExecutionContextScope.h" // for ExecutionContextS...
+#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -42,30 +41,32 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/AnsiTerminal.h"
-#include "lldb/Utility/ConstString.h" // for ConstString, oper...
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h" // for Log
-#include "lldb/Utility/Logging.h" // for GetLogIfAllCatego...
-#include "lldb/Utility/SharingPtr.h" // for SharingPtr
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Logging.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/SharingPtr.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
-#include "lldb/Utility/StringList.h" // for StringList
-#include "lldb/Utility/StructuredData.h" // for StructuredData::O...
-#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS
-#include "lldb/lldb-forward.h" // for ValueObjectSP
+#include "lldb/Utility/StringList.h"
+#include "lldb/Utility/StructuredData.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-forward.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h" // for Triple, Triple::O...
-#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH
-
-#include <ctype.h> // for isxdigit
-#include <inttypes.h> // for PRIu64, PRIx64
-#include <memory> // for shared_ptr, opera...
-#include <stdio.h> // for sprintf
-#include <stdlib.h> // for strtoul
-#include <string.h> // for size_t, strchr
-#include <type_traits> // for move
-#include <utility> // for pair
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Compiler.h"
+
+#include <ctype.h>
+#include <inttypes.h>
+#include <memory>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <type_traits>
+#include <utility>
namespace lldb_private {
class ScriptInterpreter;
@@ -127,6 +128,7 @@ static FormatEntity::Entry::Definition g_frame_child_entries[] = {
ENTRY("flags", FrameRegisterFlags, UInt64),
ENTRY("no-debug", FrameNoDebug, None),
ENTRY_CHILDREN("reg", FrameRegisterByName, UInt64, g_string_entry),
+ ENTRY("is-artificial", FrameIsArtificial, UInt32),
};
static FormatEntity::Entry::Definition g_function_child_entries[] = {
@@ -145,6 +147,7 @@ static FormatEntity::Entry::Definition g_function_child_entries[] = {
static FormatEntity::Entry::Definition g_line_child_entries[] = {
ENTRY_CHILDREN("file", LineEntryFile, None, g_file_child_entries),
ENTRY("number", LineEntryLineNumber, UInt32),
+ ENTRY("column", LineEntryColumn, UInt32),
ENTRY("start-addr", LineEntryStartAddress, UInt64),
ENTRY("end-addr", LineEntryEndAddress, UInt64),
};
@@ -355,6 +358,7 @@ const char *FormatEntity::Entry::TypeToCString(Type t) {
ENUM_TO_CSTR(FrameRegisterFP);
ENUM_TO_CSTR(FrameRegisterFlags);
ENUM_TO_CSTR(FrameRegisterByName);
+ ENUM_TO_CSTR(FrameIsArtificial);
ENUM_TO_CSTR(ScriptFrame);
ENUM_TO_CSTR(FunctionID);
ENUM_TO_CSTR(FunctionDidChange);
@@ -371,6 +375,7 @@ const char *FormatEntity::Entry::TypeToCString(Type t) {
ENUM_TO_CSTR(FunctionIsOptimized);
ENUM_TO_CSTR(LineEntryFile);
ENUM_TO_CSTR(LineEntryLineNumber);
+ ENUM_TO_CSTR(LineEntryColumn);
ENUM_TO_CSTR(LineEntryStartAddress);
ENUM_TO_CSTR(LineEntryEndAddress);
ENUM_TO_CSTR(CurrentPCArrow);
@@ -467,10 +472,9 @@ static bool DumpAddressOffsetFromFunction(Stream &s, const SymbolContext *sc,
if (sc->function) {
func_addr = sc->function->GetAddressRange().GetBaseAddress();
if (sc->block && !concrete_only) {
- // Check to make sure we aren't in an inline
- // function. If we are, use the inline block
- // range that contains "format_addr" since
- // blocks can be discontiguous.
+ // Check to make sure we aren't in an inline function. If we are, use
+ // the inline block range that contains "format_addr" since blocks
+ // can be discontiguous.
Block *inline_block = sc->block->GetContainingInlinedBlock();
AddressRange inline_range;
if (inline_block &&
@@ -622,7 +626,7 @@ static bool DumpRegister(Stream &s, StackFrame *frame, RegisterKind reg_kind,
if (reg_info) {
RegisterValue reg_value;
if (reg_ctx->ReadRegister(reg_info, reg_value)) {
- reg_value.Dump(&s, reg_info, false, false, format);
+ DumpRegisterValue(reg_value, &s, reg_info, false, false, format);
return true;
}
}
@@ -822,8 +826,7 @@ static bool DumpValue(Stream &s, const SymbolContext *sc,
if (do_deref_pointer && !is_array_range) {
// I have not deref-ed yet, let's do it
// this happens when we are not going through
- // GetValueForVariableExpressionPath
- // to get to the target ValueObject
+ // GetValueForVariableExpressionPath to get to the target ValueObject
Status error;
target = target->Dereference(error).get();
if (error.Fail()) {
@@ -842,9 +845,9 @@ static bool DumpValue(Stream &s, const SymbolContext *sc,
return false;
}
- // we do not want to use the summary for a bitfield of type T:n
- // if we were originally dealing with just a T - that would get
- // us into an endless recursion
+ // we do not want to use the summary for a bitfield of type T:n if we were
+ // originally dealing with just a T - that would get us into an endless
+ // recursion
if (target->IsBitfield() && was_var_indexed) {
// TODO: check for a (T:n)-specific summary - we should still obey that
StreamString bitfield_name;
@@ -905,8 +908,7 @@ static bool DumpValue(Stream &s, const SymbolContext *sc,
}
// if directly trying to print ${var}, and this is an aggregate, display a
- // nice
- // type @ location message
+ // nice type @ location message
if (is_aggregate && was_plain_var) {
s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
return true;
@@ -1021,7 +1023,7 @@ static bool DumpRegister(Stream &s, StackFrame *frame, const char *reg_name,
if (reg_info) {
RegisterValue reg_value;
if (reg_ctx->ReadRegister(reg_info, reg_value)) {
- reg_value.Dump(&s, reg_info, false, false, format);
+ DumpRegisterValue(reg_value, &s, reg_info, false, false, format);
return true;
}
}
@@ -1142,8 +1144,8 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
if (!success)
break;
}
- // Only if all items in a scope succeed, then do we
- // print the output into the main stream
+ // Only if all items in a scope succeed, then do we print the output into
+ // the main stream
if (success)
s.Write(scope_stream.GetString().data(), scope_stream.GetString().size());
}
@@ -1206,9 +1208,8 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
// Watch for the special "tid" format...
if (entry.printf_format == "tid") {
// TODO(zturner): Rather than hardcoding this to be platform
- // specific, it should be controlled by a
- // setting and the default value of the setting can be different
- // depending on the platform.
+ // specific, it should be controlled by a setting and the default
+ // value of the setting can be different depending on the platform.
Target &target = thread->GetProcess()->GetTarget();
ArchSpec arch(target.GetArchitecture());
llvm::Triple::OSType ostype = arch.IsValid()
@@ -1216,7 +1217,8 @@ 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::NetBSD) ||
+ (ostype == llvm::Triple::OpenBSD)) {
format = "%" PRIu64;
}
} else {
@@ -1490,6 +1492,13 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
}
return false;
+ case Entry::Type::FrameIsArtificial: {
+ if (exe_ctx)
+ if (StackFrame *frame = exe_ctx->GetFramePtr())
+ return frame->IsArtificial();
+ return false;
+ }
+
case Entry::Type::ScriptFrame:
if (exe_ctx) {
StackFrame *frame = exe_ctx->GetFramePtr();
@@ -1817,6 +1826,16 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
}
return false;
+ case Entry::Type::LineEntryColumn:
+ if (sc && sc->line_entry.IsValid() && sc->line_entry.column) {
+ const char *format = "%" PRIu32;
+ if (!entry.printf_format.empty())
+ format = entry.printf_format.c_str();
+ s.Printf(format, sc->line_entry.column);
+ return true;
+ }
+ return false;
+
case Entry::Type::LineEntryStartAddress:
case Entry::Type::LineEntryEndAddress:
if (sc && sc->line_entry.range.GetBaseAddress().IsValid()) {
@@ -1914,9 +1933,9 @@ static Status ParseEntry(const llvm::StringRef &format_str,
error.SetErrorStringWithFormat("%s", error_strm.GetData());
} else if (sep_char == ':') {
// Any value whose separator is a with a ':' means this value has a
- // string argument
- // that needs to be stored in the entry (like "${script.var:}").
- // In this case the string value is the empty string which is ok.
+ // string argument that needs to be stored in the entry (like
+ // "${script.var:}"). In this case the string value is the empty
+ // string which is ok.
} else {
error.SetErrorStringWithFormat("%s", "invalid entry definitions");
}
@@ -1926,8 +1945,7 @@ static Status ParseEntry(const llvm::StringRef &format_str,
error = ParseEntry(value, entry_def, entry);
} else if (sep_char == ':') {
// Any value whose separator is a with a ':' means this value has a
- // string argument
- // that needs to be stored in the entry (like
+ // string argument that needs to be stored in the entry (like
// "${script.var:modulename.function}")
entry.string = value.str();
} else {
@@ -2065,17 +2083,17 @@ Status FormatEntity::ParseInternal(llvm::StringRef &format, Entry &parent_entry,
case '0':
// 1 to 3 octal chars
{
- // Make a string that can hold onto the initial zero char,
- // up to 3 octal digits, and a terminating NULL.
+ // Make a string that can hold onto the initial zero char, up to 3
+ // octal digits, and a terminating NULL.
char oct_str[5] = {0, 0, 0, 0, 0};
int i;
for (i = 0; (format[i] >= '0' && format[i] <= '7') && i < 4; ++i)
oct_str[i] = format[i];
- // We don't want to consume the last octal character since
- // the main for loop will do this for us, so we advance p by
- // one less than i (even if i is zero)
+ // We don't want to consume the last octal character since the main
+ // for loop will do this for us, so we advance p by one less than i
+ // (even if i is zero)
format = format.drop_front(i);
unsigned long octal_value = ::strtoul(oct_str, nullptr, 8);
if (octal_value <= UINT8_MAX) {
@@ -2115,8 +2133,8 @@ Status FormatEntity::ParseInternal(llvm::StringRef &format, Entry &parent_entry,
break;
default:
- // Just desensitize any other character by just printing what
- // came after the '\'
+ // Just desensitize any other character by just printing what came
+ // after the '\'
parent_entry.AppendChar(desens_char);
break;
}
@@ -2142,10 +2160,9 @@ Status FormatEntity::ParseInternal(llvm::StringRef &format, Entry &parent_entry,
if (!variable_format.empty()) {
entry.printf_format = variable_format.str();
- // If the format contains a '%' we are going to assume this is
- // a printf style format. So if you want to format your thread ID
- // using "0x%llx" you can use:
- // ${thread.id%0x%llx}
+ // If the format contains a '%' we are going to assume this is a
+ // printf style format. So if you want to format your thread ID
+ // using "0x%llx" you can use: ${thread.id%0x%llx}
//
// If there is no '%' in the format, then it is assumed to be a
// LLDB format name, or one of the extended formats specified in
@@ -2264,9 +2281,9 @@ Status FormatEntity::ParseInternal(llvm::StringRef &format, Entry &parent_entry,
return error;
}
}
- // Check if this entry just wants to insert a constant string
- // value into the parent_entry, if so, insert the string with
- // AppendText, else append the entry to the parent_entry.
+ // Check if this entry just wants to insert a constant string value
+ // into the parent_entry, if so, insert the string with AppendText,
+ // else append the entry to the parent_entry.
if (entry.type == Entry::Type::InsertString)
parent_entry.AppendText(entry.string.c_str());
else
@@ -2350,12 +2367,11 @@ static void AddMatches(const FormatEntity::Entry::Definition *def,
}
}
-size_t FormatEntity::AutoComplete(llvm::StringRef str, int match_start_point,
- int max_return_elements, bool &word_complete,
- StringList &matches) {
- word_complete = false;
- str = str.drop_front(match_start_point);
- matches.Clear();
+size_t FormatEntity::AutoComplete(CompletionRequest &request) {
+ llvm::StringRef str = request.GetCursorArgumentPrefix().str();
+
+ request.SetWordComplete(false);
+ str = str.drop_front(request.GetMatchStartPoint());
const size_t dollar_pos = str.rfind('$');
if (dollar_pos == llvm::StringRef::npos)
@@ -2365,7 +2381,7 @@ size_t FormatEntity::AutoComplete(llvm::StringRef str, int match_start_point,
if (dollar_pos == str.size() - 1) {
std::string match = str.str();
match.append("{");
- matches.AppendString(match);
+ request.AddCompletion(match);
return 1;
}
@@ -2383,8 +2399,10 @@ size_t FormatEntity::AutoComplete(llvm::StringRef str, int match_start_point,
llvm::StringRef partial_variable(str.substr(dollar_pos + 2));
if (partial_variable.empty()) {
// Suggest all top level entites as we are just past "${"
- AddMatches(&g_root, str, llvm::StringRef(), matches);
- return matches.GetSize();
+ StringList new_matches;
+ AddMatches(&g_root, str, llvm::StringRef(), new_matches);
+ request.AddCompletions(new_matches);
+ return request.GetNumberOfMatches();
}
// We have a partially specified variable, find it
@@ -2400,19 +2418,23 @@ size_t FormatEntity::AutoComplete(llvm::StringRef str, int match_start_point,
// Exact match
if (n > 0) {
// "${thread.info" <TAB>
- matches.AppendString(MakeMatch(str, "."));
+ request.AddCompletion(MakeMatch(str, "."));
} else {
// "${thread.id" <TAB>
- matches.AppendString(MakeMatch(str, "}"));
- word_complete = true;
+ request.AddCompletion(MakeMatch(str, "}"));
+ request.SetWordComplete(true);
}
} else if (remainder.equals(".")) {
// "${thread." <TAB>
- AddMatches(entry_def, str, llvm::StringRef(), matches);
+ StringList new_matches;
+ AddMatches(entry_def, str, llvm::StringRef(), new_matches);
+ request.AddCompletions(new_matches);
} else {
// We have a partial match
// "${thre" <TAB>
- AddMatches(entry_def, str, remainder, matches);
+ StringList new_matches;
+ AddMatches(entry_def, str, remainder, new_matches);
+ request.AddCompletions(new_matches);
}
- return matches.GetSize();
+ return request.GetNumberOfMatches();
}
diff --git a/gnu/llvm/tools/lldb/source/Host/common/SocketAddress.cpp b/gnu/llvm/tools/lldb/source/Host/common/SocketAddress.cpp
index def3e0359f0..9612af9ad70 100644
--- a/gnu/llvm/tools/lldb/source/Host/common/SocketAddress.cpp
+++ b/gnu/llvm/tools/lldb/source/Host/common/SocketAddress.cpp
@@ -21,7 +21,6 @@
#include <stddef.h>
#include <stdio.h>
-// C Includes
#if !defined(_WIN32)
#include <arpa/inet.h>
#endif
@@ -29,9 +28,6 @@
#include <assert.h>
#include <string.h>
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Host/PosixApi.h"
// WindowsXP needs an inet_ntop implementation
@@ -128,7 +124,7 @@ static socklen_t GetFamilyLength(sa_family_t family) {
}
socklen_t SocketAddress::GetLength() const {
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
return m_socket_addr.sa.sa_len;
#else
return GetFamilyLength(GetFamily());
@@ -143,7 +139,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__)
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
m_socket_addr.sa.sa_len = GetFamilyLength(family);
#endif
}
diff --git a/gnu/llvm/tools/lldb/source/Host/openbsd/Host.cpp b/gnu/llvm/tools/lldb/source/Host/openbsd/Host.cpp
index 0535256b9aa..ee65e317685 100644
--- a/gnu/llvm/tools/lldb/source/Host/openbsd/Host.cpp
+++ b/gnu/llvm/tools/lldb/source/Host/openbsd/Host.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include <sys/types.h>
#include <sys/signal.h>
@@ -19,15 +18,9 @@
#include <stdio.h>
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/Module.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
-#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
@@ -45,64 +38,78 @@ extern char **environ;
using namespace lldb;
using namespace lldb_private;
-size_t Host::GetEnvironment(StringList &env) {
+Environment Host::GetEnvironment() {
+ Environment env;
char *v;
char **var = environ;
for (; var != NULL && *var != NULL; ++var) {
v = strchr(*var, (int)'-');
if (v == NULL)
continue;
- env.AppendString(v);
+ env.insert(v);
}
- return env.GetSize();
+ return env;
}
static bool
GetOpenBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
ProcessInstanceInfo &process_info) {
- if (process_info.ProcessIDIsValid()) {
- int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ARGS,
- (int)process_info.GetProcessID()};
-
- char arg_data[8192];
- size_t arg_data_size = sizeof(arg_data);
- if (::sysctl(mib, 4, arg_data, &arg_data_size, NULL, 0) == 0) {
- 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) {
- process_info.GetExecutableFile().SetFile(cstr, false);
-
- if (!(match_info_ptr == NULL ||
- NameMatches(
- process_info.GetExecutableFile().GetFilename().GetCString(),
+ if (!process_info.ProcessIDIsValid())
+ return false;
+
+ int pid = process_info.GetProcessID();
+
+ int mib[4] = {CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_ARGV};
+ size_t kern_proc_args_size = 0;
+
+ // On OpenBSD, this will just fill ARG_MAX all the time
+ if (::sysctl(mib, 4, NULL, &kern_proc_args_size, NULL, 0) == -1)
+ return false;
+
+ std::string arg_data(kern_proc_args_size, 0);
+
+ if (::sysctl(mib, 4, (void *)arg_data.data(), &kern_proc_args_size, NULL, 0) == -1)
+ return false;
+
+ arg_data.resize(kern_proc_args_size);
+
+ // arg_data is a NULL terminated list of pointers, where the pointers
+ // point within arg_data to the location of the arg string
+ DataExtractor data(arg_data.data(), arg_data.length(), endian::InlHostByteOrder(), sizeof(void *));
+
+ lldb::offset_t offset = 0;
+ lldb::offset_t arg_offset = 0;
+ uint64_t arg_addr = 0;
+ const char *cstr;
+
+ arg_addr = data.GetAddress(&offset);
+ arg_offset = arg_addr - (uint64_t)arg_data.data();
+ cstr = data.GetCStr(&arg_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;
-
- 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)
- return true;
-
- cstr = data.GetCStr(&offset);
- if (cstr)
- proc_args.AppendArgument(llvm::StringRef(cstr));
- else
- return true;
- }
- }
- }
+ match_info_ptr->GetProcessInfo().GetName()))
+ {
+ return false;
}
- return false;
+
+ Args &proc_args = process_info.GetArguments();
+
+ while (1) {
+ arg_addr = data.GetAddress(&offset);
+ if (arg_addr == 0)
+ break;
+ arg_offset = arg_addr - (uint64_t)arg_data.data();
+ cstr = data.GetCStr(&arg_offset);
+ proc_args.AppendArgument(cstr);
+ }
+ return true;
}
static bool GetOpenBSDProcessCPUType(ProcessInstanceInfo &process_info) {
@@ -116,21 +123,21 @@ static bool GetOpenBSDProcessCPUType(ProcessInstanceInfo &process_info) {
}
static bool GetOpenBSDProcessUserAndGroup(ProcessInstanceInfo &process_info) {
- struct kinfo_proc proc_kinfo;
- size_t proc_kinfo_size;
if (process_info.ProcessIDIsValid()) {
- int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID,
- (int)process_info.GetProcessID()};
- proc_kinfo_size = sizeof(struct kinfo_proc);
+ struct kinfo_proc proc_kinfo = {};
+ size_t proc_kinfo_size = sizeof(proc_kinfo);
+ int mib[6] = {CTL_KERN, KERN_PROC, KERN_PROC_PID,
+ (int)process_info.GetProcessID(),
+ sizeof(proc_kinfo), 1};
- if (::sysctl(mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) {
+ if (::sysctl(mib, 6, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) {
if (proc_kinfo_size > 0) {
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);
+ process_info.SetEffectiveGroupID(proc_kinfo.p_gid);
return true;
}
}
@@ -147,10 +154,10 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
ProcessInstanceInfoList &process_infos) {
std::vector<struct kinfo_proc> kinfos;
- int mib[3] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
+ int mib[6] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), 0};
size_t pid_data_size = 0;
- if (::sysctl(mib, 3, NULL, &pid_data_size, NULL, 0) != 0)
+ if (::sysctl(mib, 6, NULL, &pid_data_size, NULL, 0) != 0)
return 0;
// Add a few extra in case a few more show up
@@ -158,9 +165,10 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
(pid_data_size / sizeof(struct kinfo_proc)) + 10;
kinfos.resize(estimated_pid_count);
+ mib[5] = estimated_pid_count;
pid_data_size = kinfos.size() * sizeof(struct kinfo_proc);
- if (::sysctl(mib, 3, &kinfos[0], &pid_data_size, NULL, 0) != 0)
+ if (::sysctl(mib, 6, &kinfos[0], &pid_data_size, NULL, 0) != 0)
return 0;
const size_t actual_pid_count = (pid_data_size / sizeof(struct kinfo_proc));
diff --git a/gnu/llvm/tools/lldb/source/Host/posix/DomainSocket.cpp b/gnu/llvm/tools/lldb/source/Host/posix/DomainSocket.cpp
index 3e3abadc2e5..af27e066413 100644
--- a/gnu/llvm/tools/lldb/source/Host/posix/DomainSocket.cpp
+++ b/gnu/llvm/tools/lldb/source/Host/posix/DomainSocket.cpp
@@ -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__)
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
saddr_un->sun_len = saddr_un_len;
#endif
diff --git a/gnu/llvm/tools/lldb/source/Host/posix/PipePosix.cpp b/gnu/llvm/tools/lldb/source/Host/posix/PipePosix.cpp
index da99fd70242..6782440bb1b 100644
--- a/gnu/llvm/tools/lldb/source/Host/posix/PipePosix.cpp
+++ b/gnu/llvm/tools/lldb/source/Host/posix/PipePosix.cpp
@@ -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(__NetBSD__) || defined(__OpenBSD__)
#define PIPE2_SUPPORTED 1
#else
#define PIPE2_SUPPORTED 0
@@ -61,12 +61,13 @@ bool SetCloexecFlag(int fd) {
std::chrono::time_point<std::chrono::steady_clock> Now() {
return std::chrono::steady_clock::now();
}
-}
+} // namespace
PipePosix::PipePosix()
: m_fds{PipePosix::kInvalidDescriptor, PipePosix::kInvalidDescriptor} {}
-PipePosix::PipePosix(int read_fd, int write_fd) : m_fds{read_fd, write_fd} {}
+PipePosix::PipePosix(lldb::pipe_t read, lldb::pipe_t write)
+ : m_fds{read, write} {}
PipePosix::PipePosix(PipePosix &&pipe_posix)
: PipeBase{std::move(pipe_posix)},
@@ -125,20 +126,16 @@ Status PipePosix::CreateNew(llvm::StringRef name, bool child_process_inherit) {
Status PipePosix::CreateWithUniqueName(llvm::StringRef prefix,
bool child_process_inherit,
llvm::SmallVectorImpl<char> &name) {
- llvm::SmallString<PATH_MAX> named_pipe_path;
- llvm::SmallString<PATH_MAX> pipe_spec((prefix + ".%%%%%%").str());
- FileSpec tmpdir_file_spec;
- tmpdir_file_spec.Clear();
- if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) {
- tmpdir_file_spec.AppendPathComponent(pipe_spec.c_str());
- } else {
+ llvm::SmallString<128> named_pipe_path;
+ llvm::SmallString<128> pipe_spec((prefix + ".%%%%%%").str());
+ FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir();
+ if (!tmpdir_file_spec)
tmpdir_file_spec.AppendPathComponent("/tmp");
- tmpdir_file_spec.AppendPathComponent(pipe_spec.c_str());
- }
+ tmpdir_file_spec.AppendPathComponent(pipe_spec);
// It's possible that another process creates the target path after we've
- // verified it's available but before we create it, in which case we
- // should try again.
+ // verified it's available but before we create it, in which case we should
+ // try again.
Status error;
do {
llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath(),
diff --git a/gnu/llvm/tools/lldb/source/Initialization/CMakeLists.txt b/gnu/llvm/tools/lldb/source/Initialization/CMakeLists.txt
index 7a100588e00..237e9761f02 100644
--- a/gnu/llvm/tools/lldb/source/Initialization/CMakeLists.txt
+++ b/gnu/llvm/tools/lldb/source/Initialization/CMakeLists.txt
@@ -1,8 +1,4 @@
-if ( CMAKE_SYSTEM_NAME MATCHES "Darwin" )
- list(APPEND EXTRA_PLUGINS lldbPluginObjectFileMachO)
-endif()
-
-if ( CMAKE_SYSTEM_NAME MATCHES "Linux|Android|FreeBSD|NetBSD" )
+if ( CMAKE_SYSTEM_NAME MATCHES "Linux|Android|FreeBSD|NetBSD|OpenBSD" )
list(APPEND EXTRA_PLUGINS lldbPluginProcessPOSIX)
endif()
@@ -23,8 +19,6 @@ add_lldb_library(lldbInitialization
lldbPluginInstructionMIPS64
lldbPluginObjectContainerBSDArchive
lldbPluginObjectContainerMachOArchive
- lldbPluginObjectFileELF
- lldbPluginObjectFilePECOFF
lldbPluginProcessGDBRemote
${EXTRA_PLUGINS}
${LLDB_SYSTEM_LIBS}
diff --git a/gnu/llvm/tools/lldb/source/Initialization/SystemInitializerCommon.cpp b/gnu/llvm/tools/lldb/source/Initialization/SystemInitializerCommon.cpp
index e76ba4122bb..767f54962c0 100644
--- a/gnu/llvm/tools/lldb/source/Initialization/SystemInitializerCommon.cpp
+++ b/gnu/llvm/tools/lldb/source/Initialization/SystemInitializerCommon.cpp
@@ -14,19 +14,15 @@
#include "Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h"
#include "Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h"
#include "Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h"
-#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
-#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
#include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/Timer.h"
-#if defined(__APPLE__)
-#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
-#endif
-
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
#endif
@@ -35,18 +31,19 @@
#include "lldb/Host/windows/windows.h"
#endif
-#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/TargetSelect.h"
#include <string>
using namespace lldb_private;
+using namespace lldb_private::repro;
SystemInitializerCommon::SystemInitializerCommon() {}
SystemInitializerCommon::~SystemInitializerCommon() {}
-void SystemInitializerCommon::Initialize() {
+llvm::Error
+SystemInitializerCommon::Initialize(const InitializerOptions &options) {
#if defined(_MSC_VER)
const char *disable_crash_dialog_var = getenv("LLDB_DISABLE_CRASH_DIALOG");
if (disable_crash_dialog_var &&
@@ -69,8 +66,17 @@ void SystemInitializerCommon::Initialize() {
}
#endif
- llvm::EnablePrettyStackTrace();
- InitializeLog();
+ ReproducerMode mode = ReproducerMode::Off;
+ if (options.reproducer_capture)
+ mode = ReproducerMode::Capture;
+ if (options.reproducer_replay)
+ mode = ReproducerMode::Replay;
+
+ if (auto e = Reproducer::Initialize(mode, FileSpec(options.reproducer_path)))
+ return e;
+
+ FileSystem::Initialize();
+ Log::Initialize();
HostInfo::Initialize();
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
@@ -79,8 +85,6 @@ void SystemInitializerCommon::Initialize() {
// Initialize plug-ins
ObjectContainerBSDArchive::Initialize();
- ObjectFileELF::Initialize();
- ObjectFilePECOFF::Initialize();
EmulateInstructionARM::Initialize();
EmulateInstructionMIPS::Initialize();
@@ -91,32 +95,26 @@ void SystemInitializerCommon::Initialize() {
//----------------------------------------------------------------------
ObjectContainerUniversalMachO::Initialize();
-#if defined(__APPLE__)
- ObjectFileMachO::Initialize();
-#endif
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
ProcessPOSIXLog::Initialize();
#endif
#if defined(_MSC_VER)
ProcessWindowsLog::Initialize();
#endif
+
+ return llvm::Error::success();
}
void SystemInitializerCommon::Terminate() {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
ObjectContainerBSDArchive::Terminate();
- ObjectFileELF::Terminate();
- ObjectFilePECOFF::Terminate();
EmulateInstructionARM::Terminate();
EmulateInstructionMIPS::Terminate();
EmulateInstructionMIPS64::Terminate();
ObjectContainerUniversalMachO::Terminate();
-#if defined(__APPLE__)
- ObjectFileMachO::Terminate();
-#endif
#if defined(_MSC_VER)
ProcessWindowsLog::Terminate();
@@ -124,4 +122,6 @@ void SystemInitializerCommon::Terminate() {
HostInfo::Terminate();
Log::DisableAllLogChannels();
+ FileSystem::Terminate();
+ Reproducer::Terminate();
}
diff --git a/gnu/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/gnu/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
index c1986976b0f..9a09ebc31af 100644
--- a/gnu/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
+++ b/gnu/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -7,10 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Symbol.h"
@@ -18,6 +14,7 @@
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
@@ -48,8 +45,8 @@ static addr_t ResolveRendezvousAddress(Process *process) {
if (log)
log->Printf("%s info_location = 0x%" PRIx64, __FUNCTION__, info_location);
- // If the process fails to return an address, fall back to seeing if the local
- // object file can help us find it.
+ // If the process fails to return an address, fall back to seeing if the
+ // local object file can help us find it.
if (info_location == LLDB_INVALID_ADDRESS) {
Target *target = &process->GetTarget();
if (target) {
@@ -193,8 +190,8 @@ bool DYLDRendezvous::UpdateSOEntries(bool fromRemote) {
if (!fromRemote && m_current.map_addr == 0)
return false;
- // When the previous and current states are consistent this is the first
- // time we have been asked to update. Just take a snapshot of the currently
+ // When the previous and current states are consistent this is the first time
+ // we have been asked to update. Just take a snapshot of the currently
// loaded modules.
if (m_previous.state == eConsistent && m_current.state == eConsistent)
return fromRemote ? SaveSOEntriesFromRemote(module_list)
@@ -203,9 +200,9 @@ bool DYLDRendezvous::UpdateSOEntries(bool fromRemote) {
// If we are about to add or remove a shared object clear out the current
// state and take a snapshot of the currently loaded images.
if (m_current.state == eAdd || m_current.state == eDelete) {
- // Some versions of the android dynamic linker might send two
- // notifications with state == eAdd back to back. Ignore them
- // until we get an eConsistent notification.
+ // Some versions of the android dynamic linker might send two notifications
+ // with state == eAdd back to back. Ignore them until we get an eConsistent
+ // notification.
if (!(m_previous.state == eConsistent ||
(m_previous.state == eAdd && m_current.state == eDelete)))
return false;
@@ -246,7 +243,7 @@ bool DYLDRendezvous::FillSOEntryFromModuleInfo(
entry.base_addr = base_addr;
entry.dyn_addr = dyn_addr;
- entry.file_spec.SetFile(name, false);
+ entry.file_spec.SetFile(name, FileSpec::Style::native);
UpdateBaseAddrIfNecessary(entry, name);
@@ -386,6 +383,7 @@ 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())
@@ -452,30 +450,22 @@ std::string DYLDRendezvous::ReadStringFromMemory(addr_t addr) {
}
// Returns true if the load bias reported by the linker is incorrect for the
-// given entry. This
-// function is used to handle cases where we want to work around a bug in the
-// system linker.
+// given entry. This function is used to handle cases where we want to work
+// around a bug in the system linker.
static bool isLoadBiasIncorrect(Target &target, const std::string &file_path) {
// On Android L (API 21, 22) the load address of the "/system/bin/linker"
- // isn't filled in
- // correctly.
- uint32_t os_major = 0, os_minor = 0, os_update = 0;
- if (target.GetArchitecture().GetTriple().isAndroid() &&
- target.GetPlatform()->GetOSVersion(os_major, os_minor, os_update) &&
- (os_major == 21 || os_major == 22) &&
- (file_path == "/system/bin/linker" ||
- file_path == "/system/bin/linker64")) {
- return true;
- }
-
- return false;
+ // isn't filled in correctly.
+ unsigned os_major = target.GetPlatform()->GetOSVersion().getMajor();
+ return target.GetArchitecture().GetTriple().isAndroid() &&
+ (os_major == 21 || os_major == 22) &&
+ (file_path == "/system/bin/linker" ||
+ file_path == "/system/bin/linker64");
}
void DYLDRendezvous::UpdateBaseAddrIfNecessary(SOEntry &entry,
std::string const &file_path) {
// If the load bias reported by the linker is incorrect then fetch the load
- // address of the file
- // from the proc file system.
+ // address of the file from the proc file system.
if (isLoadBiasIncorrect(m_process->GetTarget(), file_path)) {
lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
bool is_loaded = false;
@@ -494,8 +484,8 @@ bool DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry) {
if (!(addr = ReadPointer(addr, &entry.base_addr)))
return false;
- // mips adds an extra load offset field to the link map struct on
- // FreeBSD and NetBSD (need to validate other OSes).
+ // mips adds an extra load offset field to the link map struct on FreeBSD and
+ // NetBSD (need to validate other OSes).
// http://svnweb.freebsd.org/base/head/sys/sys/link_elf.h?revision=217153&view=markup#l57
const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
if ((arch.GetTriple().getOS() == llvm::Triple::FreeBSD ||
@@ -524,7 +514,7 @@ bool DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry) {
return false;
std::string file_path = ReadStringFromMemory(entry.path_addr);
- entry.file_spec.SetFile(file_path, false);
+ entry.file_spec.SetFile(file_path, FileSpec::Style::native);
UpdateBaseAddrIfNecessary(entry, file_path);
diff --git a/gnu/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/gnu/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index a7afeb6d68c..77e0c870c20 100644
--- a/gnu/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/gnu/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -10,10 +10,8 @@
// Main header include
#include "DynamicLoaderPOSIXDYLD.h"
-// Project includes
#include "AuxVector.h"
-// Other libraries and framework includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
@@ -29,8 +27,6 @@
#include "lldb/Target/ThreadPlanRunToAddress.h"
#include "lldb/Utility/Log.h"
-// C++ Includes
-// C Includes
using namespace lldb;
using namespace lldb_private;
@@ -66,7 +62,8 @@ 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::NetBSD ||
+ triple_ref.getOS() == llvm::Triple::OpenBSD)
create = true;
}
@@ -79,7 +76,8 @@ DynamicLoaderPOSIXDYLD::DynamicLoaderPOSIXDYLD(Process *process)
: DynamicLoader(process), m_rendezvous(process),
m_load_offset(LLDB_INVALID_ADDRESS), m_entry_point(LLDB_INVALID_ADDRESS),
m_auxv(), m_dyld_bid(LLDB_INVALID_BREAK_ID),
- m_vdso_base(LLDB_INVALID_ADDRESS) {}
+ m_vdso_base(LLDB_INVALID_ADDRESS),
+ m_interpreter_base(LLDB_INVALID_ADDRESS) {}
DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD() {
if (m_dyld_bid != LLDB_INVALID_BREAK_ID) {
@@ -117,10 +115,10 @@ void DynamicLoaderPOSIXDYLD::DidAttach() {
: "<null executable>",
load_offset);
- EvalVdsoStatus();
+ EvalSpecialModulesStatus();
// if we dont have a load address we cant re-base
- bool rebase_exec = (load_offset == LLDB_INVALID_ADDRESS) ? false : true;
+ bool rebase_exec = load_offset != LLDB_INVALID_ADDRESS;
// if we have a valid executable
if (executable_sp.get()) {
@@ -152,31 +150,10 @@ void DynamicLoaderPOSIXDYLD::DidAttach() {
UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset,
true);
- // When attaching to a target, there are two possible states:
- // (1) We already crossed the entry point and therefore the rendezvous
- // structure is ready to be used and we can load the list of modules
- // and place the rendezvous breakpoint.
- // (2) We didn't cross the entry point yet, so these structures are not
- // ready; we should behave as if we just launched the target and
- // call ProbeEntry(). This will place a breakpoint on the entry
- // point which itself will be hit after the rendezvous structure is
- // set up and will perform actions described in (1).
- if (m_rendezvous.Resolve()) {
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64
- " rendezvous could resolve: attach assuming dynamic loader "
- "info is available now",
- __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
- LoadAllCurrentModules();
- SetRendezvousBreakpoint();
- } else {
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64
- " rendezvous could not yet resolve: adding breakpoint to "
- "catch future rendezvous setup",
- __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ LoadAllCurrentModules();
+ if (!SetRendezvousBreakpoint()) {
+ // If we cannot establish rendezvous breakpoint right now we'll try again
+ // at entry point.
ProbeEntry();
}
@@ -207,7 +184,7 @@ void DynamicLoaderPOSIXDYLD::DidLaunch() {
executable = GetTargetExecutable();
load_offset = ComputeLoadOffset();
- EvalVdsoStatus();
+ EvalSpecialModulesStatus();
if (executable.get() && load_offset != LLDB_INVALID_ADDRESS) {
ModuleList module_list;
@@ -217,8 +194,14 @@ void DynamicLoaderPOSIXDYLD::DidLaunch() {
if (log)
log->Printf("DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()",
__FUNCTION__);
- ProbeEntry();
+ if (!SetRendezvousBreakpoint()) {
+ // If we cannot establish rendezvous breakpoint right now we'll try again
+ // at entry point.
+ ProbeEntry();
+ }
+
+ LoadVDSO();
m_process->GetTarget().ModulesDidLoad(module_list);
}
}
@@ -273,11 +256,11 @@ void DynamicLoaderPOSIXDYLD::ProbeEntry() {
}
// The runtime linker has run and initialized the rendezvous structure once the
-// process has hit its entry point. When we hit the corresponding breakpoint we
-// interrogate the rendezvous structure to get the load addresses of all
+// process has hit its entry point. When we hit the corresponding breakpoint
+// we interrogate the rendezvous structure to get the load addresses of all
// dependent modules for the process. Similarly, we can discover the runtime
-// linker function and setup a breakpoint to notify us of any dynamically loaded
-// modules (via dlopen).
+// linker function and setup a breakpoint to notify us of any dynamically
+// loaded modules (via dlopen).
bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit(
void *baton, StoppointCallbackContext *context, user_id_t break_id,
user_id_t break_loc_id) {
@@ -295,13 +278,11 @@ bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit(
: LLDB_INVALID_PROCESS_ID);
// Disable the breakpoint --- if a stop happens right after this, which we've
- // seen on occasion, we don't
- // want the breakpoint stepping thread-plan logic to show a breakpoint
- // instruction at the disassembled
- // entry point to the program. Disabling it prevents it. (One-shot is not
- // enough - one-shot removal logic
- // only happens after the breakpoint goes public, which wasn't happening in
- // our scenario).
+ // seen on occasion, we don't want the breakpoint stepping thread-plan logic
+ // to show a breakpoint instruction at the disassembled entry point to the
+ // program. Disabling it prevents it. (One-shot is not enough - one-shot
+ // removal logic only happens after the breakpoint goes public, which wasn't
+ // happening in our scenario).
if (dyld_instance->m_process) {
BreakpointSP breakpoint_sp =
dyld_instance->m_process->GetTarget().GetBreakpointByID(break_id);
@@ -329,38 +310,77 @@ bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit(
return false; // Continue running.
}
-void DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() {
+bool DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (m_dyld_bid != LLDB_INVALID_BREAK_ID) {
+ LLDB_LOG(log,
+ "Rendezvous breakpoint breakpoint id {0} for pid {1}"
+ "is already set.",
+ m_dyld_bid,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ return true;
+ }
- addr_t break_addr = m_rendezvous.GetBreakAddress();
+ addr_t break_addr;
Target &target = m_process->GetTarget();
-
- if (m_dyld_bid == LLDB_INVALID_BREAK_ID) {
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
- " setting rendezvous break address at 0x%" PRIx64,
- __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
- break_addr);
- Breakpoint *dyld_break =
- target.CreateBreakpoint(break_addr, true, false).get();
- dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
- dyld_break->SetBreakpointKind("shared-library-event");
- m_dyld_bid = dyld_break->GetID();
+ BreakpointSP dyld_break;
+ if (m_rendezvous.IsValid()) {
+ break_addr = m_rendezvous.GetBreakAddress();
+ LLDB_LOG(log, "Setting rendezvous break address for pid {0} at {1:x}",
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
+ break_addr);
+ dyld_break = target.CreateBreakpoint(break_addr, true, false);
} else {
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
- " reusing break id %" PRIu32 ", address at 0x%" PRIx64,
- __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
- m_dyld_bid, break_addr);
+ LLDB_LOG(log, "Rendezvous structure is not set up yet. "
+ "Trying to locate rendezvous breakpoint in the interpreter "
+ "by symbol name.");
+ ModuleSP interpreter = LoadInterpreterModule();
+ if (!interpreter) {
+ LLDB_LOG(log, "Can't find interpreter, rendezvous breakpoint isn't set.");
+ return false;
+ }
+
+ // Function names from different dynamic loaders that are known to be used
+ // as rendezvous between the loader and debuggers.
+ static std::vector<std::string> DebugStateCandidates{
+ "_dl_debug_state", "rtld_db_dlactivity", "__dl_rtld_db_dlactivity",
+ "r_debug_state", "_r_debug_state", "_rtld_debug_state",
+ };
+
+ FileSpecList containingModules;
+ containingModules.Append(interpreter->GetFileSpec());
+ dyld_break = target.CreateBreakpoint(
+ &containingModules, nullptr /* containingSourceFiles */,
+ DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC,
+ 0, /* offset */
+ eLazyBoolNo, /* skip_prologue */
+ true, /* internal */
+ false /* request_hardware */);
+ }
+
+ if (dyld_break->GetNumResolvedLocations() != 1) {
+ LLDB_LOG(
+ log,
+ "Rendezvous breakpoint has abnormal number of"
+ " resolved locations ({0}) in pid {1}. It's supposed to be exactly 1.",
+ dyld_break->GetNumResolvedLocations(),
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+
+ target.RemoveBreakpointByID(dyld_break->GetID());
+ return false;
}
- // Make sure our breakpoint is at the right address.
- assert(target.GetBreakpointByID(m_dyld_bid)
- ->FindLocationByAddress(break_addr)
- ->GetBreakpoint()
- .GetID() == m_dyld_bid);
+ BreakpointLocationSP location = dyld_break->GetLocationAtIndex(0);
+ LLDB_LOG(log,
+ "Successfully set rendezvous breakpoint at address {0:x} "
+ "for pid {1}",
+ location->GetLoadAddress(),
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+
+ dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
+ dyld_break->SetBreakpointKind("shared-library-event");
+ m_dyld_bid = dyld_break->GetID();
+ return true;
}
bool DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit(
@@ -477,7 +497,7 @@ DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread,
AddressVector::iterator start = addrs.begin();
AddressVector::iterator end = addrs.end();
- std::sort(start, end);
+ llvm::sort(start, end);
addrs.erase(std::unique(start, end), end);
thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop));
}
@@ -485,11 +505,11 @@ DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread,
return thread_plan_sp;
}
-void DynamicLoaderPOSIXDYLD::LoadVDSO(ModuleList &modules) {
+void DynamicLoaderPOSIXDYLD::LoadVDSO() {
if (m_vdso_base == LLDB_INVALID_ADDRESS)
return;
- FileSpec file("[vdso]", false);
+ FileSpec file("[vdso]");
MemoryRegionInfo info;
Status status = m_process->GetMemoryRegionInfo(m_vdso_base, info);
@@ -506,13 +526,40 @@ void DynamicLoaderPOSIXDYLD::LoadVDSO(ModuleList &modules) {
}
}
+ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() {
+ if (m_interpreter_base == LLDB_INVALID_ADDRESS)
+ return nullptr;
+
+ MemoryRegionInfo info;
+ Target &target = m_process->GetTarget();
+ Status status = m_process->GetMemoryRegionInfo(m_interpreter_base, info);
+ if (status.Fail() || info.GetMapped() != MemoryRegionInfo::eYes ||
+ info.GetName().IsEmpty()) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ LLDB_LOG(log, "Failed to get interpreter region info: {0}", status);
+ return nullptr;
+ }
+
+ FileSpec file(info.GetName().GetCString());
+ ModuleSpec module_spec(file, target.GetArchitecture());
+
+ if (ModuleSP module_sp = target.GetSharedModule(module_spec)) {
+ UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS, m_interpreter_base,
+ false);
+ return module_sp;
+ }
+ return nullptr;
+}
+
void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() {
DYLDRendezvous::iterator I;
DYLDRendezvous::iterator E;
ModuleList module_list;
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+
+ LoadVDSO();
if (!m_rendezvous.Resolve()) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
if (log)
log->Printf("DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD "
"rendezvous address",
@@ -520,11 +567,10 @@ void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() {
return;
}
- // The rendezvous class doesn't enumerate the main module, so track
- // that ourselves here.
+ // The rendezvous class doesn't enumerate the main module, so track that
+ // ourselves here.
ModuleSP executable = GetTargetExecutable();
m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress();
- LoadVDSO(module_list);
std::vector<FileSpec> module_names;
for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
@@ -536,6 +582,8 @@ void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() {
ModuleSP module_sp =
LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
if (module_sp.get()) {
+ LLDB_LOG(log, "LoadAllCurrentModules loading module: {0}",
+ I->file_spec.GetFilename());
module_list.Append(module_sp);
} else {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
@@ -575,11 +623,14 @@ addr_t DynamicLoaderPOSIXDYLD::ComputeLoadOffset() {
return m_load_offset;
}
-void DynamicLoaderPOSIXDYLD::EvalVdsoStatus() {
- AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AUXV_AT_SYSINFO_EHDR);
-
- if (I != m_auxv->end())
+void DynamicLoaderPOSIXDYLD::EvalSpecialModulesStatus() {
+ auto I = m_auxv->FindEntry(AuxVector::AUXV_AT_SYSINFO_EHDR);
+ if (I != m_auxv->end() && I->value != 0)
m_vdso_base = I->value;
+
+ I = m_auxv->FindEntry(AuxVector::AUXV_AT_BASE);
+ if (I != m_auxv->end() && I->value != 0)
+ m_interpreter_base = I->value;
}
addr_t DynamicLoaderPOSIXDYLD::GetEntryPoint() {
@@ -702,7 +753,7 @@ void DynamicLoaderPOSIXDYLD::ResolveExecutableModule(
return;
}
- target.SetExecutableModule(module_sp, false);
+ target.SetExecutableModule(module_sp, eLoadDependentsNo);
}
bool DynamicLoaderPOSIXDYLD::AlwaysRelyOnEHUnwindInfo(
diff --git a/gnu/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp b/gnu/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
index edb8ec951d3..b5f7226901c 100644
--- a/gnu/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
+++ b/gnu/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
@@ -10,28 +10,24 @@
#include "PlatformOpenBSD.h"
#include "lldb/Host/Config.h"
-// C Includes
#include <stdio.h>
#ifndef LLDB_DISABLE_POSIX
#include <sys/utsname.h>
#endif
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/State.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
-// Define these constants from OpenBSD mman.h for use when targeting
-// remote openbsd systems even when host has different values.
+// Define these constants from OpenBSD mman.h for use when targeting remote
+// openbsd systems even when host has different values.
#define MAP_PRIVATE 0x0002
#define MAP_ANON 0x1000
@@ -50,7 +46,7 @@ PlatformSP PlatformOpenBSD::CreateInstance(bool force, const ArchSpec *arch) {
arch ? arch->GetTriple().getTriple() : "<null>");
bool create = force;
- if (create == false && arch && arch->IsValid()) {
+ if (!create && arch && arch->IsValid()) {
const llvm::Triple &triple = arch->GetTriple();
switch (triple.getOS()) {
case llvm::Triple::OpenBSD:
@@ -58,9 +54,8 @@ PlatformSP PlatformOpenBSD::CreateInstance(bool force, const ArchSpec *arch) {
break;
#if defined(__OpenBSD__)
- // Only accept "unknown" for the OS if the host is BSD and
- // it "unknown" wasn't specified (it was just returned because it
- // was NOT specified)
+ // Only accept "unknown" for the OS if the host is BSD and it "unknown"
+ // wasn't specified (it was just returned because it was NOT specified)
case llvm::Triple::OSType::UnknownOS:
create = !arch->TripleOSWasSpecified();
break;
@@ -98,7 +93,7 @@ ConstString PlatformOpenBSD::GetPluginName() {
}
void PlatformOpenBSD::Initialize() {
- Platform::Initialize();
+ PlatformPOSIX::Initialize();
if (g_initialize_count++ == 0) {
#if defined(__OpenBSD__)
@@ -133,7 +128,7 @@ PlatformOpenBSD::PlatformOpenBSD(bool is_host)
PlatformOpenBSD::~PlatformOpenBSD() = default;
bool PlatformOpenBSD::GetSupportedArchitectureAtIndex(uint32_t idx,
- ArchSpec &arch) {
+ ArchSpec &arch) {
if (IsHost()) {
ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
if (hostArch.GetTriple().isOSOpenBSD()) {
@@ -167,13 +162,10 @@ bool PlatformOpenBSD::GetSupportedArchitectureAtIndex(uint32_t idx,
return false;
}
// Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the
- // vendor by
- // calling triple.SetVendorName("unknown") so that it is a "unspecified
- // unknown".
- // This means when someone calls triple.GetVendorName() it will return an
- // empty string
- // which indicates that the vendor can be set when two architectures are
- // merged
+ // vendor by calling triple.SetVendorName("unknown") so that it is a
+ // "unspecified unknown". This means when someone calls
+ // triple.GetVendorName() it will return an empty string which indicates
+ // that the vendor can be set when two architectures are merged
// Now set the triple into "arch" and return true
arch.SetTriple(triple);
@@ -202,22 +194,145 @@ void PlatformOpenBSD::GetStatus(Stream &strm) {
#endif
}
-// OpenBSD processes cannot yet be launched by spawning and attaching.
bool PlatformOpenBSD::CanDebugProcess() {
- return false;
+ 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;
}
void PlatformOpenBSD::CalculateTrapHandlerSymbolNames() {
m_trap_handlers.push_back(ConstString("_sigtramp"));
}
-uint64_t PlatformOpenBSD::ConvertMmapFlagsToPlatform(const ArchSpec &arch,
- unsigned flags) {
+MmapArgList PlatformOpenBSD::GetMmapArgumentList(const ArchSpec &arch,
+ addr_t addr, addr_t length,
+ unsigned prot, unsigned flags,
+ addr_t fd, addr_t offset) {
uint64_t flags_platform = 0;
if (flags & eMmapFlagsPrivate)
flags_platform |= MAP_PRIVATE;
if (flags & eMmapFlagsAnon)
flags_platform |= MAP_ANON;
- return flags_platform;
+
+ MmapArgList args({addr, length, prot, flags_platform, fd, offset});
+ return args;
}
diff --git a/gnu/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h b/gnu/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h
index 55f6451e236..32a1a991b62 100644
--- a/gnu/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h
+++ b/gnu/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h
@@ -51,10 +51,15 @@ public:
bool CanDebugProcess() override;
+ lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
+ Target *target, Status &error) override;
+
void CalculateTrapHandlerSymbolNames() override;
- uint64_t ConvertMmapFlagsToPlatform(const ArchSpec &arch,
- unsigned flags) override;
+ MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr,
+ lldb::addr_t length, unsigned prot,
+ unsigned flags, lldb::addr_t fd,
+ lldb::addr_t offset) override;
private:
DISALLOW_COPY_AND_ASSIGN(PlatformOpenBSD);
diff --git a/gnu/llvm/tools/lldb/source/Plugins/Process/CMakeLists.txt b/gnu/llvm/tools/lldb/source/Plugins/Process/CMakeLists.txt
index 62abd75a43b..bc80f93a271 100644
--- a/gnu/llvm/tools/lldb/source/Plugins/Process/CMakeLists.txt
+++ b/gnu/llvm/tools/lldb/source/Plugins/Process/CMakeLists.txt
@@ -7,13 +7,16 @@ 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")
add_subdirectory(MacOSX-Kernel)
- add_subdirectory(mach-core)
endif()
add_subdirectory(gdb-remote)
add_subdirectory(Utility)
add_subdirectory(elf-core)
+add_subdirectory(mach-core)
add_subdirectory(minidump)
diff --git a/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/CMakeLists.txt b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/CMakeLists.txt
new file mode 100644
index 00000000000..4eb5697ab83
--- /dev/null
+++ b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/CMakeLists.txt
@@ -0,0 +1,17 @@
+add_lldb_library(lldbPluginProcessOpenBSD PLUGIN
+ NativeProcessOpenBSD.cpp
+ NativeRegisterContextOpenBSD.cpp
+ NativeRegisterContextOpenBSD_x86_64.cpp
+ NativeThreadOpenBSD.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbHost
+ lldbSymbol
+ lldbTarget
+ lldbUtility
+ lldbPluginProcessPOSIX
+ lldbPluginProcessUtility
+ LINK_COMPONENTS
+ Support
+ )
diff --git a/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp
new file mode 100644
index 00000000000..eeb05cfa495
--- /dev/null
+++ b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.cpp
@@ -0,0 +1,576 @@
+//===-- NativeProcessOpenBSD.cpp ------------------------------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeProcessOpenBSD.h"
+
+// C Includes
+#include <errno.h>
+#define _DYN_LOADER
+#include <elf.h>
+#include <util.h>
+
+// C++ Includes
+
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Host/common/NativeRegisterContext.h"
+#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
+#include "llvm/Support/Errno.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/State.h"
+
+// System includes - They have to be included after framework includes because
+// they define some macros which collide with variable names in other modules
+// clang-format off
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+// clang-format on
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_openbsd;
+using namespace llvm;
+
+// Simple helper function to ensure flags are enabled on the given file
+// descriptor.
+static Status EnsureFDFlags(int fd, int flags) {
+ Status error;
+
+ int status = fcntl(fd, F_GETFL);
+ if (status == -1) {
+ error.SetErrorToErrno();
+ return error;
+ }
+
+ if (fcntl(fd, F_SETFL, status | flags) == -1) {
+ error.SetErrorToErrno();
+ return error;
+ }
+
+ return error;
+}
+
+// -----------------------------------------------------------------------------
+// Public Static Methods
+// -----------------------------------------------------------------------------
+
+llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
+NativeProcessOpenBSD::Factory::Launch(ProcessLaunchInfo &launch_info,
+ NativeDelegate &native_delegate,
+ MainLoop &mainloop) const {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+
+ Status status;
+ ::pid_t pid = ProcessLauncherPosixFork()
+ .LaunchProcess(launch_info, status)
+ .GetProcessId();
+ LLDB_LOG(log, "pid = {0:x}", pid);
+ if (status.Fail()) {
+ LLDB_LOG(log, "failed to launch process: {0}", status);
+ return status.ToError();
+ }
+
+ // Wait for the child process to trap on its call to execve.
+ int wstatus;
+ ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
+ assert(wpid == pid);
+ (void)wpid;
+ if (!WIFSTOPPED(wstatus)) {
+ LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",
+ WaitStatus::Decode(wstatus));
+ return llvm::make_error<StringError>("Could not sync with inferior process",
+ llvm::inconvertibleErrorCode());
+ }
+ LLDB_LOG(log, "inferior started, now in stopped state");
+
+ ProcessInstanceInfo Info;
+ if (!Host::GetProcessInfo(pid, Info)) {
+ return llvm::make_error<StringError>("Cannot get process architecture",
+ llvm::inconvertibleErrorCode());
+ }
+
+ // Set the architecture to the exe architecture.
+ LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
+ Info.GetArchitecture().GetArchitectureName());
+
+ std::unique_ptr<NativeProcessOpenBSD> process_up(new NativeProcessOpenBSD(
+ pid, launch_info.GetPTY().ReleaseMasterFileDescriptor(), native_delegate,
+ Info.GetArchitecture(), mainloop));
+
+ status = process_up->ReinitializeThreads();
+ if (status.Fail())
+ return status.ToError();
+
+ for (const auto &thread : process_up->m_threads)
+ static_cast<NativeThreadOpenBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
+ process_up->SetState(StateType::eStateStopped, false);
+
+ return std::move(process_up);
+}
+
+llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
+NativeProcessOpenBSD::Factory::Attach(
+ lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
+ MainLoop &mainloop) const {
+
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ LLDB_LOG(log, "pid = {0:x}", pid);
+
+ // Retrieve the architecture for the running process.
+ ProcessInstanceInfo Info;
+ if (!Host::GetProcessInfo(pid, Info)) {
+ return llvm::make_error<StringError>("Cannot get process architecture",
+ llvm::inconvertibleErrorCode());
+ }
+
+ std::unique_ptr<NativeProcessOpenBSD> process_up(new NativeProcessOpenBSD(
+ pid, -1, native_delegate, Info.GetArchitecture(), mainloop));
+
+ Status status = process_up->Attach();
+ if (!status.Success())
+ return status.ToError();
+
+ return std::move(process_up);
+}
+
+// -----------------------------------------------------------------------------
+// Public Instance Methods
+// -----------------------------------------------------------------------------
+
+NativeProcessOpenBSD::NativeProcessOpenBSD(::pid_t pid, int terminal_fd,
+ NativeDelegate &delegate,
+ const ArchSpec &arch,
+ MainLoop &mainloop)
+ : NativeProcessProtocol(pid, terminal_fd, delegate), m_arch(arch) {
+ if (m_terminal_fd != -1) {
+ Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
+ assert(status.Success());
+ }
+
+ Status status;
+ m_sigchld_handle = mainloop.RegisterSignal(
+ SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status);
+ assert(m_sigchld_handle && status.Success());
+}
+
+// Handles all waitpid events from the inferior process.
+void NativeProcessOpenBSD::MonitorCallback(lldb::pid_t pid, int signal) {
+ switch (signal) {
+ case SIGTRAP:
+ return MonitorSIGTRAP(pid);
+ default:
+ return MonitorSignal(pid, signal);
+ }
+}
+
+void NativeProcessOpenBSD::MonitorExited(lldb::pid_t pid, WaitStatus status) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+
+ LLDB_LOG(log, "got exit signal({0}) , pid = {1}", status, pid);
+
+ /* Stop Tracking All Threads attached to Process */
+ m_threads.clear();
+
+ SetExitStatus(status, true);
+
+ // Notify delegate that our process has exited.
+ SetState(StateType::eStateExited, true);
+}
+
+void NativeProcessOpenBSD::MonitorSIGTRAP(lldb::pid_t pid) {
+ for (const auto &thread : m_threads) {
+ static_cast<NativeThreadOpenBSD &>(*thread).SetStoppedByBreakpoint();
+ FixupBreakpointPCAsNeeded(static_cast<NativeThreadOpenBSD &>(*thread));
+ }
+ SetState(StateType::eStateStopped, true);
+}
+
+
+void NativeProcessOpenBSD::MonitorSignal(lldb::pid_t pid, int signal) {
+ for (const auto &thread : m_threads) {
+ static_cast<NativeThreadOpenBSD &>(*thread).SetStoppedBySignal(signal);
+ }
+ SetState(StateType::eStateStopped, true);
+}
+
+Status NativeProcessOpenBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr,
+ int data, int *result) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
+ Status error;
+ int ret;
+
+ errno = 0;
+ ret = ptrace(req, static_cast<::pid_t>(pid), (caddr_t)addr, data);
+
+ if (ret == -1)
+ error.SetErrorToErrno();
+
+ if (result)
+ *result = ret;
+
+ LLDB_LOG(log, "ptrace({0}, {1}, {2}, {3})={4:x}", req, pid, addr, data, ret);
+
+ if (error.Fail())
+ LLDB_LOG(log, "ptrace() failed: {0}", error);
+
+ return error;
+}
+
+Status NativeProcessOpenBSD::Resume(const ResumeActionList &resume_actions) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ LLDB_LOG(log, "pid {0}", GetID());
+
+ const auto &thread = m_threads[0];
+ const ResumeAction *const action =
+ resume_actions.GetActionForThread(thread->GetID(), true);
+
+ if (action == nullptr) {
+ LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(),
+ thread->GetID());
+ return Status();
+ }
+
+ Status error;
+
+ switch (action->state) {
+ case eStateRunning: {
+ // Run the thread, possibly feeding it the signal.
+ error = NativeProcessOpenBSD::PtraceWrapper(PT_CONTINUE, GetID(), (void *)1,
+ action->signal);
+ if (!error.Success())
+ return error;
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadOpenBSD &>(*thread).SetRunning();
+ SetState(eStateRunning, true);
+ break;
+ }
+ case eStateStepping:
+ // Run the thread, possibly feeding it the signal.
+ error = NativeProcessOpenBSD::PtraceWrapper(PT_STEP, GetID(), (void *)1,
+ action->signal);
+ if (!error.Success())
+ return error;
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadOpenBSD &>(*thread).SetStepping();
+ SetState(eStateStepping, true);
+ break;
+
+ case eStateSuspended:
+ case eStateStopped:
+ llvm_unreachable("Unexpected state");
+
+ default:
+ return Status("NativeProcessOpenBSD::%s (): unexpected state %s specified "
+ "for pid %" PRIu64 ", tid %" PRIu64,
+ __FUNCTION__, StateAsCString(action->state), GetID(),
+ thread->GetID());
+ }
+
+ return Status();
+}
+
+Status NativeProcessOpenBSD::Halt() {
+ Status error;
+
+ if (kill(GetID(), SIGSTOP) != 0)
+ error.SetErrorToErrno();
+
+ return error;
+}
+
+Status NativeProcessOpenBSD::Detach() {
+ Status error;
+
+ // Stop monitoring the inferior.
+ m_sigchld_handle.reset();
+
+ // Tell ptrace to detach from the process.
+ if (GetID() == LLDB_INVALID_PROCESS_ID)
+ return error;
+
+ return PtraceWrapper(PT_DETACH, GetID());
+}
+
+Status NativeProcessOpenBSD::Signal(int signo) {
+ Status error;
+
+ if (kill(GetID(), signo))
+ error.SetErrorToErrno();
+
+ return error;
+}
+
+Status NativeProcessOpenBSD::Kill() {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ LLDB_LOG(log, "pid {0}", GetID());
+
+ Status error;
+
+ switch (m_state) {
+ case StateType::eStateInvalid:
+ case StateType::eStateExited:
+ case StateType::eStateCrashed:
+ case StateType::eStateDetached:
+ case StateType::eStateUnloaded:
+ // Nothing to do - the process is already dead.
+ LLDB_LOG(log, "ignored for PID {0} due to current state: {1}", GetID(),
+ StateAsCString(m_state));
+ return error;
+
+ case StateType::eStateConnected:
+ case StateType::eStateAttaching:
+ case StateType::eStateLaunching:
+ case StateType::eStateStopped:
+ case StateType::eStateRunning:
+ case StateType::eStateStepping:
+ case StateType::eStateSuspended:
+ // We can try to kill a process in these states.
+ break;
+ }
+
+ if (kill(GetID(), SIGKILL) != 0) {
+ error.SetErrorToErrno();
+ return error;
+ }
+
+ return error;
+}
+
+Status NativeProcessOpenBSD::GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) {
+ return Status("Unimplemented");
+}
+
+Status NativeProcessOpenBSD::PopulateMemoryRegionCache() {
+ return Status("Unimplemented");
+}
+
+Status NativeProcessOpenBSD::AllocateMemory(size_t size, uint32_t permissions,
+ lldb::addr_t &addr) {
+ return Status("Unimplemented");
+}
+
+Status NativeProcessOpenBSD::DeallocateMemory(lldb::addr_t addr) {
+ return Status("Unimplemented");
+}
+
+lldb::addr_t NativeProcessOpenBSD::GetSharedLibraryInfoAddress() {
+ // punt on this for now
+ return LLDB_INVALID_ADDRESS;
+}
+
+size_t NativeProcessOpenBSD::UpdateThreads() { return m_threads.size(); }
+
+Status NativeProcessOpenBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size,
+ bool hardware) {
+ if (hardware)
+ return Status("NativeProcessOpenBSD does not support hardware breakpoints");
+ else
+ return SetSoftwareBreakpoint(addr, size);
+}
+
+Status NativeProcessOpenBSD::GetLoadedModuleFileSpec(const char *module_path,
+ FileSpec &file_spec) {
+ return Status("Unimplemented");
+}
+
+Status NativeProcessOpenBSD::GetFileLoadAddress(const llvm::StringRef &file_name,
+ lldb::addr_t &load_addr) {
+ load_addr = LLDB_INVALID_ADDRESS;
+ return Status();
+}
+
+void NativeProcessOpenBSD::SigchldHandler() {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ // Process all pending waitpid notifications.
+ int status;
+ ::pid_t wait_pid =
+ llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status, WNOHANG);
+
+ if (wait_pid == 0)
+ return; // We are done.
+
+ if (wait_pid == -1) {
+ Status error(errno, eErrorTypePOSIX);
+ LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error);
+ }
+
+ WaitStatus wait_status = WaitStatus::Decode(status);
+ bool exited = wait_status.type == WaitStatus::Exit ||
+ (wait_status.type == WaitStatus::Signal &&
+ wait_pid == static_cast<::pid_t>(GetID()));
+
+ LLDB_LOG(log,
+ "waitpid ({0}, &status, _) => pid = {1}, status = {2}, exited = {3}",
+ GetID(), wait_pid, status, exited);
+
+ if (exited)
+ MonitorExited(wait_pid, wait_status);
+ else {
+ assert(wait_status.type == WaitStatus::Stop);
+ MonitorCallback(wait_pid, wait_status.status);
+ }
+}
+
+bool NativeProcessOpenBSD::HasThreadNoLock(lldb::tid_t thread_id) {
+ for (const auto &thread : m_threads) {
+ assert(thread && "thread list should not contain NULL threads");
+ if (thread->GetID() == thread_id) {
+ // We have this thread.
+ return true;
+ }
+ }
+
+ // We don't have this thread.
+ return false;
+}
+
+NativeThreadOpenBSD &NativeProcessOpenBSD::AddThread(lldb::tid_t thread_id) {
+
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id);
+
+ assert(!HasThreadNoLock(thread_id) &&
+ "attempted to add a thread by id that already exists");
+
+ // If this is the first thread, save it as the current thread
+ if (m_threads.empty())
+ SetCurrentThreadID(thread_id);
+
+ m_threads.push_back(llvm::make_unique<NativeThreadOpenBSD>(*this, thread_id));
+ return static_cast<NativeThreadOpenBSD &>(*m_threads.back());
+}
+
+Status NativeProcessOpenBSD::Attach() {
+ // Attach to the requested process.
+ // An attach will cause the thread to stop with a SIGSTOP.
+ Status status = PtraceWrapper(PT_ATTACH, m_pid);
+ if (status.Fail())
+ return status;
+
+ int wstatus;
+ // At this point we should have a thread stopped if waitpid succeeds.
+ if ((wstatus = waitpid(m_pid, NULL, 0)) < 0)
+ return Status(errno, eErrorTypePOSIX);
+
+ /* Initialize threads */
+ status = ReinitializeThreads();
+ if (status.Fail())
+ return status;
+
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadOpenBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
+
+ // Let our process instance know the thread has stopped.
+ SetState(StateType::eStateStopped);
+ return Status();
+}
+
+Status NativeProcessOpenBSD::ReadMemory(lldb::addr_t addr, void *buf,
+ size_t size, size_t &bytes_read) {
+ unsigned char *dst = static_cast<unsigned char *>(buf);
+ struct ptrace_io_desc io;
+
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
+ LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
+
+ bytes_read = 0;
+ io.piod_op = PIOD_READ_D;
+ io.piod_len = size;
+
+ do {
+ io.piod_offs = (void *)(addr + bytes_read);
+ io.piod_addr = dst + bytes_read;
+
+ Status error = NativeProcessOpenBSD::PtraceWrapper(PT_IO, GetID(), &io);
+ if (error.Fail())
+ return error;
+
+ bytes_read = io.piod_len;
+ io.piod_len = size - bytes_read;
+ } while (bytes_read < size);
+
+ return Status();
+}
+
+Status NativeProcessOpenBSD::WriteMemory(lldb::addr_t addr, const void *buf,
+ size_t size, size_t &bytes_written) {
+ const unsigned char *src = static_cast<const unsigned char *>(buf);
+ Status error;
+ struct ptrace_io_desc io;
+
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
+ LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
+
+ bytes_written = 0;
+ io.piod_op = PIOD_WRITE_D;
+ io.piod_len = size;
+
+ do {
+ io.piod_addr = const_cast<void *>(static_cast<const void *>(src + bytes_written));
+ io.piod_offs = (void *)(addr + bytes_written);
+
+ Status error = NativeProcessOpenBSD::PtraceWrapper(PT_IO, GetID(), &io);
+ if (error.Fail())
+ return error;
+
+ bytes_written = io.piod_len;
+ io.piod_len = size - bytes_written;
+ } while (bytes_written < size);
+
+ return error;
+}
+
+llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
+NativeProcessOpenBSD::GetAuxvData() const {
+ size_t auxv_size = 100 * sizeof(AuxInfo);
+
+ ErrorOr<std::unique_ptr<WritableMemoryBuffer>> buf =
+ llvm::WritableMemoryBuffer::getNewMemBuffer(auxv_size);
+
+ struct ptrace_io_desc io;
+ io.piod_op = PIOD_READ_AUXV;
+ io.piod_offs = 0;
+ io.piod_addr = static_cast<void *>(buf.get()->getBufferStart());
+ io.piod_len = auxv_size;
+
+ Status error = NativeProcessOpenBSD::PtraceWrapper(PT_IO, GetID(), &io);
+
+ if (error.Fail())
+ return std::error_code(error.GetError(), std::generic_category());
+
+ if (io.piod_len < 1)
+ return std::error_code(ECANCELED, std::generic_category());
+
+ return std::move(buf);
+}
+
+Status NativeProcessOpenBSD::ReinitializeThreads() {
+ // Clear old threads
+ m_threads.clear();
+
+ // Initialize new thread
+ struct ptrace_thread_state info = {};
+ Status error = PtraceWrapper(PT_GET_THREAD_FIRST, GetID(), &info, sizeof(info));
+ if (error.Fail()) {
+ return error;
+ }
+ // Reinitialize from scratch threads and register them in process
+ while (info.pts_tid > 0) {
+ AddThread(info.pts_tid);
+ error = PtraceWrapper(PT_GET_THREAD_NEXT, GetID(), &info, sizeof(info));
+ if (error.Fail() && errno != 0) {
+ return error;
+ }
+ }
+
+ return error;
+}
diff --git a/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.h b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.h
new file mode 100644
index 00000000000..5aeb131e18e
--- /dev/null
+++ b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeProcessOpenBSD.h
@@ -0,0 +1,123 @@
+//===-- NativeProcessOpenBSD.h --------------------------------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_NativeProcessOpenBSD_H_
+#define liblldb_NativeProcessOpenBSD_H_
+
+#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/FileSpec.h"
+
+#include "NativeThreadOpenBSD.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
+
+namespace lldb_private {
+namespace process_openbsd {
+/// @class NativeProcessOpenBSD
+/// Manages communication with the inferior (debugee) process.
+///
+/// Upon construction, this class prepares and launches an inferior process
+/// for debugging.
+///
+/// Changes in the inferior process state are broadcasted.
+class NativeProcessOpenBSD : public NativeProcessProtocol {
+public:
+ class Factory : public NativeProcessProtocol::Factory {
+ public:
+ llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
+ Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
+ MainLoop &mainloop) const override;
+
+ llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
+ Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
+ MainLoop &mainloop) const override;
+ };
+
+ // ---------------------------------------------------------------------
+ // NativeProcessProtocol Interface
+ // ---------------------------------------------------------------------
+ Status Resume(const ResumeActionList &resume_actions) override;
+
+ Status Halt() override;
+
+ Status Detach() override;
+
+ Status Signal(int signo) override;
+
+ Status Kill() override;
+
+ Status GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) override;
+
+ Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ size_t &bytes_read) override;
+
+ Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
+ size_t &bytes_written) override;
+
+ Status AllocateMemory(size_t size, uint32_t permissions,
+ lldb::addr_t &addr) override;
+
+ Status DeallocateMemory(lldb::addr_t addr) override;
+
+ lldb::addr_t GetSharedLibraryInfoAddress() override;
+
+ size_t UpdateThreads() override;
+
+ const ArchSpec &GetArchitecture() const override { return m_arch; }
+
+ Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
+ bool hardware) override;
+
+ Status GetLoadedModuleFileSpec(const char *module_path,
+ FileSpec &file_spec) override;
+
+ Status GetFileLoadAddress(const llvm::StringRef &file_name,
+ lldb::addr_t &load_addr) override;
+
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
+ GetAuxvData() const override;
+
+ // ---------------------------------------------------------------------
+ // Interface used by NativeRegisterContext-derived classes.
+ // ---------------------------------------------------------------------
+ static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
+ int data = 0, int *result = nullptr);
+
+private:
+ MainLoop::SignalHandleUP m_sigchld_handle;
+ ArchSpec m_arch;
+ std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
+
+ // ---------------------------------------------------------------------
+ // Private Instance Methods
+ // ---------------------------------------------------------------------
+ NativeProcessOpenBSD(::pid_t pid, int terminal_fd, NativeDelegate &delegate,
+ const ArchSpec &arch, MainLoop &mainloop);
+
+ bool HasThreadNoLock(lldb::tid_t thread_id);
+
+ NativeThreadOpenBSD &AddThread(lldb::tid_t thread_id);
+
+ void MonitorCallback(lldb::pid_t pid, int signal);
+ void MonitorExited(lldb::pid_t pid, WaitStatus status);
+ void MonitorSIGTRAP(lldb::pid_t pid);
+ void MonitorSignal(lldb::pid_t pid, int signal);
+
+ Status PopulateMemoryRegionCache();
+ void SigchldHandler();
+
+ Status Attach();
+ Status ReinitializeThreads();
+};
+
+} // namespace process_openbsd
+} // namespace lldb_private
+
+#endif // #ifndef liblldb_NativeProcessOpenBSD_H_
diff --git a/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD.cpp b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD.cpp
new file mode 100644
index 00000000000..fb70b028e3d
--- /dev/null
+++ b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD.cpp
@@ -0,0 +1,86 @@
+//===-- NativeRegisterContextOpenBSD.cpp -------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeRegisterContextOpenBSD.h"
+
+#include "lldb/Host/common/NativeProcessProtocol.h"
+
+using namespace lldb_private;
+using namespace lldb_private::process_openbsd;
+
+// clang-format off
+#include <sys/types.h>
+#include <sys/ptrace.h>
+// clang-format on
+
+NativeRegisterContextOpenBSD::NativeRegisterContextOpenBSD(
+ NativeThreadProtocol &native_thread,
+ RegisterInfoInterface *reg_info_interface_p)
+ : NativeRegisterContextRegisterInfo(native_thread,
+ reg_info_interface_p) {}
+
+Status NativeRegisterContextOpenBSD::ReadGPR() {
+ void *buf = GetGPRBuffer();
+ if (!buf)
+ return Status("GPR buffer is NULL");
+
+ return DoReadGPR(buf);
+}
+
+Status NativeRegisterContextOpenBSD::WriteGPR() {
+ void *buf = GetGPRBuffer();
+ if (!buf)
+ return Status("GPR buffer is NULL");
+
+ return DoWriteGPR(buf);
+}
+
+Status NativeRegisterContextOpenBSD::ReadFPR() {
+ void *buf = GetFPRBuffer();
+ if (!buf)
+ return Status("FPR buffer is NULL");
+
+ return DoReadFPR(buf);
+}
+
+Status NativeRegisterContextOpenBSD::WriteFPR() {
+ void *buf = GetFPRBuffer();
+ if (!buf)
+ return Status("FPR buffer is NULL");
+
+ return DoWriteFPR(buf);
+}
+
+Status NativeRegisterContextOpenBSD::DoReadGPR(void *buf) {
+ return NativeProcessOpenBSD::PtraceWrapper(PT_GETREGS, GetProcessPid(), buf,
+ m_thread.GetID());
+}
+
+Status NativeRegisterContextOpenBSD::DoWriteGPR(void *buf) {
+ return NativeProcessOpenBSD::PtraceWrapper(PT_SETREGS, GetProcessPid(), buf,
+ m_thread.GetID());
+}
+
+Status NativeRegisterContextOpenBSD::DoReadFPR(void *buf) {
+ return NativeProcessOpenBSD::PtraceWrapper(PT_GETFPREGS, GetProcessPid(), buf,
+ m_thread.GetID());
+}
+
+Status NativeRegisterContextOpenBSD::DoWriteFPR(void *buf) {
+ return NativeProcessOpenBSD::PtraceWrapper(PT_SETFPREGS, GetProcessPid(), buf,
+ m_thread.GetID());
+}
+
+NativeProcessOpenBSD &NativeRegisterContextOpenBSD::GetProcess() {
+ return static_cast<NativeProcessOpenBSD &>(m_thread.GetProcess());
+}
+
+::pid_t NativeRegisterContextOpenBSD::GetProcessPid() {
+ return GetProcess().GetID();
+}
diff --git a/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD.h b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD.h
new file mode 100644
index 00000000000..013fe893fc1
--- /dev/null
+++ b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD.h
@@ -0,0 +1,63 @@
+//===-- NativeRegisterContextOpenBSD.h ---------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_NativeRegisterContextOpenBSD_h
+#define lldb_NativeRegisterContextOpenBSD_h
+
+#include "lldb/Host/common/NativeThreadProtocol.h"
+
+#include "Plugins/Process/OpenBSD/NativeProcessOpenBSD.h"
+#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"
+
+namespace lldb_private {
+namespace process_openbsd {
+
+class NativeRegisterContextOpenBSD : public NativeRegisterContextRegisterInfo {
+public:
+ NativeRegisterContextOpenBSD(NativeThreadProtocol &native_thread,
+ RegisterInfoInterface *reg_info_interface_p);
+
+ // This function is implemented in the NativeRegisterContextOpenBSD_*
+ // subclasses to create a new instance of the host specific
+ // NativeRegisterContextOpenBSD. The implementations can't collide as only one
+ // NativeRegisterContextOpenBSD_* variant should be compiled into the final
+ // executable.
+ static NativeRegisterContextOpenBSD *
+ CreateHostNativeRegisterContextOpenBSD(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread);
+
+protected:
+ virtual Status ReadGPR();
+ virtual Status WriteGPR();
+
+ virtual Status ReadFPR();
+ virtual Status WriteFPR();
+
+ virtual void *GetGPRBuffer() { return nullptr; }
+ virtual size_t GetGPRSize() {
+ return GetRegisterInfoInterface().GetGPRSize();
+ }
+
+ virtual void *GetFPRBuffer() { return nullptr; }
+ virtual size_t GetFPRSize() { return 0; }
+
+ virtual Status DoReadGPR(void *buf);
+ virtual Status DoWriteGPR(void *buf);
+
+ virtual Status DoReadFPR(void *buf);
+ virtual Status DoWriteFPR(void *buf);
+
+ virtual NativeProcessOpenBSD &GetProcess();
+ virtual ::pid_t GetProcessPid();
+};
+
+} // namespace process_openbsd
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextOpenBSD_h
diff --git a/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_x86_64.cpp b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_x86_64.cpp
new file mode 100644
index 00000000000..c6102fd38e4
--- /dev/null
+++ b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_x86_64.cpp
@@ -0,0 +1,861 @@
+//===-- NativeRegisterContextOpenBSD_x86_64.cpp ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__x86_64__)
+
+#include <elf.h>
+#include <err.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "NativeRegisterContextOpenBSD_x86_64.h"
+
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Status.h"
+
+#include "Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h"
+
+// clang-format off
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <machine/cpu.h>
+// clang-format on
+
+using namespace lldb_private;
+using namespace lldb_private::process_openbsd;
+
+// ----------------------------------------------------------------------------
+// Private namespace.
+// ----------------------------------------------------------------------------
+
+namespace {
+// x86 64-bit general purpose registers.
+static const uint32_t g_gpr_regnums_x86_64[] = {
+ lldb_rax_x86_64, lldb_rbx_x86_64, lldb_rcx_x86_64, lldb_rdx_x86_64,
+ lldb_rdi_x86_64, lldb_rsi_x86_64, lldb_rbp_x86_64, lldb_rsp_x86_64,
+ lldb_r8_x86_64, lldb_r9_x86_64, lldb_r10_x86_64, lldb_r11_x86_64,
+ lldb_r12_x86_64, lldb_r13_x86_64, lldb_r14_x86_64, lldb_r15_x86_64,
+ lldb_rip_x86_64, lldb_rflags_x86_64, lldb_cs_x86_64, lldb_fs_x86_64,
+ lldb_gs_x86_64, lldb_ss_x86_64, lldb_ds_x86_64, lldb_es_x86_64,
+ lldb_eax_x86_64, lldb_ebx_x86_64, lldb_ecx_x86_64, lldb_edx_x86_64,
+ lldb_edi_x86_64, lldb_esi_x86_64, lldb_ebp_x86_64, lldb_esp_x86_64,
+ lldb_r8d_x86_64, // Low 32 bits or r8
+ lldb_r9d_x86_64, // Low 32 bits or r9
+ lldb_r10d_x86_64, // Low 32 bits or r10
+ lldb_r11d_x86_64, // Low 32 bits or r11
+ lldb_r12d_x86_64, // Low 32 bits or r12
+ lldb_r13d_x86_64, // Low 32 bits or r13
+ lldb_r14d_x86_64, // Low 32 bits or r14
+ lldb_r15d_x86_64, // Low 32 bits or r15
+ lldb_ax_x86_64, lldb_bx_x86_64, lldb_cx_x86_64, lldb_dx_x86_64,
+ lldb_di_x86_64, lldb_si_x86_64, lldb_bp_x86_64, lldb_sp_x86_64,
+ lldb_r8w_x86_64, // Low 16 bits or r8
+ lldb_r9w_x86_64, // Low 16 bits or r9
+ lldb_r10w_x86_64, // Low 16 bits or r10
+ lldb_r11w_x86_64, // Low 16 bits or r11
+ lldb_r12w_x86_64, // Low 16 bits or r12
+ lldb_r13w_x86_64, // Low 16 bits or r13
+ lldb_r14w_x86_64, // Low 16 bits or r14
+ lldb_r15w_x86_64, // Low 16 bits or r15
+ lldb_ah_x86_64, lldb_bh_x86_64, lldb_ch_x86_64, lldb_dh_x86_64,
+ lldb_al_x86_64, lldb_bl_x86_64, lldb_cl_x86_64, lldb_dl_x86_64,
+ lldb_dil_x86_64, lldb_sil_x86_64, lldb_bpl_x86_64, lldb_spl_x86_64,
+ lldb_r8l_x86_64, // Low 8 bits or r8
+ lldb_r9l_x86_64, // Low 8 bits or r9
+ lldb_r10l_x86_64, // Low 8 bits or r10
+ lldb_r11l_x86_64, // Low 8 bits or r11
+ lldb_r12l_x86_64, // Low 8 bits or r12
+ lldb_r13l_x86_64, // Low 8 bits or r13
+ lldb_r14l_x86_64, // Low 8 bits or r14
+ lldb_r15l_x86_64, // Low 8 bits or r15
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
+ 1 ==
+ k_num_gpr_registers_x86_64,
+ "g_gpr_regnums_x86_64 has wrong number of register infos");
+
+// Number of register sets provided by this context.
+enum { k_num_extended_register_sets = 2, k_num_register_sets = 4 };
+
+// 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,
+ g_gpr_regnums_x86_64},
+};
+
+#define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize())
+
+} // namespace
+
+NativeRegisterContextOpenBSD *
+NativeRegisterContextOpenBSD::CreateHostNativeRegisterContextOpenBSD(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return new NativeRegisterContextOpenBSD_x86_64(target_arch, native_thread);
+}
+
+// ----------------------------------------------------------------------------
+// NativeRegisterContextOpenBSD_x86_64 members.
+// ----------------------------------------------------------------------------
+
+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 RegisterContextOpenBSD_x86_64(target_arch);
+}
+
+NativeRegisterContextOpenBSD_x86_64::NativeRegisterContextOpenBSD_x86_64(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextOpenBSD(native_thread,
+ CreateRegisterInfoInterface(target_arch)),
+ m_gpr_x86_64(), m_fpr_x86_64() {}
+
+// CONSIDER after local and llgs debugging are merged, register set support can
+// be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.
+uint32_t NativeRegisterContextOpenBSD_x86_64::GetRegisterSetCount() const {
+ uint32_t sets = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
+ if (GetSetForNativeRegNum(set_index) != -1)
+ ++sets;
+ }
+
+ return sets;
+}
+
+const RegisterSet *
+NativeRegisterContextOpenBSD_x86_64::GetRegisterSet(uint32_t set_index) const {
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::x86_64:
+ return &g_reg_sets_x86_64[set_index];
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
+
+ return nullptr;
+}
+
+int NativeRegisterContextOpenBSD_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 -1; // 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 -1; // DBR
+ else
+ return -1;
+}
+
+int NativeRegisterContextOpenBSD_x86_64::ReadRegisterSet(uint32_t set) {
+ switch (set) {
+ case GPRegSet:
+ ReadGPR();
+ return 0;
+ case FPRegSet:
+ ReadFPR();
+ return 0;
+ default:
+ break;
+ }
+ return -1;
+}
+int NativeRegisterContextOpenBSD_x86_64::WriteRegisterSet(uint32_t set) {
+ switch (set) {
+ case GPRegSet:
+ WriteGPR();
+ return 0;
+ case FPRegSet:
+ WriteFPR();
+ return 0;
+ default:
+ break;
+ }
+ return -1;
+}
+
+Status
+NativeRegisterContextOpenBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ Status error;
+
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
+
+ const 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.
+ error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
+ "register, cannot read directly",
+ reg_info->name);
+ return error;
+ }
+
+ int set = GetSetForNativeRegNum(reg);
+ if (set == -1) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
+ reg_info->name);
+ return error;
+ }
+
+ if (ReadRegisterSet(set) != 0) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat(
+ "reading register set for register \"%s\" failed", reg_info->name);
+ return error;
+ }
+
+ switch (reg) {
+ case lldb_rax_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_rax;
+ break;
+ case lldb_rbx_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_rbx;
+ break;
+ case lldb_rcx_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_rcx;
+ break;
+ case lldb_rdx_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_rdx;
+ break;
+ case lldb_rdi_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_rdi;
+ break;
+ case lldb_rsi_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_rsi;
+ break;
+ case lldb_rbp_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_rbp;
+ break;
+ case lldb_rsp_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_rsp;
+ break;
+ case lldb_r8_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_r8;
+ break;
+ case lldb_r9_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_r9;
+ break;
+ case lldb_r10_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_r10;
+ break;
+ case lldb_r11_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_r11;
+ break;
+ case lldb_r12_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_r12;
+ break;
+ case lldb_r13_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_r13;
+ break;
+ case lldb_r14_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_r14;
+ break;
+ case lldb_r15_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_r15;
+ break;
+ case lldb_rip_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_rip;
+ break;
+ case lldb_rflags_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_rflags;
+ break;
+ case lldb_cs_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_cs;
+ break;
+ case lldb_fs_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_fs;
+ break;
+ case lldb_gs_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_gs;
+ break;
+ case lldb_ss_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_ss;
+ break;
+ case lldb_ds_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_ds;
+ break;
+ case lldb_es_x86_64:
+ reg_value = (uint64_t)m_gpr_x86_64.r_es;
+ break;
+ case lldb_fctrl_x86_64:
+ reg_value = (uint16_t)m_fpr_x86_64.fxstate.fx_fcw;
+ break;
+ case lldb_fstat_x86_64:
+ reg_value = (uint16_t)m_fpr_x86_64.fxstate.fx_fsw;
+ break;
+ case lldb_ftag_x86_64:
+ reg_value = (uint8_t)m_fpr_x86_64.fxstate.fx_ftw;
+ break;
+ case lldb_fop_x86_64:
+ reg_value = (uint64_t)m_fpr_x86_64.fxstate.fx_fop;
+ break;
+ case lldb_fiseg_x86_64:
+ reg_value = (uint64_t)m_fpr_x86_64.fxstate.fx_rip;
+ break;
+ case lldb_fioff_x86_64:
+ reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_rip;
+ break;
+ case lldb_foseg_x86_64:
+ reg_value = (uint64_t)m_fpr_x86_64.fxstate.fx_rdp;
+ break;
+ case lldb_fooff_x86_64:
+ reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_rdp;
+ break;
+ case lldb_mxcsr_x86_64:
+ reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_mxcsr;
+ break;
+ case lldb_mxcsrmask_x86_64:
+ reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_mxcsr_mask;
+ break;
+ case lldb_st0_x86_64:
+ case lldb_st1_x86_64:
+ case lldb_st2_x86_64:
+ case lldb_st3_x86_64:
+ case lldb_st4_x86_64:
+ case lldb_st5_x86_64:
+ case lldb_st6_x86_64:
+ case lldb_st7_x86_64:
+ reg_value.SetBytes(&m_fpr_x86_64.fxstate.fx_st[reg - lldb_st0_x86_64],
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_mm0_x86_64:
+ case lldb_mm1_x86_64:
+ case lldb_mm2_x86_64:
+ case lldb_mm3_x86_64:
+ case lldb_mm4_x86_64:
+ case lldb_mm5_x86_64:
+ case lldb_mm6_x86_64:
+ case lldb_mm7_x86_64:
+ reg_value.SetBytes(&m_fpr_x86_64.fxstate.fx_xmm[reg - lldb_mm0_x86_64],
+ reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ case lldb_xmm0_x86_64:
+ case lldb_xmm1_x86_64:
+ case lldb_xmm2_x86_64:
+ case lldb_xmm3_x86_64:
+ case lldb_xmm4_x86_64:
+ case lldb_xmm5_x86_64:
+ case lldb_xmm6_x86_64:
+ case lldb_xmm7_x86_64:
+ case lldb_xmm8_x86_64:
+ case lldb_xmm9_x86_64:
+ case lldb_xmm10_x86_64:
+ case lldb_xmm11_x86_64:
+ case lldb_xmm12_x86_64:
+ 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_info->byte_size, endian::InlHostByteOrder());
+ break;
+ }
+
+ return error;
+}
+
+Status NativeRegisterContextOpenBSD_x86_64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+
+ Status error;
+
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
+
+ const 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.
+ error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
+ "register, cannot read directly",
+ reg_info->name);
+ return error;
+ }
+
+ int set = GetSetForNativeRegNum(reg);
+ if (set == -1) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
+ reg_info->name);
+ return error;
+ }
+
+ if (ReadRegisterSet(set) != 0) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat(
+ "reading register set for register \"%s\" failed", reg_info->name);
+ return error;
+ }
+
+ switch (reg) {
+ case lldb_rax_x86_64:
+ m_gpr_x86_64.r_rax = reg_value.GetAsUInt64();
+ break;
+ case lldb_rbx_x86_64:
+ m_gpr_x86_64.r_rbx = reg_value.GetAsUInt64();
+ break;
+ case lldb_rcx_x86_64:
+ m_gpr_x86_64.r_rcx = reg_value.GetAsUInt64();
+ break;
+ case lldb_rdx_x86_64:
+ m_gpr_x86_64.r_rdx = reg_value.GetAsUInt64();
+ break;
+ case lldb_rdi_x86_64:
+ m_gpr_x86_64.r_rdi = reg_value.GetAsUInt64();
+ break;
+ case lldb_rsi_x86_64:
+ m_gpr_x86_64.r_rsi = reg_value.GetAsUInt64();
+ break;
+ case lldb_rbp_x86_64:
+ m_gpr_x86_64.r_rbp = reg_value.GetAsUInt64();
+ break;
+ case lldb_rsp_x86_64:
+ m_gpr_x86_64.r_rsp = reg_value.GetAsUInt64();
+ break;
+ case lldb_r8_x86_64:
+ m_gpr_x86_64.r_r8 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r9_x86_64:
+ m_gpr_x86_64.r_r9 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r10_x86_64:
+ m_gpr_x86_64.r_r10 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r11_x86_64:
+ m_gpr_x86_64.r_r11 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r12_x86_64:
+ m_gpr_x86_64.r_r12 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r13_x86_64:
+ m_gpr_x86_64.r_r13 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r14_x86_64:
+ m_gpr_x86_64.r_r14 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r15_x86_64:
+ m_gpr_x86_64.r_r15 = reg_value.GetAsUInt64();
+ break;
+ case lldb_rip_x86_64:
+ m_gpr_x86_64.r_rip = reg_value.GetAsUInt64();
+ break;
+ case lldb_rflags_x86_64:
+ m_gpr_x86_64.r_rflags = reg_value.GetAsUInt64();
+ break;
+ case lldb_cs_x86_64:
+ m_gpr_x86_64.r_cs = reg_value.GetAsUInt64();
+ break;
+ case lldb_fs_x86_64:
+ m_gpr_x86_64.r_fs = reg_value.GetAsUInt64();
+ break;
+ case lldb_gs_x86_64:
+ m_gpr_x86_64.r_gs = reg_value.GetAsUInt64();
+ break;
+ case lldb_ss_x86_64:
+ m_gpr_x86_64.r_ss = reg_value.GetAsUInt64();
+ break;
+ case lldb_ds_x86_64:
+ m_gpr_x86_64.r_ds = reg_value.GetAsUInt64();
+ break;
+ case lldb_es_x86_64:
+ m_gpr_x86_64.r_es = reg_value.GetAsUInt64();
+ break;
+ case lldb_fctrl_x86_64:
+ m_fpr_x86_64.fxstate.fx_fcw = reg_value.GetAsUInt16();
+ break;
+ case lldb_fstat_x86_64:
+ m_fpr_x86_64.fxstate.fx_fsw = reg_value.GetAsUInt16();
+ break;
+ case lldb_ftag_x86_64:
+ m_fpr_x86_64.fxstate.fx_ftw = reg_value.GetAsUInt8();
+ break;
+ case lldb_fop_x86_64:
+ m_fpr_x86_64.fxstate.fx_fop = reg_value.GetAsUInt16();
+ break;
+ case lldb_fiseg_x86_64:
+ m_fpr_x86_64.fxstate.fx_rip = reg_value.GetAsUInt64();
+ break;
+ case lldb_fioff_x86_64:
+ m_fpr_x86_64.fxstate.fx_rip = reg_value.GetAsUInt32();
+ break;
+ case lldb_foseg_x86_64:
+ m_fpr_x86_64.fxstate.fx_rdp = reg_value.GetAsUInt64();
+ break;
+ case lldb_fooff_x86_64:
+ m_fpr_x86_64.fxstate.fx_rdp = reg_value.GetAsUInt32();
+ break;
+ case lldb_mxcsr_x86_64:
+ m_fpr_x86_64.fxstate.fx_mxcsr = reg_value.GetAsUInt32();
+ break;
+ case lldb_mxcsrmask_x86_64:
+ m_fpr_x86_64.fxstate.fx_mxcsr_mask = reg_value.GetAsUInt32();
+ break;
+ case lldb_st0_x86_64:
+ case lldb_st1_x86_64:
+ case lldb_st2_x86_64:
+ case lldb_st3_x86_64:
+ case lldb_st4_x86_64:
+ case lldb_st5_x86_64:
+ case lldb_st6_x86_64:
+ case lldb_st7_x86_64:
+ ::memcpy(&m_fpr_x86_64.fxstate.fx_st[reg - lldb_st0_x86_64],
+ reg_value.GetBytes(), reg_value.GetByteSize());
+ break;
+ case lldb_mm0_x86_64:
+ case lldb_mm1_x86_64:
+ case lldb_mm2_x86_64:
+ case lldb_mm3_x86_64:
+ case lldb_mm4_x86_64:
+ case lldb_mm5_x86_64:
+ case lldb_mm6_x86_64:
+ case lldb_mm7_x86_64:
+ ::memcpy(&m_fpr_x86_64.fxstate.fx_xmm[reg - lldb_mm0_x86_64],
+ reg_value.GetBytes(), reg_value.GetByteSize());
+ break;
+ case lldb_xmm0_x86_64:
+ case lldb_xmm1_x86_64:
+ case lldb_xmm2_x86_64:
+ case lldb_xmm3_x86_64:
+ case lldb_xmm4_x86_64:
+ case lldb_xmm5_x86_64:
+ case lldb_xmm6_x86_64:
+ case lldb_xmm7_x86_64:
+ case lldb_xmm8_x86_64:
+ case lldb_xmm9_x86_64:
+ case lldb_xmm10_x86_64:
+ case lldb_xmm11_x86_64:
+ case lldb_xmm12_x86_64:
+ 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],
+ reg_value.GetBytes(), reg_value.GetByteSize());
+ break;
+ }
+
+ if (WriteRegisterSet(set) != 0)
+ error.SetErrorStringWithFormat("failed to write register set");
+
+ return error;
+}
+
+Status NativeRegisterContextOpenBSD_x86_64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "failed to allocate DataBufferHeap instance of size %zu",
+ REG_CONTEXT_SIZE);
+ return error;
+ }
+
+ error = ReadGPR();
+ if (error.Fail())
+ return error;
+
+ uint8_t *dst = data_sp->GetBytes();
+ if (dst == nullptr) {
+ error.SetErrorStringWithFormat("DataBufferHeap instance of size %zu"
+ " returned a null pointer",
+ REG_CONTEXT_SIZE);
+ return error;
+ }
+
+ ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
+ dst += GetRegisterInfoInterface().GetGPRSize();
+
+ RegisterValue value((uint64_t)-1);
+ const RegisterInfo *reg_info =
+ GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_eax");
+ if (reg_info == nullptr)
+ reg_info = GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_rax");
+ return error;
+}
+
+Status NativeRegisterContextOpenBSD_x86_64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextOpenBSD_x86_64::%s invalid data_sp provided",
+ __FUNCTION__);
+ return error;
+ }
+
+ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextOpenBSD_x86_64::%s data_sp contained mismatched "
+ "data size, expected %zu, actual %llu",
+ __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextOpenBSD_x86_64::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+ ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize());
+
+ error = WriteGPR();
+ if (error.Fail())
+ return error;
+ src += GetRegisterInfoInterface().GetGPRSize();
+
+ return error;
+}
+
+Status NativeRegisterContextOpenBSD_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);
+ Status error = ReadRegister(reg_info, reg_value);
+ if (error.Fail()) {
+ is_hit = false;
+ return error;
+ }
+
+ uint64_t status_bits = reg_value.GetAsUInt64();
+
+ is_hit = status_bits & (1 << wp_index);
+
+ return error;
+}
+
+Status NativeRegisterContextOpenBSD_x86_64::GetWatchpointHitIndex(
+ uint32_t &wp_index, lldb::addr_t trap_addr) {
+ uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
+ for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
+ bool is_hit;
+ Status error = IsWatchpointHit(wp_index, is_hit);
+ if (error.Fail()) {
+ wp_index = LLDB_INVALID_INDEX32;
+ return error;
+ } else if (is_hit) {
+ return error;
+ }
+ }
+ wp_index = LLDB_INVALID_INDEX32;
+ return Status();
+}
+
+Status NativeRegisterContextOpenBSD_x86_64::IsWatchpointVacant(uint32_t wp_index,
+ bool &is_vacant) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Status("Watchpoint index out of range");
+
+ RegisterValue reg_value;
+ const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(lldb_dr7_x86_64);
+ Status error = ReadRegister(reg_info, reg_value);
+ if (error.Fail()) {
+ is_vacant = false;
+ return error;
+ }
+
+ uint64_t control_bits = reg_value.GetAsUInt64();
+
+ is_vacant = !(control_bits & (1 << (2 * wp_index)));
+
+ return error;
+}
+
+Status NativeRegisterContextOpenBSD_x86_64::SetHardwareWatchpointWithIndex(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
+
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Status("Watchpoint index out of range");
+
+ // Read only watchpoints aren't supported on x86_64. Fall back to read/write
+ // waitchpoints instead.
+ // TODO: Add logic to detect when a write happens and ignore that watchpoint
+ // hit.
+ if (watch_flags == 0x2)
+ watch_flags = 0x3;
+
+ if (watch_flags != 0x1 && watch_flags != 0x3)
+ return Status("Invalid read/write bits for watchpoint");
+
+ if (size != 1 && size != 2 && size != 4 && size != 8)
+ return Status("Invalid size for watchpoint");
+
+ bool is_vacant;
+ Status error = IsWatchpointVacant(wp_index, is_vacant);
+ if (error.Fail())
+ return error;
+ if (!is_vacant)
+ return Status("Watchpoint index not vacant");
+
+ RegisterValue reg_value;
+ const RegisterInfo *const reg_info_dr7 =
+ GetRegisterInfoAtIndex(lldb_dr7_x86_64);
+ error = ReadRegister(reg_info_dr7, reg_value);
+ if (error.Fail())
+ return error;
+
+ // for watchpoints 0, 1, 2, or 3, respectively, set bits 1, 3, 5, or 7
+ uint64_t enable_bit = 1 << (2 * wp_index);
+
+ // set bits 16-17, 20-21, 24-25, or 28-29
+ // with 0b01 for write, and 0b11 for read/write
+ uint64_t rw_bits = watch_flags << (16 + 4 * wp_index);
+
+ // set bits 18-19, 22-23, 26-27, or 30-31
+ // with 0b00, 0b01, 0b10, or 0b11
+ // for 1, 2, 8 (if supported), or 4 bytes, respectively
+ uint64_t size_bits = (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index);
+
+ uint64_t bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
+
+ uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
+
+ control_bits |= enable_bit | rw_bits | size_bits;
+
+ const RegisterInfo *const reg_info_drN =
+ GetRegisterInfoAtIndex(lldb_dr0_x86_64 + wp_index);
+ error = WriteRegister(reg_info_drN, RegisterValue(addr));
+ if (error.Fail())
+ return error;
+
+ error = WriteRegister(reg_info_dr7, RegisterValue(control_bits));
+ if (error.Fail())
+ return error;
+
+ error.Clear();
+ return error;
+}
+
+bool NativeRegisterContextOpenBSD_x86_64::ClearHardwareWatchpoint(
+ uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return false;
+
+ RegisterValue reg_value;
+
+ // for watchpoints 0, 1, 2, or 3, respectively, clear bits 0, 1, 2, or 3 of
+ // the debug status register (DR6)
+ const RegisterInfo *const reg_info_dr6 =
+ GetRegisterInfoAtIndex(lldb_dr6_x86_64);
+ Status error = ReadRegister(reg_info_dr6, reg_value);
+ if (error.Fail())
+ return false;
+ uint64_t bit_mask = 1 << wp_index;
+ uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
+ error = WriteRegister(reg_info_dr6, RegisterValue(status_bits));
+ if (error.Fail())
+ return false;
+
+ // for watchpoints 0, 1, 2, or 3, respectively, clear bits {0-1,16-19},
+ // {2-3,20-23}, {4-5,24-27}, or {6-7,28-31} of the debug control register
+ // (DR7)
+ const RegisterInfo *const reg_info_dr7 =
+ GetRegisterInfoAtIndex(lldb_dr7_x86_64);
+ error = ReadRegister(reg_info_dr7, reg_value);
+ if (error.Fail())
+ return false;
+ bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
+ uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
+ return WriteRegister(reg_info_dr7, RegisterValue(control_bits)).Success();
+}
+
+Status NativeRegisterContextOpenBSD_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);
+ Status error = ReadRegister(reg_info_dr6, reg_value);
+ if (error.Fail())
+ return error;
+ uint64_t bit_mask = 0xF;
+ uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
+ error = WriteRegister(reg_info_dr6, RegisterValue(status_bits));
+ if (error.Fail())
+ 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);
+ error = ReadRegister(reg_info_dr7, reg_value);
+ if (error.Fail())
+ return error;
+ bit_mask = 0xFF | (0xFFFF << 16);
+ uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
+ return WriteRegister(reg_info_dr7, RegisterValue(control_bits));
+}
+
+uint32_t NativeRegisterContextOpenBSD_x86_64::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) {
+ bool is_vacant;
+ Status error = IsWatchpointVacant(wp_index, is_vacant);
+ if (is_vacant) {
+ error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index);
+ if (error.Success())
+ return wp_index;
+ }
+ if (error.Fail() && log) {
+ log->Printf("NativeRegisterContextOpenBSD_x86_64::%s Error: %s",
+ __FUNCTION__, error.AsCString());
+ }
+ }
+ return LLDB_INVALID_INDEX32;
+}
+
+lldb::addr_t
+NativeRegisterContextOpenBSD_x86_64::GetWatchpointAddress(uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return LLDB_INVALID_ADDRESS;
+ RegisterValue reg_value;
+ const RegisterInfo *const reg_info_drN =
+ GetRegisterInfoAtIndex(lldb_dr0_x86_64 + wp_index);
+ if (ReadRegister(reg_info_drN, reg_value).Fail())
+ return LLDB_INVALID_ADDRESS;
+ return reg_value.GetAsUInt64();
+}
+
+uint32_t NativeRegisterContextOpenBSD_x86_64::NumSupportedHardwareWatchpoints() {
+ // Available debug address registers: dr0, dr1, dr2, dr3
+ return 4;
+}
+
+#endif // defined(__x86_64__)
diff --git a/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_x86_64.h b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_x86_64.h
new file mode 100644
index 00000000000..595a57ad0c3
--- /dev/null
+++ b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD_x86_64.h
@@ -0,0 +1,92 @@
+//===-- NativeRegisterContextOpenBSD_x86_64.h --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__x86_64__)
+
+#ifndef lldb_NativeRegisterContextOpenBSD_x86_64_h
+#define lldb_NativeRegisterContextOpenBSD_x86_64_h
+
+// clang-format off
+#include <sys/types.h>
+#include <machine/reg.h>
+// clang-format on
+
+#include "Plugins/Process/OpenBSD/NativeRegisterContextOpenBSD.h"
+#include "Plugins/Process/Utility/RegisterContext_x86.h"
+#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
+
+namespace lldb_private {
+namespace process_openbsd {
+
+class NativeProcessOpenBSD;
+
+class NativeRegisterContextOpenBSD_x86_64 : public NativeRegisterContextOpenBSD {
+public:
+ NativeRegisterContextOpenBSD_x86_64(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread);
+ uint32_t GetRegisterSetCount() const override;
+
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
+
+ Status ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
+
+ Status WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
+
+ Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ Status IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
+
+ Status GetWatchpointHitIndex(uint32_t &wp_index,
+ lldb::addr_t trap_addr) override;
+
+ Status IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
+
+ bool ClearHardwareWatchpoint(uint32_t wp_index) override;
+
+ Status ClearAllHardwareWatchpoints() override;
+
+ Status SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags,
+ uint32_t wp_index);
+
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags) override;
+
+ lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
+
+ uint32_t NumSupportedHardwareWatchpoints() override;
+
+protected:
+ void *GetGPRBuffer() override { return &m_gpr_x86_64; }
+ void *GetFPRBuffer() override { return &m_fpr_x86_64; }
+
+private:
+ // Private member types.
+ enum { GPRegSet, FPRegSet };
+
+ // Private member variables.
+ struct reg m_gpr_x86_64;
+ struct fpreg m_fpr_x86_64;
+
+ int GetSetForNativeRegNum(int reg_num) const;
+
+ int ReadRegisterSet(uint32_t set);
+ int WriteRegisterSet(uint32_t set);
+};
+
+} // namespace process_openbsd
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextOpenBSD_x86_64_h
+
+#endif // defined(__x86_64__)
diff --git a/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeThreadOpenBSD.cpp b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeThreadOpenBSD.cpp
new file mode 100644
index 00000000000..30a5ae0fff7
--- /dev/null
+++ b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeThreadOpenBSD.cpp
@@ -0,0 +1,206 @@
+//===-- NativeThreadOpenBSD.cpp -------------------------------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeThreadOpenBSD.h"
+#include "NativeRegisterContextOpenBSD.h"
+
+#include "NativeProcessOpenBSD.h"
+
+#include "Plugins/Process/POSIX/CrashReason.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/State.h"
+
+#include <sstream>
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_openbsd;
+
+NativeThreadOpenBSD::NativeThreadOpenBSD(NativeProcessOpenBSD &process,
+ lldb::tid_t tid)
+ : NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid),
+ m_stop_info(), m_reg_context_up(
+NativeRegisterContextOpenBSD::CreateHostNativeRegisterContextOpenBSD(process.GetArchitecture(), *this)
+), m_stop_description() {}
+
+void NativeThreadOpenBSD::SetStoppedBySignal(uint32_t signo,
+ const siginfo_t *info) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ LLDB_LOG(log, "tid = {0} in called with signal {1}", GetID(), signo);
+
+ SetStopped();
+
+ m_stop_info.reason = StopReason::eStopReasonSignal;
+ m_stop_info.details.signal.signo = signo;
+
+ m_stop_description.clear();
+ if (info) {
+ switch (signo) {
+ case SIGSEGV:
+ case SIGBUS:
+ case SIGFPE:
+ case SIGILL:
+ const auto reason = GetCrashReason(*info);
+ m_stop_description = GetCrashReasonString(reason, *info);
+ break;
+ }
+ }
+}
+
+void NativeThreadOpenBSD::SetStoppedByBreakpoint() {
+ SetStopped();
+ m_stop_info.reason = StopReason::eStopReasonBreakpoint;
+ m_stop_info.details.signal.signo = SIGTRAP;
+}
+
+void NativeThreadOpenBSD::SetStoppedByTrace() {
+ SetStopped();
+ m_stop_info.reason = StopReason::eStopReasonTrace;
+ m_stop_info.details.signal.signo = SIGTRAP;
+}
+
+void NativeThreadOpenBSD::SetStoppedByExec() {
+ SetStopped();
+ m_stop_info.reason = StopReason::eStopReasonExec;
+ m_stop_info.details.signal.signo = SIGTRAP;
+}
+
+void NativeThreadOpenBSD::SetStoppedByWatchpoint(uint32_t wp_index) {
+ SetStopped();
+
+ lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
+
+ std::ostringstream ostr;
+ ostr << GetRegisterContext().GetWatchpointAddress(wp_index) << " ";
+ ostr << wp_index;
+
+ ostr << " " << GetRegisterContext().GetWatchpointHitAddress(wp_index);
+
+ m_stop_description = ostr.str();
+
+ m_stop_info.reason = StopReason::eStopReasonWatchpoint;
+ m_stop_info.details.signal.signo = SIGTRAP;
+}
+
+void NativeThreadOpenBSD::SetStopped() {
+ const StateType new_state = StateType::eStateStopped;
+ m_state = new_state;
+ m_stop_description.clear();
+}
+
+void NativeThreadOpenBSD::SetRunning() {
+ m_state = StateType::eStateRunning;
+ m_stop_info.reason = StopReason::eStopReasonNone;
+}
+
+void NativeThreadOpenBSD::SetStepping() {
+ m_state = StateType::eStateStepping;
+ m_stop_info.reason = StopReason::eStopReasonNone;
+}
+
+std::string NativeThreadOpenBSD::GetName() { return std::string(""); }
+
+lldb::StateType NativeThreadOpenBSD::GetState() { return m_state; }
+
+bool NativeThreadOpenBSD::GetStopReason(ThreadStopInfo &stop_info,
+ std::string &description) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+
+ description.clear();
+
+ switch (m_state) {
+ case eStateStopped:
+ case eStateCrashed:
+ case eStateExited:
+ case eStateSuspended:
+ case eStateUnloaded:
+ stop_info = m_stop_info;
+ description = m_stop_description;
+
+ return true;
+
+ case eStateInvalid:
+ case eStateConnected:
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateRunning:
+ case eStateStepping:
+ case eStateDetached:
+ LLDB_LOG(log, "tid = {0} in state {1} cannot answer stop reason", GetID(),
+ StateAsCString(m_state));
+ return false;
+ }
+ llvm_unreachable("unhandled StateType!");
+}
+
+NativeRegisterContext& NativeThreadOpenBSD::GetRegisterContext() {
+ assert(m_reg_context_up);
+return *m_reg_context_up;
+}
+
+Status NativeThreadOpenBSD::SetWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags, bool hardware) {
+ if (!hardware)
+ return Status("not implemented");
+ if (m_state == eStateLaunching)
+ return Status();
+ Status error = RemoveWatchpoint(addr);
+ if (error.Fail())
+ return error;
+ uint32_t wp_index = GetRegisterContext().SetHardwareWatchpoint(addr, size, watch_flags);
+ if (wp_index == LLDB_INVALID_INDEX32)
+ return Status("Setting hardware watchpoint failed.");
+ m_watchpoint_index_map.insert({addr, wp_index});
+ return Status();
+}
+
+Status NativeThreadOpenBSD::RemoveWatchpoint(lldb::addr_t addr) {
+ auto wp = m_watchpoint_index_map.find(addr);
+ if (wp == m_watchpoint_index_map.end())
+ return Status();
+ uint32_t wp_index = wp->second;
+ m_watchpoint_index_map.erase(wp);
+ if (GetRegisterContext().ClearHardwareWatchpoint(wp_index))
+ return Status();
+ return Status("Clearing hardware watchpoint failed.");
+}
+
+Status NativeThreadOpenBSD::SetHardwareBreakpoint(lldb::addr_t addr,
+ size_t size) {
+ if (m_state == eStateLaunching)
+ return Status();
+
+ Status error = RemoveHardwareBreakpoint(addr);
+ if (error.Fail())
+ return error;
+
+ uint32_t bp_index = GetRegisterContext().SetHardwareBreakpoint(addr, size);
+
+ if (bp_index == LLDB_INVALID_INDEX32)
+ return Status("Setting hardware breakpoint failed.");
+
+ m_hw_break_index_map.insert({addr, bp_index});
+ return Status();
+}
+
+Status NativeThreadOpenBSD::RemoveHardwareBreakpoint(lldb::addr_t addr) {
+ auto bp = m_hw_break_index_map.find(addr);
+ if (bp == m_hw_break_index_map.end())
+ return Status();
+
+ uint32_t bp_index = bp->second;
+ if (GetRegisterContext().ClearHardwareBreakpoint(bp_index)) {
+ m_hw_break_index_map.erase(bp);
+ return Status();
+ }
+
+ return Status("Clearing hardware breakpoint failed.");
+}
diff --git a/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeThreadOpenBSD.h b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeThreadOpenBSD.h
new file mode 100644
index 00000000000..62f6803ab95
--- /dev/null
+++ b/gnu/llvm/tools/lldb/source/Plugins/Process/OpenBSD/NativeThreadOpenBSD.h
@@ -0,0 +1,81 @@
+//===-- NativeThreadOpenBSD.h ---------------------------------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_NativeThreadOpenBSD_H_
+#define liblldb_NativeThreadOpenBSD_H_
+
+#include "lldb/Host/common/NativeThreadProtocol.h"
+
+#include <csignal>
+#include <map>
+#include <string>
+
+namespace lldb_private {
+namespace process_openbsd {
+
+class NativeProcessOpenBSD;
+
+class NativeThreadOpenBSD : public NativeThreadProtocol {
+ friend class NativeProcessOpenBSD;
+
+public:
+ NativeThreadOpenBSD(NativeProcessOpenBSD &process, lldb::tid_t tid);
+
+ // ---------------------------------------------------------------------
+ // NativeThreadProtocol Interface
+ // ---------------------------------------------------------------------
+ std::string GetName() override;
+
+ lldb::StateType GetState() override;
+
+ bool GetStopReason(ThreadStopInfo &stop_info,
+ std::string &description) override;
+
+ NativeRegisterContext& GetRegisterContext() override;
+
+ Status SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags,
+ bool hardware) override;
+
+ Status RemoveWatchpoint(lldb::addr_t addr) override;
+
+ Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
+
+ Status RemoveHardwareBreakpoint(lldb::addr_t addr) override;
+
+private:
+ // ---------------------------------------------------------------------
+ // Interface for friend classes
+ // ---------------------------------------------------------------------
+
+ void SetStoppedBySignal(uint32_t signo, const siginfo_t *info = nullptr);
+ void SetStoppedByBreakpoint();
+ void SetStoppedByTrace();
+ void SetStoppedByExec();
+ void SetStoppedByWatchpoint(uint32_t wp_index);
+ void SetStopped();
+ void SetRunning();
+ void SetStepping();
+
+ // ---------------------------------------------------------------------
+ // Member Variables
+ // ---------------------------------------------------------------------
+ lldb::StateType m_state;
+ ThreadStopInfo m_stop_info;
+ std::unique_ptr<NativeRegisterContext> m_reg_context_up;
+ std::string m_stop_description;
+ using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
+ WatchpointIndexMap m_watchpoint_index_map;
+ WatchpointIndexMap m_hw_break_index_map;
+};
+
+typedef std::shared_ptr<NativeThreadOpenBSD> NativeThreadOpenBSDSP;
+} // namespace process_openbsd
+} // namespace lldb_private
+
+#endif // #ifndef liblldb_NativeThreadOpenBSD_H_
diff --git a/gnu/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/gnu/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index f53db502be9..d22cf44baf8 100644
--- a/gnu/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/gnu/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -11,24 +11,22 @@
#include <errno.h>
-// C Includes
#ifdef __APPLE__
#include <TargetConditionals.h>
#endif
-// C++ Includes
#include <chrono>
#include <cstring>
-// Other libraries and framework includes
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/Config.h"
#include "lldb/Host/File.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Host/SafeMachO.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/FileAction.h"
#include "lldb/Target/Platform.h"
@@ -40,9 +38,8 @@
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/Triple.h"
-// Project includes
#include "ProcessGDBRemoteLog.h"
-#include "Utility/StringExtractorGDBRemote.h"
+#include "lldb/Utility/StringExtractorGDBRemote.h"
#ifdef __ANDROID__
#include "lldb/Host/android/HostInfoAndroid.h"
@@ -218,12 +215,15 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
if (sub != LLDB_INVALID_CPUTYPE)
response.Printf("cpusubtype:%u;", sub);
- if (cpu == ArchSpec::kCore_arm_any) {
+ if (cpu == llvm::MachO::CPU_TYPE_ARM
+ || cpu == llvm::MachO::CPU_TYPE_ARM64) {
// Indicate the OS type.
#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
response.PutCString("ostype:tvos;");
#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
response.PutCString("ostype:watchos;");
+#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
+ response.PutCString("ostype:bridgeos;");
#else
response.PutCString("ostype:ios;");
#endif
@@ -265,19 +265,10 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
break;
}
- uint32_t major = UINT32_MAX;
- uint32_t minor = UINT32_MAX;
- uint32_t update = UINT32_MAX;
- if (HostInfo::GetOSVersion(major, minor, update)) {
- if (major != UINT32_MAX) {
- response.Printf("os_version:%u", major);
- if (minor != UINT32_MAX) {
- response.Printf(".%u", minor);
- if (update != UINT32_MAX)
- response.Printf(".%u", update);
- }
- response.PutChar(';');
- }
+ llvm::VersionTuple version = HostInfo::GetOSVersion();
+ if (!version.empty()) {
+ response.Format("os_version:{0}", version.getAsString());
+ response.PutChar(';');
}
std::string s;
@@ -295,9 +286,9 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
#if defined(__APPLE__)
#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- // For iOS devices, we are connected through a USB Mux so we never pretend
- // to actually have a hostname as far as the remote lldb that is connecting
- // to this lldb-platform is concerned
+ // For iOS devices, we are connected through a USB Mux so we never pretend to
+ // actually have a hostname as far as the remote lldb that is connecting to
+ // this lldb-platform is concerned
response.PutCString("hostname:");
response.PutCStringAsRawHex8("127.0.0.1");
response.PutChar(';');
@@ -357,7 +348,8 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo(
StringExtractor extractor(value);
std::string file;
extractor.GetHexByteString(file);
- match_info.GetProcessInfo().GetExecutableFile().SetFile(file, false);
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(
+ file, FileSpec::Style::native);
} else if (key.equals("name_match")) {
NameMatch name_match = llvm::StringSwitch<NameMatch>(value)
.Case("equals", NameMatch::Equals)
@@ -401,10 +393,10 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo(
match_info.GetProcessInfo().SetEffectiveGroupID(gid);
} else if (key.equals("all_users")) {
match_info.SetMatchAllUsers(
- Args::StringToBoolean(value, false, &success));
+ OptionArgParser::ToBoolean(value, false, &success));
} else if (key.equals("triple")) {
- match_info.GetProcessInfo().GetArchitecture().SetTriple(
- value.str().c_str(), NULL);
+ match_info.GetProcessInfo().GetArchitecture() =
+ HostInfo::GetAugmentedArchSpec(value);
} else {
success = false;
}
@@ -415,8 +407,8 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo(
}
if (Host::FindProcesses(match_info, m_proc_infos)) {
- // We found something, return the first item by calling the get
- // subsequent process info packet handler...
+ // We found something, return the first item by calling the get subsequent
+ // process info packet handler...
return Handle_qsProcessInfo(packet);
}
return SendErrorResponse(3);
@@ -524,7 +516,8 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Open(
if (packet.GetChar() == ',') {
mode_t mode = packet.GetHexMaxU32(false, 0600);
Status error;
- const FileSpec path_spec{path, true};
+ FileSpec path_spec(path);
+ FileSystem::Instance().Resolve(path_spec);
int fd = ::open(path_spec.GetCString(), flags, mode);
const int save_errno = fd == -1 ? errno : 0;
StreamString response;
@@ -663,12 +656,14 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Mode(
std::string path;
packet.GetHexByteString(path);
if (!path.empty()) {
- Status error;
- const uint32_t mode = File::GetPermissions(FileSpec{path, true}, error);
+ FileSpec file_spec(path);
+ FileSystem::Instance().Resolve(file_spec);
+ std::error_code ec;
+ const uint32_t mode = FileSystem::Instance().GetPermissions(file_spec, ec);
StreamString response;
response.Printf("F%u", mode);
- if (mode == 0 || error.Fail())
- response.Printf(",%i", (int)error.GetError());
+ if (mode == 0 || ec)
+ response.Printf(",%i", (int)Status(ec).GetError());
return SendPacketNoLock(response.GetString());
}
return SendErrorResponse(23);
@@ -702,7 +697,11 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_symlink(
packet.GetHexByteStringTerminatedBy(dst, ',');
packet.GetChar(); // Skip ',' char
packet.GetHexByteString(src);
- Status error = FileSystem::Symlink(FileSpec{src, true}, FileSpec{dst, false});
+
+ FileSpec src_spec(src);
+ FileSystem::Instance().Resolve(src_spec);
+ Status error = FileSystem::Instance().Symlink(src_spec, FileSpec(dst));
+
StreamString response;
response.Printf("F%u,%u", error.GetError(), error.GetError());
return SendPacketNoLock(response.GetString());
@@ -731,14 +730,15 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell(
if (packet.GetChar() == ',') {
// FIXME: add timeout to qPlatform_shell packet
// uint32_t timeout = packet.GetHexMaxU32(false, 32);
- uint32_t timeout = 10;
if (packet.GetChar() == ',')
packet.GetHexByteString(working_dir);
int status, signo;
std::string output;
+ FileSpec working_spec(working_dir);
+ FileSystem::Instance().Resolve(working_spec);
Status err =
- Host::RunShellCommand(path.c_str(), FileSpec{working_dir, true},
- &status, &signo, &output, timeout);
+ Host::RunShellCommand(path.c_str(), working_spec, &status, &signo,
+ &output, std::chrono::seconds(10));
StreamGDBRemote response;
if (err.Fail()) {
response.PutCString("F,");
@@ -838,7 +838,7 @@ GDBRemoteCommunicationServerCommon::Handle_qSupported(
response.PutCString(";QThreadSuffixSupported+");
response.PutCString(";QListThreadsInStopReply+");
response.PutCString(";qEcho+");
-#if defined(__linux__) || defined(__NetBSD__)
+#if defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__)
response.PutCString(";QPassSignals+");
response.PutCString(";qXfer:auxv:read+");
#endif
@@ -889,7 +889,7 @@ GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN(
packet.GetHexByteString(path);
const bool read = true;
const bool write = false;
- if (file_action.Open(STDIN_FILENO, FileSpec{path, false}, read, write)) {
+ if (file_action.Open(STDIN_FILENO, FileSpec(path), read, write)) {
m_process_launch_info.AppendFileAction(file_action);
return SendOKResponse();
}
@@ -905,7 +905,7 @@ GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT(
packet.GetHexByteString(path);
const bool read = false;
const bool write = true;
- if (file_action.Open(STDOUT_FILENO, FileSpec{path, false}, read, write)) {
+ if (file_action.Open(STDOUT_FILENO, FileSpec(path), read, write)) {
m_process_launch_info.AppendFileAction(file_action);
return SendOKResponse();
}
@@ -921,7 +921,7 @@ GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR(
packet.GetHexByteString(path);
const bool read = false;
const bool write = true;
- if (file_action.Open(STDERR_FILENO, FileSpec{path, false}, read, write)) {
+ if (file_action.Open(STDERR_FILENO, FileSpec(path), read, write)) {
m_process_launch_info.AppendFileAction(file_action);
return SendOKResponse();
}
@@ -945,8 +945,7 @@ GDBRemoteCommunicationServerCommon::Handle_QEnvironment(
packet.SetFilePos(::strlen("QEnvironment:"));
const uint32_t bytes_left = packet.GetBytesLeft();
if (bytes_left > 0) {
- m_process_launch_info.GetEnvironmentEntries().AppendArgument(
- llvm::StringRef::withNullAsEmpty(packet.Peek()));
+ m_process_launch_info.GetEnvironment().insert(packet.Peek());
return SendOKResponse();
}
return SendErrorResponse(12);
@@ -960,7 +959,7 @@ GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded(
if (bytes_left > 0) {
std::string str;
packet.GetHexByteString(str);
- m_process_launch_info.GetEnvironmentEntries().AppendArgument(str);
+ m_process_launch_info.GetEnvironment().insert(str);
return SendOKResponse();
}
return SendErrorResponse(12);
@@ -973,8 +972,7 @@ GDBRemoteCommunicationServerCommon::Handle_QLaunchArch(
const uint32_t bytes_left = packet.GetBytesLeft();
if (bytes_left > 0) {
const char *arch_triple = packet.Peek();
- ArchSpec arch_spec(arch_triple, NULL);
- m_process_launch_info.SetArchitecture(arch_spec);
+ m_process_launch_info.SetArchitecture(HostInfo::GetAugmentedArchSpec(arch_triple));
return SendOKResponse();
}
return SendErrorResponse(13);
@@ -982,11 +980,11 @@ GDBRemoteCommunicationServerCommon::Handle_QLaunchArch(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
- // The 'A' packet is the most over designed packet ever here with
- // redundant argument indexes, redundant argument lengths and needed hex
- // encoded argument string values. Really all that is needed is a comma
- // separated hex encoded argument value list, but we will stay true to the
- // documented version of the 'A' packet here...
+ // The 'A' packet is the most over designed packet ever here with redundant
+ // argument indexes, redundant argument lengths and needed hex encoded
+ // argument string values. Really all that is needed is a comma separated hex
+ // encoded argument value list, but we will stay true to the documented
+ // version of the 'A' packet here...
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
int actual_arg_index = 0;
@@ -994,8 +992,8 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
packet.SetFilePos(1); // Skip the 'A'
bool success = true;
while (success && packet.GetBytesLeft() > 0) {
- // Decode the decimal argument string length. This length is the
- // number of hex nibbles in the argument string value.
+ // Decode the decimal argument string length. This length is the number of
+ // hex nibbles in the argument string value.
const uint32_t arg_len = packet.GetU32(UINT32_MAX);
if (arg_len == UINT32_MAX)
success = false;
@@ -1004,8 +1002,8 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
if (packet.GetChar() != ',')
success = false;
else {
- // Decode the argument index. We ignore this really because
- // who would really send down the arguments in a random order???
+ // Decode the argument index. We ignore this really because who would
+ // really send down the arguments in a random order???
const uint32_t arg_idx = packet.GetU32(UINT32_MAX);
if (arg_idx == UINT32_MAX)
success = false;
@@ -1014,9 +1012,9 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
if (packet.GetChar() != ',')
success = false;
else {
- // Decode the argument string value from hex bytes
- // back into a UTF8 string and make sure the length
- // matches the one supplied in the packet
+ // Decode the argument string value from hex bytes back into a UTF8
+ // string and make sure the length matches the one supplied in the
+ // packet
std::string arg;
if (packet.GetHexByteStringFixedLength(arg, arg_len) !=
(arg_len / 2))
@@ -1030,7 +1028,8 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
if (success) {
if (arg_idx == 0)
- m_process_launch_info.GetExecutableFile().SetFile(arg, false);
+ m_process_launch_info.GetExecutableFile().SetFile(
+ arg, FileSpec::Style::native);
m_process_launch_info.GetArguments().AppendArgument(arg);
if (log)
log->Printf("LLGSPacketHandler::%s added arg %d: \"%s\"",
@@ -1255,8 +1254,8 @@ void GDBRemoteCommunicationServerCommon::
// Nothing.
break;
}
- // In case of MIPS64, pointer size is depend on ELF ABI
- // For N32 the pointer size is 4 and for N64 it is 8
+ // In case of MIPS64, pointer size is depend on ELF ABI For N32 the pointer
+ // size is 4 and for N64 it is 8
std::string abi = proc_arch.GetTargetABI();
if (!abi.empty())
response.Printf("elf_abi:%s;", abi.c_str());
@@ -1269,7 +1268,9 @@ FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile(
#ifdef __ANDROID__
return HostInfoAndroid::ResolveLibraryPath(module_path, arch);
#else
- return FileSpec(module_path, true);
+ FileSpec file_spec(module_path);
+ FileSystem::Instance().Resolve(file_spec);
+ return file_spec;
#endif
}
@@ -1278,7 +1279,9 @@ GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path,
llvm::StringRef triple) {
ArchSpec arch(triple);
- const FileSpec req_module_path_spec(module_path, true);
+ FileSpec req_module_path_spec(module_path);
+ FileSystem::Instance().Resolve(req_module_path_spec);
+
const FileSpec module_path_spec =
FindModuleFile(req_module_path_spec.GetPath(), arch);
const ModuleSpec module_spec(module_path_spec, arch);
diff --git a/gnu/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/gnu/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 9294359dbef..96f6a8f0f8f 100644
--- a/gnu/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/gnu/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -14,15 +14,10 @@
#include "GDBRemoteCommunicationServerLLGS.h"
#include "lldb/Utility/StreamGDBRemote.h"
-// C Includes
-// C++ Includes
#include <chrono>
#include <cstring>
#include <thread>
-// Other libraries and framework includes
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/State.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/Debug.h"
#include "lldb/Host/File.h"
@@ -33,23 +28,24 @@
#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/Host/common/NativeRegisterContext.h"
#include "lldb/Host/common/NativeThreadProtocol.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Target/FileAction.h"
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/JSON.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/UriParser.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/ScopedPrinter.h"
-// Project includes
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
-#include "Utility/StringExtractorGDBRemote.h"
+#include "lldb/Utility/StringExtractorGDBRemote.h"
using namespace lldb;
using namespace lldb_private;
@@ -204,21 +200,8 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
});
}
-Status
-GDBRemoteCommunicationServerLLGS::SetLaunchArguments(const char *const args[],
- int argc) {
- if ((argc < 1) || !args || !args[0] || !args[0][0])
- return Status("%s: no process command line specified to launch",
- __FUNCTION__);
-
- m_process_launch_info.SetArguments(const_cast<const char **>(args), true);
- return Status();
-}
-
-Status
-GDBRemoteCommunicationServerLLGS::SetLaunchFlags(unsigned int launch_flags) {
- m_process_launch_info.GetFlags().Set(launch_flags);
- return Status();
+void GDBRemoteCommunicationServerLLGS::SetLaunchInfo(const ProcessLaunchInfo &info) {
+ m_process_launch_info = info;
}
Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
@@ -235,8 +218,10 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
m_process_launch_info.SetLaunchInSeparateProcessGroup(true);
m_process_launch_info.GetFlags().Set(eLaunchFlagDebug);
- const bool default_to_use_pty = true;
- m_process_launch_info.FinalizeFileActions(nullptr, default_to_use_pty);
+ if (should_forward_stdio) {
+ if (llvm::Error Err = m_process_launch_info.SetUpPtyRedirection())
+ return Status(std::move(Err));
+ }
{
std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex);
@@ -244,26 +229,20 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
"process but one already exists");
auto process_or =
m_process_factory.Launch(m_process_launch_info, *this, m_mainloop);
- if (!process_or) {
- Status status(process_or.takeError());
- llvm::errs() << llvm::formatv(
- "failed to launch executable `{0}`: {1}",
- m_process_launch_info.GetArguments().GetArgumentAtIndex(0), status);
- return status;
- }
+ if (!process_or)
+ return Status(process_or.takeError());
m_debugged_process_up = std::move(*process_or);
}
- // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol
- // as needed.
- // llgs local-process debugging may specify PTY paths, which will make these
- // file actions non-null
- // process launch -i/e/o will also make these file actions non-null
- // nullptr means that the traffic is expected to flow over gdb-remote protocol
+ // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol as
+ // needed. llgs local-process debugging may specify PTY paths, which will
+ // make these file actions non-null process launch -i/e/o will also make
+ // these file actions non-null nullptr means that the traffic is expected to
+ // flow over gdb-remote protocol
if (should_forward_stdio) {
// nullptr means it's not redirected to file or pty (in case of LLGS local)
- // at least one of stdio will be transferred pty<->gdb-remote
- // we need to give the pty master handle to this object to read and/or write
+ // at least one of stdio will be transferred pty<->gdb-remote we need to
+ // give the pty master handle to this object to read and/or write
LLDB_LOG(log,
"pid = {0}: setting up stdout/stderr redirection via $O "
"gdb-remote commands",
@@ -309,7 +288,7 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
// else.
if (m_debugged_process_up &&
m_debugged_process_up->GetID() != LLDB_INVALID_PROCESS_ID)
- return Status("cannot attach to a process %" PRIu64
+ return Status("cannot attach to process %" PRIu64
" when another process with pid %" PRIu64
" is being debugged.",
pid, m_debugged_process_up->GetID());
@@ -396,12 +375,12 @@ static void AppendHexValue(StreamString &response, const uint8_t *buf,
}
static void WriteRegisterValueInHexFixedWidth(
- StreamString &response, NativeRegisterContextSP &reg_ctx_sp,
+ StreamString &response, NativeRegisterContext &reg_ctx,
const RegisterInfo &reg_info, const RegisterValue *reg_value_p,
lldb::ByteOrder byte_order) {
RegisterValue reg_value;
if (!reg_value_p) {
- Status error = reg_ctx_sp->ReadRegister(&reg_info, reg_value);
+ Status error = reg_ctx.ReadRegister(&reg_info, reg_value);
if (error.Success())
reg_value_p = &reg_value;
// else log.
@@ -423,15 +402,13 @@ static void WriteRegisterValueInHexFixedWidth(
static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
- NativeRegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
- if (!reg_ctx_sp)
- return nullptr;
+ NativeRegisterContext& reg_ctx = thread.GetRegisterContext();
JSONObject::SP register_object_sp = std::make_shared<JSONObject>();
#ifdef LLDB_JTHREADSINFO_FULL_REGISTER_SET
- // Expedite all registers in the first register set (i.e. should be GPRs) that
- // are not contained in other registers.
+ // Expedite all registers in the first register set (i.e. should be GPRs)
+ // that are not contained in other registers.
const RegisterSet *reg_set_p = reg_ctx_sp->GetRegisterSet(0);
if (!reg_set_p)
return nullptr;
@@ -440,22 +417,21 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
uint32_t reg_num = *reg_num_p;
#else
// Expedite only a couple of registers until we figure out why sending
- // registers is
- // expensive.
+ // registers is expensive.
static const uint32_t k_expedited_registers[] = {
LLDB_REGNUM_GENERIC_PC, LLDB_REGNUM_GENERIC_SP, LLDB_REGNUM_GENERIC_FP,
LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM};
for (const uint32_t *generic_reg_p = k_expedited_registers;
*generic_reg_p != LLDB_INVALID_REGNUM; ++generic_reg_p) {
- uint32_t reg_num = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
+ uint32_t reg_num = reg_ctx.ConvertRegisterKindToRegisterNumber(
eRegisterKindGeneric, *generic_reg_p);
if (reg_num == LLDB_INVALID_REGNUM)
continue; // Target does not support the given register.
#endif
const RegisterInfo *const reg_info_p =
- reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
+ reg_ctx.GetRegisterInfoAtIndex(reg_num);
if (reg_info_p == nullptr) {
if (log)
log->Printf(
@@ -469,7 +445,7 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
// registers.
RegisterValue reg_value;
- Status error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value);
+ Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
if (error.Fail()) {
if (log)
log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s",
@@ -480,7 +456,7 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
}
StreamString stream;
- WriteRegisterValueInHexFixedWidth(stream, reg_ctx_sp, *reg_info_p,
+ WriteRegisterValueInHexFixedWidth(stream, reg_ctx, *reg_info_p,
&reg_value, lldb::eByteOrderBig);
register_object_sp->SetObject(
@@ -523,16 +499,16 @@ static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process,
// Ensure we can get info on the given thread.
uint32_t thread_idx = 0;
- for (NativeThreadProtocolSP thread_sp;
- (thread_sp = process.GetThreadAtIndex(thread_idx)) != nullptr;
+ for (NativeThreadProtocol *thread;
+ (thread = process.GetThreadAtIndex(thread_idx)) != nullptr;
++thread_idx) {
- lldb::tid_t tid = thread_sp->GetID();
+ lldb::tid_t tid = thread->GetID();
// Grab the reason this thread stopped.
struct ThreadStopInfo tid_stop_info;
std::string description;
- if (!thread_sp->GetStopReason(tid_stop_info, description))
+ if (!thread->GetStopReason(tid_stop_info, description))
return nullptr;
const int signum = tid_stop_info.details.signal.signo;
@@ -548,7 +524,7 @@ static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process,
threads_array_sp->AppendObject(thread_obj_sp);
if (!abridged) {
- if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread_sp))
+ if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread))
thread_obj_sp->SetObject("registers", registers_sp);
}
@@ -556,7 +532,7 @@ static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process,
if (signum != 0)
thread_obj_sp->SetObject("signal", std::make_shared<JSONNumber>(signum));
- const std::string thread_name = thread_sp->GetName();
+ const std::string thread_name = thread->GetName();
if (!thread_name.empty())
thread_obj_sp->SetObject("name",
std::make_shared<JSONString>(thread_name));
@@ -604,19 +580,18 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
m_debugged_process_up->GetID(), tid);
// Ensure we can get info on the given thread.
- NativeThreadProtocolSP thread_sp(m_debugged_process_up->GetThreadByID(tid));
- if (!thread_sp)
+ NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid);
+ if (!thread)
return SendErrorResponse(51);
// Grab the reason this thread stopped.
struct ThreadStopInfo tid_stop_info;
std::string description;
- if (!thread_sp->GetStopReason(tid_stop_info, description))
+ if (!thread->GetStopReason(tid_stop_info, description))
return SendErrorResponse(52);
// FIXME implement register handling for exec'd inferiors.
- // if (tid_stop_info.reason == eStopReasonExec)
- // {
+ // if (tid_stop_info.reason == eStopReasonExec) {
// const bool force = true;
// InitializeRegisters(force);
// }
@@ -638,7 +613,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
response.Printf("thread:%" PRIx64 ";", tid);
// Include the thread name if there is one.
- const std::string thread_name = thread_sp->GetName();
+ const std::string thread_name = thread->GetName();
if (!thread_name.empty()) {
size_t thread_name_len = thread_name.length();
@@ -653,36 +628,33 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
response.PutChar(';');
}
- // If a 'QListThreadsInStopReply' was sent to enable this feature, we
- // will send all thread IDs back in the "threads" key whose value is
- // a list of hex thread IDs separated by commas:
+ // If a 'QListThreadsInStopReply' was sent to enable this feature, we will
+ // send all thread IDs back in the "threads" key whose value is a list of hex
+ // thread IDs separated by commas:
// "threads:10a,10b,10c;"
- // This will save the debugger from having to send a pair of qfThreadInfo
- // and qsThreadInfo packets, but it also might take a lot of room in the
- // stop reply packet, so it must be enabled only on systems where there
- // are no limits on packet lengths.
+ // This will save the debugger from having to send a pair of qfThreadInfo and
+ // qsThreadInfo packets, but it also might take a lot of room in the stop
+ // reply packet, so it must be enabled only on systems where there are no
+ // limits on packet lengths.
if (m_list_threads_in_stop_reply) {
response.PutCString("threads:");
uint32_t thread_index = 0;
- NativeThreadProtocolSP listed_thread_sp;
- for (listed_thread_sp =
- m_debugged_process_up->GetThreadAtIndex(thread_index);
- listed_thread_sp; ++thread_index,
- listed_thread_sp = m_debugged_process_up->GetThreadAtIndex(
- thread_index)) {
+ NativeThreadProtocol *listed_thread;
+ for (listed_thread = m_debugged_process_up->GetThreadAtIndex(thread_index);
+ listed_thread; ++thread_index,
+ listed_thread = m_debugged_process_up->GetThreadAtIndex(thread_index)) {
if (thread_index > 0)
response.PutChar(',');
- response.Printf("%" PRIx64, listed_thread_sp->GetID());
+ response.Printf("%" PRIx64, listed_thread->GetID());
}
response.PutChar(';');
- // Include JSON info that describes the stop reason for any threads
- // that actually have stop reasons. We use the new "jstopinfo" key
- // whose values is hex ascii JSON that contains the thread IDs
- // thread stop info only for threads that have stop reasons. Only send
- // this if we have more than one thread otherwise this packet has all
- // the info it needs.
+ // Include JSON info that describes the stop reason for any threads that
+ // actually have stop reasons. We use the new "jstopinfo" key whose values
+ // is hex ascii JSON that contains the thread IDs thread stop info only for
+ // threads that have stop reasons. Only send this if we have more than one
+ // thread otherwise this packet has all the info it needs.
if (thread_index > 0) {
const bool threads_with_valid_stop_info_only = true;
JSONArray::SP threads_info_sp = GetJSONThreadsInfo(
@@ -701,20 +673,18 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
uint32_t i = 0;
response.PutCString("thread-pcs");
char delimiter = ':';
- for (NativeThreadProtocolSP thread_sp;
- (thread_sp = m_debugged_process_up->GetThreadAtIndex(i)) != nullptr;
+ for (NativeThreadProtocol *thread;
+ (thread = m_debugged_process_up->GetThreadAtIndex(i)) != nullptr;
++i) {
- NativeRegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext();
- if (!reg_ctx_sp)
- continue;
+ NativeRegisterContext& reg_ctx = thread->GetRegisterContext();
- uint32_t reg_to_read = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
+ uint32_t reg_to_read = reg_ctx.ConvertRegisterKindToRegisterNumber(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
const RegisterInfo *const reg_info_p =
- reg_ctx_sp->GetRegisterInfoAtIndex(reg_to_read);
+ reg_ctx.GetRegisterInfoAtIndex(reg_to_read);
RegisterValue reg_value;
- Status error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value);
+ Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
if (error.Fail()) {
if (log)
log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s",
@@ -727,7 +697,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
response.PutChar(delimiter);
delimiter = ',';
- WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p,
+ WriteRegisterValueInHexFixedWidth(response, reg_ctx, *reg_info_p,
&reg_value, endian::InlHostByteOrder());
}
@@ -739,49 +709,48 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
//
// Grab the register context.
- NativeRegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext();
- if (reg_ctx_sp) {
- // Expedite all registers in the first register set (i.e. should be GPRs)
- // that are not contained in other registers.
- const RegisterSet *reg_set_p;
- if (reg_ctx_sp->GetRegisterSetCount() > 0 &&
- ((reg_set_p = reg_ctx_sp->GetRegisterSet(0)) != nullptr)) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s expediting registers "
- "from set '%s' (registers set count: %zu)",
- __FUNCTION__,
- reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
- reg_set_p->num_registers);
-
- for (const uint32_t *reg_num_p = reg_set_p->registers;
- *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) {
- const RegisterInfo *const reg_info_p =
- reg_ctx_sp->GetRegisterInfoAtIndex(*reg_num_p);
- if (reg_info_p == nullptr) {
+ NativeRegisterContext& reg_ctx = thread->GetRegisterContext();
+ // Expedite all registers in the first register set (i.e. should be GPRs)
+ // that are not contained in other registers.
+ const RegisterSet *reg_set_p;
+ if (reg_ctx.GetRegisterSetCount() > 0 &&
+ ((reg_set_p = reg_ctx.GetRegisterSet(0)) != nullptr)) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s expediting registers "
+ "from set '%s' (registers set count: %zu)",
+ __FUNCTION__,
+ reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
+ reg_set_p->num_registers);
+
+ for (const uint32_t *reg_num_p = reg_set_p->registers;
+ *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) {
+ const RegisterInfo *const reg_info_p =
+ reg_ctx.GetRegisterInfoAtIndex(*reg_num_p);
+ if (reg_info_p == nullptr) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get "
+ "register info for register set '%s', register index "
+ "%" PRIu32,
+ __FUNCTION__,
+ reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
+ *reg_num_p);
+ } else if (reg_info_p->value_regs == nullptr) {
+ // Only expediate registers that are not contained in other registers.
+ RegisterValue reg_value;
+ Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
+ if (error.Success()) {
+ response.Printf("%.02x:", *reg_num_p);
+ WriteRegisterValueInHexFixedWidth(response, reg_ctx, *reg_info_p,
+ &reg_value, lldb::eByteOrderBig);
+ response.PutChar(';');
+ } else {
if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get "
- "register info for register set '%s', register index "
- "%" PRIu32,
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to read "
+ "register '%s' index %" PRIu32 ": %s",
__FUNCTION__,
- reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
- *reg_num_p);
- } else if (reg_info_p->value_regs == nullptr) {
- // Only expediate registers that are not contained in other registers.
- RegisterValue reg_value;
- Status error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value);
- if (error.Success()) {
- response.Printf("%.02x:", *reg_num_p);
- WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p,
- &reg_value, lldb::eByteOrderBig);
- response.PutChar(';');
- } else {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to read "
- "register '%s' index %" PRIu32 ": %s",
- __FUNCTION__, reg_info_p->name ? reg_info_p->name
- : "<unnamed-register>",
- *reg_num_p, error.AsCString());
- }
+ reg_info_p->name ? reg_info_p->name
+ : "<unnamed-register>",
+ *reg_num_p, error.AsCString());
}
}
}
@@ -831,12 +800,13 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited(
__FUNCTION__, process->GetID());
}
- // Close the pipe to the inferior terminal i/o if we launched it
- // and set one up.
+ // Close the pipe to the inferior terminal i/o if we launched it and set one
+ // up.
MaybeCloseInferiorTerminalConnection();
// We are ready to exit the debug monitor.
m_exit_now = true;
+ m_mainloop.RequestTermination();
}
void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped(
@@ -847,8 +817,7 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped(
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
- // Send the stop reason unless this is the stop after the
- // launch or attach.
+ // Send the stop reason unless this is the stop after the launch or attach.
switch (m_inferior_prev_state) {
case eStateLaunching:
case eStateAttaching:
@@ -883,13 +852,11 @@ void GDBRemoteCommunicationServerLLGS::ProcessStateChanged(
break;
case StateType::eStateStopped:
- // Make sure we get all of the pending stdout/stderr from the inferior
- // and send it to the lldb host before we send the state change
- // notification
+ // Make sure we get all of the pending stdout/stderr from the inferior and
+ // send it to the lldb host before we send the state change notification
SendProcessOutput();
// Then stop the forwarding, so that any late output (see llvm.org/pr25652)
- // does not
- // interfere with our protocol.
+ // does not interfere with our protocol.
StopSTDIOForwarding();
HandleInferiorState_Stopped(process);
break;
@@ -1311,17 +1278,17 @@ GDBRemoteCommunicationServerLLGS::Handle_qC(StringExtractorGDBRemote &packet) {
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
return SendErrorResponse(68);
- // Make sure we set the current thread so g and p packets return
- // the data the gdb will expect.
+ // Make sure we set the current thread so g and p packets return the data the
+ // gdb will expect.
lldb::tid_t tid = m_debugged_process_up->GetCurrentThreadID();
SetCurrentThreadID(tid);
- NativeThreadProtocolSP thread_sp = m_debugged_process_up->GetCurrentThread();
- if (!thread_sp)
+ NativeThreadProtocol *thread = m_debugged_process_up->GetCurrentThread();
+ if (!thread)
return SendErrorResponse(69);
StreamString response;
- response.Printf("QC%" PRIx64, thread_sp->GetID());
+ response.Printf("QC%" PRIx64, thread->GetID());
return SendPacketNoLock(response.GetString());
}
@@ -1364,7 +1331,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir(
packet.SetFilePos(::strlen("QSetWorkingDir:"));
std::string path;
packet.GetHexByteString(path);
- m_process_launch_info.SetWorkingDirectory(FileSpec{path, true});
+ m_process_launch_info.SetWorkingDirectory(FileSpec(path));
return SendOKResponse();
}
@@ -1421,10 +1388,9 @@ GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) {
Status error;
// We have two branches: what to do if a continue thread is specified (in
- // which case we target
- // sending the signal to that thread), or when we don't have a continue thread
- // set (in which
- // case we send a signal to the process).
+ // which case we target sending the signal to that thread), or when we don't
+ // have a continue thread set (in which case we send a signal to the
+ // process).
// TODO discuss with Greg Clayton, make sure this makes sense.
@@ -1663,8 +1629,8 @@ GDBRemoteCommunicationServerLLGS::SendStopReasonForState(
case eStateStopped:
case eStateCrashed: {
lldb::tid_t tid = m_debugged_process_up->GetCurrentThreadID();
- // Make sure we set the current thread so g and p packets return
- // the data the gdb will expect.
+ // Make sure we set the current thread so g and p packets return the data
+ // the gdb will expect.
SetCurrentThreadID(tid);
return SendStopReplyPacketForThread(tid);
}
@@ -1692,14 +1658,12 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
return SendErrorResponse(68);
// Ensure we have a thread.
- NativeThreadProtocolSP thread_sp(m_debugged_process_up->GetThreadAtIndex(0));
- if (!thread_sp)
+ NativeThreadProtocol *thread = m_debugged_process_up->GetThreadAtIndex(0);
+ if (!thread)
return SendErrorResponse(69);
// Get the register context for the first thread.
- NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
- if (!reg_context_sp)
- return SendErrorResponse(69);
+ NativeRegisterContext &reg_context = thread->GetRegisterContext();
// Parse out the register number from the request.
packet.SetFilePos(strlen("qRegisterInfo"));
@@ -1710,11 +1674,10 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
// Return the end of registers response if we've iterated one past the end of
// the register set.
- if (reg_index >= reg_context_sp->GetUserRegisterCount())
+ if (reg_index >= reg_context.GetUserRegisterCount())
return SendErrorResponse(69);
- const RegisterInfo *reg_info =
- reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+ const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index);
if (!reg_info)
return SendErrorResponse(69);
@@ -1796,7 +1759,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
};
const char *const register_set_name =
- reg_context_sp->GetRegisterSetNameForRegisterAtIndex(reg_index);
+ reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index);
if (register_set_name) {
response.PutCString("set:");
response.PutCString(register_set_name);
@@ -1908,18 +1871,17 @@ GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo(
response.PutChar('m');
LLDB_LOG(log, "starting thread iteration");
- NativeThreadProtocolSP thread_sp;
+ NativeThreadProtocol *thread;
uint32_t thread_index;
for (thread_index = 0,
- thread_sp = m_debugged_process_up->GetThreadAtIndex(thread_index);
- thread_sp; ++thread_index,
- thread_sp = m_debugged_process_up->GetThreadAtIndex(thread_index)) {
- LLDB_LOG(log, "iterated thread {0}({1}, tid={2})", thread_index,
- thread_sp ? "is not null" : "null",
- thread_sp ? thread_sp->GetID() : LLDB_INVALID_THREAD_ID);
+ thread = m_debugged_process_up->GetThreadAtIndex(thread_index);
+ thread; ++thread_index,
+ thread = m_debugged_process_up->GetThreadAtIndex(thread_index)) {
+ LLDB_LOG(log, "iterated thread {0}(tid={2})", thread_index,
+ thread->GetID());
if (thread_index > 0)
response.PutChar(',');
- response.Printf("%" PRIx64, thread_sp->GetID());
+ response.Printf("%" PRIx64, thread->GetID());
}
LLDB_LOG(log, "finished thread iteration");
@@ -1951,38 +1913,27 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
}
// Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
- if (!thread_sp) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no thread available",
- __FUNCTION__);
+ NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
+ if (!thread) {
+ LLDB_LOG(log, "failed, no thread available");
return SendErrorResponse(0x15);
}
// Get the thread's register context.
- NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
- if (!reg_context_sp) {
- LLDB_LOG(
- log,
- "pid {0} tid {1} failed, no register context available for the thread",
- m_debugged_process_up->GetID(), thread_sp->GetID());
- return SendErrorResponse(0x15);
- }
+ NativeRegisterContext &reg_context = thread->GetRegisterContext();
// Return the end of registers response if we've iterated one past the end of
// the register set.
- if (reg_index >= reg_context_sp->GetUserRegisterCount()) {
+ if (reg_index >= reg_context.GetUserRegisterCount()) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
"register %" PRIu32 " beyond register count %" PRIu32,
__FUNCTION__, reg_index,
- reg_context_sp->GetUserRegisterCount());
+ reg_context.GetUserRegisterCount());
return SendErrorResponse(0x15);
}
- const RegisterInfo *reg_info =
- reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+ const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index);
if (!reg_info) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
@@ -1996,7 +1947,7 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
// Retrieve the value
RegisterValue reg_value;
- Status error = reg_context_sp->ReadRegister(reg_info, reg_value);
+ Status error = reg_context.ReadRegister(reg_info, reg_value);
if (error.Fail()) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, read of "
@@ -2047,24 +1998,13 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
return SendIllFormedResponse(
packet, "P packet missing '=' char after register number");
- // Get process architecture.
- ArchSpec process_arch;
- if (!m_debugged_process_up ||
- !m_debugged_process_up->GetArchitecture(process_arch)) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to retrieve "
- "inferior architecture",
- __FUNCTION__);
- return SendErrorResponse(0x49);
- }
-
// Parse out the value.
uint8_t reg_bytes[32]; // big enough to support up to 256 bit ymmN register
size_t reg_size = packet.GetHexBytesAvail(reg_bytes);
// Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
- if (!thread_sp) {
+ NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
+ if (!thread) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, no thread "
"available (thread index 0)",
@@ -2073,18 +2013,8 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
}
// Get the thread's register context.
- NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
- if (!reg_context_sp) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64
- " failed, no register context available for the thread",
- __FUNCTION__, m_debugged_process_up->GetID(), thread_sp->GetID());
- return SendErrorResponse(0x15);
- }
-
- const RegisterInfo *reg_info =
- reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+ NativeRegisterContext &reg_context = thread->GetRegisterContext();
+ const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index);
if (!reg_info) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
@@ -2095,18 +2025,16 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
// Return the end of registers response if we've iterated one past the end of
// the register set.
- if (reg_index >= reg_context_sp->GetUserRegisterCount()) {
+ if (reg_index >= reg_context.GetUserRegisterCount()) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
"register %" PRIu32 " beyond register count %" PRIu32,
- __FUNCTION__, reg_index,
- reg_context_sp->GetUserRegisterCount());
+ __FUNCTION__, reg_index, reg_context.GetUserRegisterCount());
return SendErrorResponse(0x47);
}
- // The dwarf expression are evaluate on host site
- // which may cause register size to change
- // Hence the reg_size may not be same as reg_info->bytes_size
+ // The dwarf expression are evaluate on host site which may cause register
+ // size to change Hence the reg_size may not be same as reg_info->bytes_size
if ((reg_size != reg_info->byte_size) &&
!(reg_info->dynamic_size_dwarf_expr_bytes)) {
return SendIllFormedResponse(packet, "P packet register size is incorrect");
@@ -2115,8 +2043,10 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
// Build the reginfos response.
StreamGDBRemote response;
- RegisterValue reg_value(reg_bytes, reg_size, process_arch.GetByteOrder());
- Status error = reg_context_sp->WriteRegister(reg_info, reg_value);
+ RegisterValue reg_value(
+ reg_bytes, reg_size,
+ m_debugged_process_up->GetArchitecture().GetByteOrder());
+ Status error = reg_context.WriteRegister(reg_info, reg_value);
if (error.Fail()) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, write of "
@@ -2177,8 +2107,8 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
// Ensure we have the given thread when not specifying -1 (all threads) or 0
// (any thread).
if (tid != LLDB_INVALID_THREAD_ID && tid != 0) {
- NativeThreadProtocolSP thread_sp(m_debugged_process_up->GetThreadByID(tid));
- if (!thread_sp) {
+ NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid);
+ if (!thread) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64
" not found",
@@ -2435,10 +2365,9 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported(
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
// Currently only the NativeProcessProtocol knows if it can handle a
- // qMemoryRegionInfoSupported
- // request, but we're not guaranteed to be attached to a process. For now
- // we'll assume the
- // client only asks this when a process is being debugged.
+ // qMemoryRegionInfoSupported request, but we're not guaranteed to be
+ // attached to a process. For now we'll assume the client only asks this
+ // when a process is being debugged.
// Ensure we have a process running; otherwise, we can't figure this out
// since we won't have a NativeProcessProtocol.
@@ -2729,8 +2658,7 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
}
// We first try to use a continue thread id. If any one or any all set, use
- // the current thread.
- // Bail out if we don't have a thread id.
+ // the current thread. Bail out if we don't have a thread id.
lldb::tid_t tid = GetContinueThreadID();
if (tid == 0 || tid == LLDB_INVALID_THREAD_ID)
tid = GetCurrentThreadID();
@@ -2739,8 +2667,8 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
// Double check that we have such a thread.
// TODO investigate: on MacOSX we might need to do an UpdateThreads () here.
- NativeThreadProtocolSP thread_sp = m_debugged_process_up->GetThreadByID(tid);
- if (!thread_sp || thread_sp->GetID() != tid)
+ NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid);
+ if (!thread)
return SendErrorResponse(0x33);
// Create the step action for the given thread.
@@ -2770,7 +2698,7 @@ GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read(
StringExtractorGDBRemote &packet) {
// *BSD impls should be able to do this too.
-#if defined(__linux__) || defined(__NetBSD__)
+#if defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__)
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
// Parse out the offset.
@@ -2865,8 +2793,8 @@ GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState(
packet.SetFilePos(strlen("QSaveRegisterState"));
// Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
- if (!thread_sp) {
+ NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
+ if (!thread) {
if (m_thread_suffix_supported)
return SendIllFormedResponse(
packet, "No thread specified in QSaveRegisterState packet");
@@ -2876,18 +2804,11 @@ GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState(
}
// Grab the register context for the thread.
- NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
- if (!reg_context_sp) {
- LLDB_LOG(
- log,
- "pid {0} tid {1} failed, no register context available for the thread",
- m_debugged_process_up->GetID(), thread_sp->GetID());
- return SendErrorResponse(0x15);
- }
+ NativeRegisterContext& reg_context = thread->GetRegisterContext();
// Save registers to a buffer.
DataBufferSP register_data_sp;
- Status error = reg_context_sp->ReadAllRegisterValues(register_data_sp);
+ Status error = reg_context.ReadAllRegisterValues(register_data_sp);
if (error.Fail()) {
LLDB_LOG(log, "pid {0} failed to save all register values: {1}",
m_debugged_process_up->GetID(), error);
@@ -2930,8 +2851,8 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState(
}
// Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
- if (!thread_sp) {
+ NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
+ if (!thread) {
if (m_thread_suffix_supported)
return SendIllFormedResponse(
packet, "No thread specified in QRestoreRegisterState packet");
@@ -2941,14 +2862,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState(
}
// Grab the register context for the thread.
- NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
- if (!reg_context_sp) {
- LLDB_LOG(
- log,
- "pid {0} tid {1} failed, no register context available for the thread",
- m_debugged_process_up->GetID(), thread_sp->GetID());
- return SendErrorResponse(0x15);
- }
+ NativeRegisterContext &reg_context = thread->GetRegisterContext();
// Retrieve register state buffer, then remove from the list.
DataBufferSP register_data_sp;
@@ -2969,7 +2883,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState(
m_saved_registers_map.erase(it);
}
- Status error = reg_context_sp->WriteAllRegisterValues(register_data_sp);
+ Status error = reg_context.WriteAllRegisterValues(register_data_sp);
if (error.Fail()) {
LLDB_LOG(log, "pid {0} failed to restore all register values: {1}",
m_debugged_process_up->GetID(), error);
@@ -3008,7 +2922,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttach(
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to attach to "
"pid %" PRIu64 ": %s\n",
__FUNCTION__, pid, error.AsCString());
- return SendErrorResponse(0x01);
+ return SendErrorResponse(error);
}
// Notify we attached by sending a stop packet.
@@ -3166,8 +3080,8 @@ GDBRemoteCommunicationServerLLGS::Handle_QPassSignals(
std::vector<int> signals;
packet.SetFilePos(strlen("QPassSignals:"));
- // Read sequence of hex signal numbers divided by a semicolon and
- // optionally spaces.
+ // Read sequence of hex signal numbers divided by a semicolon and optionally
+ // spaces.
while (packet.GetBytesLeft() > 0) {
int signal = packet.GetS32(-1, 16);
if (signal < 0)
@@ -3219,22 +3133,19 @@ void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() {
}
}
-NativeThreadProtocolSP GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
+NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
StringExtractorGDBRemote &packet) {
- NativeThreadProtocolSP thread_sp;
-
// We have no thread if we don't have a process.
if (!m_debugged_process_up ||
m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)
- return thread_sp;
+ return nullptr;
// If the client hasn't asked for thread suffix support, there will not be a
- // thread suffix.
- // Use the current thread in that case.
+ // thread suffix. Use the current thread in that case.
if (!m_thread_suffix_supported) {
const lldb::tid_t current_tid = GetCurrentThreadID();
if (current_tid == LLDB_INVALID_THREAD_ID)
- return thread_sp;
+ return nullptr;
else if (current_tid == 0) {
// Pick a thread.
return m_debugged_process_up->GetThreadAtIndex(0);
@@ -3251,11 +3162,11 @@ NativeThreadProtocolSP GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
"error: expected ';' prior to start of thread suffix: packet "
"contents = '%s'",
__FUNCTION__, packet.GetStringRef().c_str());
- return thread_sp;
+ return nullptr;
}
if (!packet.GetBytesLeft())
- return thread_sp;
+ return nullptr;
// Parse out thread: portion.
if (strncmp(packet.Peek(), "thread:", strlen("thread:")) != 0) {
@@ -3264,21 +3175,21 @@ NativeThreadProtocolSP GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
"error: expected 'thread:' but not found, packet contents = "
"'%s'",
__FUNCTION__, packet.GetStringRef().c_str());
- return thread_sp;
+ return nullptr;
}
packet.SetFilePos(packet.GetFilePos() + strlen("thread:"));
const lldb::tid_t tid = packet.GetHexMaxU64(false, 0);
if (tid != 0)
return m_debugged_process_up->GetThreadByID(tid);
- return thread_sp;
+ return nullptr;
}
lldb::tid_t GDBRemoteCommunicationServerLLGS::GetCurrentThreadID() const {
if (m_current_tid == 0 || m_current_tid == LLDB_INVALID_THREAD_ID) {
- // Use whatever the debug process says is the current thread id
- // since the protocol either didn't specify or specified we want
- // any/all threads marked as the current thread.
+ // Use whatever the debug process says is the current thread id since the
+ // protocol either didn't specify or specified we want any/all threads
+ // marked as the current thread.
if (!m_debugged_process_up)
return LLDB_INVALID_THREAD_ID;
return m_debugged_process_up->GetCurrentThreadID();
@@ -3307,7 +3218,7 @@ GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path,
if (m_debugged_process_up
->GetLoadedModuleFileSpec(module_path.c_str(), file_spec)
.Success()) {
- if (file_spec.Exists())
+ if (FileSystem::Instance().Exists(file_spec))
return file_spec;
}
}
diff --git a/gnu/llvm/tools/lldb/source/Utility/ArchSpec.cpp b/gnu/llvm/tools/lldb/source/Utility/ArchSpec.cpp
index a10fe78260b..01accfee83e 100644
--- a/gnu/llvm/tools/lldb/source/Utility/ArchSpec.cpp
+++ b/gnu/llvm/tools/lldb/source/Utility/ArchSpec.cpp
@@ -9,16 +9,17 @@
#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Utility/NameMatches.h"
-#include "lldb/Utility/Stream.h" // for Stream
+#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StringList.h"
-#include "lldb/lldb-defines.h" // for LLDB_INVALID_C...
+#include "lldb/lldb-defines.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Twine.h" // for Twine
+#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/BinaryFormat/ELF.h"
-#include "llvm/BinaryFormat/MachO.h" // for CPUType::CPU_T...
-#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Host.h"
using namespace lldb;
@@ -203,6 +204,8 @@ 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,
@@ -223,8 +226,8 @@ static const CoreDefinition g_core_definitions[] = {
"kalimba5"}};
// Ensure that we have an entry in the g_core_definitions for each core. If you
-// comment out an entry above,
-// you will need to comment out the corresponding ArchSpec::Core enumeration.
+// comment out an entry above, you will need to comment out the corresponding
+// ArchSpec::Core enumeration.
static_assert(sizeof(g_core_definitions) / sizeof(CoreDefinition) ==
ArchSpec::kNumCores,
"make sure we have one core definition for each core");
@@ -244,17 +247,24 @@ struct ArchDefinition {
const char *name;
};
-size_t ArchSpec::AutoComplete(llvm::StringRef name, StringList &matches) {
- if (!name.empty()) {
+void ArchSpec::ListSupportedArchNames(StringList &list) {
+ for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
+ list.AppendString(g_core_definitions[i].name);
+}
+
+size_t ArchSpec::AutoComplete(CompletionRequest &request) {
+ if (!request.GetCursorArgumentPrefix().empty()) {
for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) {
- if (NameMatches(g_core_definitions[i].name, NameMatch::StartsWith, name))
- matches.AppendString(g_core_definitions[i].name);
+ if (NameMatches(g_core_definitions[i].name, NameMatch::StartsWith,
+ request.GetCursorArgumentPrefix()))
+ request.AddCompletion(g_core_definitions[i].name);
}
} else {
- for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
- matches.AppendString(g_core_definitions[i].name);
+ StringList matches;
+ ListSupportedArchNames(matches);
+ request.AddCompletions(matches);
}
- return matches.GetSize();
+ return request.GetNumberOfMatches();
}
#define CPU_ANY (UINT32_MAX)
@@ -602,10 +612,8 @@ const char *ArchSpec::GetArchitectureName() const {
bool ArchSpec::IsMIPS() const {
const llvm::Triple::ArchType machine = GetMachine();
- if (machine == llvm::Triple::mips || machine == llvm::Triple::mipsel ||
- machine == llvm::Triple::mips64 || machine == llvm::Triple::mips64el)
- return true;
- return false;
+ return machine == llvm::Triple::mips || machine == llvm::Triple::mipsel ||
+ machine == llvm::Triple::mips64 || machine == llvm::Triple::mips64el;
}
std::string ArchSpec::GetTargetABI() const {
@@ -807,6 +815,7 @@ bool ArchSpec::CharIsSignedByDefault() const {
case llvm::Triple::ppc64le:
case llvm::Triple::systemz:
case llvm::Triple::xcore:
+ case llvm::Triple::arc:
return false;
}
}
@@ -890,7 +899,12 @@ void ArchSpec::MergeFrom(const ArchSpec &other) {
GetTriple().setOS(other.GetTriple().getOS());
if (GetTriple().getArch() == llvm::Triple::UnknownArch) {
GetTriple().setArch(other.GetTriple().getArch());
- UpdateCore();
+
+ // MachO unknown64 isn't really invalid as the debugger can still obtain
+ // information from the binary, e.g. line tables. As such, we don't update
+ // the core here.
+ if (other.GetCore() != eCore_uknownMach64)
+ UpdateCore();
}
if (GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
!TripleVendorWasSpecified()) {
@@ -898,9 +912,8 @@ void ArchSpec::MergeFrom(const ArchSpec &other) {
GetTriple().setEnvironment(other.GetTriple().getEnvironment());
}
// If this and other are both arm ArchSpecs and this ArchSpec is a generic
- // "some kind of arm"
- // spec but the other ArchSpec is a specific arm core, adopt the specific arm
- // core.
+ // "some kind of arm" spec but the other ArchSpec is a specific arm core,
+ // adopt the specific arm core.
if (GetTriple().getArch() == llvm::Triple::arm &&
other.GetTriple().getArch() == llvm::Triple::arm &&
IsCompatibleMatch(other) && GetCore() == ArchSpec::eCore_arm_generic &&
@@ -926,24 +939,21 @@ bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu,
if (core_def) {
m_core = core_def->core;
update_triple = false;
- // Always use the architecture name because it might be more descriptive
- // than the architecture enum ("armv7" -> llvm::Triple::arm).
+ // Always use the architecture name because it might be more
+ // descriptive than the architecture enum ("armv7" ->
+ // llvm::Triple::arm).
m_triple.setArchName(llvm::StringRef(core_def->name));
if (arch_type == eArchTypeMachO) {
m_triple.setVendor(llvm::Triple::Apple);
// Don't set the OS. It could be simulator, macosx, ios, watchos,
- // tvos. We could
- // get close with the cpu type - but we can't get it right all of the
- // time. Better
- // to leave this unset so other sections of code will set it when they
- // have more
- // information.
- // NB: don't call m_triple.setOS (llvm::Triple::UnknownOS). That sets
- // the OSName to
- // "unknown" and the ArchSpec::TripleVendorWasSpecified() method says
- // that any
- // OSName setting means it was specified.
+ // tvos, bridgeos. We could get close with the cpu type - but we
+ // can't get it right all of the time. Better to leave this unset
+ // so other sections of code will set it when they have more
+ // information. NB: don't call m_triple.setOS (llvm::Triple::UnknownOS).
+ // That sets the OSName to "unknown" and the
+ // ArchSpec::TripleVendorWasSpecified() method says that any OSName
+ // setting means it was specified.
} else if (arch_type == eArchTypeELF) {
switch (os) {
case llvm::ELF::ELFOSABI_AIX:
@@ -972,10 +982,15 @@ bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu,
m_triple.setVendor(llvm::Triple::UnknownVendor);
m_triple.setOS(llvm::Triple::UnknownOS);
}
- // Fall back onto setting the machine type if the arch by name failed...
+ // Fall back onto setting the machine type if the arch by name
+ // failed...
if (m_triple.getArch() == llvm::Triple::UnknownArch)
m_triple.setArch(core_def->machine);
}
+ } else {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET | LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_PLATFORM));
+ if (log)
+ log->Printf("Unable to find a core definition for cpu 0x%" PRIx32 " sub %" PRId32, cpu, sub);
}
}
CoreUpdated(update_triple);
@@ -1004,7 +1019,7 @@ bool ArchSpec::IsCompatibleMatch(const ArchSpec &rhs) const {
return IsEqualTo(rhs, false);
}
-static bool isCompatibleEnvironment(llvm::Triple::EnvironmentType lhs,
+static bool IsCompatibleEnvironment(llvm::Triple::EnvironmentType lhs,
llvm::Triple::EnvironmentType rhs) {
if (lhs == rhs)
return true;
@@ -1015,10 +1030,9 @@ static bool isCompatibleEnvironment(llvm::Triple::EnvironmentType lhs,
return true;
// If one of the environment is Android and the other one is EABI then they
- // are considered to
- // be compatible. This is required as a workaround for shared libraries
- // compiled for Android
- // without the NOTE section indicating that they are using the Android ABI.
+ // are considered to be compatible. This is required as a workaround for
+ // shared libraries compiled for Android without the NOTE section indicating
+ // that they are using the Android ABI.
if ((lhs == llvm::Triple::Android && rhs == llvm::Triple::EABI) ||
(rhs == llvm::Triple::Android && lhs == llvm::Triple::EABI) ||
(lhs == llvm::Triple::GNUEABI && rhs == llvm::Triple::EABI) ||
@@ -1050,8 +1064,8 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const {
if (lhs_triple_vendor != rhs_triple_vendor) {
const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified();
const bool lhs_vendor_specified = TripleVendorWasSpecified();
- // Both architectures had the vendor specified, so if they aren't
- // equal then we return false
+ // Both architectures had the vendor specified, so if they aren't equal
+ // then we return false
if (rhs_vendor_specified && lhs_vendor_specified)
return false;
@@ -1066,8 +1080,8 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const {
if (lhs_triple_os != rhs_triple_os) {
const bool rhs_os_specified = rhs.TripleOSWasSpecified();
const bool lhs_os_specified = TripleOSWasSpecified();
- // Both architectures had the OS specified, so if they aren't
- // equal then we return false
+ // Both architectures had the OS specified, so if they aren't equal then
+ // we return false
if (rhs_os_specified && lhs_os_specified)
return false;
@@ -1082,9 +1096,7 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const {
const llvm::Triple::EnvironmentType rhs_triple_env =
rhs_triple.getEnvironment();
- if (!isCompatibleEnvironment(lhs_triple_env, rhs_triple_env))
- return false;
- return true;
+ return IsCompatibleEnvironment(lhs_triple_env, rhs_triple_env);
}
return false;
}
@@ -1094,9 +1106,9 @@ void ArchSpec::UpdateCore() {
const CoreDefinition *core_def = FindCoreDefinition(arch_name);
if (core_def) {
m_core = core_def->core;
- // Set the byte order to the default byte order for an architecture.
- // This can be modified if needed for cases when cores handle both
- // big and little endian
+ // Set the byte order to the default byte order for an architecture. This
+ // can be modified if needed for cases when cores handle both big and
+ // little endian
m_byte_order = core_def->default_byte_order;
} else {
Clear();
@@ -1193,9 +1205,8 @@ static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2,
break;
// v. https://en.wikipedia.org/wiki/ARM_Cortex-M#Silicon_customization
- // Cortex-M0 - ARMv6-M - armv6m
- // Cortex-M3 - ARMv7-M - armv7m
- // Cortex-M4 - ARMv7E-M - armv7em
+ // Cortex-M0 - ARMv6-M - armv6m Cortex-M3 - ARMv7-M - armv7m Cortex-M4 -
+ // ARMv7E-M - armv7em
case ArchSpec::eCore_arm_armv7em:
if (!enforce_exact_match) {
if (core2 == ArchSpec::eCore_arm_generic)
@@ -1211,9 +1222,8 @@ static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2,
break;
// v. https://en.wikipedia.org/wiki/ARM_Cortex-M#Silicon_customization
- // Cortex-M0 - ARMv6-M - armv6m
- // Cortex-M3 - ARMv7-M - armv7m
- // Cortex-M4 - ARMv7E-M - armv7em
+ // Cortex-M0 - ARMv6-M - armv6m Cortex-M3 - ARMv7-M - armv7m Cortex-M4 -
+ // ARMv7E-M - armv7em
case ArchSpec::eCore_arm_armv7m:
if (!enforce_exact_match) {
if (core2 == ArchSpec::eCore_arm_generic)
@@ -1242,9 +1252,17 @@ 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;
@@ -1411,6 +1429,11 @@ bool lldb_private::operator<(const ArchSpec &lhs, const ArchSpec &rhs) {
return lhs_core < rhs_core;
}
+
+bool lldb_private::operator==(const ArchSpec &lhs, const ArchSpec &rhs) {
+ return lhs.GetCore() == rhs.GetCore();
+}
+
bool ArchSpec::IsFullySpecifiedTriple() const {
const auto &user_specified_triple = GetTriple();
@@ -1456,13 +1479,15 @@ bool ArchSpec::IsAlwaysThumbInstructions() const {
// Cortex-M0 through Cortex-M7 are ARM processor cores which can only
// execute thumb instructions. We map the cores to arch names like this:
//
- // Cortex-M0, Cortex-M0+, Cortex-M1: armv6m
- // Cortex-M3: armv7m
- // Cortex-M4, Cortex-M7: armv7em
+ // Cortex-M0, Cortex-M0+, Cortex-M1: armv6m Cortex-M3: armv7m Cortex-M4,
+ // Cortex-M7: armv7em
if (GetCore() == ArchSpec::Core::eCore_arm_armv7m ||
GetCore() == ArchSpec::Core::eCore_arm_armv7em ||
- GetCore() == ArchSpec::Core::eCore_arm_armv6m) {
+ GetCore() == ArchSpec::Core::eCore_arm_armv6m ||
+ GetCore() == ArchSpec::Core::eCore_thumbv7m ||
+ GetCore() == ArchSpec::Core::eCore_thumbv7em ||
+ GetCore() == ArchSpec::Core::eCore_thumbv6m) {
return true;
}
}
diff --git a/gnu/llvm/tools/lldb/tools/lldb-server/CMakeLists.txt b/gnu/llvm/tools/lldb/tools/lldb-server/CMakeLists.txt
index f8c57cb9488..0b3cbbacd63 100644
--- a/gnu/llvm/tools/lldb/tools/lldb-server/CMakeLists.txt
+++ b/gnu/llvm/tools/lldb/tools/lldb-server/CMakeLists.txt
@@ -22,42 +22,15 @@ include_directories(
)
endif ()
-include_directories(../../source)
-
-set(LLDB_SYSTEM_LIBS)
-if (NOT LLDB_DISABLE_LIBEDIT)
- list(APPEND LLDB_SYSTEM_LIBS edit)
-endif()
-if (NOT LLDB_DISABLE_CURSES)
- list(APPEND LLDB_SYSTEM_LIBS ${CURSES_LIBRARIES})
- if(LLVM_ENABLE_TERMINFO AND HAVE_TERMINFO)
- list(APPEND LLDB_SYSTEM_LIBS ${TERMINFO_LIBS})
- endif()
-endif()
-
-if (NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB )
- list(APPEND LLDB_SYSTEM_LIBS atomic)
-endif()
-
-# On FreeBSD/NetBSD backtrace() is provided by libexecinfo, not libc.
-if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR CMAKE_SYSTEM_NAME MATCHES "NetBSD")
- list(APPEND LLDB_SYSTEM_LIBS execinfo)
-endif()
-
-if (NOT LLDB_DISABLE_PYTHON AND NOT LLVM_BUILD_STATIC)
- list(APPEND LLDB_SYSTEM_LIBS ${PYTHON_LIBRARIES})
-endif()
-
-list(APPEND LLDB_SYSTEM_LIBS ${system_libs})
+if ( CMAKE_SYSTEM_NAME MATCHES "OpenBSD" )
+include_directories(
+ ../../../../llvm/include
+ ../../source/Plugins/Process/OpenBSD
+ ../../source/Plugins/Process/POSIX
+ )
+endif ()
-if (LLVM_BUILD_STATIC)
- if (NOT LLDB_DISABLE_PYTHON)
- list(APPEND LLDB_SYSTEM_LIBS python2.7 util)
- endif()
- if (NOT LLDB_DISABLE_CURSES)
- list(APPEND LLDB_SYSTEM_LIBS gpm)
- endif()
-endif()
+include_directories(../../source)
set(LLDB_PLUGINS)
@@ -69,12 +42,25 @@ if(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
list(APPEND LLDB_PLUGINS lldbPluginProcessNetBSD)
endif()
-add_lldb_tool(lldb-server INCLUDE_IN_FRAMEWORK
+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")
+ list(APPEND LLDB_PLUGINS lldbPluginObjectFilePECOFF)
+else()
+ list(APPEND LLDB_PLUGINS lldbPluginObjectFileELF)
+endif()
+
+add_lldb_tool(lldb-server
Acceptor.cpp
lldb-gdbserver.cpp
lldb-platform.cpp
lldb-server.cpp
LLDBServerUtilities.cpp
+ SystemInitializerLLGS.cpp
LINK_LIBS
lldbBase
@@ -89,4 +75,4 @@ add_lldb_tool(lldb-server INCLUDE_IN_FRAMEWORK
Support
)
-target_link_libraries(lldb-server ${LLDB_SYSTEM_LIBS})
+target_link_libraries(lldb-server PRIVATE ${LLDB_SYSTEM_LIBS})
diff --git a/gnu/llvm/tools/lldb/tools/lldb-server/lldb-gdbserver.cpp b/gnu/llvm/tools/lldb/tools/lldb-server/lldb-gdbserver.cpp
index f1a9b113c8e..78384e97a00 100644
--- a/gnu/llvm/tools/lldb/tools/lldb-server/lldb-gdbserver.cpp
+++ b/gnu/llvm/tools/lldb/tools/lldb-server/lldb-gdbserver.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
@@ -19,8 +18,6 @@
#include <unistd.h>
#endif
-// C++ Includes
-
#include "Acceptor.h"
#include "LLDBServerUtilities.h"
@@ -28,6 +25,7 @@
#include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostGetOpt.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Host/Pipe.h"
@@ -42,6 +40,8 @@
#include "Plugins/Process/Linux/NativeProcessLinux.h"
#elif defined(__NetBSD__)
#include "Plugins/Process/NetBSD/NativeProcessNetBSD.h"
+#elif defined(__OpenBSD__)
+#include "Plugins/Process/OpenBSD/NativeProcessOpenBSD.h"
#endif
#ifndef LLGS_PROGRAM_NAME
@@ -63,6 +63,8 @@ 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;
#else
// Dummy implementation to make sure the code compiles
class NativeProcessFactory : public NativeProcessProtocol::Factory {
@@ -106,6 +108,7 @@ static struct option g_long_options[] = {
// than llgs listening for a connection from address on port.
{"setsid", no_argument, NULL,
'S'}, // Call setsid() to make llgs run in its own session.
+ {"fd", required_argument, NULL, 'F'},
{NULL, 0, NULL, 0}};
//----------------------------------------------------------------------
@@ -132,13 +135,13 @@ static void display_usage(const char *progname, const char *subcommand) {
"[--log-file log-file-name] "
"[--log-channels log-channel-list] "
"[--setsid] "
+ "[--fd file-descriptor]"
"[--named-pipe named-pipe-path] "
"[--native-regs] "
"[--attach pid] "
"[[HOST]:PORT] "
"[-- PROGRAM ARG1 ARG2 ...]\n",
progname, subcommand);
- exit(0);
}
void handle_attach_to_pid(GDBRemoteCommunicationServerLLGS &gdb_server,
@@ -176,27 +179,27 @@ void handle_attach(GDBRemoteCommunicationServerLLGS &gdb_server,
void handle_launch(GDBRemoteCommunicationServerLLGS &gdb_server, int argc,
const char *const argv[]) {
- Status error;
- error = gdb_server.SetLaunchArguments(argv, argc);
- if (error.Fail()) {
- fprintf(stderr, "error: failed to set launch args for '%s': %s\n", argv[0],
- error.AsCString());
+ ProcessLaunchInfo info;
+ info.GetFlags().Set(eLaunchFlagStopAtEntry | eLaunchFlagDebug |
+ eLaunchFlagDisableASLR);
+ info.SetArguments(const_cast<const char **>(argv), true);
+
+ llvm::SmallString<64> cwd;
+ if (std::error_code ec = llvm::sys::fs::current_path(cwd)) {
+ llvm::errs() << "Error getting current directory: " << ec.message() << "\n";
exit(1);
}
+ FileSpec cwd_spec(cwd);
+ FileSystem::Instance().Resolve(cwd_spec);
+ info.SetWorkingDirectory(cwd_spec);
+ info.GetEnvironment() = Host::GetEnvironment();
- unsigned int launch_flags = eLaunchFlagStopAtEntry | eLaunchFlagDebug;
-
- error = gdb_server.SetLaunchFlags(launch_flags);
- if (error.Fail()) {
- fprintf(stderr, "error: failed to set launch flags for '%s': %s\n", argv[0],
- error.AsCString());
- exit(1);
- }
+ gdb_server.SetLaunchInfo(info);
- error = gdb_server.LaunchProcess();
+ Status error = gdb_server.LaunchProcess();
if (error.Fail()) {
- fprintf(stderr, "error: failed to launch '%s': %s\n", argv[0],
- error.AsCString());
+ llvm::errs() << llvm::formatv("error: failed to launch '{0}': {1}\n",
+ argv[0], error);
exit(1);
}
}
@@ -219,23 +222,44 @@ Status writeSocketIdToPipe(const char *const named_pipe_path,
return writeSocketIdToPipe(port_name_pipe, socket_id);
}
-Status writeSocketIdToPipe(int unnamed_pipe_fd, const std::string &socket_id) {
-#if defined(_WIN32)
- return Status("Unnamed pipes are not supported on Windows.");
-#else
- Pipe port_pipe{Pipe::kInvalidDescriptor, unnamed_pipe_fd};
+Status writeSocketIdToPipe(lldb::pipe_t unnamed_pipe,
+ const std::string &socket_id) {
+ Pipe port_pipe{LLDB_INVALID_PIPE, unnamed_pipe};
return writeSocketIdToPipe(port_pipe, socket_id);
-#endif
}
void ConnectToRemote(MainLoop &mainloop,
GDBRemoteCommunicationServerLLGS &gdb_server,
bool reverse_connect, const char *const host_and_port,
const char *const progname, const char *const subcommand,
- const char *const named_pipe_path, int unnamed_pipe_fd) {
+ const char *const named_pipe_path, pipe_t unnamed_pipe,
+ int connection_fd) {
Status error;
- if (host_and_port && host_and_port[0]) {
+ std::unique_ptr<Connection> connection_up;
+ if (connection_fd != -1) {
+ // Build the connection string.
+ char connection_url[512];
+ snprintf(connection_url, sizeof(connection_url), "fd://%d", connection_fd);
+
+ // Create the connection.
+#if !defined LLDB_DISABLE_POSIX && !defined _WIN32
+ ::fcntl(connection_fd, F_SETFD, FD_CLOEXEC);
+#endif
+ connection_up.reset(new ConnectionFileDescriptor);
+ auto connection_result = connection_up->Connect(connection_url, &error);
+ if (connection_result != eConnectionStatusSuccess) {
+ fprintf(stderr, "error: failed to connect to client at '%s' "
+ "(connection status: %d)\n",
+ connection_url, static_cast<int>(connection_result));
+ exit(-1);
+ }
+ if (error.Fail()) {
+ fprintf(stderr, "error: failed to connect to client at '%s': %s\n",
+ connection_url, error.AsCString());
+ exit(-1);
+ }
+ } else if (host_and_port && host_and_port[0]) {
// Parse out host and port.
std::string final_host_and_port;
std::string connection_host;
@@ -255,7 +279,6 @@ void ConnectToRemote(MainLoop &mainloop,
connection_portno = StringConvert::ToUInt32(connection_port.c_str(), 0);
}
- std::unique_ptr<Connection> connection_up;
if (reverse_connect) {
// llgs will connect to the gdb-remote client.
@@ -263,7 +286,7 @@ void ConnectToRemote(MainLoop &mainloop,
// Ensure we have a port number for the connection.
if (connection_portno == 0) {
fprintf(stderr, "error: port number must be specified on when using "
- "reverse connect");
+ "reverse connect\n");
exit(1);
}
@@ -277,12 +300,12 @@ void ConnectToRemote(MainLoop &mainloop,
auto connection_result = connection_up->Connect(connection_url, &error);
if (connection_result != eConnectionStatusSuccess) {
fprintf(stderr, "error: failed to connect to client at '%s' "
- "(connection status: %d)",
+ "(connection status: %d)\n",
connection_url, static_cast<int>(connection_result));
exit(-1);
}
if (error.Fail()) {
- fprintf(stderr, "error: failed to connect to client at '%s': %s",
+ fprintf(stderr, "error: failed to connect to client at '%s': %s\n",
connection_url, error.AsCString());
exit(-1);
}
@@ -290,7 +313,7 @@ void ConnectToRemote(MainLoop &mainloop,
std::unique_ptr<Acceptor> acceptor_up(
Acceptor::Create(final_host_and_port, false, error));
if (error.Fail()) {
- fprintf(stderr, "failed to create acceptor: %s", error.AsCString());
+ fprintf(stderr, "failed to create acceptor: %s\n", error.AsCString());
exit(1);
}
error = acceptor_up->Listen(1);
@@ -304,15 +327,15 @@ void ConnectToRemote(MainLoop &mainloop,
if (named_pipe_path && named_pipe_path[0]) {
error = writeSocketIdToPipe(named_pipe_path, socket_id);
if (error.Fail())
- fprintf(stderr, "failed to write to the named pipe \'%s\': %s",
+ fprintf(stderr, "failed to write to the named pipe \'%s\': %s\n",
named_pipe_path, error.AsCString());
}
// If we have an unnamed pipe to write the socket id back to, do that
// now.
- else if (unnamed_pipe_fd >= 0) {
- error = writeSocketIdToPipe(unnamed_pipe_fd, socket_id);
+ else if (unnamed_pipe != LLDB_INVALID_PIPE) {
+ error = writeSocketIdToPipe(unnamed_pipe, socket_id);
if (error.Fail())
- fprintf(stderr, "failed to write to the unnamed pipe: %s",
+ fprintf(stderr, "failed to write to the unnamed pipe: %s\n",
error.AsCString());
}
} else {
@@ -328,14 +351,14 @@ void ConnectToRemote(MainLoop &mainloop,
}
connection_up.reset(conn);
}
- error = gdb_server.InitializeConnection(std::move(connection_up));
- if (error.Fail()) {
- fprintf(stderr, "Failed to initialize connection: %s\n",
- error.AsCString());
- exit(-1);
- }
- printf("Connection established.\n");
}
+ error = gdb_server.InitializeConnection(std::move(connection_up));
+ if (error.Fail()) {
+ fprintf(stderr, "Failed to initialize connection: %s\n",
+ error.AsCString());
+ exit(-1);
+ }
+ printf("Connection established.\n");
}
//----------------------------------------------------------------------
@@ -362,8 +385,9 @@ int main_gdbserver(int argc, char *argv[]) {
std::string log_file;
StringRef
log_channels; // e.g. "lldb process threads:gdb-remote default:linux all"
- int unnamed_pipe_fd = -1;
+ lldb::pipe_t unnamed_pipe = LLDB_INVALID_PIPE;
bool reverse_connect = false;
+ int connection_fd = -1;
// ProcessLaunchInfo launch_info;
ProcessAttachInfo attach_info;
@@ -402,7 +426,7 @@ int main_gdbserver(int argc, char *argv[]) {
case 'U': // unnamed pipe
if (optarg && optarg[0])
- unnamed_pipe_fd = StringConvert::ToUInt32(optarg, -1);
+ unnamed_pipe = (pipe_t)StringConvert::ToUInt64(optarg, -1);
break;
case 'r':
@@ -413,6 +437,10 @@ int main_gdbserver(int argc, char *argv[]) {
reverse_connect = true;
break;
+ case 'F':
+ connection_fd = StringConvert::ToUInt32(optarg, -1);
+ break;
+
#ifndef _WIN32
case 'S':
// Put llgs into a new session. Terminals group processes
@@ -472,7 +500,8 @@ int main_gdbserver(int argc, char *argv[]) {
argc -= optind;
argv += optind;
- if (argc == 0) {
+ if (argc == 0 && connection_fd == -1) {
+ fputs("No arguments\n", stderr);
display_usage(progname, subcommand);
exit(255);
}
@@ -500,8 +529,8 @@ int main_gdbserver(int argc, char *argv[]) {
printf("%s-%s", LLGS_PROGRAM_NAME, LLGS_VERSION_STR);
ConnectToRemote(mainloop, gdb_server, reverse_connect, host_and_port,
- progname, subcommand, named_pipe_path.c_str(),
- unnamed_pipe_fd);
+ progname, subcommand, named_pipe_path.c_str(),
+ unnamed_pipe, connection_fd);
if (!gdb_server.IsConnected()) {
fprintf(stderr, "no connection information provided, unable to run\n");
diff --git a/gnu/usr.bin/clang/Makefile b/gnu/usr.bin/clang/Makefile
index 13656a7cf6d..7774de69a80 100644
--- a/gnu/usr.bin/clang/Makefile
+++ b/gnu/usr.bin/clang/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.11 2019/03/05 09:44:38 jsg Exp $
+# $OpenBSD: Makefile,v 1.12 2019/11/09 16:45:48 mortimer Exp $
.include <bsd.own.mk>
@@ -87,6 +87,7 @@ SUBDIR+=liblldbTarget
SUBDIR+=liblldbUtility
SUBDIR+=lldb
+SUBDIR+=lldb-server
.include <bsd.obj.mk>
.include <bsd.subdir.mk>
diff --git a/gnu/usr.bin/clang/liblldbPluginProcess/Makefile b/gnu/usr.bin/clang/liblldbPluginProcess/Makefile
index a06e216090b..acbb117b1d1 100644
--- a/gnu/usr.bin/clang/liblldbPluginProcess/Makefile
+++ b/gnu/usr.bin/clang/liblldbPluginProcess/Makefile
@@ -1,11 +1,12 @@
-# $OpenBSD: Makefile,v 1.3 2019/06/23 22:07:44 patrick Exp $
+# $OpenBSD: Makefile,v 1.4 2019/11/09 16:45:48 mortimer Exp $
LIB= lldbPluginProcess
NOPIC=
NOPROFILE=
.include <bsd.own.mk>
-SRCS= DynamicRegisterInfo.cpp \
+SRCS= CrashReason.cpp \
+ DynamicRegisterInfo.cpp \
FreeBSDSignals.cpp \
GDBRemoteClientBase.cpp \
GDBRemoteCommunication.cpp \
@@ -13,6 +14,7 @@ SRCS= DynamicRegisterInfo.cpp \
GDBRemoteCommunicationHistory.cpp \
GDBRemoteCommunicationReplayServer.cpp \
GDBRemoteCommunicationServer.cpp \
+ GDBRemoteCommunicationServerCommon.cpp \
GDBRemoteCommunicationServerLLGS.cpp \
GDBRemoteCommunicationServerPlatform.cpp \
GDBRemoteRegisterContext.cpp \
@@ -25,13 +27,19 @@ SRCS= DynamicRegisterInfo.cpp \
MinidumpParser.cpp \
MinidumpTypes.cpp \
MipsLinuxSignals.cpp \
+ NativeProcessOpenBSD.cpp \
+ NativeRegisterContextOpenBSD.cpp \
+ NativeRegisterContextOpenBSD_x86_64.cpp \
NativeRegisterContextRegisterInfo.cpp \
+ NativeThreadOpenBSD.cpp \
NetBSDSignals.cpp \
ProcessElfCore.cpp \
ProcessGDBRemote.cpp \
ProcessGDBRemoteLog.cpp \
ProcessMachCore.cpp \
+ ProcessMessage.cpp \
ProcessMinidump.cpp \
+ ProcessPOSIXLog.cpp \
RegisterContextDarwin_arm.cpp \
RegisterContextDarwin_arm64.cpp \
RegisterContextDarwin_i386.cpp \
@@ -93,6 +101,8 @@ SRCS= DynamicRegisterInfo.cpp \
.PATH: ${.CURDIR}/../../../llvm/tools/lldb/source/Plugins/Process/gdb-remote
.PATH: ${.CURDIR}/../../../llvm/tools/lldb/source/Plugins/Process/mach-core
.PATH: ${.CURDIR}/../../../llvm/tools/lldb/source/Plugins/Process/minidump
+.PATH: ${.CURDIR}/../../../llvm/tools/lldb/source/Plugins/Process/POSIX
+.PATH: ${.CURDIR}/../../../llvm/tools/lldb/source/Plugins/Process/OpenBSD
install:
@# Nothing here so far ...
diff --git a/gnu/usr.bin/clang/lldb-server/Makefile b/gnu/usr.bin/clang/lldb-server/Makefile
new file mode 100644
index 00000000000..2e1c46ef1bd
--- /dev/null
+++ b/gnu/usr.bin/clang/lldb-server/Makefile
@@ -0,0 +1,81 @@
+# $OpenBSD: Makefile,v 1.1 2019/11/09 16:45:48 mortimer Exp $
+
+.include <bsd.own.mk>
+
+NOPROG= lldb-server
+BINDIR= /usr/bin
+NOMAN=
+
+SRCS= Acceptor.cpp \
+ LLDBServerUtilities.cpp \
+ SystemInitializerLLGS.cpp \
+ lldb-platform.cpp \
+ lldb-gdbserver.cpp \
+ lldb-server.cpp \
+ lldb.cpp \
+
+LDADD+= -lcurses -ledit -lpanel
+
+
+.PATH: ${.CURDIR}/../../../llvm/tools/lldb/source
+.PATH: ${.CURDIR}/../../../llvm/tools/lldb/tools/lldb-server
+
+LLVM_LIBDEPS= clangAST \
+ clangAnalysis \
+ clangBasic \
+ clangBasicTargets \
+ clangCodeGen \
+ clangDriver \
+ clangDriverArch \
+ clangEdit \
+ clangFrontend \
+ clangLex \
+ clangParse \
+ clangRewrite \
+ clangRewriteFrontend \
+ clangSema \
+ clangSerialization \
+ lldbABI \
+ lldbAPI \
+ lldbBreakpoint \
+ lldbCommands \
+ lldbCore \
+ lldbDataFormatters \
+ lldbExpression \
+ lldbHostCommon \
+ lldbHostOpenBSD \
+ lldbHostPOSIX \
+ lldbInitialization \
+ lldbInterpreter \
+ lldbPluginArchitecture \
+ lldbPluginDisassembler \
+ lldbPluginDynamicLoader \
+ lldbPluginExpressionParser \
+ lldbPluginInstruction \
+ lldbPluginInstrumentationRuntime \
+ lldbPluginJITLoader \
+ lldbPluginLanguage \
+ lldbPluginLanguageRuntime \
+ lldbPluginMemoryHistory \
+ lldbPluginObjectContainer \
+ lldbPluginObjectFile \
+ lldbPluginOperatingSystem \
+ lldbPluginPlatform \
+ lldbPluginProcess \
+ lldbPluginScriptInterpreter \
+ lldbPluginStructuredData \
+ lldbPluginSymbolFile \
+ lldbPluginSymbolVendor \
+ lldbPluginSystemRuntime \
+ lldbPluginUnwindAssembly \
+ lldbSymbol \
+ lldbTarget \
+ lldbUtility
+
+
+LDADD+= -L ${.OBJDIR}/../libLLVM -lLLVM
+
+.include <bsd.prog.mk>
+
+CPPFLAGS+= ${LLDB_INCLUDES} \
+ ${CLANG_INCLUDES}