Skip to content

Commit b2ed11a

Browse files
author
Ana Pazos
committedSep 7, 2018
[RISCV] Fix crash in decoding instruction with unknown floating point 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
1 parent 4911d36 commit b2ed11a

File tree

4 files changed

+37
-1
lines changed

4 files changed

+37
-1
lines changed
 

‎llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//
1212
//===----------------------------------------------------------------------===//
1313

14+
#include "MCTargetDesc/RISCVBaseInfo.h"
1415
#include "MCTargetDesc/RISCVMCTargetDesc.h"
1516
#include "llvm/MC/MCContext.h"
1617
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
@@ -243,6 +244,17 @@ static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm,
243244
return MCDisassembler::Success;
244245
}
245246

247+
static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm,
248+
int64_t Address,
249+
const void *Decoder) {
250+
assert(isUInt<3>(Imm) && "Invalid immediate");
251+
if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm))
252+
return MCDisassembler::Fail;
253+
254+
Inst.addOperand(MCOperand::createImm(Imm));
255+
return MCDisassembler::Success;
256+
}
257+
246258
#include "RISCVGenDisassemblerTables.inc"
247259

248260
DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,

‎llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,21 @@ inline static RoundingMode stringToRoundingMode(StringRef Str) {
104104
.Case("dyn", RISCVFPRndMode::DYN)
105105
.Default(RISCVFPRndMode::Invalid);
106106
}
107+
108+
inline static bool isValidRoundingMode(unsigned Mode) {
109+
switch (Mode) {
110+
default:
111+
return false;
112+
case RISCVFPRndMode::RNE:
113+
case RISCVFPRndMode::RTZ:
114+
case RISCVFPRndMode::RDN:
115+
case RISCVFPRndMode::RUP:
116+
case RISCVFPRndMode::RMM:
117+
case RISCVFPRndMode::DYN:
118+
return true;
119+
}
120+
}
121+
107122
} // namespace RISCVFPRndMode
108123
} // namespace llvm
109124

‎llvm/lib/Target/RISCV/RISCVInstrInfoF.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def FRMArg : AsmOperandClass {
2727
def frmarg : Operand<XLenVT> {
2828
let ParserMatchClass = FRMArg;
2929
let PrintMethod = "printFRMArg";
30-
let DecoderMethod = "decodeUImmOperand<3>";
30+
let DecoderMethod = "decodeFRMArg";
3131
}
3232

3333
//===----------------------------------------------------------------------===//
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# RUN: not llvm-mc -disassemble -triple=riscv32 -mattr=+f,+d < %s 2>&1 | FileCheck %s
2+
# RUN: not llvm-mc -disassemble -triple=riscv64 -mattr=+f,+d < %s 2>&1 | FileCheck %s
3+
#
4+
# Test generated by a LLVM MC Disassembler Protocol Buffer Fuzzer
5+
# for the RISC-V assembly language.
6+
7+
# This decodes as fadd.s ft0, ft0, ft0 with unknown floating point rounding mode
8+
[0x53 0x50 0x00 0x00]
9+
# CHECK: warning: invalid instruction encoding

0 commit comments

Comments
 (0)
Please sign in to comment.