当前位置: 首页>>代码示例>>C++>>正文


C++ Thread::CalculateTarget方法代码示例

本文整理汇总了C++中Thread::CalculateTarget方法的典型用法代码示例。如果您正苦于以下问题:C++ Thread::CalculateTarget方法的具体用法?C++ Thread::CalculateTarget怎么用?C++ Thread::CalculateTarget使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在Thread的用法示例。


在下文中一共展示了Thread::CalculateTarget方法的6个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: target_sp

bool
ABIMacOSX_arm::PrepareTrivialCall (Thread &thread,
                                   addr_t sp,
                                   addr_t function_addr,
                                   addr_t return_addr,
                                   addr_t *arg1_ptr,
                                   addr_t *arg2_ptr,
                                   addr_t *arg3_ptr,
                                   addr_t *arg4_ptr,
                                   addr_t *arg5_ptr,
                                   addr_t *arg6_ptr) const
{
    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    if (!reg_ctx)
        return false;

    const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
    const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
    const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);

    RegisterValue reg_value;

    if (arg1_ptr)
    {
        reg_value.SetUInt32(*arg1_ptr);
        if (!reg_ctx->WriteRegister (reg_ctx->GetRegisterInfoByName("r0"), reg_value))
            return false;

        if (arg2_ptr)
        {
            reg_value.SetUInt32(*arg2_ptr);
            if (!reg_ctx->WriteRegister (reg_ctx->GetRegisterInfoByName("r1"), reg_value))
                return false;

            if (arg3_ptr)
            {
                reg_value.SetUInt32(*arg3_ptr);
                if (!reg_ctx->WriteRegister (reg_ctx->GetRegisterInfoByName("r2"), reg_value))
                    return false;
                if (arg4_ptr)
                {
                    reg_value.SetUInt32(*arg4_ptr);
                    const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r3");
                    if (!reg_ctx->WriteRegister (reg_info, reg_value))
                        return false;
                    if (arg5_ptr)
                    {
                        // Keep the stack 8 byte aligned, not that we need to
                        sp -= 8;
                        sp &= ~(8ull-1ull);
                        reg_value.SetUInt32(*arg5_ptr);
                        if (reg_ctx->WriteRegisterValueToMemory (reg_info, sp, reg_info->byte_size, reg_value).Fail())
                            return false;
                        if (arg6_ptr)
                        {
                            reg_value.SetUInt32(*arg6_ptr);
                            if (reg_ctx->WriteRegisterValueToMemory (reg_info, sp + 4, reg_info->byte_size, reg_value).Fail())
                                return false;
                        }
                    }
                }
            }
        }
    }


    TargetSP target_sp (thread.CalculateTarget());
    Address so_addr;

    // Figure out if our return address is ARM or Thumb by using the
    // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
    // thumb-ness and set the correct address bits for us.
    so_addr.SetLoadAddress (return_addr, target_sp.get());
    return_addr = so_addr.GetCallableLoadAddress (target_sp.get());

    // Set "lr" to the return address
    if (!reg_ctx->WriteRegisterFromUnsigned (ra_reg_num, return_addr))
        return false;

    // Set "sp" to the requested value
    if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_num, sp))
        return false;

    // If bit zero or 1 is set, this must be a thumb function, no need to figure
    // this out from the symbols.
    so_addr.SetLoadAddress (function_addr, target_sp.get());
    function_addr = so_addr.GetCallableLoadAddress (target_sp.get());

    const RegisterInfo *cpsr_reg_info = reg_ctx->GetRegisterInfoByName("cpsr");
    const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);

    // Make a new CPSR and mask out any Thumb IT (if/then) bits
    uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
    // If bit zero or 1 is set, this must be thumb...
    if (function_addr & 1ull)
        new_cpsr |= MASK_CPSR_T;    // Set T bit in CPSR
    else
        new_cpsr &= ~MASK_CPSR_T;   // Clear T bit in CPSR

    if (new_cpsr != curr_cpsr)
