Repository: bytecodealliance/wasmtime
Pull request #9109 (2024-08-12 06:31:59)

Fix file and line in generated DWARF
We were using a string, but the DWARF standard specifies that: "The value of the DW_AT_decl_file attribute corresponds to a file number from the line number information table...".

Additionally, a typo meant we were overwriting the file attribute with the value that was meant to be used for a DW_AT_decl_line attribute.


Patch:
diff --git a/crates/cranelift/src/debug/transform/simulate.rs b/crates/cranelift/src/debug/transform/simulate.rs
index 84a629332..2e0875a97 100644
--- a/crates/cranelift/src/debug/transform/simulate.rs
+++ b/crates/cranelift/src/debug/transform/simulate.rs
@@ -37,7 +37,7 @@ fn generate_line_info(
     comp_dir_id: write::StringId,
     name_id: write::StringId,
     name: &str,
-) -> Result<write::LineProgram, Error> {
+) -> Result<(write::LineProgram, write::FileId), Error> {
     let out_comp_dir = write::LineString::StringRef(comp_dir_id);
     let out_comp_name = write::LineString::StringRef(name_id);
 
@@ -90,7 +90,7 @@ fn generate_line_info(
         out_program.end_sequence(end_addr);
     }
 
-    Ok(out_program)
+    Ok((out_program, file_index))
 }
 
 fn check_invalid_chars_in_name(s: &str) -> Option<&str> {
@@ -108,8 +108,8 @@ fn autogenerate_dwarf_wasm_path(di: &DebugInfoData) -> PathBuf {
         .module_name
         .and_then(check_invalid_chars_in_name)
         .map(|s| s.to_string())
-        .unwrap_or_else(|| format!("<gen-{}>", NEXT_ID.fetch_add(1, SeqCst)));
-    let path = format!("/<wasm-module>/{module_name}.wasm");
+        .unwrap_or_else(|| format!("<gen-{}>.wasm", NEXT_ID.fetch_add(1, SeqCst)));
+    let path = format!("/<wasm-module>/{module_name}");
     PathBuf::from(path)
 }
 
@@ -302,7 +302,7 @@ pub fn generate_simulated_dwarf(
         (&di.wasm_file, path)
     };
 
-    let (unit, root_id, name_id) = {
+    let (unit, root_id, file_id) = {
         let comp_dir_id = out_strings.add(assert_dwarf_str!(path
             .parent()
             .context("path dir")?
@@ -315,7 +315,7 @@ pub fn generate_simulated_dwarf(
             .context("path name encoding")?;
         let name_id = out_strings.add(assert_dwarf_str!(name));
 
-        let out_program = generate_line_info(
+        let (out_program, file_id) = generate_line_info(
             addr_tr,
             translated,
             out_encoding,
@@ -342,7 +342,7 @@ pub fn generate_simulated_dwarf(
             gimli::DW_AT_comp_dir,
             write::AttributeValue::StringRef(comp_dir_id),
         );
-        (unit, root_id, name_id)
+        (unit, root_id, file_id)
     };
 
     let mut module_wasm_types = PrimaryMap::new();
@@ -393,13 +393,13 @@ pub fn generate_simulated_dwarf(
 
         die.set(
             gimli::DW_AT_decl_file,
-            write::AttributeValue::StringRef(name_id),
+            write::AttributeValue::FileIndex(Some(file_id)),
         );
 
         let f_start = map.addresses[0].wasm;
         let wasm_offset = di.wasm_file.code_section_offset + f_start;
         die.set(
-            gimli::DW_AT_decl_file,
+            gimli::DW_AT_decl_line,
             write::AttributeValue::Udata(wasm_offset),
         );
 


Test patch:
diff --git a/tests/all/debug/translate.rs b/tests/all/debug/translate.rs
index 4e72dcd39..9eec15818 100644
--- a/tests/all/debug/translate.rs
+++ b/tests/all/debug/translate.rs
@@ -132,3 +132,26 @@ check:        DW_AT_decl_line	(10)
     "##,
     )
 }
+
+#[test]
+#[ignore]
+#[cfg(all(
+    any(target_os = "linux", target_os = "macos"),
+    target_pointer_width = "64"
+))]
+fn test_debug_dwarf_translate_generated() -> Result<()> {
+    check_wasm(
+        "tests/all/debug/testsuite/fraction-norm.wasm",
+        r##"
+check: DW_TAG_compile_unit
+check: DW_TAG_compile_unit
+check:   DW_AT_producer	("wasmtime")
+check:   DW_AT_name	("<gen-$(=\d+)>.wasm")
+check:   DW_AT_comp_dir	("/<wasm-module>")
+check:   DW_TAG_subprogram
+check:     DW_AT_name	("__wasm_call_ctors")
+check:     DW_AT_decl_file	("/<wasm-module>/<gen-$(=\d+)>.wasm")
+check:     DW_AT_decl_line	(124)
+    "##,
+    )
+}