diff options
-rw-r--r-- | lldb/include/lldb/Target/ABI.h | 6 | ||||
-rw-r--r-- | lldb/lldb.xcodeproj/project.pbxproj | 2 | ||||
-rw-r--r-- | lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp | 325 | ||||
-rw-r--r-- | lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h | 15 | ||||
-rw-r--r-- | lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp | 151 | ||||
-rw-r--r-- | lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h | 14 | ||||
-rw-r--r-- | lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp | 160 | ||||
-rw-r--r-- | lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h | 13 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanCallFunction.cpp | 41 |
9 files changed, 242 insertions, 485 deletions
diff --git a/lldb/include/lldb/Target/ABI.h b/lldb/include/lldb/Target/ABI.h index 3f3b75de1ba..1b744a7214d 100644 --- a/lldb/include/lldb/Target/ABI.h +++ b/lldb/include/lldb/Target/ABI.h @@ -34,9 +34,9 @@ public: 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 = 0; + lldb::addr_t *arg1_ptr, + lldb::addr_t *arg2_ptr, + lldb::addr_t *arg3_ptr) const = 0; virtual bool GetArgumentValues (Thread &thread, diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 517d56450b3..d4dc8c64382 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -2870,7 +2870,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "sh $SRCROOT/scripts/build-swig-wrapper-classes.sh $SRCROOT $TARGET_BUILD_DIR $CONFIGURATION_BUILD_DIR \"\"\n"; + shellScript = "$SRCROOT/scripts/build-swig-wrapper-classes.sh $SRCROOT $TARGET_BUILD_DIR $CONFIGURATION_BUILD_DIR \"\"\n"; }; 9A19ACE2116563A700E0D453 /* Finish swig wrapper classes (lldb) */ = { isa = PBXShellScriptBuildPhase; diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp index 0f9bab1fcec..ce9a9c3067d 100644 --- a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp +++ b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp @@ -13,6 +13,7 @@ #include "lldb/Core/Error.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" #include "lldb/Core/Value.h" #include "lldb/Symbol/ClangASTContext.h" @@ -62,280 +63,64 @@ ABIMacOSX_arm::CreateInstance (const ArchSpec &arch) 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 + addr_t function_addr, + addr_t return_addr, + lldb::addr_t *arg1_ptr, + lldb::addr_t *arg2_ptr, + lldb::addr_t *arg3_ptr) 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; -} + RegisterContext *reg_ctx = thread.GetRegisterContext().get(); + if (!reg_ctx) + 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; + const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); + const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); + + RegisterValue reg_value; + + if (arg1_ptr) + { + reg_value.SetUInt32(*arg1_ptr); + if (!reg_ctx->WriteRegister (reg_ctx->GetRegisterInfoByName("r0"), reg_value)) + return false; + } + + if (arg2_ptr) + { + assert (arg1_ptr != NULL); // Remove this after we know the assertion isn't firing (5/11/2011) + + reg_value.SetUInt32(*arg2_ptr); + if (!reg_ctx->WriteRegister (reg_ctx->GetRegisterInfoByName("r1"), reg_value)) + return false; + } + + if (arg3_ptr) + { + assert (arg1_ptr != NULL); // Remove this after we know the assertion isn't firing (5/11/2011) + assert (arg2_ptr != NULL); // Remove this after we know the assertion isn't firing (5/11/2011) + + reg_value.SetUInt32(*arg3_ptr); + if (!reg_ctx->WriteRegister (reg_ctx->GetRegisterInfoByName("r2"), reg_value)) + return false; + } + + // Set "lr" to the return address into "lr" + if (!reg_ctx->WriteRegisterFromUnsigned (ra_reg_num, return_addr)) + return false; + + // Set "sp" to the requested value + if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_num, sp)) + return false; + + // Set "pc" to the address requested + if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_num, function_addr)) + return false; + + return true; } + static bool ReadIntegerArgument (Scalar &scalar, unsigned int bit_width, diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h index d1d5dc4c4bc..d7a2f3ee66e 100644 --- a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h +++ b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h @@ -28,18 +28,11 @@ public: virtual bool PrepareTrivialCall (lldb_private::Thread &thread, lldb::addr_t sp, - lldb::addr_t functionAddress, + lldb::addr_t func_addr, 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; + lldb::addr_t *arg1_ptr, + lldb::addr_t *arg2_ptr, + lldb::addr_t *arg3_ptr) const; virtual bool GetArgumentValues (lldb_private::Thread &thread, diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp index 8c9df142890..609618bcf31 100644 --- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp +++ b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp @@ -13,6 +13,7 @@ #include "lldb/Core/Error.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/UnwindPlan.h" @@ -57,93 +58,105 @@ ABIMacOSX_i386::CreateInstance (const ArchSpec &arch) bool ABIMacOSX_i386::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 + lldb::addr_t func_addr, + lldb::addr_t return_addr, + lldb::addr_t *arg1_ptr, + lldb::addr_t *arg2_ptr, + lldb::addr_t *arg3_ptr) const +// lldb::addr_t arg, +// lldb::addr_t *this_arg, +// lldb::addr_t *cmd_arg) const { RegisterContext *reg_ctx = thread.GetRegisterContext().get(); if (!reg_ctx) return false; -#define CHAIN_EBP + uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); + + // When writing a register value down to memory, the register info used + // to write memory just needs to have the correct size of a 32 bit register, + // the actual register it pertains to is not important, just the size needs + // to be correct. Here we use "eax"... + const RegisterInfo *reg_info_32 = reg_ctx->GetRegisterInfoByName("eax"); -#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 + + Error error; + RegisterValue reg_value; - if (this_arg && cmd_arg) + // Write any arguments onto the stack + if (arg1_ptr && arg2_ptr && arg3_ptr) sp -= 12; - else if (this_arg) + else if (arg1_ptr && arg2_ptr) sp -= 8; - else + else if (arg1_ptr) sp -= 4; - - // Align the SP - + + // Align the SP sp &= ~(0xfull); // 16-byte alignment - // Write the argument on the stack - - Error error; - - if (this_arg && cmd_arg) + if (arg1_ptr) { - 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)) + reg_value.SetUInt32(*arg1_ptr); + error = reg_ctx->WriteRegisterValueToMemory (reg_info_32, + sp, + reg_info_32->byte_size, + reg_value); + if (error.Fail()) 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; + if (arg2_ptr) + { + assert (arg1_ptr != NULL); // Remove this after we know the assertion isn't firing (5/11/2011) + reg_value.SetUInt32(*arg2_ptr); + // The register info used to write memory just needs to have the correct + // size of a 32 bit register, the actual register it pertains to is not + // important, just the size needs to be correct. Here we use "eax"... + error = reg_ctx->WriteRegisterValueToMemory (reg_info_32, + sp + 4, + reg_info_32->byte_size, + reg_value); + if (error.Fail()) + return false; + + if (arg3_ptr) + { + assert (arg1_ptr != NULL); // Remove this after we know the assertion isn't firing (5/11/2011) + assert (arg2_ptr != NULL); // Remove this after we know the assertion isn't firing (5/11/2011) + reg_value.SetUInt32(*arg3_ptr); + // The register info used to write memory just needs to have the correct + // size of a 32 bit register, the actual register it pertains to is not + // important, just the size needs to be correct. Here we use "eax"... + error = reg_ctx->WriteRegisterValueToMemory (reg_info_32, + sp + 8, + reg_info_32->byte_size, + reg_value); + if (error.Fail()) + return false; + } + } } - // The return address is pushed onto the stack. + // The return address is pushed onto the stack (yes after we just set the + // alignment above!). sp -= 4; - uint32_t returnAddressU32 = returnAddress; - if (thread.GetProcess().WriteMemory (sp, &returnAddressU32, sizeof(returnAddressU32), error) != sizeof(returnAddressU32)) + reg_value.SetUInt32(return_addr); + error = reg_ctx->WriteRegisterValueToMemory (reg_info_32, + sp, + reg_info_32->byte_size, + reg_value); + if (error.Fail()) 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)) + if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_num, sp)) return false; -#endif // %eip is set to the address of the called function. - if (!reg_ctx->WriteRegisterFromUnsigned(eipID, functionAddress)) + if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_num, func_addr)) return false; return true; @@ -152,17 +165,17 @@ ABIMacOSX_i386::PrepareTrivialCall (Thread &thread, bool ABIMacOSX_i386::PrepareNormalCall (Thread &thread, lldb::addr_t sp, - lldb::addr_t functionAddress, - lldb::addr_t returnAddress, + lldb::addr_t func_addr, + lldb::addr_t return_addr, 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); + uint32_t fp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP); + uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); // Do the argument layout @@ -307,23 +320,23 @@ ABIMacOSX_i386::PrepareNormalCall (Thread &thread, // The return address is pushed onto the stack. sp -= 4; - uint32_t returnAddressU32 = returnAddress; + uint32_t returnAddressU32 = return_addr; 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)) + if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp)) return false; // %ebp is set to a fake value, in our case 0x0x00000000 - if (!reg_ctx->WriteRegisterFromUnsigned(ebpID, 0x00000000)) + if (!reg_ctx->WriteRegisterFromUnsigned(fp_reg_num, 0x00000000)) return false; // %eip is set to the address of the called function. - if (!reg_ctx->WriteRegisterFromUnsigned(eipID, functionAddress)) + if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, func_addr)) return false; return true; diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h index e50330fda76..5bc820620fc 100644 --- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h +++ b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h @@ -144,17 +144,17 @@ public: 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; + lldb::addr_t func_addr, + lldb::addr_t return_addr, + lldb::addr_t *arg1_ptr, + lldb::addr_t *arg2_ptr, + lldb::addr_t *arg3_ptr) const; virtual bool PrepareNormalCall (lldb_private::Thread &thread, lldb::addr_t sp, - lldb::addr_t functionAddress, - lldb::addr_t returnAddress, + lldb::addr_t func_addr, + lldb::addr_t return_addr, lldb_private::ValueList &args) const; virtual bool 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 3ee0562b7e8..a943bcd9d46 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 @@ -15,6 +15,7 @@ #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/UnwindPlan.h" @@ -60,116 +61,77 @@ ABISysV_x86_64::CreateInstance (const ArchSpec &arch) bool ABISysV_x86_64::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 + lldb::addr_t func_addr, + lldb::addr_t return_addr, + lldb::addr_t *arg1_ptr, + lldb::addr_t *arg2_ptr, + lldb::addr_t *arg3_ptr) const { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); if (log) - log->Printf("ABISysV_x86_64::PrepareTrivialCall\n(\n thread = %p\n sp = 0x%llx\n functionAddress = 0x%llx\n returnAddress = 0x%llx\n arg = 0x%llx\n this_arg = %p(0x%llx)\n cmd_arg = %p(0x%llx)\n)", + log->Printf("ABISysV_x86_64::PrepareTrivialCall\n(\n thread = %p\n sp = 0x%llx\n func_addr = 0x%llx\n return_addr = 0x%llx\n arg1_ptr = %p (0x%llx)\n arg2_ptr = %p (0x%llx)\n arg3_ptr = %p (0x%llx)\n)", (void*)&thread, (uint64_t)sp, - (uint64_t)functionAddress, - (uint64_t)returnAddress, - (void*)arg, - this_arg, - this_arg ? (uint64_t)*this_arg : (uint64_t)0, - cmd_arg, - cmd_arg ? (uint64_t)*cmd_arg : (uint64_t)0); + (uint64_t)func_addr, + (uint64_t)return_addr, + arg1_ptr, arg1_ptr ? (uint64_t)*arg1_ptr : (uint64_t) 0, + arg2_ptr, arg2_ptr ? (uint64_t)*arg2_ptr : (uint64_t) 0, + arg3_ptr, arg3_ptr ? (uint64_t)*arg3_ptr : (uint64_t) 0); RegisterContext *reg_ctx = thread.GetRegisterContext().get(); if (!reg_ctx) return false; - - uint32_t rdiID = reg_ctx->GetRegisterInfoByName("rdi", 0)->kinds[eRegisterKindLLDB]; -#define CHAIN_RBP - -#ifndef CHAIN_RBP - uint32_t rbpID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP); -#endif - - uint32_t ripID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); - uint32_t rspID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); - - // The argument is in %rdi, and not on the stack. - if (cmd_arg) - { - if (log) - log->PutCString("The trivial call has a self and a _cmd pointer"); - - uint32_t rsiID = reg_ctx->GetRegisterInfoByName("rsi", 0)->kinds[eRegisterKindLLDB]; - uint32_t rdxID = reg_ctx->GetRegisterInfoByName("rdx", 0)->kinds[eRegisterKindLLDB]; - - if (log) - log->Printf("About to write 'self' (0x%llx) into RDI", (uint64_t)*this_arg); - - if (!reg_ctx->WriteRegisterFromUnsigned(rdiID, *this_arg)) - return false; - - if (log) - log->Printf("About to write '_cmd' (0x%llx) into RSI", (uint64_t)*cmd_arg); - - if (!reg_ctx->WriteRegisterFromUnsigned(rsiID, *cmd_arg)) - return false; - - if (log) - log->Printf("About to write the argument (0x%llx) into RDX", (uint64_t)arg); - - if (!reg_ctx->WriteRegisterFromUnsigned(rdxID, arg)) - return false; - } - else if (this_arg) - { - if (log) - log->PutCString("The trivial call has a this pointer"); - - uint32_t rsiID = reg_ctx->GetRegisterInfoByName("rsi", 0)->kinds[eRegisterKindLLDB]; - - if (log) - log->Printf("About to write 'this' (0x%llx) into RDI", (uint64_t)*this_arg); - - if (!reg_ctx->WriteRegisterFromUnsigned(rdiID, *this_arg)) - return false; - - if (log) - log->Printf("About to write the argument (0x%llx) into RSI", (uint64_t)arg); - - if (!reg_ctx->WriteRegisterFromUnsigned(rsiID, arg)) - return false; - } - else + RegisterValue reg_value; + if (arg1_ptr) { if (log) - log->PutCString("The trivial call does not have a this pointer"); - - if (log) - log->Printf("About to write the argument (0x%llx) into RDI", (uint64_t)arg); - - if (!reg_ctx->WriteRegisterFromUnsigned(rdiID, arg)) + log->Printf("About to write arg1 (0x%llx) into RDI", (uint64_t)*arg1_ptr); + + reg_value.SetUInt64(*arg1_ptr); + if (!reg_ctx->WriteRegister(reg_ctx->GetRegisterInfoByName("rdi", 0), reg_value)) return false; + + if (arg2_ptr) + { + if (log) + log->Printf("About to write arg2 (0x%llx) into RSI", (uint64_t)*arg2_ptr); + + reg_value.SetUInt64(*arg2_ptr); + if (!reg_ctx->WriteRegister(reg_ctx->GetRegisterInfoByName("rsi", 0), reg_value)) + return false; + + if (arg3_ptr) + { + if (log) + log->Printf("About to write arg3 (0x%llx) into RDX", (uint64_t)*arg3_ptr); + reg_value.SetUInt64(*arg3_ptr); + if (!reg_ctx->WriteRegister(reg_ctx->GetRegisterInfoByName("rdx", 0), reg_value)) + return false; + } + } } + // First, align the SP - + if (log) log->Printf("16-byte aligning SP: 0x%llx to 0x%llx", (uint64_t)sp, (uint64_t)(sp & ~0xfull)); sp &= ~(0xfull); // 16-byte alignment - // The return address is pushed onto the stack. - + // The return address is pushed onto the stack (yes after the alignment...) sp -= 8; - uint64_t returnAddressU64 = returnAddress; - Error error; - + + reg_value.SetUInt64 (return_addr); + if (log) - log->Printf("Pushing the return address onto the stack: new SP 0x%llx, return address 0x%llx", (uint64_t)sp, (uint64_t)returnAddressU64); - - if (thread.GetProcess().WriteMemory (sp, &returnAddressU64, sizeof(returnAddressU64), error) != sizeof(returnAddressU64)) + log->Printf("Pushing the return address onto the stack: new SP 0x%llx, return address 0x%llx", (uint64_t)sp, (uint64_t)return_addr); + + const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfoByName("rip"); + Error error (reg_ctx->WriteRegisterValueToMemory(pc_reg_info, sp, pc_reg_info->byte_size, reg_value)); + if (error.Fail()) return false; // %rsp is set to the actual stack value. @@ -177,37 +139,23 @@ ABISysV_x86_64::PrepareTrivialCall (Thread &thread, if (log) log->Printf("Writing SP (0x%llx) down", (uint64_t)sp); - if (!reg_ctx->WriteRegisterFromUnsigned(rspID, sp)) + reg_value.SetUInt64(sp); + if (!reg_ctx->WriteRegister (reg_ctx->GetRegisterInfoByName("rsp"), reg_value)) return false; -#ifndef CHAIN_RBP - // %rbp is set to a fake value, in our case 0x0000000000000000. - - if (!reg_ctx->WriteRegisterFromUnsigned(rbpID, 0x000000000000000)) - return false; -#endif - // %rip is set to the address of the called function. if (log) - log->Printf("Writing new IP (0x%llx) down", (uint64_t)functionAddress); + log->Printf("Writing new IP (0x%llx) down", (uint64_t)func_addr); - if (!reg_ctx->WriteRegisterFromUnsigned(ripID, functionAddress)) + reg_value.SetUInt64(func_addr); + + if (!reg_ctx->WriteRegister(pc_reg_info, func_addr)) return false; return true; } -bool -ABISysV_x86_64::PrepareNormalCall (Thread &thread, - lldb::addr_t sp, - lldb::addr_t functionAddress, - lldb::addr_t returnAddress, - ValueList &args) const -{ - return false; -} - static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, bool is_signed, 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 e1ac132da8d..d47cbf8381f 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 @@ -172,16 +172,9 @@ public: 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; + lldb::addr_t *arg1_ptr, + lldb::addr_t *arg2_ptr, + lldb::addr_t *arg3_ptr) const; virtual bool GetArgumentValues (lldb_private::Thread &thread, diff --git a/lldb/source/Target/ThreadPlanCallFunction.cpp b/lldb/source/Target/ThreadPlanCallFunction.cpp index 934ac00df56..1da0e7b7945 100644 --- a/lldb/source/Target/ThreadPlanCallFunction.cpp +++ b/lldb/source/Target/ThreadPlanCallFunction.cpp @@ -110,14 +110,39 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, m_function_addr = function; lldb::addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(&target); - if (!abi->PrepareTrivialCall(thread, - m_function_sp, - FunctionLoadAddr, - StartLoadAddr, - m_arg_addr, - this_arg, - cmd_arg)) - return; + if (this_arg && cmd_arg) + { + if (!abi->PrepareTrivialCall (thread, + m_function_sp, + FunctionLoadAddr, + StartLoadAddr, + this_arg, + cmd_arg, + &m_arg_addr)) + return; + } + else if (this_arg) + { + if (!abi->PrepareTrivialCall (thread, + m_function_sp, + FunctionLoadAddr, + StartLoadAddr, + this_arg, + &m_arg_addr, + NULL)) + return; + } + else + { + if (!abi->PrepareTrivialCall (thread, + m_function_sp, + FunctionLoadAddr, + StartLoadAddr, + &m_arg_addr, + NULL, + NULL)) + return; + } ReportRegisterState ("Function call was set up. Register state was:"); |