summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
diff options
context:
space:
mode:
authorJason Molenda <jmolenda@apple.com>2014-08-04 21:26:55 +0000
committerJason Molenda <jmolenda@apple.com>2014-08-04 21:26:55 +0000
commit300dfcd28db7c07be9f37ee0e6222e51b05e21c5 (patch)
tree820babf59f46bcde67e441ad7253938b827be33f /lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
parent5f11f5f979f15b10034e22c0aad7542c600e58f7 (diff)
downloadbcm5719-llvm-300dfcd28db7c07be9f37ee0e6222e51b05e21c5.tar.gz
bcm5719-llvm-300dfcd28db7c07be9f37ee0e6222e51b05e21c5.zip
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> llvm-svn: 214783
Diffstat (limited to 'lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp')
-rw-r--r--lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp30
1 files changed, 24 insertions, 6 deletions
diff --git a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
index caed96857b2..6df4bade548 100644
--- a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
+++ b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
@@ -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;
}
OpenPOWER on IntegriCloud