187c33c29SAlex Crichton use super::address_transform::AddressTransform;
2bd7b59daSPhilip Craig use crate::debug::Reader;
3*c4a38d67SPhilip Craig use gimli::write;
4*c4a38d67SPhilip Craig use wasmtime_environ::error::Error;
587c33c29SAlex Crichton 
clone_line_program( mut transform: write::ConvertLineProgram<'_, Reader<'_>>, addr_tr: &AddressTransform, ) -> Result<(write::LineProgram, Vec<write::FileId>), Error>6bd7b59daSPhilip Craig pub(crate) fn clone_line_program(
7*c4a38d67SPhilip Craig     mut transform: write::ConvertLineProgram<'_, Reader<'_>>,
887c33c29SAlex Crichton     addr_tr: &AddressTransform,
9*c4a38d67SPhilip Craig ) -> Result<(write::LineProgram, Vec<write::FileId>), Error> {
10*c4a38d67SPhilip Craig     while let Some(write::ConvertLineSequence {
11*c4a38d67SPhilip Craig         start,
12*c4a38d67SPhilip Craig         rows: saved_rows,
13*c4a38d67SPhilip Craig         ..
14*c4a38d67SPhilip Craig     }) = transform.read_sequence()?
1587c33c29SAlex Crichton     {
16*c4a38d67SPhilip Craig         let Some(start) = start else {
17*c4a38d67SPhilip Craig             continue;
18*c4a38d67SPhilip Craig         };
19*c4a38d67SPhilip Craig         if start == 0 {
20*c4a38d67SPhilip Craig             continue;
2187c33c29SAlex Crichton         }
22*c4a38d67SPhilip Craig         let Some(index) = addr_tr.find_func_index(start) else {
23*c4a38d67SPhilip Craig             // Some non-existent address found.
24*c4a38d67SPhilip Craig             continue;
25*c4a38d67SPhilip Craig         };
26*c4a38d67SPhilip Craig         let Some(map) = addr_tr.map().get(index) else {
27*c4a38d67SPhilip Craig             continue; // no code generated
2887c33c29SAlex Crichton         };
29dd8c48b3SAlex Crichton         let symbol = map.symbol;
3087c33c29SAlex Crichton         let base_addr = map.offset;
31*c4a38d67SPhilip Craig         transform.begin_sequence(Some(write::Address::Symbol { symbol, addend: 0 }));
3287c33c29SAlex Crichton         // TODO track and place function declaration line here
3387c33c29SAlex Crichton         let mut last_address = None;
3487c33c29SAlex Crichton         for addr_map in map.addresses.iter() {
35*c4a38d67SPhilip Craig             let Some(wasm_offset) = addr_map.wasm.checked_sub(start) else {
36*c4a38d67SPhilip Craig                 continue;
37*c4a38d67SPhilip Craig             };
38*c4a38d67SPhilip Craig             let mut saved_row =
39*c4a38d67SPhilip Craig                 match saved_rows.binary_search_by_key(&wasm_offset, |i| i.address_offset) {
40*c4a38d67SPhilip Craig                     Ok(i) => saved_rows[i],
4187c33c29SAlex Crichton                     Err(i) => {
4287c33c29SAlex Crichton                         if i > 0 {
43*c4a38d67SPhilip Craig                             saved_rows[i - 1]
4487c33c29SAlex Crichton                         } else {
45*c4a38d67SPhilip Craig                             continue;
4687c33c29SAlex Crichton                         }
4787c33c29SAlex Crichton                     }
4887c33c29SAlex Crichton                 };
4987c33c29SAlex Crichton             // Ignore duplicates
50*c4a38d67SPhilip Craig             if Some(saved_row.address_offset) != last_address {
5187c33c29SAlex Crichton                 let address_offset = if last_address.is_none() {
5287c33c29SAlex Crichton                     // Extend first entry to the function declaration
5387c33c29SAlex Crichton                     // TODO use the function declaration line instead
5487c33c29SAlex Crichton                     0
5587c33c29SAlex Crichton                 } else {
5687c33c29SAlex Crichton                     (addr_map.generated - base_addr) as u64
5787c33c29SAlex Crichton                 };
58*c4a38d67SPhilip Craig                 last_address = Some(saved_row.address_offset);
59*c4a38d67SPhilip Craig                 saved_row.address_offset = address_offset;
60*c4a38d67SPhilip Craig                 transform.generate_row(saved_row);
6187c33c29SAlex Crichton             }
6287c33c29SAlex Crichton         }
63*c4a38d67SPhilip Craig         transform.end_sequence(map.len as u64);
6487c33c29SAlex Crichton     }
65*c4a38d67SPhilip Craig     let (out_program, files) = transform.program();
66*c4a38d67SPhilip Craig     Ok((out_program, files))
671ef3eecfSPhilip Craig }
68