Beispiel #1
0
bool
AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionContextScope *exe_scope)
{
    if (!m_read_objc_library)
        return false;
        
    ExecutionContext exe_ctx;
    exe_scope->CalculateExecutionContext(exe_ctx);
    Process *process = exe_ctx.GetProcessPtr();
    if (!process)
        return false;
    
    // We need other parts of the exe_ctx, but the processes have to match.
    assert (m_process == process);
    
    // Get the function address for the print function.
    const Address *function_address = GetPrintForDebuggerAddr();
    if (!function_address)
        return false;
    
    Target *target = exe_ctx.GetTargetPtr();
    CompilerType compiler_type = value.GetCompilerType();
    if (compiler_type)
    {
        if (!ClangASTContext::IsObjCObjectPointerType(compiler_type))
        {
            strm.Printf ("Value doesn't point to an ObjC object.\n");
            return false;
        }
    }
    else 
    {
        // If it is not a pointer, see if we can make it into a pointer.
        ClangASTContext *ast_context = target->GetScratchClangASTContext();
        CompilerType opaque_type = ast_context->GetBasicType(eBasicTypeObjCID);
        if (!opaque_type)
            opaque_type = ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
        //value.SetContext(Value::eContextTypeClangType, opaque_type_ptr);
        value.SetCompilerType (opaque_type);
    }

    ValueList arg_value_list;
    arg_value_list.PushValue(value);
    
    // This is the return value:
    ClangASTContext *ast_context = target->GetScratchClangASTContext();
    
    CompilerType return_compiler_type = ast_context->GetCStringType(true);
    Value ret;
//    ret.SetContext(Value::eContextTypeClangType, return_compiler_type);
    ret.SetCompilerType (return_compiler_type);
    
    if (exe_ctx.GetFramePtr() == NULL)
    {
        Thread *thread = exe_ctx.GetThreadPtr();
        if (thread == NULL)
        {
            exe_ctx.SetThreadSP(process->GetThreadList().GetSelectedThread());
            thread = exe_ctx.GetThreadPtr();
        }
        if (thread)
        {
            exe_ctx.SetFrameSP(thread->GetSelectedFrame());
        }
    }
    
    // Now we're ready to call the function:
    
    StreamString error_stream;
    lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS;

    if (!m_print_object_caller_up)
    {
        Error error;
         m_print_object_caller_up.reset(exe_scope->CalculateTarget()->GetFunctionCallerForLanguage (eLanguageTypeObjC,
                                                                                                    return_compiler_type,
                                                                                                    *function_address,
                                                                                                    arg_value_list,
                                                                                                    "objc-object-description",
                                                                                                    error));
        if (error.Fail())
        {
            m_print_object_caller_up.reset();
            strm.Printf("Could not get function runner to call print for debugger function: %s.", error.AsCString());
            return false;
        }
        m_print_object_caller_up->InsertFunction(exe_ctx, wrapper_struct_addr, error_stream);
    }
    else
    {
        m_print_object_caller_up->WriteFunctionArguments(exe_ctx,
                                                         wrapper_struct_addr,
                                                         arg_value_list,
                                                         error_stream);
    }

    

    EvaluateExpressionOptions options;
    options.SetUnwindOnError(true);
    options.SetTryAllThreads(true);
    options.SetStopOthers(true);
    options.SetIgnoreBreakpoints(true);
    options.SetTimeoutUsec(PO_FUNCTION_TIMEOUT_USEC);
    options.SetLanguage(lldb::eLanguageTypeObjC_plus_plus);
    
    ExpressionResults results = m_print_object_caller_up->ExecuteFunction (exe_ctx,
                                                                           &wrapper_struct_addr,
                                                                           options,
                                                                           error_stream,
                                                                           ret);
    if (results != eExpressionCompleted)
    {
        strm.Printf("Error evaluating Print Object function: %d.\n", results);
        return false;
    }
       
    addr_t result_ptr = ret.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
    
    char buf[512];
    size_t cstr_len = 0;    
    size_t full_buffer_len = sizeof (buf) - 1;
    size_t curr_len = full_buffer_len;
    while (curr_len == full_buffer_len)
    {
        Error error;
        curr_len = process->ReadCStringFromMemory(result_ptr + cstr_len, buf, sizeof(buf), error);
        strm.Write (buf, curr_len);
        cstr_len += curr_len;
    }
    return cstr_len > 0;
}
Beispiel #2
0
bool
lldb_private::InferiorCall (Process *process,
                            const Address *address,
                            addr_t &returned_func)
{
    Thread *thread = process->GetThreadList().GetSelectedThread().get();
    if (thread == NULL || address == NULL)
        return false;

    EvaluateExpressionOptions options;
    options.SetStopOthers(true);
    options.SetUnwindOnError(true);
    options.SetIgnoreBreakpoints(true);
    options.SetTryAllThreads(true);
    options.SetDebug (false);
    options.SetTimeoutUsec(500000);

    ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
    CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
    lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
                                     *address,
                                     clang_void_ptr_type,
                                     llvm::ArrayRef<addr_t>(),
                                     options));
    if (call_plan_sp)
    {
        StreamString error_strm;
        // This plan is a utility plan, so set it to discard itself when done.
        call_plan_sp->SetIsMasterPlan (true);
        call_plan_sp->SetOkayToDiscard(true);

        StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
        if (frame)
        {
            ExecutionContext exe_ctx;
            frame->CalculateExecutionContext (exe_ctx);
            ExpressionResults result = process->RunThreadPlan (exe_ctx,
                                       call_plan_sp,
                                       options,
                                       error_strm);
            if (result == eExpressionCompleted)
            {
                returned_func = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);

                if (process->GetAddressByteSize() == 4)
                {
                    if (returned_func == UINT32_MAX)
                        return false;
                }
                else if (process->GetAddressByteSize() == 8)
                {
                    if (returned_func == UINT64_MAX)
                        return false;
                }
                return true;
            }
        }
    }

    return false;
}
Beispiel #3
0
bool
lldb_private::InferiorCallMmap (Process *process,
                                addr_t &allocated_addr,
                                addr_t addr,
                                addr_t length,
                                unsigned prot,
                                unsigned flags,
                                addr_t fd,
                                addr_t offset)
{
    Thread *thread = process->GetThreadList().GetSelectedThread().get();
    if (thread == NULL)
        return false;

    const bool append = true;
    const bool include_symbols = true;
    const bool include_inlines = false;
    SymbolContextList sc_list;
    const uint32_t count
        = process->GetTarget().GetImages().FindFunctions (ConstString ("mmap"),
                eFunctionNameTypeFull,
                include_symbols,
                include_inlines,
                append,
                sc_list);
    if (count > 0)
    {
        SymbolContext sc;
        if (sc_list.GetContextAtIndex(0, sc))
        {
            const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
            const bool use_inline_block_range = false;
            EvaluateExpressionOptions options;
            options.SetStopOthers(true);
            options.SetUnwindOnError(true);
            options.SetIgnoreBreakpoints(true);
            options.SetTryAllThreads(true);
            options.SetDebug (false);
            options.SetTimeoutUsec(500000);

            addr_t prot_arg, flags_arg = 0;
            if (prot == eMmapProtNone)
                prot_arg = PROT_NONE;
            else {
                prot_arg = 0;
                if (prot & eMmapProtExec)
                    prot_arg |= PROT_EXEC;
                if (prot & eMmapProtRead)
                    prot_arg |= PROT_READ;
                if (prot & eMmapProtWrite)
                    prot_arg |= PROT_WRITE;
            }

            const ArchSpec arch =  process->GetTarget().GetArchitecture();
            flags_arg = process->GetTarget().GetPlatform()->ConvertMmapFlagsToPlatform(arch,flags);

            AddressRange mmap_range;
            if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range))
            {
                ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
                CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
                lldb::addr_t args[] = { addr, length, prot_arg, flags_arg, fd, offset };
                lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
                                                 mmap_range.GetBaseAddress(),
                                                 clang_void_ptr_type,
                                                 args,
                                                 options));
                if (call_plan_sp)
                {
                    StreamFile error_strm;
                    // This plan is a utility plan, so set it to discard itself when done.
                    call_plan_sp->SetIsMasterPlan (true);
                    call_plan_sp->SetOkayToDiscard(true);

                    StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
                    if (frame)
                    {
                        ExecutionContext exe_ctx;
                        frame->CalculateExecutionContext (exe_ctx);
                        ExpressionResults result = process->RunThreadPlan (exe_ctx,
                                                   call_plan_sp,
                                                   options,
                                                   error_strm);
                        if (result == eExpressionCompleted)
                        {

                            allocated_addr = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
                            if (process->GetAddressByteSize() == 4)
                            {
                                if (allocated_addr == UINT32_MAX)
                                    return false;
                            }
                            else if (process->GetAddressByteSize() == 8)
                            {
                                if (allocated_addr == UINT64_MAX)
                                    return false;
                            }
                            return true;
                        }
                    }
                }
            }
        }
    }

    return false;
}
Beispiel #4
0
bool
lldb_private::InferiorCallMunmap (Process *process,
                                  addr_t addr,
                                  addr_t length)
{
    Thread *thread = process->GetThreadList().GetSelectedThread().get();
    if (thread == NULL)
        return false;

    const bool append = true;
    const bool include_symbols = true;
    const bool include_inlines = false;
    SymbolContextList sc_list;
    const uint32_t count
        = process->GetTarget().GetImages().FindFunctions (ConstString ("munmap"),
                eFunctionNameTypeFull,
                include_symbols,
                include_inlines,
                append,
                sc_list);
    if (count > 0)
    {
        SymbolContext sc;
        if (sc_list.GetContextAtIndex(0, sc))
        {
            const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
            const bool use_inline_block_range = false;
            EvaluateExpressionOptions options;
            options.SetStopOthers(true);
            options.SetUnwindOnError(true);
            options.SetIgnoreBreakpoints(true);
            options.SetTryAllThreads(true);
            options.SetDebug (false);
            options.SetTimeoutUsec(500000);

            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(),
                                                 CompilerType(),
                                                 args,
                                                 options));
                if (call_plan_sp)
                {
                    StreamFile error_strm;
                    // This plan is a utility plan, so set it to discard itself when done.
                    call_plan_sp->SetIsMasterPlan (true);
                    call_plan_sp->SetOkayToDiscard(true);

                    StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
                    if (frame)
                    {
                        ExecutionContext exe_ctx;
                        frame->CalculateExecutionContext (exe_ctx);
                        ExpressionResults result = process->RunThreadPlan (exe_ctx,
                                                   call_plan_sp,
                                                   options,
                                                   error_strm);
                        if (result == eExpressionCompleted)
                        {
                            return true;
                        }
                    }
                }
            }
        }
    }

    return false;
}