forked from OSchip/llvm-project
Changed the ABIs and ClangFunction to take a
llvm::ArrayRef of arguments rather than taking a fixed number of possibly-NULL pointers to arguments. Also changed ClangFunction::GetThreadPlanToCallFunction to take the address of the argument struct by value instead of by reference, since it doesn't actually modify the value passed into it. llvm-svn: 194232
This commit is contained in:
parent
949ec546c4
commit
a464f3d43a
|
@ -270,8 +270,8 @@ public:
|
|||
/// @param[in] func_addr
|
||||
/// The address of the function in the target process.
|
||||
///
|
||||
/// @param[in] args_addr_ref
|
||||
/// The value of the void* parameter.
|
||||
/// @param[in] args_addr
|
||||
/// The address of the argument struct.
|
||||
///
|
||||
/// @param[in] errors
|
||||
/// The stream to write errors to.
|
||||
|
@ -287,7 +287,7 @@ public:
|
|||
//------------------------------------------------------------------
|
||||
ThreadPlan *
|
||||
GetThreadPlanToCallFunction (ExecutionContext &exe_ctx,
|
||||
lldb::addr_t &args_addr_ref,
|
||||
lldb::addr_t args_addr,
|
||||
const EvaluateExpressionOptions &options,
|
||||
Stream &errors);
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "lldb/Core/PluginInterface.h"
|
||||
#include "lldb/lldb-private.h"
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class ABI :
|
||||
|
@ -35,12 +37,7 @@ public:
|
|||
lldb::addr_t sp,
|
||||
lldb::addr_t functionAddress,
|
||||
lldb::addr_t returnAddress,
|
||||
lldb::addr_t *arg1_ptr = NULL,
|
||||
lldb::addr_t *arg2_ptr = NULL,
|
||||
lldb::addr_t *arg3_ptr = NULL,
|
||||
lldb::addr_t *arg4_ptr = NULL,
|
||||
lldb::addr_t *arg5_ptr = NULL,
|
||||
lldb::addr_t *arg6_ptr = NULL) const = 0;
|
||||
llvm::ArrayRef<lldb::addr_t> args) const = 0;
|
||||
|
||||
virtual bool
|
||||
GetArgumentValues (Thread &thread,
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "lldb/Target/Thread.h"
|
||||
#include "lldb/Target/ThreadPlan.h"
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class ThreadPlanCallFunction : public ThreadPlan
|
||||
|
@ -29,21 +31,8 @@ public:
|
|||
ThreadPlanCallFunction (Thread &thread,
|
||||
const Address &function,
|
||||
const ClangASTType &return_type,
|
||||
lldb::addr_t arg,
|
||||
const EvaluateExpressionOptions &options,
|
||||
lldb::addr_t *this_arg = 0,
|
||||
lldb::addr_t *cmd_arg = 0);
|
||||
|
||||
ThreadPlanCallFunction (Thread &thread,
|
||||
const Address &function,
|
||||
const ClangASTType &return_type,
|
||||
const EvaluateExpressionOptions &options,
|
||||
lldb::addr_t *arg1_ptr = NULL,
|
||||
lldb::addr_t *arg2_ptr = NULL,
|
||||
lldb::addr_t *arg3_ptr = NULL,
|
||||
lldb::addr_t *arg4_ptr = NULL,
|
||||
lldb::addr_t *arg5_ptr = NULL,
|
||||
lldb::addr_t *arg6_ptr = NULL);
|
||||
llvm::ArrayRef<lldb::addr_t> args,
|
||||
const EvaluateExpressionOptions &options);
|
||||
|
||||
virtual
|
||||
~ThreadPlanCallFunction ();
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "lldb/Target/ThreadPlan.h"
|
||||
#include "lldb/Target/ThreadPlanCallFunction.h"
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class ThreadPlanCallUserExpression : public ThreadPlanCallFunction
|
||||
|
@ -27,10 +29,8 @@ class ThreadPlanCallUserExpression : public ThreadPlanCallFunction
|
|||
public:
|
||||
ThreadPlanCallUserExpression (Thread &thread,
|
||||
Address &function,
|
||||
lldb::addr_t arg,
|
||||
llvm::ArrayRef<lldb::addr_t> args,
|
||||
const EvaluateExpressionOptions &options,
|
||||
lldb::addr_t *this_arg,
|
||||
lldb::addr_t *cmd_arg,
|
||||
ClangUserExpression::ClangUserExpressionSP &user_expression_sp);
|
||||
|
||||
virtual
|
||||
|
|
|
@ -394,7 +394,7 @@ ClangFunction::InsertFunction (ExecutionContext &exe_ctx, lldb::addr_t &args_add
|
|||
|
||||
ThreadPlan *
|
||||
ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx,
|
||||
lldb::addr_t &args_addr,
|
||||
lldb::addr_t args_addr,
|
||||
const EvaluateExpressionOptions &options,
|
||||
Stream &errors)
|
||||
{
|
||||
|
@ -414,13 +414,14 @@ ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx,
|
|||
// Okay, now run the function:
|
||||
|
||||
Address wrapper_address (m_jit_start_addr);
|
||||
|
||||
lldb::addr_t args = { args_addr };
|
||||
|
||||
ThreadPlan *new_plan = new ThreadPlanCallFunction (*thread,
|
||||
wrapper_address,
|
||||
ClangASTType(),
|
||||
args_addr,
|
||||
options,
|
||||
0,
|
||||
0);
|
||||
args,
|
||||
options);
|
||||
new_plan->SetIsMasterPlan(true);
|
||||
new_plan->SetOkayToDiscard (false);
|
||||
return new_plan;
|
||||
|
|
|
@ -824,12 +824,21 @@ ClangUserExpression::Execute (Stream &error_stream,
|
|||
else
|
||||
{
|
||||
Address wrapper_address (m_jit_start_addr);
|
||||
|
||||
llvm::SmallVector <lldb::addr_t, 3> args;
|
||||
|
||||
if (m_needs_object_ptr) {
|
||||
args.push_back(object_ptr);
|
||||
if (m_objectivec)
|
||||
args.push_back(cmd_ptr);
|
||||
}
|
||||
|
||||
args.push_back(struct_address);
|
||||
|
||||
lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
|
||||
wrapper_address,
|
||||
struct_address,
|
||||
args,
|
||||
options,
|
||||
(m_needs_object_ptr ? &object_ptr : NULL),
|
||||
((m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL),
|
||||
shared_ptr_to_me));
|
||||
|
||||
if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
|
||||
|
|
|
@ -198,12 +198,7 @@ ABIMacOSX_arm::PrepareTrivialCall (Thread &thread,
|
|||
addr_t sp,
|
||||
addr_t function_addr,
|
||||
addr_t return_addr,
|
||||
addr_t *arg1_ptr,
|
||||
addr_t *arg2_ptr,
|
||||
addr_t *arg3_ptr,
|
||||
addr_t *arg4_ptr,
|
||||
addr_t *arg5_ptr,
|
||||
addr_t *arg6_ptr) const
|
||||
llvm::ArrayRef<addr_t> args) const
|
||||
{
|
||||
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
|
||||
if (!reg_ctx)
|
||||
|
@ -215,50 +210,45 @@ ABIMacOSX_arm::PrepareTrivialCall (Thread &thread,
|
|||
|
||||
RegisterValue reg_value;
|
||||
|
||||
if (arg1_ptr)
|
||||
const char *reg_names[] = { "r0", "r1", "r2", "r3" };
|
||||
|
||||
llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
|
||||
|
||||
for (size_t i = 0; i < (sizeof(reg_names) / sizeof(reg_names[0])); ++i)
|
||||
{
|
||||
reg_value.SetUInt32(*arg1_ptr);
|
||||
if (!reg_ctx->WriteRegister (reg_ctx->GetRegisterInfoByName("r0"), reg_value))
|
||||
if (ai == ae)
|
||||
break;
|
||||
|
||||
reg_value.SetUInt32(*ai);
|
||||
if (!reg_ctx->WriteRegister(reg_ctx->GetRegisterInfoByName(reg_names[i]), reg_value))
|
||||
return false;
|
||||
|
||||
if (arg2_ptr)
|
||||
|
||||
++ai;
|
||||
}
|
||||
|
||||
if (ai != ae)
|
||||
{
|
||||
// Spill onto the stack
|
||||
size_t num_stack_regs = ae - ai;
|
||||
|
||||
sp -= (num_stack_regs * 4);
|
||||
// Keep the stack 8 byte aligned, not that we need to
|
||||
sp &= ~(8ull-1ull);
|
||||
|
||||
// just using arg1 to get the right size
|
||||
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
|
||||
|
||||
addr_t arg_pos = sp;
|
||||
|
||||
for (; ai != ae; ++ai)
|
||||
{
|
||||
reg_value.SetUInt32(*arg2_ptr);
|
||||
if (!reg_ctx->WriteRegister (reg_ctx->GetRegisterInfoByName("r1"), reg_value))
|
||||
reg_value.SetUInt32(*ai);
|
||||
if (reg_ctx->WriteRegisterValueToMemory(reg_info, arg_pos, reg_info->byte_size, reg_value).Fail())
|
||||
return false;
|
||||
|
||||
if (arg3_ptr)
|
||||
{
|
||||
reg_value.SetUInt32(*arg3_ptr);
|
||||
if (!reg_ctx->WriteRegister (reg_ctx->GetRegisterInfoByName("r2"), reg_value))
|
||||
return false;
|
||||
if (arg4_ptr)
|
||||
{
|
||||
reg_value.SetUInt32(*arg4_ptr);
|
||||
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r3");
|
||||
if (!reg_ctx->WriteRegister (reg_info, reg_value))
|
||||
return false;
|
||||
if (arg5_ptr)
|
||||
{
|
||||
// Keep the stack 8 byte aligned, not that we need to
|
||||
sp -= 8;
|
||||
sp &= ~(8ull-1ull);
|
||||
reg_value.SetUInt32(*arg5_ptr);
|
||||
if (reg_ctx->WriteRegisterValueToMemory (reg_info, sp, reg_info->byte_size, reg_value).Fail())
|
||||
return false;
|
||||
if (arg6_ptr)
|
||||
{
|
||||
reg_value.SetUInt32(*arg6_ptr);
|
||||
if (reg_ctx->WriteRegisterValueToMemory (reg_info, sp + 4, reg_info->byte_size, reg_value).Fail())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
arg_pos += reg_info->byte_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TargetSP target_sp (thread.CalculateTarget());
|
||||
Address so_addr;
|
||||
|
||||
|
|
|
@ -30,12 +30,7 @@ public:
|
|||
lldb::addr_t sp,
|
||||
lldb::addr_t func_addr,
|
||||
lldb::addr_t returnAddress,
|
||||
lldb::addr_t *arg1_ptr = NULL,
|
||||
lldb::addr_t *arg2_ptr = NULL,
|
||||
lldb::addr_t *arg3_ptr = NULL,
|
||||
lldb::addr_t *arg4_ptr = NULL,
|
||||
lldb::addr_t *arg5_ptr = NULL,
|
||||
lldb::addr_t *arg6_ptr = NULL) const;
|
||||
llvm::ArrayRef<lldb::addr_t> args) const;
|
||||
|
||||
virtual bool
|
||||
GetArgumentValues (lldb_private::Thread &thread,
|
||||
|
|
|
@ -260,12 +260,7 @@ ABIMacOSX_i386::PrepareTrivialCall (Thread &thread,
|
|||
addr_t sp,
|
||||
addr_t func_addr,
|
||||
addr_t return_addr,
|
||||
addr_t *arg1_ptr,
|
||||
addr_t *arg2_ptr,
|
||||
addr_t *arg3_ptr,
|
||||
addr_t *arg4_ptr,
|
||||
addr_t *arg5_ptr,
|
||||
addr_t *arg6_ptr) const
|
||||
llvm::ArrayRef<addr_t> args) const
|
||||
{
|
||||
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
|
||||
if (!reg_ctx)
|
||||
|
@ -287,114 +282,25 @@ ABIMacOSX_i386::PrepareTrivialCall (Thread &thread,
|
|||
RegisterValue reg_value;
|
||||
|
||||
// Write any arguments onto the stack
|
||||
if (arg1_ptr)
|
||||
{
|
||||
sp -= 4;
|
||||
if (arg2_ptr)
|
||||
{
|
||||
sp -= 4;
|
||||
if (arg3_ptr)
|
||||
{
|
||||
sp -= 4;
|
||||
if (arg4_ptr)
|
||||
{
|
||||
sp -= 4;
|
||||
if (arg5_ptr)
|
||||
{
|
||||
sp -= 4;
|
||||
if (arg6_ptr)
|
||||
{
|
||||
sp -= 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sp -= 4 * args.size();
|
||||
|
||||
// Align the SP
|
||||
sp &= ~(16ull-1ull); // 16-byte alignment
|
||||
|
||||
if (arg1_ptr)
|
||||
addr_t arg_pos = sp;
|
||||
|
||||
for (addr_t arg : args)
|
||||
{
|
||||
reg_value.SetUInt32(*arg1_ptr);
|
||||
error = reg_ctx->WriteRegisterValueToMemory (reg_info_32,
|
||||
sp,
|
||||
reg_info_32->byte_size,
|
||||
reg_value.SetUInt32(arg);
|
||||
error = reg_ctx->WriteRegisterValueToMemory (reg_info_32,
|
||||
arg_pos,
|
||||
reg_info_32->byte_size,
|
||||
reg_value);
|
||||
if (error.Fail())
|
||||
return false;
|
||||
|
||||
if (arg2_ptr)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
if (arg4_ptr)
|
||||
{
|
||||
reg_value.SetUInt32(*arg4_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 + 12,
|
||||
reg_info_32->byte_size,
|
||||
reg_value);
|
||||
if (error.Fail())
|
||||
return false;
|
||||
if (arg5_ptr)
|
||||
{
|
||||
reg_value.SetUInt32(*arg5_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 + 16,
|
||||
reg_info_32->byte_size,
|
||||
reg_value);
|
||||
if (error.Fail())
|
||||
return false;
|
||||
if (arg6_ptr)
|
||||
{
|
||||
reg_value.SetUInt32(*arg6_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 + 20,
|
||||
reg_info_32->byte_size,
|
||||
reg_value);
|
||||
if (error.Fail())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
arg_pos += 4;
|
||||
}
|
||||
|
||||
|
||||
// The return address is pushed onto the stack (yes after we just set the
|
||||
// alignment above!).
|
||||
sp -= 4;
|
||||
|
|
|
@ -33,12 +33,7 @@ public:
|
|||
lldb::addr_t sp,
|
||||
lldb::addr_t func_addr,
|
||||
lldb::addr_t return_addr,
|
||||
lldb::addr_t *arg1_ptr = NULL,
|
||||
lldb::addr_t *arg2_ptr = NULL,
|
||||
lldb::addr_t *arg3_ptr = NULL,
|
||||
lldb::addr_t *arg4_ptr = NULL,
|
||||
lldb::addr_t *arg5_ptr = NULL,
|
||||
lldb::addr_t *arg6_ptr = NULL) const;
|
||||
llvm::ArrayRef<lldb::addr_t> args) const;
|
||||
|
||||
virtual bool
|
||||
PrepareNormalCall (lldb_private::Thread &thread,
|
||||
|
|
|
@ -303,12 +303,7 @@ ABISysV_x86_64::PrepareTrivialCall (Thread &thread,
|
|||
addr_t sp,
|
||||
addr_t func_addr,
|
||||
addr_t return_addr,
|
||||
addr_t *arg1_ptr,
|
||||
addr_t *arg2_ptr,
|
||||
addr_t *arg3_ptr,
|
||||
addr_t *arg4_ptr,
|
||||
addr_t *arg5_ptr,
|
||||
addr_t *arg6_ptr) const
|
||||
llvm::ArrayRef<addr_t> args) const
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
|
||||
|
||||
|
@ -321,28 +316,8 @@ ABISysV_x86_64::PrepareTrivialCall (Thread &thread,
|
|||
(uint64_t)func_addr,
|
||||
(uint64_t)return_addr);
|
||||
|
||||
if (arg1_ptr)
|
||||
{
|
||||
s.Printf (", arg1 = 0x%" PRIx64, (uint64_t)*arg1_ptr);
|
||||
if (arg2_ptr)
|
||||
{
|
||||
s.Printf (", arg2 = 0x%" PRIx64, (uint64_t)*arg2_ptr);
|
||||
if (arg3_ptr)
|
||||
{
|
||||
s.Printf (", arg3 = 0x%" PRIx64, (uint64_t)*arg3_ptr);
|
||||
if (arg4_ptr)
|
||||
{
|
||||
s.Printf (", arg4 = 0x%" PRIx64, (uint64_t)*arg4_ptr);
|
||||
if (arg5_ptr)
|
||||
{
|
||||
s.Printf (", arg5 = 0x%" PRIx64, (uint64_t)*arg5_ptr);
|
||||
if (arg6_ptr)
|
||||
s.Printf (", arg6 = 0x%" PRIx64, (uint64_t)*arg6_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < args.size(); ++i)
|
||||
s.Printf (", arg%d = 0x%" PRIx64, i + 1, args[i]);
|
||||
s.PutCString (")");
|
||||
log->PutCString(s.GetString().c_str());
|
||||
}
|
||||
|
@ -352,62 +327,19 @@ ABISysV_x86_64::PrepareTrivialCall (Thread &thread,
|
|||
return false;
|
||||
|
||||
const RegisterInfo *reg_info = NULL;
|
||||
if (arg1_ptr)
|
||||
|
||||
if (args.size() > 6) // TODO handle more than 6 arguments
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < args.size(); ++i)
|
||||
{
|
||||
reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
|
||||
reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
|
||||
if (log)
|
||||
log->Printf("About to write arg1 (0x%" PRIx64 ") into %s", (uint64_t)*arg1_ptr, reg_info->name);
|
||||
|
||||
if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg1_ptr))
|
||||
log->Printf("About to write arg%d (0x%" PRIx64 ") into %s", i + 1, args[i], reg_info->name);
|
||||
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
|
||||
return false;
|
||||
|
||||
if (arg2_ptr)
|
||||
{
|
||||
reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
|
||||
if (log)
|
||||
log->Printf("About to write arg2 (0x%" PRIx64 ") into %s", (uint64_t)*arg2_ptr, reg_info->name);
|
||||
if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg2_ptr))
|
||||
return false;
|
||||
|
||||
if (arg3_ptr)
|
||||
{
|
||||
reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3);
|
||||
if (log)
|
||||
log->Printf("About to write arg3 (0x%" PRIx64 ") into %s", (uint64_t)*arg3_ptr, reg_info->name);
|
||||
if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg3_ptr))
|
||||
return false;
|
||||
|
||||
if (arg4_ptr)
|
||||
{
|
||||
reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4);
|
||||
if (log)
|
||||
log->Printf("About to write arg4 (0x%" PRIx64 ") into %s", (uint64_t)*arg4_ptr, reg_info->name);
|
||||
if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg4_ptr))
|
||||
return false;
|
||||
|
||||
if (arg5_ptr)
|
||||
{
|
||||
reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5);
|
||||
if (log)
|
||||
log->Printf("About to write arg5 (0x%" PRIx64 ") into %s", (uint64_t)*arg5_ptr, reg_info->name);
|
||||
if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg5_ptr))
|
||||
return false;
|
||||
|
||||
if (arg6_ptr)
|
||||
{
|
||||
reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6);
|
||||
if (log)
|
||||
log->Printf("About to write arg6 (0x%" PRIx64 ") into %s", (uint64_t)*arg6_ptr, reg_info->name);
|
||||
if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg6_ptr))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// First, align the SP
|
||||
|
||||
if (log)
|
||||
|
|
|
@ -34,12 +34,7 @@ public:
|
|||
lldb::addr_t sp,
|
||||
lldb::addr_t functionAddress,
|
||||
lldb::addr_t returnAddress,
|
||||
lldb::addr_t *arg1_ptr = NULL,
|
||||
lldb::addr_t *arg2_ptr = NULL,
|
||||
lldb::addr_t *arg3_ptr = NULL,
|
||||
lldb::addr_t *arg4_ptr = NULL,
|
||||
lldb::addr_t *arg5_ptr = NULL,
|
||||
lldb::addr_t *arg6_ptr = NULL) const;
|
||||
llvm::ArrayRef<lldb::addr_t> args) const;
|
||||
|
||||
virtual bool
|
||||
GetArgumentValues (lldb_private::Thread &thread,
|
||||
|
|
|
@ -90,17 +90,13 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
|
|||
{
|
||||
ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
|
||||
ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
|
||||
lldb::addr_t args[] = { addr, length, prot_arg, flags_arg, fd, offset };
|
||||
ThreadPlanCallFunction *call_function_thread_plan
|
||||
= new ThreadPlanCallFunction (*thread,
|
||||
mmap_range.GetBaseAddress(),
|
||||
clang_void_ptr_type,
|
||||
options,
|
||||
&addr,
|
||||
&length,
|
||||
&prot_arg,
|
||||
&flags_arg,
|
||||
&fd,
|
||||
&offset);
|
||||
args,
|
||||
options);
|
||||
lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
|
||||
if (call_plan_sp)
|
||||
{
|
||||
|
@ -178,12 +174,12 @@ bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
|
|||
AddressRange munmap_range;
|
||||
if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range))
|
||||
{
|
||||
lldb::addr_t args[] = { addr, length };
|
||||
lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
|
||||
munmap_range.GetBaseAddress(),
|
||||
ClangASTType(),
|
||||
options,
|
||||
&addr,
|
||||
&length));
|
||||
args,
|
||||
options));
|
||||
if (call_plan_sp)
|
||||
{
|
||||
StreamFile error_strm;
|
||||
|
@ -232,6 +228,7 @@ bool lldb_private::InferiorCall(Process *process, const Address *address, addr_t
|
|||
= new ThreadPlanCallFunction (*thread,
|
||||
*address,
|
||||
clang_void_ptr_type,
|
||||
llvm::ArrayRef<addr_t>(),
|
||||
options);
|
||||
lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
|
||||
if (call_plan_sp)
|
||||
|
|
|
@ -126,10 +126,8 @@ ThreadPlanCallFunction::ConstructorSetup (Thread &thread,
|
|||
ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
|
||||
const Address &function,
|
||||
const ClangASTType &return_type,
|
||||
addr_t arg,
|
||||
const EvaluateExpressionOptions &options,
|
||||
addr_t *this_arg,
|
||||
addr_t *cmd_arg) :
|
||||
llvm::ArrayRef<addr_t> args,
|
||||
const EvaluateExpressionOptions &options) :
|
||||
ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
|
||||
m_valid (false),
|
||||
m_stop_other_threads (options.GetStopOthers()),
|
||||
|
@ -150,87 +148,14 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
|
|||
lldb::addr_t function_load_addr;
|
||||
if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr))
|
||||
return;
|
||||
|
||||
if (this_arg && cmd_arg)
|
||||
{
|
||||
if (!abi->PrepareTrivialCall (thread,
|
||||
m_function_sp,
|
||||
function_load_addr,
|
||||
start_load_addr,
|
||||
this_arg,
|
||||
cmd_arg,
|
||||
&arg))
|
||||
return;
|
||||
}
|
||||
else if (this_arg)
|
||||
{
|
||||
if (!abi->PrepareTrivialCall (thread,
|
||||
m_function_sp,
|
||||
function_load_addr,
|
||||
start_load_addr,
|
||||
this_arg,
|
||||
&arg))
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!abi->PrepareTrivialCall (thread,
|
||||
m_function_sp,
|
||||
function_load_addr,
|
||||
start_load_addr,
|
||||
&arg))
|
||||
return;
|
||||
}
|
||||
|
||||
ReportRegisterState ("Function call was set up. Register state was:");
|
||||
|
||||
m_valid = true;
|
||||
}
|
||||
|
||||
|
||||
ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
|
||||
const Address &function,
|
||||
const ClangASTType &return_type,
|
||||
const EvaluateExpressionOptions &options,
|
||||
addr_t *arg1_ptr,
|
||||
addr_t *arg2_ptr,
|
||||
addr_t *arg3_ptr,
|
||||
addr_t *arg4_ptr,
|
||||
addr_t *arg5_ptr,
|
||||
addr_t *arg6_ptr) :
|
||||
ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
|
||||
m_valid (false),
|
||||
m_stop_other_threads (options.GetStopOthers()),
|
||||
m_unwind_on_error (options.DoesUnwindOnError()),
|
||||
m_ignore_breakpoints (options.DoesIgnoreBreakpoints()),
|
||||
m_debug_execution (options.GetDebug()),
|
||||
m_trap_exceptions (options.GetTrapExceptions()),
|
||||
m_function_addr (function),
|
||||
m_function_sp (0),
|
||||
m_return_type (return_type),
|
||||
m_takedown_done (false),
|
||||
m_stop_address (LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
lldb::addr_t start_load_addr;
|
||||
ABI *abi;
|
||||
lldb::addr_t function_load_addr;
|
||||
if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr))
|
||||
if (!abi->PrepareTrivialCall(thread,
|
||||
m_function_sp,
|
||||
function_load_addr,
|
||||
start_load_addr,
|
||||
args))
|
||||
return;
|
||||
|
||||
if (!abi->PrepareTrivialCall (thread,
|
||||
m_function_sp,
|
||||
function_load_addr,
|
||||
start_load_addr,
|
||||
arg1_ptr,
|
||||
arg2_ptr,
|
||||
arg3_ptr,
|
||||
arg4_ptr,
|
||||
arg5_ptr,
|
||||
arg6_ptr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ReportRegisterState ("Function call was set up. Register state was:");
|
||||
|
||||
m_valid = true;
|
||||
|
|
|
@ -38,12 +38,10 @@ using namespace lldb_private;
|
|||
|
||||
ThreadPlanCallUserExpression::ThreadPlanCallUserExpression (Thread &thread,
|
||||
Address &function,
|
||||
lldb::addr_t arg,
|
||||
llvm::ArrayRef<lldb::addr_t> args,
|
||||
const EvaluateExpressionOptions &options,
|
||||
lldb::addr_t *this_arg,
|
||||
lldb::addr_t *cmd_arg,
|
||||
ClangUserExpression::ClangUserExpressionSP &user_expression_sp) :
|
||||
ThreadPlanCallFunction (thread, function, ClangASTType(), arg, options, this_arg, cmd_arg),
|
||||
ThreadPlanCallFunction (thread, function, ClangASTType(), args, options),
|
||||
m_user_expression_sp (user_expression_sp)
|
||||
{
|
||||
// User expressions are generally "User generated" so we should set them up to stop when done.
|
||||
|
|
Loading…
Reference in New Issue