summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
diff options
context:
space:
mode:
authorJason Molenda <jmolenda@apple.com>2016-10-04 05:10:06 +0000
committerJason Molenda <jmolenda@apple.com>2016-10-04 05:10:06 +0000
commit2630acc0c5cc025dc5ecaaf6fe32b8eebd8269cd (patch)
tree9bce82822e70098fe3f9a10ef5bc62f82e8de215 /lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
parente923a1a486e467fd167a98f4dcc2dfea15f3abfa (diff)
downloadbcm5719-llvm-2630acc0c5cc025dc5ecaaf6fe32b8eebd8269cd.tar.gz
bcm5719-llvm-2630acc0c5cc025dc5ecaaf6fe32b8eebd8269cd.zip
Finish adding the individual instruction tests to the x86 unwinder
unittests. If I have time, I'd like to see if I can write some tests of the eh_frame augmentation which is a wholly separate code path (it seems like maybe it should be rolled into the main instruction scanning codepath, to be honest, and operate on the generated UnwindPlan instead of bothering with raw instructions at all). Outside the eh_frame augmentation, I'm comfortable that this unwind generator is being tested well now. llvm-svn: 283186
Diffstat (limited to 'lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp')
-rw-r--r--lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp51
1 files changed, 49 insertions, 2 deletions
diff --git a/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp b/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
index 9131acaab5b..e731a5a02ab 100644
--- a/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
+++ b/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
@@ -346,6 +346,20 @@ bool x86AssemblyInspectionEngine::push_extended_pattern_p() {
return false;
}
+// instructions only valid in 32-bit mode:
+// 0x0e - push cs
+// 0x16 - push ss
+// 0x1e - push ds
+// 0x06 - push es
+bool x86AssemblyInspectionEngine::push_misc_reg_p() {
+ uint8_t p = *m_cur_insn;
+ if (m_wordsize == 4) {
+ if (p == 0x0e || p == 0x16 || p == 0x1e || p == 0x06)
+ return true;
+ }
+ return false;
+}
+
// pushq %rbx
// pushl %ebx
bool x86AssemblyInspectionEngine::push_reg_p(int &regno) {
@@ -462,6 +476,19 @@ bool x86AssemblyInspectionEngine::pop_rbp_pattern_p() {
return (*p == 0x5d);
}
+// instructions valid only in 32-bit mode:
+// 0x1f - pop ds
+// 0x07 - pop es
+// 0x17 - pop ss
+bool x86AssemblyInspectionEngine::pop_misc_reg_p() {
+ uint8_t p = *m_cur_insn;
+ if (m_wordsize == 4) {
+ if (p == 0x1f || p == 0x07 || p == 0x17)
+ return true;
+ }
+ return false;
+}
+
// leave [0xc9]
bool x86AssemblyInspectionEngine::leave_pattern_p() {
uint8_t *p = m_cur_insn;
@@ -725,6 +752,15 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
}
}
+ else if (pop_misc_reg_p()) {
+ current_sp_bytes_offset_from_cfa -= m_wordsize;
+ if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
+ row->GetCFAValue().SetIsRegisterPlusOffset(
+ m_lldb_sp_regnum, current_sp_bytes_offset_from_cfa);
+ row_updated = true;
+ }
+ }
+
// The LEAVE instruction moves the value from rbp into rsp and pops
// a value off the stack into rbp (restoring the caller's rbp value).
// It is the opposite of ENTER, or 'push rbp, mov rsp rbp'.
@@ -788,7 +824,8 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
in_epilogue = true;
}
- else if (push_extended_pattern_p() || push_imm_pattern_p()) {
+ else if (push_extended_pattern_p() || push_imm_pattern_p() ||
+ push_misc_reg_p()) {
current_sp_bytes_offset_from_cfa += m_wordsize;
if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
@@ -1026,6 +1063,16 @@ bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
continue;
}
+ if (pop_misc_reg_p()) {
+ row->SetOffset(offset);
+ row->GetCFAValue().IncOffset(-m_wordsize);
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ continue;
+ }
+
// push imm
if (push_imm_pattern_p()) {
row->SetOffset(offset);
@@ -1037,7 +1084,7 @@ bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
}
// push extended
- if (push_extended_pattern_p()) {
+ if (push_extended_pattern_p() || push_misc_reg_p()) {
row->SetOffset(offset);
row->GetCFAValue().IncOffset(m_wordsize);
UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
OpenPOWER on IntegriCloud