Higuoxing updated this revision to Diff 286780.
Higuoxing marked 11 inline comments as done.
Higuoxing added a comment.

Address comments.


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/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 for compilation unit with index 0
 
 --- !ELF
 FileHeader:
@@ -917,3 +920,102 @@
         - 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
+  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
+      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
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,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
+
+--- !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
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,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
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) 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::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
@@ -246,7 +246,8 @@
                         /*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 @@
   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 @@
 }
 
 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 @@
     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();
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) const;
+
+private:
+  mutable std::unordered_map<uint64_t, uint64_t> AbbrevTableID2Index;
 };
 
 } // end namespace DWARFYAML
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to