diff --git a/llvm/include/llvm/ObjectYAML/DWARFYAML.h b/llvm/include/llvm/ObjectYAML/DWARFYAML.h --- a/llvm/include/llvm/ObjectYAML/DWARFYAML.h +++ b/llvm/include/llvm/ObjectYAML/DWARFYAML.h @@ -21,6 +21,7 @@ #include "llvm/ObjectYAML/YAML.h" #include "llvm/Support/YAMLTraits.h" #include +#include #include namespace llvm { @@ -40,6 +41,7 @@ }; struct AbbrevTable { + Optional ID; std::vector Table; }; @@ -110,6 +112,7 @@ uint16_t Version; Optional AddrSize; llvm::dwarf::UnitType Type; // Added in DWARF 5 + Optional AbbrevTableID; yaml::Hex64 AbbrOffset; std::vector Entries; }; @@ -228,6 +231,10 @@ bool isEmpty() const; SetVector getNonEmptySectionNames() const; + Expected getAbbrevTableIndexByID(uint64_t ID) const; + +private: + mutable std::unordered_map AbbrevTableID2Index; }; } // end namespace DWARFYAML diff --git a/llvm/lib/ObjectYAML/DWARFEmitter.cpp b/llvm/lib/ObjectYAML/DWARFEmitter.cpp --- a/llvm/lib/ObjectYAML/DWARFEmitter.cpp +++ b/llvm/lib/ObjectYAML/DWARFEmitter.cpp @@ -246,7 +246,8 @@ /*IsGNUStyle=*/true); } -static Expected writeDIE(ArrayRef AbbrevTable, +static Expected writeDIE(const DWARFYAML::Data &DI, uint64_t CUIndex, + uint64_t AbbrevTableID, const dwarf::FormParams &Params, const DWARFYAML::Entry &Entry, raw_ostream &OS, bool IsLittleEndian) { @@ -256,12 +257,16 @@ if (AbbrCode == 0 || Entry.Values.empty()) return OS.tell() - EntryBegin; - if (AbbrevTable.empty()) - return createStringError( - errc::invalid_argument, - "non-empty compilation unit should have an associated abbrev table"); + Expected AbbrevTableIndexOrErr = + DI.getAbbrevTableIndexByID(AbbrevTableID); + if (!AbbrevTableIndexOrErr) + return createStringError(errc::invalid_argument, + toString(AbbrevTableIndexOrErr.takeError()) + + " for compilation unit with index " + + utostr(CUIndex)); - ArrayRef AbbrevDecls(AbbrevTable[0].Table); + ArrayRef AbbrevDecls( + DI.DebugAbbrev[*AbbrevTableIndexOrErr].Table); if (AbbrCode > AbbrevDecls.size()) return createStringError( @@ -384,7 +389,8 @@ } Error DWARFYAML::emitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) { - for (const DWARFYAML::Unit &Unit : DI.CompileUnits) { + for (uint64_t I = 0; I < DI.CompileUnits.size(); ++I) { + const DWARFYAML::Unit &Unit = DI.CompileUnits[I]; uint8_t AddrSize; if (Unit.AddrSize) AddrSize = *Unit.AddrSize; @@ -402,9 +408,11 @@ std::string EntryBuffer; raw_string_ostream EntryBufferOS(EntryBuffer); + uint64_t AbbrevTableID = Unit.AbbrevTableID.getValueOr(I); for (const DWARFYAML::Entry &Entry : Unit.Entries) { - if (Expected EntryLength = writeDIE( - DI.DebugAbbrev, Params, Entry, EntryBufferOS, DI.IsLittleEndian)) + if (Expected EntryLength = + writeDIE(DI, I, AbbrevTableID, Params, Entry, EntryBufferOS, + DI.IsLittleEndian)) Length += *EntryLength; else return EntryLength.takeError(); diff --git a/llvm/lib/ObjectYAML/DWARFYAML.cpp b/llvm/lib/ObjectYAML/DWARFYAML.cpp --- a/llvm/lib/ObjectYAML/DWARFYAML.cpp +++ b/llvm/lib/ObjectYAML/DWARFYAML.cpp @@ -13,6 +13,8 @@ #include "llvm/ObjectYAML/DWARFYAML.h" #include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/Support/Errc.h" +#include "llvm/Support/Error.h" namespace llvm { @@ -53,6 +55,31 @@ return SecNames; } +Expected DWARFYAML::Data::getAbbrevTableIndexByID(uint64_t ID) const { + if (AbbrevTableID2Index.empty()) { + for (auto &AbbrevTable : enumerate(DebugAbbrev)) { + // If the abbrev table's ID isn't specified, we use the index as its ID. + uint64_t AbbrevTableID = + AbbrevTable.value().ID.getValueOr(AbbrevTable.index()); + auto It = + AbbrevTableID2Index.insert({AbbrevTableID, AbbrevTable.index()}); + if (!It.second) + return createStringError( + errc::invalid_argument, + "the ID (%" PRIu64 ") of abbrev table with index %zu has been used " + "by abbrev table with index %" PRIu64, + AbbrevTableID, AbbrevTable.index(), It.first->second); + } + } + + auto It = AbbrevTableID2Index.find(ID); + if (It == AbbrevTableID2Index.end()) + return createStringError(errc::invalid_argument, + "cannot find abbrev table whose ID is %" PRIu64, + ID); + return It->second; +} + namespace yaml { void MappingTraits::mapping(IO &IO, DWARFYAML::Data &DWARF) { @@ -80,6 +107,7 @@ void MappingTraits::mapping( IO &IO, DWARFYAML::AbbrevTable &AbbrevTable) { + IO.mapOptional("ID", AbbrevTable.ID); IO.mapOptional("Table", AbbrevTable.Table); } @@ -153,6 +181,7 @@ IO.mapRequired("Version", Unit.Version); if (Unit.Version >= 5) IO.mapRequired("UnitType", Unit.Type); + IO.mapOptional("AbbrevTableID", Unit.AbbrevTableID); IO.mapRequired("AbbrOffset", Unit.AbbrOffset); IO.mapOptional("AddrSize", Unit.AddrSize); IO.mapOptional("Entries", Unit.Entries); diff --git a/llvm/test/ObjectYAML/MachO/DWARF-debug_abbrev.yaml b/llvm/test/ObjectYAML/MachO/DWARF-debug_abbrev.yaml --- a/llvm/test/ObjectYAML/MachO/DWARF-debug_abbrev.yaml +++ b/llvm/test/ObjectYAML/MachO/DWARF-debug_abbrev.yaml @@ -1,4 +1,7 @@ -# RUN: yaml2obj %s | obj2yaml | FileCheck %s +## a) Test that yaml2obj is able to emit the __debug_abbrev section and obj2yaml is +## able to convert it back. + +# RUN: yaml2obj --docnum=1 %s | obj2yaml | FileCheck %s --- !mach-o FileHeader: @@ -420,3 +423,69 @@ #CHECK: Attributes: #CHECK: - Attribute: DW_AT_type #CHECK: Form: DW_FORM_ref4 + +## b) Test that yaml2obj emits an error message when there are non-empty compilation +## units and multiple abbrev tables are assigned the same ID. + +# RUN: not yaml2obj --docnum=2 %s 2>&1 | FileCheck %s --check-prefix=ID-COLLISION + +# ID-COLLISION: yaml2obj: error: the ID (1) of abbrev table with index 1 has been used by abbrev table with index 0 + +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x00000003 + filetype: 0x0000000A + ncmds: 1 + sizeofcmds: 232 + flags: 0x00000000 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 232 + segname: __DWARF + vmaddr: 0x00 + vmsize: 0x00 + fileoff: 0x00 + filesize: 0x00 + maxprot: 0 + initprot: 0 + nsects: 2 + flags: 0 + Sections: + - sectname: __debug_abbrev + segname: __DWARF + addr: 0x00 + size: 24 + offset: 528 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_info + segname: __DWARF + addr: 0x00 + size: 64 + offset: 1070 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 +DWARF: + debug_abbrev: + - ID: 1 + - ID: 1 + debug_info: + - Version: 4 + AbbrOffset: 0x00 + Entries: + - AbbrCode: 1 + Values: + - Value: 0x1234 diff --git a/llvm/test/ObjectYAML/MachO/DWARF-debug_info.yaml b/llvm/test/ObjectYAML/MachO/DWARF-debug_info.yaml --- a/llvm/test/ObjectYAML/MachO/DWARF-debug_info.yaml +++ b/llvm/test/ObjectYAML/MachO/DWARF-debug_info.yaml @@ -514,6 +514,7 @@ # DWARF32: debug_info: # DWARF32-NEXT: - Length: 0x0000000000000075 # DWARF32-NEXT: Version: 4 +# DWARF32-NEXT: AbbrevTableID: 0 # DWARF32-NEXT: AbbrOffset: 0 # DWARF32-NEXT: AddrSize: 8 # DWARF32-NEXT: Entries: @@ -583,6 +584,7 @@ # DWARF32-YAML: debug_info: # DWARF32-YAML-NEXT: - Length: 0x000000000000000C # DWARF32-YAML-NEXT: Version: 4 +# DWARF32-YAML-NEXT: AbbrevTableID: 0 # DWARF32-YAML-NEXT: AbbrOffset: 0 # DWARF32-YAML-NEXT: AddrSize: 8 # DWARF32-YAML-NEXT: Entries: @@ -666,9 +668,234 @@ # DWARF64-YAML-NEXT: - Format: DWARF64 # DWARF64-YAML-NEXT: Length: 0x000000000000000C # DWARF64-YAML-NEXT: Version: 4 +# DWARF64-YAML-NEXT: AbbrevTableID: 0 # DWARF64-YAML-NEXT: AbbrOffset: 0 # DWARF64-YAML-NEXT: AddrSize: 8 # DWARF64-YAML-NEXT: Entries: # DWARF64-YAML-NEXT: - AbbrCode: 0x00000001 # DWARF64-YAML-NEXT: Values: # DWARF64-YAML-NEXT: - Value: 0x0000000000001234 + +## c) Test that yaml2obj is able to generate compilation units according to the +## associated abbrev table that is referenced by the 'AbbrevTableID' and obj2yaml +## is able to convert it back. + +# RUN: yaml2obj --docnum=3 %s | obj2yaml | FileCheck %s --check-prefix=MULTI-TABLES + +# MULTI-TABLES: DWARF: +# MULTI-TABLES-NEXT: debug_abbrev: +# MULTI-TABLES-NEXT: - ID: 0 +# MULTI-TABLES-NEXT: Table: +# MULTI-TABLES-NEXT: - Code: 0x0000000000000001 +# MULTI-TABLES-NEXT: Tag: DW_TAG_compile_unit +# MULTI-TABLES-NEXT: Children: DW_CHILDREN_no +# MULTI-TABLES-NEXT: Attributes: +# MULTI-TABLES-NEXT: - Attribute: DW_AT_low_pc +# MULTI-TABLES-NEXT: Form: DW_FORM_addr +# MULTI-TABLES-NEXT: - ID: 1 +# MULTI-TABLES-NEXT: Table: +# MULTI-TABLES-NEXT: - Code: 0x0000000000000001 +# MULTI-TABLES-NEXT: Tag: DW_TAG_compile_unit +# MULTI-TABLES-NEXT: Children: DW_CHILDREN_no +# MULTI-TABLES-NEXT: Attributes: +# MULTI-TABLES-NEXT: - Attribute: DW_AT_low_pc +# MULTI-TABLES-NEXT: Form: DW_FORM_data4 +# MULTI-TABLES-NEXT: - ID: 2 +# MULTI-TABLES-NEXT: Table: +# MULTI-TABLES-NEXT: - Code: 0x0000000000000001 +# MULTI-TABLES-NEXT: Tag: DW_TAG_compile_unit +# MULTI-TABLES-NEXT: Children: DW_CHILDREN_no +# MULTI-TABLES-NEXT: Attributes: +# MULTI-TABLES-NEXT: - Attribute: DW_AT_low_pc +# MULTI-TABLES-NEXT: Form: DW_FORM_udata +# MULTI-TABLES-NEXT: debug_info: +# MULTI-TABLES-NEXT: - Length: 0x000000000000000C +# MULTI-TABLES-NEXT: Version: 4 +# MULTI-TABLES-NEXT: AbbrevTableID: 1 +# MULTI-TABLES-NEXT: AbbrOffset: 0x0000000000000008 +# MULTI-TABLES-NEXT: AddrSize: 8 +# MULTI-TABLES-NEXT: Entries: +# MULTI-TABLES-NEXT: - AbbrCode: 0x00000001 +# MULTI-TABLES-NEXT: Values: +# MULTI-TABLES-NEXT: - Value: 0x0000000000001234 +# MULTI-TABLES-NEXT: - Length: 0x000000000000000C +# MULTI-TABLES-NEXT: Version: 4 +# MULTI-TABLES-NEXT: AbbrevTableID: 1 +# MULTI-TABLES-NEXT: AbbrOffset: 0x0000000000000008 +# MULTI-TABLES-NEXT: AddrSize: 8 +# MULTI-TABLES-NEXT: Entries: +# MULTI-TABLES-NEXT: - AbbrCode: 0x00000001 +# MULTI-TABLES-NEXT: Values: +# MULTI-TABLES-NEXT: - Value: 0x0000000000004321 +# MULTI-TABLES-NEXT: - Length: 0x0000000000000010 +# MULTI-TABLES-NEXT: Version: 4 +# MULTI-TABLES-NEXT: AbbrevTableID: 0 +# MULTI-TABLES-NEXT: AbbrOffset: 0x0000000000000000 +# MULTI-TABLES-NEXT: AddrSize: 8 +# MULTI-TABLES-NEXT: Entries: +# MULTI-TABLES-NEXT: - AbbrCode: 0x00000001 +# MULTI-TABLES-NEXT: Values: +# MULTI-TABLES-NEXT: - Value: 0x0000000000005678 +# MULTI-TABLES-NEXT: - Length: 0x000000000000000B +# MULTI-TABLES-NEXT: Version: 4 +# MULTI-TABLES-NEXT: AbbrevTableID: 2 +# MULTI-TABLES-NEXT: AbbrOffset: 0x0000000000000010 +# MULTI-TABLES-NEXT: AddrSize: 8 +# MULTI-TABLES-NEXT: Entries: +# MULTI-TABLES-NEXT: - AbbrCode: 0x00000001 +# MULTI-TABLES-NEXT: Values: +# MULTI-TABLES-NEXT: - Value: 0x0000000000008765 +# MULTI-TABLES-NEXT: ... + +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x00000003 + filetype: 0x0000000A + ncmds: 1 + sizeofcmds: 232 + flags: 0x00000000 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 232 + segname: __DWARF + vmaddr: 0x00 + vmsize: 0x00 + fileoff: 0x00 + filesize: 0x00 + maxprot: 0 + initprot: 0 + nsects: 2 + flags: 0 + Sections: + - sectname: __debug_abbrev + segname: __DWARF + addr: 0x00 + size: 24 + offset: 528 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_info + segname: __DWARF + addr: 0x00 + size: 67 + offset: 1070 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 +DWARF: + debug_abbrev: + - Table: + - Code: 1 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - ID: 2 + Table: + - Code: 1 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_data4 + - ID: 1 + Table: + - Code: 1 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_udata + debug_info: + - Version: 4 + AbbrevTableID: 2 + AbbrOffset: 8 + Entries: + - AbbrCode: 1 + Values: + - Value: 0x1234 + - Version: 4 + AbbrevTableID: 2 + AbbrOffset: 8 + Entries: + - AbbrCode: 1 + Values: + - Value: 0x4321 + - Version: 4 + AbbrevTableID: 0 + AbbrOffset: 0 + Entries: + - AbbrCode: 1 + Values: + - Value: 0x5678 + - Version: 4 + AbbrevTableID: 1 + AbbrOffset: 16 + Entries: + - AbbrCode: 1 + Values: + - Value: 0x8765 + +## d) Test that yaml2obj emits an error message when a compilation unit doesn't have +## an associated abbrev table. + +# RUN: not yaml2obj --docnum=4 %s 2>&1 | FileCheck %s --check-prefix=MISSING-ABBREV + +# MISSING-ABBREV: yaml2obj: error: cannot find abbrev table whose ID is 0 for compilation unit with index 0 + +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x00000003 + filetype: 0x0000000A + ncmds: 1 + sizeofcmds: 232 + flags: 0x00000000 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __DWARF + vmaddr: 0x00 + vmsize: 0x00 + fileoff: 0x00 + filesize: 0x00 + maxprot: 0 + initprot: 0 + nsects: 2 + flags: 0 + Sections: + - sectname: __debug_info + segname: __DWARF + addr: 0x00 + size: 64 + offset: 1070 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 +DWARF: + debug_info: + - Version: 4 + AbbrOffset: 0x00 + Entries: + - AbbrCode: 1 + Values: + - Value: 0x1234 diff --git a/llvm/test/ObjectYAML/MachO/DWARF5-debug_info.yaml b/llvm/test/ObjectYAML/MachO/DWARF5-debug_info.yaml --- a/llvm/test/ObjectYAML/MachO/DWARF5-debug_info.yaml +++ b/llvm/test/ObjectYAML/MachO/DWARF5-debug_info.yaml @@ -515,6 +515,7 @@ # DWARF32-NEXT: - Length: 0x0000000000000076 # DWARF32-NEXT: Version: 5 # DWARF32-NEXT: UnitType: DW_UT_compile +# DWARF32-NEXT: AbbrevTableID: 0 # DWARF32-NEXT: AbbrOffset: 0 # DWARF32-NEXT: AddrSize: 8 # DWARF32-NEXT: Entries: @@ -585,6 +586,7 @@ # DWARF32-YAML-NEXT: - Length: 0x000000000000000C # DWARF32-YAML-NEXT: Version: 5 # DWARF32-YAML-NEXT: UnitType: DW_UT_compile +# DWARF32-YAML-NEXT: AbbrevTableID: 0 # DWARF32-YAML-NEXT: AbbrOffset: 0x0000000000000000 # DWARF32-YAML-NEXT: AddrSize: 8 # DWARF32-YAML-NEXT: Entries: @@ -670,6 +672,7 @@ # DWARF64-YAML-NEXT: Length: 0x0000000000000014 # DWARF64-YAML-NEXT: Version: 5 # DWARF64-YAML-NEXT: UnitType: DW_UT_compile +# DWARF64-YAML-NEXT: AbbrevTableID: 0 # DWARF64-YAML-NEXT: AbbrOffset: 0x0000000000000000 # DWARF64-YAML-NEXT: AddrSize: 8 # DWARF64-YAML-NEXT: Entries: diff --git a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-abbrev.yaml b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-abbrev.yaml --- a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-abbrev.yaml +++ b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-abbrev.yaml @@ -306,3 +306,28 @@ - Tag: DW_TAG_subprogram Children: DW_CHILDREN_no Attributes: [] + +## i) Test that yaml2obj emits an error message when there are non-empty compilation units +## and multiple abbrev tables are assigned the same ID. + +## RUN: not yaml2obj --docnum=9 %s 2>&1 | FileCheck %s --check-prefix=ID-COLLISION + +# ID-COLLISION: yaml2obj: error: the ID (1) of abbrev table with index 1 has been used by abbrev table with index 0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_abbrev: + - ID: 1 + - ID: 1 + debug_info: + - Version: 4 + AbbrOffset: 0x00 + Entries: + - AbbrCode: 1 + Values: + - Value: 0x1234 diff --git a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml --- a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml +++ b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml @@ -279,6 +279,7 @@ - Length: 0x5678 ## Test DWARFv4 Version: 4 + AbbrevTableID: 0 AbbrOffset: 0x5678 AddrSize: 4 Entries: @@ -886,7 +887,7 @@ ## RUN: not yaml2obj --docnum=16 %s 2>&1 | FileCheck %s --check-prefix=NO-ABBREV -# NO-ABBREV: yaml2obj: error: non-empty compilation unit should have an associated abbrev table +# NO-ABBREV: yaml2obj: error: cannot find abbrev table whose ID is 0 for compilation unit with index 0 --- !ELF FileHeader: @@ -902,3 +903,101 @@ - AbbrCode: 1 Values: - Value: 0x1234 + +## o) Test that yaml2obj is able to generate compilation units according to the +## associated abbrev table that is referenced by the 'AbbrevTableID'. + +# RUN: yaml2obj --docnum=17 %s -o %t17.o +# RUN: llvm-readelf --hex-dump=.debug_info %t17.o | FileCheck %s --check-prefix=MULTI-TABLES + +# MULTI-TABLES: Hex dump of section '.debug_info': +# MULTI-TABLES-NEXT: 0x00000000 0c000000 04000800 00000801 34120000 ............4... +## ^------- unit_length (4-byte) +## ^--- version (2-byte) +## ^-------- debug_abbrev_offset (4-byte) +## ^- address_size (1-byte) +## ^- abbrev_code (ULEB128) 0x01 +## ^------- Form: DW_FORM_data4 (4-byte) 0x1234 +# MULTI-TABLES-NEXT: 0x00000010 0c000000 04000800 00000801 21430000 ............!C.. +## ^------- unit_length (4-byte) +## ^--- version (2-byte) +## ^-------- debug_abbrev_offset (4-byte) +## ^- address_size (1-byte) +## ^- abbrev_code (ULEB128) 0x01 +## ^------- Form: DW_FORM_data4 (4-byte) 0x4321 +# MULTI-TABLES-NEXT: 0x00000020 10000000 04000000 00000801 78560000 ............xV.. +## ^------- unit_length (4-byte) +## ^--- version (2-byte) +## ^-------- debug_abbrev_offset (4-byte) +## ^- address_size (1-byte) +## ^- abbrev_code (ULEB128) 0x01 +## ^------- Form: DW_FORM_addr (8-byte) 0x5678 +# MULTI-TABLES-NEXT: 0x00000030 00000000 0b000000 04001000 00000801 ................ +## -------- +## ^------- unit_length (4-byte) +## ^--- version (2-byte) +## ^-------- debug_abbrev_offset (4-byte) +## ^- address_size (1-byte) +## ^- abbrev_code (ULEB128) 0x01 +# MULTI-TABLES-NEXT: 0x00000040 e58e02 ... +## ^----- Form: DW_FORM_udata (ULEB128) 0x8765 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC +DWARF: + debug_abbrev: + - Table: + - Code: 1 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - ID: 2 + Table: + - Code: 1 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_data4 + - ID: 1 + Table: + - Code: 1 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_udata + debug_info: + - Version: 4 + AbbrevTableID: 2 + AbbrOffset: 8 + Entries: + - AbbrCode: 1 + Values: + - Value: 0x1234 + - Version: 4 + AbbrevTableID: 2 + AbbrOffset: 8 + Entries: + - AbbrCode: 1 + Values: + - Value: 0x4321 + - Version: 4 + AbbrevTableID: 0 + AbbrOffset: 0 + Entries: + - AbbrCode: 1 + Values: + - Value: 0x5678 + - Version: 4 + AbbrevTableID: 1 + AbbrOffset: 16 + Entries: + - AbbrCode: 1 + Values: + - Value: 0x8765 diff --git a/llvm/tools/obj2yaml/dwarf2yaml.cpp b/llvm/tools/obj2yaml/dwarf2yaml.cpp --- a/llvm/tools/obj2yaml/dwarf2yaml.cpp +++ b/llvm/tools/obj2yaml/dwarf2yaml.cpp @@ -23,6 +23,7 @@ void dumpDebugAbbrev(DWARFContext &DCtx, DWARFYAML::Data &Y) { auto AbbrevSetPtr = DCtx.getDebugAbbrev(); if (AbbrevSetPtr) { + uint64_t AbbrevTableID = 0; for (auto AbbrvDeclSet : *AbbrevSetPtr) { Y.DebugAbbrev.emplace_back(); for (auto AbbrvDecl : AbbrvDeclSet.second) { @@ -39,6 +40,7 @@ AttAbrv.Value = Attribute.getImplicitConstValue(); Abbrv.Attributes.push_back(AttAbrv); } + Y.DebugAbbrev.back().ID = AbbrevTableID++; Y.DebugAbbrev.back().Table.push_back(Abbrv); } } @@ -172,6 +174,14 @@ NewUnit.Version = CU->getVersion(); if (NewUnit.Version >= 5) NewUnit.Type = (dwarf::UnitType)CU->getUnitType(); + const DWARFDebugAbbrev *DebugAbbrev = DCtx.getDebugAbbrev(); + NewUnit.AbbrevTableID = std::distance( + DebugAbbrev->begin(), + std::find_if( + DebugAbbrev->begin(), DebugAbbrev->end(), + [&](const std::pair &P) { + return P.first == CU->getAbbreviations()->getOffset(); + })); NewUnit.AbbrOffset = CU->getAbbreviations()->getOffset(); NewUnit.AddrSize = CU->getAddressByteSize(); for (auto DIE : CU->dies()) { diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp --- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp @@ -2487,6 +2487,7 @@ - Value: 0x0000000000000000 - Length: 16 Version: 4 + AbbrevTableID: 0 AbbrOffset: 0 AddrSize: 8 Entries: