Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 37 additions & 37 deletions llvm/lib/Target/BPF/BTFDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -957,47 +957,47 @@ void BTFDebug::visitMapDefType(const DIType *Ty, uint32_t &TypeId) {
return;
}

// 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;

auto Tag = CTy->getTag();
if (Tag != dwarf::DW_TAG_structure_type || CTy->isForwardDecl())
return;

// Visit all struct members to ensure their types are visited.
const DINodeArray Elements = CTy->getElements();
for (const auto *Element : Elements) {
const auto *MemberType = cast<DIDerivedType>(Element);
const DIType *MemberBaseType = MemberType->getBaseType();

// If the member is a composite type, that may indicate the currently
// visited composite type is a wrapper, and the member represents the
// actual map definition.
// In that case, visit the member with `visitMapDefType` instead of
// `visitTypeEntry`, treating it specifically as a map definition rather
// than as a regular composite type.
const auto *MemberCTy = dyn_cast<DICompositeType>(MemberBaseType);
if (MemberCTy) {
visitMapDefType(MemberBaseType, TypeId);
} else {
visitTypeEntry(MemberBaseType);
uint32_t TmpId;
switch (Ty->getTag()) {
case dwarf::DW_TAG_typedef:
case dwarf::DW_TAG_const_type:
case dwarf::DW_TAG_volatile_type:
case dwarf::DW_TAG_restrict_type:
case dwarf::DW_TAG_pointer_type:
visitMapDefType(dyn_cast<DIDerivedType>(Ty)->getBaseType(), TmpId);
break;
case dwarf::DW_TAG_array_type:
// Visit nested map array and jump to the element type
visitMapDefType(dyn_cast<DICompositeType>(Ty)->getBaseType(), TmpId);
break;
case dwarf::DW_TAG_structure_type: {
// Visit all struct members to ensure their types are visited.
const auto *CTy = cast<DICompositeType>(Ty);
const DINodeArray Elements = CTy->getElements();
for (const auto *Element : Elements) {
const auto *MemberType = cast<DIDerivedType>(Element);
const DIType *MemberBaseType = MemberType->getBaseType();
// If the member is a composite type, that may indicate the currently
// visited composite type is a wrapper, and the member represents the
// actual map definition.
// In that case, visit the member with `visitMapDefType` instead of
// `visitTypeEntry`, treating it specifically as a map definition rather
// than as a regular composite type.
const auto *MemberCTy = dyn_cast<DICompositeType>(MemberBaseType);
if (MemberCTy) {
visitMapDefType(MemberBaseType, TmpId);
} else {
visitTypeEntry(MemberBaseType);
}
}
break;
}
default:
break;
}

// Visit this type, struct or a const/typedef/volatile/restrict type
visitTypeEntry(OrigTy, TypeId, false, false);
visitTypeEntry(Ty, TypeId, false, false);
}

/// Read file contents from the actual file or from the source
Expand Down
61 changes: 14 additions & 47 deletions llvm/test/CodeGen/BPF/BTF/map-def-2.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
; RUN: llc -mtriple=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s
; RUN: llc -mtriple=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s
; RUN: llc -mtriple=bpfel -mcpu=v3 -filetype=obj -o %t1 %s
; RUN: llvm-objcopy --dump-section='.BTF'=%t2 %t1
; RUN: %python %p/print_btf.py %t2 | FileCheck -check-prefixes=CHECK-BTF %s
;
; Source code:
; struct key_type {
Expand All @@ -18,51 +19,17 @@

@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
; CHECK-BTF: [1] PTR '(anon)' type_id=2
; CHECK-BTF-NEXT: [2] STRUCT 'key_type' size=4 vlen=1
; CHECK-BTF-NEXT: 'a1' type_id=3 bits_offset=0
; CHECK-BTF-NEXT: [3] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
; CHECK-BTF-NEXT: [4] STRUCT 'map_type' size=8 vlen=1
; CHECK-BTF-NEXT: 'key' type_id=1 bits_offset=0
; CHECK-BTF-NEXT: [5] TYPEDEF '_map_type' type_id=4
; CHECK-BTF-NEXT: [6] TYPEDEF '__map_type' type_id=5
; CHECK-BTF-NEXT: [7] VAR 'hash_map' type_id=6, linkage=global
; CHECK-BTF-NEXT: [8] DATASEC '.maps' size=0 vlen=1
; CHECK-BTF-NEXT: type_id=7 offset=0 size=8

!llvm.dbg.cu = !{!2}
!llvm.module.flags = !{!16, !17, !18}
Expand Down
42 changes: 10 additions & 32 deletions llvm/test/CodeGen/BPF/BTF/map-def-3.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
; RUN: llc -mtriple=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s
; RUN: llc -mtriple=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s
; RUN: llc -mtriple=bpfel -mcpu=v3 -filetype=obj -o %t1 %s
; RUN: llvm-objcopy --dump-section='.BTF'=%t2 %t1
; RUN: %python %p/print_btf.py %t2 | FileCheck -check-prefixes=CHECK-BTF %s
;
; Source code:
; struct key_type {
Expand All @@ -13,36 +14,13 @@

@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

; CHECK-BTF: [1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
; CHECK-BTF-NEXT: [2] STRUCT 'key_type' size=4 vlen=1
; CHECK-BTF-NEXT: 'a1' type_id=1 bits_offset=0
; CHECK-BTF-NEXT: [3] CONST '(anon)' type_id=2
; CHECK-BTF-NEXT: [4] VAR 'hash_map' type_id=3, linkage=global
; CHECK-BTF-NEXT: [5] DATASEC '.maps' size=0 vlen=1
; CHECK-BTF-NEXT: type_id=4 offset=0 size=4

!llvm.dbg.cu = !{!2}
!llvm.module.flags = !{!11, !12, !13}
Expand Down
75 changes: 75 additions & 0 deletions llvm/test/CodeGen/BPF/BTF/map-def-nested-array.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
; RUN: llc -mtriple=bpfel -mcpu=v3 -filetype=obj -o %t1 %s
; RUN: llvm-objcopy --dump-section='.BTF'=%t2 %t1
; RUN: %python %p/print_btf.py %t2 | FileCheck -check-prefixes=CHECK-BTF-SHORT %s
; RUN: %python %p/print_btf.py %t2 | FileCheck -check-prefixes=CHECK-BTF %s
; Source:
; struct nested_value_type {
; int a1;
; };
; struct map_type {
; struct {
; struct nested_value_type *value;
; } *values[];
; };
; Compilation flags:
; clang -target bpf -g -O2 -S -emit-llvm prog.c

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

%struct.map_type = type { [0 x ptr] }

@array_of_maps = dso_local local_unnamed_addr global %struct.map_type zeroinitializer, section ".maps", align 8, !dbg !0

; We expect no forward declarations.
;
; CHECK-BTF-SHORT-NOT: FWD

; Assert the whole BTF.
;
; CHECK-BTF: [1] PTR '(anon)' type_id=2
; CHECK-BTF-NEXT: [2] STRUCT 'nested_value_type' size=4 vlen=1
; CHECK-BTF-NEXT: 'a1' type_id=3 bits_offset=0
; CHECK-BTF-NEXT: [3] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
; CHECK-BTF-NEXT: [4] STRUCT '(anon)' size=8 vlen=1
; CHECK-BTF-NEXT: 'value' type_id=1 bits_offset=0
; CHECK-BTF-NEXT: [5] PTR '(anon)' type_id=4
; CHECK-BTF-NEXT: [6] ARRAY '(anon)' type_id=5 index_type_id=7 nr_elems=0
; CHECK-BTF-NEXT: [7] INT '__ARRAY_SIZE_TYPE__' size=4 bits_offset=0 nr_bits=32 encoding=(none)
; CHECK-BTF-NEXT: [8] STRUCT 'map_type' size=0 vlen=1
; CHECK-BTF-NEXT: 'values' type_id=6 bits_offset=0
; CHECK-BTF-NEXT: [9] VAR 'array_of_maps' type_id=8, linkage=global
; CHECK-BTF-NEXT: [10] DATASEC '.maps' size=0 vlen=1
; CHECK-BTF-NEXT: type_id=9 offset=0 size=0

!llvm.dbg.cu = !{!2}
!llvm.module.flags = !{!20, !21, !22, !23}
!llvm.ident = !{!24}

!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "array_of_maps", scope: !2, file: !3, line: 9, type: !5, isLocal: false, isDefinition: true)
!2 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, producer: "clang version 22.0.0git ([email protected]:llvm/llvm-project.git ed93eaa421b714028b85cc887d80c45991d7207f)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None)
!3 = !DIFile(filename: "prog.c", directory: "/home/mtardy/llvm-bug-repro", checksumkind: CSK_MD5, checksum: "9381d9e83e9c0b235a14704224815e96")
!4 = !{!0}
!5 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "map_type", file: !3, line: 4, elements: !6)
!6 = !{!7}
!7 = !DIDerivedType(tag: DW_TAG_member, name: "values", scope: !5, file: !3, line: 7, baseType: !8)
!8 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, elements: !18)
!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64)
!10 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !5, file: !3, line: 5, size: 64, elements: !11)
!11 = !{!12}
!12 = !DIDerivedType(tag: DW_TAG_member, name: "value", scope: !10, file: !3, line: 6, baseType: !13, size: 64)
!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 64)
!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "nested_value_type", file: !3, line: 1, size: 32, elements: !15)
!15 = !{!16}
!16 = !DIDerivedType(tag: DW_TAG_member, name: "a1", scope: !14, file: !3, line: 2, baseType: !17, size: 32)
!17 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!18 = !{!19}
!19 = !DISubrange(count: -1)
!20 = !{i32 7, !"Dwarf Version", i32 5}
!21 = !{i32 2, !"Debug Info Version", i32 3}
!22 = !{i32 1, !"wchar_size", i32 4}
!23 = !{i32 7, !"frame-pointer", i32 2}
!24 = !{!"clang version 22.0.0git ([email protected]:llvm/llvm-project.git ed93eaa421b714028b85cc887d80c45991d7207f)"}