Fix single stepping over the IT instruction
The ARM instruction emulator had 2 bugs related to the handling of the IT instruction causing an error in single stepping: * We haven't initialized the IT mask from the CPSR so if the last instruction of the IT block is a branch and the condition is false then the emulator evaluated the branch what resulted in an incorrect pc for the next instruction. * The ITSTATE was advanced before the execution of each instruction. As a result the emulator was using the condition of following instruction in every case. The ITSTATE should be edvanced after the execution of an instruction except after an IT instruction. Differential revision: http://reviews.llvm.org/D16772 llvm-svn: 259509
This commit is contained in:
parent
926b189a81
commit
8e18fe6e54
|
@ -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,10 +13581,6 @@ 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)
|
||||
|
@ -13615,6 +13620,12 @@ EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
|
|||
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->callback != &EmulateInstructionARM::EmulateIT)
|
||||
m_it_session.ITAdvance();
|
||||
|
||||
if (auto_advance_pc)
|
||||
{
|
||||
uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
|
||||
|
|
Loading…
Reference in New Issue