[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