(
&self,
symbol: &Symbol,
section: &Section,
next_address: u64,
)
| 349 | } |
| 350 | |
| 351 | fn infer_function_size( |
| 352 | &self, |
| 353 | symbol: &Symbol, |
| 354 | section: &Section, |
| 355 | next_address: u64, |
| 356 | ) -> Result<u64> { |
| 357 | let Ok(size) = (next_address - symbol.address).try_into() else { |
| 358 | return Ok(next_address.saturating_sub(symbol.address)); |
| 359 | }; |
| 360 | let Some(code) = section.data_range(symbol.address, size) else { |
| 361 | return Ok(0); |
| 362 | }; |
| 363 | // Decode instructions to find the last non-NOP instruction |
| 364 | let mut decoder = self.decoder(code, symbol.address); |
| 365 | let mut instruction = Instruction::default(); |
| 366 | let mut new_address = 0; |
| 367 | let mut reloc_iter = section.relocations.iter().peekable(); |
| 368 | 'outer: while decoder.can_decode() { |
| 369 | let address = decoder.ip(); |
| 370 | while let Some(reloc) = reloc_iter.peek() { |
| 371 | match reloc.address.cmp(&address) { |
| 372 | Ordering::Less => { |
| 373 | reloc_iter.next(); |
| 374 | } |
| 375 | Ordering::Equal => { |
| 376 | // If the instruction starts at a relocation, it's inline data |
| 377 | let reloc_size = self.reloc_size(reloc.flags).with_context(|| { |
| 378 | format!("Unsupported inline x86 relocation {:?}", reloc.flags) |
| 379 | })?; |
| 380 | if decoder.set_position(decoder.position() + reloc_size).is_ok() { |
| 381 | new_address = address + reloc_size as u64; |
| 382 | decoder.set_ip(new_address); |
| 383 | continue 'outer; |
| 384 | } |
| 385 | } |
| 386 | Ordering::Greater => break, |
| 387 | } |
| 388 | } |
| 389 | decoder.decode_out(&mut instruction); |
| 390 | if instruction.mnemonic() != iced_x86::Mnemonic::Nop { |
| 391 | new_address = instruction.next_ip(); |
| 392 | } |
| 393 | } |
| 394 | Ok(new_address.saturating_sub(symbol.address)) |
| 395 | } |
| 396 | } |
| 397 | |
| 398 | struct InstructionFormatterOutput<'a> { |
nothing calls this directly
no test coverage detected