//.........这里部分代码省略.........
开发者ID:carlokok,项目名称:lldb,代码行数:101,代码来源:ABIMacOSX_arm.cpp

示例2: GetReturnValueObject

ValueObjectSP ABI::GetReturnValueObject(Thread &thread, CompilerType &ast_type,
                                        bool persistent) const {
  if (!ast_type.IsValid())
    return ValueObjectSP();

  ValueObjectSP return_valobj_sp;

  return_valobj_sp = GetReturnValueObjectImpl(thread, ast_type);
  if (!return_valobj_sp)
    return return_valobj_sp;

  // Now turn this into a persistent variable.
  // FIXME: This code is duplicated from Target::EvaluateExpression, and it is
  // used in similar form in a couple
  // of other places.  Figure out the correct Create function to do all this
  // work.

  if (persistent) {
    PersistentExpressionState *persistent_expression_state =
        thread.CalculateTarget()->GetPersistentExpressionStateForLanguage(
            ast_type.GetMinimumLanguage());

    if (!persistent_expression_state)
      return ValueObjectSP();

    ConstString persistent_variable_name(
        persistent_expression_state->GetNextPersistentVariableName());

    lldb::ValueObjectSP const_valobj_sp;

    // Check in case our value is already a constant value
    if (return_valobj_sp->GetIsConstant()) {
      const_valobj_sp = return_valobj_sp;
      const_valobj_sp->SetName(persistent_variable_name);
    } else
      const_valobj_sp =
          return_valobj_sp->CreateConstantValue(persistent_variable_name);

    lldb::ValueObjectSP live_valobj_sp = return_valobj_sp;

    return_valobj_sp = const_valobj_sp;

    ExpressionVariableSP clang_expr_variable_sp(
        persistent_expression_state->CreatePersistentVariable(
            return_valobj_sp));

    assert(clang_expr_variable_sp);

    // Set flags and live data as appropriate

    const Value &result_value = live_valobj_sp->GetValue();

    switch (result_value.GetValueType()) {
    case Value::eValueTypeHostAddress:
    case Value::eValueTypeFileAddress:
      // we don't do anything with these for now
      break;
    case Value::eValueTypeScalar:
    case Value::eValueTypeVector:
      clang_expr_variable_sp->m_flags |=
          ClangExpressionVariable::EVIsFreezeDried;
      clang_expr_variable_sp->m_flags |=
          ClangExpressionVariable::EVIsLLDBAllocated;
      clang_expr_variable_sp->m_flags |=
          ClangExpressionVariable::EVNeedsAllocation;
      break;
    case Value::eValueTypeLoadAddress:
      clang_expr_variable_sp->m_live_sp = live_valobj_sp;
      clang_expr_variable_sp->m_flags |=
          ClangExpressionVariable::EVIsProgramReference;
      break;
    }

    return_valobj_sp = clang_expr_variable_sp->GetValueObject();
  }
  return return_valobj_sp;
}
开发者ID:2trill2spill,项目名称:freebsd,代码行数:77,代码来源:ABI.cpp

