diff options
Diffstat (limited to 'lldb/source/Plugins/ABI')
-rw-r--r-- | lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp | 807 | ||||
-rw-r--r-- | lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h | 95 | ||||
-rw-r--r-- | lldb/source/Plugins/ABI/MacOSX-arm/Makefile | 14 | ||||
-rw-r--r-- | lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp | 152 | ||||
-rw-r--r-- | lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h | 246 | ||||
-rw-r--r-- | lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp | 151 | ||||
-rw-r--r-- | lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h | 178 |
7 files changed, 1561 insertions, 82 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_ |