summaryrefslogtreecommitdiff
path: root/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp')
-rw-r--r--source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
index 9aad2e1e70e2..9d79a411faad 100644
--- a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
+++ b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
@@ -452,6 +452,33 @@ bool x86AssemblyInspectionEngine::lea_rsp_pattern_p(int &amount) {
return false;
}
+// lea -0x28(%ebp), %esp
+// (32-bit and 64-bit variants, 8-bit and 32-bit displacement)
+bool x86AssemblyInspectionEngine::lea_rbp_rsp_pattern_p(int &amount) {
+ uint8_t *p = m_cur_insn;
+ if (m_wordsize == 8 && *p == 0x48)
+ p++;
+
+ // Check opcode
+ if (*p != 0x8d)
+ return false;
+ ++p;
+
+ // 8 bit displacement
+ if (*p == 0x65) {
+ amount = (int8_t)p[1];
+ return true;
+ }
+
+ // 32 bit displacement
+ if (*p == 0xa5) {
+ amount = (int32_t)extract_4(p + 1);
+ return true;
+ }
+
+ return false;
+}
+
// popq %rbx
// popl %ebx
bool x86AssemblyInspectionEngine::pop_reg_p(int &regno) {
@@ -843,6 +870,12 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
in_epilogue = true;
}
+ else if (lea_rbp_rsp_pattern_p(stack_offset) &&
+ row->GetCFAValue().GetRegisterNumber() == m_lldb_fp_regnum) {
+ current_sp_bytes_offset_from_cfa =
+ row->GetCFAValue().GetOffset() - stack_offset;
+ }
+
else if (ret_pattern_p() && prologue_completed_row.get()) {
// Reinstate the saved prologue setup for any instructions
// that come after the ret instruction