[Lldb-commits] [PATCH] D15877: Fix for undefined behavior while updating PC value on arm-linux

Muhammad Omair Javaid via lldb-commits lldb-commits at lists.llvm.org
Mon Jan 4 16:37:34 PST 2016


omjavaid created this revision.
omjavaid added reviewers: tberghammer, clayborg.
omjavaid added a subscriber: lldb-commits.
Herald added subscribers: rengolin, aemerson.

This patch provides fix for the cases where an expression or jump tries to update the value of PC in thumb mode.

As precaution for an undefined behavior encountered while setting PC we will clear thumb bit of new PC if we are already in thumb mode; that is CPSR thumb mode bit is set.

Also if intended behavior of setting new PC value is to change to ARM/Thumb mode then user must switch to arm or thumb mode by explicitly setting mode bit in CPSR. This update to CPSR should be done before writing new PC value.

http://reviews.llvm.org/D15877

Files:
  source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp

Index: source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
===================================================================
--- source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
+++ source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
@@ -973,7 +973,24 @@
     if (error.Fail())
         return error;
 
-    m_gpr_arm[offset / sizeof(uint32_t)] = value.GetAsUInt32();
+    uint32_t reg_value = value.GetAsUInt32();
+    // As precaution for an undefined behavior encountered while setting PC we
+    // will clear thumb bit of new PC if we are already in thumb mode; that is
+    // CPSR thumb mode bit is set.
+    if (offset / sizeof(uint32_t) == gpr_pc_arm)
+    {
+        // Check if we are already in thumb mode and
+    	// thumb bit of current PC is read out to be zero and
+    	// thumb bit of next PC is read out to be one.
+    	if ((m_gpr_arm[gpr_cpsr_arm] &  0x20) &&
+    		!(m_gpr_arm[gpr_pc_arm] &  0x01) &&
+			(value.GetAsUInt32() & 0x01))
+    	{
+    		reg_value &= (~1ull);
+    	}
+    }
+
+    m_gpr_arm[offset / sizeof(uint32_t)] = reg_value;
     return DoWriteGPR(m_gpr_arm, sizeof(m_gpr_arm));
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D15877.43941.patch
Type: text/x-patch
Size: 1168 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20160105/fb9083a9/attachment.bin>


More information about the lldb-commits mailing list