Index: source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h =================================================================== --- source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h +++ source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h @@ -142,7 +142,7 @@ m_pushed_regs(), m_curr_row_modified (false), m_curr_insn_is_branch_immediate (false), - m_curr_insn_restored_a_register (false) + m_curr_insn_part_of_epilogue (false) { if (m_inst_emulator_ap.get()) { @@ -183,8 +183,8 @@ bool m_curr_row_modified; // The instruction we're examining is a branch immediate instruction bool m_curr_insn_is_branch_immediate; - // The instruction we're processing restored a caller's reg value (e.g. in an epilogue) - bool m_curr_insn_restored_a_register; + // The instruction we're processing can only appear in the epilogue. + bool m_curr_insn_part_of_epilogue; }; #endif // liblldb_UnwindAssemblyInstEmulation_h_ Index: source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp =================================================================== --- source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp +++ source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp @@ -140,7 +140,7 @@ for (size_t idx=0; idxEvaluateInstruction (eEmulateInstructionOptionIgnoreConditions); + // If the previous instruction was a return-to-caller (epilogue), and we're still executing + // instructions in this function, there must be a code path that jumps over that epilogue. + // Also detect the case where we epilogue & branch imm to another function (tail-call opt) + // instead of a normal pop lr-into-pc exit. + // Reinstate the frame setup from the prologue. + if (reinstate_prologue_next_instruction + || (m_curr_insn_is_branch_immediate && last_instruction_restored_return_addr_reg)) + { + if (log && log->GetVerbose()) + log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- Reinstating prologue instruction set"); + UnwindPlan::Row *newrow = new UnwindPlan::Row; + *newrow = *prologue_completed_row.get(); + m_curr_row.reset(newrow); + m_curr_row->SetOffset (inst->GetAddress().GetFileAddress() - base_addr); + unwind_plan.AppendRow(m_curr_row); + + newrow = new UnwindPlan::Row; + *newrow = *m_curr_row.get(); + m_curr_row.reset(newrow); + + reinstate_prologue_next_instruction = false; + last_instruction_restored_return_addr_reg = false; + m_curr_insn_is_branch_immediate = false; + } + + // clear both of these if either one wasn't set + if (last_instruction_restored_return_addr_reg) + { + last_instruction_restored_return_addr_reg = false; + } + if (m_curr_insn_is_branch_immediate) + { + m_curr_insn_is_branch_immediate = false; + } + // Were there any changes to the CFI while evaluating this instruction? if (m_curr_row_modified) { @@ -172,10 +207,10 @@ *newrow = *m_curr_row.get(); m_curr_row.reset(newrow); - // If m_curr_insn_restored_a_register == true, we're looking at an epilogue instruction. - // Set instructions_since_last_prologue_insn to a very high number so we don't append + // If m_curr_insn_part_of_epilogue, we're looking at an epilogue instruction. + // Set instructions_since_last_prologue_insn to a very high number so we don't append // any of these epilogue instructions to our prologue_complete row. - if (m_curr_insn_restored_a_register == false && instructions_since_last_prologue_insn < 8) + if (m_curr_insn_part_of_epilogue == false && instructions_since_last_prologue_insn < 8) instructions_since_last_prologue_insn = 0; else instructions_since_last_prologue_insn = 99; @@ -218,53 +253,16 @@ last_instruction_restored_return_addr_reg = true; } } - else - { - // If the previous instruction was a return-to-caller (epilogue), and we're still executing - // instructions in this function, there must be a code path that jumps over that epilogue. - // Also detect the case where we epilogue & branch imm to another function (tail-call opt) - // instead of a normal pop lr-into-pc exit. - // Reinstate the frame setup from the prologue. - if (reinstate_prologue_next_instruction - || (m_curr_insn_is_branch_immediate && last_instruction_restored_return_addr_reg)) - { - if (log && log->GetVerbose()) - log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- Reinstating prologue instruction set"); - UnwindPlan::Row *newrow = new UnwindPlan::Row; - *newrow = *prologue_completed_row.get(); - m_curr_row.reset(newrow); - m_curr_row->SetOffset (inst->GetAddress().GetFileAddress() + inst->GetOpcode().GetByteSize() - base_addr); - unwind_plan.AppendRow(m_curr_row); - - newrow = new UnwindPlan::Row; - *newrow = *m_curr_row.get(); - m_curr_row.reset(newrow); - - reinstate_prologue_next_instruction = false; - last_instruction_restored_return_addr_reg = false; - m_curr_insn_is_branch_immediate = false; - } - // clear both of these if either one wasn't set - if (last_instruction_restored_return_addr_reg) - { - last_instruction_restored_return_addr_reg = false; - } - if (m_curr_insn_is_branch_immediate) - { - m_curr_insn_is_branch_immediate = false; - } - - // Stop updating the prologue instructions if we've seen 8 non-prologue instructions - // in a row. - if (instructions_since_last_prologue_insn++ < 8) - { - UnwindPlan::Row *newrow = new UnwindPlan::Row; - *newrow = *m_curr_row.get(); - prologue_completed_row.reset(newrow); - if (log && log->GetVerbose()) - log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- saving a copy of the current row as the prologue row."); - } + // Stop updating the prologue instructions if we've seen 8 non-prologue instructions + // in a row. + if (instructions_since_last_prologue_insn++ < 8) + { + UnwindPlan::Row *newrow = new UnwindPlan::Row; + *newrow = *m_curr_row.get(); + prologue_completed_row.reset(newrow); + if (log && log->GetVerbose()) + log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- saving a copy of the current row as the prologue row."); } } } @@ -641,7 +639,6 @@ { m_curr_row->SetRegisterLocationToRegister (reg_num, reg_num, must_replace); m_curr_row_modified = true; - m_curr_insn_restored_a_register = true; if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_RA) { @@ -678,7 +675,7 @@ { m_curr_row->SetRegisterLocationToSame (reg_num, must_replace); m_curr_row_modified = true; - m_curr_insn_restored_a_register = true; + m_curr_insn_part_of_epilogue = true; } } break;