[Lldb-commits] [lldb] r240533 - Improve instruction emulation based stack unwinding on ARM

Tamas Berghammer tberghammer at google.com
Wed Jun 24 04:27:33 PDT 2015


Author: tberghammer
Date: Wed Jun 24 06:27:32 2015
New Revision: 240533

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

* Add and fix the emulation of several instruction.
* Disable frame pointer usage on Android.
* Specify return address register for the unwind plan instead of explict
  tracking the value of RA.
* Replace prologue detection heuristics (unreliable in several cases)
  with a logic to follow the branch instructions and restore the CFI
  value based on them. The target address for a branch should have the
  same CFI as the source address (if they are in the same function).
* Handle symbols in ELF files where the symbol size is not specified
  with calcualting their size based on the next symbol (already done
  in MachO files).
* Fix architecture in FuncUnwinders with filling up the inforamtion
  missing from the object file with the architecture of the target.
* Add code to read register wehn the value is set to "IsSame" as it
  meanse the value of a register in the parent frame is the same as the
  value in the current frame.

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

Modified:
    lldb/trunk/include/lldb/Symbol/FuncUnwinders.h
    lldb/trunk/source/Commands/CommandObjectTarget.cpp
    lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
    lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
    lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
    lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
    lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
    lldb/trunk/source/Symbol/FuncUnwinders.cpp
    lldb/trunk/source/Symbol/UnwindPlan.cpp

Modified: lldb/trunk/include/lldb/Symbol/FuncUnwinders.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/FuncUnwinders.h?rev=240533&r1=240532&r2=240533&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/FuncUnwinders.h (original)
+++ lldb/trunk/include/lldb/Symbol/FuncUnwinders.h Wed Jun 24 06:27:32 2015
@@ -50,7 +50,7 @@ public:
     GetUnwindPlanAtNonCallSite (Target& target, lldb_private::Thread& thread, int current_offset);
 
     lldb::UnwindPlanSP
-    GetUnwindPlanFastUnwind (lldb_private::Thread& Thread);
+    GetUnwindPlanFastUnwind (Target& target, lldb_private::Thread& thread);
 
     lldb::UnwindPlanSP
     GetUnwindPlanArchitectureDefault (lldb_private::Thread& thread);
@@ -111,7 +111,7 @@ public:
 private:
 
     lldb::UnwindAssemblySP
-    GetUnwindAssemblyProfiler ();
+    GetUnwindAssemblyProfiler (Target& target);
 
     UnwindTable& m_unwind_table;
     AddressRange m_range;

Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectTarget.cpp?rev=240533&r1=240532&r2=240533&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectTarget.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectTarget.cpp Wed Jun 24 06:27:32 2015
@@ -3775,7 +3775,7 @@ protected:
             {
                 result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan is '%s'\n", callsite_unwind_plan->GetSourceName().AsCString());
             }
