diff options
author | Greg Clayton <gclayton@apple.com> | 2011-07-06 04:07:21 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2011-07-06 04:07:21 +0000 |
commit | 34132754bdfd94be8199945b3f4c8dbe8bd67cf3 (patch) | |
tree | a5484c20520094a78a9d9cc93656d414f9df6dc2 /lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp | |
parent | a98034a25e3084073f1068568e1d1b95ed243f71 (diff) | |
download | bcm5719-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.cpp | 109 |
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; } |