Index: lldb/trunk/include/lldb/Core/EmulateInstruction.h =================================================================== --- lldb/trunk/include/lldb/Core/EmulateInstruction.h +++ lldb/trunk/include/lldb/Core/EmulateInstruction.h @@ -404,7 +404,10 @@ virtual bool EvaluateInstruction (uint32_t evaluate_options) = 0; - + + virtual bool + IsInstructionConditional() { return false; } + virtual bool TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) = 0; Index: lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h =================================================================== --- lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h +++ lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h @@ -165,7 +165,10 @@ virtual bool EvaluateInstruction (uint32_t evaluate_options); - + + bool + IsInstructionConditional() override; + virtual bool TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data); @@ -180,9 +183,7 @@ ArchVersion(); bool - ConditionPassed (const uint32_t opcode, - bool *is_conditional = NULL); // Filled in with true if the opcode is a conditional opcode - // Filled in with false if the opcode is always executed + ConditionPassed (const uint32_t opcode); uint32_t CurrentCond (const uint32_t opcode); Index: lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp =================================================================== --- lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -387,9 +387,8 @@ } #endif - bool conditional = false; bool success = false; - if (ConditionPassed(opcode, &conditional)) + if (ConditionPassed(opcode)) { const uint32_t addr_byte_size = GetAddressByteSize(); const addr_t sp = ReadCoreReg (SP_REG, &success); @@ -442,10 +441,7 @@ uint32_t i; EmulateInstruction::Context context; - if (conditional) - context.type = EmulateInstruction::eContextRegisterStore; - else - context.type = EmulateInstruction::eContextPushRegisterOnStack; + context.type = EmulateInstruction::eContextPushRegisterOnStack; RegisterInfo reg_info; RegisterInfo sp_reg; GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); @@ -511,8 +507,7 @@ bool success = false; - bool conditional = false; - if (ConditionPassed(opcode, &conditional)) + if (ConditionPassed(opcode)) { const uint32_t addr_byte_size = GetAddressByteSize(); const addr_t sp = ReadCoreReg (SP_REG, &success); @@ -574,10 +569,7 @@ uint32_t i, data; EmulateInstruction::Context context; - if (conditional) - context.type = EmulateInstruction::eContextRegisterLoad; - else - context.type = EmulateInstruction::eContextPopRegisterOffStack; + context.type = EmulateInstruction::eContextPopRegisterOffStack; RegisterInfo sp_reg; GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); @@ -1971,9 +1963,8 @@ } #endif - bool conditional = false; bool success = false; - if (ConditionPassed(opcode, &conditional)) + if (ConditionPassed(opcode)) { const uint32_t addr_byte_size = GetAddressByteSize(); const addr_t sp = ReadCoreReg (SP_REG, &success); @@ -2018,10 +2009,7 @@ addr = sp; EmulateInstruction::Context context; - if (conditional) - context.type = EmulateInstruction::eContextRegisterStore; - else - context.type = EmulateInstruction::eContextPushRegisterOnStack; + context.type = EmulateInstruction::eContextPushRegisterOnStack; RegisterInfo sp_reg; RegisterInfo dwarf_reg; @@ -2082,8 +2070,7 @@ #endif bool success = false; - bool conditional = false; - if (ConditionPassed(opcode, &conditional)) + if (ConditionPassed(opcode)) { const uint32_t addr_byte_size = GetAddressByteSize(); const addr_t sp = ReadCoreReg (SP_REG, &success); @@ -2125,10 +2112,8 @@ uint32_t i; EmulateInstruction::Context context; - if (conditional) - context.type = EmulateInstruction::eContextRegisterStore; - else - context.type = EmulateInstruction::eContextPushRegisterOnStack; + context.type = EmulateInstruction::eContextPushRegisterOnStack; + RegisterInfo dwarf_reg; RegisterInfo sp_reg; GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); @@ -2178,8 +2163,7 @@ #endif bool success = false; - bool conditional = false; - if (ConditionPassed(opcode, &conditional)) + if (ConditionPassed(opcode)) { const uint32_t addr_byte_size = GetAddressByteSize(); const addr_t sp = ReadCoreReg (SP_REG, &success); @@ -2222,10 +2206,8 @@ uint64_t data; // uint64_t to accommodate 64-bit registers. EmulateInstruction::Context context; - if (conditional) - context.type = EmulateInstruction::eContextRegisterLoad; - else - context.type = EmulateInstruction::eContextPopRegisterOffStack; + context.type = EmulateInstruction::eContextPopRegisterOffStack; + RegisterInfo dwarf_reg; RegisterInfo sp_reg; GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); @@ -3462,8 +3444,7 @@ #endif bool success = false; - bool conditional = false; - if (ConditionPassed(opcode, &conditional)) + if (ConditionPassed(opcode)) { uint32_t n; uint32_t registers = 0; @@ -3535,12 +3516,7 @@ context.type = EmulateInstruction::eContextRegisterPlusOffset; context.SetRegisterPlusOffset (dwarf_reg, offset); if (wback && (n == 13)) // Pop Instruction - { - if (conditional) - context.type = EmulateInstruction::eContextRegisterLoad; - else - context.type = EmulateInstruction::eContextPopRegisterOffStack; - } + context.type = EmulateInstruction::eContextPopRegisterOffStack; // R[i] = MemA [address, 4]; address = address + 4; uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); @@ -13076,7 +13052,7 @@ } bool -EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional) +EmulateInstructionARM::ConditionPassed (const uint32_t opcode) { // If we are ignoring conditions, then always return true. // this allows us to iterate over disassembly code and still @@ -13084,12 +13060,8 @@ // bits set in the CPSR register... if (m_ignore_conditions) return true; - - if (is_conditional) - *is_conditional = true; const uint32_t cond = CurrentCond (opcode); - if (cond == UINT32_MAX) return false; @@ -13149,8 +13121,6 @@ case 7: // Always execute (cond == 0b1110, or the special 0b1111 which gives // opcodes different meanings, but always means execution happens. - if (is_conditional) - *is_conditional = false; return true; } @@ -13643,6 +13613,13 @@ } bool +EmulateInstructionARM::IsInstructionConditional() +{ + const uint32_t cond = CurrentCond (m_opcode.GetOpcode32()); + return cond != 0xe && cond != 0xf && cond != UINT32_MAX; +} + +bool EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) { if (!test_data) Index: lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h =================================================================== --- lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h +++ lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h @@ -272,7 +272,7 @@ BranchTo (const Context &context, uint32_t N, lldb::addr_t target); bool - ConditionHolds (const uint32_t cond, bool *is_conditional = nullptr); + ConditionHolds (const uint32_t cond); bool UsingAArch32 (); Index: lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp =================================================================== --- lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp +++ lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp @@ -462,7 +462,7 @@ } bool -EmulateInstructionARM64::ConditionHolds (const uint32_t cond, bool *is_conditional) +EmulateInstructionARM64::ConditionHolds (const uint32_t cond) { // If we are ignoring conditions, then always return true. // this allows us to iterate over disassembly code and still @@ -470,10 +470,7 @@ // bits set in the CPSR register... if (m_ignore_conditions) return true; - - if (is_conditional) - *is_conditional = true; - + bool result = false; switch (UnsignedBits(cond, 3, 1)) { @@ -499,13 +496,12 @@ result = (m_opcode_pstate.N == m_opcode_pstate.V && m_opcode_pstate.Z == 0); break; case 7: - result = true; - if (is_conditional) - *is_conditional = false; - break; + // Always execute (cond == 0b1110, or the special 0b1111 which gives + // opcodes different meanings, but always means execution happens. + return true; } - if (cond & 1 && cond != 15) + if (cond & 1) result = !result; return result; } Index: lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp =================================================================== --- lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp +++ lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp @@ -511,7 +511,8 @@ log->PutCString(strm.GetData()); } - SetRegisterValue (*reg_info, reg_value); + if (!instruction->IsInstructionConditional()) + SetRegisterValue (*reg_info, reg_value); switch (context.type) { @@ -573,18 +574,21 @@ case EmulateInstruction::eContextPopRegisterOffStack: { - const uint32_t reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()]; - const uint32_t generic_regnum = reg_info->kinds[eRegisterKindGeneric]; - if (reg_num != LLDB_INVALID_REGNUM && generic_regnum != LLDB_REGNUM_GENERIC_SP) + if (!instruction->IsInstructionConditional()) { - m_curr_row->SetRegisterLocationToSame (reg_num, /*must_replace*/ false); - m_curr_row_modified = true; + const uint32_t reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()]; + const uint32_t generic_regnum = reg_info->kinds[eRegisterKindGeneric]; + if (reg_num != LLDB_INVALID_REGNUM && generic_regnum != LLDB_REGNUM_GENERIC_SP) + { + m_curr_row->SetRegisterLocationToSame (reg_num, /*must_replace*/ false); + m_curr_row_modified = true; + } } } break; case EmulateInstruction::eContextSetFramePointer: - if (!m_fp_is_cfa) + if (!m_fp_is_cfa && !instruction->IsInstructionConditional()) { m_fp_is_cfa = true; m_cfa_reg_info = *reg_info; @@ -599,7 +603,7 @@ case EmulateInstruction::eContextAdjustStackPointer: // If we have created a frame using the frame pointer, don't follow // subsequent adjustments to the stack pointer. - if (!m_fp_is_cfa) + if (!m_fp_is_cfa && !instruction->IsInstructionConditional()) { m_curr_row->GetCFAValue().SetIsRegisterPlusOffset( m_curr_row->GetCFAValue().GetRegisterNumber(), Index: lldb/trunk/test/functionalities/unwind/standard/TestStandardUnwind.py =================================================================== --- lldb/trunk/test/functionalities/unwind/standard/TestStandardUnwind.py +++ lldb/trunk/test/functionalities/unwind/standard/TestStandardUnwind.py @@ -39,7 +39,6 @@ "_start", # Base function on the stack "__memcpy_base", # Function reached by a fall through from the previous function "__memcpy_base_aligned", # Function reached by a fall through from the previous function - "__subdf3", # __aeabi_ui2d jumps into the middle of the function. Possibly missing symbol? ] no_step_function_names = [ "__sync_fetch_and_add_4", # Calls into a special SO where we can't set a breakpoint