Higuoxing updated this revision to Diff 286755.
Higuoxing marked 10 inline comments as done.
Higuoxing added a comment.

Merge `DWARFYAML::Data` and `DWARFYAML::DWARFState`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83116/new/

https://reviews.llvm.org/D83116

Files:
  llvm/include/llvm/ObjectYAML/DWARFEmitter.h
  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

Index: llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
===================================================================
--- llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
+++ llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
@@ -2487,6 +2487,7 @@
               - Value:           0x0000000000000000
       - Length:          16
         Version:         4
+        AbbrevTableID:   0
         AbbrOffset:      0
         AddrSize:        8
         Entries:
Index: llvm/tools/obj2yaml/dwarf2yaml.cpp
===================================================================
--- llvm/tools/obj2yaml/dwarf2yaml.cpp
+++ 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<uint64_t, DWARFAbbreviationDeclarationSet> &P) {
+              return P.first == CU->getAbbreviations()->getOffset();
+            }));
     NewUnit.AbbrOffset = CU->getAbbreviations()->getOffset();
     NewUnit.AddrSize = CU->getAddressByteSize();
     for (auto DIE : CU->dies()) {
Index: llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml
===================================================================
--- llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml
+++ llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml
@@ -207,11 +207,12 @@
             - 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:
@@ -272,6 +273,7 @@
       Version:       5
       ## Test another unit type.
       UnitType:      DW_UT_compile
+      AbbrevTableID: 0
       AbbrOffset:    0x1234
       AddrSize:      4
       Entries:
@@ -280,6 +282,7 @@
     - Length:        0x5678
       ## Test DWARFv4
       Version:       4
+      AbbrevTableID: 0
       AbbrOffset:    0x5678
       AddrSize:      4
       Entries:
@@ -901,7 +904,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
 
 --- !ELF
 FileHeader:
Index: llvm/test/tools/yaml2obj/ELF/DWARF/debug-abbrev.yaml
===================================================================
--- llvm/test/tools/yaml2obj/ELF/DWARF/debug-abbrev.yaml
+++ llvm/test/tools/yaml2obj/ELF/DWARF/debug-abbrev.yaml
@@ -314,3 +314,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
Index: llvm/test/ObjectYAML/MachO/DWARF5-debug_info.yaml
===================================================================
--- llvm/test/ObjectYAML/MachO/DWARF5-debug_info.yaml
+++ 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:
Index: llvm/test/ObjectYAML/MachO/DWARF-debug_info.yaml
===================================================================
--- llvm/test/ObjectYAML/MachO/DWARF-debug_info.yaml
+++ 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,237 @@
 # 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: ...
+
+--- !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:
+    - 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:  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_info:
+    - Version:    4
+      AbbrOffset: 0x00
+      Entries:
+        - AbbrCode: 1
+          Values:
+            - Value: 0x1234
Index: llvm/test/ObjectYAML/MachO/DWARF-debug_abbrev.yaml
===================================================================
--- llvm/test/ObjectYAML/MachO/DWARF-debug_abbrev.yaml
+++ 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,70 @@
 #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
Index: llvm/lib/ObjectYAML/ELFEmitter.cpp
===================================================================
--- llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -939,7 +939,7 @@
 
 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
Index: llvm/lib/ObjectYAML/DWARFYAML.cpp
===================================================================
--- llvm/lib/ObjectYAML/DWARFYAML.cpp
+++ 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<uint64_t> DWARFYAML::Data::getAbbrevTableIndexByID(uint64_t ID) {
+  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::AbbrevTable>::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);
Index: llvm/lib/ObjectYAML/DWARFEmitter.cpp
===================================================================
--- llvm/lib/ObjectYAML/DWARFEmitter.cpp
+++ llvm/lib/ObjectYAML/DWARFEmitter.cpp
@@ -85,7 +85,7 @@
                                      OS, IsLittleEndian));
 }
 
