[llvm] [DWARFLinker] Support MD5 checksums in the line table (PR #77151)

Jonas Devlieghere via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 5 16:55:18 PST 2024


https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/77151

>From f2580f0981681484b9b7c9c1d4f64e808a02599a Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Fri, 5 Jan 2024 14:25:17 -0800
Subject: [PATCH] [DWARFLinker] Support MD5 checksums in the line table

Add support to the DWARF linkers for emitting DWARF 5 MD5 checksum in
the line table.
---
 llvm/lib/DWARFLinker/DWARFStreamer.cpp        | 24 +++++++++++++------
 .../DebugLineSectionEmitter.h                 | 13 +++++++++-
 .../DWARFLinkerParallel/OutputSections.cpp    |  4 ++++
 llvm/lib/DWARFLinkerParallel/OutputSections.h |  2 ++
 .../ARM/dwarf5-dwarf4-combination-macho.test  | 12 +++++-----
 .../test/tools/dsymutil/ARM/dwarf5-macho.test |  9 +++----
 6 files changed, 46 insertions(+), 18 deletions(-)

diff --git a/llvm/lib/DWARFLinker/DWARFStreamer.cpp b/llvm/lib/DWARFLinker/DWARFStreamer.cpp
index faa91364ec9c36..3ec082f4ea0c24 100644
--- a/llvm/lib/DWARFLinker/DWARFStreamer.cpp
+++ b/llvm/lib/DWARFLinker/DWARFStreamer.cpp
@@ -859,10 +859,8 @@ void DwarfStreamer::emitLineTablePrologueV5IncludeAndFileTable(
   for (auto Include : P.IncludeDirectories)
     emitLineTableString(P, Include, DebugStrPool, DebugLineStrPool);
 
-  bool InlineSources = any_of(P.FileNames, [](auto &File) {
-    auto s = dwarf::toString(File.Source);
-    return s && !**s;
-  });
+  bool HasChecksums = P.ContentTypes.HasMD5;
+  bool HasInlineSources = P.ContentTypes.HasSource;
 
   if (P.FileNames.empty()) {
     // file_name_entry_format_count (ubyte).
@@ -870,7 +868,7 @@ void DwarfStreamer::emitLineTablePrologueV5IncludeAndFileTable(
     LineSectionSize += 1;
   } else {
     // file_name_entry_format_count (ubyte).
-    MS->emitInt8(2 + (InlineSources ? 1 : 0));
+    MS->emitInt8(2 + (HasChecksums ? 1 : 0) + (HasInlineSources ? 1 : 0));
     LineSectionSize += 1;
 
     // file_name_entry_format (sequence of ULEB128 pairs).
@@ -880,7 +878,13 @@ void DwarfStreamer::emitLineTablePrologueV5IncludeAndFileTable(
 
     LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_directory_index);
     LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_FORM_data1);
-    if (InlineSources) {
+
+    if (HasChecksums) {
+      LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_MD5);
+      LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_FORM_data16);
+    }
+
+    if (HasInlineSources) {
       LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_LLVM_source);
       LineSectionSize += MS->emitULEB128IntValue(StrForm);
     }
@@ -894,7 +898,13 @@ void DwarfStreamer::emitLineTablePrologueV5IncludeAndFileTable(
     emitLineTableString(P, File.Name, DebugStrPool, DebugLineStrPool);
     MS->emitInt8(File.DirIdx);
     LineSectionSize += 1;
-    if (InlineSources)
+    if (HasChecksums) {
+      MS->emitBinaryData(
+          StringRef(reinterpret_cast<const char *>(File.Checksum.data()),
+                    File.Checksum.size()));
+      LineSectionSize += File.Checksum.size();
+    }
+    if (HasInlineSources)
       emitLineTableString(P, File.Source, DebugStrPool, DebugLineStrPool);
   }
 }
