diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h @@ -111,6 +111,16 @@ return AttributeSpecs[idx].Attr; } + bool getAttrIsImplicitConstByIndex(uint32_t idx) const { + assert(idx < AttributeSpecs.size()); + return AttributeSpecs[idx].isImplicitConst(); + } + + int64_t getAttrImplicitConstValueByIndex(uint32_t idx) const { + assert(idx < AttributeSpecs.size()); + return AttributeSpecs[idx].getImplicitConstValue(); + } + /// Get the index of the specified attribute. /// /// Searches the this abbreviation declaration for the index of the specified diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -632,15 +632,8 @@ OS << '\n'; // Dump all data in the DIE for the attributes. - for (const DWARFAttribute &AttrValue : attributes()) { - if (AttrValue.Value.getForm() == DW_FORM_implicit_const) { - // We are dumping .debug_info section , - // implicit_const attribute values are not really stored here, - // but in .debug_abbrev section. So we just skip such attrs. - continue; - } + for (const DWARFAttribute &AttrValue : attributes()) dumpAttribute(OS, *this, AttrValue, Indent, DumpOpts); - } DWARFDie child = getFirstChild(); if (DumpOpts.ShowChildren && DumpOpts.ChildRecurseDepth > 0 && child) { @@ -723,10 +716,16 @@ // Add the previous byte size of any previous attribute value. AttrValue.Offset += AttrValue.ByteSize; uint64_t ParseOffset = AttrValue.Offset; - auto U = Die.getDwarfUnit(); - assert(U && "Die must have valid DWARF unit"); - AttrValue.Value = DWARFFormValue::createFromUnit( - AbbrDecl.getFormByIndex(Index), U, &ParseOffset); + if (AbbrDecl.getAttrIsImplicitConstByIndex(Index)) + AttrValue.Value = DWARFFormValue::createFromSValue( + AbbrDecl.getFormByIndex(Index), + AbbrDecl.getAttrImplicitConstValueByIndex(Index)); + else { + auto U = Die.getDwarfUnit(); + assert(U && "Die must have valid DWARF unit"); + AttrValue.Value = DWARFFormValue::createFromUnit( + AbbrDecl.getFormByIndex(Index), U, &ParseOffset); + } AttrValue.ByteSize = ParseOffset - AttrValue.Offset; } else { assert(Index == NumAttrs && "Indexes should be [0, NumAttrs) only"); diff --git a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -168,6 +168,7 @@ case DW_FORM_line_strp: case DW_FORM_GNU_ref_alt: case DW_FORM_GNU_strp_alt: + case DW_FORM_implicit_const: if (Optional FixedSize = dwarf::getFixedFormByteSize(Form, Params)) { *OffsetPtr += *FixedSize; @@ -356,6 +357,9 @@ case DW_FORM_ref_sig8: Value.uval = Data.getU64(OffsetPtr, &Err); break; + case DW_FORM_implicit_const: + // Value has been already set by DWARFFormValue::createFromSValue. + break; default: // DWARFFormValue::skipValue() will have caught this and caused all // DWARF DIEs to fail to be parsed, so this code is not be reachable. @@ -510,6 +514,7 @@ break; case DW_FORM_sdata: + case DW_FORM_implicit_const: OS << Value.sval; break; case DW_FORM_udata: diff --git a/llvm/test/DebugInfo/implicit-const-test2.s b/llvm/test/DebugInfo/implicit-const-test2.s new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/implicit-const-test2.s @@ -0,0 +1,44 @@ +# REQUIRES: x86-registered-target + +# RUN: llvm-mc --filetype=obj --triple=x86_64-pc-linux %s -o %t.o -g + +# RUN: llvm-dwarfdump -v %t.o | FileCheck %s + +# CHECK: [1] DW_TAG_compile_unit DW_CHILDREN_no +# CHECK-NEXT: DW_AT_producer DW_FORM_string +# CHECK-NEXT: DW_AT_language DW_FORM_implicit_const 29 +# CHECK-NEXT: DW_AT_name DW_FORM_string + +# CHECK: DW_AT_producer [DW_FORM_string] ("GNU C17 11.0.0 20210210 (Red Hat 11.0.0-0) -mtune=generic -march=x86-64 -g") +# CHECK-NEXT: DW_AT_language [DW_FORM_implicit_const] (DW_LANG_C11) +# CHECK-NEXT: DW_AT_name [DW_FORM_string] ("main.c") + + .section .debug_info,"",@progbits +.Ldebug_info0: + .long .Ldebug_info0_end - .Ldebug_info0_start # Length of Compilation Unit Info +.Ldebug_info0_start: + .value 0x5 # DWARF version number + .byte 0x1 # DW_UT_compile + .byte 0x8 # Pointer Size (in bytes) + .long .Ldebug_abbrev0 # Offset Into Abbrev. Section + .uleb128 0x1 # (DIE (0xc) DW_TAG_compile_unit) + # DW_AT_producer: "GNU C17 11.0.0 20210210 (Red Hat 11.0.0-0) -mtune=generic -march=x86-64 -g" + .string "GNU C17 11.0.0 20210210 (Red Hat 11.0.0-0) -mtune=generic -march=x86-64 -g" + # DW_AT_language + .string "main.c" # DW_AT_name: "main.c" +.Ldebug_info0_end: + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev0: + .uleb128 0x1 # (abbrev code) + .uleb128 0x11 # (TAG: DW_TAG_compile_unit) + .byte 0x0 # DW_children_no + .uleb128 0x25 # (DW_AT_producer) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x13 # (DW_AT_language) + .uleb128 0x21 # (DW_FORM_implicit_const) + .sleb128 0x1d + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .byte 0 + .byte 0 + .byte 0