Skip to content

[BPF] llc with target BPF crashes when file not present in DISubprogram #165202

@varun-r-mallya

Description

@varun-r-mallya

Version

$ llc --version
LLVM (http://llvm.org/):
  LLVM version 22.0.0git
  DEBUG build with assertions.
  Default target: x86_64-unknown-linux-gnu
  Host CPU: alderlake

  Registered Targets:
    aarch64     - AArch64 (little endian)
    aarch64_32  - AArch64 (little endian ILP32)
    aarch64_be  - AArch64 (big endian)
    amdgcn      - AMD GCN GPUs
    arm         - ARM
    arm64       - ARM64 (little endian)
    arm64_32    - ARM64 (little endian ILP32)
    armeb       - ARM (big endian)
    avr         - Atmel AVR Microcontroller
    bpf         - BPF (host endian)
    bpfeb       - BPF (big endian)
    bpfel       - BPF (little endian)
    hexagon     - Hexagon
    lanai       - Lanai
    loongarch32 - 32-bit LoongArch
    loongarch64 - 64-bit LoongArch
    mips        - MIPS (32-bit big endian)
    mips64      - MIPS (64-bit big endian)
    mips64el    - MIPS (64-bit little endian)
    mipsel      - MIPS (32-bit little endian)
    msp430      - MSP430 [experimental]
    nvptx       - NVIDIA PTX 32-bit
    nvptx64     - NVIDIA PTX 64-bit
    ppc32       - PowerPC 32
    ppc32le     - PowerPC 32 LE
    ppc64       - PowerPC 64
    ppc64le     - PowerPC 64 LE
    r600        - AMD GPUs HD2XXX-HD6XXX
    riscv32     - 32-bit RISC-V
    riscv32be   - 32-bit big endian RISC-V
    riscv64     - 64-bit RISC-V
    riscv64be   - 64-bit big endian RISC-V
    sparc       - Sparc
    sparcel     - Sparc LE
    sparcv9     - Sparc V9
    spirv       - SPIR-V Logical
    spirv32     - SPIR-V 32-bit
    spirv64     - SPIR-V 64-bit
    systemz     - SystemZ
    thumb       - Thumb
    thumbeb     - Thumb (big endian)
    ve          - VE
    wasm32      - WebAssembly 32-bit
    wasm64      - WebAssembly 64-bit
    x86         - 32-bit X86: Pentium-Pro and above
    x86-64      - 64-bit X86: EM64T and AMD64
    xcore       - XCore

Command to Crash

$ llc crashesLLVM.ll -O2 -march=bpf -filetype=obj -o test.o

Payload for crashing

; ModuleID = 'struct_field_tests.bpf.c'
source_filename = "struct_field_tests.bpf.c"
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "bpf"

@handle_setuid_entry.____fmt = internal constant [25 x i8] c"This is context field %d\00", align 1, !dbg !0
@LICENSE = dso_local global [4 x i8] c"GPL\00", section "license", align 1, !dbg !34
@"llvm.trace_event_raw_sys_enter:0:8$0:1" = external global i64, !llvm.preserve.access.index !8 "btf_ama"
@llvm.compiler.used = appending global [2 x ptr] [ptr @LICENSE, ptr @handle_setuid_entry], section "llvm.metadata"

; Function Attrs: nounwind
define dso_local noundef i32 @handle_setuid_entry(ptr noundef readonly %0) #1 section "tracepoint/syscalls/sys_enter_execve" !dbg !2 {
  %2 = load i64, ptr @"llvm.trace_event_raw_sys_enter:0:8$0:1", align 8
  %3 = getelementptr i8, ptr %0, i64 %2
  %4 = tail call ptr @llvm.bpf.passthrough.p0.p0(i32 0, ptr %3)
  %5 = load i64, ptr %4, align 8
  %6 = tail call i64 (ptr, i32, ...) inttoptr (i64 6 to ptr)(ptr noundef nonnull @handle_setuid_entry.____fmt, i32 noundef 25, i64 noundef %5) #4
  ret i32 0
}