diff --git a/llvm/lib/DWARFLinkerParallel/DebugLineSectionEmitter.h b/llvm/lib/DWARFLinkerParallel/DebugLineSectionEmitter.h
index fc7f8cbc4a8e7b..27c63fad712f13 100644
--- a/llvm/lib/DWARFLinkerParallel/DebugLineSectionEmitter.h
+++ b/llvm/lib/DWARFLinkerParallel/DebugLineSectionEmitter.h
@@ -197,7 +197,7 @@ class DebugLineSectionEmitter {
       Section.emitIntVal(0, 1);
     } else {
       // file_name_entry_format_count (ubyte).
-      Section.emitIntVal(2, 1);
+      Section.emitIntVal(2 + (P.ContentTypes.HasMD5 ? 1 : 0), 1);
 
       // file_name_entry_format (sequence of ULEB128 pairs).
       encodeULEB128(dwarf::DW_LNCT_path, Section.OS);
@@ -205,6 +205,11 @@ class DebugLineSectionEmitter {
 
       encodeULEB128(dwarf::DW_LNCT_directory_index, Section.OS);
       encodeULEB128(dwarf::DW_FORM_data1, Section.OS);
+
+      if (P.ContentTypes.HasMD5) {
+        encodeULEB128(dwarf::DW_LNCT_MD5, Section.OS);
+        encodeULEB128(dwarf::DW_FORM_data16, Section.OS);
+      }
     }
 
     // file_names_count (ULEB128).
@@ -222,6 +227,12 @@ class DebugLineSectionEmitter {
       // source file.
       Section.emitString(File.Name.getForm(), *FileNameStr);
       Section.emitIntVal(File.DirIdx, 1);
+
+      if (P.ContentTypes.HasMD5) {
+        Section.emitBinaryData(
+            StringRef(reinterpret_cast<const char *>(File.Checksum.data()),
+                      File.Checksum.size()));
+      }
     }
   }
 
diff --git a/llvm/lib/DWARFLinkerParallel/OutputSections.cpp b/llvm/lib/DWARFLinkerParallel/OutputSections.cpp
index 9c3e3ebd220aaf..730ae0f83d7b27 100644
--- a/llvm/lib/DWARFLinkerParallel/OutputSections.cpp
+++ b/llvm/lib/DWARFLinkerParallel/OutputSections.cpp
@@ -227,6 +227,10 @@ void SectionDescriptor::emitIntVal(uint64_t Val, unsigned Size) {
   }
 }
 
