From ddff9799d2d0052653aa0385969b418a87bf5d7c Mon Sep 17 00:00:00 2001 From: Yonghong Song Date: Mon, 18 May 2020 11:56:29 -0700 Subject: [PATCH] [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 | 2 +- llvm/test/CodeGen/BPF/objdump_nop.ll | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/BPF/objdump_nop.ll 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 let BPFClass = BPF_ALU64; } -let hasSideEffects = 0 in +let hasSideEffects = 0, isCodeGenOnly = 1 in def NOP : NOP_I<"nop">; class RET 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