[Lldb-commits] [lldb] r245546 - Improve instruction emulation based stack unwinding

Tamas Berghammer via lldb-commits lldb-commits at lists.llvm.org
Thu Aug 20 02:09:02 PDT 2015


Author: tberghammer
Date: Thu Aug 20 04:09:01 2015
New Revision: 245546

URL: http://llvm.org/viewvc/llvm-project?rev=245546&view=rev
Log:
Improve instruction emulation based stack unwinding

On ARM there is no difference petween a pop and a load instruction so
a register can be loaded multiple times during the function. Add check
to threat the load as a restore only if it do the restore from the
same location where the register was saved.

Differential revision: http://reviews.llvm.org/D11947

Modified:
    lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
    lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
    lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp

Modified: lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp?rev=245546&r1=245545&r2=245546&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp Thu Aug 20 04:09:01 2015
@@ -578,7 +578,7 @@ EmulateInstructionARM::EmulatePOP (const
         {
             if (BitIsSet (registers, i))
             {
-                context.SetRegisterPlusOffset (sp_reg, addr - sp);
+                context.SetAddress(addr);
                 data = MemARead(context, addr, 4, 0, &success);
                 if (!success)
                     return false;    
@@ -2214,7 +2214,7 @@ EmulateInstructionARM::EmulateVPOP (cons
         for (i=0; i<regs; ++i)
         {
             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
-            context.SetRegisterPlusOffset (sp_reg, addr - sp);
+            context.SetAddress(addr);
             data = MemARead(context, addr, reg_byte_size, 0, &success);
             if (!success)
                 return false;    
@@ -3516,7 +3516,10 @@ EmulateInstructionARM::EmulateLDM (const
                 context.type = EmulateInstruction::eContextRegisterPlusOffset;
                 context.SetRegisterPlusOffset (dwarf_reg, offset);
                 if (wback && (n == 13)) // Pop Instruction
+                {
                     context.type = EmulateInstruction::eContextPopRegisterOffStack;
+                    context.SetAddress(base_address + offset);
+                }
 
                 // R[i] = MemA [address, 4]; address = address + 4;
                 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
@@ -10307,7 +10310,7 @@ EmulateInstructionARM::EmulateLDRDImmedi
             context.type = eContextPopRegisterOffStack;
         else
             context.type = eContextRegisterLoad;
-        context.SetRegisterPlusOffset (base_reg, address - Rn);
+        context.SetAddress(address);
                   
         const uint32_t addr_byte_size = GetAddressByteSize();
         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
@@ -10437,7 +10440,7 @@ EmulateInstructionARM::EmulateLDRDRegist
             context.type = eContextPopRegisterOffStack;
         else
             context.type = eContextRegisterLoad;
-        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
+        context.SetAddress(address);
                   
         // R[t] = MemA[address,4];
         const uint32_t addr_byte_size = GetAddressByteSize();

Modified: lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp?rev=245546&r1=245545&r2=245546&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp Thu Aug 20 04:09:01 2015
@@ -768,8 +768,6 @@ EmulateInstructionARM64::EmulateLDPSTP (
     Context context_t;
     Context context_t2;
 
-    context_t.SetRegisterToRegisterPlusOffset (reg_info_Rt, reg_info_base, 0);
-    context_t2.SetRegisterToRegisterPlusOffset (reg_info_Rt2, reg_info_base, size);
     uint8_t buffer [RegisterValue::kMaxRegisterByteSize];
     Error error;
 
@@ -787,6 +785,8 @@ EmulateInstructionARM64::EmulateLDPSTP (
                 context_t.type = eContextRegisterStore;
                 context_t2.type = eContextRegisterStore;
             }
+            context_t.SetRegisterToRegisterPlusOffset (reg_info_Rt, reg_info_base, 0);
+            context_t2.SetRegisterToRegisterPlusOffset (reg_info_Rt2, reg_info_base, size);
 
             if (!ReadRegister (&reg_info_Rt, data_Rt))
                 return false;
@@ -820,6 +820,8 @@ EmulateInstructionARM64::EmulateLDPSTP (
                 context_t.type = eContextRegisterLoad;
                 context_t2.type = eContextRegisterLoad;
             }
+            context_t.SetAddress(address);
+            context_t2.SetAddress(address + size);
 
             if (rt_unknown)
                 memset (buffer, 'U', reg_info_Rt.byte_size);
@@ -950,8 +952,6 @@ EmulateInstructionARM64::EmulateLDRSTRIm
         return false;
 
     Context context;
-    context.SetRegisterToRegisterPlusOffset (reg_info_Rt, reg_info_base, postindex ? 0 : offset);
-
     switch (memop)
     {
         case MemOp_STORE:
@@ -959,6 +959,7 @@ EmulateInstructionARM64::EmulateLDRSTRIm
                 context.type = eContextPushRegisterOnStack;
             else
                 context.type = eContextRegisterStore;
+            context.SetRegisterToRegisterPlusOffset (reg_info_Rt, reg_info_base, postindex ? 0 : offset);
 
             if (!ReadRegister (&reg_info_Rt, data_Rt))
                 return false;
@@ -975,6 +976,7 @@ EmulateInstructionARM64::EmulateLDRSTRIm
                 context.type = eContextPopRegisterOffStack;
             else
                 context.type = eContextRegisterLoad;
+            context.SetAddress(address);
 
             if (!ReadMemory (context, address, buffer, reg_info_Rt.byte_size))
                 return false;

Modified: lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp?rev=245546&r1=245545&r2=245546&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp (original)
+++ lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp Thu Aug 20 04:09:01 2015
@@ -580,8 +580,17 @@ UnwindAssemblyInstEmulation::WriteRegist
                     const uint32_t generic_regnum = reg_info->kinds[eRegisterKindGeneric];
                     if (reg_num != LLDB_INVALID_REGNUM && generic_regnum != LLDB_REGNUM_GENERIC_SP)
                     {
-                        m_curr_row->SetRegisterLocationToSame (reg_num, /*must_replace*/ false);
-                        m_curr_row_modified = true;
+                        if (context.info_type == EmulateInstruction::eInfoTypeAddress)
+                        {
+                            if (m_pushed_regs.find (reg_num) != m_pushed_regs.end () &&
+                                context.info.address == m_pushed_regs[reg_num])
+                            {
+                                m_curr_row->SetRegisterLocationToSame (reg_num, /*must_replace*/ false);
+                                m_curr_row_modified = true;
+                            }
+                        }
+                        else
+                            assert (!"unhandled case, add code to handle this!");
                     }
                 }
             }




More information about the lldb-commits mailing list