예제 #1
0
// get value object specialized to work with llvm IR types
lldb::ValueObjectSP
ABISysV_hexagon::GetReturnValueObjectImpl( lldb_private::Thread &thread, llvm::Type &retType ) const
{
    Value value;
    ValueObjectSP vObjSP;

    // get the current register context
    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    if (!reg_ctx)
        return vObjSP;

    // for now just pop R0 to find the return value
    const lldb_private::RegisterInfo *r0_info = reg_ctx->GetRegisterInfoAtIndex( 0 );
    if ( r0_info == nullptr )
        return vObjSP;
    
    // void return type
    if ( retType.isVoidTy( ) )
    {
        value.GetScalar( ) = 0;
    }
    // integer / pointer return type
    else
    if ( retType.isIntegerTy( ) || retType.isPointerTy( ) )
    {
        // read r0 register value
        lldb_private::RegisterValue r0_value;
        if ( !reg_ctx->ReadRegister( r0_info, r0_value ) )
            return vObjSP;

        // push r0 into value
        uint32_t r0_u32 = r0_value.GetAsUInt32( );

        // account for integer size
        if ( retType.isIntegerTy() && retType.isSized() )
        {
            uint64_t size = retType.getScalarSizeInBits( );
            uint64_t mask = ( 1ull << size ) - 1;
            // mask out higher order bits then the type we expect
            r0_u32 &= mask;
        }

        value.GetScalar( ) = r0_u32;
    }
    // unsupported return type
    else
        return vObjSP;

    // pack the value into a ValueObjectSP
    vObjSP = ValueObjectConstResult::Create
    (
        thread.GetStackFrameAtIndex(0).get(),
        value,
        ConstString("")
    );
    return vObjSP;
}
예제 #2
0
RegisterNumber::RegisterNumber(lldb_private::Thread &thread,
                               lldb::RegisterKind kind, uint32_t num)
    : m_reg_ctx_sp(thread.GetRegisterContext()), m_regnum(num), m_kind(kind),
      m_kind_regnum_map(), m_name("") {
  if (m_reg_ctx_sp.get()) {
    const lldb_private::RegisterInfo *reginfo =
        m_reg_ctx_sp->GetRegisterInfoAtIndex(
            GetAsKind(lldb::eRegisterKindLLDB));
    if (reginfo && reginfo->name) {
      m_name = reginfo->name;
    }
  }
}
예제 #3
0
void RegisterNumber::init(lldb_private::Thread &thread, lldb::RegisterKind kind,
                          uint32_t num) {
  m_reg_ctx_sp = thread.GetRegisterContext();
  m_regnum = num;
  m_kind = kind;
  if (m_reg_ctx_sp.get()) {
    const lldb_private::RegisterInfo *reginfo =
        m_reg_ctx_sp->GetRegisterInfoAtIndex(
            GetAsKind(lldb::eRegisterKindLLDB));
    if (reginfo && reginfo->name) {
      m_name = reginfo->name;
    }
  }
}
예제 #4
0
static void
StopInfoOverrideCallbackTypeARM(lldb_private::Thread &thread)
{
    // We need to check if we are stopped in Thumb mode in a IT instruction
    // and detect if the condition doesn't pass. If this is the case it means
    // we won't actually execute this instruction. If this happens we need to
    // clear the stop reason to no thread plans think we are stopped for a
    // reason and the plans should keep going.
    //
    // We do this because when single stepping many ARM processes, debuggers
    // often use the BVR/BCR registers that says "stop when the PC is not
    // equal to its current value". This method of stepping means we can end
    // up stopping on instructions inside an if/then block that wouldn't get
    // executed. By fixing this we can stop the debugger from seeming like
    // you stepped through both the "if" _and_ the "else" clause when source
    // level stepping because the debugger stops regardless due to the BVR/BCR
    // triggering a stop.
    //
    // It also means we can set breakpoints on instructions inside an an
    // if/then block and correctly skip them if we use the BKPT instruction.
    // The ARM and Thumb BKPT instructions are unconditional even when executed
    // in a Thumb IT block.
    //
    // If your debugger inserts software traps in ARM/Thumb code, it will
    // need to use 16 and 32 bit instruction for 16 and 32 bit thumb
    // instructions respectively. If your debugger inserts a 16 bit thumb
    // trap on top of a 32 bit thumb instruction for an opcode that is inside
    // an if/then, it will change the it/then to conditionally execute your
    // 16 bit trap and then cause your program to crash if it executes the
    // trailing 16 bits (the second half of the 32 bit thumb instruction you
    // partially overwrote).

    RegisterContextSP reg_ctx_sp (thread.GetRegisterContext());
    if (reg_ctx_sp)
    {
        const uint32_t cpsr = reg_ctx_sp->GetFlags(0);
        if (cpsr != 0)
        {
            // Read the J and T bits to get the ISETSTATE
            const uint32_t J = Bit32(cpsr, 24);
            const uint32_t T = Bit32(cpsr, 5);
            const uint32_t ISETSTATE = J << 1 | T;
            if (ISETSTATE == 0)
            {
                // NOTE: I am pretty sure we want to enable the code below
                // that detects when we stop on an instruction in ARM mode
                // that is conditional and the condition doesn't pass. This
                // can happen if you set a breakpoint on an instruction that
                // is conditional. We currently will _always_ stop on the
                // instruction which is bad. You can also run into this while
                // single stepping and you could appear to run code in the "if"
                // and in the "else" clause because it would stop at all of the
                // conditional instructions in both.
                // In such cases, we really don't want to stop at this location.
                // I will check with the lldb-dev list first before I enable this.
#if 0
                // ARM mode: check for condition on intsruction
                const addr_t pc = reg_ctx_sp->GetPC();
                Error error;
                // If we fail to read the opcode we will get UINT64_MAX as the
                // result in "opcode" which we can use to detect if we read a
                // valid opcode.
                const uint64_t opcode = thread.GetProcess()->ReadUnsignedIntegerFromMemory(pc, 4, UINT64_MAX, error);
                if (opcode <= UINT32_MAX)
                {
                    const uint32_t condition = Bits32((uint32_t)opcode, 31, 28);
                    if (ARMConditionPassed(condition, cpsr) == false)
                    {
                        // We ARE stopped on an ARM instruction whose condition doesn't
                        // pass so this instruction won't get executed.
                        // Regardless of why it stopped, we need to clear the stop info
                        thread.SetStopInfo (StopInfoSP());
                    }
                }
#endif
            }
            else if (ISETSTATE == 1)
            {
                // Thumb mode
                const uint32_t ITSTATE = Bits32 (cpsr, 15, 10) << 2 | Bits32 (cpsr, 26, 25);
                if (ITSTATE != 0)
                {
                    const uint32_t condition = Bits32(ITSTATE, 7, 4);
                    if (ARMConditionPassed(condition, cpsr) == false)
                    {
                        // We ARE stopped in a Thumb IT instruction on an instruction whose
                        // condition doesn't pass so this instruction won't get executed.
                        // Regardless of why it stopped, we need to clear the stop info
                        thread.SetStopInfo (StopInfoSP());
                    }
                }
            }
        }
    }
}