From 9f7039dc33b1e2fe595c309402997d05a70e116b Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Thu, 10 Jan 2019 22:59:50 +0000 Subject: [PATCH] [MSP430] Minor fixes/improvements for assembler/disassembler * Teach AsmParser to recognize @rn in distination operand as 0(rn). * Do not allow Disassembler decoding instructions that have size more than a number of input bytes. * Fix UB in MSP430MCCodeEmitter. Patch by Kristina Bessonova! Differential Revision: https://reviews.llvm.org/D56547 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350903 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp | 6 +++++- .../MSP430/Disassembler/MSP430Disassembler.cpp | 12 ++++++++++++ .../MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp | 2 +- test/MC/Disassembler/MSP430/unknown.txt | 13 +++++++++++++ test/MC/MSP430/addrmode.s | 2 ++ test/MC/MSP430/invalid.s | 1 - 6 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 test/MC/Disassembler/MSP430/unknown.txt diff --git a/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp b/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp index 3cc6da2c21a..1ad70ac72c7 100644 --- a/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp +++ b/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp @@ -497,7 +497,11 @@ bool MSP430AsmParser::ParseOperand(OperandVector &Operands) { getLexer().Lex(); // Eat '+' return false; } - Operands.push_back(MSP430Operand::CreateIndReg(RegNo, StartLoc, EndLoc)); + if (Operands.size() > 1) // Emulate @rd in destination position as 0(rd) + Operands.push_back(MSP430Operand::CreateMem(RegNo, + MCConstantExpr::create(0, getContext()), StartLoc, EndLoc)); + else + Operands.push_back(MSP430Operand::CreateIndReg(RegNo, StartLoc, EndLoc)); return false; } case AsmToken::Hash: diff --git a/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp b/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp index 2a66b4ed7f2..e5da130f9bb 100644 --- a/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp +++ b/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp @@ -249,6 +249,10 @@ DecodeStatus MSP430Disassembler::getInstructionI(MCInst &MI, uint64_t &Size, case amSymbolic: case amImmediate: case amAbsolute: + if (Bytes.size() < (Words + 1) * 2) { + Size = 2; + return DecodeStatus::Fail; + } Insn |= (uint64_t)support::endian::read16le(Bytes.data() + 2) << 16; ++Words; break; @@ -259,6 +263,10 @@ DecodeStatus MSP430Disassembler::getInstructionI(MCInst &MI, uint64_t &Size, case amIndexed: case amSymbolic: case amAbsolute: + if (Bytes.size() < (Words + 1) * 2) { + Size = 2; + return DecodeStatus::Fail; + } Insn |= (uint64_t)support::endian::read16le(Bytes.data() + Words * 2) << (Words * 16); ++Words; @@ -296,6 +304,10 @@ DecodeStatus MSP430Disassembler::getInstructionII(MCInst &MI, uint64_t &Size, case amSymbolic: case amImmediate: case amAbsolute: + if (Bytes.size() < (Words + 1) * 2) { + Size = 2; + return DecodeStatus::Fail; + } Insn |= (uint64_t)support::endian::read16le(Bytes.data() + 2) << 16; ++Words; break; diff --git a/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp b/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp index adf2384f6e9..06f9f307cb1 100644 --- a/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp +++ b/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp @@ -128,7 +128,7 @@ unsigned MSP430MCCodeEmitter::getMemOpValue(const MCInst &MI, unsigned Op, const MCOperand &MO2 = MI.getOperand(Op + 1); if (MO2.isImm()) { Offset += 2; - return (MO2.getImm() << 4) | Reg; + return ((unsigned)MO2.getImm() << 4) | Reg; } assert(MO2.isExpr() && "Expr operand expected"); diff --git a/test/MC/Disassembler/MSP430/unknown.txt b/test/MC/Disassembler/MSP430/unknown.txt new file mode 100644 index 00000000000..d7e680b98ae --- /dev/null +++ b/test/MC/Disassembler/MSP430/unknown.txt @@ -0,0 +1,13 @@ +# RUN: not llvm-mc -disassemble -triple=msp430 %s 2>&1 | FileCheck %s + +# This should not decode as 'and.b @r15+, (0)r1' [0xf1,0xff,0x00,0x00] +[0xf1 0xff] +# CHECK: warning: invalid instruction encoding + +# This should not decode as 'add 6(r7), 6(r5)' [0x95 0x57 0x06 0x00 0x06 0x00] +[0x95 0x57 0x06 0x00] +# CHECK: warning: invalid instruction encoding + +# This should not decode as 'call 6(r7)' [0x97 0x12 0x06 0x00] +[0x97 0x12] +# CHECK: warning: invalid instruction encoding diff --git a/test/MC/MSP430/addrmode.s b/test/MC/MSP430/addrmode.s index 7e389b6a50f..c787e683aea 100644 --- a/test/MC/MSP430/addrmode.s +++ b/test/MC/MSP430/addrmode.s @@ -21,11 +21,13 @@ foo: mov #42, 12(r15) mov #42, &disp mov disp, disp+2 + mov r7, @r15 ; CHECK: mov #42, r15 ; encoding: [0x3f,0x40,0x2a,0x00] ; CHECK: mov #42, 12(r15) ; encoding: [0xbf,0x40,0x2a,0x00,0x0c,0x00] ; CHECK: mov #42, &disp ; encoding: [0xb2,0x40,0x2a,0x00,A,A] ; CHECK: mov disp, disp+2 ; encoding: [0x90,0x40,A,A,B,B] +; CHECK: mov r7, 0(r15) ; encoding: [0x8f,0x47,0x00,0x00] add r7, r8 add 6(r7), r8 diff --git a/test/MC/MSP430/invalid.s b/test/MC/MSP430/invalid.s index 2815b520dd5..ce686bd83f1 100644 --- a/test/MC/MSP430/invalid.s +++ b/test/MC/MSP430/invalid.s @@ -4,7 +4,6 @@ foo: mov r7 ; CHECK: :[[@LINE]]:3: error: too few operands for instruction ;; invalid destination addressing modes - mov r7, @r15 ; CHECK: :[[@LINE]]:14: error: invalid operand for instruction mov r7, @r15+ ; CHECK: :[[@LINE]]:14: error: invalid operand for instruction mov r7, #0 ; CHECK: :[[@LINE]]:14: error: invalid operand for instruction mov r7, #123 ; CHECK: :[[@LINE]]:14: error: invalid operand for instruction -- 2.50.1