[llvm] ddff979 - [BPF] Prevent disassembly segfault for NOP insn

Yonghong Song via llvm-commits llvm-commits at lists.llvm.org
Mon May 18 17:40:56 PDT 2020


Author: Yonghong Song
Date: 2020-05-18T17:40:18-07:00
New Revision: ddff9799d2d0052653aa0385969b418a87bf5d7c

URL: https://github.com/llvm/llvm-project/commit/ddff9799d2d0052653aa0385969b418a87bf5d7c
DIFF: https://github.com/llvm/llvm-project/commit/ddff9799d2d0052653aa0385969b418a87bf5d7c.diff

LOG: [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

Added: 
    llvm/test/CodeGen/BPF/objdump_nop.ll

Modified: 
    llvm/lib/Target/BPF/BPFInstrInfo.td

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/BPF/BPFInstrInfo.td b/llvm/lib/Target/BPF/BPFInstrInfo.td
index 0f39294daa2b..6781d09b846e 100644
--- a/llvm/lib/Target/BPF/BPFInstrInfo.td
+++ b/llvm/lib/Target/BPF/BPFInstrInfo.td
@@ -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>

diff  --git a/llvm/test/CodeGen/BPF/objdump_nop.ll b/llvm/test/CodeGen/BPF/objdump_nop.ll
new file mode 100644
index 000000000000..6df2699f2e74
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/objdump_nop.ll
@@ -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


        


More information about the llvm-commits mailing list