[PATCH] D125185: [BPF] Mark FI_ri as isPseudo to avoid assertion during disassembly

Eduard Zingerman via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun May 8 11:23:35 PDT 2022


eddyz87 created this revision.
Herald added a subscriber: hiraditya.
Herald added a project: All.
eddyz87 updated this revision to Diff 427932.
eddyz87 edited the summary of this revision.
eddyz87 added a comment.
eddyz87 added a reviewer: ast.
eddyz87 updated this revision to Diff 427936.
eddyz87 added a comment.
eddyz87 published this revision for review.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Commit message fixes for better formatting


When a specific sequence of bytes is present in the file during
disassembly the disassembler fails with the following assertion:

  ...
       0:	18 20 00 00 00 00 00 00	lea
  ... Assertion `idx < size()' failed.
  ...
  llvm::SmallVectorTemplateCommon<...>::operator[](...) ...
  llvm::MCInst::getOperand(unsigned int) ...
  llvm::BPFInstPrinter::printOperand(...) ...
  llvm::BPFInstPrinter::printInstruction() ...
  llvm::BPFInstPrinter::printInst(...) ...
  ...

The byte sequence causing the error is (little endian):

18 20 00 00  00 00 00 00  00 00 00 00  00 00 00 00

The issue could be reproduced using the program bellow:

  test.ir:
  
  @G = constant
         [16 x i8]
         [i8 u0x18, i8 u0x20, i8 u0x00, i8 u0x00, i8 u0x00, i8 u0x00, i8 u0x00, i8 u0x00,
          i8 u0x00, i8 u0x00, i8 u0x00, i8 u0x00, i8 u0x00, i8 u0x00, i8 u0x00, i8 u0x00],
         section "foo", align 8

Compiled and disassembled as follows:

  cat test.ir | llc -march=bpfel -filetype=obj -o - \
              | llvm-objdump --arch=bpfel --section=foo -d -

This byte sequence corresponds to FI_ri instruction declared in the
BPFInstrInfo.td as follows:

  def FI_ri
      : TYPE_LD_ST<BPF_IMM.Value, BPF_DW.Value,
                   (outs GPR:$dst),
                   (ins MEMri:$addr),
                   "lea\t$dst, $addr",
                   [(set i64:$dst, FIri:$addr)]> {
    // This is a tentative instruction, and will be replaced
    // with MOV_rr and ADD_ri in PEI phase
    let Inst{51-48} = 0;
    let Inst{55-52} = 2;
    let Inst{47-32} = 0;
    let Inst{31-0} = 0;
    let BPFClass = BPF_LD;
  }

Notes:

- First byte (opcode) is formed as follows:
  - BPF_IMM.Value is 0x00
  - BPF_DW.Value  is 0x18
  - BPF_LD        is 0x00
- Second byte (registers) is formed as follows:
  - let Inst{55-52} = 2;
  - let Inst{51-48} = 0;

The FI_ri instruction is always replaced by MOV_rr ADD_ri instructions
pair in the BPFRegisterInfo::eliminateFrameIndex method. Thus, this
instruction should be invisible to disassembler. This patch achieves
this by adding "isPseudo" flag for this instruction.

The bug was found by decompiling of one of the BPF tests from Linux
kernel (llvm-objdump -D tools/testing/selftests/bpf/bpf_iter_sockmap.o)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D125185

Files:
  llvm/lib/Target/BPF/BPFInstrInfo.td
  llvm/test/CodeGen/BPF/objdump_fi_ri.ll


Index: llvm/test/CodeGen/BPF/objdump_fi_ri.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/BPF/objdump_fi_ri.ll
@@ -0,0 +1,28 @@
+; RUN: llc -march=bpfel -filetype=obj -o - %s \
+; RUN:     | llvm-objdump --arch=bpfel --section=foo -d - \
+; RUN:     | FileCheck %s
+
+; This test was added because "isPseudo" flag was missing in FI_ri
+; instruction definition and certain byte sequence caused an assertion
+; in llvm-objdump tool.
+
+; The value "G" is byte by byte little endian representation of the FI_ri instruction,
+; as declared in the BPFInstrInfo.td.
+; The first byte encodes an opcode: BPF_IMM(0x00) | BPF_DW(0x18) | BPF_LD(0x00)
+; The second byte encodes source and destination registers: 2 and 0 respectively.
+; The rest of the bytes are zeroes to comply with the specification.
+; An additional 8 bytes follow the instruction as an immediate 64 bit argument,
+; (because of the BPF_IMM flag).
+
+; This is a pseudo instruction, meaning that it's not possible to
+; write it in assembly directly. Thus it is coded as a byte array.
+
+; Note the "bpfel" flags in the RUN command.
+
+ at G = constant [16 x i8]
+              [i8 u0x18, i8 u0x20, i8 u0x00, i8 u0x00, i8 u0x00, i8 u0x00, i8 u0x00, i8 u0x00,
+               i8 u0x00, i8 u0x00, i8 u0x00, i8 u0x00, i8 u0x00, i8 u0x00, i8 u0x00, i8 u0x00],
+              section "foo", align 8
+
+; CHECK-LABEL: G
+; CHECK:       0: 18 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ld_pseudo r0, 2, 0
Index: llvm/lib/Target/BPF/BPFInstrInfo.td
===================================================================
--- llvm/lib/Target/BPF/BPFInstrInfo.td
+++ llvm/lib/Target/BPF/BPFInstrInfo.td
@@ -372,6 +372,7 @@
   let Inst{47-32} = 0;
   let Inst{31-0} = 0;
   let BPFClass = BPF_LD;
+  bit isPseudo = true;
 }
 
 def LD_pseudo


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D125185.427936.patch
Type: text/x-patch
Size: 1847 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220508/c7d392a4/attachment.bin>


More information about the llvm-commits mailing list