[Lldb-commits] [lldb] r235292 - Auto advance pc for signle stepping on arm when emulation failes

Tamas Berghammer tberghammer at google.com
Mon Apr 20 03:31:23 PDT 2015


Author: tberghammer
Date: Mon Apr 20 05:31:22 2015
New Revision: 235292

URL: http://llvm.org/viewvc/llvm-project?rev=235292&view=rev
Log:
Auto advance pc for signle stepping on arm when emulation failes

The arm instruction emulation handles only some of the opcode (including
all of them modifying the PC). For the rest of the instructions we can
advance the PC by the size of the instruction as they don't modify the
PC on any other way.

Differential revision: http://reviews.llvm.org/D9076

Modified:
    lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp?rev=235292&r1=235291&r2=235292&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp Mon Apr 20 05:31:22 2015
@@ -3894,16 +3894,25 @@ WriteRegisterCallback (EmulateInstructio
     return true;
 }
 
-static size_t WriteMemoryCallback (EmulateInstruction *instruction,
-                                   void *baton,
-                                   const EmulateInstruction::Context &context, 
-                                   lldb::addr_t addr, 
-                                   const void *dst,
-                                   size_t length)
+static size_t
+WriteMemoryCallback (EmulateInstruction *instruction,
+                     void *baton,
+                     const EmulateInstruction::Context &context, 
+                     lldb::addr_t addr, 
+                     const void *dst,
+                     size_t length)
 {
     return length;
 }
 
+static lldb::addr_t
+ReadCpsr (NativeRegisterContext* regsiter_context)
+{
+    const RegisterInfo* cpsr_info = regsiter_context->GetRegisterInfo(
+            eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
+    return regsiter_context->ReadRegisterAsUnsigned(cpsr_info, LLDB_INVALID_ADDRESS);
+}
+
 Error
 NativeProcessLinux::SingleStep(lldb::tid_t tid, uint32_t signo)
 {
@@ -3914,7 +3923,7 @@ NativeProcessLinux::SingleStep(lldb::tid
         EmulateInstruction::FindPlugin(m_arch, eInstructionTypePCModifying, nullptr));
 
     if (emulator_ap == nullptr)
-        return Error("Instrunction emulator not found!");
+        return Error("Instruction emulator not found!");
 
     EmulatorBaton baton(this, register_context_sp.get());
     emulator_ap->SetBaton(&baton);
@@ -3926,20 +3935,31 @@ NativeProcessLinux::SingleStep(lldb::tid
     if (!emulator_ap->ReadInstruction())
         return Error("Read instruction failed!");
 
-    if (!emulator_ap->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC))
-        return Error("Evaluate instrcution failed!");
-
-    lldb::addr_t next_pc = baton.m_pc.GetAsUInt32();
-    lldb::addr_t next_cpsr = 0;
-    if (baton.m_cpsr.GetType() != RegisterValue::eTypeInvalid)
+    lldb::addr_t next_pc;
+    lldb::addr_t next_cpsr;
+    if (emulator_ap->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC))
+    {
+        next_pc = baton.m_pc.GetAsUInt32();
+        if (baton.m_cpsr.GetType() != RegisterValue::eTypeInvalid)
+            next_cpsr = baton.m_cpsr.GetAsUInt32();
+        else
+            next_cpsr = ReadCpsr (register_context_sp.get());
+    }
+    else if (baton.m_pc.GetType() == RegisterValue::eTypeInvalid)
     {
-        next_cpsr = baton.m_cpsr.GetAsUInt32();
+        // Emulate instruction failed and it haven't changed PC. Advance PC
+        // with the size of the current opcode because the emulation of all
+        // PC modifying instruction should be successful. The failure most
+        // likely caused by a not supported instruction which don't modify PC.
+        next_pc = register_context_sp->GetPC() + emulator_ap->GetOpcode().GetByteSize();
+        next_cpsr = ReadCpsr (register_context_sp.get());
     }
     else
     {
-        const RegisterInfo* cpsr_info = register_context_sp->GetRegisterInfo(
-            eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
-        next_cpsr = register_context_sp->ReadRegisterAsUnsigned(cpsr_info, LLDB_INVALID_ADDRESS);
+        // The instruction emulation failed after it modified the PC. It is an
+        // unknown error where we can't continue because the next instruction is
+        // modifying the PC but we don't  know how.
+        return Error ("Instruction emulation failed unexpectedly.");
     }
 
     if (next_cpsr & 0x20)





More information about the lldb-commits mailing list