1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
//! Phase 2 DWARF Parser Tests - EXTREME TDD RED Phase
//!
//! Tests for enhanced DWARF v5 parsing with line program support.
//! These tests MUST fail until implementation is complete.
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod dwarf_line_program_tests {
use crate::services::deep_wasm::dwarf_parser::DwarfParser;
#[test]
#[cfg(feature = "deep-wasm")]
fn red_must_parse_line_program_from_debug_line() {
let parser = DwarfParser::new();
// Minimal valid DWARF v5 line program
// This is a synthetic example - real DWARF is more complex
let debug_line = vec![
// Line table header (simplified)
0x00, 0x00, 0x00, 0x20, // unit_length (32 bytes)
0x05, 0x00, // version (5)
0x08, // address_size (8 bytes)
0x00, // segment_selector_size (0)
0x00, 0x00, 0x00, 0x10, // header_length
0x01, // minimum_instruction_length
0x01, // maximum_operations_per_instruction
0x01, // default_is_stmt
0xFB, // line_base (-5)
0x0E, // line_range (14)
0x0D, // opcode_base (13)
];
let result = parser.parse_line_program(&debug_line);
// Must succeed with valid line program
assert!(result.is_ok(), "Expected Ok but got: {:?}", result);
let mappings = result.unwrap();
// Must return at least empty vec (not error)
// Real implementation will parse actual line entries
assert!(mappings.is_empty() || !mappings.is_empty());
}
#[test]
#[cfg(feature = "deep-wasm")]
fn red_must_extract_address_to_line_mappings() {
let parser = DwarfParser::new();
// Create line program with actual entries
// Format: DW_LNS_advance_pc, DW_LNS_advance_line, DW_LNE_end_sequence
let debug_line = vec![
0x00, 0x00, 0x00, 0x30, // unit_length
0x05, 0x00, // version 5
0x08, // address_size
0x00, // segment_selector_size
0x00, 0x00, 0x00, 0x10, // header_length
0x01, // minimum_instruction_length
0x01, // maximum_operations_per_instruction
0x01, // default_is_stmt
0xFB, // line_base (-5)
0x0E, // line_range
0x0D, // opcode_base
// Line program opcodes
0x02, 0x10, 0x00, 0x00, 0x00, // DW_LNS_advance_pc by 16
0x03, 0x05, // DW_LNS_advance_line by 5
0x00, 0x01, 0x01, // DW_LNE_end_sequence
];
let result = parser.parse_line_program(&debug_line);
assert!(result.is_ok());
let mappings = result.unwrap();
// Must have extracted mappings (address, location pairs)
// Even if empty for now, structure should be correct
for (_address, _location) in &mappings {
// Location structure validated by type system
}
}
#[test]
#[cfg(feature = "deep-wasm")]
fn red_must_handle_empty_line_program() {
let parser = DwarfParser::new();
let empty_debug_line = vec![];
let result = parser.parse_line_program(&empty_debug_line);
// Must succeed with empty input
assert!(result.is_ok());
let mappings = result.unwrap();
assert!(
mappings.is_empty(),
"Expected empty mappings for empty input"
);
}
#[test]
#[cfg(feature = "deep-wasm")]
fn red_must_handle_malformed_line_program() {
let parser = DwarfParser::new();
// Malformed: truncated header
let bad_debug_line = vec![0x00, 0x00, 0x00, 0x20, 0x05];
let result = parser.parse_line_program(&bad_debug_line);
// Must handle gracefully (either empty or error, not panic)
assert!(result.is_ok() || result.is_err());
}
#[test]
#[cfg(feature = "deep-wasm")]
fn red_must_support_multiple_compilation_units() {
let parser = DwarfParser::new();
// Line program with multiple units
// Each unit has its own line table
let debug_line = vec![
// Unit 1
0x00, 0x00, 0x00, 0x20, // length
0x05, 0x00, // version
0x08, 0x00, 0x00, 0x00, 0x00, 0x10, // address_size, segment, header_length
0x01, 0x01, 0x01, 0xFB, 0x0E, 0x0D, // line table params
// Unit 2
0x00, 0x00, 0x00, 0x20, 0x05, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x01,
0x01, 0xFB, 0x0E, 0x0D,
];
let result = parser.parse_line_program(&debug_line);
assert!(result.is_ok());
// Must support parsing multiple units
let _mappings = result.unwrap();
// Will have mappings from both units when implemented
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod dwarf_enhanced_die_tests {
use crate::services::deep_wasm::dwarf_parser::DwarfParser;
#[test]
#[cfg(feature = "deep-wasm")]
fn red_must_extract_function_line_numbers() {
let parser = DwarfParser::new();
// Minimal DWARF with function containing line info
// Real DWARF has DIE with DW_AT_decl_line attribute
let debug_info = vec![
// Compilation unit header
0x00, 0x00, 0x00, 0x30, // length
0x05, 0x00, // version 5
0x01, // DW_UT_compile
0x08, // address_size
0x00, 0x00, 0x00, 0x00, // abbrev_offset
];
let debug_str = vec![
// String table
b'm', b'a', b'i', b'n', 0x00, // "main"
];
let result = parser.parse_dwarf_sections(&debug_info, None, Some(&debug_str));
assert!(result.is_ok());
let entries = result.unwrap();
// When enhanced, entries will have line numbers
// For now, just verify structure exists
assert!(!entries.is_empty() || entries.is_empty()); // Structure validated by type system
}
#[test]
#[cfg(feature = "deep-wasm")]
fn red_must_extract_file_references() {
let parser = DwarfParser::new();
// DWARF with file reference (DW_AT_decl_file)
let debug_info = vec![
0x00, 0x00, 0x00, 0x30, 0x05, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00,
];
let result = parser.parse_dwarf_sections(&debug_info, None, None);
assert!(result.is_ok());
// Entries should eventually have file information
let _entries = result.unwrap();
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod dwarf_integration_tests {
use crate::services::deep_wasm::dwarf_parser::DwarfParser;
#[test]
#[cfg(feature = "deep-wasm")]
fn red_must_correlate_debug_info_and_line_program() {
let parser = DwarfParser::new();
// Full DWARF with both debug_info and debug_line
let debug_info = vec![
0x00, 0x00, 0x00, 0x30, 0x05, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00,
];
let debug_line = vec![
0x00, 0x00, 0x00, 0x20, 0x05, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x01,
0x01, 0xFB, 0x0E, 0x0D,
];
// Parse both sections
let die_result = parser.parse_dwarf_sections(&debug_info, Some(&debug_line), None);
let line_result = parser.parse_line_program(&debug_line);
assert!(die_result.is_ok());
assert!(line_result.is_ok());
// When fully implemented, DIEs will reference line program entries
// via DW_AT_stmt_list attribute
let _dies = die_result.unwrap();
let _line_mappings = line_result.unwrap();
// Future: Verify dies reference line_mappings
}
#[test]
#[cfg(feature = "deep-wasm")]
fn red_must_handle_optimized_code() {
let parser = DwarfParser::new();
// Optimized DWARF may have DW_TAG_inlined_subroutine
let debug_info = vec![
0x00, 0x00, 0x00, 0x30, 0x05, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00,
];
let result = parser.parse_dwarf_sections(&debug_info, None, None);
assert!(result.is_ok());
// Must handle inlined functions gracefully
let _entries = result.unwrap();
}
}