; Function Attrs: nofree nosync nounwind memory(none)
declare ptr @llvm.bpf.passthrough.p0.p0(i32, ptr) #2


attributes #1 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
attributes #2 = { nofree nosync nounwind memory(none) }
attributes #3 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
attributes #4 = { nounwind }

!llvm.dbg.cu = !{!32}
!llvm.module.flags = !{!55, !56, !57, !58, !59}
!llvm.ident = !{!60}

!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "____fmt", scope: !2, file: !3, line: 23, type: !52, isLocal: true, isDefinition: true)
!2 = distinct !DISubprogram(name: "handle_setuid_entry", scope: !3, type: !4, scopeLine: 20, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !32)
!3 = !DIFile(filename: "struct_field_tests.bpf.c", directory: "/home/xeon/Desktop/pybpf-dev/IR-generation-experiment", checksumkind: CSK_MD5, checksum: "1a0c4cfd384da167fc3ab18902c9bea6")
!4 = !DISubroutineType(types: !5)
!5 = !{!6, !7}
!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64)
!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "trace_event_raw_sys_enter", line: 92600, size: 512, elements: !10)
!10 = !{!11, !20, !22, !27}
!11 = !DIDerivedType(tag: DW_TAG_member, name: "ent", line: 92601, baseType: !12, size: 64)
!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "trace_entry", line: 5925, size: 64, elements: !13)
!13 = !{!14, !16, !18, !19}
!14 = !DIDerivedType(tag: DW_TAG_member, name: "type", scope: !12, line: 5926, baseType: !15, size: 16)
!15 = !DIBasicType(name: "unsigned short", size: 16, encoding: DW_ATE_unsigned)
!16 = !DIDerivedType(tag: DW_TAG_member, name: "flags", scope: !12, line: 5927, baseType: !17, size: 8, offset: 16)
!17 = !DIBasicType(name: "unsigned char", size: 8, encoding: DW_ATE_unsigned_char)
!18 = !DIDerivedType(tag: DW_TAG_member, name: "preempt_count", scope: !12, line: 5928, baseType: !17, size: 8, offset: 24)
!19 = !DIDerivedType(tag: DW_TAG_member, name: "pid", scope: !12, line: 5929, baseType: !6, size: 32, offset: 32)
!20 = !DIDerivedType(tag: DW_TAG_member, name: "id", line: 92602, baseType: !21, size: 64, offset: 64)
!21 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed)
!22 = !DIDerivedType(tag: DW_TAG_member, name: "args", line: 92603, baseType: !23, size: 384, offset: 128)
!23 = !DICompositeType(tag: DW_TAG_array_type, baseType: !24, size: 384, elements: !25)
!24 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned)
!25 = !{!26}
!26 = !DISubrange(count: 6)
!27 = !DIDerivedType(tag: DW_TAG_member, name: "__data", line: 92604, baseType: !28, offset: 512)
!28 = !DICompositeType(tag: DW_TAG_array_type, baseType: !29, elements: !30)
!29 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
!30 = !{!31}
!31 = !DISubrange(count: 0)
!32 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, producer: "Ubuntu clang version 18.1.3 (1ubuntu1)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !33, splitDebugInlining: false, nameTableKind: None)
!33 = !{!0, !34, !39}
!34 = !DIGlobalVariableExpression(var: !35, expr: !DIExpression())
!35 = distinct !DIGlobalVariable(name: "LICENSE", scope: !32, file: !3, line: 42, type: !36, isLocal: false, isDefinition: true)
!36 = !DICompositeType(tag: DW_TAG_array_type, baseType: !29, size: 32, elements: !37)
!37 = !{!38}
!38 = !DISubrange(count: 4)
!39 = !DIGlobalVariableExpression(var: !40, expr: !DIExpression(DW_OP_constu, 6, DW_OP_stack_value))
!40 = distinct !DIGlobalVariable(name: "bpf_trace_printk", scope: !32, file: !41, line: 177, type: !42, isLocal: true, isDefinition: true)
!41 = !DIFile(filename: "/usr/include/bpf/bpf_helper_defs.h", directory: "", checksumkind: CSK_MD5, checksum: "09cfcd7169c24bec448f30582e8c6db9")
!42 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !43, size: 64)
!43 = !DISubroutineType(types: !44)
!44 = !{!21, !45, !47, null}
!45 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !46, size: 64)
!46 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !29)
!47 = !DIDerivedType(tag: DW_TAG_typedef, name: "__u32", line: 12, baseType: !48)
!48 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned)
!50 = !DILocalVariable(name: "ctx", arg: 1, scope: !2, file: !3, line: 20, type: !7)
!51 = !DILocalVariable(name: "id", scope: !2, file: !3, line: 22, type: !21)
!52 = !DICompositeType(tag: DW_TAG_array_type, baseType: !46, size: 200, elements: !53)
!53 = !{!54}
!54 = !DISubrange(count: 25)
!55 = !{i32 7, !"Dwarf Version", i32 5}
!56 = !{i32 2, !"Debug Info Version", i32 3}
!57 = !{i32 1, !"wchar_size", i32 4}
!58 = !{i32 7, !"frame-pointer", i32 2}
!59 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
!60 = !{!"Ubuntu clang version 18.1.3 (1ubuntu1)"}
!61 = !DILocation(line: 0, scope: !2)
!62 = !DILocation(line: 22, column: 22, scope: !2)
!71 = !DILocation(line: 23, column: 3, scope: !72)
!72 = distinct !DILexicalBlock(scope: !2, file: !3, line: 23, column: 3)
!73 = !DILocation(line: 39, column: 3, scope: !2)

