X86: validate 'int' instruction
authorSaleem Abdulrasool <compnerd@compnerd.org>
Wed, 14 Jan 2015 05:10:21 +0000 (05:10 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Wed, 14 Jan 2015 05:10:21 +0000 (05:10 +0000)
The int instruction takes as an operand an 8-bit immediate value.  Validate that
the input is valid rather than silently truncating the value.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225941 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/AsmParser/X86AsmParser.cpp
test/MC/X86/validate-inst-att.s [new file with mode: 0644]
test/MC/X86/validate-inst-intel.s [new file with mode: 0644]

index bb738231baa77cc029d90448d3be36a4469055cc..28824488a7115bc4867e26496f82724aa0a3da02 100644 (file)
@@ -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/test/MC/X86/validate-inst-att.s b/test/MC/X86/validate-inst-att.s
new file mode 100644 (file)
index 0000000..dec8bfd
--- /dev/null
@@ -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/test/MC/X86/validate-inst-intel.s b/test/MC/X86/validate-inst-intel.s
new file mode 100644 (file)
index 0000000..9a7d122
--- /dev/null
@@ -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:            ^
+