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