[BPF] Prevent disassembly segfault for NOP insn
authorYonghong Song <yhs@fb.com>
Mon, 18 May 2020 18:56:29 +0000 (11:56 -0700)
committerYonghong Song <yhs@fb.com>
Tue, 19 May 2020 00:40:18 +0000 (17:40 -0700)
commitddff9799d2d0052653aa0385969b418a87bf5d7c
tree559f83ace37f7ffc594a3bcea5cf71d3df8f0e26
parent47cc6db928d063d96e11e70c196bd5601b2bdd06
[BPF] Prevent disassembly segfault for NOP insn

For a simple program like below:
  -bash-4.4$ cat t.c
  int test() {
    asm volatile("r0 = r0" ::);
    return 0;
  }
compiled with
  clang -target bpf -O2 -c t.c
the following llvm-objdump command will segfault.
  llvm-objdump -d t.o

  0:       bf 00 00 00 00 00 00 00 nop
  llvm-objdump: ../include/llvm/ADT/SmallVector.h:180
  ...
  Assertion `idx < size()' failed
  ...
  abort
  ...
  llvm::BPFInstPrinter::printOperand
  llvm::BPFInstPrinter::printInstruction
  ...

The reason is both NOP and MOV_rr (r0 = r0) having the same encoding.
The disassembly getInstruction() decodes to be a NOP instruciton but
during printInstruction() the same encoding is interpreted as
a MOV_rr instruction. Such a mismatcch caused the segfault.

The fix is to make NOP instruction as CodeGen only so disassembler
will skip NOP insn for disassembling.

Note that instruction "r0 = r0" should not appear in non inline
asm codes since BPF Machine Instruction Peephole optimization will
remove it.

Differential Revision: https://reviews.llvm.org/D80156
llvm/lib/Target/BPF/BPFInstrInfo.td
llvm/test/CodeGen/BPF/objdump_nop.ll [new file with mode: 0644]