[llvm] 152a9fe - BPF: permit .maps section variables with typedef type

Yonghong Song via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 12 09:46:58 PDT 2020


Author: Yonghong Song
Date: 2020-07-12T09:42:25-07:00
New Revision: 152a9fef1b3b44f2c224cb8096b3d649279f2578

URL: https://github.com/llvm/llvm-project/commit/152a9fef1b3b44f2c224cb8096b3d649279f2578
DIFF: https://github.com/llvm/llvm-project/commit/152a9fef1b3b44f2c224cb8096b3d649279f2578.diff

LOG: BPF: permit .maps section variables with typedef type

Currently, llvm when see a global variable in .maps section,
it ensures its type must be a struct type. Then pointee
will be further evaluated for the structure members.
In normal cases, the pointee type will be skipped.

Although this is what current all bpf programs are doing,
but it is a little bit restrictive. For example, it is legitimate
for users to have:
typedef struct { int key_size; int value_size; } __map_t;
__map_t map __attribute__((section(".maps")));

This patch lifts this restriction and typedef of
a struct type is also allowed for .maps section variables.
To avoid create unnecessary fixup entries when traversal
started with typedef/struct type, the new implementation
first traverse all map struct members and then traverse
the typedef/struct type. This way, in internal BTFDebug
implementation, no fixup entries are generated.

Two new unit tests are added for typedef and const
struct in .maps section. Also tested with kernel bpf selftests.

Differential Revision: https://reviews.llvm.org/D83638

Added: 
    llvm/test/CodeGen/BPF/BTF/map-def-2.ll
    llvm/test/CodeGen/BPF/BTF/map-def-3.ll

Modified: 
    llvm/lib/Target/BPF/BTFDebug.cpp
    llvm/test/CodeGen/BPF/BTF/map-def.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp
index 6ada75adba96..4510e9357489 100644
--- a/llvm/lib/Target/BPF/BTFDebug.cpp
+++ b/llvm/lib/Target/BPF/BTFDebug.cpp
@@ -664,7 +664,17 @@ void BTFDebug::visitMapDefType(const DIType *Ty, uint32_t &TypeId) {
     return;
   }
 
-  // MapDef type is a struct type
+  // MapDef type may be a struct type or a non-pointer derived type
+  const DIType *OrigTy = Ty;
+  while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
+    auto Tag = DTy->getTag();
+    if (Tag != dwarf::DW_TAG_typedef && Tag != dwarf::DW_TAG_const_type &&
+        Tag != dwarf::DW_TAG_volatile_type &&
+        Tag != dwarf::DW_TAG_restrict_type)
+      break;
+    Ty = DTy->getBaseType();
+  }
+
   const auto *CTy = dyn_cast<DICompositeType>(Ty);
   if (!CTy)
     return;
@@ -673,27 +683,15 @@ void BTFDebug::visitMapDefType(const DIType *Ty, uint32_t &TypeId) {
   if (Tag != dwarf::DW_TAG_structure_type || CTy->isForwardDecl())
     return;
 
-  // Record this type
+  // Visit all struct members to ensure pointee type is visited
   const DINodeArray Elements = CTy->getElements();
-  bool HasBitField = false;
-  for (const auto *Element : Elements) {
-    auto E = cast<DIDerivedType>(Element);
-    if (E->isBitField()) {
-      HasBitField = true;
-      break;
-    }
-  }
-
-  auto TypeEntry =
-      std::make_unique<BTFTypeStruct>(CTy, true, HasBitField, Elements.size());
-  StructTypes.push_back(TypeEntry.get());
-  TypeId = addType(std::move(TypeEntry), CTy);
-
-  // Visit all struct members
   for (const auto *Element : Elements) {
     const auto *MemberType = cast<DIDerivedType>(Element);
     visitTypeEntry(MemberType->getBaseType());
   }
+
+  // Visit this type, struct or a const/typedef/volatile/restrict type
+  visitTypeEntry(OrigTy, TypeId, false, false);
 }
 
 /// Read file contents from the actual file or from the source

