本文整理汇总了C++中Thread::GetRegisterContext方法的典型用法代码示例。如果您正苦于以下问题:C++ Thread::GetRegisterContext方法的具体用法?C++ Thread::GetRegisterContext怎么用?C++ Thread::GetRegisterContext使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Thread
的用法示例。
在下文中一共展示了Thread::GetRegisterContext方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: exe_ctx
ValueObjectSP ABISysV_s390x::GetReturnValueObjectImpl(
Thread &thread, CompilerType &return_compiler_type) const {
ValueObjectSP return_valobj_sp;
if (!return_compiler_type)
return return_valobj_sp;
ExecutionContext exe_ctx(thread.shared_from_this());
return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
if (return_valobj_sp)
return return_valobj_sp;
RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
if (!reg_ctx_sp)
return return_valobj_sp;
if (return_compiler_type.IsAggregateType()) {
// FIXME: This is just taking a guess, r2 may very well no longer hold the
// return storage location.
// If we are going to do this right, when we make a new frame we should
// check to see if it uses a memory return, and if we are at the first
// instruction and if so stash away the return location. Then we would
// only return the memory return value if we know it is valid.
unsigned r2_id =
reg_ctx_sp->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB];
lldb::addr_t storage_addr =
(uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_id, 0);
return_valobj_sp = ValueObjectMemory::Create(
&thread, "", Address(storage_addr, nullptr), return_compiler_type);
}
return return_valobj_sp;
}
示例2: exe_ctx
ValueObjectSP
ABISysV_i386::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_clang_type) const
{
ValueObjectSP return_valobj_sp;
if (!return_clang_type)
return return_valobj_sp;
ExecutionContext exe_ctx (thread.shared_from_this());
return_valobj_sp = GetReturnValueObjectSimple(thread, return_clang_type);
if (return_valobj_sp)
return return_valobj_sp;
RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
if (!reg_ctx_sp)
return return_valobj_sp;
if (return_clang_type.IsAggregateType())
{
unsigned eax_id = reg_ctx_sp->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
lldb::addr_t storage_addr = (uint32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff);
return_valobj_sp = ValueObjectMemory::Create (&thread,
"",
Address (storage_addr, nullptr),
return_clang_type);
}
return return_valobj_sp;
}
示例3: ReadIntegerArgument
static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
bool is_signed, Thread &thread,
uint32_t *argument_register_ids,
unsigned int ¤t_argument_register,
addr_t ¤t_stack_argument) {
if (bit_width > 64)
return false; // Scalar can't hold large integer arguments
if (current_argument_register < 6) {
scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
argument_register_ids[current_argument_register], 0);
current_argument_register++;
if (is_signed)
scalar.SignExtend(bit_width);
} else {
uint32_t byte_size = (bit_width + (8 - 1)) / 8;
Status error;
if (thread.GetProcess()->ReadScalarIntegerFromMemory(
current_stack_argument, byte_size, is_signed, scalar, error)) {
current_stack_argument += byte_size;
return true;
}
return false;
}
return true;
}
示例4: compiler_type
bool
ABIMacOSX_i386::GetArgumentValues (Thread &thread,
ValueList &values) const
{
unsigned int num_values = values.GetSize();
unsigned int value_index;
// 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?
CompilerType compiler_type (value->GetCompilerType());
if (compiler_type)
{
bool is_signed;
if (compiler_type.IsIntegerType (is_signed))
{
ReadIntegerArgument(value->GetScalar(),
compiler_type.GetBitSize(&thread),
is_signed,
thread.GetProcess().get(),
current_stack_argument);
}
else if (compiler_type.IsPointerType())
{
ReadIntegerArgument(value->GetScalar(),
compiler_type.GetBitSize(&thread),
false,
thread.GetProcess().get(),
current_stack_argument);
}
}
}
return true;
}
示例5: Unwind
UnwindLibUnwind::UnwindLibUnwind (Thread &thread, unw_addr_space_t addr_space) :
Unwind (thread),
m_addr_space (addr_space),
m_cursors()
{
m_pc_regnum = thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
m_sp_regnum = thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
}
示例6: executableModuleSP
ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
Address &function,
ValueList &args,
bool stop_other_threads,
bool discard_on_error) :
ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
m_valid (false),
m_stop_other_threads (stop_other_threads),
m_arg_addr (0),
m_args (&args),
m_process (thread.GetProcess()),
m_thread (thread)
{
SetOkayToDiscard (discard_on_error);
Process& process = thread.GetProcess();
Target& target = process.GetTarget();
const ABI *abi = process.GetABI();
if(!abi)
return;
lldb::addr_t spBelowRedZone = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
SymbolContextList contexts;
SymbolContext context;
ModuleSP executableModuleSP (target.GetExecutableModule());
if (!executableModuleSP ||
!executableModuleSP->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
return;
contexts.GetContextAtIndex(0, context);
m_start_addr = context.symbol->GetValue();
lldb::addr_t StartLoadAddr = m_start_addr.GetLoadAddress(&process);
if(!thread.SaveFrameZeroState(m_register_backup))
return;
m_function_addr = function;
lldb::addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(&process);
if (!abi->PrepareNormalCall(thread,
spBelowRedZone,
FunctionLoadAddr,
StartLoadAddr,
*m_args))
return;
m_valid = true;
}
示例7: clang_type
bool
ABISysV_i386::GetArgumentValues (Thread &thread,
ValueList &values) const
{
unsigned int num_values = values.GetSize();
unsigned int value_index;
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
if (!reg_ctx)
return false;
// Get pointer to the first stack argument
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;
// Currently: Support for extracting values with Clang QualTypes only.
CompilerType clang_type (value->GetCompilerType());
if (clang_type)
{
bool is_signed;
if (clang_type.IsIntegerType (is_signed))
{
ReadIntegerArgument(value->GetScalar(),
clang_type.GetBitSize(&thread),
is_signed,
thread.GetProcess().get(),
current_stack_argument);
}
else if (clang_type.IsPointerType())
{
ReadIntegerArgument(value->GetScalar(),
clang_type.GetBitSize(&thread),
false,
thread.GetProcess().get(),
current_stack_argument);
}
}
}
return true;
}
示例8: process_sp
bool UnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly(
AddressRange &func, Thread &thread, UnwindPlan &unwind_plan) {
if (!func.GetBaseAddress().IsValid() || func.GetByteSize() == 0)
return false;
if (m_assembly_inspection_engine == nullptr)
return false;
ProcessSP process_sp(thread.GetProcess());
if (process_sp.get() == nullptr)
return false;
const bool prefer_file_cache = true;
std::vector<uint8_t> function_text(func.GetByteSize());
Status error;
if (process_sp->GetTarget().ReadMemory(
func.GetBaseAddress(), prefer_file_cache, function_text.data(),
func.GetByteSize(), error) == func.GetByteSize()) {
RegisterContextSP reg_ctx(thread.GetRegisterContext());
m_assembly_inspection_engine->Initialize(reg_ctx);
return m_assembly_inspection_engine->GetNonCallSiteUnwindPlanFromAssembly(
function_text.data(), func.GetByteSize(), func, unwind_plan);
}
return false;
}
示例9:
bool
ABISysV_i386::PrepareTrivialCall (Thread &thread,
addr_t sp,
addr_t func_addr,
addr_t return_addr,
llvm::ArrayRef<addr_t> args) const
{
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
if (!reg_ctx)
return false;
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);
// While using register info to write a register value to memory, the register info
// 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.
// "eax" is used here for this purpose.
const RegisterInfo *reg_info_32 = reg_ctx->GetRegisterInfoByName("eax");
if (!reg_info_32)
return false; // TODO this should actually never happen
Error error;
RegisterValue reg_value;
// Make room for the argument(s) on the stack
sp -= 4 * args.size();
// SP Alignment
sp &= ~(16ull-1ull); // 16-byte alignment
// Write arguments onto the stack
addr_t arg_pos = sp;
for (addr_t arg : args)
{
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;
arg_pos += 4;
}
// The return address is pushed onto the stack
sp -= 4;
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;
// Setting %esp to the actual stack value.
if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_num, sp))
return false;
// Setting %eip to the address of the called function.
if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_num, func_addr))
return false;
return true;
}
示例10: process_sp
//----------------------------------------------------------------------
// ThreadPlanCallFunction: Plan to call a single function
//----------------------------------------------------------------------
bool
ThreadPlanCallFunction::ConstructorSetup (Thread &thread,
ABI *& abi,
lldb::addr_t &start_load_addr,
lldb::addr_t &function_load_addr)
{
SetIsMasterPlan (true);
SetOkayToDiscard (false);
SetPrivate (true);
ProcessSP process_sp (thread.GetProcess());
if (!process_sp)
return false;
abi = process_sp->GetABI().get();
if (!abi)
return false;
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
SetBreakpoints();
m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
// If we can't read memory at the point of the process where we are planning to put our function, we're
// not going to get any further...
Error error;
process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error);
if (!error.Success())
{
m_constructor_errors.Printf ("Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".", m_function_sp);
if (log)
log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
return false;
}
Module *exe_module = GetTarget().GetExecutableModulePointer();
if (exe_module == NULL)
{
m_constructor_errors.Printf ("Can't execute code without an executable module.");
if (log)
log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
return false;
}
else
{
ObjectFile *objectFile = exe_module->GetObjectFile();
if (!objectFile)
{
m_constructor_errors.Printf ("Could not find object file for module \"%s\".",
exe_module->GetFileSpec().GetFilename().AsCString());
if (log)
log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
return false;
}
m_start_addr = objectFile->GetEntryPointAddress();
if (!m_start_addr.IsValid())
{
m_constructor_errors.Printf ("Could not find entry point address for executable module \"%s\".",
exe_module->GetFileSpec().GetFilename().AsCString());
if (log)
log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
return false;
}
}
start_load_addr = m_start_addr.GetLoadAddress (&GetTarget());
// Checkpoint the thread state so we can restore it later.
if (log && log->GetVerbose())
ReportRegisterState ("About to checkpoint thread before function call. Original register state was:");
if (!thread.CheckpointThreadState (m_stored_thread_state))
{
m_constructor_errors.Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state.");
if (log)
log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
return false;
}
function_load_addr = m_function_addr.GetLoadAddress (&GetTarget());
return true;
}
示例11: exe_ctx
ValueObjectSP ABISysV_ppc64::GetReturnValueObjectImpl(
Thread &thread, CompilerType &return_compiler_type) const {
ValueObjectSP return_valobj_sp;
if (!return_compiler_type)
return return_valobj_sp;
ExecutionContext exe_ctx(thread.shared_from_this());
return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
if (return_valobj_sp)
return return_valobj_sp;
RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
if (!reg_ctx_sp)
return return_valobj_sp;
const size_t bit_width = return_compiler_type.GetBitSize(&thread);
if (return_compiler_type.IsAggregateType()) {
Target *target = exe_ctx.GetTargetPtr();
bool is_memory = true;
if (bit_width <= 128) {
ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
DataBufferSP data_sp(new DataBufferHeap(16, 0));
DataExtractor return_ext(data_sp, target_byte_order,
target->GetArchitecture().GetAddressByteSize());
const RegisterInfo *r3_info = reg_ctx_sp->GetRegisterInfoByName("r3", 0);
const RegisterInfo *rdx_info =
reg_ctx_sp->GetRegisterInfoByName("rdx", 0);
RegisterValue r3_value, rdx_value;
reg_ctx_sp->ReadRegister(r3_info, r3_value);
reg_ctx_sp->ReadRegister(rdx_info, rdx_value);
DataExtractor r3_data, rdx_data;
r3_value.GetData(r3_data);
rdx_value.GetData(rdx_data);
uint32_t fp_bytes =
0; // Tracks how much of the xmm registers we've consumed so far
uint32_t integer_bytes =
0; // Tracks how much of the r3/rds registers we've consumed so far
const uint32_t num_children = return_compiler_type.GetNumFields();
// Since we are in the small struct regime, assume we are not in memory.
is_memory = false;
for (uint32_t idx = 0; idx < num_children; idx++) {
std::string name;
uint64_t field_bit_offset = 0;
bool is_signed;
bool is_complex;
uint32_t count;
CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
idx, name, &field_bit_offset, nullptr, nullptr);
const size_t field_bit_width = field_compiler_type.GetBitSize(&thread);
// If there are any unaligned fields, this is stored in memory.
if (field_bit_offset % field_bit_width != 0) {
is_memory = true;
break;
}
uint32_t field_byte_width = field_bit_width / 8;
uint32_t field_byte_offset = field_bit_offset / 8;
DataExtractor *copy_from_extractor = nullptr;
uint32_t copy_from_offset = 0;
if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
field_compiler_type.IsPointerType()) {
if (integer_bytes < 8) {
if (integer_bytes + field_byte_width <= 8) {
// This is in RAX, copy from register to our result structure:
copy_from_extractor = &r3_data;
copy_from_offset = integer_bytes;
integer_bytes += field_byte_width;
} else {
// The next field wouldn't fit in the remaining space, so we
// pushed it to rdx.
copy_from_extractor = &rdx_data;
copy_from_offset = 0;
integer_bytes = 8 + field_byte_width;
}
} else if (integer_bytes + field_byte_width <= 16) {
copy_from_extractor = &rdx_data;
copy_from_offset = integer_bytes - 8;
integer_bytes += field_byte_width;
} else {
// The last field didn't fit. I can't see how that would happen w/o
// the overall size being
// greater than 16 bytes. For now, return a nullptr return value
// object.
return return_valobj_sp;
}
} else if (field_compiler_type.IsFloatingPointType(count, is_complex)) {
// Structs with long doubles are always passed in memory.
//.........这里部分代码省略.........
示例12: sizeof
ValueObjectSP ABISysV_s390x::GetReturnValueObjectSimple(
Thread &thread, CompilerType &return_compiler_type) const {
ValueObjectSP return_valobj_sp;
Value value;
if (!return_compiler_type)
return return_valobj_sp;
// value.SetContext (Value::eContextTypeClangType, return_value_type);
value.SetCompilerType(return_compiler_type);
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
if (!reg_ctx)
return return_valobj_sp;
const uint32_t type_flags = return_compiler_type.GetTypeInfo();
if (type_flags & eTypeIsScalar) {
value.SetValueType(Value::eValueTypeScalar);
bool success = false;
if (type_flags & eTypeIsInteger) {
// Extract the register context so we can read arguments from registers.
llvm::Optional<uint64_t> byte_size =
return_compiler_type.GetByteSize(nullptr);
if (!byte_size)
return return_valobj_sp;
uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
reg_ctx->GetRegisterInfoByName("r2", 0), 0);
const bool is_signed = (type_flags & eTypeIsSigned) != 0;
switch (*byte_size) {
default:
break;
case sizeof(uint64_t):
if (is_signed)
value.GetScalar() = (int64_t)(raw_value);
else
value.GetScalar() = (uint64_t)(raw_value);
success = true;
break;
case sizeof(uint32_t):
if (is_signed)
value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
else
value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
success = true;
break;
case sizeof(uint16_t):
if (is_signed)
value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
else
value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
success = true;
break;
case sizeof(uint8_t):
if (is_signed)
value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
else
value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
success = true;
break;
}
} else if (type_flags & eTypeIsFloat) {
if (type_flags & eTypeIsComplex) {
// Don't handle complex yet.
} else {
llvm::Optional<uint64_t> byte_size =
return_compiler_type.GetByteSize(nullptr);
if (byte_size && *byte_size <= sizeof(long double)) {
const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
RegisterValue f0_value;
if (reg_ctx->ReadRegister(f0_info, f0_value)) {
DataExtractor data;
if (f0_value.GetData(data)) {
lldb::offset_t offset = 0;
if (*byte_size == sizeof(float)) {
value.GetScalar() = (float)data.GetFloat(&offset);
success = true;
} else if (*byte_size == sizeof(double)) {
value.GetScalar() = (double)data.GetDouble(&offset);
success = true;
} else if (*byte_size == sizeof(long double)) {
// Don't handle long double yet.
}
}
}
}
}
}
if (success)
return_valobj_sp = ValueObjectConstResult::Create(
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
} else if (type_flags & eTypeIsPointer) {
unsigned r2_id =
reg_ctx->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB];
value.GetScalar() =
//.........这里部分代码省略.........
示例13: isa_value
ThreadPlanSP
ObjCTrampolineHandler::GetStepThroughDispatchPlan (Thread &thread, bool stop_others)
{
ThreadPlanSP ret_plan_sp;
lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC();
MsgsendMap::iterator pos;
pos = m_msgSend_map.find (curr_pc);
if (pos != m_msgSend_map.end())
{
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
const DispatchFunction *this_dispatch = &g_dispatch_functions[(*pos).second];
lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
Process *process = thread.CalculateProcess();
const ABI *abi = process->GetABI();
if (abi == NULL)
return ret_plan_sp;
Target *target = thread.CalculateTarget();
// FIXME: Since neither the value nor the Clang QualType know their ASTContext,
// we have to make sure the type we put in our value list comes from the same ASTContext
// the ABI will use to get the argument values. THis is the bottom-most frame's module.
ClangASTContext *clang_ast_context = target->GetScratchClangASTContext();
ValueList argument_values;
Value input_value;
void *clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
input_value.SetValueType (Value::eValueTypeScalar);
input_value.SetContext (Value::eContextTypeOpaqueClangQualType, clang_void_ptr_type);
int obj_index;
int sel_index;
// If this is a struct return dispatch, then the first argument is the
// return struct pointer, and the object is the second, and the selector is the third.
// Otherwise the object is the first and the selector the second.
if (this_dispatch->stret_return)
{
obj_index = 1;
sel_index = 2;
argument_values.PushValue(input_value);
argument_values.PushValue(input_value);
argument_values.PushValue(input_value);
}
else
{
obj_index = 0;
sel_index = 1;
argument_values.PushValue(input_value);
argument_values.PushValue(input_value);
}
bool success = abi->GetArgumentValues (thread, argument_values);
if (!success)
return ret_plan_sp;
// Okay, the first value here is the object, we actually want the class of that object.
// For now we're just going with the ISA.
// FIXME: This should really be the return value of [object class] to properly handle KVO interposition.
Value isa_value(*(argument_values.GetValueAtIndex(obj_index)));
// This is a little cheesy, but since object->isa is the first field,
// making the object value a load address value and resolving it will get
// the pointer sized data pointed to by that value...
ExecutionContext exec_ctx;
thread.Calculate (exec_ctx);
isa_value.SetValueType(Value::eValueTypeLoadAddress);
isa_value.ResolveValue(&exec_ctx, clang_ast_context->getASTContext());
if (this_dispatch->fixedup == DispatchFunction::eFixUpFixed)
{
// For the FixedUp method the Selector is actually a pointer to a
// structure, the second field of which is the selector number.
Value *sel_value = argument_values.GetValueAtIndex(sel_index);
sel_value->GetScalar() += process->GetAddressByteSize();
sel_value->SetValueType(Value::eValueTypeLoadAddress);
sel_value->ResolveValue(&exec_ctx, clang_ast_context->getASTContext());
}
else if (this_dispatch->fixedup == DispatchFunction::eFixUpToFix)
{
// FIXME: If the method dispatch is not "fixed up" then the selector is actually a
// pointer to the string name of the selector. We need to look that up...
// For now I'm going to punt on that and just return no plan.
if (log)
log->Printf ("Punting on stepping into un-fixed-up method dispatch.");
return ret_plan_sp;
}
// FIXME: If this is a dispatch to the super-class, we need to get the super-class from
// the class, and disaptch to that instead.
// But for now I just punt and return no plan.
if (this_dispatch->is_super)
{
//.........这里部分代码省略.........
示例14:
bool
ABISysV_mips::PrepareTrivialCall (Thread &thread,
addr_t sp,
addr_t func_addr,
addr_t return_addr,
llvm::ArrayRef<addr_t> args) const
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
{
StreamString s;
s.Printf("ABISysV_mips::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
thread.GetID(),
(uint64_t)sp,
(uint64_t)func_addr,
(uint64_t)return_addr);
for (size_t i = 0; i < args.size(); ++i)
s.Printf (", arg%zd = 0x%" PRIx64, i + 1, args[i]);
s.PutCString (")");
log->PutCString(s.GetString().c_str());
}
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
if (!reg_ctx)
return false;
const RegisterInfo *reg_info = NULL;
RegisterValue reg_value;
// Argument registers
const char *reg_names[] = { "r4", "r5", "r6", "r7" };
llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
// Write arguments to registers
for (size_t i = 0; i < llvm::array_lengthof(reg_names); ++i)
{
if (ai == ae)
break;
reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
if (log)
log->Printf("About to write arg%zd (0x%" PRIx64 ") into %s", i + 1, args[i], reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
return false;
++ai;
}
// If we have more than 4 arguments --Spill onto the stack
if (ai != ae)
{
// No of arguments to go on stack
size_t num_stack_regs = args.size();
// Allocate needed space for args on the stack
sp -= (num_stack_regs * 4);
// Keep the stack 8 byte aligned
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+16;
size_t i = 4;
for (; ai != ae; ++ai)
{
reg_value.SetUInt32(*ai);
if (log)
log->Printf("About to write arg%zd (0x%" PRIx64 ") at 0x%" PRIx64 "", i+1, args[i], arg_pos);
if (reg_ctx->WriteRegisterValueToMemory(reg_info, arg_pos, reg_info->byte_size, reg_value).Fail())
return false;
arg_pos += reg_info->byte_size;
i++;
}
}
Error error;
const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
const RegisterInfo *ra_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
if (log)
log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
// Set "sp" to the requested value
if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_info, sp))
return false;
if (log)
log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
// Set "ra" to the return address
//.........这里部分代码省略.........
示例15: process_sp
bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp,
addr_t func_addr, addr_t return_addr,
llvm::ArrayRef<addr_t> args) const {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
if (log) {
StreamString s;
s.Printf("ABISysV_ppc64::PrepareTrivialCall (tid = 0x%" PRIx64
", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
", return_addr = 0x%" PRIx64,
thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
(uint64_t)return_addr);
for (size_t i = 0; i < args.size(); ++i)
s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
args[i]);
s.PutCString(")");
log->PutString(s.GetString());
}
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
if (!reg_ctx)
return false;
const RegisterInfo *reg_info = nullptr;
if (args.size() > 8) // TODO handle more than 8 arguments
return false;
for (size_t i = 0; i < args.size(); ++i) {
reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
LLDB_REGNUM_GENERIC_ARG1 + i);
if (log)
log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
static_cast<uint64_t>(i + 1), args[i], reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
return false;
}
// First, align the SP
if (log)
log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
(uint64_t)sp, (uint64_t)(sp & ~0xfull));
sp &= ~(0xfull); // 16-byte alignment
sp -= 8;
Status error;
const RegisterInfo *pc_reg_info =
reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
const RegisterInfo *sp_reg_info =
reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
ProcessSP process_sp(thread.GetProcess());
RegisterValue reg_value;
if (log)
log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
": 0x%" PRIx64,
(uint64_t)sp, (uint64_t)return_addr);
// Save return address onto the stack
if (!process_sp->WritePointerToMemory(sp, return_addr, error))
return false;
// %r1 is set to the actual stack value.
if (log)
log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
return false;
// %pc is set to the address of the called function.
if (log)
log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
return false;
return true;
}