diff options
Diffstat (limited to 'source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp')
| -rw-r--r-- | source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp | 81 | 
1 files changed, 45 insertions, 36 deletions
diff --git a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index d646d4d4754a..884078b27175 100644 --- a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -13004,7 +13004,7 @@ EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address  {      if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))      { -        if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) +        if (m_arch.GetTriple().getArch() == llvm::Triple::thumb || m_arch.IsAlwaysThumbInstructions ())              m_opcode_mode = eModeThumb;          else          { @@ -13017,7 +13017,7 @@ EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address              else                  return false;          } -        if (m_opcode_mode == eModeThumb) +        if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions ())              m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;          else              m_opcode_cpsr = CPSR_MODE_USR; @@ -13040,7 +13040,7 @@ EmulateInstructionARM::ReadInstruction ()              read_inst_context.type = eContextReadOpcode;              read_inst_context.SetNoArgs (); -            if (m_opcode_cpsr & MASK_CPSR_T) +            if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions ())              {                  m_opcode_mode = eModeThumb;                  uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); @@ -13062,6 +13062,15 @@ EmulateInstructionARM::ReadInstruction ()                  m_opcode_mode = eModeARM;                  m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder());              } + +            if (!m_ignore_conditions) +            { +                // If we are not ignoreing the conditions then init the it session from the current +                // value of cpsr. +                uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) | Bits32(m_opcode_cpsr, 26, 25); +                if (it != 0) +                    m_it_session.InitIT(it); +            }          }      }      if (!success) @@ -13572,20 +13581,13 @@ EmulateInstructionARM::WriteFlags (Context &context,  bool  EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)  { -    // Advance the ITSTATE bits to their values for the next instruction. -    if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) -        m_it_session.ITAdvance(); -      ARMOpcode *opcode_data = NULL;      if (m_opcode_mode == eModeThumb)          opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);      else if (m_opcode_mode == eModeARM)          opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); -         -    if (opcode_data == NULL) -        return false; -     +      const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;      m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; @@ -13609,41 +13611,48 @@ EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)          if (!success)              return false;      } -     -    // Call the Emulate... function. -    success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);   -    if (!success) -        return false; -         + +    // Call the Emulate... function if we managed to decode the opcode. +    if (opcode_data) +    { +        success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);   +        if (!success) +            return false; +    } + +    // Advance the ITSTATE bits to their values for the next instruction if we haven't just executed +    // an IT instruction what initialized it. +    if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() && +        (opcode_data == nullptr || opcode_data->callback != &EmulateInstructionARM::EmulateIT)) +        m_it_session.ITAdvance(); +      if (auto_advance_pc)      {          uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);          if (!success)              return false; -             +          if (auto_advance_pc && (after_pc_value == orig_pc_value))          { -            if (opcode_data->size == eSize32) -                after_pc_value += 4; -            else if (opcode_data->size == eSize16) -                after_pc_value += 2; -                 +            after_pc_value += m_opcode.GetByteSize(); +              EmulateInstruction::Context context;              context.type = eContextAdvancePC;              context.SetNoArgs();              if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))                  return false; -                          }      }      return true;  } -bool -EmulateInstructionARM::IsInstructionConditional() +EmulateInstruction::InstructionCondition +EmulateInstructionARM::GetInstructionCondition()  {      const uint32_t cond = CurrentCond (m_opcode.GetOpcode32()); -    return cond != 0xe && cond != 0xf && cond != UINT32_MAX; +    if (cond == 0xe || cond == 0xf || cond == UINT32_MAX) +        return EmulateInstruction::UnconditionalCondition; +    return cond;  }  bool @@ -13669,19 +13678,19 @@ EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, Option      }      test_opcode = value_sp->GetUInt64Value (); -    if (arch.GetTriple().getArch() == llvm::Triple::arm) -    { -        m_opcode_mode = eModeARM; -        m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); -    } -    else if (arch.GetTriple().getArch() == llvm::Triple::thumb) + +    if (arch.GetTriple().getArch() == llvm::Triple::thumb || arch.IsAlwaysThumbInstructions ())      {          m_opcode_mode = eModeThumb;          if (test_opcode < 0x10000) -            m_opcode.SetOpcode16 (test_opcode, GetByteOrder()); +            m_opcode.SetOpcode16 (test_opcode, endian::InlHostByteOrder());          else -            m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); - +            m_opcode.SetOpcode32 (test_opcode, endian::InlHostByteOrder()); +    } +    else if (arch.GetTriple().getArch() == llvm::Triple::arm) +    { +        m_opcode_mode = eModeARM; +        m_opcode.SetOpcode32 (test_opcode, endian::InlHostByteOrder());      }      else      {  | 