diff  --git a/llvm/test/CodeGen/BPF/BTF/map-def-2.ll b/llvm/test/CodeGen/BPF/BTF/map-def-2.ll
new file mode 100644
index 000000000000..bf3c4a7961fb
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/BTF/map-def-2.ll
@@ -0,0 +1,90 @@
+; 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:
+;   struct key_type {
+;     int a1;
+;   };
+;   typedef struct map_type {
+;     struct key_type *key;
+;   } _map_type;
+;   typedef _map_type __map_type;
+;   __map_type __attribute__((section(".maps"))) hash_map;
+; Compilation flag:
+;   clang -target bpf -O2 -g -S -emit-llvm t2.c
+
+%struct.map_type = type { %struct.key_type* }
+%struct.key_type = type { i32 }
+
+ at hash_map = dso_local local_unnamed_addr global %struct.map_type zeroinitializer, section ".maps", align 8, !dbg !0
+
+; CHECK:             .long   0                               # BTF_KIND_PTR(id = 1)
+; CHECK-NEXT:        .long   33554432                        # 0x2000000
+; CHECK-NEXT:        .long   2
+; CHECK-NEXT:        .long   1                               # BTF_KIND_STRUCT(id = 2)
+; CHECK-NEXT:        .long   67108865                        # 0x4000001
+; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   10
+; CHECK-NEXT:        .long   3
+; CHECK-NEXT:        .long   0                               # 0x0
+; CHECK-NEXT:        .long   13                              # BTF_KIND_INT(id = 3)
+; CHECK-NEXT:        .long   16777216                        # 0x1000000
+; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   16777248                        # 0x1000020
+; CHECK-NEXT:        .long   17                              # BTF_KIND_TYPEDEF(id = 4)
+; CHECK-NEXT:        .long   134217728                       # 0x8000000
+; CHECK-NEXT:        .long   5
+; CHECK-NEXT:        .long   28                              # BTF_KIND_TYPEDEF(id = 5)
+; CHECK-NEXT:        .long   134217728                       # 0x8000000
+; CHECK-NEXT:        .long   6
+; CHECK-NEXT:        .long   38                              # BTF_KIND_STRUCT(id = 6)
+; CHECK-NEXT:        .long   67108865                        # 0x4000001
+; CHECK-NEXT:        .long   8
+; CHECK-NEXT:        .long   47
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   0                               # 0x0
+; CHECK-NEXT:        .long   51                              # BTF_KIND_VAR(id = 7)
+; CHECK-NEXT:        .long   234881024                       # 0xe000000
+; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   60                              # BTF_KIND_DATASEC(id = 8)
+; CHECK-NEXT:        .long   251658241                       # 0xf000001
+; CHECK-NEXT:        .long   0
+; CHECK-NEXT:        .long   7
+; CHECK-NEXT:        .long   hash_map
+; CHECK-NEXT:        .long   8
+
+; CHECK:             .ascii  "key_type"                      # string offset=1
+; CHECK:             .ascii  "a1"                            # string offset=10
+; CHECK:             .ascii  "int"                           # string offset=13
+; CHECK:             .ascii  "__map_type"                    # string offset=17
+; CHECK:             .ascii  "_map_type"                     # string offset=28
+; CHECK:             .ascii  "map_type"                      # string offset=38
+; CHECK:             .ascii  "key"                           # string offset=47
+; CHECK:             .ascii  "hash_map"                      # string offset=51
+; CHECK:             .ascii  ".maps"                         # string offset=60
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!16, !17, !18}
+!llvm.ident = !{!19}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "hash_map", scope: !2, file: !3, line: 8, type: !6, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 11.0.0 (https://github.com/llvm/llvm-project.git b8409c03ed90807f3d49c7d98dceea98cf461f7a)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, splitDebugInlining: false, nameTableKind: None)
+!3 = !DIFile(filename: "t2.c", directory: "/tmp/home/yhs/tmp1")
+!4 = !{}
+!5 = !{!0}
+!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "__map_type", file: !3, line: 7, baseType: !7)
+!7 = !DIDerivedType(tag: DW_TAG_typedef, name: "_map_type", file: !3, line: 6, baseType: !8)
+!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "map_type", file: !3, line: 4, size: 64, elements: !9)
+!9 = !{!10}
+!10 = !DIDerivedType(tag: DW_TAG_member, name: "key", scope: !8, file: !3, line: 5, baseType: !11, size: 64)
+!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64)
+!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "key_type", file: !3, line: 1, size: 32, elements: !13)
+!13 = !{!14}
+!14 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !12, file: !3, line: 2, baseType: !15, size: 32)
+!15 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!16 = !{i32 7, !"Dwarf Version", i32 4}
+!17 = !{i32 2, !"Debug Info Version", i32 3}
+!18 = !{i32 1, !"wchar_size", i32 4}
+!19 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git b8409c03ed90807f3d49c7d98dceea98cf461f7a)"}

