diff options
Diffstat (limited to 'lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp')
-rw-r--r-- | lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp | 38 |
1 files changed, 18 insertions, 20 deletions
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index ec57eb5f1fc..c9e942e6ba6 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -13587,10 +13587,7 @@ EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); else if (m_opcode_mode == eModeARM) opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); - - if (opcode_data == NULL) - return false; - + const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; @@ -13614,16 +13611,19 @@ EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) if (!success) return false; } - - // Call the Emulate... function. - success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); - if (!success) - return false; + + // Call the Emulate... function if we managed to decode the opcode. + if (opcode_data) + { + 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) + (opcode_data == nullptr || opcode_data->callback != &EmulateInstructionARM::EmulateIT)) m_it_session.ITAdvance(); if (auto_advance_pc) @@ -13631,30 +13631,28 @@ EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); if (!success) return false; - + if (auto_advance_pc && (after_pc_value == orig_pc_value)) { - if (opcode_data->size == eSize32) - after_pc_value += 4; - else if (opcode_data->size == eSize16) - after_pc_value += 2; - + after_pc_value += m_opcode.GetByteSize(); + EmulateInstruction::Context context; context.type = eContextAdvancePC; context.SetNoArgs(); if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) return false; - } } return true; } -bool -EmulateInstructionARM::IsInstructionConditional() +EmulateInstruction::InstructionCondition +EmulateInstructionARM::GetInstructionCondition() { const uint32_t cond = CurrentCond (m_opcode.GetOpcode32()); - return cond != 0xe && cond != 0xf && cond != UINT32_MAX; + if (cond == 0xe || cond == 0xf || cond == UINT32_MAX) + return EmulateInstruction::UnconditionalCondition; + return cond; } bool |