[llvm] r267895 - Debug info: Support DWARF4 bitfields via DW_AT_data_bit_offset.
Adrian Prantl via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 28 08:37:49 PDT 2016
Author: adrian
Date: Thu Apr 28 10:37:48 2016
New Revision: 267895
URL: http://llvm.org/viewvc/llvm-project?rev=267895&view=rev
Log:
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.
Added:
llvm/trunk/test/DebugInfo/ARM/big-endian-bitfield.ll
llvm/trunk/test/DebugInfo/X86/bitfields-dwarf4.ll
Modified:
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp?rev=267895&r1=267894&r2=267895&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp Thu Apr 28 10:37:48 2016
@@ -1395,41 +1395,43 @@ void DwarfUnit::constructMemberDIE(DIE &
// Handle bitfield, assume bytes are 8 bits.
addUInt(MemberDie, dwarf::DW_AT_byte_size, None, FieldSize/8);
addUInt(MemberDie, dwarf::DW_AT_bit_size, None, Size);
- //
- // The DWARF 2 DW_AT_bit_offset is counting the bits between the most
- // significant bit of the aligned storage unit containing the bit field to
- // the most significan bit of the bit field.
- //
- // FIXME: DWARF 4 states that DW_AT_data_bit_offset (which
- // counts from the beginning, regardless of endianness) should
- // be used instead.
- //
- //
- // Struct Align Align Align
- // v v v v
- // +-----------+-----*-----+-----*-----+--
- // | ... |b1|b2|b3|b4|
- // +-----------+-----*-----+-----*-----+--
- // | | |<-- Size ->| |
- // |<---- Offset --->| |<--->|
- // | | | \_ DW_AT_bit_offset (little endian)
- // | |<--->|
- // |<--------->| \_ StartBitOffset = DW_AT_bit_offset (big endian)
- // \ = DW_AT_data_bit_offset (biendian)
- // \_ OffsetInBytes
+
uint64_t Offset = DT->getOffsetInBits();
uint64_t Align = DT->getAlignInBits() ? DT->getAlignInBits() : FieldSize;
uint64_t AlignMask = ~(Align - 1);
// The bits from the start of the storage unit to the start of the field.
uint64_t StartBitOffset = Offset - (Offset & AlignMask);
- // The endian-dependent DWARF 2 offset.
- uint64_t DwarfBitOffset = Asm->getDataLayout().isLittleEndian()
- ? OffsetToAlignment(Offset + Size, Align)
- : StartBitOffset;
-
// The byte offset of the field's aligned storage unit inside the struct.
OffsetInBytes = (Offset - StartBitOffset) / 8;
- addUInt(MemberDie, dwarf::DW_AT_bit_offset, None, DwarfBitOffset);
+
+ if (DD->getDwarfVersion() >= 4)
+ addUInt(MemberDie, dwarf::DW_AT_data_bit_offset, None, Offset);
+ else {
+ //
+ // The DWARF 2 DW_AT_bit_offset is counting the bits between the most
+ // significant bit of the aligned storage unit containing the bit field
+ // to
+ // the most significan bit of the bit field.
+ //
+ // Struct Align Align Align
+ // v v v v
+ // +-----------+-----*-----+-----*-----+--
+ // | ... |b1|b2|b3|b4|
+ // +-----------+-----*-----+-----*-----+--
+ // | | |<-- Size ->| |
+ // |<---- Offset --->| |<--->|
+ // | | | \_ DW_AT_bit_offset (little endian)
+ // | |<--->|
+ // |<--------->| \_ StartBitOffset = DW_AT_bit_offset (big endian)
+ // \ = DW_AT_data_bit_offset (biendian)
+ // \_ OffsetInBytes
+ // The endian-dependent DWARF 2 offset.
+ uint64_t DwarfBitOffset = Asm->getDataLayout().isLittleEndian()
+ ? OffsetToAlignment(Offset + Size, Align)
+ : StartBitOffset;
+
+ addUInt(MemberDie, dwarf::DW_AT_bit_offset, None, DwarfBitOffset);
+ }
} else
// This is not a bitfield.
OffsetInBytes = DT->getOffsetInBits() / 8;
Added: llvm/trunk/test/DebugInfo/ARM/big-endian-bitfield.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/ARM/big-endian-bitfield.ll?rev=267895&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/ARM/big-endian-bitfield.ll (added)
+++ llvm/trunk/test/DebugInfo/ARM/big-endian-bitfield.ll Thu Apr 28 10:37:48 2016
@@ -0,0 +1,56 @@
+; RUN: llc -O0 -filetype=obj -mtriple=armeb-none-linux %s -o - \
+; RUN: | llvm-dwarfdump --debug-dump=info - | FileCheck %s
+; Generated from:
+; struct S {
+; int j:5;
+; int k:6;
+; int m:5;
+; int n:8;
+; } s;
+
+target datalayout = "E-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+%struct.S = type { i24 }
+
+ at s = common global %struct.S zeroinitializer, align 4
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!12, !13, !14}
+!llvm.ident = !{!15}
+
+!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)
+!1 = !DIFile(filename: "bitfield.c", directory: "/Volumes/Data/llvm")
+!2 = !{}
+!3 = !{!4}
+!4 = distinct !DIGlobalVariable(name: "s", scope: !0, file: !1, line: 6, type: !5, isLocal: false, isDefinition: true, variable: %struct.S* @s)
+!5 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !1, line: 1, size: 32, align: 32, elements: !6)
+!6 = !{!7, !9, !10, !11}
+; CHECK: DW_TAG_member
+; CHECK-NEXT: DW_AT_name{{.*}}"j"
+; CHECK-NOT: DW_TAG
+; CHECK: DW_AT_data_bit_offset [DW_FORM_data1] (0x00)
+; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
+!7 = !DIDerivedType(tag: DW_TAG_member, name: "j", scope: !5, file: !1, line: 2, baseType: !8, size: 5, align: 32)
+!8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
+; CHECK: DW_TAG_member
+; CHECK-NEXT: DW_AT_name{{.*}}"k"
+; CHECK-NOT: DW_TAG
+; CHECK: DW_AT_data_bit_offset [DW_FORM_data1] (0x05)
+; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
+!9 = !DIDerivedType(tag: DW_TAG_member, name: "k", scope: !5, file: !1, line: 3, baseType: !8, size: 6, align: 32, offset: 5)
+; CHECK: DW_TAG_member
+; CHECK-NEXT: DW_AT_name{{.*}}"m"
+; CHECK-NOT: DW_TAG
+; CHECK: DW_AT_data_bit_offset [DW_FORM_data1] (0x0b)
+; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
+!10 = !DIDerivedType(tag: DW_TAG_member, name: "m", scope: !5, file: !1, line: 4, baseType: !8, size: 5, align: 32, offset: 11)
+; CHECK: DW_TAG_member
+; CHECK-NEXT: DW_AT_name{{.*}}"n"
+; CHECK-NOT: DW_TAG
+; CHECK: DW_AT_data_bit_offset [DW_FORM_data1] (0x10)
+; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
+!11 = !DIDerivedType(tag: DW_TAG_member, name: "n", scope: !5, file: !1, line: 5, baseType: !8, size: 8, align: 32, offset: 16)
+!12 = !{i32 2, !"Dwarf Version", i32 4}
+!13 = !{i32 2, !"Debug Info Version", i32 3}
+!14 = !{i32 1, !"PIC Level", i32 2}
+!15 = !{!"clang version 3.9.0 (trunk 267633)"}
Added: llvm/trunk/test/DebugInfo/X86/bitfields-dwarf4.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/bitfields-dwarf4.ll?rev=267895&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/bitfields-dwarf4.ll (added)
+++ llvm/trunk/test/DebugInfo/X86/bitfields-dwarf4.ll Thu Apr 28 10:37:48 2016
@@ -0,0 +1,68 @@
+; RUN: llc -mtriple x86_64-apple-macosx -O0 -filetype=obj -o - %s \
+; RUN: | llvm-dwarfdump -debug-dump=info - | FileCheck %s
+;
+; Generated from:
+; #include <stdint.h>
+; #pragma pack(1)
+; struct PackedBits
+; {
+; char a;
+; uint32_t b : 5,
+; c : 27
+; } s;
+; #pragma pack()
+
+source_filename = "bitfield.c"
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx"
+
+%struct.PackedBits = type <{ i8, i32 }>
+
+ at s = common global %struct.PackedBits zeroinitializer, align 1
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!14, !15, !16}
+!llvm.ident = !{!17}
+
+!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)
+!1 = !DIFile(filename: "bitfield.c", directory: "/Volumes/Data/llvm")
+!2 = !{}
+!3 = !{!4}
+!4 = distinct !DIGlobalVariable(name: "s", scope: !0, file: !1, line: 8, type: !5, isLocal: false, isDefinition: true, variable: %struct.PackedBits* @s)
+!5 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "PackedBits", file: !1, line: 3, size: 40, align: 8, elements: !6)
+!6 = !{!7, !9, !13}
+
+; CHECK: DW_TAG_member
+; CHECK-NEXT: DW_AT_name{{.*}}"a"
+; CHECK-NOT: DW_TAG
+; CHECK-NOT: DW_AT_bit_offset
+; CHECK-NOT: DW_AT_data_bit_offset
+; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
+!7 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !5, file: !1, line: 5, baseType: !8, size: 8, align: 8)
+
+!8 = !DIBasicType(name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char)
+
+; CHECK: DW_TAG_member
+; CHECK-NEXT: DW_AT_name{{.*}}"b"
+; CHECK-NOT: DW_TAG
+; CHECK-NOT: DW_AT_bit_offset
+; CHECK: DW_AT_data_bit_offset [DW_FORM_data1] (0x08)
+; CHECK-NEXT: DW_AT_data_member_location [DW_FORM_data1] (0x00)
+!9 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !5, file: !1, line: 6, baseType: !10, size: 5, align: 32, offset: 8)
+
+!10 = !DIDerivedType(tag: DW_TAG_typedef, name: "uint32_t", file: !11, line: 183, baseType: !12)
+!11 = !DIFile(filename: "/Volumes/Data/llvm/_build.ninja.release/bin/../lib/clang/3.9.0/include/stdint.h", directory: "/Volumes/Data/llvm")
+!12 = !DIBasicType(name: "unsigned int", size: 32, align: 32, encoding: DW_ATE_unsigned)
+
+; CHECK: DW_TAG_member
+; CHECK-NEXT: DW_AT_name{{.*}}"c"
+; CHECK-NOT: DW_TAG
+; CHECK-NOT: DW_AT_bit_offset
+; CHECK: DW_AT_data_bit_offset [DW_FORM_data1] (0x0d)
+; CHECK-NEXT: DW_AT_data_member_location [DW_FORM_data1] (0x00)
+!13 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !5, file: !1, line: 7, baseType: !10, size: 27, align: 32, offset: 13)
+
+!14 = !{i32 2, !"Dwarf Version", i32 4}
+!15 = !{i32 2, !"Debug Info Version", i32 3}
+!16 = !{i32 1, !"PIC Level", i32 2}
+!17 = !{!"clang version 3.9.0 (trunk 267633)"}
More information about the llvm-commits
mailing list