示例3: 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)
        {
//.........这里部分代码省略.........
开发者ID:ice799,项目名称:lldb,代码行数:101,代码来源:ObjCTrampolineHandler.cpp

示例4: disasm_sp


//.........这里部分代码省略.........
                RegisterInfo pc_reg_info;
                if (m_inst_emulator_ap->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc_reg_info))
                    pc_reg_num = pc_reg_info.kinds[unwind_plan.GetRegisterKind()];
                else
                    pc_reg_num = LLDB_INVALID_REGNUM;

                // cache the return address register number (in whatever register numbering this UnwindPlan uses) for
                // quick reference during instruction parsing.
                uint32_t ra_reg_num = LLDB_INVALID_REGNUM;
                RegisterInfo ra_reg_info;
                if (m_inst_emulator_ap->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, ra_reg_info))
                    ra_reg_num = ra_reg_info.kinds[unwind_plan.GetRegisterKind()];
                else
                    ra_reg_num = LLDB_INVALID_REGNUM;

                for (size_t idx=0; idx<num_instructions; ++idx)
                {
                    m_curr_row_modified = false;
                    m_forward_branch_offset = 0;

                    inst = inst_list.GetInstructionAtIndex (idx).get();
                    if (inst)
                    {
                        lldb::addr_t current_offset = inst->GetAddress().GetFileAddress() - base_addr;
                        auto it = saved_unwind_states.upper_bound(current_offset);
                        assert(it != saved_unwind_states.begin() && "Unwind row for the function entry missing");
                        --it; // Move it to the row corresponding to the current offset

                        // If the offset of m_curr_row don't match with the offset we see in saved_unwind_states
                        // then we have to update m_curr_row and m_register_values based on the saved values. It
                        // is happenning after we processed an epilogue and a return to caller instruction.
                        if (it->second.first->GetOffset() != m_curr_row->GetOffset())
                        {
                            UnwindPlan::Row *newrow = new UnwindPlan::Row;
                            *newrow = *it->second.first;
                            m_curr_row.reset(newrow);
                            m_register_values = it->second.second;;
                        }

                        if (log && log->GetVerbose ())
                        {
                            StreamString strm;
                            lldb_private::FormatEntity::Entry format;
                            FormatEntity::Parse("${frame.pc}: ", format);
                            inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize (), show_address, show_bytes, NULL, NULL, NULL, &format, 0);
                            log->PutCString (strm.GetData());
                        }

                        m_inst_emulator_ap->SetInstruction (inst->GetOpcode(), 
                                                            inst->GetAddress(), 
                                                            exe_ctx.GetTargetPtr());

                        m_inst_emulator_ap->EvaluateInstruction (eEmulateInstructionOptionIgnoreConditions);

                        // If the current instruction is a branch forward then save the current CFI information
                        // for the offset where we are branching.
                        if (m_forward_branch_offset != 0 && range.ContainsFileAddress(inst->GetAddress().GetFileAddress() + m_forward_branch_offset))
                        {
                            auto newrow = std::make_shared<UnwindPlan::Row>(*m_curr_row.get());
                            newrow->SetOffset(current_offset + m_forward_branch_offset);
                            saved_unwind_states.insert({current_offset + m_forward_branch_offset, {newrow, m_register_values}});
                            unwind_plan.InsertRow(newrow);
                        }

                        // Were there any changes to the CFI while evaluating this instruction?
                        if (m_curr_row_modified)
                        {
                            // Save the modified row if we don't already have a CFI row in the currennt address
                            if (saved_unwind_states.count(current_offset + inst->GetOpcode().GetByteSize()) == 0)
                            {
                                m_curr_row->SetOffset (current_offset + inst->GetOpcode().GetByteSize());
                                unwind_plan.InsertRow (m_curr_row);
                                saved_unwind_states.insert({current_offset + inst->GetOpcode().GetByteSize(), {m_curr_row, m_register_values}});

                                // Allocate a new Row for m_curr_row, copy the current state into it
                                UnwindPlan::Row *newrow = new UnwindPlan::Row;
                                *newrow = *m_curr_row.get();
                                m_curr_row.reset(newrow);
                            }
                        }
                    }
                }
            }
            // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
            // I'll fix that but for now, just clear the list and it will go away nicely.
            disasm_sp->GetInstructionList().Clear();
        }
        
        if (log && log->GetVerbose ())
        {
            StreamString strm;
            lldb::addr_t base_addr = range.GetBaseAddress().GetLoadAddress(thread.CalculateTarget().get());
            strm.Printf ("Resulting unwind rows for [0x%" PRIx64 " - 0x%" PRIx64 "):", base_addr, base_addr + range.GetByteSize());
            unwind_plan.Dump(strm, &thread, base_addr);
            log->PutCString (strm.GetData());
        }
        return unwind_plan.GetRowCount() > 0;
    }
    return false;
}
开发者ID:JuliaLang,项目名称:lldb,代码行数:101,代码来源:UnwindAssemblyInstEmulation.cpp

