[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