Example #1
0
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;
}
Example #2
0
bool
ABINyuzi::GetArgumentValues ( Thread &thread, ValueList &values ) const
{
  printf("ABINyuzi::GetArgumentValues %d\n", values.GetSize());

  assert(0);


  return false;
}
Example #3
0
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;
}
Example #4
0
bool
ABIMacOSX_arm::GetArgumentValues (Thread &thread,
                                  ValueList &values) const
{
    uint32_t num_values = values.GetSize();


    ExecutionContext exe_ctx (thread.shared_from_this());
    // For now, assume that the types in the AST values come from the Target's
    // scratch AST.

    clang::ASTContext *ast_context = exe_ctx.GetTargetRef().GetScratchClangASTContext()->getASTContext();

    // Extract the register context so we can read arguments from registers

    RegisterContext *reg_ctx = thread.GetRegisterContext().get();

    if (!reg_ctx)
        return false;

    addr_t sp = reg_ctx->GetSP(0);

    if (!sp)
        return false;

    for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx)
    {
        // We currently only support extracting values with Clang QualTypes.
        // Do we care about others?
        Value *value = values.GetValueAtIndex(value_idx);

        if (!value)
            return false;

        void *value_type = value->GetClangType();
        if (value_type)
        {
            bool is_signed = false;
            size_t bit_width = 0;
            if (ClangASTContext::IsIntegerType (value_type, is_signed))
            {
                bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
            }
            else if (ClangASTContext::IsPointerOrReferenceType (value_type))
            {
                bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
            }
            else
            {
                // We only handle integer, pointer and reference types currently...
                return false;
            }

            if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8))
            {
                if (value_idx < 4)
                {
                    // Arguments 1-4 are in r0-r3...
                    const RegisterInfo *arg_reg_info = NULL;
                    // Search by generic ID first, then fall back to by name
                    uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
                    if (arg_reg_num != LLDB_INVALID_REGNUM)
                    {
                        arg_reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num);
                    }
                    else
                    {
                        switch (value_idx)
                        {
                        case 0:
                            arg_reg_info = reg_ctx->GetRegisterInfoByName("r0");
                            break;
                        case 1:
                            arg_reg_info = reg_ctx->GetRegisterInfoByName("r1");
                            break;
                        case 2:
                            arg_reg_info = reg_ctx->GetRegisterInfoByName("r2");
                            break;
                        case 3:
                            arg_reg_info = reg_ctx->GetRegisterInfoByName("r3");
                            break;
                        }
                    }

                    if (arg_reg_info)
                    {
                        RegisterValue reg_value;

                        if (reg_ctx->ReadRegister(arg_reg_info, reg_value))
                        {
                            if (is_signed)
                                reg_value.SignExtend(bit_width);
                            if (!reg_value.GetScalarValue(value->GetScalar()))
                                return false;
                            continue;
                        }
                    }
                    return false;
                }
                else
                {
                    // Arguments 5 on up are on the stack
                    const uint32_t arg_byte_size = (bit_width + (8-1)) / 8;
                    Error error;
                    if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(sp, arg_byte_size, is_signed, value->GetScalar(), error))
                        return false;

                    sp += arg_byte_size;
                }
            }
        }
    }
    return true;
}
Example #5
0
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;
}
Example #6
0
bool ABISysV_ppc64::GetArgumentValues(Thread &thread, ValueList &values) const {
  unsigned int num_values = values.GetSize();
  unsigned int value_index;

  // Extract the register context so we can read arguments from registers

  RegisterContext *reg_ctx = thread.GetRegisterContext().get();

  if (!reg_ctx)
    return false;

  // Get the pointer to the first stack argument so we have a place to start
  // when reading data

  addr_t sp = reg_ctx->GetSP(0);

  if (!sp)
    return false;

  addr_t current_stack_argument = sp + 48; // jump over return address

  uint32_t argument_register_ids[8];

  argument_register_ids[0] =
      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)
          ->kinds[eRegisterKindLLDB];
  argument_register_ids[1] =
      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)
          ->kinds[eRegisterKindLLDB];
  argument_register_ids[2] =
      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)
          ->kinds[eRegisterKindLLDB];
  argument_register_ids[3] =
      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)
          ->kinds[eRegisterKindLLDB];
  argument_register_ids[4] =
      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)
          ->kinds[eRegisterKindLLDB];
  argument_register_ids[5] =
      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6)
          ->kinds[eRegisterKindLLDB];
  argument_register_ids[6] =
      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG7)
          ->kinds[eRegisterKindLLDB];
  argument_register_ids[7] =
      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG8)
          ->kinds[eRegisterKindLLDB];

  unsigned int current_argument_register = 0;

  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)
      return false;
    bool is_signed;

    if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
      ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread),
                          is_signed, thread, argument_register_ids,
                          current_argument_register, current_stack_argument);
    } else if (compiler_type.IsPointerType()) {
      ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread),
                          false, thread, argument_register_ids,
                          current_argument_register, current_stack_argument);
    }
  }

  return true;
}
Example #7
0
bool
ABISysV_arm::GetArgumentValues (Thread &thread,
                                  ValueList &values) const
{
    uint32_t num_values = values.GetSize();
    
    
    ExecutionContext exe_ctx (thread.shared_from_this());
    // For now, assume that the types in the AST values come from the Target's 
    // scratch AST.    
    
    // Extract the register context so we can read arguments from registers
    
    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    
    if (!reg_ctx)
        return false;
        
    addr_t sp = 0;

    for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx)
    {
        // We currently only support extracting values with Clang QualTypes.
        // Do we care about others?
        Value *value = values.GetValueAtIndex(value_idx);
        
        if (!value)
            return false;
        
        CompilerType compiler_type = value->GetCompilerType();
        if (compiler_type)
        {
            bool is_signed = false;
            size_t bit_width = 0;
            if (compiler_type.IsIntegerType (is_signed))
            {
                bit_width = compiler_type.GetBitSize(&thread);
            }
            else if (compiler_type.IsPointerOrReferenceType ())
            {
                bit_width = compiler_type.GetBitSize(&thread);
            }
            else
            {
                // We only handle integer, pointer and reference types currently...
                return false;
            }
            
            if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8))
            {
                if (value_idx < 4)
                {
                    // Arguments 1-4 are in r0-r3...
                    const RegisterInfo *arg_reg_info = NULL;
                    arg_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
                    if (arg_reg_info)
                    {
                        RegisterValue reg_value;
                        
                        if (reg_ctx->ReadRegister(arg_reg_info, reg_value))
                        {
                            if (is_signed)
                                reg_value.SignExtend(bit_width);
                            if (!reg_value.GetScalarValue(value->GetScalar()))
                                return false;
                            continue;
                        }
                    }
                    return false;
                }
                else
                {
                    if (sp == 0)
                    {
                        // Read the stack pointer if it already hasn't been read
                        sp = reg_ctx->GetSP(0);
                        if (sp == 0)
                            return false;
                    }

                    // Arguments 5 on up are on the stack
                    const uint32_t arg_byte_size = (bit_width + (8-1)) / 8;
                    Error error;
                    if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(sp, arg_byte_size, is_signed, value->GetScalar(), error))
                        return false;

                    sp += arg_byte_size;
                }
            }
        }
    }
    return true;
}
Example #8
0
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;
}