bool RegisterContext::SetPC(Address addr) { TargetSP target_sp = m_thread.CalculateTarget(); Target *target = target_sp.get(); lldb::addr_t callAddr = addr.GetCallableLoadAddress(target); if (callAddr == LLDB_INVALID_ADDRESS) return false; return SetPC(callAddr); }
bool ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Address function_address, ValueList &arg_values, Stream &errors) { // All the information to reconstruct the struct is provided by the // StructExtractor. if (!m_struct_valid) { errors.Printf("Argument information was not correctly parsed, so the function cannot be called."); return false; } Error error; using namespace clang; ExecutionResults return_value = eExecutionSetupError; Process *process = exe_ctx.GetProcessPtr(); if (process == NULL) return return_value; if (process != m_jit_process_sp.get()) return false; if (args_addr_ref == LLDB_INVALID_ADDRESS) { args_addr_ref = process->AllocateMemory(m_struct_size, lldb::ePermissionsReadable|lldb::ePermissionsWritable, error); if (args_addr_ref == LLDB_INVALID_ADDRESS) return false; m_wrapper_args_addrs.push_back (args_addr_ref); } else { // Make sure this is an address that we've already handed out. if (find (m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr_ref) == m_wrapper_args_addrs.end()) { return false; } } // TODO: verify fun_addr needs to be a callable address Scalar fun_addr (function_address.GetCallableLoadAddress(exe_ctx.GetTargetPtr())); int first_offset = m_member_offsets[0]; process->WriteScalarToMemory(args_addr_ref + first_offset, fun_addr, process->GetAddressByteSize(), error); // FIXME: We will need to extend this for Variadic functions. Error value_error; size_t num_args = arg_values.GetSize(); if (num_args != m_arg_values.GetSize()) { errors.Printf ("Wrong number of arguments - was: %lu should be: %lu", num_args, m_arg_values.GetSize()); return false; } for (size_t i = 0; i < num_args; i++) { // FIXME: We should sanity check sizes. int offset = m_member_offsets[i+1]; // Clang sizes are in bytes. Value *arg_value = arg_values.GetValueAtIndex(i); // FIXME: For now just do scalars: // Special case: if it's a pointer, don't do anything (the ABI supports passing cstrings) if (arg_value->GetValueType() == Value::eValueTypeHostAddress && arg_value->GetContextType() == Value::eContextTypeClangType && ClangASTContext::IsPointerType(arg_value->GetClangType())) continue; const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx, m_clang_ast_context->getASTContext()); if (!process->WriteScalarToMemory(args_addr_ref + offset, arg_scalar, arg_scalar.GetByteSize(), error)) return false; } return true; }