diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h | 4 | ||||
| -rw-r--r-- | llvm/include/llvm/Support/Dwarf.def | 19 | ||||
| -rw-r--r-- | llvm/include/llvm/Support/Dwarf.h | 13 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 25 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h | 9 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp | 6 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp | 6 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp | 11 | ||||
| -rw-r--r-- | llvm/lib/Support/Dwarf.cpp | 11 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/dwarf-headers.ll | 109 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/Inputs/dwarfdump-header.elf-x86-64 | bin | 0 -> 2376 bytes | |||
| -rw-r--r-- | llvm/test/DebugInfo/Inputs/dwarfdump-header.s | 149 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/dwarfdump-header.test | 29 | ||||
| -rw-r--r-- | llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp | 10 | 
15 files changed, 383 insertions, 23 deletions
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h index db7b59be90c..786eba306c2 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -124,6 +124,7 @@ class DWARFUnit {    uint32_t Length;    uint16_t Version;    const DWARFAbbreviationDeclarationSet *Abbrevs; +  uint8_t UnitType;    uint8_t AddrSize;    uint64_t BaseAddr;    // The compile unit debug information entry items. @@ -152,7 +153,7 @@ class DWARFUnit {  protected:    virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr);    /// Size in bytes of the unit header. -  virtual uint32_t getHeaderSize() const { return 11; } +  virtual uint32_t getHeaderSize() const { return Version <= 4 ? 11 : 12; }  public:    DWARFUnit(DWARFContext &Context, const DWARFSection &Section, @@ -208,6 +209,7 @@ public:    const DWARFAbbreviationDeclarationSet *getAbbreviations() const {      return Abbrevs;    } +  uint8_t getUnitType() const { return UnitType; }    uint8_t getAddressByteSize() const { return AddrSize; }    uint8_t getRefAddrByteSize() const {      if (Version == 2) diff --git a/llvm/include/llvm/Support/Dwarf.def b/llvm/include/llvm/Support/Dwarf.def index 841fc7d4ae2..4ef0176a491 100644 --- a/llvm/include/llvm/Support/Dwarf.def +++ b/llvm/include/llvm/Support/Dwarf.def @@ -19,7 +19,8 @@        defined HANDLE_DW_CC || defined HANDLE_DW_LNS ||                         \        defined HANDLE_DW_LNE || defined HANDLE_DW_LNCT ||                       \        defined HANDLE_DW_MACRO || defined HANDLE_DW_RLE ||                      \ -      defined HANDLE_DW_CFA || defined HANDLE_DW_APPLE_PROPERTY) +      defined HANDLE_DW_CFA || defined HANDLE_DW_APPLE_PROPERTY ||             \ +      defined HANDLE_DW_UT)  #error "Missing macro definition of HANDLE_DW*"  #endif @@ -87,6 +88,10 @@  #define HANDLE_DW_APPLE_PROPERTY(ID, NAME)  #endif +#ifndef HANDLE_DW_UT +#define HANDLE_DW_UT(ID, NAME) +#endif +  HANDLE_DW_TAG(0x0000, null)  HANDLE_DW_TAG(0x0001, array_type)  HANDLE_DW_TAG(0x0002, class_type) @@ -268,7 +273,7 @@ HANDLE_DW_AT(0x6c, const_expr)  HANDLE_DW_AT(0x6d, enum_class)  HANDLE_DW_AT(0x6e, linkage_name) -// New in DWARF 5: +// New in DWARF v5:  HANDLE_DW_AT(0x6f, string_length_bit_size)  HANDLE_DW_AT(0x70, string_length_byte_size)  HANDLE_DW_AT(0x71, rank) @@ -622,7 +627,7 @@ HANDLE_DW_LANG(0x0011, ObjC_plus_plus)  HANDLE_DW_LANG(0x0012, UPC)  HANDLE_DW_LANG(0x0013, D) -// New in DWARF 5: +// New in DWARF v5:  HANDLE_DW_LANG(0x0014, Python)  HANDLE_DW_LANG(0x0015, OpenCL)  HANDLE_DW_LANG(0x0016, Go) @@ -792,6 +797,13 @@ HANDLE_DW_APPLE_PROPERTY(0x1000, nullability)  HANDLE_DW_APPLE_PROPERTY(0x2000, null_resettable)  HANDLE_DW_APPLE_PROPERTY(0x4000, class) +// DWARF v5 Unit Types. +HANDLE_DW_UT(0x01, compile) +HANDLE_DW_UT(0x02, type) +HANDLE_DW_UT(0x03, partial) +HANDLE_DW_UT(0x04, skeleton) +HANDLE_DW_UT(0x05, split_compile) +HANDLE_DW_UT(0x06, split_type)  #undef HANDLE_DW_TAG  #undef HANDLE_DW_AT @@ -809,3 +821,4 @@ HANDLE_DW_APPLE_PROPERTY(0x4000, class)  #undef HANDLE_DW_RLE  #undef HANDLE_DW_CFA  #undef HANDLE_DW_APPLE_PROPERTY +#undef HANDLE_DW_UT diff --git a/llvm/include/llvm/Support/Dwarf.h b/llvm/include/llvm/Support/Dwarf.h index 8336b9df9df..84056682924 100644 --- a/llvm/include/llvm/Support/Dwarf.h +++ b/llvm/include/llvm/Support/Dwarf.h @@ -29,7 +29,7 @@ class StringRef;  namespace dwarf {  //===----------------------------------------------------------------------===// -// Dwarf constants as gleaned from the DWARF Debugging Information Format V.4 +// DWARF constants as gleaned from the DWARF Debugging Information Format V.5  // reference manual http://www.dwarfstd.org/.  // @@ -305,7 +305,15 @@ enum ApplePropertyAttributes {  #include "llvm/Support/Dwarf.def"  }; -// Constants for the DWARF5 Accelerator Table Proposal +/// Constants for unit types in DWARF v5. +enum UnitType : unsigned char { +#define HANDLE_DW_UT(ID, NAME) DW_UT_##NAME = ID, +#include "llvm/Support/Dwarf.def" +  DW_UT_lo_user = 0x80, +  DW_UT_hi_user = 0xff +}; + +// Constants for the DWARF v5 Accelerator Table Proposal  enum AcceleratorTable {    // Data layout descriptors.    DW_ATOM_null = 0u,       // Marker as the end of a list of atoms. @@ -373,6 +381,7 @@ StringRef LNExtendedString(unsigned Encoding);  StringRef MacinfoString(unsigned Encoding);  StringRef CallFrameString(unsigned Encoding);  StringRef ApplePropertyString(unsigned); +StringRef UnitTypeString(unsigned);  StringRef AtomTypeString(unsigned Atom);  StringRef GDBIndexEntryKindString(GDBIndexEntryKind Kind);  StringRef GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 66ac0e7271d..147f03e2c6d 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -690,7 +690,10 @@ void DwarfCompileUnit::emitHeader(bool UseOffsets) {      Asm->OutStreamer->EmitLabel(LabelBegin);    } -  DwarfUnit::emitHeader(UseOffsets); +  dwarf::UnitType UT = Skeleton ? dwarf::DW_UT_split_compile +                                : DD->useSplitDwarf() ? dwarf::DW_UT_skeleton +                                                      : dwarf::DW_UT_compile; +  DwarfUnit::emitCommonHeader(UseOffsets, UT);  }  /// addGlobalName - Add a new global name to the compile unit. diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 0c57f8222ee..f74d7bf2cb1 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1531,18 +1531,27 @@ DIE *DwarfUnit::getOrCreateStaticMemberDIE(const DIDerivedType *DT) {    return &StaticMemberDIE;  } -void DwarfUnit::emitHeader(bool UseOffsets) { +void DwarfUnit::emitCommonHeader(bool UseOffsets, dwarf::UnitType UT) {    // Emit size of content not including length itself    Asm->OutStreamer->AddComment("Length of Unit");    Asm->EmitInt32(getHeaderSize() + getUnitDie().getSize());    Asm->OutStreamer->AddComment("DWARF version number"); -  Asm->EmitInt16(DD->getDwarfVersion()); -  Asm->OutStreamer->AddComment("Offset Into Abbrev. Section"); +  unsigned Version = DD->getDwarfVersion(); +  Asm->EmitInt16(Version); + +  // DWARF v5 reorders the address size and adds a unit type. +  if (Version >= 5) { +    Asm->OutStreamer->AddComment("DWARF Unit Type"); +    Asm->EmitInt8(UT); +    Asm->OutStreamer->AddComment("Address Size (in bytes)"); +    Asm->EmitInt8(Asm->getDataLayout().getPointerSize()); +  }    // We share one abbreviations table across all units so it's always at the    // start of the section. Use a relocatable offset where needed to ensure    // linking doesn't invalidate that offset. +  Asm->OutStreamer->AddComment("Offset Into Abbrev. Section");    const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();    if (UseOffsets)      Asm->EmitInt32(0); @@ -1550,12 +1559,16 @@ void DwarfUnit::emitHeader(bool UseOffsets) {      Asm->emitDwarfSymbolReference(          TLOF.getDwarfAbbrevSection()->getBeginSymbol(), false); -  Asm->OutStreamer->AddComment("Address Size (in bytes)"); -  Asm->EmitInt8(Asm->getDataLayout().getPointerSize()); +  if (Version <= 4) { +    Asm->OutStreamer->AddComment("Address Size (in bytes)"); +    Asm->EmitInt8(Asm->getDataLayout().getPointerSize()); +  }  }  void DwarfTypeUnit::emitHeader(bool UseOffsets) { -  DwarfUnit::emitHeader(UseOffsets); +  DwarfUnit::emitCommonHeader(UseOffsets,  +                              DD->useSplitDwarf() ? dwarf::DW_UT_split_type +                                                  : dwarf::DW_UT_type);    Asm->OutStreamer->AddComment("Type Signature");    Asm->OutStreamer->EmitIntValue(TypeSignature, sizeof(TypeSignature));    Asm->OutStreamer->AddComment("Type DIE Offset"); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h index 89e654b33d0..a48b976a6fa 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -279,11 +279,13 @@ public:    virtual unsigned getHeaderSize() const {      return sizeof(int16_t) + // DWARF version number             sizeof(int32_t) + // Offset Into Abbrev. Section -           sizeof(int8_t);   // Pointer Size (in bytes) +           sizeof(int8_t) +  // Pointer Size (in bytes) +           (DD->getDwarfVersion() >= 5 ? sizeof(int8_t) +                                       : 0); // DWARF v5 unit type    }    /// Emit the header for this unit, not including the initial length field. -  virtual void emitHeader(bool UseOffsets); +  virtual void emitHeader(bool UseOffsets) = 0;    virtual DwarfCompileUnit &getCU() = 0; @@ -308,6 +310,9 @@ protected:    void updateAcceleratorTables(const DIScope *Context, const DIType *Ty,                                 const DIE &TyDIE); +  /// Emit the common part of the header for this unit. +  void emitCommonHeader(bool UseOffsets, dwarf::UnitType UT); +  private:    void constructTypeDIE(DIE &Buffer, const DIBasicType *BTy);    void constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy); diff --git a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp index 948972f8f13..6e550f2e9ec 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp @@ -18,8 +18,10 @@ using namespace llvm;  void DWARFCompileUnit::dump(raw_ostream &OS) {    OS << format("0x%08x", getOffset()) << ": Compile Unit:"       << " length = " << format("0x%08x", getLength()) -     << " version = " << format("0x%04x", getVersion()) -     << " abbr_offset = " << format("0x%04x", getAbbreviations()->getOffset()) +     << " version = " << format("0x%04x", getVersion()); +  if (getVersion() >= 5) +    OS << " unit_type = " << dwarf::UnitTypeString(getUnitType()); +  OS << " abbr_offset = " << format("0x%04x", getAbbreviations()->getOffset())       << " addr_size = " << format("0x%02x", getAddressByteSize())       << " (next unit at " << format("0x%08x", getNextUnitOffset())       << ")\n"; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp index b468ba28c94..1faa23a3df8 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp @@ -37,8 +37,10 @@ void DWARFTypeUnit::dump(raw_ostream &OS, bool SummarizeTypes) {    OS << format("0x%08x", getOffset()) << ": Type Unit:"       << " length = " << format("0x%08x", getLength()) -     << " version = " << format("0x%04x", getVersion()) -     << " abbr_offset = " << format("0x%04x", getAbbreviations()->getOffset()) +     << " version = " << format("0x%04x", getVersion()); +  if (getVersion() >= 5) +    OS << " unit_type = " << dwarf::UnitTypeString(getUnitType()); +  OS << " abbr_offset = " << format("0x%04x", getAbbreviations()->getOffset())       << " addr_size = " << format("0x%02x", getAddressByteSize())       << " name = '" << Name << "'"       << " type_signature = " << format("0x%16" PRIx64, TypeHash) diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp index 84dc904f9b8..6050adb4bc7 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -88,7 +88,15 @@ bool DWARFUnit::getStringOffsetSectionItem(uint32_t Index,  bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) {    Length = debug_info.getU32(offset_ptr);    Version = debug_info.getU16(offset_ptr); -  uint64_t AbbrOffset = debug_info.getU32(offset_ptr); +  uint64_t AbbrOffset; +  if (Version >= 5) { +    UnitType = debug_info.getU8(offset_ptr); +    AddrSize = debug_info.getU8(offset_ptr); +    AbbrOffset = debug_info.getU32(offset_ptr); +  } else { +    AbbrOffset = debug_info.getU32(offset_ptr); +    AddrSize = debug_info.getU8(offset_ptr); +  }    if (IndexEntry) {      if (AbbrOffset)        return false; @@ -100,7 +108,6 @@ bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) {        return false;      AbbrOffset = AbbrEntry->Offset;    } -  AddrSize = debug_info.getU8(offset_ptr);    bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1);    bool VersionOK = DWARFContext::isSupportedVersion(Version); diff --git a/llvm/lib/Support/Dwarf.cpp b/llvm/lib/Support/Dwarf.cpp index 8950e8c919a..f13da62e4a8 100644 --- a/llvm/lib/Support/Dwarf.cpp +++ b/llvm/lib/Support/Dwarf.cpp @@ -304,6 +304,17 @@ StringRef llvm::dwarf::ApplePropertyString(unsigned Prop) {    }  } +StringRef llvm::dwarf::UnitTypeString(unsigned UT) { +  switch (UT) { +  default: +    return StringRef(); +#define HANDLE_DW_UT(ID, NAME)                                                 \ +  case DW_UT_##NAME:                                                           \ +    return "DW_UT_" #NAME; +#include "llvm/Support/Dwarf.def" +  } +} +  StringRef llvm::dwarf::AtomTypeString(unsigned AT) {    switch (AT) {    case dwarf::DW_ATOM_null: diff --git a/llvm/test/CodeGen/X86/dwarf-headers.ll b/llvm/test/CodeGen/X86/dwarf-headers.ll new file mode 100644 index 00000000000..612807dd812 --- /dev/null +++ b/llvm/test/CodeGen/X86/dwarf-headers.ll @@ -0,0 +1,109 @@ +; RUN: llc -split-dwarf=Disable -dwarf-version=4 -generate-type-units \ +; RUN:     -filetype=obj -O0 -mtriple=x86_64-unknown-linux-gnu < %s \ +; RUN:     | llvm-dwarfdump - | FileCheck %s --check-prefix=SINGLE-4 + +; RUN: llc -split-dwarf=Enable -dwarf-version=4 -generate-type-units \ +; RUN:     -filetype=obj -O0 -mtriple=x86_64-unknown-linux-gnu < %s \ +; RUN:     | llvm-dwarfdump - | FileCheck %s --check-prefix=SPLIT-4 + +; RUN: llc -split-dwarf=Disable -dwarf-version=5 -generate-type-units \ +; RUN:     -filetype=obj -O0 -mtriple=x86_64-unknown-linux-gnu < %s \ +; RUN:     | llvm-dwarfdump - | FileCheck %s --check-prefix=SINGLE-5 + +; RUN: llc -split-dwarf=Enable -dwarf-version=5 -generate-type-units \ +; RUN:     -filetype=obj -O0 -mtriple=x86_64-unknown-linux-gnu < %s \ +; RUN:     | llvm-dwarfdump - | FileCheck %s --check-prefix=SPLIT-5 + +; Looking for DWARF headers to be generated correctly. +; There are 7 variants: v4 CU, v4 TU, v5 (normal/skeleton/split) CU, +; v5 (normal/split) TU.  The v5 CU variants and TU variants differ +; only in the type-unit code. +; (v2 thru v4 CUs are all the same, and TUs were invented in v4, +; so we don't bother checking older versions.) + +; Test case built from: +;struct S { +;  int s1; +;}; +; +;S s; + +; Verify the v4 non-split headers. +; Note that we check the exact offset of the DIEs because that tells us +; the length of the header. +; +; SINGLE-4: .debug_info contents: +; SINGLE-4: 0x00000000: Compile Unit: {{.*}} version = 0x0004 abbr_offset +; SINGLE-4: 0x0000000b: DW_TAG_compile_unit +; +; SINGLE-4: .debug_types contents: +; SINGLE-4: 0x00000000: Type Unit: {{.*}} version = 0x0004 abbr_offset +; SINGLE-4: 0x00000017: DW_TAG_type_unit + +; Verify the v4 split headers. +; +; SPLIT-4: .debug_info contents: +; SPLIT-4: 0x00000000: Compile Unit: {{.*}} version = 0x0004 abbr_offset +; SPLIT-4: 0x0000000b: DW_TAG_compile_unit +; +; SPLIT-4: .debug_info.dwo contents: +; SPLIT-4: 0x00000000: Compile Unit: {{.*}} version = 0x0004 abbr_offset +; SPLIT-4: 0x0000000b: DW_TAG_compile_unit +; +; SPLIT-4: .debug_types.dwo contents: +; SPLIT-4: 0x00000000: Type Unit: {{.*}} version = 0x0004 abbr_offset +; SPLIT-4: 0x00000017: DW_TAG_type_unit + +; Verify the v5 non-split headers. +; +; SINGLE-5: .debug_info contents: +; SINGLE-5: 0x00000000: Compile Unit: {{.*}} version = 0x0005 unit_type = DW_UT_compile abbr_offset +; SINGLE-5: 0x0000000c: DW_TAG_compile_unit +; +; FIXME: V5 wants type units in .debug_info not .debug_types. +; SINGLE-5: .debug_types contents: +; SINGLE-5: 0x00000000: Type Unit: {{.*}} version = 0x0005 unit_type = DW_UT_type abbr_offset +; SINGLE-5: 0x00000018: DW_TAG_type_unit + +; Verify the v5 split headers. +; +; SPLIT-5: .debug_info contents: +; SPLIT-5: 0x00000000: Compile Unit: {{.*}} version = 0x0005 unit_type = DW_UT_skeleton abbr_offset +; SPLIT-5: 0x0000000c: DW_TAG_compile_unit +; +; SPLIT-5: .debug_info.dwo contents: +; SPLIT-5: 0x00000000: Compile Unit: {{.*}} version = 0x0005 unit_type = DW_UT_split_compile abbr_offset +; SPLIT-5: 0x0000000c: DW_TAG_compile_unit +; +; FIXME: V5 wants type units in .debug_info.dwo not .debug_types.dwo. +; SPLIT-5: .debug_types.dwo contents: +; SPLIT-5: 0x00000000: Type Unit: {{.*}} version = 0x0005 unit_type = DW_UT_split_type abbr_offset +; SPLIT-5: 0x00000018: DW_TAG_type_unit + + +; ModuleID = 't.cpp' +source_filename = "t.cpp" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%struct.S = type { i32 } + +@s = global %struct.S zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!10, !11} +!llvm.ident = !{!12} + +!0 = !DIGlobalVariableExpression(var: !1) +!1 = distinct !DIGlobalVariable(name: "s", scope: !2, file: !3, line: 5, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 5.0.0 (trunk 295942)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5) +!3 = !DIFile(filename: "t.cpp", directory: "/home/probinson/projects/scratch") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !3, line: 1, size: 32, elements: !7, identifier: "_ZTS1S") +!7 = !{!8} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "s1", scope: !6, file: !3, line: 2, baseType: !9, size: 32) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{!"clang version 5.0.0 (trunk 295942)"} diff --git a/llvm/test/DebugInfo/Inputs/dwarfdump-header.elf-x86-64 b/llvm/test/DebugInfo/Inputs/dwarfdump-header.elf-x86-64 Binary files differnew file mode 100644 index 00000000000..5a6f0cf7bb3 --- /dev/null +++ b/llvm/test/DebugInfo/Inputs/dwarfdump-header.elf-x86-64 diff --git a/llvm/test/DebugInfo/Inputs/dwarfdump-header.s b/llvm/test/DebugInfo/Inputs/dwarfdump-header.s new file mode 100644 index 00000000000..f9ebc047d57 --- /dev/null +++ b/llvm/test/DebugInfo/Inputs/dwarfdump-header.s @@ -0,0 +1,149 @@ +# Test object to verify dwarfdump handles v4 and v5 CU/TU headers. +# We have a representative set of units: v4 CU, v5 CU, v4 TU, v5 split TU. +# +# To generate the test object: +# llvm-mc -triple x86_64-unknown-linux dwarfdump-header.s -filetype=obj \ +#         -o dwarfdump-header.elf-x86-64 + +        .section .debug_str,"MS",@progbits,1 +str_producer: +        .asciz "Handmade DWARF producer" +str_CU_4: +        .asciz "V4_compile_unit" +str_CU_5: +        .asciz "V5_compile_unit" +str_TU_4: +        .asciz "V4_type_unit" + +        .section .debug_str.dwo,"MS",@progbits,1 +dwo_TU_5: +        .asciz "V5_split_type_unit" + +# All CUs/TUs use the same abbrev section for simplicity. +        .section .debug_abbrev,"",@progbits +        .byte 0x01  # Abbrev code +        .byte 0x11  # DW_TAG_compile_unit +        .byte 0x00  # DW_CHILDREN_no +        .byte 0x25  # DW_AT_producer +        .byte 0x0e  # DW_FORM_strp +        .byte 0x03  # DW_AT_name +        .byte 0x0e  # DW_FORM_strp +        .byte 0x00  # EOM(1) +        .byte 0x00  # EOM(2) +        .byte 0x02  # Abbrev code +        .byte 0x41  # DW_TAG_type_unit +        .byte 0x01  # DW_CHILDREN_yes +        .byte 0x03  # DW_AT_name +        .byte 0x0e  # DW_FORM_strp +        .byte 0x00  # EOM(1) +        .byte 0x00  # EOM(2) +        .byte 0x03  # Abbrev code +        .byte 0x13  # DW_TAG_structure_type +        .byte 0x00  # DW_CHILDREN_no (no members) +        .byte 0x03  # DW_AT_name +        .byte 0x0e  # DW_FORM_strp +        .byte 0x00  # EOM(1) +        .byte 0x00  # EOM(2) +        .byte 0x00  # EOM(3) + +# And a .dwo copy for the .dwo sections. +        .section .debug_abbrev.dwo,"",@progbits +        .byte 0x01  # Abbrev code +        .byte 0x11  # DW_TAG_compile_unit +        .byte 0x00  # DW_CHILDREN_no +        .byte 0x25  # DW_AT_producer +        .byte 0x0e  # DW_FORM_strp +        .byte 0x03  # DW_AT_name +        .byte 0x0e  # DW_FORM_strp +        .byte 0x00  # EOM(1) +        .byte 0x00  # EOM(2) +        .byte 0x02  # Abbrev code +        .byte 0x41  # DW_TAG_type_unit +        .byte 0x01  # DW_CHILDREN_yes +        .byte 0x03  # DW_AT_name +        .byte 0x0e  # DW_FORM_strp +        .byte 0x00  # EOM(1) +        .byte 0x00  # EOM(2) +        .byte 0x03  # Abbrev code +        .byte 0x13  # DW_TAG_structure_type +        .byte 0x00  # DW_CHILDREN_no (no members) +        .byte 0x03  # DW_AT_name +        .byte 0x0e  # DW_FORM_strp +        .byte 0x00  # EOM(1) +        .byte 0x00  # EOM(2) +        .byte 0x00  # EOM(3) + +        .section .debug_info,"",@progbits + +# DWARF v4 CU header. V4 CU headers all look the same so we do only one. +        .long  CU_4_end-CU_4_version  # Length of Unit +CU_4_version: +        .short 4               # DWARF version number +        .long .debug_abbrev    # Offset Into Abbrev. Section +        .byte 8                # Address Size (in bytes) +# The compile-unit DIE, which has just DW_AT_producer and DW_AT_name. +        .byte 1 +        .long str_producer +        .long str_CU_4 +        .byte 0 # NULL +CU_4_end: + +# DWARF v5 normal CU header. +        .long  CU_5_end-CU_5_version  # Length of Unit +CU_5_version: +        .short 5               # DWARF version number +        .byte 1                # DWARF Unit Type +        .byte 8                # Address Size (in bytes) +        .long .debug_abbrev    # Offset Into Abbrev. Section +# The compile-unit DIE, which has just DW_AT_producer and DW_AT_name. +        .byte 1 +        .long str_producer +        .long str_CU_5 +        .byte 0 # NULL +CU_5_end: + +        .section .debug_types,"",@progbits + +# DWARF v4 Type unit header. Normal/split are identical so we do only one. +TU_4_start: +        .long  TU_4_end-TU_4_version  # Length of Unit +TU_4_version: +        .short 4               # DWARF version number +        .long .debug_abbrev    # Offset Into Abbrev. Section +        .byte 8                # Address Size (in bytes) +        .quad 0x1122334455667788 # Type Signature +        .long TU_4_type-TU_4_start # Type offset +# The type-unit DIE, which has a name. +        .byte 2 +        .long str_TU_4 +# The type DIE, which has a name. +TU_4_type: +        .byte 3 +        .long str_TU_4 +        .byte 0 # NULL +        .byte 0 # NULL +TU_4_end: + +        .section .debug_types.dwo,"",@progbits +# FIXME: DWARF v5 wants type units in .debug_info[.dwo] not .debug_types[.dwo]. + +# DWARF v5 split type unit header. +TU_split_5_start: +        .long  TU_split_5_end-TU_split_5_version  # Length of Unit +TU_split_5_version: +        .short 5               # DWARF version number +        .byte 6                # DWARF Unit Type +        .byte 8                # Address Size (in bytes) +        .long .debug_abbrev.dwo    # Offset Into Abbrev. Section +        .quad 0x8899aabbccddeeff # Type Signature +        .long TU_split_5_type-TU_split_5_start  # Type offset +# The type-unit DIE, which has a name. +        .byte 2 +        .long dwo_TU_5 +# The type DIE, which has a name. +TU_split_5_type: +        .byte 3 +        .long dwo_TU_5 +        .byte 0 # NULL +        .byte 0 # NULL +TU_split_5_end: diff --git a/llvm/test/DebugInfo/dwarfdump-header.test b/llvm/test/DebugInfo/dwarfdump-header.test new file mode 100644 index 00000000000..7c198d423f3 --- /dev/null +++ b/llvm/test/DebugInfo/dwarfdump-header.test @@ -0,0 +1,29 @@ +RUN: llvm-dwarfdump %p/Inputs/dwarfdump-header.elf-x86-64 | FileCheck %s + +The input file is hand-coded assembler to generate all the units, +so we're willing to make exact checks for offsets and such. + +CHECK-LABEL: .debug_info contents: + +The v4 CU header. + +CHECK: 0x00000000: Compile Unit: length = 0x00000011 version = 0x0004 abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x00000015) +CHECK: 0x0000000b: DW_TAG_compile_unit + +The v5 normal CU header. + +CHECK: 0x00000015: Compile Unit: length = 0x00000012 version = 0x0005 unit_type = DW_UT_compile abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x0000002b) +CHECK: 0x00000021: DW_TAG_compile_unit + +CHECK-LABEL: .debug_types contents: + +The v4 type unit header. + +CHECK: 0x00000000: Type Unit: length = 0x0000001f version = 0x0004 abbr_offset = 0x0000 addr_size = 0x08 name = 'V4_type_unit' type_signature = 0x1122334455667788 type_offset = 0x001c (next unit at 0x00000023) +CHECK: 0x00000017: DW_TAG_type_unit + +FIXME: DWARF v5 wants type units in .debug_info[.dwo] not .debug_types[.dwo]. +CHECK: .debug_types.dwo contents: + +CHECK: 0x00000000: Type Unit: length = 0x00000020 version = 0x0005 unit_type = DW_UT_split_type abbr_offset = 0x0000 addr_size = 0x08 name = 'V5_split_type_unit' type_signature = 0x8899aabbccddeeff type_offset = 0x001d (next unit at 0x00000024) +CHECK: 0x00000018: DW_TAG_type_unit diff --git a/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp b/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp index 9ec43cab4dc..2c14786e584 100644 --- a/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp @@ -240,8 +240,14 @@ StringRef dwarfgen::Generator::generate() {      assert(Length != -1U);      Asm->EmitInt32(Length);      Asm->EmitInt16(Version); -    Asm->EmitInt32(0); -    Asm->EmitInt8(CU->getAddressSize()); +    if (Version <= 4) { +      Asm->EmitInt32(0); +      Asm->EmitInt8(CU->getAddressSize()); +    } else { +      Asm->EmitInt8(dwarf::DW_UT_compile); +      Asm->EmitInt8(CU->getAddressSize()); +      Asm->EmitInt32(0); +    }      Asm->emitDwarfDIE(*CU->getUnitDIE().Die);    }  | 

