本文整理汇总了C++中Process::GetAddressByteSize方法的典型用法代码示例。如果您正苦于以下问题:C++ Process::GetAddressByteSize方法的具体用法?C++ Process::GetAddressByteSize怎么用?C++ Process::GetAddressByteSize使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Process
的用法示例。
在下文中一共展示了Process::GetAddressByteSize方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: UpdateValue
bool ValueObjectRegister::UpdateValue() {
m_error.Clear();
ExecutionContext exe_ctx(GetExecutionContextRef());
StackFrame *frame = exe_ctx.GetFramePtr();
if (frame == NULL) {
m_reg_ctx_sp.reset();
m_reg_value.Clear();
}
if (m_reg_ctx_sp) {
RegisterValue m_old_reg_value(m_reg_value);
if (m_reg_ctx_sp->ReadRegister(&m_reg_info, m_reg_value)) {
if (m_reg_value.GetData(m_data)) {
Process *process = exe_ctx.GetProcessPtr();
if (process)
m_data.SetAddressByteSize(process->GetAddressByteSize());
m_value.SetContext(Value::eContextTypeRegisterInfo,
(void *)&m_reg_info);
m_value.SetValueType(Value::eValueTypeHostAddress);
m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
SetValueIsValid(true);
SetValueDidChange(!(m_old_reg_value == m_reg_value));
return true;
}
}
}
SetValueIsValid(false);
m_error.SetErrorToGenericError();
return false;
}
示例2: exe_ctx
// this code relies on the assumption that an Objective-C object always starts
// with an ISA at offset 0.
ObjCLanguageRuntime::ObjCISA
AppleObjCRuntimeV1::GetISA(ValueObject& valobj)
{
if (ClangASTType::GetMinimumLanguage(valobj.GetClangAST(),valobj.GetClangType()) != eLanguageTypeObjC)
return 0;
// if we get an invalid VO (which might still happen when playing around
// with pointers returned by the expression parser, don't consider this
// a valid ObjC object)
if (valobj.GetValue().GetContextType() == Value::eContextTypeInvalid)
return 0;
addr_t isa_pointer = valobj.GetPointerValue();
ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
Process *process = exe_ctx.GetProcessPtr();
if (process)
{
uint8_t pointer_size = process->GetAddressByteSize();
Error error;
return process->ReadUnsignedIntegerFromMemory (isa_pointer,
pointer_size,
0,
error);
}
return 0;
}
示例3: DumpRegister
bool DumpRegister(const ExecutionContext &exe_ctx, Stream &strm,
RegisterContext *reg_ctx, const RegisterInfo *reg_info) {
if (reg_info) {
RegisterValue reg_value;
if (reg_ctx->ReadRegister(reg_info, reg_value)) {
strm.Indent();
bool prefix_with_altname = (bool)m_command_options.alternate_name;
bool prefix_with_name = !prefix_with_altname;
reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname,
m_format_options.GetFormat(), 8);
if ((reg_info->encoding == eEncodingUint) ||
(reg_info->encoding == eEncodingSint)) {
Process *process = exe_ctx.GetProcessPtr();
if (process && reg_info->byte_size == process->GetAddressByteSize()) {
addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS);
if (reg_addr != LLDB_INVALID_ADDRESS) {
Address so_reg_addr;
if (exe_ctx.GetTargetRef()
.GetSectionLoadList()
.ResolveLoadAddress(reg_addr, so_reg_addr)) {
strm.PutCString(" ");
so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(),
Address::DumpStyleResolvedDescription);
}
}
}
}
strm.EOL();
return true;
}
}
return false;
}
示例4: fun_addr
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;
}
示例5: 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)
{
//.........这里部分代码省略.........
示例6: GetDynamicTypeAndAddress
bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name, Address &dynamic_address,
Value::ValueType &value_type) {
// For Itanium, if the type has a vtable pointer in the object, it will be at
// offset 0
// in the object. That will point to the "address point" within the vtable
// (not the beginning of the
// vtable.) We can then look up the symbol containing this "address point"
// and that symbol's name
// demangled will contain the full class name.
// The second pointer above the "address point" is the "offset_to_top". We'll
// use that to get the
// start of the value object which holds the dynamic type.
//
class_type_or_name.Clear();
value_type = Value::ValueType::eValueTypeScalar;
// Only a pointer or reference type can have a different dynamic and static
// type:
if (CouldHaveDynamicValue(in_value)) {
// First job, pull out the address at 0 offset from the object.
AddressType address_type;
lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type);
if (original_ptr == LLDB_INVALID_ADDRESS)
return false;
ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
Process *process = exe_ctx.GetProcessPtr();
if (process == nullptr)
return false;
Error error;
const lldb::addr_t vtable_address_point =
process->ReadPointerFromMemory(original_ptr, error);
if (!error.Success() || vtable_address_point == LLDB_INVALID_ADDRESS) {
return false;
}
class_type_or_name = GetTypeInfoFromVTableAddress(in_value, original_ptr,
vtable_address_point);
if (class_type_or_name) {
TypeSP type_sp = class_type_or_name.GetTypeSP();
// There can only be one type with a given name,
// so we've just found duplicate definitions, and this
// one will do as well as any other.
// We don't consider something to have a dynamic type if
// it is the same as the static type. So compare against
// the value we were handed.
if (type_sp) {
if (ClangASTContext::AreTypesSame(in_value.GetCompilerType(),
type_sp->GetForwardCompilerType())) {
// The dynamic type we found was the same type,
// so we don't have a dynamic type here...
return false;
}
// The offset_to_top is two pointers above the vtable pointer.
const uint32_t addr_byte_size = process->GetAddressByteSize();
const lldb::addr_t offset_to_top_location =
vtable_address_point - 2 * addr_byte_size;
// Watch for underflow, offset_to_top_location should be less than
// vtable_address_point
if (offset_to_top_location >= vtable_address_point)
return false;
const int64_t offset_to_top = process->ReadSignedIntegerFromMemory(
offset_to_top_location, addr_byte_size, INT64_MIN, error);
if (offset_to_top == INT64_MIN)
return false;
// So the dynamic type is a value that starts at offset_to_top
// above the original address.
lldb::addr_t dynamic_addr = original_ptr + offset_to_top;
if (!process->GetTarget().GetSectionLoadList().ResolveLoadAddress(
dynamic_addr, dynamic_address)) {
dynamic_address.SetRawAddress(dynamic_addr);
}
return true;
}
}
}
return class_type_or_name.IsEmpty() == false;
}
示例7: exe_ctx
bool
ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value,
lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name,
Address &dynamic_address)
{
// For Itanium, if the type has a vtable pointer in the object, it will be at offset 0
// in the object. That will point to the "address point" within the vtable (not the beginning of the
// vtable.) We can then look up the symbol containing this "address point" and that symbol's name
// demangled will contain the full class name.
// The second pointer above the "address point" is the "offset_to_top". We'll use that to get the
// start of the value object which holds the dynamic type.
//
class_type_or_name.Clear();
// Only a pointer or reference type can have a different dynamic and static type:
if (CouldHaveDynamicValue (in_value))
{
// First job, pull out the address at 0 offset from the object.
AddressType address_type;
lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type);
if (original_ptr == LLDB_INVALID_ADDRESS)
return false;
ExecutionContext exe_ctx (in_value.GetExecutionContextRef());
Target *target = exe_ctx.GetTargetPtr();
Process *process = exe_ctx.GetProcessPtr();
char memory_buffer[16];
DataExtractor data(memory_buffer, sizeof(memory_buffer),
process->GetByteOrder(),
process->GetAddressByteSize());
size_t address_byte_size = process->GetAddressByteSize();
Error error;
size_t bytes_read = process->ReadMemory (original_ptr,
memory_buffer,
address_byte_size,
error);
if (!error.Success() || (bytes_read != address_byte_size))
{
return false;
}
lldb::offset_t offset = 0;
lldb::addr_t vtable_address_point = data.GetAddress (&offset);
if (offset == 0)
return false;
// Now find the symbol that contains this address:
SymbolContext sc;
Address address_point_address;
if (target && !target->GetSectionLoadList().IsEmpty())
{
if (target->GetSectionLoadList().ResolveLoadAddress (vtable_address_point, address_point_address))
{
target->GetImages().ResolveSymbolContextForAddress (address_point_address, eSymbolContextSymbol, sc);
Symbol *symbol = sc.symbol;
if (symbol != NULL)
{
const char *name = symbol->GetMangled().GetDemangledName().AsCString();
if (strstr(name, vtable_demangled_prefix) == name)
{
Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has vtable symbol '%s'\n",
original_ptr,
in_value.GetTypeName().GetCString(),
name);
// We are a C++ class, that's good. Get the class name and look it up:
const char *class_name = name + strlen(vtable_demangled_prefix);
class_type_or_name.SetName (class_name);
const bool exact_match = true;
TypeList class_types;
uint32_t num_matches = 0;
// First look in the module that the vtable symbol came from
// and look for a single exact match.
if (sc.module_sp)
{
num_matches = sc.module_sp->FindTypes (sc,
ConstString(class_name),
exact_match,
1,
class_types);
}
// If we didn't find a symbol, then move on to the entire
// module list in the target and get as many unique matches
// as possible
if (num_matches == 0)
{
num_matches = target->GetImages().FindTypes (sc,
ConstString(class_name),
exact_match,
UINT32_MAX,
class_types);
//.........这里部分代码省略.........
示例8: member__f_
CPPLanguageRuntime::LibCppStdFunctionCallableInfo
CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo(
lldb::ValueObjectSP &valobj_sp) {
LibCppStdFunctionCallableInfo optional_info;
if (!valobj_sp)
return optional_info;
// Member __f_ has type __base*, the contents of which will hold:
// 1) a vtable entry which may hold type information needed to discover the
// lambda being called
// 2) possibly hold a pointer to the callable object
// e.g.
//
// (lldb) frame var -R f_display
// (std::__1::function<void (int)>) f_display = {
// __buf_ = {
// …
// }
// __f_ = 0x00007ffeefbffa00
// }
// (lldb) memory read -fA 0x00007ffeefbffa00
// 0x7ffeefbffa00: ... `vtable for std::__1::__function::__func<void (*) ...
// 0x7ffeefbffa08: ... `print_num(int) at std_function_cppreference_exam ...
//
// We will be handling five cases below, std::function is wrapping:
//
// 1) a lambda we know at compile time. We will obtain the name of the lambda
// from the first template pameter from __func's vtable. We will look up
// the lambda's operator()() and obtain the line table entry.
// 2) a lambda we know at runtime. A pointer to the lambdas __invoke method
// will be stored after the vtable. We will obtain the lambdas name from
// this entry and lookup operator()() and obtain the line table entry.
// 3) a callable object via operator()(). We will obtain the name of the
// object from the first template parameter from __func's vtable. We will
// look up the objectc operator()() and obtain the line table entry.
// 4) a member function. A pointer to the function will stored after the
// we will obtain the name from this pointer.
// 5) a free function. A pointer to the function will stored after the vtable
// we will obtain the name from this pointer.
ValueObjectSP member__f_(
valobj_sp->GetChildMemberWithName(ConstString("__f_"), true));
if (member__f_) {
ValueObjectSP sub_member__f_(
member__f_->GetChildMemberWithName(ConstString("__f_"), true));
if (sub_member__f_)
member__f_ = sub_member__f_;
}
lldb::addr_t member__f_pointer_value = member__f_->GetValueAsUnsigned(0);
optional_info.member__f_pointer_value = member__f_pointer_value;
ExecutionContext exe_ctx(valobj_sp->GetExecutionContextRef());
Process *process = exe_ctx.GetProcessPtr();
if (process == nullptr)
return optional_info;
uint32_t address_size = process->GetAddressByteSize();
Status status;
// First item pointed to by __f_ should be the pointer to the vtable for
// a __base object.
lldb::addr_t vtable_address =
process->ReadPointerFromMemory(member__f_pointer_value, status);
if (status.Fail())
return optional_info;
lldb::addr_t address_after_vtable = member__f_pointer_value + address_size;
// As commened above we may not have a function pointer but if we do we will
// need it.
lldb::addr_t possible_function_address =
process->ReadPointerFromMemory(address_after_vtable, status);
if (status.Fail())
return optional_info;
Target &target = process->GetTarget();
if (target.GetSectionLoadList().IsEmpty())
return optional_info;
Address vtable_addr_resolved;
SymbolContext sc;
Symbol *symbol;
if (!target.GetSectionLoadList().ResolveLoadAddress(vtable_address,
vtable_addr_resolved))
return optional_info;
target.GetImages().ResolveSymbolContextForAddress(
vtable_addr_resolved, eSymbolContextEverything, sc);
symbol = sc.symbol;
if (symbol == nullptr)
return optional_info;
//.........这里部分代码省略.........
示例9: data
bool
ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value,
lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name,
Address &dynamic_address)
{
// For Itanium, if the type has a vtable pointer in the object, it will be at offset 0
// in the object. That will point to the "address point" within the vtable (not the beginning of the
// vtable.) We can then look up the symbol containing this "address point" and that symbol's name
// demangled will contain the full class name.
// The second pointer above the "address point" is the "offset_to_top". We'll use that to get the
// start of the value object which holds the dynamic type.
//
// Only a pointer or reference type can have a different dynamic and static type:
if (CouldHaveDynamicValue (in_value))
{
// FIXME: Can we get the Clang Type and ask it if the thing is really virtual? That would avoid false positives,
// at the cost of not looking for the dynamic type of objects if DWARF->Clang gets it wrong.
// First job, pull out the address at 0 offset from the object.
AddressType address_type;
lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type);
if (original_ptr == LLDB_INVALID_ADDRESS)
return false;
Target *target = in_value.GetUpdatePoint().GetTargetSP().get();
Process *process = in_value.GetUpdatePoint().GetProcessSP().get();
char memory_buffer[16];
DataExtractor data(memory_buffer, sizeof(memory_buffer),
process->GetByteOrder(),
process->GetAddressByteSize());
size_t address_byte_size = process->GetAddressByteSize();
Error error;
size_t bytes_read = process->ReadMemory (original_ptr,
memory_buffer,
address_byte_size,
error);
if (!error.Success() || (bytes_read != address_byte_size))
{
return false;
}
uint32_t offset_ptr = 0;
lldb::addr_t vtable_address_point = data.GetAddress (&offset_ptr);
if (offset_ptr == 0)
return false;
// Now find the symbol that contains this address:
SymbolContext sc;
Address address_point_address;
if (target && !target->GetSectionLoadList().IsEmpty())
{
if (target->GetSectionLoadList().ResolveLoadAddress (vtable_address_point, address_point_address))
{
target->GetImages().ResolveSymbolContextForAddress (address_point_address, eSymbolContextSymbol, sc);
Symbol *symbol = sc.symbol;
if (symbol != NULL)
{
const char *name = symbol->GetMangled().GetDemangledName().AsCString();
if (strstr(name, vtable_demangled_prefix) == name)
{
// We are a C++ class, that's good. Get the class name and look it up:
const char *class_name = name + strlen(vtable_demangled_prefix);
class_type_or_name.SetName (class_name);
TypeList class_types;
uint32_t num_matches = target->GetImages().FindTypes (sc,
ConstString(class_name),
true,
UINT32_MAX,
class_types);
if (num_matches == 1)
{
class_type_or_name.SetTypeSP(class_types.GetTypeAtIndex(0));
}
else if (num_matches > 1)
{
for (size_t i = 0; i < num_matches; i++)
{
lldb::TypeSP this_type(class_types.GetTypeAtIndex(i));
if (this_type)
{
if (ClangASTContext::IsCXXClassType(this_type->GetClangFullType()))
{
// There can only be one type with a given name,
// so we've just found duplicate definitions, and this
// one will do as well as any other.
// We don't consider something to have a dynamic type if
// it is the same as the static type. So compare against
// the value we were handed:
clang::ASTContext *in_ast_ctx = in_value.GetClangAST ();
clang::ASTContext *this_ast_ctx = this_type->GetClangAST ();
if (in_ast_ctx != this_ast_ctx
|| !ClangASTContext::AreTypesSame (in_ast_ctx,
in_value.GetClangType(),
this_type->GetClangFullType()))
//.........这里部分代码省略.........
示例10: WriteFunctionArguments
bool FunctionCaller::WriteFunctionArguments(
ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref,
ValueList &arg_values, DiagnosticManager &diagnostic_manager) {
// All the information to reconstruct the struct is provided by the
// StructExtractor.
if (!m_struct_valid) {
diagnostic_manager.PutString(eDiagnosticSeverityError,
"Argument information was not correctly "
"parsed, so the function cannot be called.");
return false;
}
Status error;
lldb::ExpressionResults return_value = lldb::eExpressionSetupError;
Process *process = exe_ctx.GetProcessPtr();
if (process == NULL)
return return_value;
lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
if (process != 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(
m_function_addr.GetCallableLoadAddress(exe_ctx.GetTargetPtr()));
uint64_t 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.
Status value_error;
size_t num_args = arg_values.GetSize();
if (num_args != m_arg_values.GetSize()) {
diagnostic_manager.Printf(
eDiagnosticSeverityError,
"Wrong number of arguments - was: %" PRIu64 " should be: %" PRIu64 "",
(uint64_t)num_args, (uint64_t)m_arg_values.GetSize());
return false;
}
for (size_t i = 0; i < num_args; i++) {
// FIXME: We should sanity check sizes.
uint64_t 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::eContextTypeInvalid &&
arg_value->GetCompilerType().IsPointerType())
continue;
const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx);
if (!process->WriteScalarToMemory(args_addr_ref + offset, arg_scalar,
arg_scalar.GetByteSize(), error))
return false;
}
return true;
}