summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins')
-rw-r--r--lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp807
-rw-r--r--lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h95
-rw-r--r--lldb/source/Plugins/ABI/MacOSX-arm/Makefile14
-rw-r--r--lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp152
-rw-r--r--lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h246
-rw-r--r--lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp151
-rw-r--r--lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h178
-rw-r--r--lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.cpp193
-rw-r--r--lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.h104
-rw-r--r--lldb/source/Plugins/ArchVolatileRegs/x86/ArchVolatileRegs-x86.cpp150
-rw-r--r--lldb/source/Plugins/ArchVolatileRegs/x86/ArchVolatileRegs-x86.h63
-rw-r--r--lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp7
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp4
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp48
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp1
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp4
-rw-r--r--lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp300
-rw-r--r--lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h36
18 files changed, 1827 insertions, 726 deletions
diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
new file mode 100644
index 00000000000..0f9bab1fcec
--- /dev/null
+++ b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
@@ -0,0 +1,807 @@
+//===-- ABIMacOSX_arm.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ABIMacOSX_arm.h"
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Scalar.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+
+#include "llvm/ADT/Triple.h"
+
+#include "Utility/ARM_DWARF_Registers.h"
+
+#include <vector>
+
+using namespace lldb;
+using namespace lldb_private;
+
+static const char *pluginName = "ABIMacOSX_arm";
+static const char *pluginDesc = "Mac OS X ABI for arm targets";
+static const char *pluginShort = "abi.macosx-arm";
+
+size_t
+ABIMacOSX_arm::GetRedZoneSize () const
+{
+ return 0;
+}
+
+//------------------------------------------------------------------
+// Static Functions
+//------------------------------------------------------------------
+ABISP
+ABIMacOSX_arm::CreateInstance (const ArchSpec &arch)
+{
+ static ABISP g_abi_sp;
+ const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
+ if ((arch_type == llvm::Triple::arm) ||
+ (arch_type == llvm::Triple::thumb))
+ {
+ if (!g_abi_sp)
+ g_abi_sp.reset (new ABIMacOSX_arm);
+ return g_abi_sp;
+ }
+ return ABISP();
+}
+
+bool
+ABIMacOSX_arm::PrepareTrivialCall (Thread &thread,
+ addr_t sp,
+ addr_t functionAddress,
+ addr_t returnAddress,
+ addr_t arg,
+ addr_t *this_arg,
+ addr_t *cmd_arg) const
+{
+// RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+// if (!reg_ctx)
+// return false;
+//#define CHAIN_EBP
+//
+//#ifndef CHAIN_EBP
+// uint32_t ebpID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
+//#endif
+// uint32_t eipID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+// uint32_t espID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+//
+// // Make room for the argument(s) on the stack
+//
+// if (this_arg && cmd_arg)
+// sp -= 12;
+// else if (this_arg)
+// sp -= 8;
+// else
+// sp -= 4;
+//
+// // Align the SP
+//
+// sp &= ~(0xfull); // 16-byte alignment
+//
+// // Write the argument on the stack
+//
+// Error error;
+//
+// if (this_arg && cmd_arg)
+// {
+// uint32_t cmd_argU32 = *cmd_arg & 0xffffffffull;
+// uint32_t this_argU32 = *this_arg & 0xffffffffull;
+// uint32_t argU32 = arg & 0xffffffffull;
+//
+// if (thread.GetProcess().WriteMemory(sp, &this_argU32, sizeof(this_argU32), error) != sizeof(this_argU32))
+// return false;
+// if (thread.GetProcess().WriteMemory(sp + 4, &cmd_argU32, sizeof(cmd_argU32), error) != sizeof(cmd_argU32))
+// return false;
+// if (thread.GetProcess().WriteMemory(sp + 8, &argU32, sizeof(argU32), error) != sizeof(argU32))
+// return false;
+// }
+// else if (this_arg)
+// {
+// uint32_t this_argU32 = *this_arg & 0xffffffffull;
+// uint32_t argU32 = arg & 0xffffffffull;
+//
+// if (thread.GetProcess().WriteMemory(sp, &this_argU32, sizeof(this_argU32), error) != sizeof(this_argU32))
+// return false;
+// if (thread.GetProcess().WriteMemory(sp + 4, &argU32, sizeof(argU32), error) != sizeof(argU32))
+// return false;
+// }
+// else
+// {
+// uint32_t argU32 = arg & 0xffffffffull;
+//
+// if (thread.GetProcess().WriteMemory (sp, &argU32, sizeof(argU32), error) != sizeof(argU32))
+// return false;
+// }
+//
+// // The return address is pushed onto the stack.
+//
+// sp -= 4;
+// uint32_t returnAddressU32 = returnAddress;
+// if (thread.GetProcess().WriteMemory (sp, &returnAddressU32, sizeof(returnAddressU32), error) != sizeof(returnAddressU32))
+// return false;
+//
+// // %esp is set to the actual stack value.
+//
+// if (!reg_ctx->WriteRegisterFromUnsigned(espID, sp))
+// return false;
+//
+//#ifndef CHAIN_EBP
+// // %ebp is set to a fake value, in our case 0x0x00000000
+//
+// if (!reg_ctx->WriteRegisterFromUnsigned(ebpID, 0x00000000))
+// return false;
+//#endif
+//
+// // %eip is set to the address of the called function.
+//
+// if (!reg_ctx->WriteRegisterFromUnsigned(eipID, functionAddress))
+// return false;
+//
+// return true;
+ return false;
+}
+
+bool
+ABIMacOSX_arm::PrepareNormalCall (Thread &thread,
+ addr_t sp,
+ addr_t functionAddress,
+ addr_t returnAddress,
+ ValueList &args) const
+{
+// RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+// if (!reg_ctx)
+// return false;
+// Error error;
+// uint32_t ebpID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
+// uint32_t eipID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+// uint32_t espID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+//
+// // Do the argument layout
+//
+// std::vector <uint32_t> argLayout; // 4-byte chunks, as discussed in the ABI Function Call Guide
+//
+// size_t numArgs = args.GetSize();
+// size_t index;
+//
+// for (index = 0; index < numArgs; ++index)
+// {
+// Value *val = args.GetValueAtIndex(index);
+//
+// if (!val)
+// return false;
+//
+// switch (val->GetValueType())
+// {
+// case Value::eValueTypeScalar:
+// {
+// Scalar &scalar = val->GetScalar();
+// switch (scalar.GetType())
+// {
+// case Scalar::e_void:
+// default:
+// return false;
+// case Scalar::e_sint:
+// case Scalar::e_uint:
+// case Scalar::e_slong:
+// case Scalar::e_ulong:
+// case Scalar::e_slonglong:
+// case Scalar::e_ulonglong:
+// {
+// uint64_t data = scalar.ULongLong();
+//
+// switch (scalar.GetByteSize())
+// {
+// default:
+// return false;
+// case 1:
+// argLayout.push_back((uint32_t)(data & 0xffull));
+// break;
+// case 2:
+// argLayout.push_back((uint32_t)(data & 0xffffull));
+// break;
+// case 4:
+// argLayout.push_back((uint32_t)(data & 0xffffffffull));
+// break;
+// case 8:
+// argLayout.push_back((uint32_t)(data & 0xffffffffull));
+// argLayout.push_back((uint32_t)(data >> 32));
+// break;
+// }
+// }
+// break;
+// case Scalar::e_float:
+// {
+// float data = scalar.Float();
+// uint32_t dataRaw = *((uint32_t*)(&data));
+// argLayout.push_back(dataRaw);
+// }
+// break;
+// case Scalar::e_double:
+// {
+// double data = scalar.Double();
+// uint32_t *dataRaw = ((uint32_t*)(&data));
+// argLayout.push_back(dataRaw[0]);
+// argLayout.push_back(dataRaw[1]);
+// }
+// break;
+// case Scalar::e_long_double:
+// {
+// long double data = scalar.Double();
+// uint32_t *dataRaw = ((uint32_t*)(&data));
+// while ((argLayout.size() * 4) & 0xf)
+// argLayout.push_back(0);
+// argLayout.push_back(dataRaw[0]);
+// argLayout.push_back(dataRaw[1]);
+// argLayout.push_back(dataRaw[2]);
+// argLayout.push_back(dataRaw[3]);
+// }
+// break;
+// }
+// }
+// break;
+// case Value::eValueTypeHostAddress:
+// switch (val->GetContextType())
+// {
+// default:
+// return false;
+// case Value::eContextTypeClangType:
+// {
+// void *val_type = val->GetClangType();
+// uint32_t cstr_length;
+//
+// if (ClangASTContext::IsCStringType (val_type, cstr_length))
+// {
+// const char *cstr = (const char*)val->GetScalar().ULongLong();
+// cstr_length = strlen(cstr);
+//
+// // Push the string onto the stack immediately.
+//
+// sp -= (cstr_length + 1);
+//
+// if (thread.GetProcess().WriteMemory(sp, cstr, cstr_length + 1, error) != (cstr_length + 1))
+// return false;
+//
+// // Put the address of the string into the argument array.
+//
+// argLayout.push_back((uint32_t)(sp & 0xffffffff));
+// }
+// else
+// {
+// return false;
+// }
+// }
+// break;
+// }
+// break;
+// case Value::eValueTypeFileAddress:
+// case Value::eValueTypeLoadAddress:
+// default:
+// return false;
+// }
+// }
+//
+// // Make room for the arguments on the stack
+//
+// sp -= 4 * argLayout.size();
+//
+// // Align the SP
+//
+// sp &= ~(0xfull); // 16-byte alignment
+//
+// // Write the arguments on the stack
+//
+// size_t numChunks = argLayout.size();
+//
+// for (index = 0; index < numChunks; ++index)
+// if (thread.GetProcess().WriteMemory(sp + (index * 4), &argLayout[index], sizeof(uint32_t), error) != sizeof(uint32_t))
+// return false;
+//
+// // The return address is pushed onto the stack.
+//
+// sp -= 4;
+// uint32_t returnAddressU32 = returnAddress;
+// if (thread.GetProcess().WriteMemory (sp, &returnAddressU32, sizeof(returnAddressU32), error) != sizeof(returnAddressU32))
+// return false;
+//
+// // %esp is set to the actual stack value.
+//
+// if (!reg_ctx->WriteRegisterFromUnsigned(espID, sp))
+// return false;
+//
+// // %ebp is set to a fake value, in our case 0x0x00000000
+//
+// if (!reg_ctx->WriteRegisterFromUnsigned(ebpID, 0x00000000))
+// return false;
+//
+// // %eip is set to the address of the called function.
+//
+// if (!reg_ctx->WriteRegisterFromUnsigned(eipID, functionAddress))
+// return false;
+//
+// return true;
+ return false;
+}
+
+static bool
+ReadIntegerArgument (Scalar &scalar,
+ unsigned int bit_width,
+ bool is_signed,
+ Process &process,
+ addr_t &current_stack_argument)
+{
+// if (bit_width > 64)
+// return false; // Scalar can't hold large integer arguments
+//
+// uint64_t arg_contents;
+// uint32_t read_data;
+// Error error;
+//
+// if (bit_width > 32)
+// {
+// if (process.ReadMemory(current_stack_argument, &read_data, sizeof(read_data), error) != sizeof(read_data))
+// return false;
+//
+// arg_contents = read_data;
+//
+// if (process.ReadMemory(current_stack_argument + 4, &read_data, sizeof(read_data), error) != sizeof(read_data))
+// return false;
+//
+// arg_contents |= ((uint64_t)read_data) << 32;
+//
+// current_stack_argument += 8;
+// }
+// else {
+// if (process.ReadMemory(current_stack_argument, &read_data, sizeof(read_data), error) != sizeof(read_data))
+// return false;
+//
+// arg_contents = read_data;
+//
+// current_stack_argument += 4;
+// }
+//
+// if (is_signed)
+// {
+// switch (bit_width)
+// {
+// default:
+// return false;
+// case 8:
+// scalar = (int8_t)(arg_contents & 0xff);
+// break;
+// case 16:
+// scalar = (int16_t)(arg_contents & 0xffff);
+// break;
+// case 32:
+// scalar = (int32_t)(arg_contents & 0xffffffff);
+// break;
+// case 64:
+// scalar = (int64_t)arg_contents;
+// break;
+// }
+// }
+// else
+// {
+// switch (bit_width)
+// {
+// default:
+// return false;
+// case 8:
+// scalar = (uint8_t)(arg_contents & 0xff);
+// break;
+// case 16:
+// scalar = (uint16_t)(arg_contents & 0xffff);
+// break;
+// case 32:
+// scalar = (uint32_t)(arg_contents & 0xffffffff);
+// break;
+// case 64:
+// scalar = (uint64_t)arg_contents;
+// break;
+// }
+// }
+//
+// return true;
+ return false;
+}
+
+bool
+ABIMacOSX_arm::GetArgumentValues (Thread &thread,
+ ValueList &values) const
+{
+// unsigned int num_values = values.GetSize();
+// unsigned int value_index;
+//
+// // Extract the Clang AST context from the PC so that we can figure out type
+// // sizes
+//
+// clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
+//
+// // Get the pointer to the first stack argument so we have a place to start
+// // when reading data
+//
+// RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+//
+// if (!reg_ctx)
+// return false;
+//
+// addr_t sp = reg_ctx->GetSP(0);
+//
+// if (!sp)
+// return false;
+//
+// addr_t current_stack_argument = sp + 4; // jump over return address
+//
+// for (value_index = 0;
+// value_index < num_values;
+// ++value_index)
+// {
+// Value *value = values.GetValueAtIndex(value_index);
+//
+// if (!value)
+// return false;
+//
+// // We currently only support extracting values with Clang QualTypes.
+// // Do we care about others?
+// switch (value->GetContextType())
+// {
+// default:
+// return false;
+// case Value::eContextTypeClangType:
+// {
+// void *value_type = value->GetClangType();
+// bool is_signed;
+//
+// if (ClangASTContext::IsIntegerType (value_type, is_signed))
+// {
+// size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+//
+// ReadIntegerArgument(value->GetScalar(),
+// bit_width,
+// is_signed,
+// thread.GetProcess(),
+// current_stack_argument);
+// }
+// else if (ClangASTContext::IsPointerType (value_type))
+// {
+// ReadIntegerArgument(value->GetScalar(),
+// 32,
+// false,
+// thread.GetProcess(),
+// current_stack_argument);
+// }
+// }
+// break;
+// }
+// }
+//
+// return true;
+ return false;
+}
+
+bool
+ABIMacOSX_arm::GetReturnValue (Thread &thread,
+ Value &value) const
+{
+// switch (value.GetContextType())
+// {
+// default:
+// return false;
+// case Value::eContextTypeClangType:
+// {
+// // Extract the Clang AST context from the PC so that we can figure out type
+// // sizes
+//
+// clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
+//
+// // Get the pointer to the first stack argument so we have a place to start
+// // when reading data
+//
+// RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+//
+// void *value_type = value.GetClangType();
+// bool is_signed;
+//
+// if (ClangASTContext::IsIntegerType (value_type, is_signed))
+// {
+// size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+//
+// unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
+// unsigned edx_id = reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];
+//
+// switch (bit_width)
+// {
+// default:
+// case 128:
+// // Scalar can't hold 128-bit literals, so we don't handle this
+// return false;
+// case 64:
+// uint64_t raw_value;
+// raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff;
+// raw_value |= (thread.GetRegisterContext()->ReadRegisterAsUnsigned(edx_id, 0) & 0xffffffff) << 32;
+// if (is_signed)
+// value.GetScalar() = (int64_t)raw_value;
+// else
+// value.GetScalar() = (uint64_t)raw_value;
+// break;
+// case 32:
+// if (is_signed)
+// value.GetScalar() = (int32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff);
+// else
+// value.GetScalar() = (uint32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff);
+// break;
+// case 16:
+// if (is_signed)
+// value.GetScalar() = (int16_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffff);
+// else
+// value.GetScalar() = (uint16_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffff);
+// break;
+// case 8:
+// if (is_signed)
+// value.GetScalar() = (int8_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xff);
+// else
+// value.GetScalar() = (uint8_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xff);
+// break;
+// }
+// }
+// else if (ClangASTContext::IsPointerType (value_type))
+// {
+// unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
+// uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff;
+// value.GetScalar() = ptr;
+// }
+// else
+// {
+// // not handled yet
+// return false;
+// }
+// }
+// break;
+// }
+//
+// return true;
+ return false;
+}
+
+bool
+ABIMacOSX_arm::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
+{
+ uint32_t reg_kind = unwind_plan.GetRegisterKind();
+ uint32_t lr_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t sp_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t pc_reg_num = LLDB_INVALID_REGNUM;
+
+ switch (reg_kind)
+ {
+ case eRegisterKindDWARF:
+ case eRegisterKindGCC:
+ lr_reg_num = dwarf_lr;
+ sp_reg_num = dwarf_sp;
+ pc_reg_num = dwarf_pc;
+ break;
+
+ case eRegisterKindGeneric:
+ lr_reg_num = LLDB_REGNUM_GENERIC_RA;
+ sp_reg_num = LLDB_REGNUM_GENERIC_SP;
+ pc_reg_num = LLDB_REGNUM_GENERIC_PC;
+ break;
+ }
+
+ if (lr_reg_num == LLDB_INVALID_REGNUM ||
+ sp_reg_num == LLDB_INVALID_REGNUM ||
+ pc_reg_num == LLDB_INVALID_REGNUM)
+ return false;
+
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+
+ UnwindPlan::Row row;
+
+ // Our previous Call Frame Address is the stack pointer
+ row.SetCFARegister (sp_reg_num);
+
+ // Our previous PC is in the LR
+ row.SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
+ unwind_plan.AppendRow (row);
+
+ // All other registers are the same.
+
+ unwind_plan.SetSourceName (pluginName);
+ return true;
+}
+
+bool
+ABIMacOSX_arm::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
+{
+ uint32_t reg_kind = unwind_plan.GetRegisterKind();
+ uint32_t fp_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t sp_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t pc_reg_num = LLDB_INVALID_REGNUM;
+
+ switch (reg_kind)
+ {
+ case eRegisterKindDWARF:
+ case eRegisterKindGCC:
+ fp_reg_num = dwarf_r7; // apple uses r7 for all frames. Normal arm uses r11
+ sp_reg_num = dwarf_sp;
+ pc_reg_num = dwarf_pc;
+ break;
+
+ case eRegisterKindGeneric:
+ fp_reg_num = LLDB_REGNUM_GENERIC_FP;
+ sp_reg_num = LLDB_REGNUM_GENERIC_SP;
+ pc_reg_num = LLDB_REGNUM_GENERIC_PC;
+ break;
+ }
+
+ if (fp_reg_num == LLDB_INVALID_REGNUM ||
+ sp_reg_num == LLDB_INVALID_REGNUM ||
+ pc_reg_num == LLDB_INVALID_REGNUM)
+ return false;
+
+ UnwindPlan::Row row;
+ const int32_t ptr_size = 8;
+
+ unwind_plan.SetRegisterKind (eRegisterKindGeneric);
+ row.SetCFARegister (fp_reg_num);
+ row.SetCFAOffset (2 * ptr_size);
+ row.SetOffset (0);
+
+ row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
+ row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
+
+ unwind_plan.AppendRow (row);
+ unwind_plan.SetSourceName ("arm-apple-darwin default unwind plan");
+ return true;
+}
+
+bool
+ABIMacOSX_arm::RegisterIsVolatile (const RegisterInfo *reg_info)
+{
+ if (reg_info)
+ {
+ // Volatile registers include: ebx, ebp, esi, edi, esp, eip
+ const char *name = reg_info->name;
+ if (name[0] == 'r')
+ {
+ switch (name[1])
+ {
+ case '0': return name[2] == '\0'; // r0
+ case '1':
+ switch (name[2])
+ {
+ case '\0':
+ return true; // r1
+ case '2':
+ case '3':
+ return name[2] == '\0'; // r12 - r13
+ default:
+ break;
+ }
+ break;
+
+ case '2': return name[2] == '\0'; // r2
+ case '3': return name[2] == '\0'; // r3
+ case '9': return name[2] == '\0'; // r9 (apple-darwin only...)
+
+ break;
+ }
+ }
+ else if (name[0] == 'd')
+ {
+ switch (name[1])
+ {
+ case '0':
+ return name[2] == '\0'; // d0
+
+ case '1':
+ switch (name[2])
+ {
+ case '\0':
+ return true; // d1;
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return name[3] == '\0'; // d16 - d19
+ default:
+ break;
+ }
+ break;
+
+ case '2':
+ switch (name[2])
+ {
+ case '\0':
+ return true; // d2;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return name[3] == '\0'; // d20 - d29
+ default:
+ break;
+ }
+ break;
+
+ case '3':
+ switch (name[2])
+ {
+ case '\0':
+ return true; // d3;
+ case '0':
+ case '1':
+ return name[3] == '\0'; // d30 - d31
+ default:
+ break;
+ }
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ return name[2] == '\0'; // d4 - d7
+
+ default:
+ break;
+ }
+ }
+ else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')
+ return true;
+ }
+ return false;
+}
+
+void
+ABIMacOSX_arm::Initialize()
+{
+ PluginManager::RegisterPlugin (pluginName,
+ pluginDesc,
+ CreateInstance);
+}
+
+void
+ABIMacOSX_arm::Terminate()
+{
+ PluginManager::UnregisterPlugin (CreateInstance);
+}
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+const char *
+ABIMacOSX_arm::GetPluginName()
+{
+ return pluginName;
+}
+
+const char *
+ABIMacOSX_arm::GetShortPluginName()
+{
+ return pluginShort;
+}
+
+uint32_t
+ABIMacOSX_arm::GetPluginVersion()
+{
+ return 1;
+}
+
diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
new file mode 100644
index 00000000000..d1d5dc4c4bc
--- /dev/null
+++ b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
@@ -0,0 +1,95 @@
+//===-- ABIMacOSX_arm.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ABIMacOSX_arm_h_
+#define liblldb_ABIMacOSX_arm_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Target/ABI.h"
+
+class ABIMacOSX_arm : public lldb_private::ABI
+{
+public:
+ ~ABIMacOSX_arm() { }
+
+ virtual size_t
+ GetRedZoneSize () const;
+
+ virtual bool
+ PrepareTrivialCall (lldb_private::Thread &thread,
+ lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ lldb::addr_t arg,
+ lldb::addr_t *this_arg,
+ lldb::addr_t *cmd_arg) const;
+
+ virtual bool
+ PrepareNormalCall (lldb_private::Thread &thread,
+ lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ lldb_private::ValueList &args) const;
+
+ virtual bool
+ GetArgumentValues (lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const;
+
+ virtual bool
+ GetReturnValue (lldb_private::Thread &thread,
+ lldb_private::Value &value) const;
+
+ virtual bool
+ CreateFunctionEntryUnwindPlan (lldb_private::UnwindPlan &unwind_plan);
+
+ virtual bool
+ CreateDefaultUnwindPlan (lldb_private::UnwindPlan &unwind_plan);
+
+ virtual bool
+ RegisterIsVolatile (const lldb_private::RegisterInfo *reg_info);
+
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ static lldb::ABISP
+ CreateInstance (const lldb_private::ArchSpec &arch);
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ virtual const char *
+ GetPluginName();
+
+ virtual const char *
+ GetShortPluginName();
+
+ virtual uint32_t
+ GetPluginVersion();
+
+protected:
+private:
+ ABIMacOSX_arm() :
+ lldb_private::ABI()
+ {
+ // Call CreateInstance instead.
+ }
+};
+
+#endif // liblldb_ABIMacOSX_arm_h_
diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/Makefile b/lldb/source/Plugins/ABI/MacOSX-arm/Makefile
new file mode 100644
index 00000000000..18073266d34
--- /dev/null
+++ b/lldb/source/Plugins/ABI/MacOSX-arm/Makefile
@@ -0,0 +1,14 @@
+##===- source/Plugins/ABI/MacOSX-arm/Makefile ------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===--------------------------------------------------------------------===##
+
+LLDB_LEVEL := ../../../..
+LIBRARYNAME := lldbPluginABIMacOSX_arm
+BUILD_ARCHIVE = 1
+
+include $(LLDB_LEVEL)/Makefile
diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
index a65a2efa78f..8c9df142890 100644
--- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
+++ b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
@@ -15,6 +15,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
@@ -40,13 +41,17 @@ ABIMacOSX_i386::GetRedZoneSize () const
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
-lldb_private::ABI *
+ABISP
ABIMacOSX_i386::CreateInstance (const ArchSpec &arch)
{
+ static ABISP g_abi_sp;
if (arch.GetTriple().getArch() == llvm::Triple::x86)
- return new ABIMacOSX_i386;
-
- return NULL;
+ {
+ if (!g_abi_sp)
+ g_abi_sp.reset (new ABIMacOSX_i386);
+ return g_abi_sp;
+ }
+ return ABISP();
}
bool
@@ -560,6 +565,145 @@ ABIMacOSX_i386::GetReturnValue (Thread &thread,
return true;
}
+bool
+ABIMacOSX_i386::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
+{
+ uint32_t reg_kind = unwind_plan.GetRegisterKind();
+ uint32_t sp_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t pc_reg_num = LLDB_INVALID_REGNUM;
+
+ switch (reg_kind)
+ {
+ case eRegisterKindDWARF:
+ sp_reg_num = dwarf_esp;
+ pc_reg_num = dwarf_eip;
+ break;
+
+ case eRegisterKindGCC:
+ sp_reg_num = gcc_esp;
+ pc_reg_num = gcc_eip;
+ break;
+
+ case eRegisterKindGDB:
+ sp_reg_num = gdb_esp;
+ pc_reg_num = gdb_eip;
+ break;
+
+ case eRegisterKindGeneric:
+ sp_reg_num = LLDB_REGNUM_GENERIC_SP;
+ pc_reg_num = LLDB_REGNUM_GENERIC_PC;
+ break;
+ }
+
+ if (sp_reg_num == LLDB_INVALID_REGNUM ||
+ pc_reg_num == LLDB_INVALID_REGNUM)
+ return false;
+
+ UnwindPlan::Row row;
+ row.SetCFARegister (sp_reg_num);
+ row.SetCFAOffset (4);
+ row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);
+ unwind_plan.AppendRow (row);
+ unwind_plan.SetSourceName (pluginName);
+ return true;
+}
+
+bool
+ABIMacOSX_i386::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
+{
+ uint32_t reg_kind = unwind_plan.GetRegisterKind();
+ uint32_t fp_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t sp_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t pc_reg_num = LLDB_INVALID_REGNUM;
+
+ switch (reg_kind)
+ {
+ case eRegisterKindDWARF:
+ fp_reg_num = dwarf_ebp;
+ sp_reg_num = dwarf_esp;
+ pc_reg_num = dwarf_eip;
+ break;
+
+ case eRegisterKindGCC:
+ fp_reg_num = gcc_ebp;
+ sp_reg_num = gcc_esp;
+ pc_reg_num = gcc_eip;
+ break;
+
+ case eRegisterKindGDB:
+ fp_reg_num = gdb_ebp;
+ sp_reg_num = gdb_esp;
+ pc_reg_num = gdb_eip;
+ break;
+
+ case eRegisterKindGeneric:
+ fp_reg_num = LLDB_REGNUM_GENERIC_FP;
+ sp_reg_num = LLDB_REGNUM_GENERIC_SP;
+ pc_reg_num = LLDB_REGNUM_GENERIC_PC;
+ break;
+ }
+
+ if (fp_reg_num == LLDB_INVALID_REGNUM ||
+ sp_reg_num == LLDB_INVALID_REGNUM ||
+ pc_reg_num == LLDB_INVALID_REGNUM)
+ return false;
+
+ UnwindPlan::Row row;
+ const int32_t ptr_size = 4;
+
+ unwind_plan.SetRegisterKind (eRegisterKindGeneric);
+ row.SetCFARegister (fp_reg_num);
+ row.SetCFAOffset (2 * ptr_size);
+ row.SetOffset (0);
+
+ row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
+ row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
+ row.SetRegisterLocationToAtCFAPlusOffset(sp_reg_num, ptr_size * 0, true);
+
+ unwind_plan.AppendRow (row);
+ unwind_plan.SetSourceName ("i386 default unwind plan");
+ return true;
+}
+
+bool
+ABIMacOSX_i386::RegisterIsVolatile (const RegisterInfo *reg_info)
+{
+ return RegisterIsCalleeSaved (reg_info);
+}
+
+bool
+ABIMacOSX_i386::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
+{
+ if (reg_info)
+ {
+ // Volatile registers include: ebx, ebp, esi, edi, esp, eip
+ const char *name = reg_info->name;
+ if (name[0] == 'e')
+ {
+ switch (name[1])
+ {
+ case 'b':
+ if (name[2] == 'x' || name[2] == 'p')
+ return name[0] == '\0';
+ break;
+ case 'd':
+ if (name[2] == 'i')
+ return name[0] == '\0';
+ break;
+ case 'i':
+ if (name[2] == 'p')
+ return name[0] == '\0';
+ break;
+ case 's':
+ if (name[2] == 'i' || name[2] == 'p')
+ return name[0] == '\0';
+ break;
+ }
+ }
+ }
+ return false;
+}
+
void
ABIMacOSX_i386::Initialize()
{
diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
index 20dbc4af5ec..e50330fda76 100644
--- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
+++ b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
@@ -17,71 +17,195 @@
#include "lldb/lldb-private.h"
#include "lldb/Target/ABI.h"
#include "lldb/Core/Value.h"
-
-namespace lldb_private {
- class ABIMacOSX_i386 :
+class ABIMacOSX_i386 :
public lldb_private::ABI
+{
+public:
+
+ enum
{
- public:
- ~ABIMacOSX_i386() { }
-
- virtual size_t
- GetRedZoneSize () const;
-
- virtual bool
- PrepareTrivialCall (Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t functionAddress,
- lldb::addr_t returnAddress,
- lldb::addr_t arg,
- lldb::addr_t *this_arg,
- lldb::addr_t *cmd_arg) const;
-
- virtual bool
- PrepareNormalCall (Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t functionAddress,
- lldb::addr_t returnAddress,
- ValueList &args) const;
-
- virtual bool
- GetArgumentValues (Thread &thread,
- ValueList &values) const;
-
- virtual bool
- GetReturnValue (Thread &thread,
- Value &value) const;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ABI *
- CreateInstance (const ArchSpec &arch);
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- virtual const char *
- GetPluginName();
-
- virtual const char *
- GetShortPluginName();
-
- virtual uint32_t
- GetPluginVersion();
-
- protected:
- private:
- ABIMacOSX_i386() : lldb_private::ABI() { } // Call CreateInstance instead.
+ gcc_eax = 0,
+ gcc_ecx,
+ gcc_edx,
+ gcc_ebx,
+ gcc_ebp,
+ gcc_esp,
+ gcc_esi,
+ gcc_edi,
+ gcc_eip,
+ gcc_eflags
};
-} // namespace lldb_private
+ enum
+ {
+ dwarf_eax = 0,
+ dwarf_ecx,
+ dwarf_edx,
+ dwarf_ebx,
+ dwarf_esp,
+ dwarf_ebp,
+ dwarf_esi,
+ dwarf_edi,
+ dwarf_eip,
+ dwarf_eflags,
+ dwarf_stmm0 = 11,
+ dwarf_stmm1,
+ dwarf_stmm2,
+ dwarf_stmm3,
+ dwarf_stmm4,
+ dwarf_stmm5,
+ dwarf_stmm6,
+ dwarf_stmm7,
+ dwarf_xmm0 = 21,
+ dwarf_xmm1,
+ dwarf_xmm2,
+ dwarf_xmm3,
+ dwarf_xmm4,
+ dwarf_xmm5,
+ dwarf_xmm6,
+ dwarf_xmm7,
+ dwarf_ymm0 = dwarf_xmm0,
+ dwarf_ymm1 = dwarf_xmm1,
+ dwarf_ymm2 = dwarf_xmm2,
+ dwarf_ymm3 = dwarf_xmm3,
+ dwarf_ymm4 = dwarf_xmm4,
+ dwarf_ymm5 = dwarf_xmm5,
+ dwarf_ymm6 = dwarf_xmm6,
+ dwarf_ymm7 = dwarf_xmm7,
+ };
+
+ enum
+ {
+ gdb_eax = 0,
+ gdb_ecx = 1,
+ gdb_edx = 2,
+ gdb_ebx = 3,
+ gdb_esp = 4,
+ gdb_ebp = 5,
+ gdb_esi = 6,
+ gdb_edi = 7,
+ gdb_eip = 8,
+ gdb_eflags = 9,
+ gdb_cs = 10,
+ gdb_ss = 11,
+ gdb_ds = 12,
+ gdb_es = 13,
+ gdb_fs = 14,
+ gdb_gs = 15,
+ gdb_stmm0 = 16,
+ gdb_stmm1 = 17,
+ gdb_stmm2 = 18,
+ gdb_stmm3 = 19,
+ gdb_stmm4 = 20,
+ gdb_stmm5 = 21,
+ gdb_stmm6 = 22,
+ gdb_stmm7 = 23,
+ gdb_fctrl = 24, gdb_fcw = gdb_fctrl,
+ gdb_fstat = 25, gdb_fsw = gdb_fstat,
+ gdb_ftag = 26, gdb_ftw = gdb_ftag,
+ gdb_fiseg = 27, gdb_fpu_cs = gdb_fiseg,
+ gdb_fioff = 28, gdb_ip = gdb_fioff,
+ gdb_foseg = 29, gdb_fpu_ds = gdb_foseg,
+ gdb_fooff = 30, gdb_dp = gdb_fooff,
+ gdb_fop = 31,
+ gdb_xmm0 = 32,
+ gdb_xmm1 = 33,
+ gdb_xmm2 = 34,
+ gdb_xmm3 = 35,
+ gdb_xmm4 = 36,
+ gdb_xmm5 = 37,
+ gdb_xmm6 = 38,
+ gdb_xmm7 = 39,
+ gdb_mxcsr = 40,
+ gdb_mm0 = 41,
+ gdb_mm1 = 42,
+ gdb_mm2 = 43,
+ gdb_mm3 = 44,
+ gdb_mm4 = 45,
+ gdb_mm5 = 46,
+ gdb_mm6 = 47,
+ gdb_mm7 = 48,
+ gdb_ymm0 = gdb_xmm0,
+ gdb_ymm1 = gdb_xmm1,
+ gdb_ymm2 = gdb_xmm2,
+ gdb_ymm3 = gdb_xmm3,
+ gdb_ymm4 = gdb_xmm4,
+ gdb_ymm5 = gdb_xmm5,
+ gdb_ymm6 = gdb_xmm6,
+ gdb_ymm7 = gdb_xmm7
+ };
+
+ ~ABIMacOSX_i386() { }
+
+ virtual size_t
+ GetRedZoneSize () const;
+
+ virtual bool
+ PrepareTrivialCall (lldb_private::Thread &thread,
+ lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ lldb::addr_t arg,
+ lldb::addr_t *this_arg,
+ lldb::addr_t *cmd_arg) const;
+
+ virtual bool
+ PrepareNormalCall (lldb_private::Thread &thread,
+ lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ lldb_private::ValueList &args) const;
+
+ virtual bool
+ GetArgumentValues (lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const;
+
+ virtual bool
+ GetReturnValue (lldb_private::Thread &thread,
+ lldb_private::Value &value) const;
+
+ virtual bool
+ CreateFunctionEntryUnwindPlan (lldb_private::UnwindPlan &unwind_plan);
+
+ virtual bool
+ CreateDefaultUnwindPlan (lldb_private::UnwindPlan &unwind_plan);
+
+ virtual bool
+ RegisterIsVolatile (const lldb_private::RegisterInfo *reg_info);
+
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ static lldb::ABISP
+ CreateInstance (const lldb_private::ArchSpec &arch);
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ virtual const char *
+ GetPluginName();
+
+ virtual const char *
+ GetShortPluginName();
+
+ virtual uint32_t
+ GetPluginVersion();
+
+protected:
+ bool
+ RegisterIsCalleeSaved (const lldb_private::RegisterInfo *reg_info);
+
+private:
+ ABIMacOSX_i386() : lldb_private::ABI() { } // Call CreateInstance instead.
+};
+
#endif // liblldb_ABI_h_
diff --git a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
index 5c2cd7403ec..3ee0562b7e8 100644
--- a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
+++ b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
@@ -17,6 +17,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Value.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -32,6 +33,8 @@ static const char *pluginName = "ABISysV_x86_64";
static const char *pluginDesc = "System V ABI for x86_64 targets";
static const char *pluginShort = "abi.sysv-x86_64";
+
+
size_t
ABISysV_x86_64::GetRedZoneSize () const
{
@@ -41,12 +44,17 @@ ABISysV_x86_64::GetRedZoneSize () const
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
-lldb_private::ABI *
+ABISP
ABISysV_x86_64::CreateInstance (const ArchSpec &arch)
{
+ static ABISP g_abi_sp;
if (arch.GetTriple().getArch() == llvm::Triple::x86_64)
- return new ABISysV_x86_64;
- return NULL;
+ {
+ if (!g_abi_sp)
+ g_abi_sp.reset (new ABISysV_x86_64);
+ return g_abi_sp;
+ }
+ return ABISP();
}
bool
@@ -446,6 +454,143 @@ ABISysV_x86_64::GetReturnValue (Thread &thread,
return true;
}
+bool
+ABISysV_x86_64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
+{
+ uint32_t reg_kind = unwind_plan.GetRegisterKind();
+ uint32_t sp_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t pc_reg_num = LLDB_INVALID_REGNUM;
+
+ switch (reg_kind)
+ {
+ case eRegisterKindDWARF:
+ case eRegisterKindGCC:
+ sp_reg_num = gcc_dwarf_rsp;
+ pc_reg_num = gcc_dwarf_rip;
+ break;
+
+ case eRegisterKindGDB:
+ sp_reg_num = gdb_rsp;
+ pc_reg_num = gdb_rip;
+ break;
+
+ case eRegisterKindGeneric:
+ sp_reg_num = LLDB_REGNUM_GENERIC_SP;
+ pc_reg_num = LLDB_REGNUM_GENERIC_PC;
+ break;
+ }
+
+ if (sp_reg_num == LLDB_INVALID_REGNUM ||
+ pc_reg_num == LLDB_INVALID_REGNUM)
+ return false;
+
+ UnwindPlan::Row row;
+ row.SetCFARegister (sp_reg_num);
+ row.SetCFAOffset (8);
+ row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
+ unwind_plan.AppendRow (row);
+ unwind_plan.SetSourceName (pluginName);
+ return true;
+}
+
+bool
+ABISysV_x86_64::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
+{
+ uint32_t reg_kind = unwind_plan.GetRegisterKind();
+ uint32_t fp_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t sp_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t pc_reg_num = LLDB_INVALID_REGNUM;
+
+ switch (reg_kind)
+ {
+ case eRegisterKindDWARF:
+ case eRegisterKindGCC:
+ fp_reg_num = gcc_dwarf_rbp;
+ sp_reg_num = gcc_dwarf_rsp;
+ pc_reg_num = gcc_dwarf_rip;
+ break;
+
+ case eRegisterKindGDB:
+ fp_reg_num = gdb_rbp;
+ sp_reg_num = gdb_rsp;
+ pc_reg_num = gdb_rip;
+ break;
+
+ case eRegisterKindGeneric:
+ fp_reg_num = LLDB_REGNUM_GENERIC_FP;
+ sp_reg_num = LLDB_REGNUM_GENERIC_SP;
+ pc_reg_num = LLDB_REGNUM_GENERIC_PC;
+ break;
+ }
+
+ if (fp_reg_num == LLDB_INVALID_REGNUM ||
+ sp_reg_num == LLDB_INVALID_REGNUM ||
+ pc_reg_num == LLDB_INVALID_REGNUM)
+ return false;
+
+ UnwindPlan::Row row;
+
+ const int32_t ptr_size = 8;
+ row.SetCFARegister (LLDB_REGNUM_GENERIC_FP);
+ row.SetCFAOffset (2 * ptr_size);
+ row.SetOffset (0);
+
+ row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
+ row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
+ row.SetRegisterLocationToAtCFAPlusOffset(sp_reg_num, ptr_size * 0, true);
+
+ unwind_plan.AppendRow (row);
+ unwind_plan.SetSourceName ("x86_64 default unwind plan");
+ return true;
+}
+
+bool
+ABISysV_x86_64::RegisterIsVolatile (const RegisterInfo *reg_info)
+{
+ return !RegisterIsCalleeSaved (reg_info);
+}
+
+bool
+ABISysV_x86_64::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
+{
+ if (reg_info)
+ {
+ // Volatile registers include: rbx, rbp, rsp, r12, r13, r14, r15, rip
+ const char *name = reg_info->name;
+ if (name[0] == 'r')
+ {
+ switch (name[1])
+ {
+ case '1': // r12, r13, r14, r15
+ if (name[2] >= '2' && name[2] <= '5')
+ return name[3] == '\0';
+ break;
+
+ case 'b': // rbp, rbx
+ if (name[2] == 'p' || name[2] == 'x')
+ return name[3] == '\0';
+ break;
+
+ case 'i': // rip
+ if (name[2] == 'p')
+ return name[3] == '\0';
+ break;
+
+ case 's': // rsp
+ if (name[2] == 'p')
+ return name[3] == '\0';
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ return false;
+}
+
+
+
void
ABISysV_x86_64::Initialize()
{
diff --git a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
index beb617891c2..e1ac132da8d 100644
--- a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
+++ b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
@@ -17,19 +17,158 @@
#include "lldb/lldb-private.h"
#include "lldb/Target/ABI.h"
-namespace lldb_private {
-
class ABISysV_x86_64 :
public lldb_private::ABI
{
public:
- ~ABISysV_x86_64() { }
+
+ enum gcc_dwarf_regnums
+ {
+ gcc_dwarf_rax = 0,
+ gcc_dwarf_rdx,
+ gcc_dwarf_rcx,
+ gcc_dwarf_rbx,
+ gcc_dwarf_rsi,
+ gcc_dwarf_rdi,
+ gcc_dwarf_rbp,
+ gcc_dwarf_rsp,
+ gcc_dwarf_r8,
+ gcc_dwarf_r9,
+ gcc_dwarf_r10,
+ gcc_dwarf_r11,
+ gcc_dwarf_r12,
+ gcc_dwarf_r13,
+ gcc_dwarf_r14,
+ gcc_dwarf_r15,
+ gcc_dwarf_rip,
+ gcc_dwarf_xmm0,
+ gcc_dwarf_xmm1,
+ gcc_dwarf_xmm2,
+ gcc_dwarf_xmm3,
+ gcc_dwarf_xmm4,
+ gcc_dwarf_xmm5,
+ gcc_dwarf_xmm6,
+ gcc_dwarf_xmm7,
+ gcc_dwarf_xmm8,
+ gcc_dwarf_xmm9,
+ gcc_dwarf_xmm10,
+ gcc_dwarf_xmm11,
+ gcc_dwarf_xmm12,
+ gcc_dwarf_xmm13,
+ gcc_dwarf_xmm14,
+ gcc_dwarf_xmm15,
+ gcc_dwarf_stmm0,
+ gcc_dwarf_stmm1,
+ gcc_dwarf_stmm2,
+ gcc_dwarf_stmm3,
+ gcc_dwarf_stmm4,
+ gcc_dwarf_stmm5,
+ gcc_dwarf_stmm6,
+ gcc_dwarf_stmm7,
+ gcc_dwarf_ymm0 = gcc_dwarf_xmm0,
+ gcc_dwarf_ymm1 = gcc_dwarf_xmm1,
+ gcc_dwarf_ymm2 = gcc_dwarf_xmm2,
+ gcc_dwarf_ymm3 = gcc_dwarf_xmm3,
+ gcc_dwarf_ymm4 = gcc_dwarf_xmm4,
+ gcc_dwarf_ymm5 = gcc_dwarf_xmm5,
+ gcc_dwarf_ymm6 = gcc_dwarf_xmm6,
+ gcc_dwarf_ymm7 = gcc_dwarf_xmm7,
+ gcc_dwarf_ymm8 = gcc_dwarf_xmm8,
+ gcc_dwarf_ymm9 = gcc_dwarf_xmm9,
+ gcc_dwarf_ymm10 = gcc_dwarf_xmm10,
+ gcc_dwarf_ymm11 = gcc_dwarf_xmm11,
+ gcc_dwarf_ymm12 = gcc_dwarf_xmm12,
+ gcc_dwarf_ymm13 = gcc_dwarf_xmm13,
+ gcc_dwarf_ymm14 = gcc_dwarf_xmm14,
+ gcc_dwarf_ymm15 = gcc_dwarf_xmm15
+ };
+
+ enum gdb_regnums
+ {
+ gdb_rax = 0,
+ gdb_rbx = 1,
+ gdb_rcx = 2,
+ gdb_rdx = 3,
+ gdb_rsi = 4,
+ gdb_rdi = 5,
+ gdb_rbp = 6,
+ gdb_rsp = 7,
+ gdb_r8 = 8,
+ gdb_r9 = 9,
+ gdb_r10 = 10,
+ gdb_r11 = 11,
+ gdb_r12 = 12,
+ gdb_r13 = 13,
+ gdb_r14 = 14,
+ gdb_r15 = 15,
+ gdb_rip = 16,
+ gdb_rflags = 17,
+ gdb_cs = 18,
+ gdb_ss = 19,
+ gdb_ds = 20,
+ gdb_es = 21,
+ gdb_fs = 22,
+ gdb_gs = 23,
+ gdb_stmm0 = 24,
+ gdb_stmm1 = 25,
+ gdb_stmm2 = 26,
+ gdb_stmm3 = 27,
+ gdb_stmm4 = 28,
+ gdb_stmm5 = 29,
+ gdb_stmm6 = 30,
+ gdb_stmm7 = 31,
+ gdb_fctrl = 32, gdb_fcw = gdb_fctrl,
+ gdb_fstat = 33, gdb_fsw = gdb_fstat,
+ gdb_ftag = 34, gdb_ftw = gdb_ftag,
+ gdb_fiseg = 35, gdb_fpu_cs = gdb_fiseg,
+ gdb_fioff = 36, gdb_ip = gdb_fioff,
+ gdb_foseg = 37, gdb_fpu_ds = gdb_foseg,
+ gdb_fooff = 38, gdb_dp = gdb_fooff,
+ gdb_fop = 39,
+ gdb_xmm0 = 40,
+ gdb_xmm1 = 41,
+ gdb_xmm2 = 42,
+ gdb_xmm3 = 43,
+ gdb_xmm4 = 44,
+ gdb_xmm5 = 45,
+ gdb_xmm6 = 46,
+ gdb_xmm7 = 47,
+ gdb_xmm8 = 48,
+ gdb_xmm9 = 49,
+ gdb_xmm10 = 50,
+ gdb_xmm11 = 51,
+ gdb_xmm12 = 52,
+ gdb_xmm13 = 53,
+ gdb_xmm14 = 54,
+ gdb_xmm15 = 55,
+ gdb_mxcsr = 56,
+ gdb_ymm0 = gdb_xmm0,
+ gdb_ymm1 = gdb_xmm1,
+ gdb_ymm2 = gdb_xmm2,
+ gdb_ymm3 = gdb_xmm3,
+ gdb_ymm4 = gdb_xmm4,
+ gdb_ymm5 = gdb_xmm5,
+ gdb_ymm6 = gdb_xmm6,
+ gdb_ymm7 = gdb_xmm7,
+ gdb_ymm8 = gdb_xmm8,
+ gdb_ymm9 = gdb_xmm9,
+ gdb_ymm10 = gdb_xmm10,
+ gdb_ymm11 = gdb_xmm11,
+ gdb_ymm12 = gdb_xmm12,
+ gdb_ymm13 = gdb_xmm13,
+ gdb_ymm14 = gdb_xmm14,
+ gdb_ymm15 = gdb_xmm15
+ };
+
+ ~ABISysV_x86_64()
+ {
+ }
virtual size_t
GetRedZoneSize () const;
virtual bool
- PrepareTrivialCall (Thread &thread,
+ PrepareTrivialCall (lldb_private::Thread &thread,
lldb::addr_t sp,
lldb::addr_t functionAddress,
lldb::addr_t returnAddress,
@@ -38,19 +177,28 @@ public:
lldb::addr_t *cmd_arg) const;
virtual bool
- PrepareNormalCall (Thread &thread,
+ PrepareNormalCall (lldb_private::Thread &thread,
lldb::addr_t sp,
lldb::addr_t functionAddress,
lldb::addr_t returnAddress,
- ValueList &args) const;
+ lldb_private::ValueList &args) const;
+
+ virtual bool
+ GetArgumentValues (lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const;
virtual bool
- GetArgumentValues (Thread &thread,
- ValueList &values) const;
+ GetReturnValue (lldb_private::Thread &thread,
+ lldb_private::Value &value) const;
virtual bool
- GetReturnValue (Thread &thread,
- Value &value) const;
+ CreateFunctionEntryUnwindPlan (lldb_private::UnwindPlan &unwind_plan);
+
+ virtual bool
+ CreateDefaultUnwindPlan (lldb_private::UnwindPlan &unwind_plan);
+
+ virtual bool
+ RegisterIsVolatile (const lldb_private::RegisterInfo *reg_info);
//------------------------------------------------------------------
// Static Functions
@@ -61,8 +209,8 @@ public:
static void
Terminate();
- static lldb_private::ABI *
- CreateInstance (const ArchSpec &arch);
+ static lldb::ABISP
+ CreateInstance (const lldb_private::ArchSpec &arch);
//------------------------------------------------------------------
// PluginInterface protocol
@@ -77,10 +225,12 @@ public:
GetPluginVersion();
protected:
+
+ bool
+ RegisterIsCalleeSaved (const lldb_private::RegisterInfo *reg_info);
+
private:
ABISysV_x86_64() : lldb_private::ABI() { } // Call CreateInstance instead.
};
-} // namespace lldb_private
-
#endif // liblldb_ABI_h_
diff --git a/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.cpp b/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.cpp
deleted file mode 100644
index 4be89faaca5..00000000000
--- a/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-//===-- ArchDefaultUnwindPlan-x86.cpp --------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ArchDefaultUnwindPlan-x86.h"
-#include "lldb/Core/ArchSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Target/ArchDefaultUnwindPlan.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-ArchDefaultUnwindPlan *
-ArchDefaultUnwindPlan_x86_64::CreateInstance (const ArchSpec &arch)
-{
- if (arch.GetMachine () == llvm::Triple::x86_64)
- return new ArchDefaultUnwindPlan_x86_64 ();
- return NULL;
-}
-
-ArchDefaultUnwindPlan_x86_64::ArchDefaultUnwindPlan_x86_64() :
- ArchDefaultUnwindPlan(),
- m_unwind_plan_sp (new UnwindPlan)
-{
- UnwindPlan::Row row;
- UnwindPlan::Row::RegisterLocation regloc;
-
- m_unwind_plan_sp->SetRegisterKind (eRegisterKindGeneric);
- row.SetCFARegister (LLDB_REGNUM_GENERIC_FP);
- row.SetCFAOffset (2 * 8);
- row.SetOffset (0);
-
- regloc.SetAtCFAPlusOffset (2 * -8);
- row.SetRegisterInfo (LLDB_REGNUM_GENERIC_FP, regloc);
- regloc.SetAtCFAPlusOffset (1 * -8);
- row.SetRegisterInfo (LLDB_REGNUM_GENERIC_PC, regloc);
- regloc.SetIsCFAPlusOffset (0);
- row.SetRegisterInfo (LLDB_REGNUM_GENERIC_SP, regloc);
-
- m_unwind_plan_sp->AppendRow (row);
- m_unwind_plan_sp->SetSourceName ("x86_64 architectural default");
-}
-
-//------------------------------------------------------------------
-// PluginInterface protocol in UnwindAssemblyParser_x86
-//------------------------------------------------------------------
-
-const char *
-ArchDefaultUnwindPlan_x86_64::GetPluginName()
-{
- return "ArchDefaultUnwindPlan_x86_64";
-}
-
-const char *
-ArchDefaultUnwindPlan_x86_64::GetShortPluginName()
-{
- return "lldb.arch-default-unwind-plan.x86-64";
-}
-
-
-uint32_t
-ArchDefaultUnwindPlan_x86_64::GetPluginVersion()
-{
- return 1;
-}
-void
-ArchDefaultUnwindPlan_x86_64::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
-}
-
-void
-ArchDefaultUnwindPlan_x86_64::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
-}
-
-
-const char *
-ArchDefaultUnwindPlan_x86_64::GetPluginNameStatic()
-{
- return "ArchDefaultUnwindPlan_x86_64";
-}
-
-const char *
-ArchDefaultUnwindPlan_x86_64::GetPluginDescriptionStatic()
-{
- return "x86_64 architecture default unwind plan assembly plugin.";
-}
-
-UnwindPlanSP
-ArchDefaultUnwindPlan_x86_64::GetArchDefaultUnwindPlan (Thread& thread,
- const Address &current_pc)
-{
- return m_unwind_plan_sp;
-}
-
-
-
-ArchDefaultUnwindPlan *
-ArchDefaultUnwindPlan_i386::CreateInstance (const ArchSpec &arch)
-{
- if (arch.GetMachine () == llvm::Triple::x86)
- return new ArchDefaultUnwindPlan_i386 ();
- return NULL;
-}
-
-ArchDefaultUnwindPlan_i386::ArchDefaultUnwindPlan_i386() :
- ArchDefaultUnwindPlan(),
- m_unwind_plan_sp (new UnwindPlan)
-{
- UnwindPlan::Row row;
- UnwindPlan::Row::RegisterLocation regloc;
-
- m_unwind_plan_sp->SetRegisterKind (eRegisterKindGeneric);
- row.SetCFARegister (LLDB_REGNUM_GENERIC_FP);
- row.SetCFAOffset (2 * 4);
- row.SetOffset (0);
-
- regloc.SetAtCFAPlusOffset (2 * -4);
- row.SetRegisterInfo (LLDB_REGNUM_GENERIC_FP, regloc);
- regloc.SetAtCFAPlusOffset (1 * -4);
- row.SetRegisterInfo (LLDB_REGNUM_GENERIC_PC, regloc);
- regloc.SetIsCFAPlusOffset (0);
- row.SetRegisterInfo (LLDB_REGNUM_GENERIC_SP, regloc);
-
- m_unwind_plan_sp->AppendRow (row);
- m_unwind_plan_sp->SetSourceName ("i386 architectural default");
-}
-
-//------------------------------------------------------------------
-// PluginInterface protocol in UnwindAssemblyParser_x86
-//------------------------------------------------------------------
-
-const char *
-ArchDefaultUnwindPlan_i386::GetPluginName()
-{
- return "ArchDefaultUnwindPlan_i386";
-}
-
-const char *
-ArchDefaultUnwindPlan_i386::GetShortPluginName()
-{
- return "archdefaultunwindplan.x86";
-}
-
-
-uint32_t
-ArchDefaultUnwindPlan_i386::GetPluginVersion()
-{
- return 1;
-}
-
-void
-ArchDefaultUnwindPlan_i386::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
-}
-
-void
-ArchDefaultUnwindPlan_i386::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
-}
-
-
-const char *
-ArchDefaultUnwindPlan_i386::GetPluginNameStatic()
-{
- return "ArchDefaultUnwindPlan_i386";
-}
-
-const char *
-ArchDefaultUnwindPlan_i386::GetPluginDescriptionStatic()
-{
- return "i386 architecture default unwind plan assembly plugin.";
-}
-
-UnwindPlanSP
-ArchDefaultUnwindPlan_i386::GetArchDefaultUnwindPlan (Thread& thread, const Address &current_pc)
-{
- return m_unwind_plan_sp;
-}
-
diff --git a/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.h b/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.h
deleted file mode 100644
index ce5abb1c0d8..00000000000
--- a/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.h
+++ /dev/null
@@ -1,104 +0,0 @@
-//===-- ArchDefaultUnwindPlan-x86.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_ArchDefaultUnwindPlan_x86_h_
-#define liblldb_ArchDefaultUnwindPlan_x86_h_
-
-#include "lldb/lldb-private.h"
-#include "lldb/Target/ArchDefaultUnwindPlan.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Symbol/UnwindPlan.h"
-
-class ArchDefaultUnwindPlan_x86_64 : public lldb_private::ArchDefaultUnwindPlan
-{
-public:
-
- ~ArchDefaultUnwindPlan_x86_64 () { }
-
- virtual lldb::UnwindPlanSP
- GetArchDefaultUnwindPlan (lldb_private::Thread& thread,
- const lldb_private::Address &current_pc);
-
- static lldb_private::ArchDefaultUnwindPlan *
- CreateInstance (const lldb_private::ArchSpec &arch);
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static const char *
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- virtual const char *
- GetPluginName();
-
- virtual const char *
- GetShortPluginName();
-
- virtual uint32_t
- GetPluginVersion();
-
-private:
- ArchDefaultUnwindPlan_x86_64(); // Call CreateInstance instead.
-
- lldb::UnwindPlanSP m_unwind_plan_sp;
-};
-
-class ArchDefaultUnwindPlan_i386 : public lldb_private::ArchDefaultUnwindPlan
-{
-public:
-
- ~ArchDefaultUnwindPlan_i386 () { }
-
- virtual lldb::UnwindPlanSP
- GetArchDefaultUnwindPlan (lldb_private::Thread& thread,
- const lldb_private::Address& current_pc);
-
- static lldb_private::ArchDefaultUnwindPlan *
- CreateInstance (const lldb_private::ArchSpec &arch);
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static const char *
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- virtual const char *
- GetPluginName();
-
- virtual const char *
- GetShortPluginName();
-
- virtual uint32_t
- GetPluginVersion();
-
-private:
- ArchDefaultUnwindPlan_i386(); // Call CreateInstance instead.
-
- lldb::UnwindPlanSP m_unwind_plan_sp;
-};
-
-#endif // liblldb_UnwindAssembly_x86_h_
diff --git a/lldb/source/Plugins/ArchVolatileRegs/x86/ArchVolatileRegs-x86.cpp b/lldb/source/Plugins/ArchVolatileRegs/x86/ArchVolatileRegs-x86.cpp
deleted file mode 100644
index 915dbf9bb7e..00000000000
--- a/lldb/source/Plugins/ArchVolatileRegs/x86/ArchVolatileRegs-x86.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-//===-- ArchVolatileRegs-x86.cpp --------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ArchVolatileRegs-x86.h"
-
-#include <set>
-
-#include "llvm/Support/MachO.h"
-
-#include "lldb/Core/ArchSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Target/ArchVolatileRegs.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Target/RegisterContext.h"
-
-
-using namespace lldb;
-using namespace lldb_private;
-
-bool
-ArchVolatileRegs_x86::RegisterIsVolatile (Thread& thread, uint32_t regnum)
-{
- initialize_regset (thread);
- if (m_non_volatile_regs.find (regnum) == m_non_volatile_regs.end())
- return true;
- else
- return false;
-}
-
-lldb_private::ArchVolatileRegs *
-ArchVolatileRegs_x86::CreateInstance (const lldb_private::ArchSpec &arch)
-{
- llvm::Triple::ArchType cpu = arch.GetMachine ();
- if (cpu == llvm::Triple::x86 || cpu == llvm::Triple::x86_64)
- return new ArchVolatileRegs_x86 (cpu);
- return NULL;
-}
-
-ArchVolatileRegs_x86::ArchVolatileRegs_x86(llvm::Triple::ArchType cpu) :
- lldb_private::ArchVolatileRegs(),
- m_cpu(cpu),
- m_non_volatile_regs()
-{
-}
-
-void
-ArchVolatileRegs_x86::initialize_regset(Thread& thread)
-{
- if (m_non_volatile_regs.size() > 0)
- return;
-
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- const RegisterInfo *ri;
-
- const char *x86_64_regnames[] = { "rbx",
- "rsp",
- "rbp",
- "r12",
- "r13",
- "r14",
- "r15",
- "rip" };
-
- const char *i386_regnames[] = { "ebx",
- "ebp",
- "esi",
- "edi",
- "esp",
- "eip" };
-
-
- const char **names;
- int namecount;
- if (m_cpu == llvm::Triple::x86_64)
- {
- names = x86_64_regnames;
- namecount = sizeof (x86_64_regnames) / sizeof (char *);
- }
- else
- {
- assert (m_cpu == llvm::Triple::x86);
- names = i386_regnames;
- namecount = sizeof (i386_regnames) / sizeof (char *);
- }
-
- for (int i = 0; i < namecount; i++)
- {
- ri = reg_ctx->GetRegisterInfoByName (names[i]);
- if (ri)
- m_non_volatile_regs.insert (ri->kinds[eRegisterKindLLDB]);
- }
-}
-
-
-//------------------------------------------------------------------
-// PluginInterface protocol in ArchVolatileRegs_x86
-//------------------------------------------------------------------
-
-const char *
-ArchVolatileRegs_x86::GetPluginName()
-{
- return "ArchVolatileRegs_x86";
-}
-
-const char *
-ArchVolatileRegs_x86::GetShortPluginName()
-{
- return "archvolatileregs.x86";
-}
-
-
-uint32_t
-ArchVolatileRegs_x86::GetPluginVersion()
-{
- return 1;
-}
-
-void
-ArchVolatileRegs_x86::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
-}
-
-void
-ArchVolatileRegs_x86::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
-}
-
-
-const char *
-ArchVolatileRegs_x86::GetPluginNameStatic()
-{
- return "ArchVolatileRegs_x86";
-}
-
-const char *
-ArchVolatileRegs_x86::GetPluginDescriptionStatic()
-{
- return "i386 and x86_64 architecture volatile register information.";
-}
diff --git a/lldb/source/Plugins/ArchVolatileRegs/x86/ArchVolatileRegs-x86.h b/lldb/source/Plugins/ArchVolatileRegs/x86/ArchVolatileRegs-x86.h
deleted file mode 100644
index c01bef581d7..00000000000
--- a/lldb/source/Plugins/ArchVolatileRegs/x86/ArchVolatileRegs-x86.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//===-- ArchVolatileRegs-x86.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_ArchVolatileRegs_x86_h_
-#define liblldb_ArchVolatileRegs_x86_h_
-
-#include "lldb/lldb-private.h"
-#include "lldb/Core/ArchSpec.h"
-#include "lldb/Target/ArchVolatileRegs.h"
-#include <set>
-
-class ArchVolatileRegs_x86 : public lldb_private::ArchVolatileRegs
-{
-public:
-
- ~ArchVolatileRegs_x86 () { }
-
- bool
- RegisterIsVolatile (lldb_private::Thread& thread, uint32_t regnum);
-
- static lldb_private::ArchVolatileRegs *
- CreateInstance (const lldb_private::ArchSpec &arch);
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static const char *
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- virtual const char *
- GetPluginName();
-
- virtual const char *
- GetShortPluginName();
-
- virtual uint32_t
- GetPluginVersion();
-
-private:
- ArchVolatileRegs_x86(llvm::Triple::ArchType cpu); // Call CreateInstance instead.
-
- void initialize_regset(lldb_private::Thread& thread);
-
- llvm::Triple::ArchType m_cpu;
- std::set<int> m_non_volatile_regs;
-};
-
-#endif // liblldb_ArchVolatileRegs_x86_h_
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index 91f1f1c0438..48e5c7f3ca7 100644
--- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -576,7 +576,7 @@ EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncodi
addr_t addr = sp + sp_offset; // a pointer to the stack area
EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextAdjustStackPointer;
+ context.type = eContextSetFramePointer;
RegisterInfo sp_reg;
GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
context.SetRegisterPlusOffset (sp_reg, sp_offset);
@@ -13413,17 +13413,16 @@ EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, Option
bool
EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
{
+ unwind_plan.Clear();
unwind_plan.SetRegisterKind (eRegisterKindDWARF);
UnwindPlan::Row row;
- UnwindPlan::Row::RegisterLocation regloc;
// Our previous Call Frame Address is the stack pointer
row.SetCFARegister (dwarf_sp);
// Our previous PC is in the LR
- regloc.SetInRegister(dwarf_lr);
- row.SetRegisterInfo (dwarf_pc, regloc);
+ row.SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
unwind_plan.AppendRow (row);
// All other registers are the same.
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
index 9de258e3381..e042cb280bc 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
@@ -391,7 +391,7 @@ AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines (void *baton,
// The Update function is called with the address of an added region. So we grab that address, and
// feed it into ReadRegions. Of course, our friend the ABI will get the values for us.
Process *process = context->exe_ctx.process;
- const ABI *abi = process->GetABI();
+ const ABI *abi = process->GetABI().get();
ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
ValueList argument_values;
@@ -624,7 +624,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan (Thread &thread, bool sto
lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
Process *process = thread.CalculateProcess();
- const ABI *abi = process->GetABI();
+ const ABI *abi = process->GetABI().get();
if (abi == NULL)
return ret_plan_sp;
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index ef882fa540d..a0ca3af3a27 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -21,8 +21,7 @@
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Expression/DWARFExpression.h"
-#include "lldb/Target/ArchDefaultUnwindPlan.h"
-#include "lldb/Target/ArchVolatileRegs.h"
+#include "lldb/Target/ABI.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
@@ -247,12 +246,12 @@ RegisterContextLLDB::InitializeNonZerothFrame()
log->Printf("%*sFrame %u using architectural default unwind method",
m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number);
}
- const ArchSpec &arch = m_thread.GetProcess().GetTarget().GetArchitecture ();
- ArchDefaultUnwindPlanSP arch_default_sp (ArchDefaultUnwindPlan::FindPlugin (arch));
- if (arch_default_sp)
+ ABI *abi = m_thread.GetProcess().GetABI().get();
+ if (abi)
{
- m_fast_unwind_plan_sp.reset();
- m_full_unwind_plan_sp = arch_default_sp->GetArchDefaultUnwindPlan (m_thread, m_current_pc);
+ m_fast_unwind_plan_sp.reset ();
+ m_full_unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
+ abi->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp);
m_frame_type = eNormalFrame;
m_all_registers_available = false;
m_current_offset = -1;
@@ -519,10 +518,14 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame ()
UnwindPlanSP unwind_plan_sp;
LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
UnwindPlanSP arch_default_unwind_plan_sp;
- const ArchSpec &arch = m_thread.GetProcess().GetTarget().GetArchitecture ();
- ArchDefaultUnwindPlanSP arch_default_sp (ArchDefaultUnwindPlan::FindPlugin (arch));
- if (arch_default_sp)
- arch_default_unwind_plan_sp = arch_default_sp->GetArchDefaultUnwindPlan (m_thread, m_current_pc);
+
+
+ ABI *abi = m_thread.GetProcess().GetABI().get();
+ if (abi)
+ {
+ arch_default_unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
+ abi->CreateDefaultUnwindPlan(*arch_default_unwind_plan_sp);
+ }
bool behaves_like_zeroth_frame = false;
if (IsFrameZero ()
@@ -871,18 +874,21 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc
{
// If a volatile register is being requested, we don't want to forward m_next_frame's register contents
// up the stack -- the register is not retrievable at this frame.
- const ArchSpec &arch = m_thread.GetProcess().GetTarget().GetArchitecture ();
- ArchVolatileRegs *volatile_regs = ArchVolatileRegs::FindPlugin (arch);
- if (volatile_regs && volatile_regs->RegisterIsVolatile (m_thread, lldb_regnum))
+ ABI *abi = m_thread.GetProcess().GetABI().get();
+ if (abi)
{
- if (log)
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum);
+ if (reg_info && abi->RegisterIsVolatile (reg_info))
{
- log->Printf("%*sFrame %u did not supply reg location for %d because it is volatile",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum);
- }
- return false;
- }
+ if (log)
+ {
+ log->Printf("%*sFrame %u did not supply reg location for %d because it is volatile",
+ m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+ lldb_regnum);
+ }
+ return false;
+ }
+ }
if (IsFrameZero ())
{
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
index 98078195c45..2de786f0639 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -12,7 +12,6 @@
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/UnwindPlan.h"
-#include "lldb/Target/ArchDefaultUnwindPlan.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index df16f56c3f3..3e9cef34c19 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -147,8 +147,8 @@ ThreadGDBRemote::GetUnwinder ()
{
case llvm::Triple::x86_64:
case llvm::Triple::x86:
-// case llvm::Triple::arm:
-// case llvm::Triple::thumb:
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
m_unwinder_ap.reset (new UnwindLLDB (*this));
break;
diff --git a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
index 0ce503cf7ea..ee427ee9cdd 100644
--- a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
+++ b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
@@ -16,8 +16,9 @@
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/StreamString.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
@@ -37,49 +38,19 @@ UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange&
Thread& thread,
UnwindPlan& unwind_plan)
{
-#if 0
- UnwindPlan::Row row;
- UnwindPlan::Row::RegisterLocation regloc;
-
- m_unwind_plan_sp->SetRegisterKind (eRegisterKindGeneric);
- row.SetCFARegister (LLDB_REGNUM_GENERIC_FP);
- row.SetCFAOffset (2 * 8);
- row.SetOffset (0);
-
- regloc.SetAtCFAPlusOffset (2 * -8);
- row.SetRegisterInfo (LLDB_REGNUM_GENERIC_FP, regloc);
- regloc.SetAtCFAPlusOffset (1 * -8);
- row.SetRegisterInfo (LLDB_REGNUM_GENERIC_PC, regloc);
- regloc.SetIsCFAPlusOffset (0);
- row.SetRegisterInfo (LLDB_REGNUM_GENERIC_SP, regloc);
-
- m_unwind_plan_sp->AppendRow (row);
- m_unwind_plan_sp->SetSourceName ("x86_64 architectural default");
-#endif
-
if (range.GetByteSize() > 0 &&
range.GetBaseAddress().IsValid() &&
m_inst_emulator_ap.get())
{
-#if 0
- Target &target = thread.GetProcess().GetTarget();
- const ArchSpec &target_arch = target.GetArchitecture();
- bool prefer_file_cache = true;
- Error error;
- DataBufferHeap data_buffer (range.GetByteSize(), 0);
- if (target.ReadMemory (range.GetBaseAddress(),
- prefer_file_cache,
- data_buffer.GetBytes(),
- data_buffer.GetByteSize(),
- error) == data_buffer.GetByteSize())
- {
- DataExtractor data (data_buffer.GetBytes(),
- data_buffer.GetByteSize(),
- target_arch.GetByteOrder(),
- target_arch.GetAddressByteSize());
- }
-#endif
- StreamFile strm (stdout, false);
+
+ // The the instruction emulation subclass setup the unwind plan for the
+ // first instruction.
+ m_inst_emulator_ap->CreateFunctionEntryUnwind (unwind_plan);
+
+ // CreateFunctionEntryUnwind should have created the first row. If it
+ // doesn't, then we are done.
+ if (unwind_plan.GetRowCount() == 0)
+ return false;
ExecutionContext exe_ctx;
thread.CalculateExecutionContext(exe_ctx);
@@ -87,6 +58,9 @@ UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange&
NULL,
exe_ctx,
range));
+
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+
if (disasm_sp)
{
@@ -98,13 +72,19 @@ UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange&
const bool show_address = true;
const bool show_bytes = true;
const bool raw = false;
- // Initialize the stack pointer with a known value. In the 32 bit case
+ // Initialize the CFA with a known value. In the 32 bit case
// it will be 0x80000000, and in the 64 bit case 0x8000000000000000.
// We use the address byte size to be safe for any future addresss sizes
- RegisterInfo sp_reg_info;
- m_inst_emulator_ap->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp_reg_info);
+ m_inst_emulator_ap->GetRegisterInfo (unwind_plan.GetRegisterKind(),
+ unwind_plan.GetInitialCFARegister(),
+ m_cfa_reg_info);
+
+ m_fp_is_cfa = false;
+ m_register_values.clear();
+ m_pushed_regs.clear();
+
m_initial_sp = (1ull << ((addr_byte_size * 8) - 1));
- SetRegisterValue(sp_reg_info, m_initial_sp);
+ SetRegisterValue (m_cfa_reg_info, m_initial_sp);
const InstructionList &inst_list = disasm_sp->GetInstructionList ();
const size_t num_instructions = inst_list.GetSize();
@@ -112,26 +92,51 @@ UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange&
{
Instruction *inst = inst_list.GetInstructionAtIndex (0).get();
const addr_t base_addr = inst->GetAddress().GetFileAddress();
+ // Initialize the current row with the one row that was created
+ // from the CreateFunctionEntryUnwind call above...
+ m_curr_row = unwind_plan.GetLastRow();
for (size_t idx=0; idx<num_instructions; ++idx)
{
inst = inst_list.GetInstructionAtIndex (idx).get();
if (inst)
{
- m_curr_row.Clear();
- inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize (), show_address, show_bytes, &exe_ctx, raw);
- strm.EOL();
+
+ if (log)
+ {
+ StreamString strm;
+ inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize (), show_address, show_bytes, &exe_ctx, raw);
+ log->PutCString (strm.GetData());
+ }
m_inst_emulator_ap->SetInstruction (inst->GetOpcode(),
inst->GetAddress(),
exe_ctx.target);
- m_curr_row.SetOffset (inst->GetAddress().GetFileAddress() + inst->GetOpcode().GetByteSize() - base_addr);
m_inst_emulator_ap->EvaluateInstruction (eEmulateInstructionOptionIgnoreConditions);
+
+ if (unwind_plan.GetLastRow() != m_curr_row)
+ {
+ // Be sure to not edit the offset unless our row has changed
+ // so that the "!=" call above doesn't trigger every time
+ m_curr_row.SetOffset (inst->GetAddress().GetFileAddress() + inst->GetOpcode().GetByteSize() - base_addr);
+ // Append the new row
+ unwind_plan.AppendRow (m_curr_row);
+ }
}
}
}
}
+
+ if (log)
+ {
+ StreamString strm;
+ lldb::addr_t base_addr = range.GetBaseAddress().GetLoadAddress(&thread.GetProcess().GetTarget());
+ strm.Printf ("Resulting unwind rows for [0x%llx - 0x%llx):", base_addr, base_addr + range.GetByteSize());
+ unwind_plan.Dump(strm, &thread, base_addr);
+ log->PutCString (strm.GetData());
+ }
+ return unwind_plan.GetRowCount() > 0;
}
return false;
}
@@ -255,12 +260,18 @@ UnwindAssemblyInstEmulation::ReadMemory (EmulateInstruction *instruction,
void *dst,
size_t dst_len)
{
- //UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton;
- printf ("UnwindAssemblyInstEmulation::ReadMemory (addr = 0x%16.16llx, dst = %p, dst_len = %zu, context = ",
- addr,
- dst,
- dst_len);
- context.Dump(stdout, instruction);
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+
+ if (log)
+ {
+ StreamString strm;
+ strm.Printf ("UnwindAssemblyInstEmulation::ReadMemory (addr = 0x%16.16llx, dst = %p, dst_len = %zu, context = ",
+ addr,
+ dst,
+ dst_len);
+ context.Dump(strm, instruction);
+ log->PutCString (strm.GetData ());
+ }
return dst_len;
}
@@ -272,19 +283,39 @@ UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction,
const void *dst,
size_t dst_len)
{
- UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton;
-
+ if (baton && dst && dst_len)
+ return ((UnwindAssemblyInstEmulation *)baton)->WriteMemory (instruction, context, addr, dst, dst_len);
+ return 0;
+}
+
+size_t
+UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction,
+ const EmulateInstruction::Context &context,
+ lldb::addr_t addr,
+ const void *dst,
+ size_t dst_len)
+{
DataExtractor data (dst,
dst_len,
instruction->GetArchitecture ().GetByteOrder(),
instruction->GetArchitecture ().GetAddressByteSize());
- StreamFile strm(stdout, false);
- strm.PutCString ("UnwindAssemblyInstEmulation::WriteMemory (");
- data.Dump(&strm, 0, eFormatBytes, 1, dst_len, UINT32_MAX, addr, 0, 0);
- strm.PutCString (", context = ");
- context.Dump(stdout, instruction);
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+
+ if (log)
+ {
+ StreamString strm;
+
+ strm.PutCString ("UnwindAssemblyInstEmulation::WriteMemory (");
+ data.Dump(&strm, 0, eFormatBytes, 1, dst_len, UINT32_MAX, addr, 0, 0);
+ strm.PutCString (", context = ");
+ context.Dump(strm, instruction);
+ log->PutCString (strm.GetData());
+ }
+ const bool can_replace = true;
+ const bool cant_replace = false;
+
switch (context.type)
{
default:
@@ -307,25 +338,45 @@ UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction,
case EmulateInstruction::eContextReturnFromException:
case EmulateInstruction::eContextPopRegisterOffStack:
case EmulateInstruction::eContextAdjustStackPointer:
- assert (!"unhandled case, add code to handle this!");
break;
case EmulateInstruction::eContextPushRegisterOnStack:
- switch (context.info_type)
{
- case EmulateInstruction::eInfoTypeRegisterToRegisterPlusOffset:
+ uint32_t reg_num = LLDB_INVALID_REGNUM;
+ bool is_return_address_reg = false;
+ const uint32_t unwind_reg_kind = m_unwind_plan_ptr->GetRegisterKind();
+ if (context.info_type == EmulateInstruction::eInfoTypeRegisterToRegisterPlusOffset)
+ {
+ reg_num = context.info.RegisterToRegisterPlusOffset.data_reg.kinds[unwind_reg_kind];
+ if (context.info.RegisterToRegisterPlusOffset.data_reg.kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_RA)
+ is_return_address_reg = true;
+ }
+ else
+ {
+ assert (!"unhandled case, add code to handle this!");
+ }
+
+ if (reg_num != LLDB_INVALID_REGNUM)
+ {
+ if (m_pushed_regs.find (reg_num) == m_pushed_regs.end())
{
- UnwindPlan::Row::RegisterLocation regloc;
- const uint32_t dwarf_reg_num = context.info.RegisterToRegisterPlusOffset.data_reg.kinds[eRegisterKindDWARF];
- //const addr_t reg_cfa_offset = inst_emulator->m_curr_row.GetCFAOffset() + context.info.RegisterToRegisterPlusOffset.offset;
- regloc.SetAtCFAPlusOffset (addr - inst_emulator->m_initial_sp);
- inst_emulator->m_curr_row.SetRegisterInfo (dwarf_reg_num, regloc);
+ m_pushed_regs[reg_num] = addr;
+ const int32_t offset = addr - m_initial_sp;
+ m_curr_row.SetRegisterLocationToAtCFAPlusOffset (reg_num, offset, cant_replace);
+ if (is_return_address_reg)
+ {
+ // This push was pushing the return address register,
+ // so this is also how we will unwind the PC...
+ RegisterInfo pc_reg_info;
+ if (instruction->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc_reg_info))
+ {
+ uint32_t pc_reg_num = pc_reg_info.kinds[unwind_reg_kind];
+ if (pc_reg_num != LLDB_INVALID_REGNUM)
+ m_curr_row.SetRegisterLocationToAtCFAPlusOffset (pc_reg_num, offset, can_replace);
+ }
+ }
}
- break;
-
- default:
- assert (!"unhandled case, add code to handle this!");
- break;
+ }
}
break;
@@ -340,15 +391,27 @@ UnwindAssemblyInstEmulation::ReadRegister (EmulateInstruction *instruction,
const RegisterInfo *reg_info,
RegisterValue &reg_value)
{
+
if (baton && reg_info)
- {
- UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton;
- bool synthetic = inst_emulator->GetRegisterValue (*reg_info, reg_value);
+ return ((UnwindAssemblyInstEmulation *)baton)->ReadRegister (instruction, reg_info, reg_value);
+ return false;
+}
+bool
+UnwindAssemblyInstEmulation::ReadRegister (EmulateInstruction *instruction,
+ const RegisterInfo *reg_info,
+ RegisterValue &reg_value)
+{
+ bool synthetic = GetRegisterValue (*reg_info, reg_value);
- StreamFile strm (stdout, false);
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+
+ if (log)
+ {
+
+ StreamString strm;
strm.Printf ("UnwindAssemblyInstEmulation::ReadRegister (name = \"%s\") => synthetic_value = %i, value = ", reg_info->name, synthetic);
reg_value.Dump(&strm, reg_info, false, eFormatDefault);
- strm.EOL();
+ log->PutCString(strm.GetData());
}
return true;
}
@@ -360,17 +423,31 @@ UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
const RegisterInfo *reg_info,
const RegisterValue &reg_value)
{
- if (!baton || !reg_info)
- return false;
+ if (baton && reg_info)
+ return ((UnwindAssemblyInstEmulation *)baton)->WriteRegister (instruction, context, reg_info, reg_value);
+ return false;
+}
+bool
+UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
+ const EmulateInstruction::Context &context,
+ const RegisterInfo *reg_info,
+ const RegisterValue &reg_value)
+{
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
- UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton;
- StreamFile strm (stdout, false);
- strm.Printf ("UnwindAssemblyInstEmulation::WriteRegister (name = \"%s\", value = ", reg_info->name);
- reg_value.Dump(&strm, reg_info, false, eFormatDefault);
- strm.PutCString (", context = ");
- context.Dump(stdout, instruction);
+ if (log)
+ {
+
+ StreamString strm;
+ strm.Printf ("UnwindAssemblyInstEmulation::WriteRegister (name = \"%s\", value = ", reg_info->name);
+ reg_value.Dump(&strm, reg_info, false, eFormatDefault);
+ strm.PutCString (", context = ");
+ context.Dump(strm, instruction);
+ log->PutCString(strm.GetData());
+ }
- inst_emulator->SetRegisterValue (*reg_info, reg_value);
+ const bool must_replace = true;
+ SetRegisterValue (*reg_info, reg_value);
switch (context.type)
{
@@ -393,31 +470,48 @@ UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
case EmulateInstruction::eContextAdvancePC:
case EmulateInstruction::eContextReturnFromException:
case EmulateInstruction::eContextPushRegisterOnStack:
- assert (!"unhandled case, add code to handle this!");
+// {
+// const uint32_t reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
+// if (reg_num != LLDB_INVALID_REGNUM)
+// {
+// const bool can_replace_only_if_unspecified = true;
+//
+// m_curr_row.SetRegisterLocationToUndefined (reg_num,
+// can_replace_only_if_unspecified,
+// can_replace_only_if_unspecified);
+// }
+// }
break;
case EmulateInstruction::eContextPopRegisterOffStack:
{
- switch (context.info_type)
+ const uint32_t reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
+ if (reg_num != LLDB_INVALID_REGNUM)
{
- case EmulateInstruction::eInfoTypeRegisterPlusOffset:
- {
- const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
- UnwindPlan::Row::RegisterLocation regloc;
- regloc.SetSame();
- inst_emulator->m_curr_row.SetRegisterInfo (dwarf_reg_num, regloc);
- }
- break;
-
- default:
- assert (!"unhandled case, add code to handle this!");
- break;
+ m_curr_row.SetRegisterLocationToSame (reg_num, must_replace);
}
}
break;
+ case EmulateInstruction::eContextSetFramePointer:
+ if (!m_fp_is_cfa)
+ {
+ m_fp_is_cfa = true;
+ m_cfa_reg_info = *reg_info;
+ const uint32_t cfa_reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
+ assert (cfa_reg_num != LLDB_INVALID_REGNUM);
+ m_curr_row.SetCFARegister(cfa_reg_num);
+ m_curr_row.SetCFAOffset(m_initial_sp - reg_value.GetAsUInt64());
+ }
+ break;
+
case EmulateInstruction::eContextAdjustStackPointer:
- inst_emulator->m_curr_row.SetCFAOffset (reg_value.GetAsUInt64() - inst_emulator->m_initial_sp);
+ // If we have created a frame using the frame pointer, don't follow
+ // subsequent adjustments to the stack pointer.
+ if (!m_fp_is_cfa)
+ {
+ m_curr_row.SetCFAOffset (m_initial_sp - reg_value.GetAsUInt64());
+ }
break;
}
return true;
diff --git a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
index 96c13813e48..b7025710333 100644
--- a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
+++ b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
@@ -101,6 +101,31 @@ private:
const lldb_private::RegisterValue &reg_value);
+// size_t
+// ReadMemory (lldb_private::EmulateInstruction *instruction,
+// const lldb_private::EmulateInstruction::Context &context,
+// lldb::addr_t addr,
+// void *dst,
+// size_t length);
+
+ size_t
+ WriteMemory (lldb_private::EmulateInstruction *instruction,
+ const lldb_private::EmulateInstruction::Context &context,
+ lldb::addr_t addr,
+ const void *dst,
+ size_t length);
+
+ bool
+ ReadRegister (lldb_private::EmulateInstruction *instruction,
+ const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &reg_value);
+
+ bool
+ WriteRegister (lldb_private::EmulateInstruction *instruction,
+ const lldb_private::EmulateInstruction::Context &context,
+ const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &reg_value);
+
// Call CreateInstance to get an instance of this class
UnwindAssemblyInstEmulation (const lldb_private::ArchSpec &arch,
lldb_private::EmulateInstruction *inst_emulator) :
@@ -108,7 +133,12 @@ private:
m_inst_emulator_ap (inst_emulator),
m_range_ptr (NULL),
m_thread_ptr (NULL),
- m_unwind_plan_ptr (NULL)
+ m_unwind_plan_ptr (NULL),
+ m_curr_row (),
+ m_cfa_reg_info (),
+ m_fp_is_cfa (false),
+ m_register_values (),
+ m_pushed_regs()
{
if (m_inst_emulator_ap.get())
{
@@ -133,9 +163,13 @@ private:
lldb_private::Thread* m_thread_ptr;
lldb_private::UnwindPlan* m_unwind_plan_ptr;
lldb_private::UnwindPlan::Row m_curr_row;
+ typedef std::map<uint64_t, uint64_t> PushedRegisterToAddrMap;
uint64_t m_initial_sp;
+ lldb_private::RegisterInfo m_cfa_reg_info;
+ bool m_fp_is_cfa;
typedef std::map<uint64_t, lldb_private::RegisterValue> RegisterValueMap;
RegisterValueMap m_register_values;
+ PushedRegisterToAddrMap m_pushed_regs;
};
#endif // liblldb_UnwindAssemblyInstEmulation_h_
OpenPOWER on IntegriCloud