Ejemplo n.º 1
0
UnwindPlanSP
FuncUnwinders::GetUnwindPlanArchitectureDefaultAtFunctionEntry (Thread& thread)
{
    // Lock the mutex to ensure we can always give out the most appropriate
    // information. We want to make sure if someone requests an unwind
    // plan, that they get one and don't run into a race condition where one
    // thread has started to create the unwind plan and has put it into 
    // the auto_ptr member variable, and have another thread enter this function
    // and return the partially filled pointer contained in the auto_ptr.
    // We also want to make sure that we lock out other unwind plans from
    // being accessed until this one is done creating itself in case someone
    // had some code like:
    //  UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...)
    //  if (best_unwind_plan == NULL)
    //      best_unwind_plan = GetUnwindPlanAtNonCallSite (...)
    Mutex::Locker locker (m_mutex);
    if (m_tried_unwind_arch_default_at_func_entry == false && m_unwind_plan_arch_default_at_func_entry_sp.get() == NULL)
    {
        m_tried_unwind_arch_default_at_func_entry = true;
        Address current_pc;
        ProcessSP process_sp (thread.CalculateProcess());
        if (process_sp)
        {
            ABI *abi = process_sp->GetABI().get();
            if (abi)
            {
                m_unwind_plan_arch_default_at_func_entry_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
                if (m_unwind_plan_arch_default_at_func_entry_sp)
                    abi->CreateFunctionEntryUnwindPlan(*m_unwind_plan_arch_default_at_func_entry_sp);
            }
        }
    }

    return m_unwind_plan_arch_default_sp;
}
Ejemplo n.º 2
0
UnwindPlanSP
FuncUnwinders::GetUnwindPlanArchitectureDefaultAtFunctionEntry (Thread& thread)
{
    if (m_unwind_plan_arch_default_at_func_entry_sp.get() || m_tried_unwind_arch_default_at_func_entry)
        return m_unwind_plan_arch_default_at_func_entry_sp;

    std::lock_guard<std::recursive_mutex> guard(m_mutex);
    m_tried_unwind_arch_default_at_func_entry = true;

    Address current_pc;
    ProcessSP process_sp (thread.CalculateProcess());
    if (process_sp)
    {
        ABI *abi = process_sp->GetABI().get();
        if (abi)
        {
            m_unwind_plan_arch_default_at_func_entry_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
            if (!abi->CreateFunctionEntryUnwindPlan(*m_unwind_plan_arch_default_at_func_entry_sp))
            {
                m_unwind_plan_arch_default_at_func_entry_sp.reset();
            }
        }
    }

    return m_unwind_plan_arch_default_at_func_entry_sp;
}
// ThreadPlanCallFunctionUsingABI: Plan to call a single function using the ABI
// instead of JIT
ThreadPlanCallFunctionUsingABI::ThreadPlanCallFunctionUsingABI(
    Thread &thread, const Address &function, llvm::Type &prototype,
    llvm::Type &return_type, llvm::ArrayRef<ABI::CallArgument> args,
    const EvaluateExpressionOptions &options)
    : ThreadPlanCallFunction(thread, function, options),
      m_return_type(return_type) {
  lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS;
  lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS;
  ABI *abi = nullptr;

  if (!ConstructorSetup(thread, abi, start_load_addr, function_load_addr))
    return;

  if (!abi->PrepareTrivialCall(thread, m_function_sp, function_load_addr,
                               start_load_addr, prototype, args))
    return;

  ReportRegisterState("ABI Function call was set up.  Register state was:");

  m_valid = true;
}
Ejemplo n.º 4
0
ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
                                                const Address &function,
                                                const CompilerType &return_type,
                                                llvm::ArrayRef<addr_t> args,
                                                const EvaluateExpressionOptions &options) :
    ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
    m_valid (false),
    m_stop_other_threads (options.GetStopOthers()),
    m_unwind_on_error (options.DoesUnwindOnError()),
    m_ignore_breakpoints (options.DoesIgnoreBreakpoints()),
    m_debug_execution (options.GetDebug()),
    m_trap_exceptions (options.GetTrapExceptions()),
    m_function_addr (function),
    m_function_sp (0),
    m_takedown_done (false),
    m_should_clear_objc_exception_bp(false),
    m_should_clear_cxx_exception_bp (false),
    m_stop_address (LLDB_INVALID_ADDRESS),
    m_expression_language (options.GetLanguage()),
    m_hit_error_backstop(false),
    m_return_type (return_type)
{
    lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS;
    lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS;
    ABI *abi = nullptr;

    if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr))
        return;

    if (!abi->PrepareTrivialCall(thread,
                                 m_function_sp,
                                 function_load_addr,
                                 start_load_addr,
                                 args))
        return;

    ReportRegisterState ("Function call was set up.  Register state was:");

    m_valid = true;    
}