Error
ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
                                            lldb::addr_t &func_end,
                                            lldb::IRExecutionUnitSP &execution_unit_sp,
                                            ExecutionContext &exe_ctx,
                                            bool &can_interpret,
                                            ExecutionPolicy execution_policy)
{
	func_addr = LLDB_INVALID_ADDRESS;
	func_end = LLDB_INVALID_ADDRESS;
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    Error err;

    std::unique_ptr<llvm::Module> llvm_module_ap (m_code_generator->ReleaseModule());

    if (!llvm_module_ap.get())
    {
        err.SetErrorToGenericError();
        err.SetErrorString("IR doesn't contain a module");
        return err;
    }
    
    for (llvm::Function &function : *llvm_module_ap.get()) {
        llvm::AttributeSet attributes = function.getAttributes();
        llvm::AttrBuilder attributes_to_remove;
        
        attributes_to_remove.addAttribute("target-cpu");
        
        function.setAttributes(attributes.removeAttributes(function.getContext(), llvm::AttributeSet::FunctionIndex, llvm::AttributeSet::get(function.getContext(), llvm::AttributeSet::FunctionIndex, attributes_to_remove)));
    }

    // Find the actual name of the function (it's often mangled somehow)

    ConstString function_name;

    if (!FindFunctionInModule(function_name, llvm_module_ap.get(), m_expr.FunctionName()))
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName());
        return err;
    }
    else
    {
        if (log)
            log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName());
    }

    execution_unit_sp.reset(new IRExecutionUnit (m_llvm_context, // handed off here
                                                 llvm_module_ap, // handed off here
                                                 function_name,
                                                 exe_ctx.GetTargetSP(),
                                                 m_compiler->getTargetOpts().Features));

    ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
    ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap(); // result can be NULL

    if (decl_map)
    {
        Stream *error_stream = NULL;
        Target *target = exe_ctx.GetTargetPtr();
        if (target)
            error_stream = target->GetDebugger().GetErrorFile().get();

        IRForTarget ir_for_target(decl_map,
                                  m_expr.NeedsVariableResolution(),
                                  *execution_unit_sp,
                                  error_stream,
                                  function_name.AsCString());

        bool ir_can_run = ir_for_target.runOnModule(*execution_unit_sp->GetModule());

        Error interpret_error;
        Process *process = exe_ctx.GetProcessPtr();

        bool interpret_function_calls = !process ? false : process->CanInterpretFunctionCalls();
        can_interpret = IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(), interpret_error, interpret_function_calls);


        if (!ir_can_run)
        {
            err.SetErrorString("The expression could not be prepared to run in the target");
            return err;
        }

        if (!can_interpret && execution_policy == eExecutionPolicyNever)
        {
            err.SetErrorStringWithFormat("Can't run the expression locally: %s", interpret_error.AsCString());
            return err;
        }

        if (!process && execution_policy == eExecutionPolicyAlways)
        {
            err.SetErrorString("Expression needed to run in the target, but the target can't be run");
            return err;
        }

        if (execution_policy == eExecutionPolicyAlways || !can_interpret)
        {
            if (m_expr.NeedsValidation() && process)
            {
                if (!process->GetDynamicCheckers())
                {
                    DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();

                    StreamString install_errors;

                    if (!dynamic_checkers->Install(install_errors, exe_ctx))
                    {
                        if (install_errors.GetString().empty())
                            err.SetErrorString ("couldn't install checkers, unknown error");
                        else
                            err.SetErrorString (install_errors.GetString().c_str());

                        return err;
                    }

                    process->SetDynamicCheckers(dynamic_checkers);

                    if (log)
                        log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers ==");
                }

                IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.AsCString());

                if (!ir_dynamic_checks.runOnModule(*execution_unit_sp->GetModule()))
                {
                    err.SetErrorToGenericError();
                    err.SetErrorString("Couldn't add dynamic checks to the expression");
                    return err;
                }
            }

            execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
        }
    }
    else
    {
        execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
    }

    return err;
}
Exemplo n.º 2
0
lldb_private::Error
ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
                                            lldb::addr_t &func_end,
                                            lldb::IRExecutionUnitSP &execution_unit_sp,
                                            ExecutionContext &exe_ctx,
                                            bool &can_interpret,
                                            ExecutionPolicy execution_policy)
{
	func_addr = LLDB_INVALID_ADDRESS;
	func_end = LLDB_INVALID_ADDRESS;
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    lldb_private::Error err;

    std::unique_ptr<llvm::Module> llvm_module_ap (m_code_generator->ReleaseModule());

    if (!llvm_module_ap.get())
    {
        err.SetErrorToGenericError();
        err.SetErrorString("IR doesn't contain a module");
        return err;
    }

    ConstString function_name;

    if (execution_policy != eExecutionPolicyTopLevel)
    {
        // Find the actual name of the function (it's often mangled somehow)

        if (!FindFunctionInModule(function_name, llvm_module_ap.get(), m_expr.FunctionName()))
        {
            err.SetErrorToGenericError();
            err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName());
            return err;
        }
        else
        {
            if (log)
                log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName());
        }
    }

    SymbolContext sc;

    if (lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP())
    {
        sc = frame_sp->GetSymbolContext(lldb::eSymbolContextEverything);
    }
    else if (lldb::TargetSP target_sp = exe_ctx.GetTargetSP())
    {
        sc.target_sp = target_sp;
    }

    LLVMUserExpression::IRPasses custom_passes;
    {
        auto lang = m_expr.Language();
        if (log)
            log->Printf("%s - Currrent expression language is %s\n", __FUNCTION__,
                        Language::GetNameForLanguageType(lang));

        if (lang != lldb::eLanguageTypeUnknown)
        {
            auto runtime = exe_ctx.GetProcessSP()->GetLanguageRuntime(lang);
            if (runtime)
                runtime->GetIRPasses(custom_passes);
        }
    }

    if (custom_passes.EarlyPasses)
    {
        if (log)
            log->Printf("%s - Running Early IR Passes from LanguageRuntime on expression module '%s'", __FUNCTION__,
                        m_expr.FunctionName());

        custom_passes.EarlyPasses->run(*llvm_module_ap);
    }

    execution_unit_sp.reset(new IRExecutionUnit (m_llvm_context, // handed off here
                                                 llvm_module_ap, // handed off here
                                                 function_name,
                                                 exe_ctx.GetTargetSP(),
                                                 sc,
                                                 m_compiler->getTargetOpts().Features));

    ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
    ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap(); // result can be NULL

    if (decl_map)
    {
        Stream *error_stream = NULL;
        Target *target = exe_ctx.GetTargetPtr();
        if (target)
            error_stream = target->GetDebugger().GetErrorFile().get();

        IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(), *execution_unit_sp, error_stream,
                                  function_name.AsCString());

        bool ir_can_run = ir_for_target.runOnModule(*execution_unit_sp->GetModule());

        Process *process = exe_ctx.GetProcessPtr();

        if (execution_policy != eExecutionPolicyAlways && execution_policy != eExecutionPolicyTopLevel)
        {
            lldb_private::Error interpret_error;

            bool interpret_function_calls = !process ? false : process->CanInterpretFunctionCalls();
            can_interpret =
                IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(),
                                            interpret_error, interpret_function_calls);

            if (!can_interpret && execution_policy == eExecutionPolicyNever)
            {
                err.SetErrorStringWithFormat("Can't run the expression locally: %s", interpret_error.AsCString());
                return err;
            }
        }

        if (!ir_can_run)
        {
            err.SetErrorString("The expression could not be prepared to run in the target");
            return err;
        }

        if (!process && execution_policy == eExecutionPolicyAlways)
        {
            err.SetErrorString("Expression needed to run in the target, but the target can't be run");
            return err;
        }

        if (!process && execution_policy == eExecutionPolicyTopLevel)
        {
            err.SetErrorString(
                "Top-level code needs to be inserted into a runnable target, but the target can't be run");
            return err;
        }

        if (execution_policy == eExecutionPolicyAlways ||
            (execution_policy != eExecutionPolicyTopLevel && !can_interpret))
        {
            if (m_expr.NeedsValidation() && process)
            {
                if (!process->GetDynamicCheckers())
                {
                    DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();

                    DiagnosticManager install_diagnostics;

                    if (!dynamic_checkers->Install(install_diagnostics, exe_ctx))
                    {
                        if (install_diagnostics.Diagnostics().size())
                            err.SetErrorString("couldn't install checkers, unknown error");
                        else
                            err.SetErrorString(install_diagnostics.GetString().c_str());

                        return err;
                    }

                    process->SetDynamicCheckers(dynamic_checkers);

                    if (log)
                        log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers ==");
                }

                IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.AsCString());

                llvm::Module *module = execution_unit_sp->GetModule();
                if (!module || !ir_dynamic_checks.runOnModule(*module))
                {
                    err.SetErrorToGenericError();
                    err.SetErrorString("Couldn't add dynamic checks to the expression");
                    return err;
                }

                if (custom_passes.LatePasses)
                {
                    if (log)
                        log->Printf("%s - Running Late IR Passes from LanguageRuntime on expression module '%s'",
                                    __FUNCTION__, m_expr.FunctionName());

                    custom_passes.LatePasses->run(*module);
                }
            }
        }

        if (execution_policy == eExecutionPolicyAlways || execution_policy == eExecutionPolicyTopLevel ||
            !can_interpret)
        {
            execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
        }
    }
    else
    {
        execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
    }

    return err;
}