示例5: target_sp

bool
ABIMacOSX_arm::PrepareTrivialCall (Thread &thread, 
                                   addr_t sp, 
                                   addr_t function_addr, 
                                   addr_t return_addr, 
                                   llvm::ArrayRef<addr_t> args) const
{
    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    if (!reg_ctx)
        return false;    

    const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
    const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
    const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);

    RegisterValue reg_value;

    const char *reg_names[] = { "r0", "r1", "r2", "r3" };
    
    llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
    
    for (size_t i = 0; i < llvm::array_lengthof(reg_names); ++i)
    {
        if (ai == ae)
            break;
        
        reg_value.SetUInt32(*ai);
        if (!reg_ctx->WriteRegister(reg_ctx->GetRegisterInfoByName(reg_names[i]), reg_value))
            return false;
        
        ++ai;
    }
    
    if (ai != ae)
    {
        // Spill onto the stack
        size_t num_stack_regs = ae - ai;
        
        sp -= (num_stack_regs * 4);
        // Keep the stack 8 byte aligned, not that we need to
        sp &= ~(8ull-1ull);
        
        // just using arg1 to get the right size
        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
        
        addr_t arg_pos = sp;
        
        for (; ai != ae; ++ai)
        {
            reg_value.SetUInt32(*ai);
            if (reg_ctx->WriteRegisterValueToMemory(reg_info, arg_pos, reg_info->byte_size, reg_value).Fail())
                return false;
            arg_pos += reg_info->byte_size;
        }
    }
    
    TargetSP target_sp (thread.CalculateTarget());
    Address so_addr;

    // Figure out if our return address is ARM or Thumb by using the 
    // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
    // thumb-ness and set the correct address bits for us.
    so_addr.SetLoadAddress (return_addr, target_sp.get());
    return_addr = so_addr.GetCallableLoadAddress (target_sp.get());

    // Set "lr" to the return address
    if (!reg_ctx->WriteRegisterFromUnsigned (ra_reg_num, return_addr))
        return false;

    // Set "sp" to the requested value
    if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_num, sp))
        return false;
    
    // If bit zero or 1 is set, this must be a thumb function, no need to figure
    // this out from the symbols.
    so_addr.SetLoadAddress (function_addr, target_sp.get());
    function_addr = so_addr.GetCallableLoadAddress (target_sp.get());
    
    const RegisterInfo *cpsr_reg_info = reg_ctx->GetRegisterInfoByName("cpsr");
    const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);

    // Make a new CPSR and mask out any Thumb IT (if/then) bits
    uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
    // If bit zero or 1 is set, this must be thumb...
    if (function_addr & 1ull)
        new_cpsr |= MASK_CPSR_T;    // Set T bit in CPSR
    else
        new_cpsr &= ~MASK_CPSR_T;   // Clear T bit in CPSR

    if (new_cpsr != curr_cpsr)
    {
        if (!reg_ctx->WriteRegisterFromUnsigned (cpsr_reg_info, new_cpsr))
            return false;
    }

    function_addr &= ~1ull;   // clear bit zero since the CPSR will take care of the mode for us
    
    // Set "pc" to the address requested
    if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_num, function_addr))
        return false;
//.........这里部分代码省略.........
开发者ID:Jean-Daniel,项目名称:lldb,代码行数:101,代码来源:ABIMacOSX_arm.cpp

示例6: disasm_sp


