(
obj_file: &object::File,
sections: &mut [Section],
)
| 15 | const ST_END: u8 = 8; |
| 16 | |
| 17 | pub(super) fn parse_line_info_mdebug( |
| 18 | obj_file: &object::File, |
| 19 | sections: &mut [Section], |
| 20 | ) -> Result<()> { |
| 21 | let Some(section) = obj_file.section_by_name(".mdebug") else { |
| 22 | return Ok(()); |
| 23 | }; |
| 24 | |
| 25 | let data = section.data().context("failed to read .mdebug contents")?; |
| 26 | if data.len() < HDRR_SIZE { |
| 27 | return Ok(()); |
| 28 | } |
| 29 | |
| 30 | let section_file_offset = section.file_range().map(|(offset, _)| offset as usize); |
| 31 | |
| 32 | let endianness = obj_file.endianness(); |
| 33 | let header = Header::parse(data, endianness)?; |
| 34 | |
| 35 | let symbols_data = slice_at( |
| 36 | data, |
| 37 | header.cb_sym_offset, |
| 38 | header.isym_max.checked_mul(SYMR_SIZE as u32).context("symbol table size overflow")?, |
| 39 | section_file_offset, |
| 40 | )?; |
| 41 | let symbols = parse_symbols(symbols_data, endianness)?; |
| 42 | |
| 43 | let fdr_data = slice_at( |
| 44 | data, |
| 45 | header.cb_fd_offset, |
| 46 | header |
| 47 | .ifd_max |
| 48 | .checked_mul(FDR_SIZE as u32) |
| 49 | .context("file descriptor table size overflow")?, |
| 50 | section_file_offset, |
| 51 | )?; |
| 52 | |
| 53 | for fdr_index in 0..header.ifd_max as usize { |
| 54 | let fdr_offset = fdr_index * FDR_SIZE; |
| 55 | let fdr = FileDescriptor::parse(&fdr_data[fdr_offset..fdr_offset + FDR_SIZE], endianness)?; |
| 56 | if fdr.cpd == 0 || fdr.csym == 0 { |
| 57 | continue; |
| 58 | } |
| 59 | |
| 60 | let sym_base = fdr.isym_base as usize; |
| 61 | let sym_end = sym_base + fdr.csym as usize; |
| 62 | if sym_end > symbols.len() { |
| 63 | continue; |
| 64 | } |
| 65 | |
| 66 | let Some(line_file_offset) = header.cb_line_offset.checked_add(fdr.cb_line_offset) else { |
| 67 | continue; |
| 68 | }; |
| 69 | let Some(line_file_base) = |
| 70 | resolve_offset(line_file_offset, data.len(), section_file_offset) |
| 71 | else { |
| 72 | continue; |
| 73 | }; |
| 74 | let Some(line_file_end) = line_file_base.checked_add(fdr.cb_line as usize) else { |
no test coverage detected