1 use super::dump::{DwarfDumpSection, get_dwarfdump};
2 use super::obj::compile_cranelift;
3 use filecheck::{CheckerBuilder, NO_VARIABLES};
4 use std::fs::read;
5 use tempfile::NamedTempFile;
6 use test_programs_artifacts::*;
7 use wasmtime::{Result, format_err};
8 
check_wasm(wasm_path: &str, directives: &str) -> Result<()>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]
test_debug_dwarf_translate_dead_code() -> Result<()>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]
test_debug_dwarf_translate() -> Result<()>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]
test_debug_dwarf5_translate() -> Result<()>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]
test_debug_split_dwarf4_translate() -> Result<()>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]
test_debug_dwarf_translate_generated() -> Result<()>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]
test_debug_dwarf_translate_fission() -> Result<()>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