//.........这里部分代码省略.........
                            // executed an epilogue.
                            if (ra_reg_num != LLDB_INVALID_REGNUM
                                && m_curr_row->GetRegisterInfo (ra_reg_num, ra_regloc)
                                && !ra_regloc.IsSame())
                            {
                                return_address_register_has_been_saved = true;
                            }

                            // If the caller's pc is "same", we've just executed an epilogue and we return to the caller
                            // after this instruction completes executing.
                            // If there are any instructions past this, there must have been flow control over this
                            // epilogue so we'll reinstate the original prologue setup instructions.
                            if (prologue_completed_row.get()
                                && pc_reg_num != LLDB_INVALID_REGNUM 
                                && m_curr_row->GetRegisterInfo (pc_reg_num, pc_regloc)
                                && pc_regloc.IsSame())
                            {
                                if (log && log->GetVerbose())
                                    log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- pc is <same>, restore prologue instructions.");
                                reinstate_prologue_next_instruction = true;
                            }
                            else if (prologue_completed_row.get()
                                     && return_address_register_has_been_saved
                                     && ra_reg_num != LLDB_INVALID_REGNUM
                                     && m_curr_row->GetRegisterInfo (ra_reg_num, ra_regloc)
                                     && ra_regloc.IsSame())
                            {
                                if (log && log->GetVerbose())
                                    log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- lr is <same>, restore prologue instruction if the next instruction is a branch immediate.");
                                last_instruction_restored_return_addr_reg = true;
                            }
                        }
                        else
                        {
                            // If the previous instruction was a return-to-caller (epilogue), and we're still executing
                            // instructions in this function, there must be a code path that jumps over that epilogue.
                            // Also detect the case where we epilogue & branch imm to another function (tail-call opt)
                            // instead of a normal pop lr-into-pc exit.
                            // Reinstate the frame setup from the prologue.
                            if (reinstate_prologue_next_instruction
                                || (m_curr_insn_is_branch_immediate && last_instruction_restored_return_addr_reg))
                            {
                                if (log && log->GetVerbose())
                                    log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- Reinstating prologue instruction set");
                                UnwindPlan::Row *newrow = new UnwindPlan::Row;
                                *newrow = *prologue_completed_row.get();
                                m_curr_row.reset(newrow);
                                m_curr_row->SetOffset (inst->GetAddress().GetFileAddress() + inst->GetOpcode().GetByteSize() - base_addr);
                                unwind_plan.AppendRow(m_curr_row);

                                newrow = new UnwindPlan::Row;
                                *newrow = *m_curr_row.get();
                                m_curr_row.reset(newrow);

                                reinstate_prologue_next_instruction = false;
                                last_instruction_restored_return_addr_reg = false; 
                                m_curr_insn_is_branch_immediate = false;
                            }

                            // clear both of these if either one wasn't set
                            if (last_instruction_restored_return_addr_reg)
                            {
                                last_instruction_restored_return_addr_reg = false;
                            }
                            if (m_curr_insn_is_branch_immediate)
                            {
                                m_curr_insn_is_branch_immediate = false;
                            }
 
                            // Stop updating the prologue instructions if we've seen 8 non-prologue instructions
                            // in a row.
                            if (instructions_since_last_prologue_insn++ < 8)
                            {
                                UnwindPlan::Row *newrow = new UnwindPlan::Row;
                                *newrow = *m_curr_row.get();
                                prologue_completed_row.reset(newrow);
                                if (log && log->GetVerbose())
                                    log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- saving a copy of the current row as the prologue row.");
                            }
                        }
                    }
                }
            }
            // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
            // I'll fix that but for now, just clear the list and it will go away nicely.
            disasm_sp->GetInstructionList().Clear();
        }
        
        if (log && log->GetVerbose ())
        {
            StreamString strm;
            lldb::addr_t base_addr = range.GetBaseAddress().GetLoadAddress(thread.CalculateTarget().get());
            strm.Printf ("Resulting unwind rows for [0x%" PRIx64 " - 0x%" PRIx64 "):", base_addr, base_addr + range.GetByteSize());
            unwind_plan.Dump(strm, &thread, base_addr);
            log->PutCString (strm.GetData());
        }
        return unwind_plan.GetRowCount() > 0;
    }
    return false;
}
开发者ID:jashank,项目名称:freebsd,代码行数:101,代码来源:UnwindAssemblyInstEmulation.cpp


注:本文中的Thread::CalculateTarget方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。