diff options
Diffstat (limited to 'lldb/source/Plugins')
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 ¤t_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 ¤t_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 ¤t_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 ¤t_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 ®_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 ®_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 ®_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 ®_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 ®_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 ®_value); + + bool + WriteRegister (lldb_private::EmulateInstruction *instruction, + const lldb_private::EmulateInstruction::Context &context, + const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue ®_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_ |