From 0e9595e648f9982694e5b84b5f63830308a591ed Mon Sep 17 00:00:00 2001 From: Igor kehrazy Date: Sun, 21 Sep 2025 10:14:13 +0300 Subject: [PATCH] Support -Zembed-source in debuginfo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - honour the session DWARF version, enabling v5 when embed-source is requested and plumb the flag through the debug context - attach embedded source bytes to line table FileInfo records alongside existing MD5 hashes - stop excluding rustc’s embed-source-dwarf run-make test so CG_CLIF exercises the feature --- scripts/test_rustc_tests.sh | 1 - src/debuginfo/line_info.rs | 50 +++++++++++++++++++++---------------- src/debuginfo/mod.rs | 28 +++++++++++++-------- 3 files changed, 47 insertions(+), 32 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 1a65d7020..5e54acb3a 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -60,7 +60,6 @@ rm tests/ui/asm/global-asm-mono-sym-fn.rs # same rm tests/ui/asm/naked-asm-mono-sym-fn.rs # same rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported rm tests/ui/simd/simd-bitmask-notpow2.rs # non-pow-of-2 simd vector sizes -rm -r tests/run-make/embed-source-dwarf # embedding sources in debuginfo rm -r tests/run-make/used-proc-macro # used(linker) isn't supported yet rm tests/ui/linking/no-gc-encapsulation-symbols.rs # same rm tests/ui/attributes/fn-align-dyn.rs # per-function alignment not supported diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs index fa7b39c83..6fe22f5c6 100644 --- a/src/debuginfo/line_info.rs +++ b/src/debuginfo/line_info.rs @@ -6,9 +6,7 @@ use std::path::{Component, Path}; use cranelift_codegen::MachSrcLoc; use cranelift_codegen::binemit::CodeOffset; use gimli::write::{AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable}; -use rustc_span::{ - FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm, hygiene, -}; +use rustc_span::{FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHashAlgorithm, hygiene}; use crate::debuginfo::FunctionDebugContext; use crate::debuginfo::emit::address_for_func; @@ -44,21 +42,27 @@ fn osstr_as_utf8_bytes(path: &OsStr) -> &[u8] { } } -const MD5_LEN: usize = 16; - -fn make_file_info(hash: SourceFileHash) -> Option { - if hash.kind == SourceFileHashAlgorithm::Md5 { - let mut buf = [0u8; MD5_LEN]; - buf.copy_from_slice(hash.hash_bytes()); - Some(FileInfo { - timestamp: 0, - size: 0, - md5: buf, - source: None, // FIXME implement -Zembed-source - }) - } else { - None +fn make_file_info(source_file: &SourceFile, embed_source: bool) -> Option { + let has_md5 = source_file.src_hash.kind == SourceFileHashAlgorithm::Md5; + let has_source = embed_source && source_file.src.is_some(); + + if !has_md5 && !has_source { + return None; + } + + let mut info = FileInfo::default(); + + if has_md5 { + info.md5.copy_from_slice(source_file.src_hash.hash_bytes()); } + + if embed_source { + if let Some(src) = &source_file.src { + info.source = Some(LineString::String(src.as_bytes().to_vec())); + } + } + + Some(info) } impl DebugContext { @@ -105,15 +109,19 @@ impl DebugContext { let file_name = LineString::new(file_name, line_program.encoding(), line_strings); - let info = make_file_info(source_file.src_hash); + let info = make_file_info(source_file, self.embed_source); - line_program.file_has_md5 &= info.is_some(); + let has_md5 = source_file.src_hash.kind == SourceFileHashAlgorithm::Md5; + line_program.file_has_md5 &= has_md5; line_program.add_file(file_name, dir_id, info) } filename => { - let dir_id = line_program.default_directory(); + // For anonymous sources, create an empty directory instead of using the default + let empty_dir = LineString::new(b"", line_program.encoding(), line_strings); + let dir_id = line_program.add_directory(empty_dir); + let dummy_file_name = LineString::new( - filename.display(self.filename_display_preference).to_string().into_bytes(), + filename.prefer_remapped_unconditionally().to_string().into_bytes(), line_program.encoding(), line_strings, ); diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 05b0253ef..e552376e3 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -45,6 +45,7 @@ pub(crate) struct DebugContext { array_size_type: UnitEntryId, filename_display_preference: FileNameDisplayPreference, + embed_source: bool, } pub(crate) struct FunctionDebugContext { @@ -67,21 +68,24 @@ impl DebugContext { return None; } + let mut requested_dwarf_version = tcx.sess.dwarf_version(); + if tcx.sess.target.is_like_darwin && requested_dwarf_version > 4 { + // Apple’s shipped debuggers still expect DWARF <= 4 by default. + // Stay on v4 unless the user explicitly opts into a feature that + // only works with v5 (e.g. -Zembed-source). + if !tcx.sess.opts.unstable_opts.embed_source { + requested_dwarf_version = 4; + } + } + let encoding = Encoding { format: Format::Dwarf32, - // FIXME this should be configurable - // macOS doesn't seem to support DWARF > 3 - // 5 version is required for md5 file hash - version: if tcx.sess.target.is_like_darwin { - 3 - } else { - // FIXME change to version 5 once the gdb and lldb shipping with the latest debian - // support it. - 4 - }, + version: requested_dwarf_version as u16, address_size: isa.frontend_config().pointer_bytes(), }; + let embed_source = tcx.sess.opts.unstable_opts.embed_source && encoding.version >= 5; + let endian = match isa.endianness() { Endianness::Little => RunTimeEndian::Little, Endianness::Big => RunTimeEndian::Big, @@ -125,6 +129,9 @@ impl DebugContext { file_info, ); line_program.file_has_md5 = file_has_md5; + if embed_source { + line_program.file_has_source = true; + } dwarf.unit.line_program = line_program; @@ -169,6 +176,7 @@ impl DebugContext { namespace_map: DefIdMap::default(), array_size_type, filename_display_preference, + embed_source, }) }