Fixes for switch analysis

- When finalizing a block, restart analysis at
  the first block
- Check for default case in jump table entries
This commit is contained in:
Luke Street 2024-04-03 00:11:58 -06:00
parent 9249fa67b8
commit e9a9ed0453
2 changed files with 11 additions and 3 deletions

View File

@ -248,8 +248,12 @@ impl AnalyzerState {
}
if self.functions.iter().any(|(_, i)| i.is_unfinalized()) {
log::error!("Failed to finalize functions:");
for (addr, _) in self.functions.iter().filter(|(_, i)| i.is_unfinalized()) {
log::error!(" {:#010X}", addr);
for (addr, info) in self.functions.iter().filter(|(_, i)| i.is_unfinalized()) {
log::error!(
" {:#010X}: blocks [{:?}]",
addr,
info.slices.as_ref().unwrap().possible_blocks.keys()
);
}
bail!("Failed to finalize functions");
}
@ -298,11 +302,15 @@ impl AnalyzerState {
&self.functions,
Some(vm),
)?;
// Start at the beginning of the function again
current = SectionAddress::new(addr.section, 0);
}
TailCallResult::Is => {
log::trace!("Finalized tail call @ {:#010X}", block);
slices.possible_blocks.remove(&block);
slices.function_references.insert(block);
// Start at the beginning of the function again
current = SectionAddress::new(addr.section, 0);
}
TailCallResult::Possible => {
if finalize {

View File

@ -328,7 +328,7 @@ impl FunctionSlices {
function_end.or_else(|| self.end()),
)?;
log::debug!("-> size {}: {:?}", size, entries);
if entries.contains(&next_address)
if (entries.contains(&next_address) || self.blocks.contains_key(&next_address))
&& !entries.iter().any(|&addr| {
self.is_known_function(known_functions, addr)
.is_some_and(|fn_addr| fn_addr != function_start)