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:
parent
9249fa67b8
commit
e9a9ed0453
|
@ -248,8 +248,12 @@ impl AnalyzerState {
|
||||||
}
|
}
|
||||||
if self.functions.iter().any(|(_, i)| i.is_unfinalized()) {
|
if self.functions.iter().any(|(_, i)| i.is_unfinalized()) {
|
||||||
log::error!("Failed to finalize functions:");
|
log::error!("Failed to finalize functions:");
|
||||||
for (addr, _) in self.functions.iter().filter(|(_, i)| i.is_unfinalized()) {
|
for (addr, info) in self.functions.iter().filter(|(_, i)| i.is_unfinalized()) {
|
||||||
log::error!(" {:#010X}", addr);
|
log::error!(
|
||||||
|
" {:#010X}: blocks [{:?}]",
|
||||||
|
addr,
|
||||||
|
info.slices.as_ref().unwrap().possible_blocks.keys()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
bail!("Failed to finalize functions");
|
bail!("Failed to finalize functions");
|
||||||
}
|
}
|
||||||
|
@ -298,11 +302,15 @@ impl AnalyzerState {
|
||||||
&self.functions,
|
&self.functions,
|
||||||
Some(vm),
|
Some(vm),
|
||||||
)?;
|
)?;
|
||||||
|
// Start at the beginning of the function again
|
||||||
|
current = SectionAddress::new(addr.section, 0);
|
||||||
}
|
}
|
||||||
TailCallResult::Is => {
|
TailCallResult::Is => {
|
||||||
log::trace!("Finalized tail call @ {:#010X}", block);
|
log::trace!("Finalized tail call @ {:#010X}", block);
|
||||||
slices.possible_blocks.remove(&block);
|
slices.possible_blocks.remove(&block);
|
||||||
slices.function_references.insert(block);
|
slices.function_references.insert(block);
|
||||||
|
// Start at the beginning of the function again
|
||||||
|
current = SectionAddress::new(addr.section, 0);
|
||||||
}
|
}
|
||||||
TailCallResult::Possible => {
|
TailCallResult::Possible => {
|
||||||
if finalize {
|
if finalize {
|
||||||
|
|
|
@ -328,7 +328,7 @@ impl FunctionSlices {
|
||||||
function_end.or_else(|| self.end()),
|
function_end.or_else(|| self.end()),
|
||||||
)?;
|
)?;
|
||||||
log::debug!("-> size {}: {:?}", size, entries);
|
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| {
|
&& !entries.iter().any(|&addr| {
|
||||||
self.is_known_function(known_functions, addr)
|
self.is_known_function(known_functions, addr)
|
||||||
.is_some_and(|fn_addr| fn_addr != function_start)
|
.is_some_and(|fn_addr| fn_addr != function_start)
|
||||||
|
|
Loading…
Reference in New Issue