[llvm] f7ff0ac - [DWARFYAML] Add support for referencing different abbrev tables.

Xing GUO via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 20 20:44:56 PDT 2020


Author: Xing GUO
Date: 2020-08-21T11:44:25+08:00
New Revision: f7ff0ace96db9164dcde232c36cab6519ea4fce8

URL: https://github.com/llvm/llvm-project/commit/f7ff0ace96db9164dcde232c36cab6519ea4fce8
DIFF: https://github.com/llvm/llvm-project/commit/f7ff0ace96db9164dcde232c36cab6519ea4fce8.diff

LOG: [DWARFYAML] Add support for referencing different abbrev tables.

This patch adds support for referencing different abbrev tables. We use
'ID' to distinguish abbrev tables and use 'AbbrevTableID' to explicitly
assign an abbrev table to compilation units.

The syntax is:
```
debug_abbrev:
  - ID: 0
    Table:
      ...
  - ID: 1
    Table:
      ...
debug_info:
  - ...
    AbbrevTableID: 1 ## Reference the second abbrev table.
  - ...
    AbbrevTableID: 0 ## Reference the first abbrev table.
```

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D83116

Added: 
    

Modified: 
    llvm/include/llvm/ObjectYAML/DWARFYAML.h
    llvm/lib/ObjectYAML/DWARFEmitter.cpp
    llvm/lib/ObjectYAML/DWARFYAML.cpp
    llvm/lib/ObjectYAML/ELFEmitter.cpp
    llvm/test/ObjectYAML/MachO/DWARF-debug_abbrev.yaml
    llvm/test/ObjectYAML/MachO/DWARF-debug_info.yaml
    llvm/test/ObjectYAML/MachO/DWARF5-debug_info.yaml
    llvm/test/tools/yaml2obj/ELF/DWARF/debug-abbrev.yaml
    llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml
    llvm/tools/obj2yaml/dwarf2yaml.cpp
    llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ObjectYAML/DWARFYAML.h b/llvm/include/llvm/ObjectYAML/DWARFYAML.h
index a37cfd8460e3..005936d1a8ab 100644
--- 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 <cstdint>
+#include <unordered_map>
 #include <vector>
 
 namespace llvm {
@@ -40,6 +41,7 @@ struct Abbrev {
 };
 
 struct AbbrevTable {
+  Optional<uint64_t> ID;
   std::vector<Abbrev> Table;
 };
 
@@ -110,6 +112,7 @@ struct Unit {
   uint16_t Version;
   Optional<uint8_t> AddrSize;
   llvm::dwarf::UnitType Type; // Added in DWARF 5
+  Optional<uint64_t> AbbrevTableID;
   yaml::Hex64 AbbrOffset;
   std::vector<Entry> Entries;
 };
@@ -228,6 +231,10 @@ struct Data {
   bool isEmpty() const;
 
   SetVector<StringRef> getNonEmptySectionNames() const;
+  Expected<uint64_t> getAbbrevTableIndexByID(uint64_t ID) const;
+
+private:
+  mutable std::unordered_map<uint64_t, uint64_t> AbbrevTableID2Index;
 };
 
 } // end namespace DWARFYAML

diff  --git a/llvm/lib/ObjectYAML/DWARFEmitter.cpp b/llvm/lib/ObjectYAML/DWARFEmitter.cpp
index 682969a8e9fd..c932337009e9 100644
--- a/llvm/lib/ObjectYAML/DWARFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DWARFEmitter.cpp
@@ -246,7 +246,8 @@ Error DWARFYAML::emitDebugGNUPubtypes(raw_ostream &OS, const Data &DI) {
                         /*IsGNUStyle=*/true);
 }
 
