From e679d3331b5fb4747c5f03b546376f8fdb6a25d4 Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Mon, 11 Apr 2011 18:34:12 +0000 Subject: [PATCH] Check invalid register encodings for LdFrm/StFrm ARM instructions and flag them as invalid instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129286 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../ARM/Disassembler/ARMDisassemblerCore.cpp | 68 +++++++++++++++++++ .../ARM/invalid-LDRB_POST-arm.txt | 10 +++ .../Disassembler/ARM/invalid-LDR_POST-arm.txt | 4 ++ .../Disassembler/ARM/invalid-LDR_PRE-arm.txt | 10 +++ .../Disassembler/ARM/invalid-STRBrs-arm.txt | 10 +++ 5 files changed, 102 insertions(+) create mode 100644 test/MC/Disassembler/ARM/invalid-LDRB_POST-arm.txt create mode 100644 test/MC/Disassembler/ARM/invalid-LDR_POST-arm.txt create mode 100644 test/MC/Disassembler/ARM/invalid-LDR_PRE-arm.txt create mode 100644 test/MC/Disassembler/ARM/invalid-STRBrs-arm.txt diff --git a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp index d5675d26fcb..26d0e03787d 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp @@ -1175,6 +1175,71 @@ static bool DisassembleDPSoRegFrm(MCInst &MI, unsigned Opcode, uint32_t insn, return true; } +static bool BadRegsLdStFrm(unsigned Opcode, uint32_t insn, bool Store, bool WBack, + bool Imm) { + const StringRef Name = ARMInsts[Opcode].Name; + unsigned Rt = decodeRd(insn); + unsigned Rn = decodeRn(insn); + unsigned Rm = decodeRm(insn); + unsigned P = getPBit(insn); + unsigned W = getWBit(insn); + + if (Store) { + // Only STR (immediate, register) allows PC as the source. + if (Name.startswith("STRB") && Rt == 15) { + DEBUG(errs() << "if t == 15 then UNPREDICTABLE\n"); + return true; + } + if (WBack && (Rn == 15 || Rn == Rt)) { + DEBUG(errs() << "if wback && (n == 15 || n == t) then UNPREDICTABLE\n"); + return true; + } + if (!Imm && Rm == 15) { + DEBUG(errs() << "if m == 15 then UNPREDICTABLE\n"); + return true; + } + } else { + // Only LDR (immediate, register) allows PC as the destination. + if (Name.startswith("LDRB") && Rt == 15) { + DEBUG(errs() << "if t == 15 then UNPREDICTABLE\n"); + return true; + } + if (Imm) { + // Immediate + if (Rn == 15) { + // The literal form must be in offset mode; it's an encoding error + // otherwise. + if (!(P == 1 && W == 0)) { + DEBUG(errs() << "Ld literal form with !(P == 1 && W == 0)\n"); + return true; + } + // LDRB (literal) does not allow PC as the destination. + if (Opcode != ARM::LDRi12 && Rt == 15) { + DEBUG(errs() << "if t == 15 then UNPREDICTABLE\n"); + return true; + } + } else { + // Write back while Rn == Rt does not make sense. + if (WBack && (Rn == Rt)) { + DEBUG(errs() << "if wback && n == t then UNPREDICTABLE\n"); + return true; + } + } + } else { + // Register + if (Rm == 15) { + DEBUG(errs() << "if m == 15 then UNPREDICTABLE\n"); + return true; + } + if (WBack && (Rn == 15 || Rn == Rt)) { + DEBUG(errs() << "if wback && (n == 15 || n == t) then UNPREDICTABLE\n"); + return true; + } + } + } + return false; +} + static bool DisassembleLdStFrm(MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, bool isStore, BO B) { @@ -1237,6 +1302,9 @@ static bool DisassembleLdStFrm(MCInst &MI, unsigned Opcode, uint32_t insn, if (OpIdx + 1 >= NumOps) return false; + if (BadRegsLdStFrm(Opcode, insn, isStore, isPrePost, getIBit(insn)==0)) + return false; + ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub; unsigned IndexMode = (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift; diff --git a/test/MC/Disassembler/ARM/invalid-LDRB_POST-arm.txt b/test/MC/Disassembler/ARM/invalid-LDRB_POST-arm.txt new file mode 100644 index 00000000000..7a35c2d6ce0 --- /dev/null +++ b/test/MC/Disassembler/ARM/invalid-LDRB_POST-arm.txt @@ -0,0 +1,10 @@ +# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} + +# Opcode=140 Name=LDRB_POST Format=ARM_FORMAT_LDFRM(6) +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# ------------------------------------------------------------------------------------------------- +# | 1: 1: 1: 0| 0: 1: 1: 0| 1: 1: 0: 1| 0: 1: 1: 1| 0: 1: 1: 1| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 0: 1| +# ------------------------------------------------------------------------------------------------- +# +# if wback && (n == 15 || n == t) then UNPREDICTABLE +0x05 0x70 0xd7 0xe6 diff --git a/test/MC/Disassembler/ARM/invalid-LDR_POST-arm.txt b/test/MC/Disassembler/ARM/invalid-LDR_POST-arm.txt new file mode 100644 index 00000000000..ad79986b254 --- /dev/null +++ b/test/MC/Disassembler/ARM/invalid-LDR_POST-arm.txt @@ -0,0 +1,4 @@ +# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} + +# LDR_PRE/POST has encoding Inst{4} = 0. +0xde 0x69 0x18 0x46 diff --git a/test/MC/Disassembler/ARM/invalid-LDR_PRE-arm.txt b/test/MC/Disassembler/ARM/invalid-LDR_PRE-arm.txt new file mode 100644 index 00000000000..36c1124bced --- /dev/null +++ b/test/MC/Disassembler/ARM/invalid-LDR_PRE-arm.txt @@ -0,0 +1,10 @@ +# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} + +# Opcode=165 Name=LDR_PRE Format=ARM_FORMAT_LDFRM(6) +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# ------------------------------------------------------------------------------------------------- +# | 1: 1: 1: 0| 0: 1: 1: 1| 1: 0: 1: 1| 0: 1: 1: 1| 0: 1: 1: 0| 0: 0: 0: 0| 1: 0: 0: 0| 1: 1: 1: 1| +# ------------------------------------------------------------------------------------------------- +# +# if m == 15 then UNPREDICTABLE +0x8f 0x60 0xb7 0xe7 diff --git a/test/MC/Disassembler/ARM/invalid-STRBrs-arm.txt b/test/MC/Disassembler/ARM/invalid-STRBrs-arm.txt new file mode 100644 index 00000000000..5209323fa84 --- /dev/null +++ b/test/MC/Disassembler/ARM/invalid-STRBrs-arm.txt @@ -0,0 +1,10 @@ +# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} + +# Opcode=355 Name=STRBrs Format=ARM_FORMAT_STFRM(7) +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# ------------------------------------------------------------------------------------------------- +# | 1: 1: 1: 0| 0: 1: 1: 1| 1: 1: 0: 0| 1: 1: 1: 1| 1: 1: 1: 1| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| +# ------------------------------------------------------------------------------------------------- +# +# if t == 15 then UNPREDICTABLE +0x00 0xf0 0xcf 0xe7