llvm-project/llvm/test/CodeGen/BPF/BTF/global-var-sec.ll

70 lines
3.3 KiB
LLVM
Raw Normal View History

[BPF] Add BTF Var and DataSec Support Two new kinds, BTF_KIND_VAR and BTF_KIND_DATASEC, are added. BTF_KIND_VAR has the following specification: btf_type.name: var name btf_type.info: type kind btf_type.type: var type // btf_type is followed by one u32 u32: varinfo (currently, only 0 - static, 1 - global allocated in elf sections) Not all globals are supported in this patch. The following globals are supported: . static variables with or without section attributes . global variables with section attributes The inclusion of globals with section attributes is for future potential extraction of key/value type id's from map definition. BTF_KIND_DATASEC has the following specification: btf_type.name: section name associated with variable or one of .data/.bss/.readonly btf_type.info: type kind and vlen for # of variables btf_type.size: 0 #vlen number of the following: u32: id of corresponding BTF_KIND_VAR u32: in-session offset of the var u32: the size of memory var occupied At the time of debug info emission, the data section size is unknown, so the btf_type.size = 0 for BTF_KIND_DATASEC. The loader can patch it during loading time. The in-session offseet of the var is only available for static variables. For global variables, the loader neeeds to assign the global variable symbol value in symbol table to in-section offset. The size of memory is used to specify the amount of the memory a variable occupies. Typically, it equals to the type size, but for certain structures, e.g., struct tt { int a; int b; char c[]; }; static volatile struct tt s2 = {3, 4, "abcdefghi"}; The static variable s2 has size of 20. Note that for BTF_KIND_DATASEC name, the section name does not contain object name. The compiler does have input module name. For example, two cases below: . clang -target bpf -O2 -g -c test.c The compiler knows the input file (module) is test.c and can generate sec name like test.data/test.bss etc. . clang -target bpf -O2 -g -emit-llvm -c test.c -o - | llc -march=bpf -filetype=obj -o test.o The llc compiler has the input file as stdin, and would generate something like stdin.data/stdin.bss etc. which does not really make sense. For any user specificed section name, e.g., static volatile int a __attribute__((section("id1"))); static volatile const int b __attribute__((section("id2"))); The DataSec with name "id1" and "id2" does not contain information whether the section is readonly or not. The loader needs to check the corresponding elf section flags for such information. A simple example: -bash-4.4$ cat t.c int g1; int g2 = 3; const int g3 = 4; static volatile int s1; struct tt { int a; int b; char c[]; }; static volatile struct tt s2 = {3, 4, "abcdefghi"}; static volatile const int s3 = 4; int m __attribute__((section("maps"), used)) = 4; int test() { return g1 + g2 + g3 + s1 + s2.a + s3 + m; } -bash-4.4$ clang -target bpf -O2 -g -S t.c Checking t.s, 4 BTF_KIND_VAR's are generated (s1, s2, s3 and m). 4 BTF_KIND_DATASEC's are generated with names ".data", ".bss", ".rodata" and "maps". Signed-off-by: Yonghong Song <yhs@fb.com> Differential Revision: https://reviews.llvm.org/D59441 llvm-svn: 356326
2019-03-16 23:36:31 +08:00
; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s
; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s
; Source code:
; int gv1 __attribute__((section("maps")));
; int gv2 __attribute__((section("maps"))) = 5;
; Compilation flag:
; clang -target bpf -O2 -g -S -emit-llvm test.c
@gv2 = dso_local local_unnamed_addr global i32 5, section "maps", align 4, !dbg !0
@gv1 = dso_local local_unnamed_addr global i32 0, section "maps", align 4, !dbg !6
; CHECK: .section .BTF,"",@progbits
; CHECK-NEXT: .short 60319 # 0xeb9f
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .long 24
; CHECK-NEXT: .long 0
; CHECK-NEXT: .long 84
; CHECK-NEXT: .long 84
; CHECK-NEXT: .long 18
; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1)
; CHECK-NEXT: .long 16777216 # 0x1000000
; CHECK-NEXT: .long 4
; CHECK-NEXT: .long 16777248 # 0x1000020
; CHECK-NEXT: .long 5 # BTF_KIND_VAR(id = 2)
; CHECK-NEXT: .long 234881024 # 0xe000000
; CHECK-NEXT: .long 1
; CHECK-NEXT: .long 1
; CHECK-NEXT: .long 9 # BTF_KIND_VAR(id = 3)
; CHECK-NEXT: .long 234881024 # 0xe000000
; CHECK-NEXT: .long 1
; CHECK-NEXT: .long 1
; CHECK-NEXT: .long 13 # BTF_KIND_DATASEC(id = 4)
; CHECK-NEXT: .long 251658242 # 0xf000002
; CHECK-NEXT: .long 0
; CHECK-NEXT: .long 2
; CHECK-NEXT: .long gv2
; CHECK-NEXT: .long 4
; CHECK-NEXT: .long 3
; CHECK-NEXT: .long gv1
; CHECK-NEXT: .long 4
; CHECK-NEXT: .byte 0 # string offset=0
; CHECK-NEXT: .ascii "int" # string offset=1
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .ascii "gv2" # string offset=5
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .ascii "gv1" # string offset=9
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .ascii "maps" # string offset=13
; CHECK-NEXT: .byte 0
!llvm.dbg.cu = !{!2}
!llvm.module.flags = !{!9, !10, !11}
!llvm.ident = !{!12}
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "gv2", scope: !2, file: !3, line: 2, type: !8, isLocal: false, isDefinition: true)
!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.20181009 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None)
!3 = !DIFile(filename: "test.c", directory: "/home/yhs/work/tests/llvm/bug")
!4 = !{}
!5 = !{!0, !6}
!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression())
!7 = distinct !DIGlobalVariable(name: "gv1", scope: !2, file: !3, line: 1, type: !8, isLocal: false, isDefinition: true)
!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!9 = !{i32 2, !"Dwarf Version", i32 4}
!10 = !{i32 2, !"Debug Info Version", i32 3}
!11 = !{i32 1, !"wchar_size", i32 4}
!12 = !{!"clang version 8.0.20181009 "}