From 8a63326150ee7e3e67e019ac8fe90fe420cd5162 Mon Sep 17 00:00:00 2001 From: Eduard Zingerman Date: Tue, 10 May 2022 17:04:58 -0700 Subject: [PATCH] [BPF] Mark FI_ri as isPseudo to avoid assertion during disassembly 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 { // 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) Differential Revision: https://reviews.llvm.org/D125185 --- llvm/lib/Target/BPF/BPFInstrInfo.td | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.td b/llvm/lib/Target/BPF/BPFInstrInfo.td index 082e1f4..ce5bb00 100644 --- a/llvm/lib/Target/BPF/BPFInstrInfo.td +++ b/llvm/lib/Target/BPF/BPFInstrInfo.td @@ -372,6 +372,7 @@ def FI_ri let Inst{47-32} = 0; let Inst{31-0} = 0; let BPFClass = BPF_LD; + bit isPseudo = true; } def LD_pseudo -- 2.7.4