forked from OSchip/llvm-project
Ignore "push/pop {sp}" in emulation based unwinding
These instructions confusing the unwind code because in case of a push it assumes that the original valu of a register is pushed to the stack what is not neccessarily true in case of SP. The same is true for the pop (in the opposite way). Differential revision: http://reviews.llvm.org/D10806 llvm-svn: 241051
This commit is contained in:
parent
0b736f1ed0
commit
f366af309a
|
@ -422,13 +422,17 @@ UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction,
|
||||||
case EmulateInstruction::eContextPushRegisterOnStack:
|
case EmulateInstruction::eContextPushRegisterOnStack:
|
||||||
{
|
{
|
||||||
uint32_t reg_num = LLDB_INVALID_REGNUM;
|
uint32_t reg_num = LLDB_INVALID_REGNUM;
|
||||||
const uint32_t unwind_reg_kind = m_unwind_plan_ptr->GetRegisterKind();
|
uint32_t generic_regnum = LLDB_INVALID_REGNUM;
|
||||||
if (context.info_type == EmulateInstruction::eInfoTypeRegisterToRegisterPlusOffset)
|
if (context.info_type == EmulateInstruction::eInfoTypeRegisterToRegisterPlusOffset)
|
||||||
|
{
|
||||||
|
const uint32_t unwind_reg_kind = m_unwind_plan_ptr->GetRegisterKind();
|
||||||
reg_num = context.info.RegisterToRegisterPlusOffset.data_reg.kinds[unwind_reg_kind];
|
reg_num = context.info.RegisterToRegisterPlusOffset.data_reg.kinds[unwind_reg_kind];
|
||||||
|
generic_regnum = context.info.RegisterToRegisterPlusOffset.data_reg.kinds[eRegisterKindGeneric];
|
||||||
|
}
|
||||||
else
|
else
|
||||||
assert (!"unhandled case, add code to handle this!");
|
assert (!"unhandled case, add code to handle this!");
|
||||||
|
|
||||||
if (reg_num != LLDB_INVALID_REGNUM)
|
if (reg_num != LLDB_INVALID_REGNUM && generic_regnum != LLDB_REGNUM_GENERIC_SP)
|
||||||
{
|
{
|
||||||
if (m_pushed_regs.find (reg_num) == m_pushed_regs.end())
|
if (m_pushed_regs.find (reg_num) == m_pushed_regs.end())
|
||||||
{
|
{
|
||||||
|
@ -570,7 +574,8 @@ UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
|
||||||
case EmulateInstruction::eContextPopRegisterOffStack:
|
case EmulateInstruction::eContextPopRegisterOffStack:
|
||||||
{
|
{
|
||||||
const uint32_t reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
|
const uint32_t reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
|
||||||
if (reg_num != LLDB_INVALID_REGNUM)
|
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->SetRegisterLocationToSame (reg_num, /*must_replace*/ false);
|
||||||
m_curr_row_modified = true;
|
m_curr_row_modified = true;
|
||||||
|
|
|
@ -40,8 +40,6 @@ class StandardUnwindTest(TestBase):
|
||||||
"__memcpy_base", # Function reached by a fall through from the previous function
|
"__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
|
"__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?
|
"__subdf3", # __aeabi_ui2d jumps into the middle of the function. Possibly missing symbol?
|
||||||
"__aeabi_ldivmod", # llvm.org/pr23879 ("push {sp}" not handled correctly)
|
|
||||||
"__aeabi_uldivmod", # llvm.org/pr23879 ("push {sp}" not handled correctly)
|
|
||||||
]
|
]
|
||||||
no_step_function_names = [
|
no_step_function_names = [
|
||||||
"__sync_fetch_and_add_4", # Calls into a special SO where we can't set a breakpoint
|
"__sync_fetch_and_add_4", # Calls into a special SO where we can't set a breakpoint
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
//===-- divmod.cpp ----------------------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char const *argv[])
|
||||||
|
{
|
||||||
|
signed long long a = 123456789, b = 12, c = a / b, d = a % b;
|
||||||
|
unsigned long long e = 123456789, f = 12, g = e / f, h = e % f;
|
||||||
|
}
|
Loading…
Reference in New Issue