From: Ana Pazos Date: Thu, 13 Sep 2018 18:21:19 +0000 (+0000) Subject: [RISCV] Fix decoding of invalid instruction with C extension enabled. X-Git-Tag: llvmorg-8.0.0-rc1~8783 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b0799dda77c6b75526e1415331e2a9656abd6f95;p=platform%2Fupstream%2Fllvm.git [RISCV] Fix decoding of invalid instruction with C extension enabled. Summary: The illegal instruction 0x00 0x00 is being wrongly decoded as c.addi4spn with 0 immediate. The invalid instruction 0x01 0x61 is being wrongly decoded as c.addi16sp with 0 immediate. This bug was uncovered by a LLVM MC Disassembler Protocol Buffer Fuzzer for the RISC-V assembly language. Reviewers: asb Reviewed By: asb Subscribers: rbar, johnrusso, simoncook, sabuasal, niosHD, kito-cheng, shiva0217, zzheng, edward-jones, mgrang, rogfer01, MartinMosbeck, brucehoult, the_o, rkruppe, PkmX, jocewei, asb Differential Revision: https://reviews.llvm.org/D51815 llvm-svn: 342159 --- diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 69afa4b..d5b8b38 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -212,6 +212,15 @@ static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, } template +static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint64_t Imm, + int64_t Address, + const void *Decoder) { + if (Imm == 0) + return MCDisassembler::Fail; + return decodeUImmOperand(Inst, Imm, Address, Decoder); +} + +template static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder) { assert(isUInt(Imm) && "Invalid immediate"); @@ -222,6 +231,15 @@ static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, } template +static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint64_t Imm, + int64_t Address, + const void *Decoder) { + if (Imm == 0) + return MCDisassembler::Fail; + return decodeSImmOperand(Inst, Imm, Address, Decoder); +} + +template static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder) { diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td index eae9441..c85a634 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td @@ -167,7 +167,7 @@ def uimm10_lsb00nonzero : Operand, [{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> { let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">; let EncoderMethod = "getImmOpValue"; - let DecoderMethod = "decodeUImmOperand<10>"; + let DecoderMethod = "decodeUImmNonZeroOperand<10>"; let MCOperandPredicate = [{ int64_t Imm; if (!MCOp.evaluateAsConstantImm(Imm)) @@ -182,7 +182,7 @@ def simm10_lsb0000nonzero : Operand, [{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> { let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">; let EncoderMethod = "getImmOpValue"; - let DecoderMethod = "decodeSImmOperand<10>"; + let DecoderMethod = "decodeSImmNonZeroOperand<10>"; let MCOperandPredicate = [{ int64_t Imm; if (!MCOp.evaluateAsConstantImm(Imm)) diff --git a/llvm/test/MC/Disassembler/RISCV/invalid-instruction.txt b/llvm/test/MC/Disassembler/RISCV/invalid-instruction.txt new file mode 100644 index 0000000..1bf033c --- /dev/null +++ b/llvm/test/MC/Disassembler/RISCV/invalid-instruction.txt @@ -0,0 +1,13 @@ +# RUN: not llvm-mc -disassemble -triple=riscv32 -mattr=+c < %s 2>&1 | FileCheck %s +# RUN: not llvm-mc -disassemble -triple=riscv64 -mattr=+c < %s 2>&1 | FileCheck %s +# +# Test generated by a LLVM MC Disassembler Protocol Buffer Fuzzer +# for the RISC-V assembly language. + +# This should not decode as c.addi4spn with 0 imm when compression is enabled. +[0x00 0x00] +# CHECK: warning: invalid instruction encoding + +# This should not decode as c.addi16sp with 0 imm when compression is enabled. +[0x01 0x61] +# CHECK: warning: invalid instruction encoding