[llvm] c9cbe69 - [dsymutil] Track uncloned references in the DIEInfo.

Jonas Devlieghere via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 20 12:53:30 PST 2022


Author: Jonas Devlieghere
Date: 2022-12-20T12:53:17-08:00
New Revision: c9cbe6937b1fe797f805648216257ae88bde4ad7

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

LOG: [dsymutil] Track uncloned references in the DIEInfo.

To improve deduplication across CUs within a single object file,
2b747241a6a0 changed the way we track ODR canonical candidates. The
result is that some assumptions no longer hold. Because of the
aforementioned change, the following condition

  assert(Ref > InputDIE.getOffset());

in DWARFLinker::DIECloner::cloneDieReferenceAttribute is no longer an
invariant. An example of a situation where this assertion no longer
holds is when we have decided to replace a backward reference in the
current CU with a forward reference in a subsequent CU. The ODR
canonical DIE hasn't been emitted yet, but the references DIE has an
offset smaller than the current DIE. The assertion is only true if the
referenced DIE was the ODR canonical DIE, which is no longer guaranteed
to be part of the same CU.

Big thanks to Alexey for putting a test together.

Differential revision: https://reviews.llvm.org/D138176

Added: 
    llvm/test/tools/dsymutil/odr-two-units-in-single-file.test

Modified: 
    llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
    llvm/lib/DWARFLinker/DWARFLinker.cpp
    llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h b/llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
