Author: tberghammer Date: Tue Feb 2 08:32:11 2016 New Revision: 259509 URL: http://llvm.org/viewvc/llvm-project?rev=259509&view=rev Log: 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 Modified: lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp Modified: lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp?rev=259509&r1=259508&r2=259509&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp (original) +++ lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp Tue Feb 2 08:32:11 2016 @@ -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 (Conte 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) @@ -13614,7 +13619,13 @@ EmulateInstructionARM::EvaluateInstructi 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->callback != &EmulateInstructionARM::EmulateIT) + m_it_session.ITAdvance(); + if (auto_advance_pc) { uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits