[Lldb-commits] [PATCH] Add support for 'leal' instruction to UnwindAssembly-x86

Tamas Berghammer tberghammer at google.com
Tue Mar 24 06:42:25 PDT 2015


Hi jasonmolenda,

Add support for 'leal' instruction to UnwindAssembly-x86

Gcc for android use the leal instruction to subtract from the stack pointer in the prologue of a function call. This patch add basic support for evaluating this instruction to support stack unwinding on android-x86.

http://reviews.llvm.org/D8583

Files:
  source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp

Index: source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
===================================================================
--- source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
+++ source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
@@ -148,6 +148,7 @@
     bool mov_rsp_rbp_pattern_p ();
     bool sub_rsp_pattern_p (int& amount);
     bool add_rsp_pattern_p (int& amount);
+    bool lea_rsp_pattern_p (int& amount);
     bool push_reg_p (int& regno);
     bool pop_reg_p (int& regno);
     bool push_imm_pattern_p ();
@@ -410,6 +411,36 @@
     return false;
 }
 
+// lea esp, [esp - 0x28]
+// lea esp, [esp + 0x28]
+bool
+AssemblyParse_x86::lea_rsp_pattern_p (int& amount)
+{
+    uint8_t *p = m_cur_insn_bytes;
+    if (m_wordsize == 8 && *p == 0x48)
+        p++;
+
+    // Check opcode
+    if (*p != 0x8d)
+        return false;
+
+    // 8 bis displacement
+    if (*(p + 1) == 0x64 && (*(p + 2) & 0x3f) == 0x24)
+    {
+        amount = (int8_t) *(p + 3);
+        return true;
+    }
+
+    // 32 bt displacement
+    if (*(p + 1) == 0xa4 && (*(p + 2) & 0x3f) == 0x24)
+    {
+        amount = (int32_t) extract_4 (p + 2);
+        return true;
+    }
+
+    return false;
+}
+
 // pushq %rbx
 // pushl %ebx
 bool 
@@ -808,6 +839,18 @@
             in_epilogue = true;
         }
 
+        else if (lea_rsp_pattern_p (stack_offset))
+        {
+            current_sp_bytes_offset_from_cfa -= stack_offset;
+            if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum)
+            {
+                row->GetCFAValue().SetOffset (current_sp_bytes_offset_from_cfa);
+                row_updated = true;
+            }
+            if (stack_offset > 0)
+                in_epilogue = true;
+        }
+
         else if (ret_pattern_p () && prologue_completed_row.get())
         {
             // Reinstate the saved prologue setup for any instructions
@@ -1068,6 +1111,19 @@
                 unwind_plan_updated = true;
                 continue;
             }
+
+            // lea %rsp, [%rsp + $offset]
+            if (lea_rsp_pattern_p (amount))
+            {
+                row->SetOffset (offset);
+                row->GetCFAValue().IncOffset (-amount);
+
+                UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+                unwind_plan.InsertRow (new_row);
+                unwind_plan_updated = true;
+                continue;
+            }
+
             if (ret_pattern_p ())
             {
                 reinstate_unwind_state = true;
@@ -1234,7 +1290,8 @@
         }
 
         if (push_rbp_pattern_p () || mov_rsp_rbp_pattern_p () || sub_rsp_pattern_p (offset)
-            || push_reg_p (regno) || mov_reg_to_local_stack_frame_p (regno, offset))
+            || push_reg_p (regno) || mov_reg_to_local_stack_frame_p (regno, offset)
+            || (lea_rsp_pattern_p (offset) && offset < 0))
         {
             m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len);
             continue;

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D8583.22569.patch
Type: text/x-patch
Size: 2988 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20150324/76d832f7/attachment.bin>


More information about the lldb-commits mailing list