summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2011-07-06 04:07:21 +0000
committerGreg Clayton <gclayton@apple.com>2011-07-06 04:07:21 +0000
commit34132754bdfd94be8199945b3f4c8dbe8bd67cf3 (patch)
treea5484c20520094a78a9d9cc93656d414f9df6dc2 /lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
parenta98034a25e3084073f1068568e1d1b95ed243f71 (diff)
downloadbcm5719-llvm-34132754bdfd94be8199945b3f4c8dbe8bd67cf3.tar.gz
bcm5719-llvm-34132754bdfd94be8199945b3f4c8dbe8bd67cf3.zip
Fixed some issues with ARM backtraces by not processing any push/pop
instructions if they are conditional. Also fixed issues where the PC wasn't getting bit zero stripped for ARM targets when a stack frame was thumb. We now properly call through the GetOpcodeLoadAddress() functions to make sure the addresses are properly stripped for any targets that may decorate up their addresses. We now don't pass the SIGSTOP signals along. We can revisit this soon, but currently this was interfering with debugging some older ARM targets that don't have vCont support in the GDB server. llvm-svn: 134461
Diffstat (limited to 'lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp')
-rw-r--r--lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp109
1 files changed, 72 insertions, 37 deletions
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index f79f7d28e66..daaac46b317 100644
--- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -327,8 +327,9 @@ EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding enc
}
#endif
+ bool conditional = false;
bool success = false;
- if (ConditionPassed(opcode))
+ if (ConditionPassed(opcode, &conditional))
{
const uint32_t addr_byte_size = GetAddressByteSize();
const addr_t sp = ReadCoreReg (SP_REG, &success);
@@ -381,7 +382,10 @@ EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding enc
uint32_t i;
EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextPushRegisterOnStack;
+ if (conditional)
+ context.type = EmulateInstruction::eContextRegisterStore;
+ else
+ context.type = EmulateInstruction::eContextPushRegisterOnStack;
RegisterInfo reg_info;
RegisterInfo sp_reg;
GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
@@ -447,7 +451,9 @@ EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding enco
bool success = false;
- if (ConditionPassed(opcode)) {
+ bool conditional = false;
+ if (ConditionPassed(opcode, &conditional))
+ {
const uint32_t addr_byte_size = GetAddressByteSize();
const addr_t sp = ReadCoreReg (SP_REG, &success);
if (!success)
@@ -508,7 +514,10 @@ EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding enco
uint32_t i, data;
EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextPopRegisterOffStack;
+ if (conditional)
+ context.type = EmulateInstruction::eContextRegisterLoad;
+ else
+ context.type = EmulateInstruction::eContextPopRegisterOffStack;
RegisterInfo sp_reg;
GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
@@ -1847,9 +1856,9 @@ EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding
}
#endif
+ bool conditional = false;
bool success = false;
-
- if (ConditionPassed(opcode))
+ if (ConditionPassed(opcode, &conditional))
{
const uint32_t addr_byte_size = GetAddressByteSize();
const addr_t sp = ReadCoreReg (SP_REG, &success);
@@ -1894,7 +1903,10 @@ EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding
addr = sp;
EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextPushRegisterOnStack;
+ if (conditional)
+ context.type = EmulateInstruction::eContextRegisterStore;
+ else
+ context.type = EmulateInstruction::eContextPushRegisterOnStack;
RegisterInfo sp_reg;
RegisterInfo dwarf_reg;
@@ -1955,8 +1967,8 @@ EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding en
#endif
bool success = false;
-
- if (ConditionPassed(opcode))
+ bool conditional = false;
+ if (ConditionPassed(opcode, &conditional))
{
const uint32_t addr_byte_size = GetAddressByteSize();
const addr_t sp = ReadCoreReg (SP_REG, &success);
@@ -1998,7 +2010,10 @@ EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding en
uint32_t i;
EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextPushRegisterOnStack;
+ if (conditional)
+ context.type = EmulateInstruction::eContextRegisterStore;
+ else
+ context.type = EmulateInstruction::eContextPushRegisterOnStack;
RegisterInfo dwarf_reg;
RegisterInfo sp_reg;
GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
@@ -2048,8 +2063,8 @@ EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding enc
#endif
bool success = false;
-
- if (ConditionPassed(opcode))
+ bool conditional = false;
+ if (ConditionPassed(opcode, &conditional))
{
const uint32_t addr_byte_size = GetAddressByteSize();
const addr_t sp = ReadCoreReg (SP_REG, &success);
@@ -2092,7 +2107,10 @@ EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding enc
uint64_t data; // uint64_t to accomodate 64-bit registers.
EmulateInstruction::Context context;
- context.type = EmulateInstruction::eContextPopRegisterOffStack;
+ if (conditional)
+ context.type = EmulateInstruction::eContextRegisterLoad;
+ else
+ context.type = EmulateInstruction::eContextPopRegisterOffStack;
RegisterInfo dwarf_reg;
RegisterInfo sp_reg;
GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
@@ -3303,8 +3321,8 @@ EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding enco
#endif
bool success = false;
-
- if (ConditionPassed(opcode))
+ bool conditional = false;
+ if (ConditionPassed(opcode, &conditional))
{
uint32_t n;
uint32_t registers = 0;
@@ -3376,7 +3394,12 @@ EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding enco
context.type = EmulateInstruction::eContextRegisterPlusOffset;
context.SetRegisterPlusOffset (dwarf_reg, offset);
if (wback && (n == 13)) // Pop Instruction
- context.type = EmulateInstruction::eContextPopRegisterOffStack;
+ {
+ if (conditional)
+ context.type = EmulateInstruction::eContextRegisterLoad;
+ else
+ context.type = EmulateInstruction::eContextPopRegisterOffStack;
+ }
// R[i] = MemA [address, 4]; address = address + 4;
uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
@@ -12849,7 +12872,7 @@ EmulateInstructionARM::ArchVersion ()
}
bool
-EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
+EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional)
{
// If we are ignoring conditions, then always return true.
// this allows us to iterate over disassembly code and still
@@ -12857,6 +12880,9 @@ EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
// bits set in the CPSR register...
if (m_ignore_conditions)
return true;
+
+ if (is_conditional)
+ *is_conditional = true;
const uint32_t cond = CurrentCond (opcode);
@@ -12868,33 +12894,38 @@ EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
{
case 0:
if (m_opcode_cpsr == 0)
- return true;
- result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
+ result = true;
+ else
+ result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
break;
case 1:
- if (m_opcode_cpsr == 0)
- return true;
- result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else
+ result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
break;
case 2:
- if (m_opcode_cpsr == 0)
- return true;
- result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else
+ result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
break;
case 3:
- if (m_opcode_cpsr == 0)
- return true;
- result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else
+ result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
break;
case 4:
- if (m_opcode_cpsr == 0)
- return true;
- result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else
+ result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
break;
case 5:
- if (m_opcode_cpsr == 0)
- return true;
- else
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else
{
bool n = (m_opcode_cpsr & MASK_CPSR_N);
bool v = (m_opcode_cpsr & MASK_CPSR_V);
@@ -12902,9 +12933,9 @@ EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
}
break;
case 6:
- if (m_opcode_cpsr == 0)
- return true;
- else
+ if (m_opcode_cpsr == 0)
+ result = true;
+ else
{
bool n = (m_opcode_cpsr & MASK_CPSR_N);
bool v = (m_opcode_cpsr & MASK_CPSR_V);
@@ -12912,6 +12943,10 @@ EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
}
break;
case 7:
+ // Always execute (cond == 0b1110, or the special 0b1111 which gives
+ // opcodes different meanings, but always means execution happpens.
+ if (is_conditional)
+ *is_conditional = false;
result = true;
break;
}
OpenPOWER on IntegriCloud