-static Expected<uint64_t> writeDIE(ArrayRef<DWARFYAML::AbbrevTable> AbbrevTable,
+static Expected<uint64_t> 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,15 @@ static Expected<uint64_t> writeDIE(ArrayRef<DWARFYAML::AbbrevTable> AbbrevTable,
   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");
-
-  ArrayRef<DWARFYAML::Abbrev> AbbrevDecls(AbbrevTable[0].Table);
+  Expected<uint64_t> AbbrevTableIndexOrErr =
+      DI.getAbbrevTableIndexByID(AbbrevTableID);
+  if (!AbbrevTableIndexOrErr)
+    return createStringError(errc::invalid_argument,
+                             toString(AbbrevTableIndexOrErr.takeError()) +
+                                 " for compilation unit with index " +
+                                 utostr(CUIndex));
+  ArrayRef<DWARFYAML::Abbrev> AbbrevDecls(
+      DI.DebugAbbrev[*AbbrevTableIndexOrErr].Table);
 
   if (AbbrCode > AbbrevDecls.size())
     return createStringError(
@@ -384,7 +388,8 @@ static Expected<uint64_t> writeDIE(ArrayRef<DWARFYAML::AbbrevTable> AbbrevTable,
 }
 
 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 +407,11 @@ Error DWARFYAML::emitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) {
     std::string EntryBuffer;
     raw_string_ostream EntryBufferOS(EntryBuffer);
 
+    uint64_t AbbrevTableID = Unit.AbbrevTableID.getValueOr(I);
     for (const DWARFYAML::Entry &Entry : Unit.Entries) {
-      if (Expected<uint64_t> EntryLength = writeDIE(
-              DI.DebugAbbrev, Params, Entry, EntryBufferOS, DI.IsLittleEndian))
+      if (Expected<uint64_t> 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
index 5c4fd53a8259..e1ebdfae55a1 100644
--- 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 @@ SetVector<StringRef> DWARFYAML::Data::getNonEmptySectionNames() const {
   return SecNames;
 }
 
+Expected<uint64_t> 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 %" PRIu64
+            " 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<DWARFYAML::Data>::mapping(IO &IO, DWARFYAML::Data &DWARF) {
@@ -80,6 +107,7 @@ void MappingTraits<DWARFYAML::Data>::mapping(IO &IO, DWARFYAML::Data &DWARF) {
 
 void MappingTraits<DWARFYAML::AbbrevTable>::mapping(
     IO &IO, DWARFYAML::AbbrevTable &AbbrevTable) {
+  IO.mapOptional("ID", AbbrevTable.ID);
   IO.mapOptional("Table", AbbrevTable.Table);
 }
 
@@ -153,6 +181,7 @@ void MappingTraits<DWARFYAML::Unit>::mapping(IO &IO, DWARFYAML::Unit &Unit) {
   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/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index b1adf03074a1..d9774c28ace3 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -944,7 +944,7 @@ static bool shouldEmitDWARF(DWARFYAML::Data &DWARF, StringRef Name) {
 
 template <class ELFT>
 Expected<uint64_t> emitDWARF(typename ELFT::Shdr &SHeader, StringRef Name,
-                             const DWARFYAML::Data &DWARF,
+                             DWARFYAML::Data &DWARF,
                              ContiguousBlobAccumulator &CBA) {
   // We are unable to predict the size of debug data, so we request to write 0
   // bytes. This should always return us an output stream unless CBA is already

diff  --git a/llvm/test/ObjectYAML/MachO/DWARF-debug_abbrev.yaml b/llvm/test/ObjectYAML/MachO/DWARF-debug_abbrev.yaml
index 607d6ebc6cfd..91af7bdf143e 100644
--- 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 @@ DWARF:
 #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
index 46bf5221baad..7683da771171 100644
--- a/llvm/test/ObjectYAML/MachO/DWARF-debug_info.yaml
+++ b/llvm/test/ObjectYAML/MachO/DWARF-debug_info.yaml
@@ -514,6 +514,7 @@ DWARF:
 #      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 @@ DWARF:
 #      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 @@ DWARF:
 # 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
+
+--- !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
index d63be6043d0a..d016b8c485ee 100644
--- a/llvm/test/ObjectYAML/MachO/DWARF5-debug_info.yaml
+++ b/llvm/test/ObjectYAML/MachO/DWARF5-debug_info.yaml
@@ -515,6 +515,7 @@ DWARF:
 # 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 @@ DWARF:
 # 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 @@ DWARF:
 # 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
index 82786db446bc..d199ac260c17 100644
--- a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-abbrev.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-abbrev.yaml
@@ -306,3 +306,28 @@ DWARF:
         - 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
index ac661dfc1903..80bb064e31b0 100644
--- a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml
@@ -206,11 +206,12 @@ DWARF:
             - Attribute: 0x01
               Form:      DW_FORM_addrx4         ## 0x2c
   debug_info:
-    - Length:     0x1234
-      Version:    5
-      UnitType:   DW_UT_type
-      AbbrOffset: 0x1234
-      AddrSize:   4
+    - Length:        0x1234
+      Version:       5
+      UnitType:      DW_UT_type
+      AbbrevTableID: 0
+      AbbrOffset:    0x1234
+      AddrSize:      4
       Entries:
         - AbbrCode: 1
           Values:
@@ -271,6 +272,7 @@ DWARF:
       Version:       5
       ## Test another unit type.
       UnitType:      DW_UT_compile
+      AbbrevTableID: 0
       AbbrOffset:    0x1234
       AddrSize:      4
       Entries:
@@ -279,6 +281,7 @@ DWARF:
     - Length:        0x5678
       ## Test DWARFv4
       Version:       4
+      AbbrevTableID: 0
       AbbrOffset:    0x5678
       AddrSize:      4
       Entries:
@@ -886,7 +889,7 @@ DWARF:
 
 ## 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:
@@ -903,11 +906,43 @@ DWARF:
           Values:
             - Value: 0x1234
 
-## n) Test that yaml2obj emits an error message when a compilation unit has values but there is no associated abbrev table.
+## o) Test that yaml2obj is able to generate compilation units according to the
+## associated abbrev table that is referenced by the 'AbbrevTableID'.
 
-## RUN: not yaml2obj --docnum=16 %s 2>&1 | FileCheck %s --check-prefix=NO-ABBREV
+# RUN: yaml2obj --docnum=17 %s -o %t17.o
+# RUN: llvm-readelf --hex-dump=.debug_info %t17.o | FileCheck %s --check-prefix=MULTI-TABLES
 
-# NO-ABBREV: yaml2obj: error: non-empty compilation unit should have an associated abbrev table
+#      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:
@@ -916,10 +951,56 @@ FileHeader:
   Type:    ET_EXEC
   Machine: EM_X86_64
 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
-      AbbrOffset: 0x00
+    - 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
index 6acce091ab9f..0f9794f1a403 100644
--- a/llvm/tools/obj2yaml/dwarf2yaml.cpp
+++ b/llvm/tools/obj2yaml/dwarf2yaml.cpp
@@ -23,6 +23,7 @@ using namespace llvm;
 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 @@ void dumpDebugAbbrev(DWARFContext &DCtx, DWARFYAML::Data &Y) {
             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 @@ void dumpDebugInfo(DWARFContext &DCtx, DWARFYAML::Data &Y) {
     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<uint64_t, DWARFAbbreviationDeclarationSet> &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
index f59b18ff3b9b..c08a0e15a337 100644
--- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
+++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
@@ -2487,6 +2487,7 @@ TEST(DWARFDebugInfo, TestDwarfVerifyCUDontShareLineTable) {
               - Value:           0x0000000000000000
       - Length:          16
         Version:         4
+        AbbrevTableID:   0
         AbbrOffset:      0
         AddrSize:        8
         Entries:


        


More information about the llvm-commits mailing list