Parse line information from DWARF 2+ sections.
(
obj_file: &object::File,
sections: &mut [Section],
)
| 8 | |
| 9 | /// Parse line information from DWARF 2+ sections. |
| 10 | pub(crate) fn parse_line_info_dwarf2( |
| 11 | obj_file: &object::File, |
| 12 | sections: &mut [Section], |
| 13 | ) -> Result<()> { |
| 14 | let arena_data = Arena::new(); |
| 15 | let arena_relocations = Arena::new(); |
| 16 | let endian = match obj_file.endianness() { |
| 17 | object::Endianness::Little => gimli::RunTimeEndian::Little, |
| 18 | object::Endianness::Big => gimli::RunTimeEndian::Big, |
| 19 | }; |
| 20 | let dwarf = gimli::Dwarf::load(|id: gimli::SectionId| -> Result<_> { |
| 21 | load_file_section(id, obj_file, endian, &arena_data, &arena_relocations) |
| 22 | }) |
| 23 | .context("loading DWARF sections")?; |
| 24 | |
| 25 | let mut iter = dwarf.units(); |
| 26 | if let Some(header) = iter.next().map_err(|e| gimli_error(e, "iterating over DWARF units"))? { |
| 27 | let unit = dwarf.unit(header).map_err(|e| gimli_error(e, "loading DWARF unit"))?; |
| 28 | if let Some(program) = unit.line_program.clone() { |
| 29 | let mut text_sections = sections.iter_mut().filter(|s| s.kind == SectionKind::Code); |
| 30 | let mut lines = text_sections.next().map(|section| &mut section.line_info); |
| 31 | |
| 32 | let mut rows = program.rows(); |
| 33 | while let Some((_header, row)) = |
| 34 | rows.next_row().map_err(|e| gimli_error(e, "loading program row"))? |
| 35 | { |
| 36 | if let (Some(line), Some(lines)) = (row.line(), &mut lines) { |
| 37 | lines.insert(row.address(), line.get() as u32); |
| 38 | } |
| 39 | if row.end_sequence() { |
| 40 | // The next row is the start of a new sequence, which means we must |
| 41 | // advance to the next .text section. |
| 42 | lines = text_sections.next().map(|section| &mut section.line_info); |
| 43 | } |
| 44 | } |
| 45 | } |
| 46 | } |
| 47 | if iter.next().map_err(|e| gimli_error(e, "checking for next unit"))?.is_some() { |
| 48 | log::warn!("Multiple units found in DWARF data, only processing the first"); |
| 49 | } |
| 50 | |
| 51 | Ok(()) |
| 52 | } |
| 53 | |
| 54 | #[derive(Debug, Default)] |
| 55 | struct RelocationMap(object::read::RelocationMap); |
no test coverage detected