diff  --git a/llvm/test/CodeGen/BPF/BTF/map-def-3.ll b/llvm/test/CodeGen/BPF/BTF/map-def-3.ll
new file mode 100644
index 000000000000..e05470782ec2
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/BTF/map-def-3.ll
@@ -0,0 +1,65 @@
+; 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:
+;   struct key_type {
+;     int a1;
+;   };
+;   const struct key_type __attribute__((section(".maps"))) hash_map;
+; Compilation flag:
+;   clang -target bpf -O2 -g -S -emit-llvm t3.c
+
+%struct.key_type = type { i32 }
+
+ at hash_map = dso_local local_unnamed_addr constant %struct.key_type zeroinitializer, section ".maps", align 4, !dbg !0
+
+; CHECK:             .long   1                               # BTF_KIND_INT(id = 1)
+; CHECK-NEXT:        .long   16777216                        # 0x1000000
+; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   16777248                        # 0x1000020
+; CHECK-NEXT:        .long   0                               # BTF_KIND_CONST(id = 2)
+; CHECK-NEXT:        .long   167772160                       # 0xa000000
+; CHECK-NEXT:        .long   3
+; CHECK-NEXT:        .long   5                               # BTF_KIND_STRUCT(id = 3)
+; CHECK-NEXT:        .long   67108865                        # 0x4000001
+; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   14
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   0                               # 0x0
+; CHECK-NEXT:        .long   17                              # BTF_KIND_VAR(id = 4)
+; CHECK-NEXT:        .long   234881024                       # 0xe000000
+; CHECK-NEXT:        .long   2
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   26                              # BTF_KIND_DATASEC(id = 5)
+; CHECK-NEXT:        .long   251658241                       # 0xf000001
+; CHECK-NEXT:        .long   0
+; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   hash_map
+; CHECK-NEXT:        .long   4
+
+; CHECK:             .ascii  "int"                           # string offset=1
+; CHECK:             .ascii  "key_type"                      # string offset=5
+; CHECK:             .ascii  "a1"                            # string offset=14
+; CHECK:             .ascii  "hash_map"                      # string offset=17
+; CHECK:             .ascii  ".maps"                         # string offset=26
+
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!11, !12, !13}
+!llvm.ident = !{!14}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "hash_map", scope: !2, file: !3, line: 4, type: !6, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 11.0.0 (https://github.com/llvm/llvm-project.git 5bd074629f00d4798674b411cf00216f38016483)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, splitDebugInlining: false, nameTableKind: None)
+!3 = !DIFile(filename: "t3.c", directory: "/tmp/home/yhs/tmp1")
+!4 = !{}
+!5 = !{!0}
+!6 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !7)
+!7 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "key_type", file: !3, line: 1, size: 32, elements: !8)
+!8 = !{!9}
+!9 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !7, file: !3, line: 2, baseType: !10, size: 32)
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{i32 7, !"Dwarf Version", i32 4}
+!12 = !{i32 2, !"Debug Info Version", i32 3}
+!13 = !{i32 1, !"wchar_size", i32 4}
+!14 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git 5bd074629f00d4798674b411cf00216f38016483)"}

diff  --git a/llvm/test/CodeGen/BPF/BTF/map-def.ll b/llvm/test/CodeGen/BPF/BTF/map-def.ll
index cf777880efa1..e12cde3ef98a 100644
--- a/llvm/test/CodeGen/BPF/BTF/map-def.ll
+++ b/llvm/test/CodeGen/BPF/BTF/map-def.ll
@@ -28,41 +28,41 @@
 ; CHECK-NEXT:        .long   168
 ; CHECK-NEXT:        .long   168
 ; CHECK-NEXT:        .long   65
-; CHECK-NEXT:        .long   1                       # BTF_KIND_STRUCT(id = 1)
-; CHECK-NEXT:        .long   67108866                # 0x4000002
-; CHECK-NEXT:        .long   16
-; CHECK-NEXT:        .long   10
-; CHECK-NEXT:        .long   2
-; CHECK-NEXT:        .long   0                       # 0x0
-; CHECK-NEXT:        .long   14
-; CHECK-NEXT:        .long   5
-; CHECK-NEXT:        .long   64                      # 0x40
-; CHECK-NEXT:        .long   0                       # BTF_KIND_PTR(id = 2)
+; CHECK-NEXT:        .long   0                       # BTF_KIND_PTR(id = 1)
 ; CHECK-NEXT:        .long   33554432                # 0x2000000
-; CHECK-NEXT:        .long   3
-; CHECK-NEXT:        .long   20                      # BTF_KIND_STRUCT(id = 3)
+; CHECK-NEXT:        .long   2
+; CHECK-NEXT:        .long   1                       # BTF_KIND_STRUCT(id = 2)
 ; CHECK-NEXT:        .long   67108866                # 0x4000002
 ; CHECK-NEXT:        .long   8
