(
coff: &object::coff::CoffFile,
sections: &mut [Section],
section_indices: &[usize],
obj_data: &[u8],
)
| 763 | } |
| 764 | |
| 765 | fn parse_line_info_coff( |
| 766 | coff: &object::coff::CoffFile, |
| 767 | sections: &mut [Section], |
| 768 | section_indices: &[usize], |
| 769 | obj_data: &[u8], |
| 770 | ) -> Result<()> { |
| 771 | use object::{ |
| 772 | coff::{CoffHeader as _, ImageSymbol as _}, |
| 773 | endian::LittleEndian as LE, |
| 774 | }; |
| 775 | let symbol_table = coff.coff_header().symbols(obj_data)?; |
| 776 | |
| 777 | // Enumerate over all sections. |
| 778 | for sect in coff.sections() { |
| 779 | let ptr_linenums = sect.coff_section().pointer_to_linenumbers.get(LE) as usize; |
| 780 | let num_linenums = sect.coff_section().number_of_linenumbers.get(LE) as usize; |
| 781 | |
| 782 | // If we have no line number, skip this section. |
| 783 | if num_linenums == 0 { |
| 784 | continue; |
| 785 | } |
| 786 | |
| 787 | // Find this section in our out_section. If it's not in out_section, |
| 788 | // skip it. |
| 789 | let Some(out_section) = |
| 790 | section_indices.get(sect.index().0).and_then(|&i| sections.get_mut(i)) |
| 791 | else { |
| 792 | continue; |
| 793 | }; |
| 794 | |
| 795 | // Turn the line numbers into an ImageLinenumber slice. |
| 796 | let Some(linenums) = &obj_data.get( |
| 797 | ptr_linenums..ptr_linenums + num_linenums * size_of::<object::pe::ImageLinenumber>(), |
| 798 | ) else { |
| 799 | continue; |
| 800 | }; |
| 801 | let Ok(linenums) = |
| 802 | object::pod::slice_from_all_bytes::<object::pe::ImageLinenumber>(linenums) |
| 803 | else { |
| 804 | continue; |
| 805 | }; |
| 806 | |
| 807 | // In COFF, the line numbers are stored relative to the start of the |
| 808 | // function. Because of this, we need to know the line number where the |
| 809 | // function starts, so we can sum the two and get the line number |
| 810 | // relative to the start of the file. |
| 811 | // |
| 812 | // This variable stores the line number where the function currently |
| 813 | // being processed starts. It is set to None when we failed to find the |
| 814 | // line number of the start of the function. |
| 815 | let mut cur_fun_start_linenumber = None; |
| 816 | for linenum in linenums { |
| 817 | let line_number = linenum.linenumber.get(LE); |
| 818 | if line_number == 0 { |
| 819 | // Starting a new function. We need to find the line where that |
| 820 | // function is located in the file. To do this, we need to find |
| 821 | // the `.bf` symbol "associated" with this function. The .bf |
| 822 | // symbol will have a Function Begin/End Auxillary Record, which |
no test coverage detected