-            UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get());
+            UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread.get());
             if (fast_unwind_plan.get())
             {
                 result.GetOutputStream().Printf("Fast UnwindPlan is '%s'\n", fast_unwind_plan->GetSourceName().AsCString());

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=240533&r1=240532&r2=240533&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp Wed Jun 24 06:27:32 2015
@@ -290,6 +290,9 @@ EmulateInstructionARM::GetRegisterInfo (
 uint32_t
 EmulateInstructionARM::GetFramePointerRegisterNumber () const
 {
+    if (m_arch.GetTriple().getEnvironment() == llvm::Triple::Android)
+        return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
+
     bool is_apple = false;
     if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
         is_apple = true;
@@ -1339,29 +1342,61 @@ EmulateInstructionARM::EmulateADDSPImm (
             return false;
         uint32_t imm32; // the immediate operand
         uint32_t d;
-        //bool setflags = false; // Add this back if/when support eEncodingT3 eEncodingA1
-        switch (encoding) 
+        bool setflags;
+        switch (encoding)
         {
             case eEncodingT1:
                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
                 d = Bits32 (opcode, 10, 8);
                 imm32 = (Bits32 (opcode, 7, 0) << 2);
-                  
+                setflags = false;
                 break;
-                  
+
             case eEncodingT2:
                 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
                 d = 13;
-                imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
-                  
+                imm32 = ThumbImm7Scaled (opcode); // imm32 = ZeroExtend(imm7:'00', 32)
+                setflags = false;
                 break;
-                  
+
+            case eEncodingT3:
+                // d = UInt(Rd); setflags = (S == "1"); imm32 = ThumbExpandImm(i:imm3:imm8);
+                d = Bits32 (opcode, 11, 8);
+                imm32 = ThumbExpandImm (opcode);
+                setflags = Bit32 (opcode, 20);
+
+                // if Rd == "1111" && S == "1" then SEE CMN (immediate);
+                if (d == 15 && setflags == 1)
+                    return false; // CMN (immediate) not yet supported
+
+                // if d == 15 && S == "0" then UNPREDICTABLE;
+                if (d == 15 && setflags == 0)
+                    return false;
+                break;
+
+            case eEncodingT4:
+                {
+                    // if Rn == '1111' then SEE ADR;
+                    // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
+                    d = Bits32 (opcode, 11, 8);
+                    setflags = false;
+                    uint32_t i = Bit32 (opcode, 26);
+                    uint32_t imm3 = Bits32 (opcode, 14, 12);
+                    uint32_t imm8 = Bits32 (opcode, 7, 0);
+                    imm32 = (i << 11) | (imm3 << 8) | imm8;
+        
+                    // if d == 15 then UNPREDICTABLE;
+                    if (d == 15)
+                        return false;
+                }
+                break;
+
             default:
                 return false;
         }
-        addr_t sp_offset = imm32;
-        addr_t addr = sp + sp_offset; // the adjusted stack pointer value
-        
+        // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 
+        AddWithCarryResult res = AddWithCarry (sp, imm32, 0);
+
         EmulateInstruction::Context context;
         if (d == 13)
             context.type = EmulateInstruction::eContextAdjustStackPointer;
@@ -1370,26 +1405,23 @@ EmulateInstructionARM::EmulateADDSPImm (
 
         RegisterInfo sp_reg;
         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
-        context.SetRegisterPlusOffset (sp_reg, sp_offset);
-    
+        context.SetRegisterPlusOffset (sp_reg, res.result - sp);
+
         if (d == 15)
         {
-            if (!ALUWritePC (context, addr))
+            if (!ALUWritePC (context, res.result))
                 return false;
         }
         else
         {
-            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
+            // R[d] = result; 
+            // if setflags then
+            //     APSR.N = result<31>;  
+            //     APSR.Z = IsZeroBit(result); 
+            //     APSR.C = carry;  
+            //     APSR.V = overflow;
+            if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
                 return false;
-            
-            // Add this back if/when support eEncodingT3 eEncodingA1
-            //if (setflags)
-            //{
-            //    APSR.N = result<31>;
-            //    APSR.Z = IsZeroBit(result);
-            //    APSR.C = carry;
-            //    APSR.V = overflow;
-            //}
         }
     }
     return true;
@@ -2318,13 +2350,16 @@ EmulateInstructionARM::EmulateB (const u
             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
             break;
         case eEncodingT2:
-            imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
+            imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
             target = pc + imm32;
             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
             break;
         case eEncodingT3:
             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
             {
+            if (Bits32(opcode, 25, 23) == 7)
+                return false; // See Branches and miscellaneous control on page A6-235.
+
             uint32_t S = Bit32(opcode, 26);
             uint32_t imm6 = Bits32(opcode, 21, 16);
             uint32_t J1 = Bit32(opcode, 13);
@@ -2404,7 +2439,7 @@ EmulateInstructionARM::EmulateCB (const
     default:
         return false;
     }
-    if (nonzero ^ (reg_val == 0))
+    if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
         if (!BranchWritePC(context, target))
             return false;
 
@@ -2434,55 +2469,58 @@ EmulateInstructionARM::EmulateTB (const
 
     bool success = false;
 
-    uint32_t Rn;     // the base register which contains the address of the table of branch lengths
-    uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
-    bool is_tbh;     // true if table branch halfword
-    switch (encoding) {
-    case eEncodingT1:
-        Rn = Bits32(opcode, 19, 16);
-        Rm = Bits32(opcode, 3, 0);
-        is_tbh = BitIsSet(opcode, 4);
-        if (Rn == 13 || BadReg(Rm))
-            return false;
-        if (InITBlock() && !LastInITBlock())
+    if (ConditionPassed(opcode))
+    {
+        uint32_t Rn;     // the base register which contains the address of the table of branch lengths
+        uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
+        bool is_tbh;     // true if table branch halfword
+        switch (encoding) {
+        case eEncodingT1:
+            Rn = Bits32(opcode, 19, 16);
+            Rm = Bits32(opcode, 3, 0);
+            is_tbh = BitIsSet(opcode, 4);
+            if (Rn == 13 || BadReg(Rm))
+                return false;
+            if (InITBlock() && !LastInITBlock())
+                return false;
+            break;
+        default:
             return false;
-        break;
-    default:
-        return false;
-    }
+        }
 
-    // Read the address of the table from the operand register Rn.
-    // The PC can be used, in which case the table immediately follows this instruction.
-    uint32_t base = ReadCoreReg(Rm, &success);
-    if (!success)
-        return false;
+        // Read the address of the table from the operand register Rn.
+        // The PC can be used, in which case the table immediately follows this instruction.
+        uint32_t base = ReadCoreReg(Rn, &success);
+        if (!success)
+            return false;
 
-    // the table index
-    uint32_t index = ReadCoreReg(Rm, &success);
-    if (!success)
-        return false;
+        // the table index
+        uint32_t index = ReadCoreReg(Rm, &success);
+        if (!success)
+            return false;
 
-    // the offsetted table address
-    addr_t addr = base + (is_tbh ? index*2 : index);
+        // the offsetted table address
+        addr_t addr = base + (is_tbh ? index*2 : index);
 
-    // PC-relative offset to branch forward
-    EmulateInstruction::Context context;
-    context.type = EmulateInstruction::eContextTableBranchReadMemory;
-    uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
-    if (!success)
-        return false;
+        // PC-relative offset to branch forward
+        EmulateInstruction::Context context;
+        context.type = EmulateInstruction::eContextTableBranchReadMemory;
+        uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
+        if (!success)
+            return false;
 
-    const uint32_t pc = ReadCoreReg(PC_REG, &success);
-    if (!success)
-        return false;
+        const uint32_t pc = ReadCoreReg(PC_REG, &success);
+        if (!success)
+            return false;
 
-    // target address
-    addr_t target = pc + offset;
-    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
-    context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
+        // target address
+        addr_t target = pc + offset;
+        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
+        context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
 
-    if (!BranchWritePC(context, target))
-        return false;
+        if (!BranchWritePC(context, target))
+            return false;
+    }
 
     return true;
 }
@@ -2498,14 +2536,14 @@ EmulateInstructionARM::EmulateADDImmThum
         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 
         R[d] = result; 
         if setflags then
-            APSR.N = result<31>;  
-            APSR.Z = IsZeroBit(result); 
-            APSR.C = carry;  
+            APSR.N = result<31>;
+            APSR.Z = IsZeroBit(result);
+            APSR.C = carry;
             APSR.V = overflow;
 #endif
-                  
+
     bool success = false;
-                  
+
     if (ConditionPassed(opcode))
     {
         uint32_t d;
@@ -2513,8 +2551,8 @@ EmulateInstructionARM::EmulateADDImmThum
         bool setflags;
         uint32_t imm32;
         uint32_t carry_out;
-        
-        //EncodingSpecificOperations(); 
+
+        //EncodingSpecificOperations();
         switch (encoding)
         {
             case eEncodingT1:
@@ -2523,7 +2561,7 @@ EmulateInstructionARM::EmulateADDImmThum
                 n = Bits32 (opcode, 5, 3);
                 setflags = !InITBlock();
                 imm32 = Bits32 (opcode, 8,6);
-                
+
                 break;
                 
             case eEncodingT2:
@@ -2532,28 +2570,30 @@ EmulateInstructionARM::EmulateADDImmThum
                 n = Bits32 (opcode, 10, 8);
                 setflags = !InITBlock();
                 imm32 = Bits32 (opcode, 7, 0);
-                
+
                 break;
-                
+
             case eEncodingT3:
                 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 
-                // if Rn == '1101' then SEE ADD (SP plus immediate); 
                 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); 
                 d = Bits32 (opcode, 11, 8);
                 n = Bits32 (opcode, 19, 16);
                 setflags = BitIsSet (opcode, 20);
                 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
-                
+
+                // if Rn == '1101' then SEE ADD (SP plus immediate); 
+                if (n == 13)
+                    return EmulateADDSPImm(opcode, eEncodingT3);
+
                 // if BadReg(d) || n == 15 then UNPREDICTABLE;
                 if (BadReg (d) || (n == 15))
                     return false;
-                
+
                 break;
-                
+
             case eEncodingT4:
             {
                 // if Rn == '1111' then SEE ADR; 
-                // if Rn == '1101' then SEE ADD (SP plus immediate); 
                 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 
                 d = Bits32 (opcode, 11, 8);
                 n = Bits32 (opcode, 19, 16);
@@ -2562,31 +2602,36 @@ EmulateInstructionARM::EmulateADDImmThum
                 uint32_t imm3 = Bits32 (opcode, 14, 12);
                 uint32_t imm8 = Bits32 (opcode, 7, 0);
                 imm32 = (i << 11) | (imm3 << 8) | imm8;
-                
+
+                // if Rn == '1101' then SEE ADD (SP plus immediate); 
+                if (n == 13)
+                    return EmulateADDSPImm(opcode, eEncodingT4);
+
                 // if BadReg(d) then UNPREDICTABLE;
                 if (BadReg (d))
                     return false;
-                    
+
                 break;
-            }   
+            }
+
             default:
                 return false;
         }
-        
+
         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
         if (!success)
             return false;
-        
+
         //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 
         AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
-        
+
         RegisterInfo reg_n;
         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
-        
+
         EmulateInstruction::Context context;
         context.type = eContextArithmetic;
         context.SetRegisterPlusOffset (reg_n, imm32);
-        
+
         //R[d] = result; 
         //if setflags then
             //APSR.N = result<31>;  
@@ -2595,7 +2640,7 @@ EmulateInstructionARM::EmulateADDImmThum
             //APSR.V = overflow;
         if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
             return false;
-        
+
     }
     return true;
 }
@@ -2650,6 +2695,8 @@ EmulateInstructionARM::EmulateADDImmARM
         EmulateInstruction::Context context;
         if (Rd == 13)
             context.type = EmulateInstruction::eContextAdjustStackPointer;
+        else if (Rd == GetFramePointerRegisterNumber())
+            context.type = EmulateInstruction::eContextSetFramePointer;
         else
             context.type = EmulateInstruction::eContextRegisterPlusOffset;
 
@@ -2968,6 +3015,13 @@ EmulateInstructionARM::EmulateCMPReg (co
         if (Rn == 15 || Rm == 15)
             return false;
         break;
+    case eEncodingT3:
+        Rn = Bits32(opcode, 19, 16);
+        Rm = Bits32(opcode, 3, 0);
+        shift_n = DecodeImmShiftThumb(opcode, shift_t);
+        if (Rn == 15 || BadReg(Rm))
+            return false;
+        break;
     case eEncodingA1:
         Rn = Bits32(opcode, 19, 16);
         Rm = Bits32(opcode, 3, 0);
@@ -4016,8 +4070,22 @@ EmulateInstructionARM::EmulateLDRRtRnImm
         if (wback)
         {
             EmulateInstruction::Context ctx;
-            ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
-            ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
+            if (Rn == 13)
+            {
+                ctx.type = eContextAdjustStackPointer;
+                ctx.SetImmediateSigned((int32_t) (offset_addr - base));
+            }
+            else if (Rn == GetFramePointerRegisterNumber())
+            {
+                ctx.type = eContextSetFramePointer;
+                ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
+            }
+            else
+            {
+                ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
+                ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
+            }
+            
 
             if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
                 return false;
@@ -6216,8 +6284,6 @@ EmulateInstructionARM::EmulateLDRBImmedi
                 break;
                   
             case eEncodingT2:
-                // if Rt == '1111' then SEE PLD; 
-                // if Rn == '1111' then SEE LDRB (literal); 
                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 
                 t = Bits32 (opcode, 15, 12);
                 n = Bits32 (opcode, 19, 16);
@@ -6227,7 +6293,15 @@ EmulateInstructionARM::EmulateLDRBImmedi
                 index = true;
                 add = true;
                 wback = false;
-                  
+
+                // if Rt == '1111' then SEE PLD; 
+                if (t == 15)
+                    return false; // PLD is not implemented yet
+
+                // if Rn == '1111' then SEE LDRB (literal); 
+                if (n == 15)
+                    return EmulateLDRBLiteral(opcode, eEncodingT1);
+
                 // if t == 13 then UNPREDICTABLE;
                 if (t == 13)
                     return false;
@@ -6235,14 +6309,12 @@ EmulateInstructionARM::EmulateLDRBImmedi
                 break;
                   
             case eEncodingT3:
-                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 
-                // if Rn == '1111' then SEE LDRB (literal); 
                 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 
                 // if P == '0' && W == '0' then UNDEFINED;
                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
                     return false;
                   
-                  // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
+                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
                 t = Bits32 (opcode, 15, 12);
                 n = Bits32 (opcode, 19, 16);
                 imm32 = Bits32 (opcode, 7, 0);
@@ -6251,7 +6323,15 @@ EmulateInstructionARM::EmulateLDRBImmedi
                 index = BitIsSet (opcode, 10);
                 add = BitIsSet (opcode, 9);
                 wback = BitIsSet (opcode, 8);
-                  
+
+                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 
+                if (t == 15)
+                    return false; // PLD is not implemented yet
+
+                // if Rn == '1111' then SEE LDRB (literal); 
+                if (n == 15)
+                    return EmulateLDRBLiteral(opcode, eEncodingT1);
+
                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
                 if (BadReg (t) || (wback && (n == t)))
                     return false;
@@ -6333,11 +6413,14 @@ EmulateInstructionARM::EmulateLDRBLitera
         switch (encoding)
         {
             case eEncodingT1:
-                // if Rt == '1111' then SEE PLD; 
                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 
                 t = Bits32 (opcode, 15, 12);
                 imm32 = Bits32 (opcode, 11, 0);
                 add = BitIsSet (opcode, 23);
+
+                // if Rt == '1111' then SEE PLD; 
+                if (t == 15)
+                    return false; // PLD is not implemented yet
                   
                 // if t == 13 then UNPREDICTABLE;
                 if (t == 13)
@@ -6438,8 +6521,6 @@ EmulateInstructionARM::EmulateLDRBRegist
                 break;
                   
             case eEncodingT2:
-                // if Rt == '1111' then SEE PLD; 
-                // if Rn == '1111' then SEE LDRB (literal); 
                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 
                 t = Bits32 (opcode, 15, 12);
                 n = Bits32 (opcode, 19, 16);
@@ -6453,6 +6534,14 @@ EmulateInstructionARM::EmulateLDRBRegist
                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 
                 shift_t = SRType_LSL;
                 shift_n = Bits32 (opcode, 5, 4);
+
+                // if Rt == '1111' then SEE PLD; 
+                if (t == 15)
+                    return false; // PLD is not implemented yet
+
+                // if Rn == '1111' then SEE LDRB (literal); 
+                if (n == 15)
+                    return EmulateLDRBLiteral(opcode, eEncodingT1);
                   
                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
                 if ((t == 13) || BadReg (m))
@@ -9726,14 +9815,20 @@ EmulateInstructionARM::EmulateSUBReg (co
                 break;
                   
             case eEncodingT2:
-                // if Rd == Ô1111Õ && S == Ô1Õ then SEE CMP (register);
-                // if Rn == Ô1101Õ then SEE SUB (SP minus register);
-                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == Ô1Õ);
+                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
                 d = Bits32 (opcode, 11, 8);
                 n = Bits32 (opcode, 19, 16);
                 m = Bits32 (opcode, 3, 0);
                 setflags = BitIsSet (opcode, 20);
-                  
+
+                // if Rd == "1111" && S == "1" then SEE CMP (register);
+                if (d == 15 && setflags == 1)
+                    return EmulateCMPImm (opcode, eEncodingT3);
+                  
+                // if Rn == "1101" then SEE SUB (SP minus register);
+                if (n == 13)
+                    return EmulateSUBSPReg (opcode, eEncodingT1);
+
                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
                   
@@ -12740,6 +12835,7 @@ EmulateInstructionARM::GetThumbOpcodeFor
         { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
         // cmp (register) (Rn and Rm not both from r0-r7)
         { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
+        { 0xfff08f00, 0xebb00f00, ARMvAll,       eEncodingT3, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
         // asr (immediate)
         { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
         { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
@@ -13673,15 +13769,11 @@ EmulateInstructionARM::CreateFunctionEnt
 
     // Our previous Call Frame Address is the stack pointer
     row->GetCFAValue().SetIsRegisterPlusOffset (dwarf_sp, 0);
-    
-    // Our previous PC is in the LR
-    row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
-    unwind_plan.AppendRow (row);
 
-    // All other registers are the same.
-    
+    unwind_plan.AppendRow (row);
     unwind_plan.SetSourceName ("EmulateInstructionARM");
     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
     unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
+    unwind_plan.SetReturnAddressRegister (dwarf_lr);
     return true;
 }

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=240533&r1=240532&r2=240533&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp Wed Jun 24 06:27:32 2015
@@ -350,17 +350,12 @@ EmulateInstructionARM64::CreateFunctionE
 
     // Our previous Call Frame Address is the stack pointer
     row->GetCFAValue().SetIsRegisterPlusOffset(arm64_dwarf::sp, 0);
-    
-    // Our previous PC is in the LR
-    row->SetRegisterLocationToRegister(arm64_dwarf::pc, arm64_dwarf::lr, can_replace);
 
     unwind_plan.AppendRow (row);
-    
-    // All other registers are the same.
-    
     unwind_plan.SetSourceName ("EmulateInstructionARM64");
     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
     unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
+    unwind_plan.SetReturnAddressRegister (arm64_dwarf::lr);
     return true;
 }
 

Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=240533&r1=240532&r2=240533&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Wed Jun 24 06:27:32 2015
@@ -2020,11 +2020,12 @@ ObjectFileELF::ParseSymbols (Symtab *sym
                 symbol_section_sp,  // Section in which this symbol is defined or null.
                 symbol_value,       // Offset in section or symbol value.
                 symbol.st_size),    // Size in bytes of this symbol.
-            true,               // Size is valid
-            has_suffix,         // Contains linker annotations?
-            flags);             // Symbol flags.
+            symbol.st_size != 0,    // Size is valid if it is not 0
+            has_suffix,             // Contains linker annotations?
+            flags);                 // Symbol flags.
         symtab->AddSymbol(dc_symbol);
     }
+    symtab->CalculateSymbolSizes();
     return i;
 }
 

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp?rev=240533&r1=240532&r2=240533&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Wed Jun 24 06:27:32 2015
@@ -692,7 +692,7 @@ RegisterContextLLDB::GetFastUnwindPlanFo
     if (m_frame_type == eTrapHandlerFrame || m_frame_type == eDebuggerFrame)
         return unwind_plan_sp;
 
-    unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind (m_thread);
+    unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind (*m_thread.CalculateTarget(), m_thread);
     if (unwind_plan_sp)
     {
         if (unwind_plan_sp->PlanValidAtAddress (m_current_pc))
@@ -1403,16 +1403,13 @@ RegisterContextLLDB::SavedLocationForReg
 
     if (unwindplan_regloc.IsSame())
     {
-        if (IsFrameZero ())
-        {
-            UnwindLogMsg ("could not supply caller's %s (%d) location, IsSame", 
-                          regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
-            return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
-        }
-        else
-        {
-            return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
-        }
+        regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
+        regloc.location.register_number = regnum.GetAsKind (eRegisterKindLLDB);
+        m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
+        UnwindLogMsg ("supplying caller's register %s (%d), saved in register %s (%d)", 
+                      regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), 
+                      regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
+        return UnwindLLDB::RegisterSearchResult::eRegisterFound;
     }
 
     if (unwindplan_regloc.IsCFAPlusOffset())

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=240533&r1=240532&r2=240533&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp (original)
+++ lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp Wed Jun 24 06:27:32 2015
@@ -96,7 +96,13 @@ UnwindAssemblyInstEmulation::GetNonCallS
             if (num_instructions > 0)
             {
                 Instruction *inst = inst_list.GetInstructionAtIndex (0).get();
-                const addr_t base_addr = inst->GetAddress().GetFileAddress();
+                const lldb::addr_t base_addr = inst->GetAddress().GetFileAddress();
+
+                // Map for storing the unwind plan row and the value of the registers at a given offset.
+                // When we see a forward branch we add a new entry to this map with the actual unwind plan
+                // row and register context for the target address of the branch as the current data have
+                // to be valid for the target address of the branch too if we are in the same function.
+                std::map<lldb::addr_t, std::pair<UnwindPlan::RowSP, RegisterValueMap>> saved_unwind_states;
 
                 // Make a copy of the current instruction Row and save it in m_curr_row
                 // so we can add updates as we process the instructions.  
@@ -106,18 +112,8 @@ UnwindAssemblyInstEmulation::GetNonCallS
                     *newrow = *last_row.get();
                 m_curr_row.reset(newrow);
 
-                // Once we've seen the initial prologue instructions complete, save a
-                // copy of the CFI at that point into prologue_completed_row for possible
-                // use later.
-                int instructions_since_last_prologue_insn = 0;     // # of insns since last CFI was update
-
-                bool reinstate_prologue_next_instruction = false;  // Next iteration, re-install the prologue row of CFI
-
-                bool last_instruction_restored_return_addr_reg = false;  // re-install the prologue row of CFI if the next instruction is a branch immediate
-
-                bool return_address_register_has_been_saved = false; // if we've seen the ra register get saved yet
-
-                UnwindPlan::RowSP prologue_completed_row;          // copy of prologue row of CFI
+                // Add the initial state to the save list with offset 0.
+                saved_unwind_states.insert({0, {last_row, m_register_values}});
 
                 // cache the pc register number (in whatever register numbering this UnwindPlan uses) for
                 // quick reference during instruction parsing.
@@ -140,10 +136,27 @@ UnwindAssemblyInstEmulation::GetNonCallS
                 for (size_t idx=0; idx<num_instructions; ++idx)
                 {
                     m_curr_row_modified = false;
-                    m_curr_insn_restored_a_register = false;
+                    m_forward_branch_offset = 0;
+
                     inst = inst_list.GetInstructionAtIndex (idx).get();
                     if (inst)
                     {
+                        lldb::addr_t current_offset = inst->GetAddress().GetFileAddress() - base_addr;
+                        auto it = saved_unwind_states.upper_bound(current_offset);
+                        assert(it != saved_unwind_states.begin() && "Unwind row for the function entry missing");
+                        --it; // Move it to the row corresponding to the current offset
+
+                        // If the offset of m_curr_row don't match with the offset we see in saved_unwind_states
+                        // then we have to update m_curr_row and m_register_values based on the saved values. It
+                        // is happenning after we processed an epilogue and a return to caller instruction.
+                        if (it->second.first->GetOffset() != m_curr_row->GetOffset())
+                        {
+                            UnwindPlan::Row *newrow = new UnwindPlan::Row;
+                            *newrow = *it->second.first;
+                            m_curr_row.reset(newrow);
+                            m_register_values = it->second.second;;
+                        }
+
                         if (log && log->GetVerbose ())
                         {
                             StreamString strm;
@@ -159,111 +172,30 @@ UnwindAssemblyInstEmulation::GetNonCallS
 
                         m_inst_emulator_ap->EvaluateInstruction (eEmulateInstructionOptionIgnoreConditions);
 
+                        // If the current instruction is a branch forward then save the current CFI information
+                        // for the offset where we are branching.
+                        if (m_forward_branch_offset != 0 && range.ContainsFileAddress(inst->GetAddress().GetFileAddress() + m_forward_branch_offset))
+                        {
+                            auto newrow = std::make_shared<UnwindPlan::Row>(*m_curr_row.get());
+                            newrow->SetOffset(current_offset + m_forward_branch_offset);
+                            saved_unwind_states.insert({current_offset + m_forward_branch_offset, {newrow, m_register_values}});
+                            unwind_plan.InsertRow(newrow);
+                        }
+
                         // Were there any changes to the CFI while evaluating this instruction?
                         if (m_curr_row_modified)
                         {
-                            reinstate_prologue_next_instruction = false;
-                            m_curr_row->SetOffset (inst->GetAddress().GetFileAddress() + inst->GetOpcode().GetByteSize() - base_addr);
-                            // Append the new row
-                            unwind_plan.AppendRow (m_curr_row);
-
-                            // Allocate a new Row for m_curr_row, copy the current state into it
-                            UnwindPlan::Row *newrow = new UnwindPlan::Row;
-                            *newrow = *m_curr_row.get();
-                            m_curr_row.reset(newrow);
-
-                            // If m_curr_insn_restored_a_register == true, we're looking at an epilogue instruction.
-                            // Set instructions_since_last_prologue_insn to a very high number so we don't append 
-                            // any of these epilogue instructions to our prologue_complete row.
-                            if (m_curr_insn_restored_a_register == false && instructions_since_last_prologue_insn < 8)
-                              instructions_since_last_prologue_insn = 0;
-                            else
-                              instructions_since_last_prologue_insn = 99;
-
-                            UnwindPlan::Row::RegisterLocation pc_regloc;
-                            UnwindPlan::Row::RegisterLocation ra_regloc;
-
-                            // While parsing the instructions of this function, if we've ever
-                            // seen the return address register (aka lr on arm) in a non-IsSame() state,
-                            // it has been saved on the stack.  If it's ever back to IsSame(), we've
-                            // executed an epilogue.
-                            if (ra_reg_num != LLDB_INVALID_REGNUM
-                                && m_curr_row->GetRegisterInfo (ra_reg_num, ra_regloc)
-                                && !ra_regloc.IsSame())
+                            // Save the modified row if we don't already have a CFI row in the currennt address
+                            if (saved_unwind_states.count(current_offset + inst->GetOpcode().GetByteSize()) == 0)
                             {
-                                return_address_register_has_been_saved = true;
-                            }
+                                m_curr_row->SetOffset (current_offset + inst->GetOpcode().GetByteSize());
+                                unwind_plan.InsertRow (m_curr_row);
+                                saved_unwind_states.insert({current_offset + inst->GetOpcode().GetByteSize(), {m_curr_row, m_register_values}});
 
-                            // If the caller's pc is "same", we've just executed an epilogue and we return to the caller
-                            // after this instruction completes executing.
-                            // If there are any instructions past this, there must have been flow control over this
-                            // epilogue so we'll reinstate the original prologue setup instructions.
-                            if (prologue_completed_row.get()
-                                && pc_reg_num != LLDB_INVALID_REGNUM 
-                                && m_curr_row->GetRegisterInfo (pc_reg_num, pc_regloc)
-                                && pc_regloc.IsSame())
-                            {
-                                if (log && log->GetVerbose())
-                                    log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- pc is <same>, restore prologue instructions.");
-                                reinstate_prologue_next_instruction = true;
-                            }
-                            else if (prologue_completed_row.get()
-                                     && return_address_register_has_been_saved
-                                     && ra_reg_num != LLDB_INVALID_REGNUM
-                                     && m_curr_row->GetRegisterInfo (ra_reg_num, ra_regloc)
-                                     && ra_regloc.IsSame())
-                            {
-                                if (log && log->GetVerbose())
-                                    log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- lr is <same>, restore prologue instruction if the next instruction is a branch immediate.");
-                                last_instruction_restored_return_addr_reg = true;
-                            }
-                        }
-                        else
-                        {
-                            // If the previous instruction was a return-to-caller (epilogue), and we're still executing
-                            // instructions in this function, there must be a code path that jumps over that epilogue.
-                            // Also detect the case where we epilogue & branch imm to another function (tail-call opt)
-                            // instead of a normal pop lr-into-pc exit.
-                            // Reinstate the frame setup from the prologue.
-                            if (reinstate_prologue_next_instruction
-                                || (m_curr_insn_is_branch_immediate && last_instruction_restored_return_addr_reg))
-                            {
-                                if (log && log->GetVerbose())
-                                    log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- Reinstating prologue instruction set");
+                                // Allocate a new Row for m_curr_row, copy the current state into it
                                 UnwindPlan::Row *newrow = new UnwindPlan::Row;
-                                *newrow = *prologue_completed_row.get();
-                                m_curr_row.reset(newrow);
-                                m_curr_row->SetOffset (inst->GetAddress().GetFileAddress() + inst->GetOpcode().GetByteSize() - base_addr);
-                                unwind_plan.AppendRow(m_curr_row);
-
-                                newrow = new UnwindPlan::Row;
                                 *newrow = *m_curr_row.get();
                                 m_curr_row.reset(newrow);
-
-                                reinstate_prologue_next_instruction = false;
-                                last_instruction_restored_return_addr_reg = false; 
-                                m_curr_insn_is_branch_immediate = false;
-                            }
-
-                            // clear both of these if either one wasn't set
-                            if (last_instruction_restored_return_addr_reg)
-                            {
-                                last_instruction_restored_return_addr_reg = false;
-                            }
-                            if (m_curr_insn_is_branch_immediate)
-                            {
-                                m_curr_insn_is_branch_immediate = false;
-                            }
- 
-                            // Stop updating the prologue instructions if we've seen 8 non-prologue instructions
-                            // in a row.
-                            if (instructions_since_last_prologue_insn++ < 8)
-                            {
-                                UnwindPlan::Row *newrow = new UnwindPlan::Row;
-                                *newrow = *m_curr_row.get();
-                                prologue_completed_row.reset(newrow);
-                                if (log && log->GetVerbose())
-                                    log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- saving a copy of the current row as the prologue row.");
                             }
                         }
                     }
@@ -460,8 +392,7 @@ UnwindAssemblyInstEmulation::WriteMemory
         context.Dump(strm, instruction);
         log->PutCString (strm.GetData());
     }
-    
-    const bool can_replace = true;
+
     const bool cant_replace = false;
 
     switch (context.type)
@@ -491,19 +422,12 @@ UnwindAssemblyInstEmulation::WriteMemory
         case EmulateInstruction::eContextPushRegisterOnStack:
             {
                 uint32_t reg_num = LLDB_INVALID_REGNUM;
-                bool is_return_address_reg = false;
                 const uint32_t unwind_reg_kind = m_unwind_plan_ptr->GetRegisterKind();
                 if (context.info_type == EmulateInstruction::eInfoTypeRegisterToRegisterPlusOffset)
-                {
                     reg_num = context.info.RegisterToRegisterPlusOffset.data_reg.kinds[unwind_reg_kind];
-                    if (context.info.RegisterToRegisterPlusOffset.data_reg.kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_RA)
-                        is_return_address_reg = true;
-                }
                 else
-                {
                     assert (!"unhandled case, add code to handle this!");
-                }
-                
+
                 if (reg_num != LLDB_INVALID_REGNUM)
                 {
                     if (m_pushed_regs.find (reg_num) == m_pushed_regs.end())
@@ -512,21 +436,6 @@ UnwindAssemblyInstEmulation::WriteMemory
                         const int32_t offset = addr - m_initial_sp;
                         m_curr_row->SetRegisterLocationToAtCFAPlusOffset (reg_num, offset, cant_replace);
                         m_curr_row_modified = true;
-                        if (is_return_address_reg)
-                        {
-                            // This push was pushing the return address register,
-                            // so this is also how we will unwind the PC...
-                            RegisterInfo pc_reg_info;
-                            if (instruction->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc_reg_info))
-                            {
-                                uint32_t pc_reg_num = pc_reg_info.kinds[unwind_reg_kind];
-                                if (pc_reg_num != LLDB_INVALID_REGNUM)
-                                {
-                                    m_curr_row->SetRegisterLocationToAtCFAPlusOffset (pc_reg_num, offset, can_replace);
-                                    m_curr_row_modified = true;
-                                }
-                            }
-                        }
                     }
                 }
             }
@@ -598,7 +507,6 @@ UnwindAssemblyInstEmulation::WriteRegist
         log->PutCString(strm.GetData());
     }
 
-    const bool must_replace = true;
     SetRegisterValue (*reg_info, reg_value);
 
     switch (context.type)
@@ -610,7 +518,6 @@ UnwindAssemblyInstEmulation::WriteRegist
         case EmulateInstruction::eContextRegisterPlusOffset:
         case EmulateInstruction::eContextAdjustPC:
         case EmulateInstruction::eContextRegisterStore:
-        case EmulateInstruction::eContextAbsoluteBranchRegister:
         case EmulateInstruction::eContextSupervisorCall:
         case EmulateInstruction::eContextTableBranchReadMemory:
         case EmulateInstruction::eContextWriteRegisterRandomBits:
@@ -619,6 +526,7 @@ UnwindAssemblyInstEmulation::WriteRegist
         case EmulateInstruction::eContextAdvancePC:    
         case EmulateInstruction::eContextReturnFromException:
         case EmulateInstruction::eContextPushRegisterOnStack:
+        case EmulateInstruction::eContextRegisterLoad:
 //            {
 //                const uint32_t reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
 //                if (reg_num != LLDB_INVALID_REGNUM)
@@ -633,40 +541,18 @@ UnwindAssemblyInstEmulation::WriteRegist
 //            }
             break;
 
-        case EmulateInstruction::eContextRegisterLoad:
+        case EmulateInstruction::eContextAbsoluteBranchRegister:
+        case EmulateInstruction::eContextRelativeBranchImmediate:
             {
-                const uint32_t unwind_reg_kind = m_unwind_plan_ptr->GetRegisterKind();
-                const uint32_t reg_num = reg_info->kinds[unwind_reg_kind];
-                if (reg_num != LLDB_INVALID_REGNUM)
+                if (context.info_type == EmulateInstruction::eInfoTypeISAAndImmediate &&
+                    context.info.ISAAndImmediate.unsigned_data32 > 0)
                 {
-                    m_curr_row->SetRegisterLocationToRegister (reg_num, reg_num, must_replace);
-                    m_curr_row_modified = true;
-                    m_curr_insn_restored_a_register = true;
-
-                    if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_RA)
-                    {
-                        // This load was restoring the return address register,
-                        // so this is also how we will unwind the PC...
-                        RegisterInfo pc_reg_info;
-                        if (instruction->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc_reg_info))
-                        {
-                            uint32_t pc_reg_num = pc_reg_info.kinds[unwind_reg_kind];
-                            if (pc_reg_num != LLDB_INVALID_REGNUM)
-                            {
-                                m_curr_row->SetRegisterLocationToRegister (pc_reg_num, reg_num, must_replace);
-                                m_curr_row_modified = true;
-                            }
-                        }
-                    }
+                    m_forward_branch_offset = context.info.ISAAndImmediateSigned.signed_data32;
                 }
-            }
-            break;
-
-        case EmulateInstruction::eContextRelativeBranchImmediate:
-            {
-                
+                else if (context.info_type == EmulateInstruction::eInfoTypeISAAndImmediateSigned &&
+                         context.info.ISAAndImmediateSigned.signed_data32 > 0)
                 {
-                    m_curr_insn_is_branch_immediate = true;
+                    m_forward_branch_offset = context.info.ISAAndImmediate.unsigned_data32;
                 }
             }
             break;
@@ -676,9 +562,8 @@ UnwindAssemblyInstEmulation::WriteRegist
                 const uint32_t reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
                 if (reg_num != LLDB_INVALID_REGNUM)
                 {
-                    m_curr_row->SetRegisterLocationToSame (reg_num, must_replace);
+                    m_curr_row->SetRegisterLocationToSame (reg_num, /*must_replace*/ false);
                     m_curr_row_modified = true;
-                    m_curr_insn_restored_a_register = true;
                 }
             }
             break;

Modified: lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h?rev=240533&r1=240532&r2=240533&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h (original)
+++ lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h Wed Jun 24 06:27:32 2015
@@ -141,8 +141,7 @@ private:
         m_register_values (),
         m_pushed_regs(),
         m_curr_row_modified (false),
-        m_curr_insn_is_branch_immediate (false),
-        m_curr_insn_restored_a_register (false)
+        m_forward_branch_offset (0)
     {
         if (m_inst_emulator_ap.get())
         {
@@ -178,13 +177,11 @@ private:
     // While processing the instruction stream, we need to communicate some state change
     // information up to the higher level loop that makes decisions about how to push
     // the unwind instructions for the UnwindPlan we're constructing.
-    
+
     // The instruction we're processing updated the UnwindPlan::Row contents
     bool m_curr_row_modified;
-    // The instruction we're examining is a branch immediate instruction
-    bool m_curr_insn_is_branch_immediate;
-    // The instruction we're processing restored a caller's reg value (e.g. in an epilogue)
-    bool m_curr_insn_restored_a_register;
+    // The instruction is branching forward with the given offset. 0 value means no branching.
+    uint32_t m_forward_branch_offset;
 };
 
 #endif // liblldb_UnwindAssemblyInstEmulation_h_

Modified: lldb/trunk/source/Symbol/FuncUnwinders.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/FuncUnwinders.cpp?rev=240533&r1=240532&r2=240533&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/FuncUnwinders.cpp (original)
+++ lldb/trunk/source/Symbol/FuncUnwinders.cpp Wed Jun 24 06:27:32 2015
@@ -154,7 +154,7 @@ FuncUnwinders::GetEHFrameAugmentedUnwind
     // Augment the eh_frame instructions with epilogue descriptions if necessary so the
     // UnwindPlan can be used at any instruction in the function.
 
-    UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler());
+    UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target));
     if (assembly_profiler_sp)
     {
         if (!assembly_profiler_sp->AugmentUnwindPlanFromCallSite (m_range, thread, *m_unwind_plan_eh_frame_augmented_sp))
@@ -179,7 +179,7 @@ FuncUnwinders::GetAssemblyUnwindPlan (Ta
     Mutex::Locker lock (m_mutex);
     m_tried_unwind_plan_assembly = true;
 
-    UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler());
+    UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target));
     if (assembly_profiler_sp)
     {
         m_unwind_plan_assembly_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
@@ -204,7 +204,7 @@ FuncUnwinders::GetUnwindPlanAtNonCallSit
 }
 
 UnwindPlanSP