index 31b50c0c6a0ce..517cab8a9c119 100644
--- a/llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
+++ b/llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
@@ -78,6 +78,9 @@ class CompileUnit {
 
     /// Is ODR marking done?
     bool ODRMarkingDone : 1;
+
+    /// Is this a reference to a DIE that hasn't been cloned yet?
+    bool UnclonedReference : 1;
   };
 
   CompileUnit(DWARFUnit &OrigUnit, unsigned ID, bool CanUseODR,

diff  --git a/llvm/lib/DWARFLinker/DWARFLinker.cpp b/llvm/lib/DWARFLinker/DWARFLinker.cpp
index ee70690476b33..6096ffc5ad5f9 100644
--- a/llvm/lib/DWARFLinker/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/DWARFLinker.cpp
@@ -935,9 +935,9 @@ unsigned DWARFLinker::DIECloner::cloneDieReferenceAttribute(
   }
 
   if (!RefInfo.Clone) {
-    assert(Ref > InputDIE.getOffset());
     // We haven't cloned this DIE yet. Just create an empty one and
     // store it. It'll get really cloned when we process it.
+    RefInfo.UnclonedReference = true;
     RefInfo.Clone = DIE::get(DIEAlloc, dwarf::Tag(RefDie.getTag()));
   }
   NewRefDie = RefInfo.Clone;
@@ -950,8 +950,8 @@ unsigned DWARFLinker::DIECloner::cloneDieReferenceAttribute(
     // FIXME: we should be able to design DIEEntry reliance on
     // DwarfDebug away.
     uint64_t Attr;
-    if (Ref < InputDIE.getOffset()) {
-      // We must have already cloned that DIE.
+    if (Ref < InputDIE.getOffset() && !RefInfo.UnclonedReference) {
+      // We have already cloned that DIE.
       uint32_t NewRefOffset =
           RefUnit->getStartOffset() + NewRefDie->getOffset();
       Attr = NewRefOffset;

diff  --git a/llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp b/llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp
index 77d914aec79ab..d8bac503fe65e 100644
--- a/llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp
+++ b/llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp
@@ -94,8 +94,10 @@ void CompileUnit::fixupForwardReferences() {
       assert(Ctxt->getCanonicalDIEOffset() &&
              "Canonical die offset is not set");
       Attr.set(Ctxt->getCanonicalDIEOffset());
-    } else
+    } else {
+      assert(RefDie->getOffset() && "Referenced die offset is not set");
       Attr.set(RefDie->getOffset() + RefUnit->getStartOffset());
+    }
   }
 }
 

diff  --git a/llvm/test/tools/dsymutil/odr-two-units-in-single-file.test b/llvm/test/tools/dsymutil/odr-two-units-in-single-file.test
new file mode 100644
index 0000000000000..535b9e6ad7ebf
--- /dev/null
+++ b/llvm/test/tools/dsymutil/odr-two-units-in-single-file.test
@@ -0,0 +1,199 @@
+# RUN: yaml2obj %s -o %t.o
+# RUN: echo '---' > %t2.map
+# RUN: echo "triple:          'x86_64-apple-darwin'" >> %t2.map
+# RUN: echo 'objects:'  >> %t2.map
+# RUN: echo " -  filename: '%t.o'" >> %t2.map
+# RUN: echo '    symbols:' >> %t2.map
+# RUN: echo '      - { sym: __Z3foov, objAddr: 0x0, binAddr: 0x10000, size: 0x10 }' >> %t2.map
+# RUN: echo '...' >> %t2.map
+# RUN: dsymutil -y -j 16 %t2.map -f -o - | llvm-dwarfdump -a - | FileCheck %s
+
+# CHECK: file format Mach-O 64-bit x86-64
+# CHECK: .debug_info contents:
+# CHECK: Compile Unit:
+# CHECK: DW_TAG_compile_unit
+# CHECK-NOT: DW_TAG_class_type
+# CHECK: Compile Unit:
+# CHECK: DW_TAG_compile_unit
+# CHECK: DW_TAG_class_type
+# CHECK: NULL
+
+
+--- !mach-o
+FileHeader:
+  magic:      0xFEEDFACF
+  cputype:    0x01000007
+  cpusubtype: 0x00000003
+  filetype:   0x00000001
+  ncmds:      2
+  sizeofcmds: 376
+  flags:      0x00002000
+  reserved:   0x00000000
+LoadCommands:
+  - cmd:      LC_SEGMENT_64
+    cmdsize:  232
+    segname:  ''
+    vmaddr:   0x00
+    vmsize:   0x300
+    fileoff:  0x300
+    filesize: 0x300
+    maxprot:  7
+    initprot: 7
+    nsects:   2
+    flags:    0
+    Sections:
+      - sectname:  __debug_abbrev
+        segname:   __DWARF
+        addr:      0x000000000000000F
+        size:      0x4a
+        offset:    0x00000380
+        align:     0
+        reloff:    0x00000000
+        nreloc:    0
+        flags:     0x02000000
+        reserved1: 0x00000000
+        reserved2: 0x00000000
+        reserved3: 0x00000000
+      - sectname:  __debug_info
+        segname:   __DWARF
+        addr:      0x000000000000100
+        size:      0x6c
+        offset:    0x00000410
+        align:     0
+        reloff:    0x00000600
+        nreloc:    1
+        flags:     0x02000000
+        reserved1: 0x00000000
+        reserved2: 0x00000000
+        reserved3: 0x00000000
+        relocations:
+          - address:         0x1FC
+            symbolnum:       1
+            pcrel:           true
+            length:          3
+            extern:          true
+            type:            0
+            scattered:       false
+            value:           0
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          0x700
+    nsyms:           2
+    stroff:          0x720
+    strsize:         10
+LinkEditData:
+  NameList:
+    - n_strx:          1
+      n_type:          0x0F
+      n_sect:          1
+      n_desc:          0
+      n_value:         0
+    - n_strx:          1
+      n_type:          0x0F
+      n_sect:          1
+      n_desc:          0
+      n_value:         0
+  StringTable:
+    - ''
+    - '__Z3foov'
+    - ''
+DWARF:
+  debug_abbrev:
+    - Table:
+      - Tag:      DW_TAG_compile_unit
+        Children: DW_CHILDREN_yes
+        Attributes:
+          - Attribute: DW_AT_producer
+            Form:      DW_FORM_string
+          - Attribute: DW_AT_language
+            Form:      DW_FORM_data2
+          - Attribute: DW_AT_name
+            Form:      DW_FORM_string
+      - Tag:      DW_TAG_class_type
+        Children: DW_CHILDREN_no
+        Attributes:
+          - Attribute: DW_AT_name
+            Form:      DW_FORM_string
+      - Tag:      DW_TAG_variable
+        Children: DW_CHILDREN_no
+        Attributes:
+          - Attribute: DW_AT_name
+            Form:      DW_FORM_string
+          - Attribute: DW_AT_const_value
+            Form:      DW_FORM_data4
+          - Attribute: DW_AT_type
+            Form:      DW_FORM_ref4
+      - Tag:      DW_TAG_pointer_type
+        Children: DW_CHILDREN_no
+        Attributes:
+          - Attribute: DW_AT_type
+            Form:      DW_FORM_ref4
+    - Table:
+      - Tag:      DW_TAG_compile_unit
+        Children: DW_CHILDREN_yes
+        Attributes:
+          - Attribute: DW_AT_producer
+            Form:      DW_FORM_string
+          - Attribute: DW_AT_language
+            Form:      DW_FORM_data2
+          - Attribute: DW_AT_name
+            Form:      DW_FORM_string
+      - Tag:      DW_TAG_class_type
+        Children: DW_CHILDREN_no
+        Attributes:
+          - Attribute: DW_AT_name
+            Form:      DW_FORM_string
+      - Tag:      DW_TAG_variable
+        Children: DW_CHILDREN_no
+        Attributes:
+          - Attribute: DW_AT_name
+            Form:      DW_FORM_string
+          - Attribute: DW_AT_const_value
+            Form:      DW_FORM_data4
+          - Attribute: DW_AT_type
+            Form:      DW_FORM_ref_addr
+      - Tag:      DW_TAG_pointer_type
+        Children: DW_CHILDREN_no
+        Attributes:
+          - Attribute: DW_AT_type
+            Form:      DW_FORM_ref4
+  debug_info:
+    - Version: 4
+      Entries:
+        - AbbrCode: 1
+          Values:
+            - CStr: by_hand
+            - Value:  0x04
+            - CStr: CU1
+        - AbbrCode: 2
+          Values:
+            - CStr: class1
+        - AbbrCode: 4
+          Values:
+            - Value:  0x1a
+        - AbbrCode: 3
+          Values:
+            - CStr: var1
+            - Value:  0x00000000
+            - Value:  0x00000058
+        - AbbrCode: 0
+    - Version: 4
+      Entries:
+        - AbbrCode: 1
+          Values:
+            - CStr: by_hand
+            - Value:  0x04
+            - CStr: CU2
+        - AbbrCode: 2
+          Values:
+            - CStr: class1
+        - AbbrCode: 4
+          Values:
+            - Value:  0x1a
+        - AbbrCode: 3
+          Values:
+            - CStr: var2
+            - Value:  0x00000000
+            - Value:  0x00000022
+        - AbbrCode: 0
+...


        


More information about the llvm-commits mailing list