mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-28 06:00:28 +00:00
[DWARFv5] Emit new unit header format.
Requesting DWARF v5 will now get you the new compile-unit and type-unit headers. llvm-dwarfdump will also recognize them. Differential Revision: http://reviews.llvm.org/D30206 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296514 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c1a133abee
commit
77bf4a4c38
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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";
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
109
test/CodeGen/X86/dwarf-headers.ll
Normal file
109
test/CodeGen/X86/dwarf-headers.ll
Normal file
@ -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)"}
|
BIN
test/DebugInfo/Inputs/dwarfdump-header.elf-x86-64
Normal file
BIN
test/DebugInfo/Inputs/dwarfdump-header.elf-x86-64
Normal file
Binary file not shown.
149
test/DebugInfo/Inputs/dwarfdump-header.s
Normal file
149
test/DebugInfo/Inputs/dwarfdump-header.s
Normal file
@ -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:
|
29
test/DebugInfo/dwarfdump-header.test
Normal file
29
test/DebugInfo/dwarfdump-header.test
Normal file
@ -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
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user