-; CHECK-NEXT:        .long   29
-; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   10
+; CHECK-NEXT:        .long   3
 ; CHECK-NEXT:        .long   0                       # 0x0
-; CHECK-NEXT:        .long   31
-; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   12
+; CHECK-NEXT:        .long   3
 ; CHECK-NEXT:        .long   32                      # 0x20
-; CHECK-NEXT:        .long   33                      # BTF_KIND_INT(id = 4)
+; CHECK-NEXT:        .long   14                      # BTF_KIND_INT(id = 3)
 ; CHECK-NEXT:        .long   16777216                # 0x1000000
 ; CHECK-NEXT:        .long   4
 ; CHECK-NEXT:        .long   16777248                # 0x1000020
-; CHECK-NEXT:        .long   0                       # BTF_KIND_PTR(id = 5)
+; CHECK-NEXT:        .long   0                       # BTF_KIND_PTR(id = 4)
 ; CHECK-NEXT:        .long   33554432                # 0x2000000
-; CHECK-NEXT:        .long   6
-; CHECK-NEXT:        .long   37                      # BTF_KIND_INT(id = 6)
+; CHECK-NEXT:        .long   5
+; CHECK-NEXT:        .long   18                      # BTF_KIND_INT(id = 5)
 ; CHECK-NEXT:        .long   16777216                # 0x1000000
 ; CHECK-NEXT:        .long   4
 ; CHECK-NEXT:        .long   32                      # 0x20
+; CHECK-NEXT:        .long   31                      # BTF_KIND_STRUCT(id = 6)
+; CHECK-NEXT:        .long   67108866                # 0x4000002
+; CHECK-NEXT:        .long   16
+; CHECK-NEXT:        .long   40
+; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   0                       # 0x0
+; CHECK-NEXT:        .long   44
+; CHECK-NEXT:        .long   4
+; CHECK-NEXT:        .long   64                      # 0x40
 ; CHECK-NEXT:        .long   50                      # BTF_KIND_VAR(id = 7)
 ; CHECK-NEXT:        .long   234881024               # 0xe000000
-; CHECK-NEXT:        .long   1
+; CHECK-NEXT:        .long   6
 ; CHECK-NEXT:        .long   1
 ; CHECK-NEXT:        .long   59                      # BTF_KIND_DATASEC(id = 8)
 ; CHECK-NEXT:        .long   251658241               # 0xf000001
@@ -71,21 +71,21 @@
 ; CHECK-NEXT:        .long   hash_map
 ; CHECK-NEXT:        .long   16
 ; CHECK-NEXT:        .byte   0                       # string offset=0
-; CHECK-NEXT:        .ascii  "map_type"              # string offset=1
+; CHECK-NEXT:        .ascii  "key_type"              # string offset=1
 ; CHECK-NEXT:        .byte   0
-; CHECK-NEXT:        .ascii  "key"                   # string offset=10
+; CHECK-NEXT:        .byte   97                      # string offset=10
 ; CHECK-NEXT:        .byte   0
-; CHECK-NEXT:        .ascii  "value"                 # string offset=14
+; CHECK-NEXT:        .byte   98                      # string offset=12
 ; CHECK-NEXT:        .byte   0
-; CHECK-NEXT:        .ascii  "key_type"              # string offset=20
+; CHECK-NEXT:        .ascii  "int"                   # string offset=14
 ; CHECK-NEXT:        .byte   0
-; CHECK-NEXT:        .byte   97                      # string offset=29
+; CHECK-NEXT:        .ascii  "unsigned int"          # string offset=18
 ; CHECK-NEXT:        .byte   0
-; CHECK-NEXT:        .byte   98                      # string offset=31
+; CHECK-NEXT:        .ascii  "map_type"              # string offset=31
 ; CHECK-NEXT:        .byte   0
-; CHECK-NEXT:        .ascii  "int"                   # string offset=33
+; CHECK-NEXT:        .ascii  "key"                   # string offset=40
 ; CHECK-NEXT:        .byte   0
-; CHECK-NEXT:        .ascii  "unsigned int"          # string offset=37
+; CHECK-NEXT:        .ascii  "value"                 # string offset=44
 ; CHECK-NEXT:        .byte   0
 ; CHECK-NEXT:        .ascii  "hash_map"              # string offset=50
 ; CHECK-NEXT:        .byte   0


        


More information about the llvm-commits mailing list