[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
This commit is contained in:
Yonghong Song 2020-05-18 11:56:29 -07:00
parent 47cc6db928
commit ddff9799d2
2 changed files with 20 additions and 1 deletions

View File

@ -526,7 +526,7 @@ class NOP_I<string OpcodeStr>
let BPFClass = BPF_ALU64;
}
let hasSideEffects = 0 in
let hasSideEffects = 0, isCodeGenOnly = 1 in
def NOP : NOP_I<"nop">;
class RET<string OpcodeStr>

View File

@ -0,0 +1,19 @@
; RUN: llc -march=bpfel -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
;
; Source:
; int test() {
; asm volatile("r0 = r0" ::);
; return 0;
; }
; Compilation flag:
; clang -target bpf -O2 -S -emit-llvm t.c
; Function Attrs: nounwind
define dso_local i32 @test() local_unnamed_addr {
entry:
tail call void asm sideeffect "r0 = r0", ""()
ret i32 0
}
; CHECK-LABEL: test
; CHECK: r0 = r0
; CHECK: r0 = 0