+void SectionDescriptor::emitBinaryData(llvm::StringRef Data) {
+  OS.write(Data.data(), Data.size());
+}
+
 void SectionDescriptor::apply(uint64_t PatchOffset, dwarf::Form AttrForm,
                               uint64_t Val) {
   switch (AttrForm) {
diff --git a/llvm/lib/DWARFLinkerParallel/OutputSections.h b/llvm/lib/DWARFLinkerParallel/OutputSections.h
index f23b2efb869da8..0f394b0810ea9c 100644
--- a/llvm/lib/DWARFLinkerParallel/OutputSections.h
+++ b/llvm/lib/DWARFLinkerParallel/OutputSections.h
@@ -283,6 +283,8 @@ struct SectionDescriptor {
 
   void emitString(dwarf::Form StringForm, const char *StringVal);
 
+  void emitBinaryData(llvm::StringRef Data);
+
   /// Emit specified inplace string value into the current section contents.
   void emitInplaceString(StringRef String) {
     OS << GlobalData.translateString(String);
diff --git a/llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test b/llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test
index 0199bf28681bc4..d5b78bd1487e18 100644
--- a/llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test
+++ b/llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test
@@ -73,7 +73,7 @@ CHECK-NEXT:  DW_AT_low_pc [DW_FORM_addrx]     (indexed (00000000) address = 0x[[
 CHECK: DW_AT_linkage_name [DW_FORM_strx]       (indexed (00000005) string = "_Z4foo2i")
 CHECK: DW_AT_name [DW_FORM_strx]       (indexed (00000006) string = "foo2")
 CHECK:     DW_TAG_formal_parameter
-CHECK-NEXT:                   DW_AT_location [DW_FORM_sec_offset]   (0x[[LOCLIST_OFFSET:[0-9a-f]+]]: 
+CHECK-NEXT:                   DW_AT_location [DW_FORM_sec_offset]   (0x[[LOCLIST_OFFSET:[0-9a-f]+]]:
 CHECK-NEXT:                      [0x[[#%.16x,LOCLIST_PAIR_START:]], 0x[[#%.16x,LOCLIST_PAIR_END:]]): [[LOCLIST_EXPR:.*]]
 CHECK-NEXT:                      [0x[[#%.16x,LOCLIST_PAIR_START2:]], 0x[[#%.16x,LOCLIST_PAIR_END2:]]): [[LOCLIST_EXPR2:.*]])
 CHECK: DW_AT_name [DW_FORM_strx]     (indexed (00000007) string = "a")
@@ -93,7 +93,7 @@ CHECK-NEXT:                DW_AT_low_pc [DW_FORM_addr]     (0x[[#%.16x,LOC_LOWPC
 CHECK: DW_AT_linkage_name [DW_FORM_strp]       ( .debug_str[0x000000e6] = "_Z3bari")
 CHECK: DW_AT_name [DW_FORM_strp]       ( .debug_str[0x000000ee] = "bar")
 CHECK:     DW_TAG_formal_parameter
-CHECK-NEXT:                  DW_AT_location [DW_FORM_sec_offset]   (0x[[LOC_OFFSET:[0-9a-f]+]]: 
+CHECK-NEXT:                  DW_AT_location [DW_FORM_sec_offset]   (0x[[LOC_OFFSET:[0-9a-f]+]]:
 CHECK-NEXT:                     [0x[[#%.16x,LOC_PAIR_START:]], 0x[[#%.16x,LOC_PAIR_END:]]): [[LOC_EXPR:.*]]
 CHECK-NEXT:                     [0x[[#%.16x,LOC_PAIR_START2:]], 0x[[#%.16x,LOC_PAIR_END2:]]): [[LOC_EXPR2:.*]])
 CHECK: DW_AT_name [DW_FORM_strp]     ( .debug_str[0x000000f2] = "x")
@@ -105,7 +105,7 @@ CHECK-NEXT:            (0x[[#sub(LOC_PAIR_START2,LOC_LOWPC)]], 0x[[#sub(LOC_PAIR
 
 CHECK: .debug_loclists contents:
 CHECK-NEXT: 0x00000000: locations list header: length = 0x00000018, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
-CHECK-NEXT: 0x[[LOCLIST_OFFSET]]: 
+CHECK-NEXT: 0x[[LOCLIST_OFFSET]]:
 CHECK-NEXT:            DW_LLE_base_addressx   (0x0000000000000000)
 CHECK-NEXT:            DW_LLE_offset_pair     (0x[[#sub(LOCLIST_PAIR_START,LOCLIST_LOWPC)]], 0x[[#sub(LOCLIST_PAIR_END,LOCLIST_LOWPC)]])
 CHECK-NEXT:            DW_LLE_offset_pair     (0x[[#sub(LOCLIST_PAIR_START2,LOCLIST_LOWPC)]], 0x[[#sub(LOCLIST_PAIR_END2,LOCLIST_LOWPC)]])
@@ -114,12 +114,12 @@ CHECK-NEXT:            DW_LLE_end_of_list     ()
 CHECK: .debug_line contents:
 CHECK-NEXT: debug_line[0x00000000]
 CHECK-NEXT: Line table prologue:
-CHECK-NEXT:     total_length: 0x00000048
+CHECK-NEXT:     total_length: 0x0000005a
 CHECK-NEXT:           format: DWARF32
 CHECK-NEXT:          version: 5
 CHECK-NEXT:     address_size: 8
 CHECK-NEXT:  seg_select_size: 0
-CHECK-NEXT:  prologue_length: 0x00000025
+CHECK-NEXT:  prologue_length: 0x00000037
 CHECK-NEXT:  min_inst_length: 1
 CHECK-NEXT: max_ops_per_inst: 1
 CHECK-NEXT:  default_is_stmt: 1
@@ -143,7 +143,7 @@ CHECK-NEXT: file_names[  0]:
 CHECK-NEXT:            name:  .debug_line_str[0x00000029] = "a.cpp"
 CHECK-NEXT:       dir_index: 0
 
-CHECK: debug_line[0x0000004c]
+CHECK: debug_line[0x0000005e]
 CHECK-NEXT: Line table prologue:
 CHECK-NEXT:     total_length: 0x0000003b
 CHECK-NEXT:           format: DWARF32
diff --git a/llvm/test/tools/dsymutil/ARM/dwarf5-macho.test b/llvm/test/tools/dsymutil/ARM/dwarf5-macho.test
index 13409b2a07a31f..f6d42a18424cf5 100644
--- a/llvm/test/tools/dsymutil/ARM/dwarf5-macho.test
+++ b/llvm/test/tools/dsymutil/ARM/dwarf5-macho.test
@@ -49,13 +49,13 @@ CHECK-NEXT: DW_AT_addr_base [DW_FORM_sec_offset]      (0x00000008)
 CHECK:   DW_TAG_subprogram
 CHECK-NEXT:  DW_AT_low_pc [DW_FORM_addrx]     (indexed (00000000) address = 0x[[#%.16x,LOCLIST_LOWPC:]])
 CHECK:     DW_TAG_formal_parameter
-CHECK-NEXT:                   DW_AT_location [DW_FORM_sec_offset]   (0x[[LOC_OFFSET:[0-9a-f]+]]: 
+CHECK-NEXT:                   DW_AT_location [DW_FORM_sec_offset]   (0x[[LOC_OFFSET:[0-9a-f]+]]:
 CHECK-NEXT:                      [0x[[#%.16x,LOCLIST_PAIR_START:]], 0x[[#%.16x,LOCLIST_PAIR_END:]]): [[LOCLIST_EXPR:.*]]
 CHECK-NEXT:                      [0x[[#%.16x,LOCLIST_PAIR_START2:]], 0x[[#%.16x,LOCLIST_PAIR_END2:]]): [[LOCLIST_EXPR2:.*]])
 
 CHECK: .debug_loclists contents:
 CHECK-NEXT: 0x00000000: locations list header: length = 0x00000018, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
-CHECK-NEXT: 0x[[LOC_OFFSET]]: 
+CHECK-NEXT: 0x[[LOC_OFFSET]]:
 CHECK-NEXT:            DW_LLE_base_addressx   (0x0000000000000000)
 CHECK-NEXT:            DW_LLE_offset_pair     (0x[[#sub(LOCLIST_PAIR_START,LOCLIST_LOWPC)]], 0x[[#sub(LOCLIST_PAIR_END,LOCLIST_LOWPC)]])
 CHECK-NEXT:            DW_LLE_offset_pair     (0x[[#sub(LOCLIST_PAIR_START2,LOCLIST_LOWPC)]], 0x[[#sub(LOCLIST_PAIR_END2,LOCLIST_LOWPC)]])
@@ -64,12 +64,12 @@ CHECK-NEXT:            DW_LLE_end_of_list     ()
 CHECK: .debug_line contents:
 CHECK-NEXT: debug_line[0x00000000]
 CHECK-NEXT: Line table prologue:
-CHECK-NEXT:     total_length: 0x00000048
+CHECK-NEXT:     total_length: 0x0000005a
 CHECK-NEXT:           format: DWARF32
 CHECK-NEXT:          version: 5
 CHECK-NEXT:     address_size: 8
 CHECK-NEXT:  seg_select_size: 0
-CHECK-NEXT:  prologue_length: 0x00000025
+CHECK-NEXT:  prologue_length: 0x00000037
 CHECK-NEXT:  min_inst_length: 1
 CHECK-NEXT: max_ops_per_inst: 1
 CHECK-NEXT:  default_is_stmt: 1
@@ -92,6 +92,7 @@ CHECK-NEXT: include_directories[  0] =  .debug_line_str[0x00000000] = "/Users/sh
 CHECK-NEXT: file_names[  0]:
 CHECK-NEXT:            name:  .debug_line_str[0x00000029] = "a.cpp"
 CHECK-NEXT:       dir_index: 0
+CHECK-NEXT:    md5_checksum: 2675ab7ce3623b564cfd8a2906a462e5
 
 
 CHECK: .debug_str contents:



More information about the llvm-commits mailing list