Crash message and Stack Dump

$ llc crashesLLVM.ll -O2 -march=bpf -filetype=obj -o test.o
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace and instructions to reproduce the bug.
Stack dump:
0.	Program arguments: /home/xeon/Desktop/llvm-project/build/bin/llc crashesLLVM.ll -O2 -march=bpf -filetype=obj -o test.o
1.	Running pass 'Function Pass Manager' on module 'crashesLLVM.ll'.
2.	Running pass 'BPF Assembly Printer' on function '@handle_setuid_entry'
 #0 0x00005f43ef38d7c2 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/xeon/Desktop/llvm-project/llvm/lib/Support/Unix/Signals.inc:834:22
 #1 0x00005f43ef38dc35 PrintStackTraceSignalHandler(void*) /home/xeon/Desktop/llvm-project/llvm/lib/Support/Unix/Signals.inc:916:1
 #2 0x00005f43ef38adad llvm::sys::RunSignalHandlers() /home/xeon/Desktop/llvm-project/llvm/lib/Support/Signals.cpp:104:20
 #3 0x00005f43ef38cfff SignalHandler(int, siginfo_t*, void*) /home/xeon/Desktop/llvm-project/llvm/lib/Support/Unix/Signals.inc:426:14
 #4 0x000073adf5e45330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
 #5 0x00005f43ea661a0e llvm::MDNode::Header::getNumOperands() const /home/xeon/Desktop/llvm-project/llvm/include/llvm/IR/Metadata.h:1177:11
 #6 0x00005f43ea661bc4 llvm::MDNode::getNumOperands() const /home/xeon/Desktop/llvm-project/llvm/include/llvm/IR/Metadata.h:1448:74
 #7 0x00005f43ea661b2e llvm::MDNode::getOperand(unsigned int) const /home/xeon/Desktop/llvm-project/llvm/include/llvm/IR/Metadata.h:1443:5
 #8 0x00005f43ea66572a llvm::MDString* llvm::DINode::getOperandAs<llvm::MDString>(unsigned int) const /home/xeon/Desktop/llvm-project/llvm/include/llvm/IR/DebugInfoMetadata.h:198:0
 #9 0x00005f43ea66409f llvm::DINode::getStringOperand(unsigned int) const /home/xeon/Desktop/llvm-project/llvm/include/llvm/IR/DebugInfoMetadata.h:202:0
