MCPcopy Create free account
hub / github.com/Rust-for-Linux/klint / inline_info

Method inline_info

src/binary_analysis/dwarf.rs:474–546  ·  view source on GitHub ↗
(
        &self,
        section_index: SectionIndex,
        offset: u64,
    )

Source from the content-addressed store, hash-verified

472 }
473
474 pub fn inline_info<'tcx>(
475 &self,
476 section_index: SectionIndex,
477 offset: u64,
478 ) -> Result<Vec<Call>, Error> {
479 let mut iter = self.dwarf.units();
480 let mut callstack = Vec::<Call>::new();
481
482 while let Some(header) = iter.next()? {
483 let unit = self.dwarf.unit(header)?;
484
485 let mut stack = Vec::new();
486 let mut entries = unit.entries();
487 let mut prev_depth = 0;
488 while let Some(die) = entries.next_dfs()? {
489 for _ in die.depth()..=prev_depth {
490 stack.pop();
491 }
492 prev_depth = die.depth;
493
494 if matches!(
495 die.tag(),
496 gimli::DW_TAG_subprogram | gimli::DW_TAG_inlined_subroutine
497 ) {
498 stack.push(Some(self.linkage_name(&unit, die)?));
499 } else {
500 stack.push(None);
501 }
502
503 if die.tag() != gimli::DW_TAG_inlined_subroutine {
504 continue;
505 }
506
507 let ranges = self.ranges(&unit, die)?;
508 if ranges.0 != section_index {
509 continue;
510 }
511
512 if ranges
513 .1
514 .iter()
515 .any(|range| range.contains(&(offset as i64)))
516 {
517 let callee = stack.last().unwrap().as_ref().unwrap();
518 let caller = stack
519 .iter()
520 .rev()
521 .skip(1)
522 .find(|x| x.is_some())
523 .and_then(|x| x.as_ref())
524 .ok_or(Error::UnexpectedDwarf(
525 "DW_TAG_inlined_subroutine is not nested inside DW_TAG_subprogram",
526 ))?;
527
528 // Call stack must form a chain.
529 if let Some(last_call) = callstack.last() {
530 if last_call.callee != *caller {
531 Err(Error::UnexpectedDwarf("Inlined call does not form a chain"))?

Callers 1

build_error_detectionFunction · 0.80

Calls 6

nextMethod · 0.80
pushMethod · 0.80
linkage_nameMethod · 0.80
rangesMethod · 0.80
unwrapMethod · 0.80
call_locationMethod · 0.80

Tested by

no test coverage detected