-FuncUnwinders::GetUnwindPlanFastUnwind (Thread& thread)
+FuncUnwinders::GetUnwindPlanFastUnwind (Target& target, Thread& thread)
 {
     if (m_unwind_plan_fast_sp.get() || m_tried_unwind_fast)
         return m_unwind_plan_fast_sp;
@@ -212,7 +212,7 @@ FuncUnwinders::GetUnwindPlanFastUnwind (
     Mutex::Locker locker (m_mutex);
     m_tried_unwind_fast = true;
 
-    UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler());
+    UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target));
     if (assembly_profiler_sp)
     {
         m_unwind_plan_fast_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
@@ -287,7 +287,7 @@ FuncUnwinders::GetFirstNonPrologueInsn (
 
     Mutex::Locker locker (m_mutex);
     ExecutionContext exe_ctx (target.shared_from_this(), false);
-    UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler());
+    UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target));
     if (assembly_profiler_sp)
         assembly_profiler_sp->FirstNonPrologueInsn (m_range, exe_ctx, m_first_non_prologue_insn);
     return m_first_non_prologue_insn;
@@ -300,12 +300,13 @@ FuncUnwinders::GetFunctionStartAddress (
 }
 
 lldb::UnwindAssemblySP
-FuncUnwinders::GetUnwindAssemblyProfiler ()
+FuncUnwinders::GetUnwindAssemblyProfiler (Target& target)
 {
     UnwindAssemblySP assembly_profiler_sp;
     ArchSpec arch;
     if (m_unwind_table.GetArchitecture (arch))
     {
+        arch.MergeFrom (target.GetArchitecture ());
         assembly_profiler_sp = UnwindAssembly::FindPlugin (arch);
     }
     return assembly_profiler_sp;

Modified: lldb/trunk/source/Symbol/UnwindPlan.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/UnwindPlan.cpp?rev=240533&r1=240532&r2=240533&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/UnwindPlan.cpp (original)
+++ lldb/trunk/source/Symbol/UnwindPlan.cpp Wed Jun 24 06:27:32 2015
@@ -343,11 +343,12 @@ UnwindPlan::InsertRow (const UnwindPlan:
     collection::iterator it = m_row_list.begin();
     while (it != m_row_list.end()) {
         RowSP row = *it;
-        if (row->GetOffset() > row_sp->GetOffset())
+        if (row->GetOffset() >= row_sp->GetOffset())
             break;
         it++;
     }
-    m_row_list.insert(it, row_sp);
+    if (it == m_row_list.end() || (*it)->GetOffset() != row_sp->GetOffset())
+        m_row_list.insert(it, row_sp);
 }
 
 UnwindPlan::RowSP






More information about the lldb-commits mailing list