[Lldb-commits] [lldb] r225431 - Have AssemblyParse_x86::get_non_call_site_unwind_plan track

Jason Molenda jmolenda at apple.com
Wed Jan 7 22:41:12 PST 2015


Author: jmolenda
Date: Thu Jan  8 00:41:12 2015
New Revision: 225431

URL: http://llvm.org/viewvc/llvm-project?rev=225431&view=rev
Log:
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> 

Modified:
    lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp

Modified: lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp?rev=225431&r1=225430&r2=225431&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp (original)
+++ lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp Thu Jan  8 00:41:12 2015
@@ -638,6 +638,12 @@ AssemblyParse_x86::get_non_call_site_unw
     *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_unw
                 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_unw
 
         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;
 





More information about the lldb-commits mailing list