[Lldb-commits] [lldb] r259509 - Fix single stepping over the IT instruction

Tamas Berghammer via lldb-commits lldb-commits at lists.llvm.org
Tue Feb 2 06:32:11 PST 2016


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);




More information about the lldb-commits mailing list