1 use super::dump::{DwarfDumpSection, get_dwarfdump}; 2 use super::obj::compile_cranelift; 3 use anyhow::{Result, format_err}; 4 use filecheck::{CheckerBuilder, NO_VARIABLES}; 5 use std::fs::read; 6 use tempfile::NamedTempFile; 7 use test_programs_artifacts::*; 8 9 fn check_wasm(wasm_path: &str, directives: &str) -> Result<()> { 10 println!("check {wasm_path}"); 11 let wasm = read(wasm_path)?; 12 let obj_file = NamedTempFile::new()?; 13 let obj_path = obj_file.path().to_str().unwrap(); 14 compile_cranelift(&wasm, Some(wasm_path.as_ref()), None, obj_path)?; 15 let dump = get_dwarfdump(obj_path, DwarfDumpSection::DebugInfo)?; 16 let mut builder = CheckerBuilder::new(); 17 builder 18 .text(directives) 19 .map_err(|e| format_err!("unable to build checker: {e:?}"))?; 20 let checker = builder.finish(); 21 let check = checker 22 .explain(&dump, NO_VARIABLES) 23 .map_err(|e| format_err!("{e:?}"))?; 24 assert!(check.0, "didn't pass check {}", check.1); 25 Ok(()) 26 } 27 28 #[test] 29 #[ignore] 30 fn test_debug_dwarf_translate_dead_code() -> Result<()> { 31 check_wasm( 32 DWARF_DEAD_CODE, 33 r##" 34 check: DW_TAG_compile_unit 35 # We don't have "bar" function because it is dead code 36 not: DW_AT_name ("bar") 37 # We have "foo" function 38 check: DW_TAG_subprogram 39 check: DW_AT_name ("foo") 40 # We have "baz" function 41 # it was marked `noinline` so isn't dead code 42 check: DW_TAG_subprogram 43 check: DW_AT_name ("baz") 44 "##, 45 ) 46 } 47 48 #[test] 49 #[ignore] 50 fn test_debug_dwarf_translate() -> Result<()> { 51 check_wasm( 52 DWARF_FIB_WASM, 53 r##" 54 check: DW_TAG_compile_unit 55 # We have "fib" function 56 check: DW_TAG_subprogram 57 check: DW_AT_name ("fib") 58 # Accepts one parameter 59 check: DW_TAG_formal_parameter 60 check: DW_AT_name ("n") 61 check: DW_AT_decl_line (3) 62 # Has four locals: t, a, b, i 63 check: DW_TAG_variable 64 check: DW_AT_name ("t") 65 check: DW_AT_decl_line (4) 66 check: DW_TAG_variable 67 check: DW_AT_name ("a") 68 check: DW_TAG_variable 69 check: DW_AT_name ("b") 70 check: DW_TAG_variable 71 check: DW_AT_name ("i") 72 check: DW_AT_decl_line (5) 73 "##, 74 ) 75 } 76 77 #[test] 78 #[ignore] 79 fn test_debug_dwarf5_translate() -> Result<()> { 80 check_wasm( 81 DWARF_FIB_WASM_DWARF5, 82 r##" 83 check: DW_TAG_compile_unit 84 # We have "fib" function 85 check: DW_TAG_subprogram 86 check: DW_AT_name ("fib") 87 # Accepts one parameter 88 check: DW_TAG_formal_parameter 89 check: DW_AT_name ("n") 90 check: DW_AT_decl_line (3) 91 # Has four locals: t, a, b, i 92 check: DW_TAG_variable 93 check: DW_AT_name ("t") 94 check: DW_AT_decl_line (4) 95 check: DW_TAG_variable 96 check: DW_AT_name ("a") 97 check: DW_TAG_variable 98 check: DW_AT_name ("b") 99 check: DW_TAG_variable 100 check: DW_AT_name ("i") 101 check: DW_AT_decl_line (5) 102 "##, 103 ) 104 } 105 106 #[test] 107 #[ignore] 108 fn test_debug_split_dwarf4_translate() -> Result<()> { 109 check_wasm( 110 DWARF_FIB_WASM_SPLIT4, 111 r##" 112 check: DW_TAG_compile_unit 113 # We have "fib" function 114 check: DW_TAG_subprogram 115 check: DW_AT_name ("fib") 116 # Accepts one parameter 117 check: DW_TAG_formal_parameter 118 check: DW_AT_name ("n") 119 check: DW_AT_decl_line (4) 120 # Has four locals: t, a, b, i 121 check: DW_TAG_variable 122 check: DW_AT_name ("t") 123 check: DW_AT_decl_line (5) 124 check: DW_TAG_variable 125 check: DW_AT_name ("a") 126 check: DW_TAG_variable 127 check: DW_AT_name ("b") 128 check: DW_TAG_variable 129 check: DW_AT_name ("i") 130 check: DW_AT_decl_line (6) 131 "##, 132 ) 133 } 134 135 #[test] 136 #[ignore] 137 fn test_debug_dwarf_translate_generated() -> Result<()> { 138 check_wasm( 139 DWARF_FRACTION_NORM, 140 r##" 141 check: DW_TAG_compile_unit 142 check: DW_TAG_compile_unit 143 check: DW_AT_producer ("wasmtime") 144 check: DW_AT_name ("dwarf_fraction_norm.wasm") 145 check: DW_AT_comp_dir ("/<wasm-module>") 146 check: DW_TAG_subprogram 147 check: DW_AT_name ("__wasm_call_ctors") 148 check: DW_AT_decl_file ("/<wasm-module>/dwarf_fraction_norm.wasm") 149 check: DW_AT_decl_line ($(=\d+)) 150 "##, 151 ) 152 } 153 154 #[test] 155 #[ignore] 156 fn test_debug_dwarf_translate_fission() -> Result<()> { 157 check_wasm( 158 DWARF_FISSION, 159 r##" 160 check: DW_TAG_compile_unit 161 check: DW_AT_producer ("clang $(=.*)") 162 check: DW_AT_language (DW_LANG_C11) 163 check: DW_AT_name ("$(=.*)dwarf_fission.c") 164 check: DW_AT_ranges (0x$(=.+) 165 check: DW_AT_stmt_list (0x$(=.+)) 166 check: DW_AT_comp_dir ("$(=.*)artifacts") 167 "##, 168 ) 169 } 170