diff options
| author | Jason Molenda <jmolenda@apple.com> | 2015-01-08 06:41:12 +0000 |
|---|---|---|
| committer | Jason Molenda <jmolenda@apple.com> | 2015-01-08 06:41:12 +0000 |
| commit | 4535ecb1f37ee1e16c8a5ec008e22d6bc89515c8 (patch) | |
| tree | 3eef1067a8e45327de9f6702e276550f215b7c27 /lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp | |
| parent | a257ab08038df7a2ef0262d04548f25e62cf7cc1 (diff) | |
| download | bcm5719-llvm-4535ecb1f37ee1e16c8a5ec008e22d6bc89515c8.tar.gz bcm5719-llvm-4535ecb1f37ee1e16c8a5ec008e22d6bc89515c8.zip | |
Have AssemblyParse_x86::get_non_call_site_unwind_plan track
which registers have been spilled (saved to the stack) - and
if we see that same register being saved to the stack again,
don't record that, it's something specific to this stack frame.
I found a code sequence for i386 where clang did a push %esi
and then later in the function it did movl %esi, -0x7c(%ebp)
and that second save of a scratch value overrode the original
push location.
<rdar://problem/19171178>
llvm-svn: 225431
Diffstat (limited to 'lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp')
| -rw-r--r-- | lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp index 411e95e75ae..730784bb2db 100644 --- a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp +++ b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp @@ -638,6 +638,12 @@ AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan) *newrow = *row.get(); row.reset(newrow); + // Track which registers have been saved so far in the prologue. + // If we see another push of that register, it's not part of the prologue. + // The register numbers used here are the machine register #'s + // (i386_register_numbers, x86_64_register_numbers). + std::vector<bool> saved_registers(32, false); + const bool prefer_file_cache = true; Target *target = m_exe_ctx.GetTargetPtr(); @@ -707,12 +713,15 @@ AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan) row->SetCFAOffset (current_sp_bytes_offset_from_cfa); } // record where non-volatile (callee-saved, spilled) registers are saved on the stack - if (nonvolatile_reg_p (machine_regno) && machine_regno_to_lldb_regno (machine_regno, lldb_regno)) + if (nonvolatile_reg_p (machine_regno) + && machine_regno_to_lldb_regno (machine_regno, lldb_regno) + && saved_registers[machine_regno] == false) { need_to_push_row = true; UnwindPlan::Row::RegisterLocation regloc; regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa); row->SetRegisterInfo (lldb_regno, regloc); + saved_registers[machine_regno] = true; } if (need_to_push_row) { @@ -728,8 +737,10 @@ AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan) if (mov_reg_to_local_stack_frame_p (machine_regno, stack_offset) && nonvolatile_reg_p (machine_regno)) { - if (machine_regno_to_lldb_regno (machine_regno, lldb_regno)) + if (machine_regno_to_lldb_regno (machine_regno, lldb_regno) && saved_registers[machine_regno] == false) { + saved_registers[machine_regno] = true; + row->SetOffset (current_func_text_offset + insn_len); UnwindPlan::Row::RegisterLocation regloc; |