#10 0x00005f43eb7869cb llvm::DIFile::getFilename() const /home/xeon/Desktop/llvm-project/llvm/include/llvm/IR/DebugInfoMetadata.h:711:63
#11 0x00005f43eb781890 llvm::BTFDebug::populateFileContent[abi:cxx11](llvm::DIFile const*) /home/xeon/Desktop/llvm-project/llvm/lib/Target/BPF/BTFDebug.cpp:1098:25
#12 0x00005f43eb781e7e llvm::BTFDebug::constructLineInfo(llvm::MCSymbol*, llvm::DIFile const*, unsigned int, unsigned int) /home/xeon/Desktop/llvm-project/llvm/lib/Target/BPF/BTFDebug.cpp:1131:18
#13 0x00005f43eb784372 llvm::BTFDebug::beginInstruction(llvm::MachineInstr const*) /home/xeon/Desktop/llvm-project/llvm/lib/Target/BPF/BTFDebug.cpp:1498:25
#14 0x00005f43ed50561a llvm::AsmPrinter::emitFunctionBody() /home/xeon/Desktop/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:2003:7
#15 0x00005f43eb6b6b3a llvm::AsmPrinter::runOnMachineFunction(llvm::MachineFunction&) /home/xeon/Desktop/llvm-project/llvm/include/llvm/CodeGen/AsmPrinter.h:452:12
#16 0x00005f43eda500ef llvm::MachineFunctionPass::runOnFunction(llvm::Function&) /home/xeon/Desktop/llvm-project/llvm/lib/CodeGen/MachineFunctionPass.cpp:108:30
#17 0x00005f43ee340682 llvm::FPPassManager::runOnFunction(llvm::Function&) /home/xeon/Desktop/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1398:20
#18 0x00005f43ee340958 llvm::FPPassManager::runOnModule(llvm::Module&) /home/xeon/Desktop/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1444:13
#19 0x00005f43ee340db7 (anonymous namespace)::MPPassManager::runOnModule(llvm::Module&) /home/xeon/Desktop/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1513:20
#20 0x00005f43ee33bd7e llvm::legacy::PassManagerImpl::run(llvm::Module&) /home/xeon/Desktop/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:531:13
#21 0x00005f43ee3416ad llvm::legacy::PassManager::run(llvm::Module&) /home/xeon/Desktop/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1641:1
#22 0x00005f43ea2f860d compileModule(char**, llvm::LLVMContext&) /home/xeon/Desktop/llvm-project/llvm/tools/llc/llc.cpp:833:34
#23 0x00005f43ea2f5add main /home/xeon/Desktop/llvm-project/llvm/tools/llc/llc.cpp:446:35
#24 0x000073adf5e2a1ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#25 0x000073adf5e2a28b call_init ./csu/../csu/libc-start.c:128:20
#26 0x000073adf5e2a28b __libc_start_main ./csu/../csu/libc-start.c:347:5
#27 0x00005f43ea2f4325 _start (/home/xeon/Desktop/llvm-project/build/bin/llc+0x878f325)
[1]    190643 segmentation fault (core dumped)  /home/xeon/Desktop/llvm-project/build/bin/llc crashesLLVM.ll -O2 -march=bpf

Offending Line

!2 = distinct !DISubprogram(name: "handle_setuid_entry", scope: !3, type: !4, scopeLine: 20, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !32)

Working version,

!2 = distinct !DISubprogram(name: "handle_setuid_entry", scope: !3, file: !3, type: !4, scopeLine: 20, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !32)

When file is removed, we see that llc crashes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    backend:BPFcrashPrefer [crash-on-valid] or [crash-on-invalid]

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions