diff options
| -rw-r--r-- | lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp | 135 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/Utility/ARMUtils.h | 122 |
2 files changed, 187 insertions, 70 deletions
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index 7bd9d5798fa..e9237acac91 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -1121,7 +1121,9 @@ EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding e if (!success) return false; - uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry); + uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); + if (!success) + return false; uint32_t result = ~shifted; // The context specifies that an immediate is to be moved into Rd. @@ -2628,7 +2630,9 @@ EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding e if (!success) return false; - uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); + uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; AddWithCarryResult res = AddWithCarry(val1, shifted, 0); EmulateInstruction::Context context; @@ -2751,7 +2755,9 @@ EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding e if (!success) return false; - uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); + uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; AddWithCarryResult res = AddWithCarry(val1, shifted, 0); EmulateInstruction::Context context; @@ -2875,7 +2881,9 @@ EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding e if (!success) return false; - uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); + uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); EmulateInstruction::Context context; @@ -3182,7 +3190,9 @@ EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding // Decode the shift amount if not RRX. uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); - uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry); + uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); + if (!success) + return false; // The context specifies that an immediate is to be moved into Rd. EmulateInstruction::Context context; @@ -3251,7 +3261,9 @@ EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding // Get the shift amount. uint32_t amt = Bits32(val, 7, 0); - uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry); + uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); + if (!success) + return false; // The context specifies that an immediate is to be moved into Rd. EmulateInstruction::Context context; @@ -4771,7 +4783,9 @@ EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncod return false; // offset = Shift(R[m], shift_t, shift_n, APSR.C); - offset = Shift (Rm_data, shift_t, shift_n, APSR_C); + offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; // offset_addr = if add then (R[n] + offset) else (R[n] - offset); if (add) @@ -5085,7 +5099,9 @@ EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEnco return false; // offset = Shift(R[m], shift_t, shift_n, APSR.C); - uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C); + uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; // offset_addr = if add then (R[n] + offset) else (R[n] - offset); addr_t offset_addr; @@ -5289,7 +5305,9 @@ EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding e if (!success) return false; - uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); + uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); EmulateInstruction::Context context; @@ -5515,7 +5533,9 @@ EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding e if (!success) return false; - uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); + uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); + if (!success) + return false; uint32_t result = val1 & shifted; EmulateInstruction::Context context; @@ -5674,7 +5694,9 @@ EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding e if (!success) return false; - uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); + uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); + if (!success) + return false; uint32_t result = val1 & ~shifted; EmulateInstruction::Context context; @@ -5813,7 +5835,9 @@ EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARME else { // R[t] = ROR(data, 8*UInt(address<1:0>)); - data = ROR (data, Bits32 (address, 1, 0)); + data = ROR (data, Bits32 (address, 1, 0), &success); + if (!success) + return false; context.type = eContextRegisterLoad; context.SetImmediate (data); if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) @@ -5954,7 +5978,9 @@ EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncod addr_t address; // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". - addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C)); + addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success); + if (!success) + return false; // offset_addr = if add then (R[n] + offset) else (R[n] - offset); if (add) @@ -6017,7 +6043,9 @@ EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncod if (CurrentInstrSet () == eModeARM) { // R[t] = ROR(data, 8*UInt(address<1:0>)); - data = ROR (data, Bits32 (address, 1, 0)); + data = ROR (data, Bits32 (address, 1, 0), &success); + if (!success) + return false; context.type = eContextRegisterLoad; context.SetImmediate (data); if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) @@ -6357,7 +6385,9 @@ EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEnco if (!success) return false; - addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C); + addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; // offset_addr = if add then (R[n] + offset) else (R[n] - offset); uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); @@ -6771,7 +6801,9 @@ EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEnco if (!success) return false; - addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C); + addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; addr_t offset_addr; addr_t address; @@ -7176,7 +7208,9 @@ EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEnc return false; // offset = Shift(R[m], shift_t, shift_n, APSR.C); - addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C); + addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; addr_t offset_addr; addr_t address; @@ -7607,7 +7641,9 @@ EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEnc return false; // offset = Shift(R[m], shift_t, shift_n, APSR.C); - addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C); + addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; addr_t offset_addr; addr_t address; @@ -7732,7 +7768,9 @@ EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding enc return false; // rotated = ROR(R[m], rotation); - uint64_t rotated = ROR (Rm, rotation); + uint64_t rotated = ROR (Rm, rotation, &success); + if (!success) + return false; // R[d] = SignExtend(rotated<7:0>, 32); int64_t data = llvm::SignExtend64<8>(rotated); @@ -7814,7 +7852,9 @@ EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding enc return false; // rotated = ROR(R[m], rotation); - uint64_t rotated = ROR (Rm, rotation); + uint64_t rotated = ROR (Rm, rotation, &success); + if (!success) + return false; // R[d] = SignExtend(rotated<15:0>, 32); RegisterInfo source_reg; @@ -7896,7 +7936,9 @@ EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding enc return false; // rotated = ROR(R[m], rotation); - uint64_t rotated = ROR (Rm, rotation); + uint64_t rotated = ROR (Rm, rotation, &success); + if (!success) + return false; // R[d] = ZeroExtend(rotated<7:0>, 32); RegisterInfo source_reg; @@ -7975,7 +8017,9 @@ EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding enc return false; // rotated = ROR(R[m], rotation); - uint64_t rotated = ROR (Rm, rotation); + uint64_t rotated = ROR (Rm, rotation, &success); + if (!success) + return false; // R[d] = ZeroExtend(rotated<15:0>, 32); RegisterInfo source_reg; @@ -8290,7 +8334,9 @@ EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding e if (!success) return false; - uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); + uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); + if (!success) + return false; uint32_t result = val1 ^ shifted; EmulateInstruction::Context context; @@ -8453,7 +8499,9 @@ EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding e if (!success) return false; - uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); + uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); + if (!success) + return false; uint32_t result = val1 | shifted; EmulateInstruction::Context context; @@ -8603,7 +8651,9 @@ EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding e if (!success) return false; - uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); + uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); EmulateInstruction::Context context; @@ -8730,7 +8780,9 @@ EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding e if (!success) return false; - uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); + uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); EmulateInstruction::Context context; @@ -8881,7 +8933,9 @@ EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding e if (!success) return false; - uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C); + uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); EmulateInstruction::Context context; @@ -9160,7 +9214,9 @@ EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding e if (!success) return false; - uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); + uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); + if (!success) + return false; uint32_t result = val1 ^ shifted; EmulateInstruction::Context context; @@ -9288,7 +9344,9 @@ EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding e if (!success) return false; - uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry); + uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); + if (!success) + return false; uint32_t result = val1 & shifted; EmulateInstruction::Context context; @@ -9374,7 +9432,9 @@ EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding if (!success) return false; - uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C); + uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), Ô1Õ); uint32_t sp_val = ReadCoreReg (SP_REG, &success); @@ -9461,8 +9521,10 @@ EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncod if (!success) return false; - uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C); - + uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; + // (result, carry, overflow) = AddWithCarry(R[n], shifted, Ô0Õ); uint32_t Rn = ReadCoreReg (n, &success); if (!success) @@ -9584,7 +9646,9 @@ EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding e if (!success) return false; - uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C); + uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), Ô1Õ); uint32_t Rn = ReadCoreReg (n, &success); @@ -12019,8 +12083,9 @@ EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncod if (!success) return false; - operand2 = Shift (Rm, shift_t, shift_n, APSR_C); - + operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success); + if (!success) + return false; } else { diff --git a/lldb/source/Plugins/Process/Utility/ARMUtils.h b/lldb/source/Plugins/Process/Utility/ARMUtils.h index c8ffb9327d0..fce066d91ff 100644 --- a/lldb/source/Plugins/Process/Utility/ARMUtils.h +++ b/lldb/source/Plugins/Process/Utility/ARMUtils.h @@ -89,41 +89,61 @@ static inline ARM_ShifterType DecodeRegShift(const uint32_t type) } } -static inline uint32_t LSL_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out) +static inline uint32_t LSL_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success) { - //assert(amount > 0); + if (amount == 0) { + *success = false; + return 0; + } + *success = true; carry_out = amount <= 32 ? Bit32(value, 32 - amount) : 0; return value << amount; } -static inline uint32_t LSL(const uint32_t value, const uint32_t amount) +static inline uint32_t LSL(const uint32_t value, const uint32_t amount, bool *success) { - //assert(amount >= 0); + *success = true; if (amount == 0) return value; uint32_t dont_care; - return LSL_C(value, amount, dont_care); + uint32_t result = LSL_C(value, amount, dont_care, success); + if (*success) + return result; + else + return 0; } -static inline uint32_t LSR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out) +static inline uint32_t LSR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success) { - //assert(amount > 0); + if (amount == 0) { + *success = false; + return 0; + } + *success = true; carry_out = amount <= 32 ? Bit32(value, amount - 1) : 0; return value >> amount; } -static inline uint32_t LSR(const uint32_t value, const uint32_t amount) +static inline uint32_t LSR(const uint32_t value, const uint32_t amount, bool *success) { - //assert(amount >= 0); + *success = true; if (amount == 0) return value; uint32_t dont_care; - return LSR_C(value, amount, dont_care); + uint32_t result = LSR_C(value, amount, dont_care, success); + if (*success) + return result; + else + return 0; } -static inline uint32_t ASR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out) +static inline uint32_t ASR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success) { - //assert(amount > 0 && amount <= 32); + if (amount == 0 || amount > 32) { + *success = false; + return 0; + } + *success = true; bool negative = BitIsSet(value, 31); if (amount <= 32) { @@ -138,81 +158,113 @@ static inline uint32_t ASR_C(const uint32_t value, const uint32_t amount, uint32 } } -static inline uint32_t ASR(const uint32_t value, const uint32_t amount) +static inline uint32_t ASR(const uint32_t value, const uint32_t amount, bool *success) { - //assert(amount >= 0); + *success = true; if (amount == 0) return value; uint32_t dont_care; - return ASR_C(value, amount, dont_care); + uint32_t result = ASR_C(value, amount, dont_care, success); + if (*success) + return result; + else + return 0; } -static inline uint32_t ROR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out) +static inline uint32_t ROR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success) { - //assert(amount > 0); + if (amount == 0) { + *success = false; + return 0; + } + *success = true; uint32_t amt = amount % 32; uint32_t result = Rotr32(value, amt); carry_out = Bit32(value, 31); return result; } -static inline uint32_t ROR(const uint32_t value, const uint32_t amount) +static inline uint32_t ROR(const uint32_t value, const uint32_t amount, bool *success) { - //assert(amount >= 0); + *success = true; if (amount == 0) return value; uint32_t dont_care; - return ROR_C(value, amount, dont_care); + uint32_t result = ROR_C(value, amount, dont_care, success); + if (*success) + return result; + else + return 0; } -static inline uint32_t RRX_C(const uint32_t value, const uint32_t carry_in, uint32_t &carry_out) +static inline uint32_t RRX_C(const uint32_t value, const uint32_t carry_in, uint32_t &carry_out, bool *success) { + *success = true; carry_out = Bit32(value, 0); return Bit32(carry_in, 0) << 31 | Bits32(value, 31, 1); } -static inline uint32_t RRX(const uint32_t value, const uint32_t carry_in) +static inline uint32_t RRX(const uint32_t value, const uint32_t carry_in, bool *success) { + *success = true; uint32_t dont_care; - return RRX_C(value, carry_in, dont_care); + uint32_t result = RRX_C(value, carry_in, dont_care, success); + if (*success) + return result; + else + return 0; } static inline uint32_t Shift_C(const uint32_t value, ARM_ShifterType type, const uint32_t amount, - const uint32_t carry_in, uint32_t &carry_out) + const uint32_t carry_in, uint32_t &carry_out, bool *success) { - //assert(type != SRType_RRX || amount == 1); - if (amount == 0) - { + if (type == SRType_RRX && amount != 1) { + *success = false; + return 0; + } + *success = true; + + if (amount == 0) { carry_out = carry_in; return value; } uint32_t result; switch (type) { case SRType_LSL: - result = LSL_C(value, amount, carry_out); + result = LSL_C(value, amount, carry_out, success); break; case SRType_LSR: - result = LSR_C(value, amount, carry_out); + result = LSR_C(value, amount, carry_out, success); break; case SRType_ASR: - result = ASR_C(value, amount, carry_out); + result = ASR_C(value, amount, carry_out, success); break; case SRType_ROR: - result = ROR_C(value, amount, carry_out); + result = ROR_C(value, amount, carry_out, success); break; case SRType_RRX: - result = RRX_C(value, carry_in, carry_out); + result = RRX_C(value, carry_in, carry_out, success); + break; + default: + *success = false; break; } - return result; + if (*success) + return result; + else + return 0; } static inline uint32_t Shift(const uint32_t value, ARM_ShifterType type, const uint32_t amount, - const uint32_t carry_in) + const uint32_t carry_in, bool *success) { // Don't care about carry out in this case. uint32_t dont_care; - return Shift_C(value, type, amount, carry_in, dont_care); + uint32_t result = Shift_C(value, type, amount, carry_in, dont_care, success); + if (*success) + return result; + else + return 0; } static inline uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit) |

