llvm.org GIT mirror llvm / 9ed561f
Debug info: Support DWARF4 bitfields via DW_AT_data_bit_offset. The DWARF2 specification of DW_AT_bit_offset was written from the perspective of a big-endian machine with unclear semantics for other systems. DWARF4 deprecated DW_AT_bit_offset and introduced a new attribute DW_AT_data_bit_offset that simply counts the number of bits from the beginning of the containing entity regardless of endianness. After this patch LLVM emits DW_AT_bit_offset for DWARF 2 or 3 and DW_AT_data_bit_offset when DWARF 4 or later is requested. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@267895 91177308-0d34-0410-b5e6-96231b3b80d8 Adrian Prantl 4 years ago
3 changed file(s) with 154 addition(s) and 28 deletion(s). Raw diff Collapse all Expand all
13941394 // Handle bitfield, assume bytes are 8 bits.
13951395 addUInt(MemberDie, dwarf::DW_AT_byte_size, None, FieldSize/8);
13961396 addUInt(MemberDie, dwarf::DW_AT_bit_size, None, Size);
1397 //
1398 // The DWARF 2 DW_AT_bit_offset is counting the bits between the most
1399 // significant bit of the aligned storage unit containing the bit field to
1400 // the most significan bit of the bit field.
1401 //
1402 // FIXME: DWARF 4 states that DW_AT_data_bit_offset (which
1403 // counts from the beginning, regardless of endianness) should
1404 // be used instead.
1405 //
1406 //
1407 // Struct Align Align Align
1408 // v v v v
1409 // +-----------+-----*-----+-----*-----+--
1410 // | ... |b1|b2|b3|b4|
1411 // +-----------+-----*-----+-----*-----+--
1412 // | | |<-- Size ->| |
1413 // |<---- Offset --->| |<--->|
1414 // | | | \_ DW_AT_bit_offset (little endian)
1415 // | |<--->|
1416 // |<--------->| \_ StartBitOffset = DW_AT_bit_offset (big endian)
1417 // \ = DW_AT_data_bit_offset (biendian)
1418 // \_ OffsetInBytes
1397
14191398 uint64_t Offset = DT->getOffsetInBits();
14201399 uint64_t Align = DT->getAlignInBits() ? DT->getAlignInBits() : FieldSize;
14211400 uint64_t AlignMask = ~(Align - 1);
14221401 // The bits from the start of the storage unit to the start of the field.
14231402 uint64_t StartBitOffset = Offset - (Offset & AlignMask);
1424 // The endian-dependent DWARF 2 offset.
1425 uint64_t DwarfBitOffset = Asm->getDataLayout().isLittleEndian()
1426 ? OffsetToAlignment(Offset + Size, Align)
1427 : StartBitOffset;
1428
14291403 // The byte offset of the field's aligned storage unit inside the struct.
14301404 OffsetInBytes = (Offset - StartBitOffset) / 8;
1431 addUInt(MemberDie, dwarf::DW_AT_bit_offset, None, DwarfBitOffset);
1405
1406 if (DD->getDwarfVersion() >= 4)
1407 addUInt(MemberDie, dwarf::DW_AT_data_bit_offset, None, Offset);
1408 else {
1409 //
1410 // The DWARF 2 DW_AT_bit_offset is counting the bits between the most
1411 // significant bit of the aligned storage unit containing the bit field
1412 // to
1413 // the most significan bit of the bit field.
1414 //
1415 // Struct Align Align Align
1416 // v v v v
1417 // +-----------+-----*-----+-----*-----+--
1418 // | ... |b1|b2|b3|b4|
1419 // +-----------+-----*-----+-----*-----+--
1420 // | | |<-- Size ->| |
1421 // |<---- Offset --->| |<--->|
1422 // | | | \_ DW_AT_bit_offset (little endian)
1423 // | |<--->|
1424 // |<--------->| \_ StartBitOffset = DW_AT_bit_offset (big endian)
1425 // \ = DW_AT_data_bit_offset (biendian)
1426 // \_ OffsetInBytes
1427 // The endian-dependent DWARF 2 offset.
1428 uint64_t DwarfBitOffset = Asm->getDataLayout().isLittleEndian()
1429 ? OffsetToAlignment(Offset + Size, Align)
1430 : StartBitOffset;
1431
1432 addUInt(MemberDie, dwarf::DW_AT_bit_offset, None, DwarfBitOffset);
1433 }
14321434 } else
14331435 // This is not a bitfield.
14341436 OffsetInBytes = DT->getOffsetInBits() / 8;
0 ; RUN: llc -O0 -filetype=obj -mtriple=armeb-none-linux %s -o - \
1 ; RUN: | llvm-dwarfdump --debug-dump=info - | FileCheck %s
2 ; Generated from:
3 ; struct S {
4 ; int j:5;
5 ; int k:6;
6 ; int m:5;
7 ; int n:8;
8 ; } s;
9
10 target datalayout = "E-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
11
12 %struct.S = type { i24 }
13
14 @s = common global %struct.S zeroinitializer, align 4
15
16 !llvm.dbg.cu = !{!0}
17 !llvm.module.flags = !{!12, !13, !14}
18 !llvm.ident = !{!15}
19
20 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0 (trunk 267633)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3)
21 !1 = !DIFile(filename: "bitfield.c", directory: "/Volumes/Data/llvm")
22 !2 = !{}
23 !3 = !{!4}
24 !4 = distinct !DIGlobalVariable(name: "s", scope: !0, file: !1, line: 6, type: !5, isLocal: false, isDefinition: true, variable: %struct.S* @s)
25 !5 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !1, line: 1, size: 32, align: 32, elements: !6)
26 !6 = !{!7, !9, !10, !11}
27 ; CHECK: DW_TAG_member
28 ; CHECK-NEXT: DW_AT_name{{.*}}"j"
29 ; CHECK-NOT: DW_TAG
30 ; CHECK: DW_AT_data_bit_offset [DW_FORM_data1] (0x00)
31 ; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
32 !7 = !DIDerivedType(tag: DW_TAG_member, name: "j", scope: !5, file: !1, line: 2, baseType: !8, size: 5, align: 32)
33 !8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
34 ; CHECK: DW_TAG_member
35 ; CHECK-NEXT: DW_AT_name{{.*}}"k"
36 ; CHECK-NOT: DW_TAG
37 ; CHECK: DW_AT_data_bit_offset [DW_FORM_data1] (0x05)
38 ; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
39 !9 = !DIDerivedType(tag: DW_TAG_member, name: "k", scope: !5, file: !1, line: 3, baseType: !8, size: 6, align: 32, offset: 5)
40 ; CHECK: DW_TAG_member
41 ; CHECK-NEXT: DW_AT_name{{.*}}"m"
42 ; CHECK-NOT: DW_TAG
43 ; CHECK: DW_AT_data_bit_offset [DW_FORM_data1] (0x0b)
44 ; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
45 !10 = !DIDerivedType(tag: DW_TAG_member, name: "m", scope: !5, file: !1, line: 4, baseType: !8, size: 5, align: 32, offset: 11)
46 ; CHECK: DW_TAG_member
47 ; CHECK-NEXT: DW_AT_name{{.*}}"n"
48 ; CHECK-NOT: DW_TAG
49 ; CHECK: DW_AT_data_bit_offset [DW_FORM_data1] (0x10)
50 ; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
51 !11 = !DIDerivedType(tag: DW_TAG_member, name: "n", scope: !5, file: !1, line: 5, baseType: !8, size: 8, align: 32, offset: 16)
52 !12 = !{i32 2, !"Dwarf Version", i32 4}
53 !13 = !{i32 2, !"Debug Info Version", i32 3}
54 !14 = !{i32 1, !"PIC Level", i32 2}
55 !15 = !{!"clang version 3.9.0 (trunk 267633)"}
0 ; RUN: llc -mtriple x86_64-apple-macosx -O0 -filetype=obj -o - %s \
1 ; RUN: | llvm-dwarfdump -debug-dump=info - | FileCheck %s
2 ;
3 ; Generated from:
4 ; #include
5 ; #pragma pack(1)
6 ; struct PackedBits
7 ; {
8 ; char a;
9 ; uint32_t b : 5,
10 ; c : 27
11 ; } s;
12 ; #pragma pack()
13
14 source_filename = "bitfield.c"
15 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
16 target triple = "x86_64-apple-macosx"
17
18 %struct.PackedBits = type <{ i8, i32 }>
19
20 @s = common global %struct.PackedBits zeroinitializer, align 1
21
22 !llvm.dbg.cu = !{!0}
23 !llvm.module.flags = !{!14, !15, !16}
24 !llvm.ident = !{!17}
25
26 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0 (trunk 267633)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3)
27 !1 = !DIFile(filename: "bitfield.c", directory: "/Volumes/Data/llvm")
28 !2 = !{}
29 !3 = !{!4}
30 !4 = distinct !DIGlobalVariable(name: "s", scope: !0, file: !1, line: 8, type: !5, isLocal: false, isDefinition: true, variable: %struct.PackedBits* @s)
31 !5 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "PackedBits", file: !1, line: 3, size: 40, align: 8, elements: !6)
32 !6 = !{!7, !9, !13}
33
34 ; CHECK: DW_TAG_member
35 ; CHECK-NEXT: DW_AT_name{{.*}}"a"
36 ; CHECK-NOT: DW_TAG
37 ; CHECK-NOT: DW_AT_bit_offset
38 ; CHECK-NOT: DW_AT_data_bit_offset
39 ; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
40 !7 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !5, file: !1, line: 5, baseType: !8, size: 8, align: 8)
41
42 !8 = !DIBasicType(name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char)
43
44 ; CHECK: DW_TAG_member
45 ; CHECK-NEXT: DW_AT_name{{.*}}"b"
46 ; CHECK-NOT: DW_TAG
47 ; CHECK-NOT: DW_AT_bit_offset
48 ; CHECK: DW_AT_data_bit_offset [DW_FORM_data1] (0x08)
49 ; CHECK-NEXT: DW_AT_data_member_location [DW_FORM_data1] (0x00)
50 !9 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !5, file: !1, line: 6, baseType: !10, size: 5, align: 32, offset: 8)
51
52 !10 = !DIDerivedType(tag: DW_TAG_typedef, name: "uint32_t", file: !11, line: 183, baseType: !12)
53 !11 = !DIFile(filename: "/Volumes/Data/llvm/_build.ninja.release/bin/../lib/clang/3.9.0/include/stdint.h", directory: "/Volumes/Data/llvm")
54 !12 = !DIBasicType(name: "unsigned int", size: 32, align: 32, encoding: DW_ATE_unsigned)
55
56 ; CHECK: DW_TAG_member
57 ; CHECK-NEXT: DW_AT_name{{.*}}"c"
58 ; CHECK-NOT: DW_TAG
59 ; CHECK-NOT: DW_AT_bit_offset
60 ; CHECK: DW_AT_data_bit_offset [DW_FORM_data1] (0x0d)
61 ; CHECK-NEXT: DW_AT_data_member_location [DW_FORM_data1] (0x00)
62 !13 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !5, file: !1, line: 7, baseType: !10, size: 27, align: 32, offset: 13)
63
64 !14 = !{i32 2, !"Dwarf Version", i32 4}
65 !15 = !{i32 2, !"Debug Info Version", i32 3}
66 !16 = !{i32 1, !"PIC Level", i32 2}
67 !17 = !{!"clang version 3.9.0 (trunk 267633)"}