summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/ABI
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/ABI')
-rw-r--r--lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp807
-rw-r--r--lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h95
-rw-r--r--lldb/source/Plugins/ABI/MacOSX-arm/Makefile14
-rw-r--r--lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp152
-rw-r--r--lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h246
-rw-r--r--lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp151
-rw-r--r--lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h178
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 &current_stack_argument)
+{
+// if (bit_width > 64)
+// return false; // Scalar can't hold large integer arguments
+//
+// uint64_t arg_contents;
+// uint32_t read_data;
+// Error error;
+//
+// if (bit_width > 32)
+// {
+// if (process.ReadMemory(current_stack_argument, &read_data, sizeof(read_data), error) != sizeof(read_data))
+// return false;
+//
+// arg_contents = read_data;
+//
+// if (process.ReadMemory(current_stack_argument + 4, &read_data, sizeof(read_data), error) != sizeof(read_data))
+// return false;
+//
+// arg_contents |= ((uint64_t)read_data) << 32;
+//
+// current_stack_argument += 8;
+// }
+// else {
+// if (process.ReadMemory(current_stack_argument, &read_data, sizeof(read_data), error) != sizeof(read_data))
+// return false;
+//
+// arg_contents = read_data;
+//
+// current_stack_argument += 4;
+// }
+//
+// if (is_signed)
+// {
+// switch (bit_width)
+// {
+// default:
+// return false;
+// case 8:
+// scalar = (int8_t)(arg_contents & 0xff);
+// break;
+// case 16:
+// scalar = (int16_t)(arg_contents & 0xffff);
+// break;
+// case 32:
+// scalar = (int32_t)(arg_contents & 0xffffffff);
+// break;
+// case 64:
+// scalar = (int64_t)arg_contents;
+// break;
+// }
+// }
+// else
+// {
+// switch (bit_width)
+// {
+// default:
+// return false;
+// case 8:
+// scalar = (uint8_t)(arg_contents & 0xff);
+// break;
+// case 16:
+// scalar = (uint16_t)(arg_contents & 0xffff);
+// break;
+// case 32:
+// scalar = (uint32_t)(arg_contents & 0xffffffff);
+// break;
+// case 64:
+// scalar = (uint64_t)arg_contents;
+// break;
+// }
+// }
+//
+// return true;
+ return false;
+}
+
+bool
+ABIMacOSX_arm::GetArgumentValues (Thread &thread,
+ ValueList &values) const
+{
+// unsigned int num_values = values.GetSize();
+// unsigned int value_index;
+//
+// // Extract the Clang AST context from the PC so that we can figure out type
+// // sizes
+//
+// clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
+//
+// // Get the pointer to the first stack argument so we have a place to start
+// // when reading data
+//
+// RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+//
+// if (!reg_ctx)
+// return false;
+//
+// addr_t sp = reg_ctx->GetSP(0);
+//
+// if (!sp)
+// return false;
+//
+// addr_t current_stack_argument = sp + 4; // jump over return address
+//
+// for (value_index = 0;
+// value_index < num_values;
+// ++value_index)
+// {
+// Value *value = values.GetValueAtIndex(value_index);
+//
+// if (!value)
+// return false;
+//
+// // We currently only support extracting values with Clang QualTypes.
+// // Do we care about others?
+// switch (value->GetContextType())
+// {
+// default:
+// return false;
+// case Value::eContextTypeClangType:
+// {
+// void *value_type = value->GetClangType();
+// bool is_signed;
+//
+// if (ClangASTContext::IsIntegerType (value_type, is_signed))
+// {
+// size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+//
+// ReadIntegerArgument(value->GetScalar(),
+// bit_width,
+// is_signed,
+// thread.GetProcess(),
+// current_stack_argument);
+// }
+// else if (ClangASTContext::IsPointerType (value_type))
+// {
+// ReadIntegerArgument(value->GetScalar(),
+// 32,
+// false,
+// thread.GetProcess(),
+// current_stack_argument);
+// }
+// }
+// break;
+// }
+// }
+//
+// return true;
+ return false;
+}
+
+bool
+ABIMacOSX_arm::GetReturnValue (Thread &thread,
+ Value &value) const
+{
+// switch (value.GetContextType())
+// {
+// default:
+// return false;
+// case Value::eContextTypeClangType:
+// {
+// // Extract the Clang AST context from the PC so that we can figure out type
+// // sizes
+//
+// clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
+//
+// // Get the pointer to the first stack argument so we have a place to start
+// // when reading data
+//
+// RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+//
+// void *value_type = value.GetClangType();
+// bool is_signed;
+//
+// if (ClangASTContext::IsIntegerType (value_type, is_signed))
+// {
+// size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+//
+// unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
+// unsigned edx_id = reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];
+//
+// switch (bit_width)
+// {
+// default:
+// case 128:
+// // Scalar can't hold 128-bit literals, so we don't handle this
+// return false;
+// case 64:
+// uint64_t raw_value;
+// raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff;
+// raw_value |= (thread.GetRegisterContext()->ReadRegisterAsUnsigned(edx_id, 0) & 0xffffffff) << 32;
+// if (is_signed)
+// value.GetScalar() = (int64_t)raw_value;
+// else
+// value.GetScalar() = (uint64_t)raw_value;
+// break;
+// case 32:
+// if (is_signed)
+// value.GetScalar() = (int32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff);
+// else
+// value.GetScalar() = (uint32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff);
+// break;
+// case 16:
+// if (is_signed)
+// value.GetScalar() = (int16_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffff);
+// else
+// value.GetScalar() = (uint16_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffff);
+// break;
+// case 8:
+// if (is_signed)
+// value.GetScalar() = (int8_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xff);
+// else
+// value.GetScalar() = (uint8_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xff);
+// break;
+// }
+// }
+// else if (ClangASTContext::IsPointerType (value_type))
+// {
+// unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
+// uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff;
+// value.GetScalar() = ptr;
+// }
+// else
+// {
+// // not handled yet
+// return false;
+// }
+// }
+// break;
+// }
+//
+// return true;
+ return false;
+}
+
+bool
+ABIMacOSX_arm::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
+{
+ uint32_t reg_kind = unwind_plan.GetRegisterKind();
+ uint32_t lr_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t sp_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t pc_reg_num = LLDB_INVALID_REGNUM;
+
+ switch (reg_kind)
+ {
+ case eRegisterKindDWARF:
+ case eRegisterKindGCC:
+ lr_reg_num = dwarf_lr;
+ sp_reg_num = dwarf_sp;
+ pc_reg_num = dwarf_pc;
+ break;
+
+ case eRegisterKindGeneric:
+ lr_reg_num = LLDB_REGNUM_GENERIC_RA;
+ sp_reg_num = LLDB_REGNUM_GENERIC_SP;
+ pc_reg_num = LLDB_REGNUM_GENERIC_PC;
+ break;
+ }
+
+ if (lr_reg_num == LLDB_INVALID_REGNUM ||
+ sp_reg_num == LLDB_INVALID_REGNUM ||
+ pc_reg_num == LLDB_INVALID_REGNUM)
+ return false;
+
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+
+ UnwindPlan::Row row;
+
+ // Our previous Call Frame Address is the stack pointer
+ row.SetCFARegister (sp_reg_num);
+
+ // Our previous PC is in the LR
+ row.SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
+ unwind_plan.AppendRow (row);
+
+ // All other registers are the same.
+
+ unwind_plan.SetSourceName (pluginName);
+ return true;
+}
+
+bool
+ABIMacOSX_arm::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
+{
+ uint32_t reg_kind = unwind_plan.GetRegisterKind();
+ uint32_t fp_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t sp_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t pc_reg_num = LLDB_INVALID_REGNUM;
+
+ switch (reg_kind)
+ {
+ case eRegisterKindDWARF:
+ case eRegisterKindGCC:
+ fp_reg_num = dwarf_r7; // apple uses r7 for all frames. Normal arm uses r11
+ sp_reg_num = dwarf_sp;
+ pc_reg_num = dwarf_pc;
+ break;
+
+ case eRegisterKindGeneric:
+ fp_reg_num = LLDB_REGNUM_GENERIC_FP;
+ sp_reg_num = LLDB_REGNUM_GENERIC_SP;
+ pc_reg_num = LLDB_REGNUM_GENERIC_PC;
+ break;
+ }
+
+ if (fp_reg_num == LLDB_INVALID_REGNUM ||
+ sp_reg_num == LLDB_INVALID_REGNUM ||
+ pc_reg_num == LLDB_INVALID_REGNUM)
+ return false;
+
+ UnwindPlan::Row row;
+ const int32_t ptr_size = 8;
+
+ unwind_plan.SetRegisterKind (eRegisterKindGeneric);
+ row.SetCFARegister (fp_reg_num);
+ row.SetCFAOffset (2 * ptr_size);
+ row.SetOffset (0);
+
+ row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
+ row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
+
+ unwind_plan.AppendRow (row);
+ unwind_plan.SetSourceName ("arm-apple-darwin default unwind plan");
+ return true;
+}
+
+bool
+ABIMacOSX_arm::RegisterIsVolatile (const RegisterInfo *reg_info)
+{
+ if (reg_info)
+ {
+ // Volatile registers include: ebx, ebp, esi, edi, esp, eip
+ const char *name = reg_info->name;
+ if (name[0] == 'r')
+ {
+ switch (name[1])
+ {
+ case '0': return name[2] == '\0'; // r0
+ case '1':
+ switch (name[2])
+ {
+ case '\0':
+ return true; // r1
+ case '2':
+ case '3':
+ return name[2] == '\0'; // r12 - r13
+ default:
+ break;
+ }
+ break;
+
+ case '2': return name[2] == '\0'; // r2
+ case '3': return name[2] == '\0'; // r3
+ case '9': return name[2] == '\0'; // r9 (apple-darwin only...)
+
+ break;
+ }
+ }
+ else if (name[0] == 'd')
+ {
+ switch (name[1])
+ {
+ case '0':
+ return name[2] == '\0'; // d0
+
+ case '1':
+ switch (name[2])
+ {
+ case '\0':
+ return true; // d1;
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return name[3] == '\0'; // d16 - d19
+ default:
+ break;
+ }
+ break;
+
+ case '2':
+ switch (name[2])
+ {
+ case '\0':
+ return true; // d2;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return name[3] == '\0'; // d20 - d29
+ default:
+ break;
+ }
+ break;
+
+ case '3':
+ switch (name[2])
+ {
+ case '\0':
+ return true; // d3;
+ case '0':
+ case '1':
+ return name[3] == '\0'; // d30 - d31
+ default:
+ break;
+ }
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ return name[2] == '\0'; // d4 - d7
+
+ default:
+ break;
+ }
+ }
+ else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')
+ return true;
+ }
+ return false;
+}
+
+void
+ABIMacOSX_arm::Initialize()
+{
+ PluginManager::RegisterPlugin (pluginName,
+ pluginDesc,
+ CreateInstance);
+}
+
+void
+ABIMacOSX_arm::Terminate()
+{
+ PluginManager::UnregisterPlugin (CreateInstance);
+}
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+const char *
+ABIMacOSX_arm::GetPluginName()
+{
+ return pluginName;
+}
+
+const char *
+ABIMacOSX_arm::GetShortPluginName()
+{
+ return pluginShort;
+}
+
+uint32_t
+ABIMacOSX_arm::GetPluginVersion()
+{
+ return 1;
+}
+
diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
new file mode 100644
index 00000000000..d1d5dc4c4bc
--- /dev/null
+++ b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
@@ -0,0 +1,95 @@
+//===-- ABIMacOSX_arm.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ABIMacOSX_arm_h_
+#define liblldb_ABIMacOSX_arm_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Target/ABI.h"
+
+class ABIMacOSX_arm : public lldb_private::ABI
+{
+public:
+ ~ABIMacOSX_arm() { }
+
+ virtual size_t
+ GetRedZoneSize () const;
+
+ virtual bool
+ PrepareTrivialCall (lldb_private::Thread &thread,
+ lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ lldb::addr_t arg,
+ lldb::addr_t *this_arg,
+ lldb::addr_t *cmd_arg) const;
+
+ virtual bool
+ PrepareNormalCall (lldb_private::Thread &thread,
+ lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ lldb_private::ValueList &args) const;
+
+ virtual bool
+ GetArgumentValues (lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const;
+
+ virtual bool
+ GetReturnValue (lldb_private::Thread &thread,
+ lldb_private::Value &value) const;
+
+ virtual bool
+ CreateFunctionEntryUnwindPlan (lldb_private::UnwindPlan &unwind_plan);
+
+ virtual bool
+ CreateDefaultUnwindPlan (lldb_private::UnwindPlan &unwind_plan);
+
+ virtual bool
+ RegisterIsVolatile (const lldb_private::RegisterInfo *reg_info);
+
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ static lldb::ABISP
+ CreateInstance (const lldb_private::ArchSpec &arch);
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ virtual const char *
+ GetPluginName();
+
+ virtual const char *
+ GetShortPluginName();
+
+ virtual uint32_t
+ GetPluginVersion();
+
+protected:
+private:
+ ABIMacOSX_arm() :
+ lldb_private::ABI()
+ {
+ // Call CreateInstance instead.
+ }
+};
+
+#endif // liblldb_ABIMacOSX_arm_h_
diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/Makefile b/lldb/source/Plugins/ABI/MacOSX-arm/Makefile
new file mode 100644
index 00000000000..18073266d34
--- /dev/null
+++ b/lldb/source/Plugins/ABI/MacOSX-arm/Makefile
@@ -0,0 +1,14 @@
+##===- source/Plugins/ABI/MacOSX-arm/Makefile ------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===--------------------------------------------------------------------===##
+
+LLDB_LEVEL := ../../../..
+LIBRARYNAME := lldbPluginABIMacOSX_arm
+BUILD_ARCHIVE = 1
+
+include $(LLDB_LEVEL)/Makefile
diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
index a65a2efa78f..8c9df142890 100644
--- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
+++ b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
@@ -15,6 +15,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
@@ -40,13 +41,17 @@ ABIMacOSX_i386::GetRedZoneSize () const
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
-lldb_private::ABI *
+ABISP
ABIMacOSX_i386::CreateInstance (const ArchSpec &arch)
{
+ static ABISP g_abi_sp;
if (arch.GetTriple().getArch() == llvm::Triple::x86)
- return new ABIMacOSX_i386;
-
- return NULL;
+ {
+ if (!g_abi_sp)
+ g_abi_sp.reset (new ABIMacOSX_i386);
+ return g_abi_sp;
+ }
+ return ABISP();
}
bool
@@ -560,6 +565,145 @@ ABIMacOSX_i386::GetReturnValue (Thread &thread,
return true;
}
+bool
+ABIMacOSX_i386::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
+{
+ uint32_t reg_kind = unwind_plan.GetRegisterKind();
+ uint32_t sp_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t pc_reg_num = LLDB_INVALID_REGNUM;
+
+ switch (reg_kind)
+ {
+ case eRegisterKindDWARF:
+ sp_reg_num = dwarf_esp;
+ pc_reg_num = dwarf_eip;
+ break;
+
+ case eRegisterKindGCC:
+ sp_reg_num = gcc_esp;
+ pc_reg_num = gcc_eip;
+ break;
+
+ case eRegisterKindGDB:
+ sp_reg_num = gdb_esp;
+ pc_reg_num = gdb_eip;
+ break;
+
+ case eRegisterKindGeneric:
+ sp_reg_num = LLDB_REGNUM_GENERIC_SP;
+ pc_reg_num = LLDB_REGNUM_GENERIC_PC;
+ break;
+ }
+
+ if (sp_reg_num == LLDB_INVALID_REGNUM ||
+ pc_reg_num == LLDB_INVALID_REGNUM)
+ return false;
+
+ UnwindPlan::Row row;
+ row.SetCFARegister (sp_reg_num);
+ row.SetCFAOffset (4);
+ row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);
+ unwind_plan.AppendRow (row);
+ unwind_plan.SetSourceName (pluginName);
+ return true;
+}
+
+bool
+ABIMacOSX_i386::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
+{
+ uint32_t reg_kind = unwind_plan.GetRegisterKind();
+ uint32_t fp_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t sp_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t pc_reg_num = LLDB_INVALID_REGNUM;
+
+ switch (reg_kind)
+ {
+ case eRegisterKindDWARF:
+ fp_reg_num = dwarf_ebp;
+ sp_reg_num = dwarf_esp;
+ pc_reg_num = dwarf_eip;
+ break;
+
+ case eRegisterKindGCC:
+ fp_reg_num = gcc_ebp;
+ sp_reg_num = gcc_esp;
+ pc_reg_num = gcc_eip;
+ break;
+
+ case eRegisterKindGDB:
+ fp_reg_num = gdb_ebp;
+ sp_reg_num = gdb_esp;
+ pc_reg_num = gdb_eip;
+ break;
+
+ case eRegisterKindGeneric:
+ fp_reg_num = LLDB_REGNUM_GENERIC_FP;
+ sp_reg_num = LLDB_REGNUM_GENERIC_SP;
+ pc_reg_num = LLDB_REGNUM_GENERIC_PC;
+ break;
+ }
+
+ if (fp_reg_num == LLDB_INVALID_REGNUM ||
+ sp_reg_num == LLDB_INVALID_REGNUM ||
+ pc_reg_num == LLDB_INVALID_REGNUM)
+ return false;
+
+ UnwindPlan::Row row;
+ const int32_t ptr_size = 4;
+
+ unwind_plan.SetRegisterKind (eRegisterKindGeneric);
+ row.SetCFARegister (fp_reg_num);
+ row.SetCFAOffset (2 * ptr_size);
+ row.SetOffset (0);
+
+ row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
+ row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
+ row.SetRegisterLocationToAtCFAPlusOffset(sp_reg_num, ptr_size * 0, true);
+
+ unwind_plan.AppendRow (row);
+ unwind_plan.SetSourceName ("i386 default unwind plan");
+ return true;
+}
+
+bool
+ABIMacOSX_i386::RegisterIsVolatile (const RegisterInfo *reg_info)
+{
+ return RegisterIsCalleeSaved (reg_info);
+}
+
+bool
+ABIMacOSX_i386::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
+{
+ if (reg_info)
+ {
+ // Volatile registers include: ebx, ebp, esi, edi, esp, eip
+ const char *name = reg_info->name;
+ if (name[0] == 'e')
+ {
+ switch (name[1])
+ {
+ case 'b':
+ if (name[2] == 'x' || name[2] == 'p')
+ return name[0] == '\0';
+ break;
+ case 'd':
+ if (name[2] == 'i')
+ return name[0] == '\0';
+ break;
+ case 'i':
+ if (name[2] == 'p')
+ return name[0] == '\0';
+ break;
+ case 's':
+ if (name[2] == 'i' || name[2] == 'p')
+ return name[0] == '\0';
+ break;
+ }
+ }
+ }
+ return false;
+}
+
void
ABIMacOSX_i386::Initialize()
{
diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
index 20dbc4af5ec..e50330fda76 100644
--- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
+++ b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
@@ -17,71 +17,195 @@
#include "lldb/lldb-private.h"
#include "lldb/Target/ABI.h"
#include "lldb/Core/Value.h"
-
-namespace lldb_private {
- class ABIMacOSX_i386 :
+class ABIMacOSX_i386 :
public lldb_private::ABI
+{
+public:
+
+ enum
{
- public:
- ~ABIMacOSX_i386() { }
-
- virtual size_t
- GetRedZoneSize () const;
-
- virtual bool
- PrepareTrivialCall (Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t functionAddress,
- lldb::addr_t returnAddress,
- lldb::addr_t arg,
- lldb::addr_t *this_arg,
- lldb::addr_t *cmd_arg) const;
-
- virtual bool
- PrepareNormalCall (Thread &thread,
- lldb::addr_t sp,
- lldb::addr_t functionAddress,
- lldb::addr_t returnAddress,
- ValueList &args) const;
-
- virtual bool
- GetArgumentValues (Thread &thread,
- ValueList &values) const;
-
- virtual bool
- GetReturnValue (Thread &thread,
- Value &value) const;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ABI *
- CreateInstance (const ArchSpec &arch);
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- virtual const char *
- GetPluginName();
-
- virtual const char *
- GetShortPluginName();
-
- virtual uint32_t
- GetPluginVersion();
-
- protected:
- private:
- ABIMacOSX_i386() : lldb_private::ABI() { } // Call CreateInstance instead.
+ gcc_eax = 0,
+ gcc_ecx,
+ gcc_edx,
+ gcc_ebx,
+ gcc_ebp,
+ gcc_esp,
+ gcc_esi,
+ gcc_edi,
+ gcc_eip,
+ gcc_eflags
};
-} // namespace lldb_private
+ enum
+ {
+ dwarf_eax = 0,
+ dwarf_ecx,
+ dwarf_edx,
+ dwarf_ebx,
+ dwarf_esp,
+ dwarf_ebp,
+ dwarf_esi,
+ dwarf_edi,
+ dwarf_eip,
+ dwarf_eflags,
+ dwarf_stmm0 = 11,
+ dwarf_stmm1,
+ dwarf_stmm2,
+ dwarf_stmm3,
+ dwarf_stmm4,
+ dwarf_stmm5,
+ dwarf_stmm6,
+ dwarf_stmm7,
+ dwarf_xmm0 = 21,
+ dwarf_xmm1,
+ dwarf_xmm2,
+ dwarf_xmm3,
+ dwarf_xmm4,
+ dwarf_xmm5,
+ dwarf_xmm6,
+ dwarf_xmm7,
+ dwarf_ymm0 = dwarf_xmm0,
+ dwarf_ymm1 = dwarf_xmm1,
+ dwarf_ymm2 = dwarf_xmm2,
+ dwarf_ymm3 = dwarf_xmm3,
+ dwarf_ymm4 = dwarf_xmm4,
+ dwarf_ymm5 = dwarf_xmm5,
+ dwarf_ymm6 = dwarf_xmm6,
+ dwarf_ymm7 = dwarf_xmm7,
+ };
+
+ enum
+ {
+ gdb_eax = 0,
+ gdb_ecx = 1,
+ gdb_edx = 2,
+ gdb_ebx = 3,
+ gdb_esp = 4,
+ gdb_ebp = 5,
+ gdb_esi = 6,
+ gdb_edi = 7,
+ gdb_eip = 8,
+ gdb_eflags = 9,
+ gdb_cs = 10,
+ gdb_ss = 11,
+ gdb_ds = 12,
+ gdb_es = 13,
+ gdb_fs = 14,
+ gdb_gs = 15,
+ gdb_stmm0 = 16,
+ gdb_stmm1 = 17,
+ gdb_stmm2 = 18,
+ gdb_stmm3 = 19,
+ gdb_stmm4 = 20,
+ gdb_stmm5 = 21,
+ gdb_stmm6 = 22,
+ gdb_stmm7 = 23,
+ gdb_fctrl = 24, gdb_fcw = gdb_fctrl,
+ gdb_fstat = 25, gdb_fsw = gdb_fstat,
+ gdb_ftag = 26, gdb_ftw = gdb_ftag,
+ gdb_fiseg = 27, gdb_fpu_cs = gdb_fiseg,
+ gdb_fioff = 28, gdb_ip = gdb_fioff,
+ gdb_foseg = 29, gdb_fpu_ds = gdb_foseg,
+ gdb_fooff = 30, gdb_dp = gdb_fooff,
+ gdb_fop = 31,
+ gdb_xmm0 = 32,
+ gdb_xmm1 = 33,
+ gdb_xmm2 = 34,
+ gdb_xmm3 = 35,
+ gdb_xmm4 = 36,
+ gdb_xmm5 = 37,
+ gdb_xmm6 = 38,
+ gdb_xmm7 = 39,
+ gdb_mxcsr = 40,
+ gdb_mm0 = 41,
+ gdb_mm1 = 42,
+ gdb_mm2 = 43,
+ gdb_mm3 = 44,
+ gdb_mm4 = 45,
+ gdb_mm5 = 46,
+ gdb_mm6 = 47,
+ gdb_mm7 = 48,
+ gdb_ymm0 = gdb_xmm0,
+ gdb_ymm1 = gdb_xmm1,
+ gdb_ymm2 = gdb_xmm2,
+ gdb_ymm3 = gdb_xmm3,
+ gdb_ymm4 = gdb_xmm4,
+ gdb_ymm5 = gdb_xmm5,
+ gdb_ymm6 = gdb_xmm6,
+ gdb_ymm7 = gdb_xmm7
+ };
+
+ ~ABIMacOSX_i386() { }
+
+ virtual size_t
+ GetRedZoneSize () const;
+
+ virtual bool
+ PrepareTrivialCall (lldb_private::Thread &thread,
+ lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ lldb::addr_t arg,
+ lldb::addr_t *this_arg,
+ lldb::addr_t *cmd_arg) const;
+
+ virtual bool
+ PrepareNormalCall (lldb_private::Thread &thread,
+ lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ lldb_private::ValueList &args) const;
+
+ virtual bool
+ GetArgumentValues (lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const;
+
+ virtual bool
+ GetReturnValue (lldb_private::Thread &thread,
+ lldb_private::Value &value) const;
+
+ virtual bool
+ CreateFunctionEntryUnwindPlan (lldb_private::UnwindPlan &unwind_plan);
+
+ virtual bool
+ CreateDefaultUnwindPlan (lldb_private::UnwindPlan &unwind_plan);
+
+ virtual bool
+ RegisterIsVolatile (const lldb_private::RegisterInfo *reg_info);
+
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ static lldb::ABISP
+ CreateInstance (const lldb_private::ArchSpec &arch);
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ virtual const char *
+ GetPluginName();
+
+ virtual const char *
+ GetShortPluginName();
+
+ virtual uint32_t
+ GetPluginVersion();
+
+protected:
+ bool
+ RegisterIsCalleeSaved (const lldb_private::RegisterInfo *reg_info);
+
+private:
+ ABIMacOSX_i386() : lldb_private::ABI() { } // Call CreateInstance instead.
+};
+
#endif // liblldb_ABI_h_
diff --git a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
index 5c2cd7403ec..3ee0562b7e8 100644
--- a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
+++ b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
@@ -17,6 +17,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Value.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -32,6 +33,8 @@ static const char *pluginName = "ABISysV_x86_64";
static const char *pluginDesc = "System V ABI for x86_64 targets";
static const char *pluginShort = "abi.sysv-x86_64";
+
+
size_t
ABISysV_x86_64::GetRedZoneSize () const
{
@@ -41,12 +44,17 @@ ABISysV_x86_64::GetRedZoneSize () const
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
-lldb_private::ABI *
+ABISP
ABISysV_x86_64::CreateInstance (const ArchSpec &arch)
{
+ static ABISP g_abi_sp;
if (arch.GetTriple().getArch() == llvm::Triple::x86_64)
- return new ABISysV_x86_64;
- return NULL;
+ {
+ if (!g_abi_sp)
+ g_abi_sp.reset (new ABISysV_x86_64);
+ return g_abi_sp;
+ }
+ return ABISP();
}
bool
@@ -446,6 +454,143 @@ ABISysV_x86_64::GetReturnValue (Thread &thread,
return true;
}
+bool
+ABISysV_x86_64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
+{
+ uint32_t reg_kind = unwind_plan.GetRegisterKind();
+ uint32_t sp_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t pc_reg_num = LLDB_INVALID_REGNUM;
+
+ switch (reg_kind)
+ {
+ case eRegisterKindDWARF:
+ case eRegisterKindGCC:
+ sp_reg_num = gcc_dwarf_rsp;
+ pc_reg_num = gcc_dwarf_rip;
+ break;
+
+ case eRegisterKindGDB:
+ sp_reg_num = gdb_rsp;
+ pc_reg_num = gdb_rip;
+ break;
+
+ case eRegisterKindGeneric:
+ sp_reg_num = LLDB_REGNUM_GENERIC_SP;
+ pc_reg_num = LLDB_REGNUM_GENERIC_PC;
+ break;
+ }
+
+ if (sp_reg_num == LLDB_INVALID_REGNUM ||
+ pc_reg_num == LLDB_INVALID_REGNUM)
+ return false;
+
+ UnwindPlan::Row row;
+ row.SetCFARegister (sp_reg_num);
+ row.SetCFAOffset (8);
+ row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
+ unwind_plan.AppendRow (row);
+ unwind_plan.SetSourceName (pluginName);
+ return true;
+}
+
+bool
+ABISysV_x86_64::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
+{
+ uint32_t reg_kind = unwind_plan.GetRegisterKind();
+ uint32_t fp_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t sp_reg_num = LLDB_INVALID_REGNUM;
+ uint32_t pc_reg_num = LLDB_INVALID_REGNUM;
+
+ switch (reg_kind)
+ {
+ case eRegisterKindDWARF:
+ case eRegisterKindGCC:
+ fp_reg_num = gcc_dwarf_rbp;
+ sp_reg_num = gcc_dwarf_rsp;
+ pc_reg_num = gcc_dwarf_rip;
+ break;
+
+ case eRegisterKindGDB:
+ fp_reg_num = gdb_rbp;
+ sp_reg_num = gdb_rsp;
+ pc_reg_num = gdb_rip;
+ break;
+
+ case eRegisterKindGeneric:
+ fp_reg_num = LLDB_REGNUM_GENERIC_FP;
+ sp_reg_num = LLDB_REGNUM_GENERIC_SP;
+ pc_reg_num = LLDB_REGNUM_GENERIC_PC;
+ break;
+ }
+
+ if (fp_reg_num == LLDB_INVALID_REGNUM ||
+ sp_reg_num == LLDB_INVALID_REGNUM ||
+ pc_reg_num == LLDB_INVALID_REGNUM)
+ return false;
+
+ UnwindPlan::Row row;
+
+ const int32_t ptr_size = 8;
+ row.SetCFARegister (LLDB_REGNUM_GENERIC_FP);
+ row.SetCFAOffset (2 * ptr_size);
+ row.SetOffset (0);
+
+ row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
+ row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
+ row.SetRegisterLocationToAtCFAPlusOffset(sp_reg_num, ptr_size * 0, true);
+
+ unwind_plan.AppendRow (row);
+ unwind_plan.SetSourceName ("x86_64 default unwind plan");
+ return true;
+}
+
+bool
+ABISysV_x86_64::RegisterIsVolatile (const RegisterInfo *reg_info)
+{
+ return !RegisterIsCalleeSaved (reg_info);
+}
+
+bool
+ABISysV_x86_64::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
+{
+ if (reg_info)
+ {
+ // Volatile registers include: rbx, rbp, rsp, r12, r13, r14, r15, rip
+ const char *name = reg_info->name;
+ if (name[0] == 'r')
+ {
+ switch (name[1])
+ {
+ case '1': // r12, r13, r14, r15
+ if (name[2] >= '2' && name[2] <= '5')
+ return name[3] == '\0';
+ break;
+
+ case 'b': // rbp, rbx
+ if (name[2] == 'p' || name[2] == 'x')
+ return name[3] == '\0';
+ break;
+
+ case 'i': // rip
+ if (name[2] == 'p')
+ return name[3] == '\0';
+ break;
+
+ case 's': // rsp
+ if (name[2] == 'p')
+ return name[3] == '\0';
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ return false;
+}
+
+
+
void
ABISysV_x86_64::Initialize()
{
diff --git a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
index beb617891c2..e1ac132da8d 100644
--- a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
+++ b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
@@ -17,19 +17,158 @@
#include "lldb/lldb-private.h"
#include "lldb/Target/ABI.h"
-namespace lldb_private {
-
class ABISysV_x86_64 :
public lldb_private::ABI
{
public:
- ~ABISysV_x86_64() { }
+
+ enum gcc_dwarf_regnums
+ {
+ gcc_dwarf_rax = 0,
+ gcc_dwarf_rdx,
+ gcc_dwarf_rcx,
+ gcc_dwarf_rbx,
+ gcc_dwarf_rsi,
+ gcc_dwarf_rdi,
+ gcc_dwarf_rbp,
+ gcc_dwarf_rsp,
+ gcc_dwarf_r8,
+ gcc_dwarf_r9,
+ gcc_dwarf_r10,
+ gcc_dwarf_r11,
+ gcc_dwarf_r12,
+ gcc_dwarf_r13,
+ gcc_dwarf_r14,
+ gcc_dwarf_r15,
+ gcc_dwarf_rip,
+ gcc_dwarf_xmm0,
+ gcc_dwarf_xmm1,
+ gcc_dwarf_xmm2,
+ gcc_dwarf_xmm3,
+ gcc_dwarf_xmm4,
+ gcc_dwarf_xmm5,
+ gcc_dwarf_xmm6,
+ gcc_dwarf_xmm7,
+ gcc_dwarf_xmm8,
+ gcc_dwarf_xmm9,
+ gcc_dwarf_xmm10,
+ gcc_dwarf_xmm11,
+ gcc_dwarf_xmm12,
+ gcc_dwarf_xmm13,
+ gcc_dwarf_xmm14,
+ gcc_dwarf_xmm15,
+ gcc_dwarf_stmm0,
+ gcc_dwarf_stmm1,
+ gcc_dwarf_stmm2,
+ gcc_dwarf_stmm3,
+ gcc_dwarf_stmm4,
+ gcc_dwarf_stmm5,
+ gcc_dwarf_stmm6,
+ gcc_dwarf_stmm7,
+ gcc_dwarf_ymm0 = gcc_dwarf_xmm0,
+ gcc_dwarf_ymm1 = gcc_dwarf_xmm1,
+ gcc_dwarf_ymm2 = gcc_dwarf_xmm2,
+ gcc_dwarf_ymm3 = gcc_dwarf_xmm3,
+ gcc_dwarf_ymm4 = gcc_dwarf_xmm4,
+ gcc_dwarf_ymm5 = gcc_dwarf_xmm5,
+ gcc_dwarf_ymm6 = gcc_dwarf_xmm6,
+ gcc_dwarf_ymm7 = gcc_dwarf_xmm7,
+ gcc_dwarf_ymm8 = gcc_dwarf_xmm8,
+ gcc_dwarf_ymm9 = gcc_dwarf_xmm9,
+ gcc_dwarf_ymm10 = gcc_dwarf_xmm10,
+ gcc_dwarf_ymm11 = gcc_dwarf_xmm11,
+ gcc_dwarf_ymm12 = gcc_dwarf_xmm12,
+ gcc_dwarf_ymm13 = gcc_dwarf_xmm13,
+ gcc_dwarf_ymm14 = gcc_dwarf_xmm14,
+ gcc_dwarf_ymm15 = gcc_dwarf_xmm15
+ };
+
+ enum gdb_regnums
+ {
+ gdb_rax = 0,
+ gdb_rbx = 1,
+ gdb_rcx = 2,
+ gdb_rdx = 3,
+ gdb_rsi = 4,
+ gdb_rdi = 5,
+ gdb_rbp = 6,
+ gdb_rsp = 7,
+ gdb_r8 = 8,
+ gdb_r9 = 9,
+ gdb_r10 = 10,
+ gdb_r11 = 11,
+ gdb_r12 = 12,
+ gdb_r13 = 13,
+ gdb_r14 = 14,
+ gdb_r15 = 15,
+ gdb_rip = 16,
+ gdb_rflags = 17,
+ gdb_cs = 18,
+ gdb_ss = 19,
+ gdb_ds = 20,
+ gdb_es = 21,
+ gdb_fs = 22,
+ gdb_gs = 23,
+ gdb_stmm0 = 24,
+ gdb_stmm1 = 25,
+ gdb_stmm2 = 26,
+ gdb_stmm3 = 27,
+ gdb_stmm4 = 28,
+ gdb_stmm5 = 29,
+ gdb_stmm6 = 30,
+ gdb_stmm7 = 31,
+ gdb_fctrl = 32, gdb_fcw = gdb_fctrl,
+ gdb_fstat = 33, gdb_fsw = gdb_fstat,
+ gdb_ftag = 34, gdb_ftw = gdb_ftag,
+ gdb_fiseg = 35, gdb_fpu_cs = gdb_fiseg,
+ gdb_fioff = 36, gdb_ip = gdb_fioff,
+ gdb_foseg = 37, gdb_fpu_ds = gdb_foseg,
+ gdb_fooff = 38, gdb_dp = gdb_fooff,
+ gdb_fop = 39,
+ gdb_xmm0 = 40,
+ gdb_xmm1 = 41,
+ gdb_xmm2 = 42,
+ gdb_xmm3 = 43,
+ gdb_xmm4 = 44,
+ gdb_xmm5 = 45,
+ gdb_xmm6 = 46,
+ gdb_xmm7 = 47,
+ gdb_xmm8 = 48,
+ gdb_xmm9 = 49,
+ gdb_xmm10 = 50,
+ gdb_xmm11 = 51,
+ gdb_xmm12 = 52,
+ gdb_xmm13 = 53,
+ gdb_xmm14 = 54,
+ gdb_xmm15 = 55,
+ gdb_mxcsr = 56,
+ gdb_ymm0 = gdb_xmm0,
+ gdb_ymm1 = gdb_xmm1,
+ gdb_ymm2 = gdb_xmm2,
+ gdb_ymm3 = gdb_xmm3,
+ gdb_ymm4 = gdb_xmm4,
+ gdb_ymm5 = gdb_xmm5,
+ gdb_ymm6 = gdb_xmm6,
+ gdb_ymm7 = gdb_xmm7,
+ gdb_ymm8 = gdb_xmm8,
+ gdb_ymm9 = gdb_xmm9,
+ gdb_ymm10 = gdb_xmm10,
+ gdb_ymm11 = gdb_xmm11,
+ gdb_ymm12 = gdb_xmm12,
+ gdb_ymm13 = gdb_xmm13,
+ gdb_ymm14 = gdb_xmm14,
+ gdb_ymm15 = gdb_xmm15
+ };
+
+ ~ABISysV_x86_64()
+ {
+ }
virtual size_t
GetRedZoneSize () const;
virtual bool
- PrepareTrivialCall (Thread &thread,
+ PrepareTrivialCall (lldb_private::Thread &thread,
lldb::addr_t sp,
lldb::addr_t functionAddress,
lldb::addr_t returnAddress,
@@ -38,19 +177,28 @@ public:
lldb::addr_t *cmd_arg) const;
virtual bool
- PrepareNormalCall (Thread &thread,
+ PrepareNormalCall (lldb_private::Thread &thread,
lldb::addr_t sp,
lldb::addr_t functionAddress,
lldb::addr_t returnAddress,
- ValueList &args) const;
+ lldb_private::ValueList &args) const;
+
+ virtual bool
+ GetArgumentValues (lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const;
virtual bool
- GetArgumentValues (Thread &thread,
- ValueList &values) const;
+ GetReturnValue (lldb_private::Thread &thread,
+ lldb_private::Value &value) const;
virtual bool
- GetReturnValue (Thread &thread,
- Value &value) const;
+ CreateFunctionEntryUnwindPlan (lldb_private::UnwindPlan &unwind_plan);
+
+ virtual bool
+ CreateDefaultUnwindPlan (lldb_private::UnwindPlan &unwind_plan);
+
+ virtual bool
+ RegisterIsVolatile (const lldb_private::RegisterInfo *reg_info);
//------------------------------------------------------------------
// Static Functions
@@ -61,8 +209,8 @@ public:
static void
Terminate();
- static lldb_private::ABI *
- CreateInstance (const ArchSpec &arch);
+ static lldb::ABISP
+ CreateInstance (const lldb_private::ArchSpec &arch);
//------------------------------------------------------------------
// PluginInterface protocol
@@ -77,10 +225,12 @@ public:
GetPluginVersion();
protected:
+
+ bool
+ RegisterIsCalleeSaved (const lldb_private::RegisterInfo *reg_info);
+
private:
ABISysV_x86_64() : lldb_private::ABI() { } // Call CreateInstance instead.
};
-} // namespace lldb_private
-
#endif // liblldb_ABI_h_
OpenPOWER on IntegriCloud