aboutsummaryrefslogtreecommitdiffstats
path: root/source/Plugins
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2015-02-09 01:44:09 +0000
committerEd Maste <emaste@FreeBSD.org>2015-02-09 01:44:09 +0000
commit12bd4897ff0678fa663e09d78ebc22dd255ceb86 (patch)
treea8f4b3abea3e6937e60728991c736e6e3d322fc1 /source/Plugins
parent205afe679855a4ce8149cdaa94d3f0868ce796dc (diff)
downloadsrc-12bd4897ff0678fa663e09d78ebc22dd255ceb86.tar.gz
src-12bd4897ff0678fa663e09d78ebc22dd255ceb86.zip
Import LLDB as of upstream SVN 228549 (git 39760838)vendor/lldb/lldb-r228549
Notes
Notes: svn path=/vendor/lldb/dist/; revision=278425 svn path=/vendor/lldb/lldb-r228549/; revision=278426; tag=vendor/lldb/lldb-r228549
Diffstat (limited to 'source/Plugins')
-rw-r--r--source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp6
-rw-r--r--source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp10
-rw-r--r--source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp21
-rw-r--r--source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp20
-rw-r--r--source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp20
-rw-r--r--source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp27
-rw-r--r--source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp4
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp32
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h3
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp3
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp3
-rw-r--r--source/Plugins/Platform/POSIX/PlatformPOSIX.cpp84
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp146
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h6
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.cpp183
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.h15
-rw-r--r--source/Plugins/Process/POSIX/CrashReason.cpp315
-rw-r--r--source/Plugins/Process/POSIX/CrashReason.h62
-rw-r--r--source/Plugins/Process/POSIX/POSIXStopInfo.cpp15
-rw-r--r--source/Plugins/Process/POSIX/POSIXStopInfo.h22
-rw-r--r--source/Plugins/Process/POSIX/ProcessMessage.cpp190
-rw-r--r--source/Plugins/Process/POSIX/ProcessMessage.h51
-rw-r--r--source/Plugins/Process/POSIX/ProcessPOSIX.cpp11
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp53
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h9
-rw-r--r--source/Plugins/Process/Utility/DynamicRegisterInfo.cpp6
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp39
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLLDB.cpp7
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp5
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_i386.h3
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp24
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp51
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h45
-rw-r--r--source/Plugins/Process/Utility/RegisterContext_powerpc.h79
-rw-r--r--source/Plugins/Process/Utility/RegisterInfoInterface.h11
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_powerpc.h42
-rw-r--r--source/Plugins/Process/Utility/lldb-x86-register-enums.h6
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.cpp6
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp29
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h11
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.cpp5
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.h2
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp49
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h13
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp86
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h32
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp420
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h8
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp62
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp7
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp32
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp147
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h7
-rw-r--r--source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp6
55 files changed, 1658 insertions, 897 deletions
diff --git a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
index 5073b13f09ab..42acba232de1 100644
--- a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
+++ b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
@@ -334,11 +334,11 @@ ABIMacOSX_arm::GetArgumentValues (Thread &thread,
size_t bit_width = 0;
if (clang_type.IsIntegerType (is_signed))
{
- bit_width = clang_type.GetBitSize();
+ bit_width = clang_type.GetBitSize(nullptr);
}
else if (clang_type.IsPointerOrReferenceType ())
{
- bit_width = clang_type.GetBitSize();
+ bit_width = clang_type.GetBitSize(nullptr);
}
else
{
@@ -437,7 +437,7 @@ ABIMacOSX_arm::GetReturnValueObjectImpl (Thread &thread,
const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfoByName("r0", 0);
if (clang_type.IsIntegerType (is_signed))
{
- size_t bit_width = clang_type.GetBitSize();
+ size_t bit_width = clang_type.GetBitSize(nullptr);
switch (bit_width)
{
diff --git a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
index 465257db31d8..c2ba165afb4a 100644
--- a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
+++ b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
@@ -322,11 +322,11 @@ ABIMacOSX_arm64::GetArgumentValues (Thread &thread, ValueList &values) const
size_t bit_width = 0;
if (value_type.IsIntegerType (is_signed))
{
- bit_width = value_type.GetBitSize();
+ bit_width = value_type.GetBitSize(nullptr);
}
else if (value_type.IsPointerOrReferenceType ())
{
- bit_width = value_type.GetBitSize();
+ bit_width = value_type.GetBitSize(nullptr);
}
else
{
@@ -709,7 +709,7 @@ LoadValueFromConsecutiveGPRRegisters (ExecutionContext &exe_ctx,
uint32_t &NSRN, // NSRN (see ABI documentation)
DataExtractor &data)
{
- const size_t byte_size = value_type.GetByteSize();
+ const size_t byte_size = value_type.GetByteSize(nullptr);
if (byte_size == 0)
return false;
@@ -728,7 +728,7 @@ LoadValueFromConsecutiveGPRRegisters (ExecutionContext &exe_ctx,
{
if (!base_type)
return false;
- const size_t base_byte_size = base_type.GetByteSize();
+ const size_t base_byte_size = base_type.GetByteSize(nullptr);
printf ("ClangASTContext::IsHomogeneousAggregate() => base_byte_size = %" PRIu64 "\n", (uint64_t) base_byte_size);
uint32_t data_offset = 0;
@@ -871,7 +871,7 @@ ABIMacOSX_arm64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_
if (!reg_ctx)
return return_valobj_sp;
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
const uint32_t type_flags = return_clang_type.GetTypeInfo (NULL);
if (type_flags & eTypeIsScalar ||
diff --git a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
index 9a1ea11cbae7..ee5b9298721b 100644
--- a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
+++ b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
@@ -552,7 +552,7 @@ ABIMacOSX_i386::GetArgumentValues (Thread &thread,
if (clang_type.IsIntegerType (is_signed))
{
ReadIntegerArgument(value->GetScalar(),
- clang_type.GetBitSize(),
+ clang_type.GetBitSize(nullptr),
is_signed,
thread.GetProcess().get(),
current_stack_argument);
@@ -560,7 +560,7 @@ ABIMacOSX_i386::GetArgumentValues (Thread &thread,
else if (clang_type.IsPointerType())
{
ReadIntegerArgument(value->GetScalar(),
- clang_type.GetBitSize(),
+ clang_type.GetBitSize(nullptr),
false,
thread.GetProcess().get(),
current_stack_argument);
@@ -672,7 +672,7 @@ ABIMacOSX_i386::GetReturnValueObjectImpl (Thread &thread,
if (clang_type.IsIntegerType (is_signed))
{
- size_t bit_width = clang_type.GetBitSize();
+ size_t bit_width = clang_type.GetBitSize(nullptr);
unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
unsigned edx_id = reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];
@@ -732,6 +732,10 @@ ABIMacOSX_i386::GetReturnValueObjectImpl (Thread &thread,
return return_valobj_sp;
}
+// This defines the CFA as esp+4
+// the saved pc is at CFA-4 (i.e. esp+0)
+// The saved esp is CFA+0
+
bool
ABIMacOSX_i386::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
{
@@ -745,12 +749,18 @@ ABIMacOSX_i386::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
row->SetCFARegister (sp_reg_num);
row->SetCFAOffset (4);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);
+ row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
unwind_plan.AppendRow (row);
unwind_plan.SetSourceName ("i386 at-func-entry default");
unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
return true;
}
+// This defines the CFA as ebp+8
+// The saved pc is at CFA-4 (i.e. ebp+4)
+// The saved ebp is at CFA-8 (i.e. ebp+0)
+// The saved esp is CFA+0
+
bool
ABIMacOSX_i386::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
{
@@ -786,6 +796,11 @@ ABIMacOSX_i386::RegisterIsVolatile (const RegisterInfo *reg_info)
}
// v. http://developer.apple.com/library/mac/#documentation/developertools/Conceptual/LowLevelABI/130-IA-32_Function_Calling_Conventions/IA32.html#//apple_ref/doc/uid/TP40002492-SW4
+//
+// This document ("OS X ABI Function Call Guide", chapter "IA-32 Function Calling Conventions")
+// says that the following registers on i386 are preserved aka non-volatile aka callee-saved:
+//
+// ebx, ebp, esi, edi, esp
bool
ABIMacOSX_i386::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
diff --git a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
index adb3313d1a30..741afebfcb8b 100644
--- a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
+++ b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
@@ -444,7 +444,7 @@ ABISysV_ppc::GetArgumentValues (Thread &thread,
if (clang_type.IsIntegerType (is_signed))
{
ReadIntegerArgument(value->GetScalar(),
- clang_type.GetBitSize(),
+ clang_type.GetBitSize(nullptr),
is_signed,
thread,
argument_register_ids,
@@ -454,7 +454,7 @@ ABISysV_ppc::GetArgumentValues (Thread &thread,
else if (clang_type.IsPointerType ())
{
ReadIntegerArgument(value->GetScalar(),
- clang_type.GetBitSize(),
+ clang_type.GetBitSize(nullptr),
false,
thread,
argument_register_ids,
@@ -524,7 +524,7 @@ ABISysV_ppc::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjec
error.SetErrorString ("We don't support returning complex values at present");
else
{
- size_t bit_width = clang_type.GetBitSize();
+ size_t bit_width = clang_type.GetBitSize(nullptr);
if (bit_width <= 64)
{
DataExtractor data;
@@ -588,7 +588,7 @@ ABISysV_ppc::GetReturnValueObjectSimple (Thread &thread,
{
// Extract the register context so we can read arguments from registers
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r3", 0), 0);
const bool is_signed = (type_flags & eTypeIsSigned) != 0;
switch (byte_size)
@@ -637,7 +637,7 @@ ABISysV_ppc::GetReturnValueObjectSimple (Thread &thread,
}
else
{
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
if (byte_size <= sizeof(long double))
{
const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
@@ -681,13 +681,11 @@ ABISysV_ppc::GetReturnValueObjectSimple (Thread &thread,
}
else if (type_flags & eTypeIsVector)
{
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
if (byte_size > 0)
{
- const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v0", 0);
- if (altivec_reg == NULL)
- altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
+ const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
if (altivec_reg)
{
if (byte_size <= altivec_reg->byte_size)
@@ -742,7 +740,7 @@ ABISysV_ppc::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_clan
if (!reg_ctx_sp)
return return_valobj_sp;
- const size_t bit_width = return_clang_type.GetBitSize();
+ const size_t bit_width = return_clang_type.GetBitSize(nullptr);
if (return_clang_type.IsAggregateType())
{
Target *target = exe_ctx.GetTargetPtr();
@@ -784,7 +782,7 @@ ABISysV_ppc::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_clan
uint32_t count;
ClangASTType field_clang_type = return_clang_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
- const size_t field_bit_width = field_clang_type.GetBitSize();
+ const size_t field_bit_width = field_clang_type.GetBitSize(nullptr);
// If there are any unaligned fields, this is stored in memory.
if (field_bit_offset % field_bit_width != 0)
diff --git a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
index 46f1e1023f0a..88c18fb6f202 100644
--- a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
+++ b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
@@ -444,7 +444,7 @@ ABISysV_ppc64::GetArgumentValues (Thread &thread,
if (clang_type.IsIntegerType (is_signed))
{
ReadIntegerArgument(value->GetScalar(),
- clang_type.GetBitSize(),
+ clang_type.GetBitSize(nullptr),
is_signed,
thread,
argument_register_ids,
@@ -454,7 +454,7 @@ ABISysV_ppc64::GetArgumentValues (Thread &thread,
else if (clang_type.IsPointerType ())
{
ReadIntegerArgument(value->GetScalar(),
- clang_type.GetBitSize(),
+ clang_type.GetBitSize(nullptr),
false,
thread,
argument_register_ids,
@@ -524,7 +524,7 @@ ABISysV_ppc64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObj
error.SetErrorString ("We don't support returning complex values at present");
else
{
- size_t bit_width = clang_type.GetBitSize();
+ size_t bit_width = clang_type.GetBitSize(nullptr);
if (bit_width <= 64)
{
DataExtractor data;
@@ -588,7 +588,7 @@ ABISysV_ppc64::GetReturnValueObjectSimple (Thread &thread,
{
// Extract the register context so we can read arguments from registers
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r3", 0), 0);
const bool is_signed = (type_flags & eTypeIsSigned) != 0;
switch (byte_size)
@@ -637,7 +637,7 @@ ABISysV_ppc64::GetReturnValueObjectSimple (Thread &thread,
}
else
{
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
if (byte_size <= sizeof(long double))
{
const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
@@ -681,13 +681,11 @@ ABISysV_ppc64::GetReturnValueObjectSimple (Thread &thread,
}
else if (type_flags & eTypeIsVector)
{
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
if (byte_size > 0)
{
- const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v0", 0);
- if (altivec_reg == NULL)
- altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
+ const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
if (altivec_reg)
{
if (byte_size <= altivec_reg->byte_size)
@@ -742,7 +740,7 @@ ABISysV_ppc64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_cl
if (!reg_ctx_sp)
return return_valobj_sp;
- const size_t bit_width = return_clang_type.GetBitSize();
+ const size_t bit_width = return_clang_type.GetBitSize(nullptr);
if (return_clang_type.IsAggregateType())
{
Target *target = exe_ctx.GetTargetPtr();
@@ -784,7 +782,7 @@ ABISysV_ppc64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_cl
uint32_t count;
ClangASTType field_clang_type = return_clang_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
- const size_t field_bit_width = field_clang_type.GetBitSize();
+ const size_t field_bit_width = field_clang_type.GetBitSize(nullptr);
// If there are any unaligned fields, this is stored in memory.
if (field_bit_offset % field_bit_width != 0)
diff --git a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
index 776e7fea67c7..71d99c8c65d2 100644
--- a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
+++ b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
@@ -510,7 +510,7 @@ ABISysV_x86_64::GetArgumentValues (Thread &thread,
if (clang_type.IsIntegerType (is_signed))
{
ReadIntegerArgument(value->GetScalar(),
- clang_type.GetBitSize(),
+ clang_type.GetBitSize(nullptr),
is_signed,
thread,
argument_register_ids,
@@ -520,7 +520,7 @@ ABISysV_x86_64::GetArgumentValues (Thread &thread,
else if (clang_type.IsPointerType ())
{
ReadIntegerArgument(value->GetScalar(),
- clang_type.GetBitSize(),
+ clang_type.GetBitSize(nullptr),
false,
thread,
argument_register_ids,
@@ -590,7 +590,7 @@ ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb
error.SetErrorString ("We don't support returning complex values at present");
else
{
- size_t bit_width = clang_type.GetBitSize();
+ size_t bit_width = clang_type.GetBitSize(nullptr);
if (bit_width <= 64)
{
const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
@@ -658,7 +658,7 @@ ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread,
{
// Extract the register context so we can read arguments from registers
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("rax", 0), 0);
const bool is_signed = (type_flags & eTypeIsSigned) != 0;
switch (byte_size)
@@ -707,7 +707,7 @@ ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread,
}
else
{
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
if (byte_size <= sizeof(long double))
{
const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
@@ -755,7 +755,7 @@ ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread,
}
else if (type_flags & eTypeIsVector)
{
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
if (byte_size > 0)
{
@@ -821,7 +821,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_c
if (!reg_ctx_sp)
return return_valobj_sp;
- const size_t bit_width = return_clang_type.GetBitSize();
+ const size_t bit_width = return_clang_type.GetBitSize(nullptr);
if (return_clang_type.IsAggregateType())
{
Target *target = exe_ctx.GetTargetPtr();
@@ -869,7 +869,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_c
uint32_t count;
ClangASTType field_clang_type = return_clang_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
- const size_t field_bit_width = field_clang_type.GetBitSize();
+ const size_t field_bit_width = field_clang_type.GetBitSize(nullptr);
// If there are any unaligned fields, this is stored in memory.
if (field_bit_offset % field_bit_width != 0)
@@ -1070,6 +1070,10 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_c
return return_valobj_sp;
}
+// This defines the CFA as rsp+8
+// the saved pc is at CFA-8 (i.e. rsp+0)
+// The saved rsp is CFA+0
+
bool
ABISysV_x86_64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
{
@@ -1083,12 +1087,18 @@ ABISysV_x86_64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
row->SetCFARegister (sp_reg_num);
row->SetCFAOffset (8);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
+ row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
unwind_plan.AppendRow (row);
unwind_plan.SetSourceName ("x86_64 at-func-entry default");
unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
return true;
}
+// This defines the CFA as rbp+16
+// The saved pc is at CFA-8 (i.e. rbp+8)
+// The saved rbp is at CFA-16 (i.e. rbp+0)
+// The saved rsp is CFA+0
+
bool
ABISysV_x86_64::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
{
@@ -1132,6 +1142,7 @@ ABISysV_x86_64::RegisterIsVolatile (const RegisterInfo *reg_info)
// (this doc is also commonly referred to as the x86-64/AMD64 psABI)
// Edited by Michael Matz, Jan Hubicka, Andreas Jaeger, and Mark Mitchell
// current version is 0.99.6 released 2012-07-02 at http://refspecs.linuxfoundation.org/elf/x86-64-abi-0.99.pdf
+// It's being revised & updated at https://github.com/hjl-tools/x86-psABI/
bool
ABISysV_x86_64::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
diff --git a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
index 97ddbef0e307..2f9012222c02 100644
--- a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
+++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
@@ -371,7 +371,7 @@ public:
}
}
- static RegularExpression s_regex("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?", REG_EXTENDED);
+ static RegularExpression s_regex("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?");
RegularExpression::Match matches(3);
@@ -457,7 +457,7 @@ DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, uns
std::unique_ptr<llvm::MCSymbolizer> symbolizer_up(curr_target->createMCSymbolizer(triple, NULL,
DisassemblerLLVMC::SymbolLookupCallback,
(void *) &owner,
- m_context_ap.get(), RelInfo.release()));
+ m_context_ap.get(), std::move(RelInfo)));
m_disasm_ap->setSymbolizer(std::move(symbolizer_up));
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
index d8279e44e14a..a504e801daac 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -19,6 +19,8 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "llvm/Support/Path.h"
+
#include "DYLDRendezvous.h"
using namespace lldb;
@@ -238,9 +240,7 @@ DYLDRendezvous::UpdateSOEntriesForAddition()
return false;
// Only add shared libraries and not the executable.
- // On Linux this is indicated by an empty path in the entry.
- // On FreeBSD it is the name of the executable.
- if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
+ if (SOEntryIsMainExecutable(entry))
continue;
pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
@@ -277,6 +277,28 @@ DYLDRendezvous::UpdateSOEntriesForDeletion()
}
bool
+DYLDRendezvous::SOEntryIsMainExecutable(const SOEntry &entry)
+{
+ // On Linux the executable is indicated by an empty path in the entry. On
+ // FreeBSD it is the full path to the executable. On Android, it is the
+ // basename of the executable.
+
+ auto triple = m_process->GetTarget().GetArchitecture().GetTriple();
+ auto os_type = triple.getOS();
+ auto env_type = triple.getEnvironment();
+
+ switch (os_type) {
+ case llvm::Triple::FreeBSD:
+ return ::strcmp(entry.path.c_str(), m_exe_path) == 0;
+ case llvm::Triple::Linux:
+ return entry.path.empty() || (env_type == llvm::Triple::Android &&
+ llvm::sys::path::filename(m_exe_path) == entry.path);
+ default:
+ return false;
+ }
+}
+
+bool
DYLDRendezvous::TakeSnapshot(SOEntryList &entry_list)
{
SOEntry entry;
@@ -290,9 +312,7 @@ DYLDRendezvous::TakeSnapshot(SOEntryList &entry_list)
return false;
// Only add shared libraries and not the executable.
- // On Linux this is indicated by an empty path in the entry.
- // On FreeBSD it is the name of the executable.
- if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
+ if (SOEntryIsMainExecutable(entry))
continue;
entry_list.push_back(entry);
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
index ca0089317998..51fcd9b7d397 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
@@ -247,6 +247,9 @@ protected:
bool
UpdateSOEntriesForDeletion();
+ bool
+ SOEntryIsMainExecutable(const SOEntry &entry);
+
/// Reads the current list of shared objects according to the link map
/// supplied by the runtime linker.
bool
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index 6b0b6f5cc8b8..fdef1026f3c6 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -542,6 +542,9 @@ DynamicLoaderPOSIXDYLD::ComputeLoadOffset()
return LLDB_INVALID_ADDRESS;
ObjectFile *exe = module->GetObjectFile();
+ if (!exe)
+ return LLDB_INVALID_ADDRESS;
+
Address file_entry = exe->GetEntryPointAddress();
if (!file_entry.IsValid())
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index a6c74f3f1fc4..50537eb119f2 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -291,7 +291,8 @@ ItaniumABILanguageRuntime::CreateInstance (Process *process, lldb::LanguageType
// the Itanium ABI.
if (language == eLanguageTypeC_plus_plus ||
language == eLanguageTypeC_plus_plus_03 ||
- language == eLanguageTypeC_plus_plus_11)
+ language == eLanguageTypeC_plus_plus_11 ||
+ language == eLanguageTypeC_plus_plus_14)
return new ItaniumABILanguageRuntime (process);
else
return NULL;
diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index b1be0f5b1fe1..5b72728c2b48 100644
--- a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -288,82 +288,6 @@ PlatformPOSIX::PutFile (const lldb_private::FileSpec& source,
}
// if we are still here rsync has failed - let's try the slow way before giving up
}
-
- if (log)
- log->Printf ("PlatformPOSIX::PutFile(src='%s', dst='%s', uid=%u, gid=%u)",
- source.GetPath().c_str(),
- destination.GetPath().c_str(),
- uid,
- gid); // REMOVE THIS PRINTF PRIOR TO CHECKIN
- // open
- // read, write, read, write, ...
- // close
- // chown uid:gid dst
- if (log)
- log->Printf("[PutFile] Using block by block transfer....\n");
-
- uint32_t source_open_options = File::eOpenOptionRead;
- if (source.GetFileType() == FileSpec::eFileTypeSymbolicLink)
- source_open_options |= File::eOpenoptionDontFollowSymlinks;
-
- File source_file(source, source_open_options, lldb::eFilePermissionsUserRW);
- Error error;
- uint32_t permissions = source_file.GetPermissions(error);
- if (permissions == 0)
- permissions = lldb::eFilePermissionsFileDefault;
-
- if (!source_file.IsValid())
- return Error("unable to open source file");
- lldb::user_id_t dest_file = OpenFile (destination,
- File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate,
- permissions,
- error);
- if (log)
- log->Printf ("dest_file = %" PRIu64 "\n", dest_file);
- if (error.Fail())
- return error;
- if (dest_file == UINT64_MAX)
- return Error("unable to open target file");
- lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0));
- uint64_t offset = 0;
- while (error.Success())
- {
- size_t bytes_read = buffer_sp->GetByteSize();
- error = source_file.Read(buffer_sp->GetBytes(), bytes_read);
- if (bytes_read)
- {
- const uint64_t bytes_written = WriteFile(dest_file, offset, buffer_sp->GetBytes(), bytes_read, error);
- offset += bytes_written;
- if (bytes_written != bytes_read)
- {
- // We didn't write the correct numbe of bytes, so adjust
- // the file position in the source file we are reading from...
- source_file.SeekFromStart(offset);
- }
- }
- else
- break;
- }
- CloseFile(dest_file, error);
- if (uid == UINT32_MAX && gid == UINT32_MAX)
- return error;
- // This is remopve, don't chown a local file...
-// std::string dst_path (destination.GetPath());
-// if (chown_file(this,dst_path.c_str(),uid,gid) != 0)
-// return Error("unable to perform chown");
-
-
- uint64_t src_md5[2];
- uint64_t dst_md5[2];
-
- if (FileSystem::CalculateMD5 (source, src_md5[0], src_md5[1]) && CalculateMD5 (destination, dst_md5[0], dst_md5[1]))
- {
- if (src_md5[0] != dst_md5[0] || src_md5[1] != dst_md5[1])
- {
- error.SetErrorString("md5 checksum of installed file doesn't match, installation failed");
- }
- }
- return error;
}
return Platform::PutFile(source,destination,uid,gid);
}
@@ -841,8 +765,12 @@ PlatformPOSIX::Attach (ProcessAttachInfo &attach_info,
// Set UnixSignals appropriately.
process_sp->SetUnixSignals (Host::GetUnixSignals ());
- ListenerSP listener_sp (new Listener("lldb.PlatformPOSIX.attach.hijack"));
- attach_info.SetHijackListener(listener_sp);
+ auto listener_sp = attach_info.GetHijackListener();
+ if (listener_sp == nullptr)
+ {
+ listener_sp.reset(new Listener("lldb.PlatformPOSIX.attach.hijack"));
+ attach_info.SetHijackListener(listener_sp);
+ }
process_sp->HijackProcessEvents(listener_sp.get());
error = process_sp->Attach (attach_info);
}
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 43eae4d906ec..ec2084aaf98c 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -30,6 +30,8 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "Utility/UriParser.h"
+
using namespace lldb;
using namespace lldb_private;
@@ -105,12 +107,76 @@ PlatformRemoteGDBServer::ResolveExecutable (const ModuleSpec &module_spec,
lldb::ModuleSP &exe_module_sp,
const FileSpecList *module_search_paths_ptr)
{
+ // copied from PlatformRemoteiOS
+
Error error;
- //error.SetErrorString ("PlatformRemoteGDBServer::ResolveExecutable() is unimplemented");
- if (m_gdb_client.GetFileExists(module_spec.GetFileSpec()))
- return error;
- // TODO: get the remote end to somehow resolve this file
- error.SetErrorString("file not found on remote end");
+ // Nothing special to do here, just use the actual file and architecture
+
+ ModuleSpec resolved_module_spec(module_spec);
+
+ // Resolve any executable within an apk on Android?
+ //Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
+
+ if (resolved_module_spec.GetFileSpec().Exists())
+ {
+ if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid())
+ {
+ error = ModuleList::GetSharedModule (resolved_module_spec,
+ exe_module_sp,
+ NULL,
+ NULL,
+ NULL);
+
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ return error;
+ exe_module_sp.reset();
+ }
+ // No valid architecture was specified or the exact arch wasn't
+ // found so ask the platform for the architectures that we should be
+ // using (in the correct order) and see if we can find a match that way
+ StreamString arch_names;
+ for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
+ {
+ error = ModuleList::GetSharedModule (resolved_module_spec,
+ exe_module_sp,
+ NULL,
+ NULL,
+ NULL);
+ // Did we find an executable using one of the
+ if (error.Success())
+ {
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ break;
+ else
+ error.SetErrorToGenericError();
+ }
+
+ if (idx > 0)
+ arch_names.PutCString (", ");
+ arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
+ }
+
+ if (error.Fail() || !exe_module_sp)
+ {
+ if (resolved_module_spec.GetFileSpec().Readable())
+ {
+ error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ GetPluginName().GetCString(),
+ arch_names.GetString().c_str());
+ }
+ else
+ {
+ error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
+ }
+ }
+ else
+ {
+ error.SetErrorStringWithFormat ("'%s' does not exist",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
+
return error;
}
@@ -146,6 +212,15 @@ PlatformRemoteGDBServer::~PlatformRemoteGDBServer()
bool
PlatformRemoteGDBServer::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
{
+ ArchSpec remote_arch = m_gdb_client.GetSystemArchitecture();
+
+ // TODO: 64 bit systems should also advertize support for 32 bit arch
+ // unknown CPU, we just support the one arch
+ if (idx == 0)
+ {
+ arch = remote_arch;
+ return true;
+ }
return false;
}
@@ -252,6 +327,17 @@ PlatformRemoteGDBServer::ConnectRemote (Args& args)
{
const char *url = args.GetArgumentAtIndex(0);
m_gdb_client.SetConnection (new ConnectionFileDescriptor());
+
+ // we're going to reuse the hostname when we connect to the debugserver
+ std::string scheme;
+ int port;
+ std::string path;
+ if ( !UriParser::Parse(url, scheme, m_platform_hostname, port, path) )
+ {
+ error.SetErrorString("invalid uri");
+ return error;
+ }
+
const ConnectionStatus status = m_gdb_client.Connect(url, &error);
if (status == eConnectionStatusSuccess)
{
@@ -344,14 +430,30 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
Error error;
- lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
if (log)
log->Printf ("PlatformRemoteGDBServer::%s() called", __FUNCTION__);
- m_gdb_client.SetSTDIN ("/dev/null");
- m_gdb_client.SetSTDOUT ("/dev/null");
- m_gdb_client.SetSTDERR ("/dev/null");
+ auto num_file_actions = launch_info.GetNumFileActions ();
+ for (decltype(num_file_actions) i = 0; i < num_file_actions; ++i)
+ {
+ const auto file_action = launch_info.GetFileActionAtIndex (i);
+ if (file_action->GetAction () != FileAction::eFileActionOpen)
+ continue;
+ switch(file_action->GetFD())
+ {
+ case STDIN_FILENO:
+ m_gdb_client.SetSTDIN (file_action->GetPath());
+ break;
+ case STDOUT_FILENO:
+ m_gdb_client.SetSTDOUT (file_action->GetPath());
+ break;
+ case STDERR_FILENO:
+ m_gdb_client.SetSTDERR (file_action->GetPath());
+ break;
+ }
+ }
+
m_gdb_client.SetDisableASLR (launch_info.GetFlags().Test (eLaunchFlagDisableASLR));
m_gdb_client.SetDetachOnError (launch_info.GetFlags().Test (eLaunchFlagDetachOnError));
@@ -389,7 +491,7 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info)
std::string error_str;
if (m_gdb_client.GetLaunchSuccess (error_str))
{
- pid = m_gdb_client.GetCurrentProcessID ();
+ const auto pid = m_gdb_client.GetCurrentProcessID (false);
if (pid != LLDB_INVALID_PROCESS_ID)
{
launch_info.SetProcessID (pid);
@@ -400,7 +502,7 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info)
{
if (log)
log->Printf ("PlatformRemoteGDBServer::%s() launch succeeded but we didn't get a valid process id back!", __FUNCTION__);
- // FIXME isn't this an error condition? Do we need to set an error here? Check with Greg.
+ error.SetErrorString ("failed to get PID");
}
}
else
@@ -417,6 +519,14 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info)
return error;
}
+Error
+PlatformRemoteGDBServer::KillProcess (const lldb::pid_t pid)
+{
+ if (!m_gdb_client.KillSpawnedProcess(pid))
+ return Error("failed to kill remote spawned process");
+ return Error();
+}
+
lldb::ProcessSP
PlatformRemoteGDBServer::DebugProcess (lldb_private::ProcessLaunchInfo &launch_info,
lldb_private::Debugger &debugger,
@@ -483,7 +593,7 @@ PlatformRemoteGDBServer::DebugProcess (lldb_private::ProcessLaunchInfo &launch_i
const int connect_url_len = ::snprintf (connect_url,
sizeof(connect_url),
"connect://%s:%u",
- override_hostname ? override_hostname : GetHostname (),
+ override_hostname ? override_hostname : m_platform_hostname.c_str(),
port + port_offset);
assert (connect_url_len < (int)sizeof(connect_url));
error = process_sp->ConnectRemote (NULL, connect_url);
@@ -576,13 +686,19 @@ PlatformRemoteGDBServer::Attach (lldb_private::ProcessAttachInfo &attach_info,
const int connect_url_len = ::snprintf (connect_url,
sizeof(connect_url),
"connect://%s:%u",
- override_hostname ? override_hostname : GetHostname (),
+ override_hostname ? override_hostname : m_platform_hostname.c_str(),
port + port_offset);
assert (connect_url_len < (int)sizeof(connect_url));
- error = process_sp->ConnectRemote (NULL, connect_url);
+ error = process_sp->ConnectRemote(nullptr, connect_url);
if (error.Success())
+ {
+ auto listener = attach_info.GetHijackListener();
+ if (listener != nullptr)
+ process_sp->HijackProcessEvents(listener.get());
error = process_sp->Attach(attach_info);
- else if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
+ }
+
+ if (error.Fail() && debugserver_pid != LLDB_INVALID_PROCESS_ID)
{
m_gdb_client.KillSpawnedProcess(debugserver_pid);
}
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index 90b16b8b8fa9..a928c4695f79 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -86,7 +86,10 @@ public:
virtual lldb_private::Error
LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info);
-
+
+ virtual lldb_private::Error
+ KillProcess (const lldb::pid_t pid);
+
virtual lldb::ProcessSP
DebugProcess (lldb_private::ProcessLaunchInfo &launch_info,
lldb_private::Debugger &debugger,
@@ -212,6 +215,7 @@ public:
protected:
GDBRemoteCommunicationClient m_gdb_client;
std::string m_platform_description; // After we connect we can get a more complete description of what we are connected to
+ std::string m_platform_hostname;
private:
DISALLOW_COPY_AND_ASSIGN (PlatformRemoteGDBServer);
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
index 84e35ba22644..b33f83303971 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
@@ -30,7 +30,7 @@
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/PseudoTerminal.h"
-
+#include "Plugins/Process/POSIX/CrashReason.h"
#include "POSIXThread.h"
#include "ProcessFreeBSD.h"
#include "ProcessPOSIXLog.h"
@@ -994,6 +994,11 @@ ProcessMonitor::Launch(LaunchArgs *args)
if (PTRACE(PT_TRACE_ME, 0, NULL, 0) < 0)
exit(ePtraceFailed);
+ // terminal has already dupped the tty descriptors to stdin/out/err.
+ // This closes original fd from which they were copied (and avoids
+ // leaking descriptors to the debugged process.
+ terminal.CloseSlaveFileDescriptor();
+
// Do not inherit setgid powers.
if (setgid(getgid()) != 0)
exit(eSetGidFailed);
@@ -1306,27 +1311,14 @@ ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
if (log)
log->Printf ("ProcessMonitor::%s() received signal %s", __FUNCTION__, monitor->m_process->GetUnixSignals().GetSignalAsCString (signo));
- if (signo == SIGSEGV) {
- lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
- ProcessMessage::CrashReason reason = GetCrashReasonForSIGSEGV(info);
- return ProcessMessage::Crash(tid, reason, signo, fault_addr);
- }
-
- if (signo == SIGILL) {
- lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
- ProcessMessage::CrashReason reason = GetCrashReasonForSIGILL(info);
- return ProcessMessage::Crash(tid, reason, signo, fault_addr);
- }
-
- if (signo == SIGFPE) {
- lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
- ProcessMessage::CrashReason reason = GetCrashReasonForSIGFPE(info);
- return ProcessMessage::Crash(tid, reason, signo, fault_addr);
- }
-
- if (signo == SIGBUS) {
+ switch (signo)
+ {
+ case SIGSEGV:
+ case SIGILL:
+ case SIGFPE:
+ case SIGBUS:
lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
- ProcessMessage::CrashReason reason = GetCrashReasonForSIGBUS(info);
+ const auto reason = GetCrashReason(*info);
return ProcessMessage::Crash(tid, reason, signo, fault_addr);
}
@@ -1335,141 +1327,6 @@ ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
return ProcessMessage::Signal(tid, signo);
}
-ProcessMessage::CrashReason
-ProcessMonitor::GetCrashReasonForSIGSEGV(const siginfo_t *info)
-{
- ProcessMessage::CrashReason reason;
- assert(info->si_signo == SIGSEGV);
-
- reason = ProcessMessage::eInvalidCrashReason;
-
- switch (info->si_code)
- {
- default:
- assert(false && "unexpected si_code for SIGSEGV");
- break;
- case SEGV_MAPERR:
- reason = ProcessMessage::eInvalidAddress;
- break;
- case SEGV_ACCERR:
- reason = ProcessMessage::ePrivilegedAddress;
- break;
- }
-
- return reason;
-}
-
-ProcessMessage::CrashReason
-ProcessMonitor::GetCrashReasonForSIGILL(const siginfo_t *info)
-{
- ProcessMessage::CrashReason reason;
- assert(info->si_signo == SIGILL);
-
- reason = ProcessMessage::eInvalidCrashReason;
-
- switch (info->si_code)
- {
- default:
- assert(false && "unexpected si_code for SIGILL");
- break;
- case ILL_ILLOPC:
- reason = ProcessMessage::eIllegalOpcode;
- break;
- case ILL_ILLOPN:
- reason = ProcessMessage::eIllegalOperand;
- break;
- case ILL_ILLADR:
- reason = ProcessMessage::eIllegalAddressingMode;
- break;
- case ILL_ILLTRP:
- reason = ProcessMessage::eIllegalTrap;
- break;
- case ILL_PRVOPC:
- reason = ProcessMessage::ePrivilegedOpcode;
- break;
- case ILL_PRVREG:
- reason = ProcessMessage::ePrivilegedRegister;
- break;
- case ILL_COPROC:
- reason = ProcessMessage::eCoprocessorError;
- break;
- case ILL_BADSTK:
- reason = ProcessMessage::eInternalStackError;
- break;
- }
-
- return reason;
-}
-
-ProcessMessage::CrashReason
-ProcessMonitor::GetCrashReasonForSIGFPE(const siginfo_t *info)
-{
- ProcessMessage::CrashReason reason;
- assert(info->si_signo == SIGFPE);
-
- reason = ProcessMessage::eInvalidCrashReason;
-
- switch (info->si_code)
- {
- default:
- assert(false && "unexpected si_code for SIGFPE");
- break;
- case FPE_INTDIV:
- reason = ProcessMessage::eIntegerDivideByZero;
- break;
- case FPE_INTOVF:
- reason = ProcessMessage::eIntegerOverflow;
- break;
- case FPE_FLTDIV:
- reason = ProcessMessage::eFloatDivideByZero;
- break;
- case FPE_FLTOVF:
- reason = ProcessMessage::eFloatOverflow;
- break;
- case FPE_FLTUND:
- reason = ProcessMessage::eFloatUnderflow;
- break;
- case FPE_FLTRES:
- reason = ProcessMessage::eFloatInexactResult;
- break;
- case FPE_FLTINV:
- reason = ProcessMessage::eFloatInvalidOperation;
- break;
- case FPE_FLTSUB:
- reason = ProcessMessage::eFloatSubscriptRange;
- break;
- }
-
- return reason;
-}
-
-ProcessMessage::CrashReason
-ProcessMonitor::GetCrashReasonForSIGBUS(const siginfo_t *info)
-{
- ProcessMessage::CrashReason reason;
- assert(info->si_signo == SIGBUS);
-
- reason = ProcessMessage::eInvalidCrashReason;
-
- switch (info->si_code)
- {
- default:
- assert(false && "unexpected si_code for SIGBUS");
- break;
- case BUS_ADRALN:
- reason = ProcessMessage::eIllegalAlignment;
- break;
- case BUS_ADRERR:
- reason = ProcessMessage::eIllegalAddress;
- break;
- case BUS_OBJERR:
- reason = ProcessMessage::eHardwareError;
- break;
- }
-
- return reason;
-}
-
void
ProcessMonitor::ServeOperation(OperationArgs *args)
{
@@ -1706,7 +1563,10 @@ ProcessMonitor::DupDescriptor(const char *path, int fd, int flags)
if (target_fd == -1)
return false;
- return (dup2(target_fd, fd) == -1) ? false : true;
+ if (dup2(target_fd, fd) == -1)
+ return false;
+
+ return (close(target_fd) == -1) ? false : true;
}
void
@@ -1727,11 +1587,10 @@ ProcessMonitor::StopMonitor()
StopOpThread();
sem_destroy(&m_operation_pending);
sem_destroy(&m_operation_done);
-
- // Note: ProcessPOSIX passes the m_terminal_fd file descriptor to
- // Process::SetSTDIOFileDescriptor, which in turn transfers ownership of
- // the descriptor to a ConnectionFileDescriptor object. Consequently
- // even though still has the file descriptor, we shouldn't close it here.
+ if (m_terminal_fd >= 0) {
+ close(m_terminal_fd);
+ m_terminal_fd = -1;
+ }
}
// FIXME: On Linux, when a new thread is created, we receive to notifications,
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/source/Plugins/Process/FreeBSD/ProcessMonitor.h
index 935fd85ed37a..4ae963c89a2f 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.h
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.h
@@ -79,7 +79,8 @@ public:
/// Reads from this file descriptor yield both the standard output and
/// standard error of this debugee. Even if stderr and stdout were
/// redirected on launch it may still happen that data is available on this
- /// descriptor (if the inferior process opens /dev/tty, for example).
+ /// descriptor (if the inferior process opens /dev/tty, for example). This descriptor is
+ /// closed after a call to StopMonitor().
///
/// If this monitor was attached to an existing process this method returns
/// -1.
@@ -311,18 +312,6 @@ private:
MonitorSignal(ProcessMonitor *monitor,
const siginfo_t *info, lldb::pid_t pid);
- static ProcessMessage::CrashReason
- GetCrashReasonForSIGSEGV(const siginfo_t *info);
-
- static ProcessMessage::CrashReason
- GetCrashReasonForSIGILL(const siginfo_t *info);
-
- static ProcessMessage::CrashReason
- GetCrashReasonForSIGFPE(const siginfo_t *info);
-
- static ProcessMessage::CrashReason
- GetCrashReasonForSIGBUS(const siginfo_t *info);
-
void
DoOperation(Operation *op);
diff --git a/source/Plugins/Process/POSIX/CrashReason.cpp b/source/Plugins/Process/POSIX/CrashReason.cpp
new file mode 100644
index 000000000000..4dd91a6f1de8
--- /dev/null
+++ b/source/Plugins/Process/POSIX/CrashReason.cpp
@@ -0,0 +1,315 @@
+//===-- CrashReason.cpp -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CrashReason.h"
+
+#include <sstream>
+
+namespace {
+
+void
+AppendFaultAddr (std::string& str, lldb::addr_t addr)
+{
+ std::stringstream ss;
+ ss << " (fault address: 0x" << std::hex << addr << ")";
+ str += ss.str();
+}
+
+CrashReason
+GetCrashReasonForSIGSEGV(const siginfo_t& info)
+{
+ assert(info.si_signo == SIGSEGV);
+
+ switch (info.si_code)
+ {
+ case SI_KERNEL:
+ // Linux will occasionally send spurious SI_KERNEL codes.
+ // (this is poorly documented in sigaction)
+ // One way to get this is via unaligned SIMD loads.
+ return CrashReason::eInvalidAddress; // for lack of anything better
+ case SEGV_MAPERR:
+ return CrashReason::eInvalidAddress;
+ case SEGV_ACCERR:
+ return CrashReason::ePrivilegedAddress;
+ }
+
+ assert(false && "unexpected si_code for SIGSEGV");
+ return CrashReason::eInvalidCrashReason;
+}
+
+CrashReason
+GetCrashReasonForSIGILL(const siginfo_t& info)
+{
+ assert(info.si_signo == SIGILL);
+
+ switch (info.si_code)
+ {
+ case ILL_ILLOPC:
+ return CrashReason::eIllegalOpcode;
+ case ILL_ILLOPN:
+ return CrashReason::eIllegalOperand;
+ case ILL_ILLADR:
+ return CrashReason::eIllegalAddressingMode;
+ case ILL_ILLTRP:
+ return CrashReason::eIllegalTrap;
+ case ILL_PRVOPC:
+ return CrashReason::ePrivilegedOpcode;
+ case ILL_PRVREG:
+ return CrashReason::ePrivilegedRegister;
+ case ILL_COPROC:
+ return CrashReason::eCoprocessorError;
+ case ILL_BADSTK:
+ return CrashReason::eInternalStackError;
+ }
+
+ assert(false && "unexpected si_code for SIGILL");
+ return CrashReason::eInvalidCrashReason;
+}
+
+CrashReason
+GetCrashReasonForSIGFPE(const siginfo_t& info)
+{
+ assert(info.si_signo == SIGFPE);
+
+ switch (info.si_code)
+ {
+ case FPE_INTDIV:
+ return CrashReason::eIntegerDivideByZero;
+ case FPE_INTOVF:
+ return CrashReason::eIntegerOverflow;
+ case FPE_FLTDIV:
+ return CrashReason::eFloatDivideByZero;
+ case FPE_FLTOVF:
+ return CrashReason::eFloatOverflow;
+ case FPE_FLTUND:
+ return CrashReason::eFloatUnderflow;
+ case FPE_FLTRES:
+ return CrashReason::eFloatInexactResult;
+ case FPE_FLTINV:
+ return CrashReason::eFloatInvalidOperation;
+ case FPE_FLTSUB:
+ return CrashReason::eFloatSubscriptRange;
+ }
+
+ assert(false && "unexpected si_code for SIGFPE");
+ return CrashReason::eInvalidCrashReason;
+}
+
+CrashReason
+GetCrashReasonForSIGBUS(const siginfo_t& info)
+{
+ assert(info.si_signo == SIGBUS);
+
+ switch (info.si_code)
+ {
+ case BUS_ADRALN:
+ return CrashReason::eIllegalAlignment;
+ case BUS_ADRERR:
+ return CrashReason::eIllegalAddress;
+ case BUS_OBJERR:
+ return CrashReason::eHardwareError;
+ }
+
+ assert(false && "unexpected si_code for SIGBUS");
+ return CrashReason::eInvalidCrashReason;
+}
+
+}
+
+std::string
+GetCrashReasonString (CrashReason reason, lldb::addr_t fault_addr)
+{
+ std::string str;
+
+ switch (reason)
+ {
+ default:
+ assert(false && "invalid CrashReason");
+ break;
+
+ case CrashReason::eInvalidAddress:
+ str = "invalid address";
+ AppendFaultAddr (str, fault_addr);
+ break;
+ case CrashReason::ePrivilegedAddress:
+ str = "address access protected";
+ AppendFaultAddr (str, fault_addr);
+ break;
+ case CrashReason::eIllegalOpcode:
+ str = "illegal instruction";
+ break;
+ case CrashReason::eIllegalOperand:
+ str = "illegal instruction operand";
+ break;
+ case CrashReason::eIllegalAddressingMode:
+ str = "illegal addressing mode";
+ break;
+ case CrashReason::eIllegalTrap:
+ str = "illegal trap";
+ break;
+ case CrashReason::ePrivilegedOpcode:
+ str = "privileged instruction";
+ break;
+ case CrashReason::ePrivilegedRegister:
+ str = "privileged register";
+ break;
+ case CrashReason::eCoprocessorError:
+ str = "coprocessor error";
+ break;
+ case CrashReason::eInternalStackError:
+ str = "internal stack error";
+ break;
+ case CrashReason::eIllegalAlignment:
+ str = "illegal alignment";
+ break;
+ case CrashReason::eIllegalAddress:
+ str = "illegal address";
+ break;
+ case CrashReason::eHardwareError:
+ str = "hardware error";
+ break;
+ case CrashReason::eIntegerDivideByZero:
+ str = "integer divide by zero";
+ break;
+ case CrashReason::eIntegerOverflow:
+ str = "integer overflow";
+ break;
+ case CrashReason::eFloatDivideByZero:
+ str = "floating point divide by zero";
+ break;
+ case CrashReason::eFloatOverflow:
+ str = "floating point overflow";
+ break;
+ case CrashReason::eFloatUnderflow:
+ str = "floating point underflow";
+ break;
+ case CrashReason::eFloatInexactResult:
+ str = "inexact floating point result";
+ break;
+ case CrashReason::eFloatInvalidOperation:
+ str = "invalid floating point operation";
+ break;
+ case CrashReason::eFloatSubscriptRange:
+ str = "invalid floating point subscript range";
+ break;
+ }
+
+ return str;
+}
+
+const char *
+CrashReasonAsString (CrashReason reason)
+{
+#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
+ // Just return the code in ascii for integration builds.
+ chcar str[8];
+ sprintf(str, "%d", reason);
+#else
+ const char *str = nullptr;
+
+ switch (reason)
+ {
+ case CrashReason::eInvalidCrashReason:
+ str = "eInvalidCrashReason";
+ break;
+
+ // SIGSEGV crash reasons.
+ case CrashReason::eInvalidAddress:
+ str = "eInvalidAddress";
+ break;
+ case CrashReason::ePrivilegedAddress:
+ str = "ePrivilegedAddress";
+ break;
+
+ // SIGILL crash reasons.
+ case CrashReason::eIllegalOpcode:
+ str = "eIllegalOpcode";
+ break;
+ case CrashReason::eIllegalOperand:
+ str = "eIllegalOperand";
+ break;
+ case CrashReason::eIllegalAddressingMode:
+ str = "eIllegalAddressingMode";
+ break;
+ case CrashReason::eIllegalTrap:
+ str = "eIllegalTrap";
+ break;
+ case CrashReason::ePrivilegedOpcode:
+ str = "ePrivilegedOpcode";
+ break;
+ case CrashReason::ePrivilegedRegister:
+ str = "ePrivilegedRegister";
+ break;
+ case CrashReason::eCoprocessorError:
+ str = "eCoprocessorError";
+ break;
+ case CrashReason::eInternalStackError:
+ str = "eInternalStackError";
+ break;
+
+ // SIGBUS crash reasons:
+ case CrashReason::eIllegalAlignment:
+ str = "eIllegalAlignment";
+ break;
+ case CrashReason::eIllegalAddress:
+ str = "eIllegalAddress";
+ break;
+ case CrashReason::eHardwareError:
+ str = "eHardwareError";
+ break;
+
+ // SIGFPE crash reasons:
+ case CrashReason::eIntegerDivideByZero:
+ str = "eIntegerDivideByZero";
+ break;
+ case CrashReason::eIntegerOverflow:
+ str = "eIntegerOverflow";
+ break;
+ case CrashReason::eFloatDivideByZero:
+ str = "eFloatDivideByZero";
+ break;
+ case CrashReason::eFloatOverflow:
+ str = "eFloatOverflow";
+ break;
+ case CrashReason::eFloatUnderflow:
+ str = "eFloatUnderflow";
+ break;
+ case CrashReason::eFloatInexactResult:
+ str = "eFloatInexactResult";
+ break;
+ case CrashReason::eFloatInvalidOperation:
+ str = "eFloatInvalidOperation";
+ break;
+ case CrashReason::eFloatSubscriptRange:
+ str = "eFloatSubscriptRange";
+ break;
+ }
+#endif
+
+ return str;
+}
+
+CrashReason
+GetCrashReason(const siginfo_t& info)
+{
+ switch(info.si_signo)
+ {
+ case SIGSEGV:
+ return GetCrashReasonForSIGSEGV(info);
+ case SIGBUS:
+ return GetCrashReasonForSIGBUS(info);
+ case SIGFPE:
+ return GetCrashReasonForSIGFPE(info);
+ case SIGILL:
+ return GetCrashReasonForSIGILL(info);
+ }
+
+ assert(false && "unexpected signal");
+ return CrashReason::eInvalidCrashReason;
+}
diff --git a/source/Plugins/Process/POSIX/CrashReason.h b/source/Plugins/Process/POSIX/CrashReason.h
new file mode 100644
index 000000000000..f6d9ba553e4a
--- /dev/null
+++ b/source/Plugins/Process/POSIX/CrashReason.h
@@ -0,0 +1,62 @@
+//===-- CrashReason.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_CrashReason_H_
+#define liblldb_CrashReason_H_
+
+#include "lldb/lldb-types.h"
+
+#include <signal.h>
+
+#include <string>
+
+enum class CrashReason
+{
+ eInvalidCrashReason,
+
+ // SIGSEGV crash reasons.
+ eInvalidAddress,
+ ePrivilegedAddress,
+
+ // SIGILL crash reasons.
+ eIllegalOpcode,
+ eIllegalOperand,
+ eIllegalAddressingMode,
+ eIllegalTrap,
+ ePrivilegedOpcode,
+ ePrivilegedRegister,
+ eCoprocessorError,
+ eInternalStackError,
+
+ // SIGBUS crash reasons,
+ eIllegalAlignment,
+ eIllegalAddress,
+ eHardwareError,
+
+ // SIGFPE crash reasons,
+ eIntegerDivideByZero,
+ eIntegerOverflow,
+ eFloatDivideByZero,
+ eFloatOverflow,
+ eFloatUnderflow,
+ eFloatInexactResult,
+ eFloatInvalidOperation,
+ eFloatSubscriptRange
+};
+
+std::string
+GetCrashReasonString (CrashReason reason, lldb::addr_t fault_addr);
+
+const char *
+CrashReasonAsString (CrashReason reason);
+
+CrashReason
+GetCrashReason(const siginfo_t& info);
+
+#endif // #ifndef liblldb_CrashReason_H_
diff --git a/source/Plugins/Process/POSIX/POSIXStopInfo.cpp b/source/Plugins/Process/POSIX/POSIXStopInfo.cpp
index 6e2c140682ba..3b8cea737bcb 100644
--- a/source/Plugins/Process/POSIX/POSIXStopInfo.cpp
+++ b/source/Plugins/Process/POSIX/POSIXStopInfo.cpp
@@ -45,6 +45,15 @@ POSIXLimboStopInfo::ShouldNotify(Event *event_ptr)
//===----------------------------------------------------------------------===//
// POSIXCrashStopInfo
+POSIXCrashStopInfo::POSIXCrashStopInfo(POSIXThread &thread,
+ uint32_t status,
+ CrashReason reason,
+ lldb::addr_t fault_addr)
+ : POSIXStopInfo(thread, status)
+{
+ m_description = ::GetCrashReasonString(reason, fault_addr);
+}
+
POSIXCrashStopInfo::~POSIXCrashStopInfo() { }
lldb::StopReason
@@ -53,12 +62,6 @@ POSIXCrashStopInfo::GetStopReason() const
return lldb::eStopReasonException;
}
-const char *
-POSIXCrashStopInfo::GetDescription()
-{
- return ProcessMessage::GetCrashReasonString(m_crash_reason, m_fault_addr);
-}
-
//===----------------------------------------------------------------------===//
// POSIXNewThreadStopInfo
diff --git a/source/Plugins/Process/POSIX/POSIXStopInfo.h b/source/Plugins/Process/POSIX/POSIXStopInfo.h
index cbf309e53506..a1ee2ea68524 100644
--- a/source/Plugins/Process/POSIX/POSIXStopInfo.h
+++ b/source/Plugins/Process/POSIX/POSIXStopInfo.h
@@ -16,8 +16,10 @@
// Project includes
#include "lldb/Target/StopInfo.h"
+#include "CrashReason.h"
#include "POSIXThread.h"
-#include "ProcessMessage.h"
+
+#include <string>
//===----------------------------------------------------------------------===//
/// @class POSIXStopInfo
@@ -69,25 +71,13 @@ class POSIXCrashStopInfo
{
public:
POSIXCrashStopInfo(POSIXThread &thread, uint32_t status,
- ProcessMessage::CrashReason reason,
- lldb::addr_t fault_addr)
- : POSIXStopInfo(thread, status),
- m_crash_reason(reason),
- m_fault_addr(fault_addr)
- { }
-
+ CrashReason reason,
+ lldb::addr_t fault_addr);
~POSIXCrashStopInfo();
lldb::StopReason
GetStopReason() const;
-
- const char *
- GetDescription();
-
-private:
- ProcessMessage::CrashReason m_crash_reason;
- lldb::addr_t m_fault_addr;
-};
+};
//===----------------------------------------------------------------------===//
/// @class POSIXNewThreadStopInfo
diff --git a/source/Plugins/Process/POSIX/ProcessMessage.cpp b/source/Plugins/Process/POSIX/ProcessMessage.cpp
index 5c53627f9e0b..02049a2af953 100644
--- a/source/Plugins/Process/POSIX/ProcessMessage.cpp
+++ b/source/Plugins/Process/POSIX/ProcessMessage.cpp
@@ -9,205 +9,19 @@
#include "ProcessMessage.h"
-#include <sstream>
-
using namespace lldb_private;
-namespace {
-
-inline void AppendFaultAddr(std::string& str, lldb::addr_t addr)
-{
- std::stringstream ss;
- ss << " (fault address: 0x" << std::hex << addr << ")";
- str += ss.str();
-}
-
-}
-
-const char *
-ProcessMessage::GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr)
-{
- static std::string str;
-
- switch (reason)
- {
- default:
- assert(false && "invalid CrashReason");
- break;
-
- case eInvalidAddress:
- str = "invalid address";
- AppendFaultAddr(str, fault_addr);
- break;
- case ePrivilegedAddress:
- str = "address access protected";
- AppendFaultAddr(str, fault_addr);
- break;
- case eIllegalOpcode:
- str = "illegal instruction";
- break;
- case eIllegalOperand:
- str = "illegal instruction operand";
- break;
- case eIllegalAddressingMode:
- str = "illegal addressing mode";
- break;
- case eIllegalTrap:
- str = "illegal trap";
- break;
- case ePrivilegedOpcode:
- str = "privileged instruction";
- break;
- case ePrivilegedRegister:
- str = "privileged register";
- break;
- case eCoprocessorError:
- str = "coprocessor error";
- break;
- case eInternalStackError:
- str = "internal stack error";
- break;
- case eIllegalAlignment:
- str = "illegal alignment";
- break;
- case eIllegalAddress:
- str = "illegal address";
- break;
- case eHardwareError:
- str = "hardware error";
- break;
- case eIntegerDivideByZero:
- str = "integer divide by zero";
- break;
- case eIntegerOverflow:
- str = "integer overflow";
- break;
- case eFloatDivideByZero:
- str = "floating point divide by zero";
- break;
- case eFloatOverflow:
- str = "floating point overflow";
- break;
- case eFloatUnderflow:
- str = "floating point underflow";
- break;
- case eFloatInexactResult:
- str = "inexact floating point result";
- break;
- case eFloatInvalidOperation:
- str = "invalid floating point operation";
- break;
- case eFloatSubscriptRange:
- str = "invalid floating point subscript range";
- break;
- }
-
- return str.c_str();
-}
-
-const char *
-ProcessMessage::PrintCrashReason(CrashReason reason)
-{
-#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
- // Just return the code in asci for integration builds.
- chcar str[8];
- sprintf(str, "%d", reason);
-#else
- const char *str = NULL;
-
- switch (reason)
- {
- case eInvalidCrashReason:
- str = "eInvalidCrashReason";
- break;
-
- // SIGSEGV crash reasons.
- case eInvalidAddress:
- str = "eInvalidAddress";
- break;
- case ePrivilegedAddress:
- str = "ePrivilegedAddress";
- break;
-
- // SIGILL crash reasons.
- case eIllegalOpcode:
- str = "eIllegalOpcode";
- break;
- case eIllegalOperand:
- str = "eIllegalOperand";
- break;
- case eIllegalAddressingMode:
- str = "eIllegalAddressingMode";
- break;
- case eIllegalTrap:
- str = "eIllegalTrap";
- break;
- case ePrivilegedOpcode:
- str = "ePrivilegedOpcode";
- break;
- case ePrivilegedRegister:
- str = "ePrivilegedRegister";
- break;
- case eCoprocessorError:
- str = "eCoprocessorError";
- break;
- case eInternalStackError:
- str = "eInternalStackError";
- break;
-
- // SIGBUS crash reasons:
- case eIllegalAlignment:
- str = "eIllegalAlignment";
- break;
- case eIllegalAddress:
- str = "eIllegalAddress";
- break;
- case eHardwareError:
- str = "eHardwareError";
- break;
-
- // SIGFPE crash reasons:
- case eIntegerDivideByZero:
- str = "eIntegerDivideByZero";
- break;
- case eIntegerOverflow:
- str = "eIntegerOverflow";
- break;
- case eFloatDivideByZero:
- str = "eFloatDivideByZero";
- break;
- case eFloatOverflow:
- str = "eFloatOverflow";
- break;
- case eFloatUnderflow:
- str = "eFloatUnderflow";
- break;
- case eFloatInexactResult:
- str = "eFloatInexactResult";
- break;
- case eFloatInvalidOperation:
- str = "eFloatInvalidOperation";
- break;
- case eFloatSubscriptRange:
- str = "eFloatSubscriptRange";
- break;
- }
-#endif
-
- return str;
-}
-
const char *
ProcessMessage::PrintCrashReason() const
{
- return PrintCrashReason(m_crash_reason);
+ return CrashReasonAsString(m_crash_reason);
}
const char *
ProcessMessage::PrintKind(Kind kind)
{
#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
- // Just return the code in asci for integration builds.
+ // Just return the code in ascii for integration builds.
chcar str[8];
sprintf(str, "%d", reason);
#else
diff --git a/source/Plugins/Process/POSIX/ProcessMessage.h b/source/Plugins/Process/POSIX/ProcessMessage.h
index 40462d0f0e13..f932e9fff278 100644
--- a/source/Plugins/Process/POSIX/ProcessMessage.h
+++ b/source/Plugins/Process/POSIX/ProcessMessage.h
@@ -10,7 +10,10 @@
#ifndef liblldb_ProcessMessage_H_
#define liblldb_ProcessMessage_H_
+#include "CrashReason.h"
+
#include <cassert>
+#include <string>
#include "lldb/lldb-defines.h"
#include "lldb/lldb-types.h"
@@ -36,44 +39,10 @@ public:
eExecMessage
};
- enum CrashReason
- {
- eInvalidCrashReason,
-
- // SIGSEGV crash reasons.
- eInvalidAddress,
- ePrivilegedAddress,
-
- // SIGILL crash reasons.
- eIllegalOpcode,
- eIllegalOperand,
- eIllegalAddressingMode,
- eIllegalTrap,
- ePrivilegedOpcode,
- ePrivilegedRegister,
- eCoprocessorError,
- eInternalStackError,
-
- // SIGBUS crash reasons,
- eIllegalAlignment,
- eIllegalAddress,
- eHardwareError,
-
- // SIGFPE crash reasons,
- eIntegerDivideByZero,
- eIntegerOverflow,
- eFloatDivideByZero,
- eFloatOverflow,
- eFloatUnderflow,
- eFloatInexactResult,
- eFloatInvalidOperation,
- eFloatSubscriptRange
- };
-
ProcessMessage()
: m_tid(LLDB_INVALID_PROCESS_ID),
m_kind(eInvalidMessage),
- m_crash_reason(eInvalidCrashReason),
+ m_crash_reason(CrashReason::eInvalidCrashReason),
m_status(0),
m_addr(0) { }
@@ -175,15 +144,9 @@ public:
return m_child_tid;
}
- static const char *
- GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr);
-
const char *
PrintCrashReason() const;
- static const char *
- PrintCrashReason(CrashReason reason);
-
const char *
PrintKind() const;
@@ -195,7 +158,7 @@ private:
int status = 0, lldb::addr_t addr = 0)
: m_tid(tid),
m_kind(kind),
- m_crash_reason(eInvalidCrashReason),
+ m_crash_reason(CrashReason::eInvalidCrashReason),
m_status(status),
m_addr(addr),
m_child_tid(0) { }
@@ -203,14 +166,14 @@ private:
ProcessMessage(lldb::tid_t tid, Kind kind, lldb::tid_t child_tid)
: m_tid(tid),
m_kind(kind),
- m_crash_reason(eInvalidCrashReason),
+ m_crash_reason(CrashReason::eInvalidCrashReason),
m_status(0),
m_addr(0),
m_child_tid(child_tid) { }
lldb::tid_t m_tid;
Kind m_kind : 8;
- CrashReason m_crash_reason : 8;
+ CrashReason m_crash_reason;
int m_status;
lldb::addr_t m_addr;
lldb::tid_t m_child_tid;
diff --git a/source/Plugins/Process/POSIX/ProcessPOSIX.cpp b/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
index 0e5ab5a8d8b1..882fac75c9a0 100644
--- a/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
+++ b/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
@@ -252,7 +252,16 @@ ProcessPOSIX::DoLaunch (Module *module,
if (!error.Success())
return error;
- SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
+ int terminal = m_monitor->GetTerminalFD();
+ if (terminal >= 0) {
+ // The reader thread will close the file descriptor when done, so we pass it a copy.
+ int stdio = fcntl(terminal, F_DUPFD_CLOEXEC, 0);
+ if (stdio == -1) {
+ error.SetErrorToErrno();
+ return error;
+ }
+ SetSTDIOFileDescriptor(stdio);
+ }
SetID(m_monitor->GetPID());
return error;
diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp
index b542db4779db..80e1c1984225 100644
--- a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp
+++ b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp
@@ -38,14 +38,21 @@ RegisterContextPOSIXProcessMonitor_powerpc::GetMonitor()
bool
RegisterContextPOSIXProcessMonitor_powerpc::ReadGPR()
{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize());
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize());
}
bool
RegisterContextPOSIXProcessMonitor_powerpc::ReadFPR()
{
- // XXX not yet implemented
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadFPR(m_thread.GetID(), &m_fpr_powerpc, sizeof(m_fpr_powerpc));
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::ReadVMX()
+{
+ // XXX: Need a way to read/write process VMX registers with ptrace.
return false;
}
@@ -59,7 +66,14 @@ RegisterContextPOSIXProcessMonitor_powerpc::WriteGPR()
bool
RegisterContextPOSIXProcessMonitor_powerpc::WriteFPR()
{
- // XXX not yet implemented
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteFPR(m_thread.GetID(), &m_fpr_powerpc, sizeof(m_fpr_powerpc));
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::WriteVMX()
+{
+ // XXX: Need a way to read/write process VMX registers with ptrace.
return false;
}
@@ -146,26 +160,15 @@ RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(const RegisterInfo *reg
{
if (!ReadFPR())
return false;
+ uint8_t *src = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
+ value.SetUInt64(*(uint64_t*)src);
}
- else
+ else if (IsGPR(reg))
{
- uint32_t full_reg = reg;
- bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
- if (is_subreg)
- {
- // Read the full aligned 64-bit register.
- full_reg = reg_info->invalidate_regs[0];
- }
-
- bool success = ReadRegister(full_reg, value);
+ bool success = ReadRegister(reg, value);
if (success)
{
- // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right.
- if (is_subreg && (reg_info->byte_offset & 0x1))
- value.SetUInt64(value.GetAsUInt64() >> 8);
-
// If our return byte size was greater than the return value reg size, then
// use the type specified by reg_info rather than the uint64_t default
if (value.GetByteSize() > reg_info->byte_size)
@@ -183,7 +186,16 @@ RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(const RegisterInfo *re
const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
if (IsGPR(reg))
+ {
return WriteRegister(reg, value);
+ }
+ else if (IsFPR(reg))
+ {
+ assert (reg_info->byte_offset < sizeof(m_fpr_powerpc));
+ uint8_t *dst = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
+ *(uint64_t *)dst = value.GetAsUInt64();
+ return WriteFPR();
+ }
return false;
}
@@ -221,6 +233,9 @@ RegisterContextPOSIXProcessMonitor_powerpc::WriteAllRegisterValues(const DataBuf
if (WriteGPR())
{
src += GetGPRSize();
+ ::memcpy (&m_fpr_powerpc, src, sizeof(m_fpr_powerpc));
+
+ success = WriteFPR();
}
}
}
diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h
index 92a331285515..5c686df4836f 100644
--- a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h
+++ b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h
@@ -23,17 +23,26 @@ public:
protected:
bool
+ IsVMX();
+
+ bool
ReadGPR();
bool
ReadFPR();
bool
+ ReadVMX();
+
+ bool
WriteGPR();
bool
WriteFPR();
+ bool
+ WriteVMX();
+
// lldb_private::RegisterContext
bool
ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
index 1088924bfeac..25a195e11a03 100644
--- a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -15,7 +15,7 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/DataFormatters/FormatManager.h"
@@ -158,8 +158,8 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict
regex_match.GetMatchAtIndex(slice_cstr, 2, msbit_str) &&
regex_match.GetMatchAtIndex(slice_cstr, 3, lsbit_str))
{
- const uint32_t msbit = Args::StringToUInt32(msbit_str.c_str(), UINT32_MAX);
- const uint32_t lsbit = Args::StringToUInt32(lsbit_str.c_str(), UINT32_MAX);
+ const uint32_t msbit = StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX);
+ const uint32_t lsbit = StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX);
if (msbit != UINT32_MAX && lsbit != UINT32_MAX)
{
if (msbit > lsbit)
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp b/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
index 5170e6d2accb..5133d6088bd3 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
@@ -134,6 +134,45 @@ typedef struct _FPR
uint64_t fpscr;
} FPR;
+typedef struct _VMX
+{
+ uint32_t v0[4];
+ uint32_t v1[4];
+ uint32_t v2[4];
+ uint32_t v3[4];
+ uint32_t v4[4];
+ uint32_t v5[4];
+ uint32_t v6[4];
+ uint32_t v7[4];
+ uint32_t v8[4];
+ uint32_t v9[4];
+ uint32_t v10[4];
+ uint32_t v11[4];
+ uint32_t v12[4];
+ uint32_t v13[4];
+ uint32_t v14[4];
+ uint32_t v15[4];
+ uint32_t v16[4];
+ uint32_t v17[4];
+ uint32_t v18[4];
+ uint32_t v19[4];
+ uint32_t v20[4];
+ uint32_t v21[4];
+ uint32_t v22[4];
+ uint32_t v23[4];
+ uint32_t v24[4];
+ uint32_t v25[4];
+ uint32_t v26[4];
+ uint32_t v27[4];
+ uint32_t v28[4];
+ uint32_t v29[4];
+ uint32_t v30[4];
+ uint32_t v31[4];
+ uint32_t pad[2];
+ uint32_t vrsave;
+ uint32_t vscr;
+} VMX;
+
//---------------------------------------------------------------------------
// Include RegisterInfos_powerpc to declare our g_register_infos_powerpc structure.
//---------------------------------------------------------------------------
diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index f47d687702ec..1b3a9491d1c8 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -811,7 +811,7 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame ()
if (m_frame_type == eTrapHandlerFrame && process)
{
m_fast_unwind_plan_sp.reset();
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (process->GetTarget(), m_current_offset_backed_up_one);
+ unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan (process->GetTarget(), m_current_offset_backed_up_one);
if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc) && unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes)
{
return unwind_plan_sp;
@@ -826,7 +826,10 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame ()
// But there is not.
if (process && process->GetDynamicLoader() && process->GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo (m_sym_ctx))
{
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (process->GetTarget(), m_current_offset_backed_up_one);
+ // We must specifically call the GetEHFrameUnwindPlan() method here -- normally we would
+ // call GetUnwindPlanAtCallSite() -- because CallSite may return an unwind plan sourced from
+ // either eh_frame (that's what we intend) or compact unwind (this won't work)
+ unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan (process->GetTarget(), m_current_offset_backed_up_one);
if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
{
UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan because the DynamicLoader suggested we prefer it",
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
index b9b9dca07be4..b38d6cc60cac 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
@@ -125,3 +125,8 @@ RegisterContextLinux_i386::GetRegisterCount () const
return static_cast<uint32_t> (sizeof (g_register_infos_i386) / sizeof (g_register_infos_i386 [0]));
}
+uint32_t
+RegisterContextLinux_i386::GetUserRegisterCount () const
+{
+ return static_cast<uint32_t> (k_num_user_registers_i386);
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_i386.h b/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
index f8b21fc8e87d..cb71d7993e17 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
@@ -26,6 +26,9 @@ public:
uint32_t
GetRegisterCount () const override;
+
+ uint32_t
+ GetUserRegisterCount () const override;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
index 74f016bd744d..5c93ebf88faa 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
@@ -145,10 +145,26 @@ GetRegisterInfoCount (const ArchSpec &target_arch)
}
}
+static uint32_t
+GetUserRegisterInfoCount (const ArchSpec &target_arch)
+{
+ switch (target_arch.GetMachine())
+ {
+ case llvm::Triple::x86:
+ return static_cast<uint32_t> (k_num_user_registers_i386);
+ case llvm::Triple::x86_64:
+ return static_cast<uint32_t> (k_num_user_registers_x86_64);
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
+}
+
RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(const ArchSpec &target_arch) :
lldb_private::RegisterInfoInterface(target_arch),
m_register_info_p (GetRegisterInfoPtr (target_arch)),
- m_register_info_count (GetRegisterInfoCount (target_arch))
+ m_register_info_count (GetRegisterInfoCount (target_arch)),
+ m_user_register_count (GetUserRegisterInfoCount (target_arch))
{
}
@@ -169,3 +185,9 @@ RegisterContextLinux_x86_64::GetRegisterCount () const
{
return m_register_info_count;
}
+
+uint32_t
+RegisterContextLinux_x86_64::GetUserRegisterCount () const
+{
+ return m_user_register_count;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h b/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
index 7b6828661c1e..0cdfae9ac943 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
@@ -27,9 +27,13 @@ public:
uint32_t
GetRegisterCount () const override;
+ uint32_t
+ GetUserRegisterCount () const override;
+
private:
const lldb_private::RegisterInfo *m_register_info_p;
uint32_t m_register_info_count;
+ uint32_t m_user_register_count;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
index a9477d583517..828fb2571f79 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
@@ -106,10 +106,49 @@ uint32_t g_fpr_regnums[] =
fpr_fpscr_powerpc,
};
+static const
+uint32_t g_vmx_regnums[] =
+{
+ vmx_v0_powerpc,
+ vmx_v1_powerpc,
+ vmx_v2_powerpc,
+ vmx_v3_powerpc,
+ vmx_v4_powerpc,
+ vmx_v5_powerpc,
+ vmx_v6_powerpc,
+ vmx_v7_powerpc,
+ vmx_v8_powerpc,
+ vmx_v9_powerpc,
+ vmx_v10_powerpc,
+ vmx_v11_powerpc,
+ vmx_v12_powerpc,
+ vmx_v13_powerpc,
+ vmx_v14_powerpc,
+ vmx_v15_powerpc,
+ vmx_v16_powerpc,
+ vmx_v17_powerpc,
+ vmx_v18_powerpc,
+ vmx_v19_powerpc,
+ vmx_v20_powerpc,
+ vmx_v21_powerpc,
+ vmx_v22_powerpc,
+ vmx_v23_powerpc,
+ vmx_v24_powerpc,
+ vmx_v25_powerpc,
+ vmx_v26_powerpc,
+ vmx_v27_powerpc,
+ vmx_v28_powerpc,
+ vmx_v29_powerpc,
+ vmx_v30_powerpc,
+ vmx_v31_powerpc,
+ vmx_vrsave_powerpc,
+ vmx_vscr_powerpc,
+};
+
// Number of register sets provided by this context.
enum
{
- k_num_register_sets = 2
+ k_num_register_sets = 3
};
static const RegisterSet
@@ -117,20 +156,26 @@ g_reg_sets_powerpc[k_num_register_sets] =
{
{ "General Purpose Registers", "gpr", k_num_gpr_registers_powerpc, g_gpr_regnums },
{ "Floating Point Registers", "fpr", k_num_fpr_registers_powerpc, g_fpr_regnums },
+ { "Altivec/VMX Registers", "vmx", k_num_vmx_registers_powerpc, g_vmx_regnums },
};
bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg)
{
- return reg <= k_num_gpr_registers_powerpc; // GPR's come first.
+ return (reg >= k_first_gpr_powerpc) && (reg <= k_last_gpr_powerpc); // GPR's come first.
}
bool
RegisterContextPOSIX_powerpc::IsFPR(unsigned reg)
{
- // XXX
return (reg >= k_first_fpr) && (reg <= k_last_fpr);
}
+bool
+RegisterContextPOSIX_powerpc::IsVMX(unsigned reg)
+{
+ return (reg >= k_first_vmx) && (reg <= k_last_vmx);
+}
+
RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc(Thread &thread,
uint32_t concrete_frame_idx,
RegisterInfoInterface *register_info)
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
index 3194c3968c98..c7a2451d7811 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
@@ -97,9 +97,47 @@ enum
fpr_fpscr_powerpc,
k_last_fpr = fpr_fpscr_powerpc,
+ k_first_vmx,
+ vmx_v0_powerpc = k_first_vmx,
+ vmx_v1_powerpc,
+ vmx_v2_powerpc,
+ vmx_v3_powerpc,
+ vmx_v4_powerpc,
+ vmx_v5_powerpc,
+ vmx_v6_powerpc,
+ vmx_v7_powerpc,
+ vmx_v8_powerpc,
+ vmx_v9_powerpc,
+ vmx_v10_powerpc,
+ vmx_v11_powerpc,
+ vmx_v12_powerpc,
+ vmx_v13_powerpc,
+ vmx_v14_powerpc,
+ vmx_v15_powerpc,
+ vmx_v16_powerpc,
+ vmx_v17_powerpc,
+ vmx_v18_powerpc,
+ vmx_v19_powerpc,
+ vmx_v20_powerpc,
+ vmx_v21_powerpc,
+ vmx_v22_powerpc,
+ vmx_v23_powerpc,
+ vmx_v24_powerpc,
+ vmx_v25_powerpc,
+ vmx_v26_powerpc,
+ vmx_v27_powerpc,
+ vmx_v28_powerpc,
+ vmx_v29_powerpc,
+ vmx_v30_powerpc,
+ vmx_v31_powerpc,
+ vmx_vrsave_powerpc,
+ vmx_vscr_powerpc,
+ k_last_vmx = vmx_vscr_powerpc,
+
k_num_registers_powerpc,
k_num_gpr_registers_powerpc = k_last_gpr_powerpc - k_first_gpr_powerpc + 1,
k_num_fpr_registers_powerpc = k_last_fpr - k_first_fpr + 1,
+ k_num_vmx_registers_powerpc = k_last_vmx - k_first_vmx + 1,
};
class RegisterContextPOSIX_powerpc
@@ -147,6 +185,8 @@ public:
protected:
uint64_t m_gpr_powerpc[k_num_gpr_registers_powerpc]; // general purpose registers.
+ uint64_t m_fpr_powerpc[k_num_fpr_registers_powerpc]; // floating point registers.
+ uint32_t m_vmx_powerpc[k_num_vmx_registers_powerpc][4];
std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
// Determines if an extended register set is supported on the processor running the inferior process.
@@ -162,12 +202,17 @@ protected:
bool
IsFPR(unsigned reg);
+ bool
+ IsVMX(unsigned reg);
+
lldb::ByteOrder GetByteOrder();
virtual bool ReadGPR() = 0;
virtual bool ReadFPR() = 0;
+ virtual bool ReadVMX() = 0;
virtual bool WriteGPR() = 0;
virtual bool WriteFPR() = 0;
+ virtual bool WriteVMX() = 0;
};
#endif // #ifndef liblldb_RegisterContextPOSIX_powerpc_H_
diff --git a/source/Plugins/Process/Utility/RegisterContext_powerpc.h b/source/Plugins/Process/Utility/RegisterContext_powerpc.h
index cf54cc0c2145..7438b88971b3 100644
--- a/source/Plugins/Process/Utility/RegisterContext_powerpc.h
+++ b/source/Plugins/Process/Utility/RegisterContext_powerpc.h
@@ -79,10 +79,45 @@ enum
gcc_dwarf_f31_powerpc,
gcc_dwarf_cr_powerpc,
gcc_dwarf_fpscr_powerpc,
+ gcc_dwarf_msr_powerpc,
+ gcc_dwarf_vscr_powerpc,
gcc_dwarf_xer_powerpc = 101,
gcc_dwarf_lr_powerpc = 108,
gcc_dwarf_ctr_powerpc,
gcc_dwarf_pc_powerpc,
+ gcc_dwarf_vrsave_powerpc = 356,
+ gcc_dwarf_v0_powerpc = 1124,
+ gcc_dwarf_v1_powerpc,
+ gcc_dwarf_v2_powerpc,
+ gcc_dwarf_v3_powerpc,
+ gcc_dwarf_v4_powerpc,
+ gcc_dwarf_v5_powerpc,
+ gcc_dwarf_v6_powerpc,
+ gcc_dwarf_v7_powerpc,
+ gcc_dwarf_v8_powerpc,
+ gcc_dwarf_v9_powerpc,
+ gcc_dwarf_v10_powerpc,
+ gcc_dwarf_v11_powerpc,
+ gcc_dwarf_v12_powerpc,
+ gcc_dwarf_v13_powerpc,
+ gcc_dwarf_v14_powerpc,
+ gcc_dwarf_v15_powerpc,
+ gcc_dwarf_v16_powerpc,
+ gcc_dwarf_v17_powerpc,
+ gcc_dwarf_v18_powerpc,
+ gcc_dwarf_v19_powerpc,
+ gcc_dwarf_v20_powerpc,
+ gcc_dwarf_v21_powerpc,
+ gcc_dwarf_v22_powerpc,
+ gcc_dwarf_v23_powerpc,
+ gcc_dwarf_v24_powerpc,
+ gcc_dwarf_v25_powerpc,
+ gcc_dwarf_v26_powerpc,
+ gcc_dwarf_v27_powerpc,
+ gcc_dwarf_v28_powerpc,
+ gcc_dwarf_v29_powerpc,
+ gcc_dwarf_v30_powerpc,
+ gcc_dwarf_v31_powerpc,
};
// GDB Register numbers (eRegisterKindGDB)
@@ -152,12 +187,46 @@ enum
gdb_f29_powerpc,
gdb_f30_powerpc,
gdb_f31_powerpc,
- gdb_cr_powerpc,
- gdb_fpscr_powerpc,
- gdb_xer_powerpc = 101,
- gdb_lr_powerpc = 108,
- gdb_ctr_powerpc,
gdb_pc_powerpc,
+ gdb_cr_powerpc = 66,
+ gdb_lr_powerpc,
+ gdb_ctr_powerpc,
+ gdb_xer_powerpc,
+ gdb_fpscr_powerpc,
+ gdb_v0_powerpc = 106,
+ gdb_v1_powerpc,
+ gdb_v2_powerpc,
+ gdb_v3_powerpc,
+ gdb_v4_powerpc,
+ gdb_v5_powerpc,
+ gdb_v6_powerpc,
+ gdb_v7_powerpc,
+ gdb_v8_powerpc,
+ gdb_v9_powerpc,
+ gdb_v10_powerpc,
+ gdb_v11_powerpc,
+ gdb_v12_powerpc,
+ gdb_v13_powerpc,
+ gdb_v14_powerpc,
+ gdb_v15_powerpc,
+ gdb_v16_powerpc,
+ gdb_v17_powerpc,
+ gdb_v18_powerpc,
+ gdb_v19_powerpc,
+ gdb_v20_powerpc,
+ gdb_v21_powerpc,
+ gdb_v22_powerpc,
+ gdb_v23_powerpc,
+ gdb_v24_powerpc,
+ gdb_v25_powerpc,
+ gdb_v26_powerpc,
+ gdb_v27_powerpc,
+ gdb_v28_powerpc,
+ gdb_v29_powerpc,
+ gdb_v30_powerpc,
+ gdb_v31_powerpc,
+ gdb_vscr_powerpc,
+ gdb_vrsave_powerpc,
};
#endif // liblldb_RegisterContext_powerpc_H_
diff --git a/source/Plugins/Process/Utility/RegisterInfoInterface.h b/source/Plugins/Process/Utility/RegisterInfoInterface.h
index 382475f4523a..94cb5cc791c6 100644
--- a/source/Plugins/Process/Utility/RegisterInfoInterface.h
+++ b/source/Plugins/Process/Utility/RegisterInfoInterface.h
@@ -32,9 +32,20 @@ namespace lldb_private
virtual const lldb_private::RegisterInfo *
GetRegisterInfo () const = 0;
+ // Returns the number of registers including the user registers and the
+ // lldb internal registers also
virtual uint32_t
GetRegisterCount () const = 0;
+ // Returns the number of the user registers (excluding the registers
+ // kept for lldb internal use only). Subclasses should override it if
+ // they belongs to an architecture with lldb internal registers.
+ virtual uint32_t
+ GetUserRegisterCount () const
+ {
+ return GetRegisterCount();
+ }
+
const lldb_private::ArchSpec&
GetTargetArchitecture() const
{ return m_target_arch; }
diff --git a/source/Plugins/Process/Utility/RegisterInfos_powerpc.h b/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
index 045426648105..fe145e99588b 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
@@ -14,6 +14,8 @@
(offsetof(GPR, regname))
#define FPR_OFFSET(regname) \
(offsetof(FPR, regname))
+#define VMX_OFFSET(regname) \
+ (offsetof(VMX, regname))
#define GPR_SIZE(regname) \
(sizeof(((GPR*)NULL)->regname))
@@ -26,6 +28,9 @@
#define DEFINE_FPR(reg, lldb_kind) \
{ #reg, NULL, 8, FPR_OFFSET(reg), eEncodingIEEE754, \
eFormatFloat, { gcc_dwarf_##reg##_powerpc, gcc_dwarf_##reg##_powerpc, lldb_kind, gdb_##reg##_powerpc, fpr_##reg##_powerpc }, NULL, NULL }
+#define DEFINE_VMX(reg, lldb_kind) \
+ { #reg, NULL, 16, VMX_OFFSET(reg), eEncodingVector, \
+ eFormatVectorOfUInt32, { gcc_dwarf_##reg##_powerpc, gcc_dwarf_##reg##_powerpc, lldb_kind, gdb_##reg##_powerpc, vmx_##reg##_powerpc }, NULL, NULL }
// General purpose registers. GCC, DWARF, Generic, GDB
#define POWERPC_REGS \
@@ -98,7 +103,42 @@
DEFINE_FPR(f29, LLDB_INVALID_REGNUM), \
DEFINE_FPR(f30, LLDB_INVALID_REGNUM), \
DEFINE_FPR(f31, LLDB_INVALID_REGNUM), \
- { "fpscr", NULL, 8, FPR_OFFSET(fpscr), eEncodingUint, eFormatHex, { gcc_dwarf_fpscr_powerpc, gcc_dwarf_fpscr_powerpc, LLDB_INVALID_REGNUM, gdb_fpscr_powerpc, fpr_fpscr_powerpc }, NULL, NULL },
+ { "fpscr", NULL, 8, FPR_OFFSET(fpscr), eEncodingUint, eFormatHex, { gcc_dwarf_fpscr_powerpc, gcc_dwarf_fpscr_powerpc, LLDB_INVALID_REGNUM, gdb_fpscr_powerpc, fpr_fpscr_powerpc }, NULL, NULL }, \
+ DEFINE_VMX(v0, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v1, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v2, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v3, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v4, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v5, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v6, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v7, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v8, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v9, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v10, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v11, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v12, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v13, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v14, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v15, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v16, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v17, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v18, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v19, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v20, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v21, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v22, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v23, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v24, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v25, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v26, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v27, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v28, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v29, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v30, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v31, LLDB_INVALID_REGNUM), \
+ { "vrsave", NULL, 4, VMX_OFFSET(vrsave), eEncodingUint, eFormatHex, { gcc_dwarf_vrsave_powerpc, gcc_dwarf_vrsave_powerpc, LLDB_INVALID_REGNUM, gdb_vrsave_powerpc, vmx_vrsave_powerpc }, NULL, NULL }, \
+ { "vscr", NULL, 4, VMX_OFFSET(vscr), eEncodingUint, eFormatHex, { gcc_dwarf_vscr_powerpc, gcc_dwarf_vscr_powerpc, LLDB_INVALID_REGNUM, gdb_vscr_powerpc, vmx_vscr_powerpc }, NULL, NULL },
+
static RegisterInfo
g_register_infos_powerpc64[] =
{
diff --git a/source/Plugins/Process/Utility/lldb-x86-register-enums.h b/source/Plugins/Process/Utility/lldb-x86-register-enums.h
index 99fca3005820..63027b4451b8 100644
--- a/source/Plugins/Process/Utility/lldb-x86-register-enums.h
+++ b/source/Plugins/Process/Utility/lldb-x86-register-enums.h
@@ -118,7 +118,8 @@ namespace lldb_private
k_num_registers_i386,
k_num_gpr_registers_i386 = k_last_gpr_i386 - k_first_gpr_i386 + 1,
k_num_fpr_registers_i386 = k_last_fpr_i386 - k_first_fpr_i386 + 1,
- k_num_avx_registers_i386 = k_last_avx_i386 - k_first_avx_i386 + 1
+ k_num_avx_registers_i386 = k_last_avx_i386 - k_first_avx_i386 + 1,
+ k_num_user_registers_i386 = k_num_gpr_registers_i386 + k_num_fpr_registers_i386 + k_num_avx_registers_i386,
};
//---------------------------------------------------------------------------
@@ -285,7 +286,8 @@ namespace lldb_private
k_num_registers_x86_64,
k_num_gpr_registers_x86_64 = k_last_gpr_x86_64 - k_first_gpr_x86_64 + 1,
k_num_fpr_registers_x86_64 = k_last_fpr_x86_64 - k_first_fpr_x86_64 + 1,
- k_num_avx_registers_x86_64 = k_last_avx_x86_64 - k_first_avx_x86_64 + 1
+ k_num_avx_registers_x86_64 = k_last_avx_x86_64 - k_first_avx_x86_64 + 1,
+ k_num_user_registers_x86_64 = k_num_gpr_registers_x86_64 + k_num_fpr_registers_x86_64 + k_num_avx_registers_x86_64,
};
}
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index fb39d7318a5a..ead959508d88 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -412,7 +412,8 @@ enum {
NT_FPREGSET,
NT_PRPSINFO,
NT_THRMISC = 7,
- NT_PROCSTAT_AUXV = 16
+ NT_PROCSTAT_AUXV = 16,
+ NT_PPC_VMX = 0x100
};
}
@@ -538,6 +539,9 @@ ProcessElfCore::ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader *
// FIXME: FreeBSD sticks an int at the beginning of the note
m_auxv = DataExtractor(segment_data, note_start + 4, note_size - 4);
break;
+ case FREEBSD::NT_PPC_VMX:
+ thread_data->vregset = note_data;
+ break;
default:
break;
}
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
index 15b1b44182d7..d12df21a8664 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
@@ -18,7 +18,8 @@ using namespace lldb_private;
RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc(Thread &thread,
RegisterInfoInterface *register_info,
const DataExtractor &gpregset,
- const DataExtractor &fpregset)
+ const DataExtractor &fpregset,
+ const DataExtractor &vregset)
: RegisterContextPOSIX_powerpc(thread, 0, register_info)
{
m_gpr_buffer.reset(new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
@@ -27,6 +28,9 @@ RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc(Thread &threa
m_fpr_buffer.reset(new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
m_fpr.SetData(m_fpr_buffer);
m_fpr.SetByteOrder(fpregset.GetByteOrder());
+ m_vec_buffer.reset(new DataBufferHeap(vregset.GetDataStart(), vregset.GetByteSize()));
+ m_vec.SetData(m_vec_buffer);
+ m_vec.SetByteOrder(fpregset.GetByteOrder());
}
RegisterContextCorePOSIX_powerpc::~RegisterContextCorePOSIX_powerpc()
@@ -46,6 +50,12 @@ RegisterContextCorePOSIX_powerpc::ReadFPR()
}
bool
+RegisterContextCorePOSIX_powerpc::ReadVMX()
+{
+ return true;
+}
+
+bool
RegisterContextCorePOSIX_powerpc::WriteGPR()
{
assert(0);
@@ -60,16 +70,31 @@ RegisterContextCorePOSIX_powerpc::WriteFPR()
}
bool
+RegisterContextCorePOSIX_powerpc::WriteVMX()
+{
+ assert(0);
+ return false;
+}
+
+bool
RegisterContextCorePOSIX_powerpc::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
{
lldb::offset_t offset = reg_info->byte_offset;
- if (reg_info->name[0] == 'f') {
+ if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
uint64_t v = m_fpr.GetMaxU64(&offset, reg_info->byte_size);
if (offset == reg_info->byte_offset + reg_info->byte_size)
{
value = v;
return true;
}
+ } else if (IsVMX(reg_info->kinds[lldb::eRegisterKindLLDB])) {
+ uint32_t v[4];
+ offset = m_vec.CopyData(offset, reg_info->byte_size, &v);
+ if (offset == reg_info->byte_size)
+ {
+ value.SetBytes(v, reg_info->byte_size, m_vec.GetByteOrder());
+ return true;
+ }
} else {
uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
if (offset == reg_info->byte_offset + reg_info->byte_size)
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
index e6575581b360..a3590601fa7e 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
@@ -20,7 +20,8 @@ public:
RegisterContextCorePOSIX_powerpc (lldb_private::Thread &thread,
lldb_private::RegisterInfoInterface *register_info,
const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ const lldb_private::DataExtractor &fpregset,
+ const lldb_private::DataExtractor &vregset);
~RegisterContextCorePOSIX_powerpc();
@@ -47,16 +48,24 @@ protected:
ReadFPR();
bool
+ ReadVMX();
+
+ bool
WriteGPR();
bool
WriteFPR();
+ bool
+ WriteVMX();
+
private:
lldb::DataBufferSP m_gpr_buffer;
lldb::DataBufferSP m_fpr_buffer;
+ lldb::DataBufferSP m_vec_buffer;
lldb_private::DataExtractor m_gpr;
lldb_private::DataExtractor m_fpr;
+ lldb_private::DataExtractor m_vec;
};
#endif // #ifndef liblldb_RegisterContextCorePOSIX_powerpc_H_
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
index d62bcfcff600..b16335fb8e1e 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -38,7 +38,8 @@ ThreadElfCore::ThreadElfCore (Process &process, tid_t tid,
m_thread_reg_ctx_sp (),
m_signo(td.signo),
m_gpregset_data(td.gpregset),
- m_fpregset_data(td.fpregset)
+ m_fpregset_data(td.fpregset),
+ m_vregset_data(td.vregset)
{
}
@@ -148,7 +149,7 @@ ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
break;
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc (*this, reg_interface, m_gpregset_data, m_fpregset_data));
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc (*this, reg_interface, m_gpregset_data, m_fpregset_data, m_vregset_data));
break;
case llvm::Triple::x86:
case llvm::Triple::x86_64:
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.h b/source/Plugins/Process/elf-core/ThreadElfCore.h
index f1f00cf019b3..50502c101daf 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.h
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.h
@@ -111,6 +111,7 @@ struct ThreadData
{
lldb_private::DataExtractor gpregset;
lldb_private::DataExtractor fpregset;
+ lldb_private::DataExtractor vregset;
int signo;
std::string name;
};
@@ -170,6 +171,7 @@ protected:
lldb_private::DataExtractor m_gpregset_data;
lldb_private::DataExtractor m_fpregset_data;
+ lldb_private::DataExtractor m_vregset_data;
virtual bool CalculateStopInfo();
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 919fa5405117..d633b3eaf34c 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -26,9 +26,11 @@
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Pipe.h"
#include "lldb/Host/Socket.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Target/Process.h"
+#include "llvm/ADT/SmallString.h"
// Project includes
#include "ProcessGDBRemoteLog.h"
@@ -756,13 +758,14 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
}
// use native registers, not the GDB registers
- debugserver_args.AppendArgument("--native-regs");
- // make debugserver run in its own session so signals generated by
- // special terminal key sequences (^C) don't affect debugserver
- debugserver_args.AppendArgument("--setsid");
+ debugserver_args.AppendArgument("--native-regs");
- char named_pipe_path[PATH_MAX];
- named_pipe_path[0] = '\0';
+ if (launch_info.GetLaunchInSeparateProcessGroup())
+ {
+ debugserver_args.AppendArgument("--setsid");
+ }
+
+ llvm::SmallString<PATH_MAX> named_pipe_path;
Pipe port_named_pipe;
bool listen = false;
@@ -776,25 +779,11 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
{
// Binding to port zero, we need to figure out what port it ends up
// using using a named pipe...
- FileSpec tmpdir_file_spec;
- if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
- {
- tmpdir_file_spec.AppendPathComponent("debugserver-named-pipe.XXXXXX");
- strncpy(named_pipe_path, tmpdir_file_spec.GetPath().c_str(), sizeof(named_pipe_path));
- }
- else
- {
- strncpy(named_pipe_path, "/tmp/debugserver-named-pipe.XXXXXX", sizeof(named_pipe_path));
- }
-
- if (::mktemp (named_pipe_path))
- {
- error = port_named_pipe.CreateNew(named_pipe_path, false);
- if (error.Fail())
- return error;
- debugserver_args.AppendArgument("--named-pipe");
- debugserver_args.AppendArgument(named_pipe_path);
- }
+ error = port_named_pipe.CreateWithUniqueName("debugserver-named-pipe", false, named_pipe_path);
+ if (error.Fail())
+ return error;
+ debugserver_args.AppendArgument("--named-pipe");
+ debugserver_args.AppendArgument(named_pipe_path.c_str());
}
else
{
@@ -874,7 +863,7 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
if (error.Success() && launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
{
- if (named_pipe_path[0])
+ if (named_pipe_path.size() > 0)
{
error = port_named_pipe.OpenAsReader(named_pipe_path, false);
if (error.Success())
@@ -887,14 +876,14 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
if (error.Success())
{
assert (num_bytes > 0 && port_cstr[num_bytes-1] == '\0');
- out_port = Args::StringToUInt32(port_cstr, 0);
+ out_port = StringConvert::ToUInt32(port_cstr, 0);
if (log)
log->Printf("GDBRemoteCommunication::%s() debugserver listens %u port", __FUNCTION__, out_port);
}
else
{
if (log)
- log->Printf("GDBRemoteCommunication::%s() failed to read a port value from named pipe %s: %s", __FUNCTION__, named_pipe_path, error.AsCString());
+ log->Printf("GDBRemoteCommunication::%s() failed to read a port value from named pipe %s: %s", __FUNCTION__, named_pipe_path.c_str(), error.AsCString());
}
port_named_pipe.Close();
@@ -902,13 +891,13 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
else
{
if (log)
- log->Printf("GDBRemoteCommunication::%s() failed to open named pipe %s for reading: %s", __FUNCTION__, named_pipe_path, error.AsCString());
+ log->Printf("GDBRemoteCommunication::%s() failed to open named pipe %s for reading: %s", __FUNCTION__, named_pipe_path.c_str(), error.AsCString());
}
const auto err = port_named_pipe.Delete(named_pipe_path);
if (err.Fail())
{
if (log)
- log->Printf ("GDBRemoteCommunication::%s failed to delete pipe %s: %s", __FUNCTION__, named_pipe_path, err.AsCString());
+ log->Printf ("GDBRemoteCommunication::%s failed to delete pipe %s: %s", __FUNCTION__, named_pipe_path.c_str(), err.AsCString());
}
}
else if (listen)
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index ac203a62788a..ee2f3276513d 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -27,6 +27,16 @@
#include "Utility/StringExtractorGDBRemote.h"
+typedef enum
+{
+ eStoppointInvalid = -1,
+ eBreakpointSoftware = 0,
+ eBreakpointHardware,
+ eWatchpointWrite,
+ eWatchpointRead,
+ eWatchpointReadWrite
+} GDBStoppointType;
+
class ProcessGDBRemote;
class GDBRemoteCommunication : public lldb_private::Communication
@@ -282,9 +292,8 @@ protected:
ListenThread (lldb::thread_arg_t arg);
private:
- lldb_private::HostThread m_listen_thread;
+ lldb_private::HostThread m_listen_thread;
std::string m_listen_url;
-
//------------------------------------------------------------------
// For GDBRemoteCommunication only
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 52750de5a25f..0f99688fc823 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -28,6 +28,7 @@
#include "lldb/Host/Endian.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Target/Target.h"
@@ -1210,13 +1211,13 @@ GDBRemoteCommunicationClient::SendInterrupt
}
lldb::pid_t
-GDBRemoteCommunicationClient::GetCurrentProcessID ()
+GDBRemoteCommunicationClient::GetCurrentProcessID (bool allow_lazy)
{
- if (m_curr_pid_is_valid == eLazyBoolYes)
+ if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
return m_curr_pid;
// First try to retrieve the pid via the qProcessInfo request.
- GetCurrentProcessInfo ();
+ GetCurrentProcessInfo (allow_lazy);
if (m_curr_pid_is_valid == eLazyBoolYes)
{
// We really got it.
@@ -1559,7 +1560,7 @@ GDBRemoteCommunicationClient::GetGDBServerVersion()
size_t dot_pos = value.find('.');
if (dot_pos != std::string::npos)
value[dot_pos] = '\0';
- const uint32_t version = Args::StringToUInt32(value.c_str(), UINT32_MAX, 0);
+ const uint32_t version = StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0);
if (version != UINT32_MAX)
{
success = true;
@@ -1625,14 +1626,14 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force)
if (name.compare("cputype") == 0)
{
// exception type in big endian hex
- cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
+ cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
if (cpu != LLDB_INVALID_CPUTYPE)
++num_keys_decoded;
}
else if (name.compare("cpusubtype") == 0)
{
// exception count in big endian hex
- sub = Args::StringToUInt32 (value.c_str(), 0, 0);
+ sub = StringConvert::ToUInt32 (value.c_str(), 0, 0);
if (sub != 0)
++num_keys_decoded;
}
@@ -1700,7 +1701,7 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force)
}
else if (name.compare("ptrsize") == 0)
{
- pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
+ pointer_byte_size = StringConvert::ToUInt32 (value.c_str(), 0, 0);
if (pointer_byte_size != 0)
++num_keys_decoded;
}
@@ -1725,7 +1726,7 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force)
}
else if (name.compare("default_packet_timeout") == 0)
{
- m_default_packet_timeout = Args::StringToUInt32(value.c_str(), 0);
+ m_default_packet_timeout = StringConvert::ToUInt32(value.c_str(), 0);
if (m_default_packet_timeout > 0)
{
SetPacketTimeout(m_default_packet_timeout);
@@ -1865,6 +1866,21 @@ GDBRemoteCommunicationClient::SendAttach
return -1;
}
+int
+GDBRemoteCommunicationClient::SendStdinNotification (const char* data, size_t data_len)
+{
+ StreamString packet;
+ packet.PutCString("I");
+ packet.PutBytesAsRawHex8(data, data_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
+ {
+ return 0;
+ }
+ return response.GetError();
+
+}
+
const lldb_private::ArchSpec &
GDBRemoteCommunicationClient::GetHostArchitecture ()
{
@@ -2006,13 +2022,13 @@ GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,
{
if (name.compare ("start") == 0)
{
- addr_value = Args::StringToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success);
+ addr_value = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success);
if (success)
region_info.GetRange().SetRangeBase(addr_value);
}
else if (name.compare ("size") == 0)
{
- addr_value = Args::StringToUInt64(value.c_str(), 0, 16, &success);
+ addr_value = StringConvert::ToUInt64(value.c_str(), 0, 16, &success);
if (success)
region_info.GetRange().SetByteSize (addr_value);
}
@@ -2107,7 +2123,7 @@ GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num)
{
if (name.compare ("num") == 0)
{
- num = Args::StringToUInt32(value.c_str(), 0, 0);
+ num = StringConvert::ToUInt32(value.c_str(), 0, 0);
m_num_supported_hardware_watchpoints = num;
}
}
@@ -2309,27 +2325,27 @@ GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemot
{
if (name.compare("pid") == 0)
{
- process_info.SetProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
+ process_info.SetProcessID (StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
}
else if (name.compare("ppid") == 0)
{
- process_info.SetParentProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
+ process_info.SetParentProcessID (StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
}
else if (name.compare("uid") == 0)
{
- process_info.SetUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
+ process_info.SetUserID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
}
else if (name.compare("euid") == 0)
{
- process_info.SetEffectiveUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
+ process_info.SetEffectiveUserID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
}
else if (name.compare("gid") == 0)
{
- process_info.SetGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
+ process_info.SetGroupID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
}
else if (name.compare("egid") == 0)
{
- process_info.SetEffectiveGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
+ process_info.SetEffectiveGroupID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
}
else if (name.compare("triple") == 0)
{
@@ -2351,11 +2367,11 @@ GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemot
}
else if (name.compare("cputype") == 0)
{
- cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
+ cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
}
else if (name.compare("cpusubtype") == 0)
{
- sub = Args::StringToUInt32 (value.c_str(), 0, 16);
+ sub = StringConvert::ToUInt32 (value.c_str(), 0, 16);
}
else if (name.compare("vendor") == 0)
{
@@ -2408,14 +2424,17 @@ GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceIn
}
bool
-GDBRemoteCommunicationClient::GetCurrentProcessInfo ()
+GDBRemoteCommunicationClient::GetCurrentProcessInfo (bool allow_lazy)
{
Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
- if (m_qProcessInfo_is_valid == eLazyBoolYes)
- return true;
- if (m_qProcessInfo_is_valid == eLazyBoolNo)
- return false;
+ if (allow_lazy)
+ {
+ if (m_qProcessInfo_is_valid == eLazyBoolYes)
+ return true;
+ if (m_qProcessInfo_is_valid == eLazyBoolNo)
+ return false;
+ }
GetHostInfo ();
@@ -2441,13 +2460,13 @@ GDBRemoteCommunicationClient::GetCurrentProcessInfo ()
{
if (name.compare("cputype") == 0)
{
- cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
+ cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
if (cpu != LLDB_INVALID_CPUTYPE)
++num_keys_decoded;
}
else if (name.compare("cpusubtype") == 0)
{
- sub = Args::StringToUInt32 (value.c_str(), 0, 16);
+ sub = StringConvert::ToUInt32 (value.c_str(), 0, 16);
if (sub != 0)
++num_keys_decoded;
}
@@ -2483,13 +2502,13 @@ GDBRemoteCommunicationClient::GetCurrentProcessInfo ()
}
else if (name.compare("ptrsize") == 0)
{
- pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 16);
+ pointer_byte_size = StringConvert::ToUInt32 (value.c_str(), 0, 16);
if (pointer_byte_size != 0)
++num_keys_decoded;
}
else if (name.compare("pid") == 0)
{
- pid = Args::StringToUInt64(value.c_str(), 0, 16);
+ pid = StringConvert::ToUInt64(value.c_str(), 0, 16);
if (pid != LLDB_INVALID_PROCESS_ID)
++num_keys_decoded;
}
@@ -2849,7 +2868,11 @@ GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort (lldb::pid_t &pid, const
const char *packet = stream.GetData();
int packet_len = stream.GetSize();
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
+ // give the process a few seconds to startup
+ const uint32_t old_packet_timeout = SetPacketTimeout (10);
+ auto result = SendPacketAndWaitForResponse(packet, packet_len, response, false);
+ SetPacketTimeout (old_packet_timeout);
+ if (result == PacketResult::Success)
{
std::string name;
std::string value;
@@ -2857,9 +2880,9 @@ GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort (lldb::pid_t &pid, const
while (response.GetNameColonValue(name, value))
{
if (name.compare("port") == 0)
- port = Args::StringToUInt32(value.c_str(), 0, 0);
+ port = StringConvert::ToUInt32(value.c_str(), 0, 0);
else if (name.compare("pid") == 0)
- pid = Args::StringToUInt64(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
+ pid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
}
return port;
}
@@ -3013,6 +3036,7 @@ GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type,
case eWatchpointWrite: m_supports_z2 = false; break;
case eWatchpointRead: m_supports_z3 = false; break;
case eWatchpointReadWrite: m_supports_z4 = false; break;
+ case eStoppointInvalid: return UINT8_MAX;
}
}
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index fddcd6cd1426..d90614bce88b 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -21,15 +21,6 @@
#include "GDBRemoteCommunication.h"
-typedef enum
-{
- eBreakpointSoftware = 0,
- eBreakpointHardware,
- eWatchpointWrite,
- eWatchpointRead,
- eWatchpointReadWrite
-} GDBStoppointType;
-
class GDBRemoteCommunicationClient : public GDBRemoteCommunication
{
public:
@@ -109,7 +100,7 @@ public:
bool &timed_out);
lldb::pid_t
- GetCurrentProcessID ();
+ GetCurrentProcessID (bool allow_lazy = true);
bool
GetLaunchSuccess (std::string &error_str);
@@ -184,6 +175,23 @@ public:
//------------------------------------------------------------------
+ /// Sends a GDB remote protocol 'I' packet that delivers stdin
+ /// data to the remote process.
+ ///
+ /// @param[in] data
+ /// A pointer to stdin data.
+ ///
+ /// @param[in] data_len
+ /// The number of bytes available at \a data.
+ ///
+ /// @return
+ /// Zero if the attach was successful, or an error indicating
+ /// an error code.
+ //------------------------------------------------------------------
+ int
+ SendStdinNotification(const char* data, size_t data_len);
+
+ //------------------------------------------------------------------
/// Sets the path to use for stdin/out/err for a process
/// that will be launched with the 'A' packet.
///
@@ -375,8 +383,8 @@ public:
case eWatchpointWrite: return m_supports_z2;
case eWatchpointRead: return m_supports_z3;
case eWatchpointReadWrite: return m_supports_z4;
+ case eStoppointInvalid: return false;
}
- return false;
}
uint8_t
SendGDBStoppointTypePacket (GDBStoppointType type, // Type of breakpoint or watchpoint
@@ -534,7 +542,7 @@ protected:
StringExtractorGDBRemote &response);
bool
- GetCurrentProcessInfo ();
+ GetCurrentProcessInfo (bool allow_lazy_pid = true);
bool
GetGDBServerVersion();
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index a7149505e869..dd920c0df0ca 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -34,16 +34,18 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Target/FileAction.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
-#include "lldb/Target/NativeRegisterContext.h"
-#include "Host/common/NativeProcessProtocol.h"
-#include "Host/common/NativeThreadProtocol.h"
+#include "lldb/Host/common/NativeRegisterContext.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/Host/common/NativeThreadProtocol.h"
// Project includes
#include "Utility/StringExtractorGDBRemote.h"
+#include "Utility/UriParser.h"
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
@@ -276,6 +278,10 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec,
packet_result = Handle_qPlatform_shell (packet);
break;
+ case StringExtractorGDBRemote::eServerPacketType_qWatchpointSupportInfo:
+ packet_result = Handle_qWatchpointSupportInfo (packet);
+ break;
+
case StringExtractorGDBRemote::eServerPacketType_C:
packet_result = Handle_C (packet);
break;
@@ -364,6 +370,10 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec,
packet_result = Handle_H (packet);
break;
+ case StringExtractorGDBRemote::eServerPacketType_I:
+ packet_result = Handle_I (packet);
+ break;
+
case StringExtractorGDBRemote::eServerPacketType_m:
packet_result = Handle_m (packet);
break;
@@ -601,14 +611,12 @@ GDBRemoteCommunicationServer::LaunchPlatformProcess ()
// add to list of spawned processes. On an lldb-gdbserver, we
// would expect there to be only one.
- lldb::pid_t pid;
- if ( (pid = m_process_launch_info.GetProcessID()) != LLDB_INVALID_PROCESS_ID )
+ const auto pid = m_process_launch_info.GetProcessID();
+ if (pid != LLDB_INVALID_PROCESS_ID)
{
// add to spawned pids
- {
- Mutex::Locker locker (m_spawned_pids_mutex);
- m_spawned_pids.insert(pid);
- }
+ Mutex::Locker locker (m_spawned_pids_mutex);
+ m_spawned_pids.insert(pid);
}
return error;
@@ -835,12 +843,12 @@ GDBRemoteCommunicationServer::SendStopReplyPacketForThread (lldb::tid_t tid)
// Grab the reason this thread stopped.
struct ThreadStopInfo tid_stop_info;
- if (!thread_sp->GetStopReason (tid_stop_info))
+ std::string description;
+ if (!thread_sp->GetStopReason (tid_stop_info, description))
return SendErrorResponse (52);
- const bool did_exec = tid_stop_info.reason == eStopReasonExec;
// FIXME implement register handling for exec'd inferiors.
- // if (did_exec)
+ // if (tid_stop_info.reason == eStopReasonExec)
// {
// const bool force = true;
// InitializeRegisters(force);
@@ -861,25 +869,6 @@ GDBRemoteCommunicationServer::SendStopReplyPacketForThread (lldb::tid_t tid)
tid_stop_info.details.exception.type);
}
- switch (tid_stop_info.reason)
- {
- case eStopReasonSignal:
- case eStopReasonException:
- signum = thread_sp->TranslateStopInfoToGdbSignal (tid_stop_info);
- break;
- default:
- signum = 0;
- if (log)
- {
- log->Printf ("GDBRemoteCommunicationServer::%s pid %" PRIu64 " tid %" PRIu64 " has stop reason %d, using signo = 0 in stop reply response",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- tid,
- tid_stop_info.reason);
- }
- break;
- }
-
// Print the signal number.
response.PutHex8 (signum & 0xff);
@@ -906,14 +895,6 @@ GDBRemoteCommunicationServer::SendStopReplyPacketForThread (lldb::tid_t tid)
response.PutChar (';');
}
- // FIXME look for analog
- // thread_identifier_info_data_t thread_ident_info;
- // if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info))
- // {
- // if (thread_ident_info.dispatch_qaddr != 0)
- // ostrm << std::hex << "qaddr:" << thread_ident_info.dispatch_qaddr << ';';
- // }
-
// 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:
@@ -978,9 +959,45 @@ GDBRemoteCommunicationServer::SendStopReplyPacketForThread (lldb::tid_t tid)
}
}
- if (did_exec)
+ const char* reason_str = nullptr;
+ switch (tid_stop_info.reason)
+ {
+ case eStopReasonTrace:
+ reason_str = "trace";
+ break;
+ case eStopReasonBreakpoint:
+ reason_str = "breakpoint";
+ break;
+ case eStopReasonWatchpoint:
+ reason_str = "watchpoint";
+ break;
+ case eStopReasonSignal:
+ reason_str = "signal";
+ break;
+ case eStopReasonException:
+ reason_str = "exception";
+ break;
+ case eStopReasonExec:
+ reason_str = "exec";
+ break;
+ case eStopReasonInstrumentation:
+ case eStopReasonInvalid:
+ case eStopReasonPlanComplete:
+ case eStopReasonThreadExiting:
+ case eStopReasonNone:
+ break;
+ }
+ if (reason_str != nullptr)
+ {
+ response.Printf ("reason:%s;", reason_str);
+ }
+
+ if (!description.empty())
{
- response.PutCString ("reason:exec;");
+ // Description may contains special chars, send as hex bytes.
+ response.PutCString ("description:");
+ response.PutCStringAsRawHex8 (description.c_str ());
+ response.PutChar (';');
}
else if ((tid_stop_info.reason == eStopReasonException) && tid_stop_info.details.exception.type)
{
@@ -1422,23 +1439,34 @@ CreateProcessInfoResponse_DebugServerStyle (const ProcessInstanceInfo &proc_info
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_qProcessInfo (StringExtractorGDBRemote &packet)
{
- // Only the gdb server handles this.
- if (!IsGdbServer ())
- return SendUnimplementedResponse (packet.GetStringRef ().c_str ());
-
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- return SendErrorResponse (68);
-
- ProcessInstanceInfo proc_info;
- if (Host::GetProcessInfo (m_debugged_process_sp->GetID (), proc_info))
+ lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+
+ if (IsGdbServer ())
{
- StreamString response;
- CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
- return SendPacketNoLock (response.GetData (), response.GetSize ());
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse (68);
+
+ pid = m_debugged_process_sp->GetID ();
}
-
- return SendErrorResponse (1);
+ else if (m_is_platform)
+ {
+ pid = m_process_launch_info.GetProcessID ();
+ m_process_launch_info.Clear ();
+ }
+ else
+ return SendUnimplementedResponse (packet.GetStringRef ().c_str ());
+
+ if (pid == LLDB_INVALID_PROCESS_ID)
+ return SendErrorResponse (1);
+
+ ProcessInstanceInfo proc_info;
+ if (!Host::GetProcessInfo (pid, proc_info))
+ return SendErrorResponse (1);
+
+ StreamString response;
+ CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
+ return SendPacketNoLock (response.GetData (), response.GetSize ());
}
GDBRemoteCommunication::PacketResult
@@ -1512,27 +1540,27 @@ GDBRemoteCommunicationServer::Handle_qfProcessInfo (StringExtractorGDBRemote &pa
}
else if (key.compare("pid") == 0)
{
- match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
+ match_info.GetProcessInfo().SetProcessID (StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
}
else if (key.compare("parent_pid") == 0)
{
- match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
+ match_info.GetProcessInfo().SetParentProcessID (StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
}
else if (key.compare("uid") == 0)
{
- match_info.GetProcessInfo().SetUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
+ match_info.GetProcessInfo().SetUserID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
}
else if (key.compare("gid") == 0)
{
- match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
+ match_info.GetProcessInfo().SetGroupID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
}
else if (key.compare("euid") == 0)
{
- match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
+ match_info.GetProcessInfo().SetEffectiveUserID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
}
else if (key.compare("egid") == 0)
{
- match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
+ match_info.GetProcessInfo().SetEffectiveGroupID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
}
else if (key.compare("all_users") == 0)
{
@@ -1627,7 +1655,7 @@ GDBRemoteCommunicationServer::Handle_qSpeedTest (StringExtractorGDBRemote &packe
bool success = packet.GetNameColonValue(key, value);
if (success && key.compare("response_size") == 0)
{
- uint32_t response_size = Args::StringToUInt32(value.c_str(), 0, 0, &success);
+ uint32_t response_size = StringConvert::ToUInt32(value.c_str(), 0, 0, &success);
if (success)
{
if (response_size == 0)
@@ -1901,7 +1929,7 @@ GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote
if (name.compare ("host") == 0)
hostname.swap(value);
else if (name.compare ("port") == 0)
- port = Args::StringToUInt32(value.c_str(), 0, 0);
+ port = StringConvert::ToUInt32(value.c_str(), 0, 0);
}
if (port == UINT16_MAX)
port = GetNextAvailablePort();
@@ -1909,6 +1937,9 @@ GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote
// Spawn a new thread to accept the port that gets bound after
// binding to port 0 (zero).
+ // ignore the hostname send from the remote end, just use the ip address
+ // that we're currently communicating with as the hostname
+
// Spawn a debugserver and try to get the port it listens to.
ProcessLaunchInfo debugserver_launch_info;
if (hostname.empty())
@@ -1916,9 +1947,19 @@ GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote
if (log)
log->Printf("Launching debugserver with: %s:%u...\n", hostname.c_str(), port);
+ // Do not run in a new session so that it can not linger after the
+ // platform closes.
+ debugserver_launch_info.SetLaunchInSeparateProcessGroup(false);
debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false);
- Error error = StartDebugserverProcess (hostname.empty() ? NULL : hostname.c_str(),
+ std::string platform_scheme;
+ std::string platform_ip;
+ int platform_port;
+ std::string platform_path;
+ bool ok = UriParser::Parse(GetConnection()->GetURI().c_str(), platform_scheme, platform_ip, platform_port, platform_path);
+ assert(ok);
+ Error error = StartDebugserverProcess (
+ platform_ip.c_str(),
port,
debugserver_launch_info,
port);
@@ -2502,10 +2543,6 @@ GDBRemoteCommunicationServer::Handle_vCont (StringExtractorGDBRemote &packet)
thread_actions.Append (thread_action);
}
- // If a default action for all other threads wasn't mentioned
- // then we should stop the threads.
- thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
-
Error error = m_debugged_process_sp->Resume (thread_actions);
if (error.Fail ())
{
@@ -2983,7 +3020,7 @@ GDBRemoteCommunicationServer::Handle_qRegisterInfo (StringExtractorGDBRemote &pa
return SendErrorResponse (69);
// Return the end of registers response if we've iterated one past the end of the register set.
- if (reg_index >= reg_context_sp->GetRegisterCount ())
+ if (reg_index >= reg_context_sp->GetUserRegisterCount ())
return SendErrorResponse (69);
const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex(reg_index);
@@ -3184,10 +3221,10 @@ GDBRemoteCommunicationServer::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->GetRegisterCount ())
+ if (reg_index >= reg_context_sp->GetUserRegisterCount ())
{
if (log)
- log->Printf ("GDBRemoteCommunicationServer::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetRegisterCount ());
+ log->Printf ("GDBRemoteCommunicationServer::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetUserRegisterCount ());
return SendErrorResponse (0x15);
}
@@ -3264,7 +3301,8 @@ GDBRemoteCommunicationServer::Handle_P (StringExtractorGDBRemote &packet)
}
// Parse out the value.
- const uint64_t raw_value = packet.GetHexMaxU64 (process_arch.GetByteOrder () == lldb::eByteOrderLittle, std::numeric_limits<uint64_t>::max ());
+ uint8_t reg_bytes[32]; // big enough to support up to 256 bit ymmN register
+ size_t reg_size = packet.GetHexBytesAvail (reg_bytes, sizeof(reg_bytes));
// Get the thread to use.
NativeThreadProtocolSP thread_sp = GetThreadFromSuffix (packet);
@@ -3284,7 +3322,7 @@ GDBRemoteCommunicationServer::Handle_P (StringExtractorGDBRemote &packet)
return SendErrorResponse (0x15);
}
- const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+ const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex (reg_index);
if (!reg_info)
{
if (log)
@@ -3293,20 +3331,23 @@ GDBRemoteCommunicationServer::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->GetRegisterCount ())
+ if (reg_index >= reg_context_sp->GetUserRegisterCount ())
{
if (log)
- log->Printf ("GDBRemoteCommunicationServer::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetRegisterCount ());
+ log->Printf ("GDBRemoteCommunicationServer::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetUserRegisterCount ());
return SendErrorResponse (0x47);
}
+ if (reg_size != reg_info->byte_size)
+ {
+ return SendIllFormedResponse (packet, "P packet register size is incorrect");
+ }
// Build the reginfos response.
StreamGDBRemote response;
- // FIXME Could be suffixed with a thread: parameter.
- // That thread then needs to be fed back into the reg context retrieval above.
- Error error = reg_context_sp->WriteRegisterFromUnsigned (reg_info, raw_value);
+ RegisterValue reg_value (reg_bytes, reg_size, process_arch.GetByteOrder ());
+ Error error = reg_context_sp->WriteRegister (reg_info, reg_value);
if (error.Fail ())
{
if (log)
@@ -3394,6 +3435,46 @@ GDBRemoteCommunicationServer::Handle_H (StringExtractorGDBRemote &packet)
}
GDBRemoteCommunicationServer::PacketResult
+GDBRemoteCommunicationServer::Handle_I (StringExtractorGDBRemote &packet)
+{
+ Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ // Ensure we're llgs.
+ if (!IsGdbServer())
+ return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_I() unimplemented");
+
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
+ {
+ if (log)
+ log->Printf ("GDBRemoteCommunicationServer::%s failed, no process available", __FUNCTION__);
+ return SendErrorResponse (0x15);
+ }
+
+ packet.SetFilePos (::strlen("I"));
+ char tmp[4096];
+ for (;;)
+ {
+ size_t read = packet.GetHexBytesAvail(tmp, sizeof(tmp));
+ if (read == 0)
+ {
+ break;
+ }
+ // write directly to stdin *this might block if stdin buffer is full*
+ // TODO: enqueue this block in circular buffer and send window size to remote host
+ ConnectionStatus status;
+ Error error;
+ m_stdio_communication.Write(tmp, read, status, &error);
+ if (error.Fail())
+ {
+ return SendErrorResponse (0x15);
+ }
+ }
+
+ return SendOKResponse();
+}
+
+GDBRemoteCommunicationServer::PacketResult
GDBRemoteCommunicationServer::Handle_interrupt (StringExtractorGDBRemote &packet)
{
Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
@@ -3704,8 +3785,6 @@ GDBRemoteCommunicationServer::Handle_qMemoryRegionInfo (StringExtractorGDBRemote
GDBRemoteCommunicationServer::PacketResult
GDBRemoteCommunicationServer::Handle_Z (StringExtractorGDBRemote &packet)
{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
-
// We don't support if we're not llgs.
if (!IsGdbServer())
return SendUnimplementedResponse ("");
@@ -3713,12 +3792,13 @@ GDBRemoteCommunicationServer::Handle_Z (StringExtractorGDBRemote &packet)
// Ensure we have a process.
if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
{
+ Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
if (log)
log->Printf ("GDBRemoteCommunicationServer::%s failed, no process available", __FUNCTION__);
return SendErrorResponse (0x15);
}
- // Parse out software or hardware breakpoint requested.
+ // Parse out software or hardware breakpoint or watchpoint requested.
packet.SetFilePos (strlen("Z"));
if (packet.GetBytesLeft() < 1)
return SendIllFormedResponse(packet, "Too short Z packet, missing software/hardware specifier");
@@ -3726,61 +3806,82 @@ GDBRemoteCommunicationServer::Handle_Z (StringExtractorGDBRemote &packet)
bool want_breakpoint = true;
bool want_hardware = false;
- const char breakpoint_type_char = packet.GetChar ();
- switch (breakpoint_type_char)
- {
- case '0': want_hardware = false; want_breakpoint = true; break;
- case '1': want_hardware = true; want_breakpoint = true; break;
- case '2': want_breakpoint = false; break;
- case '3': want_breakpoint = false; break;
- default:
+ const GDBStoppointType stoppoint_type =
+ GDBStoppointType(packet.GetS32 (eStoppointInvalid));
+ switch (stoppoint_type)
+ {
+ case eBreakpointSoftware:
+ want_hardware = false; want_breakpoint = true; break;
+ case eBreakpointHardware:
+ want_hardware = true; want_breakpoint = true; break;
+ case eWatchpointWrite:
+ want_hardware = true; want_breakpoint = false; break;
+ case eWatchpointRead:
+ want_hardware = true; want_breakpoint = false; break;
+ case eWatchpointReadWrite:
+ want_hardware = true; want_breakpoint = false; break;
+ case eStoppointInvalid:
return SendIllFormedResponse(packet, "Z packet had invalid software/hardware specifier");
}
if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
- return SendIllFormedResponse(packet, "Malformed Z packet, expecting comma after breakpoint type");
+ return SendIllFormedResponse(packet, "Malformed Z packet, expecting comma after stoppoint type");
- // FIXME implement watchpoint support.
- if (!want_breakpoint)
- return SendUnimplementedResponse ("watchpoint support not yet implemented");
-
- // Parse out the breakpoint address.
+ // Parse out the stoppoint address.
if (packet.GetBytesLeft() < 1)
return SendIllFormedResponse(packet, "Too short Z packet, missing address");
- const lldb::addr_t breakpoint_addr = packet.GetHexMaxU64(false, 0);
+ const lldb::addr_t addr = packet.GetHexMaxU64(false, 0);
if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
return SendIllFormedResponse(packet, "Malformed Z packet, expecting comma after address");
- // Parse out the breakpoint kind (i.e. size hint for opcode size).
- const uint32_t kind = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
- if (kind == std::numeric_limits<uint32_t>::max ())
- return SendIllFormedResponse(packet, "Malformed Z packet, failed to parse kind argument");
+ // Parse out the stoppoint size (i.e. size hint for opcode size).
+ const uint32_t size = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
+ if (size == std::numeric_limits<uint32_t>::max ())
+ return SendIllFormedResponse(packet, "Malformed Z packet, failed to parse size argument");
if (want_breakpoint)
{
// Try to set the breakpoint.
- const Error error = m_debugged_process_sp->SetBreakpoint (breakpoint_addr, kind, want_hardware);
+ const Error error = m_debugged_process_sp->SetBreakpoint (addr, size, want_hardware);
if (error.Success ())
return SendOKResponse ();
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServer::%s pid %" PRIu64 " failed to set breakpoint: %s", __FUNCTION__, m_debugged_process_sp->GetID (), error.AsCString ());
- return SendErrorResponse (0x09);
- }
+ Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf ("GDBRemoteCommunicationServer::%s pid %" PRIu64
+ " failed to set breakpoint: %s",
+ __FUNCTION__,
+ m_debugged_process_sp->GetID (),
+ error.AsCString ());
+ return SendErrorResponse (0x09);
}
+ else
+ {
+ uint32_t watch_flags =
+ stoppoint_type == eWatchpointWrite
+ ? watch_flags = 0x1 // Write
+ : watch_flags = 0x3; // ReadWrite
- // FIXME fix up after watchpoints are handled.
- return SendUnimplementedResponse ("");
+ // Try to set the watchpoint.
+ const Error error = m_debugged_process_sp->SetWatchpoint (
+ addr, size, watch_flags, want_hardware);
+ if (error.Success ())
+ return SendOKResponse ();
+ Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf ("GDBRemoteCommunicationServer::%s pid %" PRIu64
+ " failed to set watchpoint: %s",
+ __FUNCTION__,
+ m_debugged_process_sp->GetID (),
+ error.AsCString ());
+ return SendErrorResponse (0x09);
+ }
}
GDBRemoteCommunicationServer::PacketResult
GDBRemoteCommunicationServer::Handle_z (StringExtractorGDBRemote &packet)
{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
-
// We don't support if we're not llgs.
if (!IsGdbServer())
return SendUnimplementedResponse ("");
@@ -3788,66 +3889,81 @@ GDBRemoteCommunicationServer::Handle_z (StringExtractorGDBRemote &packet)
// Ensure we have a process.
if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
{
+ Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
if (log)
log->Printf ("GDBRemoteCommunicationServer::%s failed, no process available", __FUNCTION__);
return SendErrorResponse (0x15);
}
- // Parse out software or hardware breakpoint requested.
+ // Parse out software or hardware breakpoint or watchpoint requested.
packet.SetFilePos (strlen("z"));
if (packet.GetBytesLeft() < 1)
return SendIllFormedResponse(packet, "Too short z packet, missing software/hardware specifier");
bool want_breakpoint = true;
- const char breakpoint_type_char = packet.GetChar ();
- switch (breakpoint_type_char)
+ const GDBStoppointType stoppoint_type =
+ GDBStoppointType(packet.GetS32 (eStoppointInvalid));
+ switch (stoppoint_type)
{
- case '0': want_breakpoint = true; break;
- case '1': want_breakpoint = true; break;
- case '2': want_breakpoint = false; break;
- case '3': want_breakpoint = false; break;
+ case eBreakpointHardware: want_breakpoint = true; break;
+ case eBreakpointSoftware: want_breakpoint = true; break;
+ case eWatchpointWrite: want_breakpoint = false; break;
+ case eWatchpointRead: want_breakpoint = false; break;
+ case eWatchpointReadWrite: want_breakpoint = false; break;
default:
return SendIllFormedResponse(packet, "z packet had invalid software/hardware specifier");
}
if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
- return SendIllFormedResponse(packet, "Malformed z packet, expecting comma after breakpoint type");
-
- // FIXME implement watchpoint support.
- if (!want_breakpoint)
- return SendUnimplementedResponse ("watchpoint support not yet implemented");
+ return SendIllFormedResponse(packet, "Malformed z packet, expecting comma after stoppoint type");
- // Parse out the breakpoint address.
+ // Parse out the stoppoint address.
if (packet.GetBytesLeft() < 1)
return SendIllFormedResponse(packet, "Too short z packet, missing address");
- const lldb::addr_t breakpoint_addr = packet.GetHexMaxU64(false, 0);
+ const lldb::addr_t addr = packet.GetHexMaxU64(false, 0);
if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
return SendIllFormedResponse(packet, "Malformed z packet, expecting comma after address");
- // Parse out the breakpoint kind (i.e. size hint for opcode size).
- const uint32_t kind = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
- if (kind == std::numeric_limits<uint32_t>::max ())
- return SendIllFormedResponse(packet, "Malformed z packet, failed to parse kind argument");
+ /*
+ // Parse out the stoppoint size (i.e. size hint for opcode size).
+ const uint32_t size = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
+ if (size == std::numeric_limits<uint32_t>::max ())
+ return SendIllFormedResponse(packet, "Malformed z packet, failed to parse size argument");
+ */
if (want_breakpoint)
{
// Try to clear the breakpoint.
- const Error error = m_debugged_process_sp->RemoveBreakpoint (breakpoint_addr);
+ const Error error = m_debugged_process_sp->RemoveBreakpoint (addr);
if (error.Success ())
return SendOKResponse ();
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServer::%s pid %" PRIu64 " failed to remove breakpoint: %s", __FUNCTION__, m_debugged_process_sp->GetID (), error.AsCString ());
- return SendErrorResponse (0x09);
- }
+ Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf ("GDBRemoteCommunicationServer::%s pid %" PRIu64
+ " failed to remove breakpoint: %s",
+ __FUNCTION__,
+ m_debugged_process_sp->GetID (),
+ error.AsCString ());
+ return SendErrorResponse (0x09);
+ }
+ else
+ {
+ // Try to clear the watchpoint.
+ const Error error = m_debugged_process_sp->RemoveWatchpoint (addr);
+ if (error.Success ())
+ return SendOKResponse ();
+ Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf ("GDBRemoteCommunicationServer::%s pid %" PRIu64
+ " failed to remove watchpoint: %s",
+ __FUNCTION__,
+ m_debugged_process_sp->GetID (),
+ error.AsCString ());
+ return SendErrorResponse (0x09);
}
-
- // FIXME fix up after watchpoints are handled.
- return SendUnimplementedResponse ("");
}
GDBRemoteCommunicationServer::PacketResult
@@ -4283,6 +4399,30 @@ GDBRemoteCommunicationServer::Handle_qThreadStopInfo (StringExtractorGDBRemote &
return SendStopReplyPacketForThread (tid);
}
+GDBRemoteCommunicationServer::PacketResult
+GDBRemoteCommunicationServer::Handle_qWatchpointSupportInfo (StringExtractorGDBRemote &packet)
+{
+ // Only the gdb server handles this.
+ if (!IsGdbServer ())
+ return SendUnimplementedResponse (packet.GetStringRef ().c_str ());
+
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)
+ return SendErrorResponse (68);
+
+ packet.SetFilePos(strlen("qWatchpointSupportInfo"));
+ if (packet.GetBytesLeft() == 0)
+ return SendOKResponse();
+ if (packet.GetChar() != ':')
+ return SendErrorResponse(67);
+
+ uint32_t num = m_debugged_process_sp->GetMaxWatchpoints();
+ StreamGDBRemote response;
+ response.Printf ("num:%d;", num);
+ return SendPacketNoLock(response.GetData(), response.GetSize());
+}
+
void
GDBRemoteCommunicationServer::FlushInferiorOutput ()
{
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index 07ce98e29ac6..dcf07844527e 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -23,7 +23,7 @@
#include "lldb/Target/Process.h"
#include "GDBRemoteCommunication.h"
-#include "../../../Host/common/NativeProcessProtocol.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
class ProcessGDBRemote;
class StringExtractorGDBRemote;
@@ -415,6 +415,9 @@ protected:
Handle_H (StringExtractorGDBRemote &packet);
PacketResult
+ Handle_I (StringExtractorGDBRemote &packet);
+
+ PacketResult
Handle_interrupt (StringExtractorGDBRemote &packet);
PacketResult
@@ -465,6 +468,9 @@ protected:
PacketResult
Handle_qThreadStopInfo (StringExtractorGDBRemote &packet);
+ PacketResult
+ Handle_qWatchpointSupportInfo (StringExtractorGDBRemote &packet);
+
void
SetCurrentThreadID (lldb::tid_t tid);
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index fe99706969c8..cb0b4bb51007 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -42,6 +42,7 @@
#include "lldb/Core/Timer.h"
#include "lldb/Core/Value.h"
#include "lldb/Host/HostThread.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/TimeValue.h"
@@ -431,11 +432,11 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
}
else if (name.compare("bitsize") == 0)
{
- reg_info.byte_size = Args::StringToUInt32(value.c_str(), 0, 0) / CHAR_BIT;
+ reg_info.byte_size = StringConvert::ToUInt32(value.c_str(), 0, 0) / CHAR_BIT;
}
else if (name.compare("offset") == 0)
{
- uint32_t offset = Args::StringToUInt32(value.c_str(), UINT32_MAX, 0);
+ uint32_t offset = StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0);
if (reg_offset != offset)
{
reg_offset = offset;
@@ -483,11 +484,11 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
}
else if (name.compare("gcc") == 0)
{
- reg_info.kinds[eRegisterKindGCC] = Args::StringToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
+ reg_info.kinds[eRegisterKindGCC] = StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
}
else if (name.compare("dwarf") == 0)
{
- reg_info.kinds[eRegisterKindDWARF] = Args::StringToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
+ reg_info.kinds[eRegisterKindDWARF] = StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
}
else if (name.compare("generic") == 0)
{
@@ -502,7 +503,7 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
value_pair = value_pair.second.split(',');
if (!value_pair.first.empty())
{
- uint32_t reg = Args::StringToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, 16);
+ uint32_t reg = StringConvert::ToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, 16);
if (reg != LLDB_INVALID_REGNUM)
value_regs.push_back (reg);
}
@@ -517,7 +518,7 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
value_pair = value_pair.second.split(',');
if (!value_pair.first.empty())
{
- uint32_t reg = Args::StringToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, 16);
+ uint32_t reg = StringConvert::ToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, 16);
if (reg != LLDB_INVALID_REGNUM)
invalidate_regs.push_back (reg);
}
@@ -941,6 +942,7 @@ ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info)
SetPrivateState (SetThreadStopInfo (m_last_stop_packet));
+ m_stdio_disable = disable_stdio;
if (!disable_stdio)
{
if (pty.GetMasterFileDescriptor() != lldb_utility::PseudoTerminal::invalid_fd)
@@ -972,9 +974,12 @@ ProcessGDBRemote::ConnectToDebugserver (const char *connect_url)
{
Error error;
// Only connect if we have a valid connect URL
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
if (connect_url && connect_url[0])
{
+ if (log)
+ log->Printf("ProcessGDBRemote::%s Connecting to %s", __FUNCTION__, connect_url);
std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
if (conn_ap.get())
{
@@ -1656,17 +1661,17 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
if (name.compare("metype") == 0)
{
// exception type in big endian hex
- exc_type = Args::StringToUInt32 (value.c_str(), 0, 16);
+ exc_type = StringConvert::ToUInt32 (value.c_str(), 0, 16);
}
else if (name.compare("medata") == 0)
{
// exception data in big endian hex
- exc_data.push_back(Args::StringToUInt64 (value.c_str(), 0, 16));
+ exc_data.push_back(StringConvert::ToUInt64 (value.c_str(), 0, 16));
}
else if (name.compare("thread") == 0)
{
// thread in big endian hex
- lldb::tid_t tid = Args::StringToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
+ lldb::tid_t tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
// m_thread_list_real does have its own mutex, but we need to
// hold onto the mutex between the call to m_thread_list_real.FindThreadByID(...)
// and the m_thread_list_real.AddThread(...) so it doesn't change on us
@@ -1702,12 +1707,12 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
{
value[comma_pos] = '\0';
// thread in big endian hex
- tid = Args::StringToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
+ tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
if (tid != LLDB_INVALID_THREAD_ID)
m_thread_ids.push_back (tid);
value.erase(0, comma_pos + 1);
}
- tid = Args::StringToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
+ tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
if (tid != LLDB_INVALID_THREAD_ID)
m_thread_ids.push_back (tid);
}
@@ -1726,7 +1731,7 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
}
else if (name.compare("qaddr") == 0)
{
- thread_dispatch_qaddr = Args::StringToUInt64 (value.c_str(), 0, 16);
+ thread_dispatch_qaddr = StringConvert::ToUInt64 (value.c_str(), 0, 16);
}
else if (name.compare("reason") == 0)
{
@@ -1738,7 +1743,8 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
// Swap "value" over into "name_extractor"
desc_extractor.GetStringRef().swap(value);
// Now convert the HEX bytes into a string value
- desc_extractor.GetHexByteString (thread_name);
+ desc_extractor.GetHexByteString (value);
+ description.swap(value);
}
else if (name.size() == 2 && ::isxdigit(name[0]) && ::isxdigit(name[1]))
{
@@ -1747,7 +1753,7 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
// so it won't have to go and read it.
if (gdb_thread)
{
- uint32_t reg = Args::StringToUInt32 (name.c_str(), UINT32_MAX, 16);
+ uint32_t reg = StringConvert::ToUInt32 (name.c_str(), UINT32_MAX, 16);
if (reg != UINT32_MAX)
{
@@ -1839,8 +1845,24 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
}
else if (reason.compare("watchpoint") == 0)
{
- break_id_t watch_id = LLDB_INVALID_WATCH_ID;
- // TODO: locate the watchpoint somehow...
+ StringExtractor desc_extractor(description.c_str());
+ addr_t wp_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
+ uint32_t wp_index = desc_extractor.GetU32(LLDB_INVALID_INDEX32);
+ watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
+ if (wp_addr != LLDB_INVALID_ADDRESS)
+ {
+ WatchpointSP wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr);
+ if (wp_sp)
+ {
+ wp_sp->SetHardwareIndex(wp_index);
+ watch_id = wp_sp->GetID();
+ }
+ }
+ if (watch_id == LLDB_INVALID_WATCH_ID)
+ {
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_WATCHPOINTS));
+ if (log) log->Printf ("failed to find watchpoint");
+ }
thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID (*thread_sp, watch_id));
handled = true;
}
@@ -2456,6 +2478,10 @@ ProcessGDBRemote::PutSTDIN (const char *src, size_t src_len, Error &error)
ConnectionStatus status;
m_stdio_communication.Write(src, src_len, status, NULL);
}
+ else if (!m_stdio_disable)
+ {
+ m_gdb_comm.SendStdinNotification(src, src_len);
+ }
return 0;
}
@@ -2760,6 +2786,10 @@ ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info
static FileSpec g_debugserver_file_spec;
ProcessLaunchInfo debugserver_launch_info;
+ // Make debugserver run in its own session so signals generated by
+ // special terminal key sequences (^C) don't affect debugserver.
+ debugserver_launch_info.SetLaunchInSeparateProcessGroup(true);
+
debugserver_launch_info.SetMonitorProcessCallback (MonitorDebugserverProcess, this, false);
debugserver_launch_info.SetUserID(process_info.GetUserID());
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
index 067449a289be..8935f7143e48 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -13,6 +13,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/Timer.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -992,11 +993,11 @@ DWARFCompileUnit::ParseProducerInfo ()
{
std::string str;
if (regex_match.GetMatchAtIndex (producer_cstr, 1, str))
- m_producer_version_major = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10);
+ m_producer_version_major = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
if (regex_match.GetMatchAtIndex (producer_cstr, 2, str))
- m_producer_version_minor = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10);
+ m_producer_version_minor = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
if (regex_match.GetMatchAtIndex (producer_cstr, 3, str))
- m_producer_version_update = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10);
+ m_producer_version_update = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
}
m_producer = eProducerClang;
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 10b51ffe0a8a..6a8c4e6d57b9 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -2294,22 +2294,26 @@ DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data,
if (dwarf2Data)
{
offset = GetOffset();
-
- const DWARFAbbreviationDeclaration* abbrev_decl = cu->GetAbbreviations()->GetAbbreviationDeclaration (m_abbr_idx);
- if (abbrev_decl)
+
+ const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
+ if (abbrev_set)
{
- // Make sure the abbreviation code still matches. If it doesn't and
- // the DWARF data was mmap'ed, the backing file might have been modified
- // which is bad news.
- const uint64_t abbrev_code = dwarf2Data->get_debug_info_data().GetULEB128 (&offset);
-
- if (abbrev_decl->Code() == abbrev_code)
- return abbrev_decl;
+ const DWARFAbbreviationDeclaration* abbrev_decl = abbrev_set->GetAbbreviationDeclaration (m_abbr_idx);
+ if (abbrev_decl)
+ {
+ // Make sure the abbreviation code still matches. If it doesn't and
+ // the DWARF data was mmap'ed, the backing file might have been modified
+ // which is bad news.
+ const uint64_t abbrev_code = dwarf2Data->get_debug_info_data().GetULEB128 (&offset);
- dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("0x%8.8x: the DWARF debug information has been modified (abbrev code was %u, and is now %u)",
- GetOffset(),
- (uint32_t)abbrev_decl->Code(),
- (uint32_t)abbrev_code);
+ if (abbrev_decl->Code() == abbrev_code)
+ return abbrev_decl;
+
+ dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("0x%8.8x: the DWARF debug information has been modified (abbrev code was %u, and is now %u)",
+ GetOffset(),
+ (uint32_t)abbrev_decl->Code(),
+ (uint32_t)abbrev_code);
+ }
}
}
offset = DW_INVALID_OFFSET;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index b3a5476227f4..7ba4f52ac297 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -893,13 +893,22 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
// only 1 compile unit which is at offset zero in the DWARF.
// TODO: modify to support LTO .o files where each .o file might
// have multiple DW_TAG_compile_unit tags.
- return info->GetCompileUnit(0).get();
+
+ DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(0).get();
+ if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
+ dwarf_cu->SetUserData(comp_unit);
+ return dwarf_cu;
}
else
{
// Just a normal DWARF file whose user ID for the compile unit is
// the DWARF offset itself
- return info->GetCompileUnit((dw_offset_t)comp_unit->GetID()).get();
+
+ DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID()).get();
+ if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
+ dwarf_cu->SetUserData(comp_unit);
+ return dwarf_cu;
+
}
}
return NULL;
@@ -1037,23 +1046,6 @@ SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
return cu_sp;
}
-static void
-AddRangesToBlock (Block& block,
- DWARFDebugRanges::RangeList& ranges,
- addr_t block_base_addr)
-{
- const size_t num_ranges = ranges.GetSize();
- for (size_t i = 0; i<num_ranges; ++i)
- {
- const DWARFDebugRanges::Range &range = ranges.GetEntryRef (i);
- const addr_t range_base = range.GetRangeBase();
- assert (range_base >= block_base_addr);
- block.AddRange(Block::Range (range_base - block_base_addr, range.GetByteSize()));;
- }
- block.FinalizeRanges ();
-}
-
-
Function *
SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
{
@@ -1397,8 +1389,24 @@ SymbolFileDWARF::ParseFunctionBlocks
subprogram_low_pc = ranges.GetMinRangeBase(0);
}
}
-
- AddRangesToBlock (*block, ranges, subprogram_low_pc);
+
+ const size_t num_ranges = ranges.GetSize();
+ for (size_t i = 0; i<num_ranges; ++i)
+ {
+ const DWARFDebugRanges::Range &range = ranges.GetEntryRef (i);
+ const addr_t range_base = range.GetRangeBase();
+ if (range_base >= subprogram_low_pc)
+ block->AddRange(Block::Range (range_base - subprogram_low_pc, range.GetByteSize()));
+ else
+ {
+ GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": adding range [0x%" PRIx64 "-0x%" PRIx64 ") which has a base that is less than the function's low PC 0x%" PRIx64 ". Please file a bug and attach the file at the start of this error message",
+ block->GetID(),
+ range_base,
+ range.GetRangeEnd(),
+ subprogram_low_pc);
+ }
+ }
+ block->FinalizeRanges ();
if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
{
@@ -2786,6 +2794,59 @@ SymbolFileDWARF::GetFunction (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEn
return false;
}
+
+
+SymbolFileDWARF::GlobalVariableMap &
+SymbolFileDWARF::GetGlobalAranges()
+{
+ if (!m_global_aranges_ap)
+ {
+ m_global_aranges_ap.reset (new GlobalVariableMap());
+
+ ModuleSP module_sp = GetObjectFile()->GetModule();
+ if (module_sp)
+ {
+ const size_t num_cus = module_sp->GetNumCompileUnits();
+ for (size_t i = 0; i < num_cus; ++i)
+ {
+ CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
+ if (cu_sp)
+ {
+ VariableListSP globals_sp = cu_sp->GetVariableList(true);
+ if (globals_sp)
+ {
+ const size_t num_globals = globals_sp->GetSize();
+ for (size_t g = 0; g < num_globals; ++g)
+ {
+ VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
+ if (var_sp && !var_sp->GetLocationIsConstantValueData())
+ {
+ const DWARFExpression &location = var_sp->LocationExpression();
+ Value location_result;
+ Error error;
+ if (location.Evaluate(NULL, NULL, NULL, LLDB_INVALID_ADDRESS, NULL, location_result, &error))
+ {
+ if (location_result.GetValueType() == Value::eValueTypeFileAddress)
+ {
+ lldb::addr_t file_addr = location_result.GetScalar().ULongLong();
+ lldb::addr_t byte_size = 1;
+ if (var_sp->GetType())
+ byte_size = var_sp->GetType()->GetByteSize();
+ m_global_aranges_ap->Append(GlobalVariableMap::Entry(file_addr, byte_size, var_sp.get()));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ m_global_aranges_ap->Sort();
+ }
+ return *m_global_aranges_ap;
+}
+
+
uint32_t
SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
{
@@ -2794,10 +2855,11 @@ SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_
static_cast<void*>(so_addr.GetSection().get()),
so_addr.GetOffset(), resolve_scope);
uint32_t resolved = 0;
- if (resolve_scope & ( eSymbolContextCompUnit |
- eSymbolContextFunction |
- eSymbolContextBlock |
- eSymbolContextLineEntry))
+ if (resolve_scope & ( eSymbolContextCompUnit |
+ eSymbolContextFunction |
+ eSymbolContextBlock |
+ eSymbolContextLineEntry |
+ eSymbolContextVariable ))
{
lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
@@ -2805,7 +2867,30 @@ SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_
if (debug_info)
{
const dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
- if (cu_offset != DW_INVALID_OFFSET)
+ if (cu_offset == DW_INVALID_OFFSET)
+ {
+ // Global variables are not in the compile unit address ranges. The only way to
+ // currently find global variables is to iterate over the .debug_pubnames or the
+ // __apple_names table and find all items in there that point to DW_TAG_variable
+ // DIEs and then find the address that matches.
+ if (resolve_scope & eSymbolContextVariable)
+ {
+ GlobalVariableMap &map = GetGlobalAranges();
+ const GlobalVariableMap::Entry *entry = map.FindEntryThatContains(file_vm_addr);
+ if (entry && entry->data)
+ {
+ Variable *variable = entry->data;
+ SymbolContextScope *scc = variable->GetSymbolContextScope();
+ if (scc)
+ {
+ scc->CalculateSymbolContext(&sc);
+ sc.variable = variable;
+ }
+ return sc.GetResolvedMask();
+ }
+ }
+ }
+ else
{
uint32_t cu_idx = DW_INVALID_INDEX;
DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
@@ -3409,9 +3494,11 @@ SymbolFileDWARF::ResolveFunction (DWARFCompileUnit *cu,
// Parse all blocks if needed
if (inlined_die)
{
- sc.block = sc.function->GetBlock (true).FindBlockByID (MakeUserID(inlined_die->GetOffset()));
- assert (sc.block != NULL);
- if (sc.block->GetStartAddress (addr) == false)
+ Block &function_block = sc.function->GetBlock (true);
+ sc.block = function_block.FindBlockByID (MakeUserID(inlined_die->GetOffset()));
+ if (sc.block == NULL)
+ sc.block = function_block.FindBlockByID (inlined_die->GetOffset());
+ if (sc.block == NULL || sc.block->GetStartAddress (addr) == false)
addr.Clear();
}
else
@@ -6906,7 +6993,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
clang_type = pointee_clang_type.CreateMemberPointerType(class_clang_type);
- byte_size = clang_type.GetByteSize();
+ byte_size = clang_type.GetByteSize(nullptr);
type_sp.reset( new Type (MakeUserID(die->GetOffset()),
this,
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 230e1a5d3984..d8efdbcb38a4 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -29,6 +29,7 @@
#include "lldb/Core/ConstString.h"
#include "lldb/Core/dwarf.h"
#include "lldb/Core/Flags.h"
+#include "lldb/Core/RangeMap.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/SymbolFile.h"
@@ -557,6 +558,11 @@ protected:
uint32_t type_mask,
TypeSet &type_set);
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, lldb_private::Variable *> GlobalVariableMap;
+
+ GlobalVariableMap &
+ GetGlobalAranges();
+
lldb::ModuleWP m_debug_map_module_wp;
SymbolFileDWARFDebugMap * m_debug_map_symfile;
clang::TranslationUnitDecl * m_clang_tu_decl;
@@ -584,6 +590,7 @@ protected:
std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_types_ap;
std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_ap;
std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_ap;
+ std::unique_ptr<GlobalVariableMap> m_global_aranges_ap;
NameToDIE m_function_basename_index; // All concrete functions
NameToDIE m_function_fullname_index; // All concrete functions
NameToDIE m_function_method_index; // All inlined functions
diff --git a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
index 7e484bd8dc73..0eb0f83d5f35 100644
--- a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
+++ b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
@@ -15,6 +15,7 @@
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Error.h"
+#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamString.h"
@@ -146,8 +147,9 @@ UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange&
if (log && log->GetVerbose ())
{
StreamString strm;
- const char *disassemble_format = "${frame.pc}: ";
- inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize (), show_address, show_bytes, NULL, NULL, NULL, disassemble_format);
+ lldb_private::FormatEntity::Entry format;
+ FormatEntity::Parse("${frame.pc}: ", format);
+ inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize (), show_address, show_bytes, NULL, NULL, NULL, &format);
log->PutCString (strm.GetData());
}