diff --git a/llvm/lib/Target/BPF/BTF.h b/llvm/lib/Target/BPF/BTF.h --- a/llvm/lib/Target/BPF/BTF.h +++ b/llvm/lib/Target/BPF/BTF.h @@ -180,8 +180,7 @@ enum : uint8_t { VAR_STATIC = 0, ///< Linkage: InternalLinkage VAR_GLOBAL_ALLOCATED = 1, ///< Linkage: ExternalLinkage - VAR_GLOBAL_TENTATIVE = 2, ///< Linkage: CommonLinkage - VAR_GLOBAL_EXTERNAL = 3, ///< Linkage: ExternalLinkage + VAR_GLOBAL_EXTERNAL = 2, ///< Linkage: ExternalLinkage }; /// BTF_KIND_DATASEC are followed by multiple "struct BTFDataSecVar". diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp --- a/llvm/lib/Target/BPF/BTFDebug.cpp +++ b/llvm/lib/Target/BPF/BTFDebug.cpp @@ -1055,20 +1055,40 @@ // Collect all types referenced by globals. const Module *M = MMI->getModule(); for (const GlobalVariable &Global : M->globals()) { - // Ignore external globals for now. - if (!Global.hasInitializer() && Global.hasExternalLinkage()) + // Ignore BPF internally created globals. + if (Global.hasAttribute(BPFCoreSharedInfo::AmaAttr)) continue; + // Support globals: + // . static: VAR_STATIC, in DataSec. + // . initialized global (0 or non-0): VAR_GLOBAL_ALLOCATED, in DataSec. + // . external global: VAR_GLOBAL_EXTERNAL, in DataSec if w/ section name. + // Whether DataSec is readonly or not can be found from the + // corresponding ELF section flags. + // Decide the section name. StringRef SecName; - if (Global.hasSection()) { - SecName = Global.getSection(); - } else { - // data, bss, or readonly sections - if (Global.isConstant()) - SecName = ".rodata"; + uint32_t GVarInfo = 0; + auto Linkage = Global.getLinkage(); + if (Global.hasInitializer()) { + if (Global.hasSection()) { + SecName = Global.getSection(); + } else { + // data, bss, or readonly sections + if (Global.isConstant()) + SecName = ".rodata"; + else + SecName = Global.getInitializer()->isZeroValue() ? ".bss" : ".data"; + } + if (Linkage == GlobalValue::InternalLinkage) + GVarInfo = BTF::VAR_STATIC; else - SecName = Global.getInitializer()->isZeroValue() ? ".bss" : ".data"; + GVarInfo = BTF::VAR_GLOBAL_ALLOCATED; + } else if (Linkage == GlobalValue::ExternalLinkage) { + GVarInfo = BTF::VAR_GLOBAL_EXTERNAL; + SecName = Global.getSection(); + } else if (Linkage != GlobalValue::CommonLinkage) { + continue; } if (ProcessingMapDef != SecName.startswith(".maps")) @@ -1085,27 +1105,18 @@ break; } - // Only support the following globals: - // . static variables - // . non-static global variables with section attributes - // Essentially means: - // . .bcc/.data/.rodata DataSec entities only contain static data - // . Other DataSec entities contain static or initialized global data. - // Initialized global data are mostly used for finding map key/value type - // id's. Whether DataSec is readonly or not can be found from - // corresponding ELF section flags. - auto Linkage = Global.getLinkage(); - if (Linkage != GlobalValue::InternalLinkage && - (Linkage != GlobalValue::ExternalLinkage || !Global.hasSection())) + // Do not generate variables for Common Linkage yet until we + // know how to use them. + if (Linkage == GlobalValue::CommonLinkage) continue; - uint32_t GVarInfo = Linkage == GlobalValue::ExternalLinkage - ? BTF::VAR_GLOBAL_ALLOCATED - : BTF::VAR_STATIC; auto VarEntry = std::make_unique(Global.getName(), GVTypeId, GVarInfo); uint32_t VarId = addType(std::move(VarEntry)); + if (SecName.empty()) + continue; + // Find or create a DataSec if (DataSecEntries.find(SecName) == DataSecEntries.end()) { DataSecEntries[SecName] = std::make_unique(Asm, SecName); diff --git a/llvm/test/CodeGen/BPF/BTF/extern-global-var-sec.ll b/llvm/test/CodeGen/BPF/BTF/extern-global-var-sec.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/BTF/extern-global-var-sec.ll @@ -0,0 +1,100 @@ +; 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: +; extern char a1 __attribute__((section("abc"))); +; extern char a2 __attribute__((section("abc"))); +; int foo() { return a1 + a2; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm test.c + +@a1 = external dso_local local_unnamed_addr global i8, section "abc", align 1 +@a2 = external dso_local local_unnamed_addr global i8, section "abc", align 1 + +; Function Attrs: norecurse nounwind readonly +define dso_local i32 @foo() local_unnamed_addr #0 !dbg !7 { +entry: + %0 = load i8, i8* @a1, align 1, !dbg !11, !tbaa !12 + %conv = sext i8 %0 to i32, !dbg !11 + %1 = load i8, i8* @a2, align 1, !dbg !15, !tbaa !12 + %conv1 = sext i8 %1 to i32, !dbg !15 + %add = add nsw i32 %conv1, %conv, !dbg !16 + ret i32 %add, !dbg !17 +} + +; 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 108 +; CHECK-NEXT: .long 108 +; CHECK-NEXT: .long 62 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326592 # 0xc000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 52 # BTF_KIND_VAR(id = 4) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 55 # BTF_KIND_VAR(id = 5) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 58 # BTF_KIND_DATASEC(id = 6) +; CHECK-NEXT: .long 251658242 # 0xf000002 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long a1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long a2 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "foo" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".text" # string offset=9 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/home/yhs/work/tests/core/test.c" # string offset=15 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "a1" # string offset=52 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "a2" # string offset=55 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "abc" # string offset=58 +; CHECK-NEXT: .byte 0 + +attributes #0 = { norecurse nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git aad6a5e3062a2bc7feaf733ba3140a47333f0fc4)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/core") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git aad6a5e3062a2bc7feaf733ba3140a47333f0fc4)"} +!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !2) +!8 = !DISubroutineType(types: !9) +!9 = !{!10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DILocation(line: 3, column: 20, scope: !7) +!12 = !{!13, !13, i64 0} +!13 = !{!"omnipotent char", !14, i64 0} +!14 = !{!"Simple C/C++ TBAA"} +!15 = !DILocation(line: 3, column: 25, scope: !7) +!16 = !DILocation(line: 3, column: 23, scope: !7) +!17 = !DILocation(line: 3, column: 13, scope: !7) diff --git a/llvm/test/CodeGen/BPF/BTF/extern-global-var.ll b/llvm/test/CodeGen/BPF/BTF/extern-global-var.ll --- a/llvm/test/CodeGen/BPF/BTF/extern-global-var.ll +++ b/llvm/test/CodeGen/BPF/BTF/extern-global-var.ll @@ -22,9 +22,9 @@ ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .long 24 ; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long 40 -; CHECK-NEXT: .long 40 -; CHECK-NEXT: .long 52 +; CHECK-NEXT: .long 56 +; CHECK-NEXT: .long 56 +; CHECK-NEXT: .long 54 ; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) ; CHECK-NEXT: .long 218103808 # 0xd000000 ; CHECK-NEXT: .long 2 @@ -35,6 +35,10 @@ ; CHECK-NEXT: .long 5 # BTF_KIND_FUNC(id = 3) ; CHECK-NEXT: .long 201326592 # 0xc000000 ; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 52 # BTF_KIND_VAR(id = 4) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 ; CHECK-NEXT: .byte 0 # string offset=0 ; CHECK-NEXT: .ascii "int" # string offset=1 ; CHECK-NEXT: .byte 0 @@ -44,6 +48,8 @@ ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .ascii "/home/yhs/work/tests/llvm/bug/test.c" # string offset=15 ; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 97 # string offset=52 +; CHECK-NEXT: .byte 0 attributes #0 = { norecurse nounwind readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/llvm/test/CodeGen/BPF/BTF/global-var-inited.ll b/llvm/test/CodeGen/BPF/BTF/global-var-inited.ll --- a/llvm/test/CodeGen/BPF/BTF/global-var-inited.ll +++ b/llvm/test/CodeGen/BPF/BTF/global-var-inited.ll @@ -14,16 +14,30 @@ ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .long 24 ; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long 16 -; CHECK-NEXT: .long 16 -; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 56 +; CHECK-NEXT: .long 56 +; CHECK-NEXT: .long 13 ; 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 7 # BTF_KIND_DATASEC(id = 3) +; CHECK-NEXT: .long 251658241 # 0xf000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long a +; CHECK-NEXT: .long 4 ; CHECK-NEXT: .byte 0 # string offset=0 ; CHECK-NEXT: .ascii "int" # string offset=1 ; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 97 # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii ".data" # string offset=7 +; CHECK-NEXT: .byte 0 !llvm.dbg.cu = !{!2} !llvm.module.flags = !{!7, !8, !9}