diff options
author | Saleem Abdulrasool <compnerd@compnerd.org> | 2015-01-14 05:10:21 +0000 |
---|---|---|
committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2015-01-14 05:10:21 +0000 |
commit | ca24b1d6385da3bb1243b89035be4557b6cd9b80 (patch) | |
tree | dcb4c60d37a5a8a3cc3fb19bcf9f7162a9108a11 | |
parent | c16c427ebcd98598e1bb5b656f92a55f56c7f15b (diff) | |
download | llvm-ca24b1d6385da3bb1243b89035be4557b6cd9b80.zip llvm-ca24b1d6385da3bb1243b89035be4557b6cd9b80.tar.gz llvm-ca24b1d6385da3bb1243b89035be4557b6cd9b80.tar.bz2 |
X86: validate 'int' instruction
The int instruction takes as an operand an 8-bit immediate value. Validate that
the input is valid rather than silently truncating the value.
llvm-svn: 225941
-rw-r--r-- | llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 21 | ||||
-rw-r--r-- | llvm/test/MC/X86/validate-inst-att.s | 7 | ||||
-rw-r--r-- | llvm/test/MC/X86/validate-inst-intel.s | 9 |
3 files changed, 37 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index bb73823..2882448 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -684,6 +684,7 @@ private: bool ParseDirectiveWord(unsigned Size, SMLoc L); bool ParseDirectiveCode(StringRef IDVal, SMLoc L); + bool validateInstruction(MCInst &Inst, const OperandVector &Ops); bool processInstruction(MCInst &Inst, const OperandVector &Ops); /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds @@ -2272,6 +2273,20 @@ static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode, return convertToSExti8(Inst, Opcode, X86::RAX, isCmp); } +bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) { + switch (Inst.getOpcode()) { + default: return true; + case X86::INT: + assert(Inst.getOperand(0).isImm() && "expected immediate"); + if (Inst.getOperand(0).getImm() > 255) { + Error(Ops[1]->getStartLoc(), "interrupt vector must be in range [0-255]"); + return false; + } + return true; + } + llvm_unreachable("handle the instruction appropriately"); +} + bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) { switch (Inst.getOpcode()) { default: return false; @@ -2434,6 +2449,9 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode, isParsingIntelSyntax())) { default: llvm_unreachable("Unexpected match result!"); case Match_Success: + if (!validateInstruction(Inst, Operands)) + return true; + // Some instructions need post-processing to, for example, tweak which // encoding is selected. Loop on it while changes happen so the // individual transformations can chain off each other. @@ -2677,6 +2695,9 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode, unsigned NumSuccessfulMatches = std::count(std::begin(Match), std::end(Match), Match_Success); if (NumSuccessfulMatches == 1) { + if (!validateInstruction(Inst, Operands)) + return true; + // Some instructions need post-processing to, for example, tweak which // encoding is selected. Loop on it while changes happen so the individual // transformations can chain off each other. diff --git a/llvm/test/MC/X86/validate-inst-att.s b/llvm/test/MC/X86/validate-inst-att.s new file mode 100644 index 0000000..dec8bfd --- /dev/null +++ b/llvm/test/MC/X86/validate-inst-att.s @@ -0,0 +1,7 @@ +# RUN: not llvm-mc -triple i686 -filetype asm -o /dev/null %s 2>&1 | FileCheck %s + + .text + int $65535 +# CHECK: error: interrupt vector must be in range [0-255] +# CHECK: int $65535 +# CHECK: ^ diff --git a/llvm/test/MC/X86/validate-inst-intel.s b/llvm/test/MC/X86/validate-inst-intel.s new file mode 100644 index 0000000..9a7d122 --- /dev/null +++ b/llvm/test/MC/X86/validate-inst-intel.s @@ -0,0 +1,9 @@ +# RUN: not llvm-mc -x86-asm-syntax intel -triple i686 -filetype asm -o /dev/null %s 2>&1 \ +# RUN: | FileCheck %s + + .text + int 65535 +# CHECK: error: interrupt vector must be in range [0-255] +# CHECK: int 65535 +# CHECK: ^ + |