[Lldb-commits] [lldb] r214783 - Add code to AssemblyParse_x86::get_non_call_site_unwind_plan

Jason Molenda jmolenda at apple.com
Mon Aug 4 14:26:55 PDT 2014


Author: jmolenda
Date: Mon Aug  4 16:26:55 2014
New Revision: 214783

URL: http://llvm.org/viewvc/llvm-project?rev=214783&view=rev
Log:
Add code to AssemblyParse_x86::get_non_call_site_unwind_plan
to recognize an epilogue that ends with a jmp to 
objc_retainAutoreleaseReturnValue instead of a ret instruction.
<rdar://problem/17889928> 

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=214783&r1=214782&r2=214783&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp (original)
+++ lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp Mon Aug  4 16:26:55 2014
@@ -697,17 +697,28 @@ loopnext:
     // Now look at the byte at the end of the AddressRange for a limited attempt at describing the
     // epilogue.  We're looking for the sequence
 
-    //  [ 0x5d ] mov %rbp, %rsp
+    //  [ 0x5d ] mov %rbp, %rsp  (aka pop %rbp)
+    //  [ 0xc3 ] ret
+
+    // or
+
+    //  [ 0x5d ] mov %rbp, %rsp  (aka pop %rbp)
+    //  [ 0xe9 xx xx xx xx ] jmp objc_retainAutoreleaseReturnValue  (this is sometimes the final insn in the function)
+
+    // or
+
+    //  [ 0x5d ] mov %rbp, %rsp  (aka pop %rbp)
     //  [ 0xc3 ] ret
     //  [ 0xe8 xx xx xx xx ] call __stack_chk_fail  (this is sometimes the final insn in the function)
 
     // We want to add a Row describing how to unwind when we're stopped on the 'ret' instruction where the
     // CFA is no longer defined in terms of rbp, but is now defined in terms of rsp like on function entry.
+    // (or the 'jmp' instruction in the second case)
 
     uint64_t ret_insn_offset = LLDB_INVALID_ADDRESS;
     Address end_of_fun(m_func_bounds.GetBaseAddress());
     end_of_fun.SetOffset (end_of_fun.GetOffset() + m_func_bounds.GetByteSize());
-    
+
     if (m_func_bounds.GetByteSize() > 7)
     {
         uint8_t bytebuf[7];
@@ -716,16 +727,23 @@ loopnext:
         if (target->ReadMemory (last_seven_bytes, prefer_file_cache, bytebuf, 7,
                                 error) != static_cast<size_t>(-1))
         {
-            if (bytebuf[5] == 0x5d && bytebuf[6] == 0xc3)  // mov, ret
+            if (bytebuf[5] == 0x5d && bytebuf[6] == 0xc3)  // mov & ret
             {
                 ret_insn_offset = m_func_bounds.GetByteSize() - 1;
             }
-            else if (bytebuf[0] == 0x5d && bytebuf[1] == 0xc3 && bytebuf[2] == 0xe8) // mov, ret, call
+            else if (bytebuf[1] == 0x5d && bytebuf[2] == 0xe9)  // mov & jmp
+            {
+                // When the pc is sitting on the 'jmp' instruction, we have the same
+                // unwind state as if it was sitting on a 'ret' instruction.
+                ret_insn_offset = m_func_bounds.GetByteSize() - 5;
+            }
+            else if (bytebuf[0] == 0x5d && bytebuf[1] == 0xc3 && bytebuf[2] == 0xe8) // mov & ret & call
             {
                 ret_insn_offset = m_func_bounds.GetByteSize() - 6;
             }
         }
-    } else if (m_func_bounds.GetByteSize() > 2)
+    }
+    else if (m_func_bounds.GetByteSize() > 2)
     {
         uint8_t bytebuf[2];
         Address last_two_bytes(end_of_fun);
@@ -733,7 +751,7 @@ loopnext:
         if (target->ReadMemory (last_two_bytes, prefer_file_cache, bytebuf, 2,
                                 error) != static_cast<size_t>(-1))
         {
-            if (bytebuf[0] == 0x5d && bytebuf[1] == 0xc3) // mov, ret
+            if (bytebuf[0] == 0x5d && bytebuf[1] == 0xc3) // mov & ret
             {
                 ret_insn_offset = m_func_bounds.GetByteSize() - 1;
             }





More information about the lldb-commits mailing list