Author: omjavaid Date: Tue Jan 5 10:56:13 2016 New Revision: 256847 URL: http://llvm.org/viewvc/llvm-project?rev=256847&view=rev Log: Fix for undefined behavior while updating PC value on arm-linux
Differential revision: http://reviews.llvm.org/D15877 Modified: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp Modified: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp?rev=256847&r1=256846&r2=256847&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp (original) +++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp Tue Jan 5 10:56:13 2016 @@ -973,7 +973,24 @@ NativeRegisterContextLinux_arm::DoWriteR 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)); } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits