Skip to content

Commit

Permalink
[RISCV] Fix crash in decoding instruction with unknown floating point…
Browse files Browse the repository at this point in the history
… rounding mode

Summary:
Instead of crashing in printFRMArg, decode and warn about invalid instruction.

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/D51705

llvm-svn: 341691
  • Loading branch information
Ana Pazos committed Sep 7, 2018
1 parent 4911d36 commit b2ed11a
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 1 deletion.
12 changes: 12 additions & 0 deletions llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
Expand Up @@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/RISCVBaseInfo.h"
#include "MCTargetDesc/RISCVMCTargetDesc.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
Expand Down Expand Up @@ -243,6 +244,17 @@ static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm,
return MCDisassembler::Success;
}

static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm,
int64_t Address,
const void *Decoder) {
assert(isUInt<3>(Imm) && "Invalid immediate");
if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm))
return MCDisassembler::Fail;

Inst.addOperand(MCOperand::createImm(Imm));
return MCDisassembler::Success;
}

#include "RISCVGenDisassemblerTables.inc"

DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
Expand Down
15 changes: 15 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
Expand Up @@ -104,6 +104,21 @@ inline static RoundingMode stringToRoundingMode(StringRef Str) {
.Case("dyn", RISCVFPRndMode::DYN)
.Default(RISCVFPRndMode::Invalid);
}

inline static bool isValidRoundingMode(unsigned Mode) {
switch (Mode) {
default:
return false;
case RISCVFPRndMode::RNE:
case RISCVFPRndMode::RTZ:
case RISCVFPRndMode::RDN:
case RISCVFPRndMode::RUP:
case RISCVFPRndMode::RMM:
case RISCVFPRndMode::DYN:
return true;
}
}

} // namespace RISCVFPRndMode
} // namespace llvm

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/RISCV/RISCVInstrInfoF.td
Expand Up @@ -27,7 +27,7 @@ def FRMArg : AsmOperandClass {
def frmarg : Operand<XLenVT> {
let ParserMatchClass = FRMArg;
let PrintMethod = "printFRMArg";
let DecoderMethod = "decodeUImmOperand<3>";
let DecoderMethod = "decodeFRMArg";
}

//===----------------------------------------------------------------------===//
Expand Down
9 changes: 9 additions & 0 deletions llvm/test/MC/Disassembler/RISCV/invalid-fp-rounding-mode.txt
@@ -0,0 +1,9 @@
# RUN: not llvm-mc -disassemble -triple=riscv32 -mattr=+f,+d < %s 2>&1 | FileCheck %s
# RUN: not llvm-mc -disassemble -triple=riscv64 -mattr=+f,+d < %s 2>&1 | FileCheck %s
#
# Test generated by a LLVM MC Disassembler Protocol Buffer Fuzzer
# for the RISC-V assembly language.

# This decodes as fadd.s ft0, ft0, ft0 with unknown floating point rounding mode
[0x53 0x50 0x00 0x00]
# CHECK: warning: invalid instruction encoding

0 comments on commit b2ed11a

Please sign in to comment.