-Error DWARFYAML::emitDebugStr(raw_ostream &OS, const DWARFYAML::Data &DI) {
+Error DWARFYAML::emitDebugStr(raw_ostream &OS, DWARFYAML::Data &DI) {
   for (auto Str : DI.DebugStrings) {
     OS.write(Str.data(), Str.size());
     OS.write('\0');
@@ -94,7 +94,7 @@
   return Error::success();
 }
 
-Error DWARFYAML::emitDebugAbbrev(raw_ostream &OS, const DWARFYAML::Data &DI) {
+Error DWARFYAML::emitDebugAbbrev(raw_ostream &OS, DWARFYAML::Data &DI) {
   uint64_t AbbrevCode = 0;
   for (const DWARFYAML::AbbrevTable &AbbrevTable : DI.DebugAbbrev) {
     for (const DWARFYAML::Abbrev &AbbrevDecl : AbbrevTable.Table) {
@@ -121,7 +121,7 @@
   return Error::success();
 }
 
-Error DWARFYAML::emitDebugAranges(raw_ostream &OS, const DWARFYAML::Data &DI) {
+Error DWARFYAML::emitDebugAranges(raw_ostream &OS, DWARFYAML::Data &DI) {
   assert(DI.DebugAranges && "unexpected emitDebugAranges() call");
   for (auto Range : *DI.DebugAranges) {
     uint8_t AddrSize;
@@ -170,7 +170,7 @@
   return Error::success();
 }
 
-Error DWARFYAML::emitDebugRanges(raw_ostream &OS, const DWARFYAML::Data &DI) {
+Error DWARFYAML::emitDebugRanges(raw_ostream &OS, DWARFYAML::Data &DI) {
   const size_t RangesOffset = OS.tell();
   uint64_t EntryIndex = 0;
   for (auto DebugRanges : DI.DebugRanges) {
@@ -224,29 +224,29 @@
   return Error::success();
 }
 
-Error DWARFYAML::emitDebugPubnames(raw_ostream &OS, const Data &DI) {
+Error DWARFYAML::emitDebugPubnames(raw_ostream &OS, DWARFYAML::Data &DI) {
   assert(DI.PubNames && "unexpected emitDebugPubnames() call");
   return emitPubSection(OS, *DI.PubNames, DI.IsLittleEndian);
 }
 
-Error DWARFYAML::emitDebugPubtypes(raw_ostream &OS, const Data &DI) {
+Error DWARFYAML::emitDebugPubtypes(raw_ostream &OS, DWARFYAML::Data &DI) {
   assert(DI.PubTypes && "unexpected emitDebugPubtypes() call");
   return emitPubSection(OS, *DI.PubTypes, DI.IsLittleEndian);
 }
 
-Error DWARFYAML::emitDebugGNUPubnames(raw_ostream &OS, const Data &DI) {
+Error DWARFYAML::emitDebugGNUPubnames(raw_ostream &OS, DWARFYAML::Data &DI) {
   assert(DI.GNUPubNames && "unexpected emitDebugGNUPubnames() call");
   return emitPubSection(OS, *DI.GNUPubNames, DI.IsLittleEndian,
                         /*IsGNUStyle=*/true);
 }
 
-Error DWARFYAML::emitDebugGNUPubtypes(raw_ostream &OS, const Data &DI) {
+Error DWARFYAML::emitDebugGNUPubtypes(raw_ostream &OS, DWARFYAML::Data &DI) {
   assert(DI.GNUPubTypes && "unexpected emitDebugGNUPubtypes() call");
   return emitPubSection(OS, *DI.GNUPubTypes, DI.IsLittleEndian,
                         /*IsGNUStyle=*/true);
 }
 
-static Expected<uint64_t> writeDIE(ArrayRef<DWARFYAML::AbbrevTable> AbbrevTable,
+static Expected<uint64_t> writeDIE(DWARFYAML::Data &DI, uint64_t AbbrevTableID,
                                    const dwarf::FormParams &Params,
                                    const DWARFYAML::Entry &Entry,
                                    raw_ostream &OS, bool IsLittleEndian) {
@@ -256,12 +256,12 @@
   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 AbbrevTableIndexOrErr.takeError();
+  ArrayRef<DWARFYAML::Abbrev> AbbrevDecls(
+      DI.DebugAbbrev[*AbbrevTableIndexOrErr].Table);
 
   if (AbbrCode > AbbrevDecls.size())
     return createStringError(
@@ -383,8 +383,9 @@
   return OS.tell() - EntryBegin;
 }
 
-Error DWARFYAML::emitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) {
-  for (const DWARFYAML::Unit &Unit : DI.CompileUnits) {
+Error DWARFYAML::emitDebugInfo(raw_ostream &OS, DWARFYAML::Data &DI) {
+  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 +403,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<uint64_t> EntryLength = writeDIE(
-              DI.DebugAbbrev, Params, Entry, EntryBufferOS, DI.IsLittleEndian))
+      if (Expected<uint64_t> EntryLength =
+              writeDIE(DI, AbbrevTableID, Params, Entry, EntryBufferOS,
+                       DI.IsLittleEndian))
         Length += *EntryLength;
       else
         return EntryLength.takeError();
@@ -440,7 +443,7 @@
   encodeULEB128(File.Length, OS);
 }
 
-Error DWARFYAML::emitDebugLine(raw_ostream &OS, const DWARFYAML::Data &DI) {
+Error DWARFYAML::emitDebugLine(raw_ostream &OS, DWARFYAML::Data &DI) {
   for (const auto &LineTable : DI.DebugLines) {
     writeInitialLength(LineTable.Format, LineTable.Length, OS,
                        DI.IsLittleEndian);
@@ -530,7 +533,7 @@
   return Error::success();
 }
 
-Error DWARFYAML::emitDebugAddr(raw_ostream &OS, const Data &DI) {
+Error DWARFYAML::emitDebugAddr(raw_ostream &OS, DWARFYAML::Data &DI) {
   for (const AddrTableEntry &TableEntry : DI.DebugAddr) {
     uint8_t AddrSize;
     if (TableEntry.AddrSize)
@@ -571,7 +574,7 @@
   return Error::success();
 }
 
-Error DWARFYAML::emitDebugStrOffsets(raw_ostream &OS, const Data &DI) {
+Error DWARFYAML::emitDebugStrOffsets(raw_ostream &OS, DWARFYAML::Data &DI) {
   assert(DI.DebugStrOffsets && "unexpected emitDebugStrOffsets() call");
   for (const DWARFYAML::StringOffsetsTable &Table : *DI.DebugStrOffsets) {
     uint64_t Length;
@@ -895,23 +898,23 @@
   return Error::success();
 }
 
-Error DWARFYAML::emitDebugRnglists(raw_ostream &OS, const Data &DI) {
+Error DWARFYAML::emitDebugRnglists(raw_ostream &OS, DWARFYAML::Data &DI) {
   assert(DI.DebugRnglists && "unexpected emitDebugRnglists() call");
   return writeDWARFLists<DWARFYAML::RnglistEntry>(
       OS, *DI.DebugRnglists, DI.IsLittleEndian, DI.Is64BitAddrSize);
 }
 
-Error DWARFYAML::emitDebugLoclists(raw_ostream &OS, const Data &DI) {
+Error DWARFYAML::emitDebugLoclists(raw_ostream &OS, DWARFYAML::Data &DI) {
   assert(DI.DebugLoclists && "unexpected emitDebugRnglists() call");
   return writeDWARFLists<DWARFYAML::LoclistEntry>(
       OS, *DI.DebugLoclists, DI.IsLittleEndian, DI.Is64BitAddrSize);
 }
 
-std::function<Error(raw_ostream &, const DWARFYAML::Data &)>
+std::function<Error(raw_ostream &, DWARFYAML::Data &)>
 DWARFYAML::getDWARFEmitterByName(StringRef SecName) {
   auto EmitFunc =
-      StringSwitch<
-          std::function<Error(raw_ostream &, const DWARFYAML::Data &)>>(SecName)
+      StringSwitch<std::function<Error(raw_ostream &, DWARFYAML::Data &)>>(
+          SecName)
           .Case("debug_abbrev", DWARFYAML::emitDebugAbbrev)
           .Case("debug_addr", DWARFYAML::emitDebugAddr)
           .Case("debug_aranges", DWARFYAML::emitDebugAranges)
@@ -926,7 +929,7 @@
           .Case("debug_rnglists", DWARFYAML::emitDebugRnglists)
           .Case("debug_str", DWARFYAML::emitDebugStr)
           .Case("debug_str_offsets", DWARFYAML::emitDebugStrOffsets)
-          .Default([&](raw_ostream &, const DWARFYAML::Data &) {
+          .Default([&](raw_ostream &, DWARFYAML::Data &) {
             return createStringError(errc::not_supported,
                                      SecName + " is not supported");
           });
@@ -935,7 +938,7 @@
 }
 
 static Error
-emitDebugSectionImpl(const DWARFYAML::Data &DI, StringRef Sec,
+emitDebugSectionImpl(DWARFYAML::Data &DI, StringRef Sec,
                      StringMap<std::unique_ptr<MemoryBuffer>> &OutputBuffers) {
   std::string Data;
   raw_string_ostream DebugInfoStream(Data);
Index: llvm/include/llvm/ObjectYAML/DWARFYAML.h
===================================================================
--- llvm/include/llvm/ObjectYAML/DWARFYAML.h
+++ 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 AbbrevTable {
+  Optional<uint64_t> ID;
   std::vector<Abbrev> Table;
 };
 
@@ -110,6 +112,7 @@
   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 @@
   bool isEmpty() const;
 
   SetVector<StringRef> getNonEmptySectionNames() const;
+  Expected<uint64_t> getAbbrevTableIndexByID(uint64_t ID);
+
+private:
+  std::unordered_map<uint64_t, uint64_t> AbbrevTableID2Index;
 };
 
 } // end namespace DWARFYAML
Index: llvm/include/llvm/ObjectYAML/DWARFEmitter.h
===================================================================
--- llvm/include/llvm/ObjectYAML/DWARFEmitter.h
+++ llvm/include/llvm/ObjectYAML/DWARFEmitter.h
@@ -28,23 +28,22 @@
 struct Data;
 struct PubSection;
 
-Error emitDebugAbbrev(raw_ostream &OS, const Data &DI);
-Error emitDebugStr(raw_ostream &OS, const Data &DI);
-
-Error emitDebugAranges(raw_ostream &OS, const Data &DI);
-Error emitDebugRanges(raw_ostream &OS, const Data &DI);
-Error emitDebugPubnames(raw_ostream &OS, const Data &DI);
-Error emitDebugPubtypes(raw_ostream &OS, const Data &DI);
-Error emitDebugGNUPubnames(raw_ostream &OS, const Data &DI);
-Error emitDebugGNUPubtypes(raw_ostream &OS, const Data &DI);
-Error emitDebugInfo(raw_ostream &OS, const Data &DI);
-Error emitDebugLine(raw_ostream &OS, const Data &DI);
-Error emitDebugAddr(raw_ostream &OS, const Data &DI);
-Error emitDebugStrOffsets(raw_ostream &OS, const Data &DI);
-Error emitDebugRnglists(raw_ostream &OS, const Data &DI);
-Error emitDebugLoclists(raw_ostream &OS, const Data &DI);
-
-std::function<Error(raw_ostream &, const Data &)>
+Error emitDebugAbbrev(raw_ostream &OS, Data &DI);
+Error emitDebugStr(raw_ostream &OS, Data &DI);
+Error emitDebugAranges(raw_ostream &OS, Data &DI);
+Error emitDebugRanges(raw_ostream &OS, Data &DI);
+Error emitDebugPubnames(raw_ostream &OS, Data &DI);
+Error emitDebugPubtypes(raw_ostream &OS, Data &DI);
+Error emitDebugGNUPubnames(raw_ostream &OS, Data &DI);
+Error emitDebugGNUPubtypes(raw_ostream &OS, Data &DI);
+Error emitDebugInfo(raw_ostream &OS, Data &DI);
+Error emitDebugLine(raw_ostream &OS, Data &DI);
+Error emitDebugAddr(raw_ostream &OS, Data &DI);
+Error emitDebugStrOffsets(raw_ostream &OS, Data &DI);
+Error emitDebugRnglists(raw_ostream &OS, Data &DI);
+Error emitDebugLoclists(raw_ostream &OS, Data &DI);
+
+std::function<Error(raw_ostream &, Data &)>
 getDWARFEmitterByName(StringRef SecName);
 Expected<StringMap<std::unique_ptr<MemoryBuffer>>>
 emitDebugSections(StringRef YAMLString,
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to