[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