Fix block label printing in precise-output tests (#5798)
As a follow-up to #5780, disassemble the regions identified by bb_starts, falling back on disassembling the whole buffer. This ensures that instructions like br_table that introduce a lot of constants don't throw off capstone for the remainder of the function. --------- Co-authored-by: Jamey Sharp <jamey@minilop.net>
This commit is contained in:
@@ -354,49 +354,57 @@ impl<T: CompilePhase> CompiledCodeBase<T> {
|
||||
|
||||
let relocs = self.buffer.relocs();
|
||||
let traps = self.buffer.traps();
|
||||
let labels = self.bb_starts.as_slice();
|
||||
|
||||
let insns = cs.disasm_all(self.buffer.data(), 0x0).map_err(map_caperr)?;
|
||||
for i in insns.iter() {
|
||||
if let Some((n, off)) = labels
|
||||
.iter()
|
||||
.copied()
|
||||
.enumerate()
|
||||
.find(|(_, val)| *val == i.address() as u32)
|
||||
{
|
||||
writeln!(buf, "block{}: ; offset 0x{:x}", n, off)?;
|
||||
}
|
||||
// Normalize the block starts to include an initial block of offset 0.
|
||||
let mut block_starts = Vec::new();
|
||||
if self.bb_starts.first().copied() != Some(0) {
|
||||
block_starts.push(0);
|
||||
}
|
||||
block_starts.extend_from_slice(&self.bb_starts);
|
||||
block_starts.push(self.buffer.data().len() as u32);
|
||||
|
||||
write!(buf, " ")?;
|
||||
// Iterate over block regions, to ensure that we always produce block labels
|
||||
for (n, (&start, &end)) in block_starts
|
||||
.iter()
|
||||
.zip(block_starts.iter().skip(1))
|
||||
.enumerate()
|
||||
{
|
||||
writeln!(buf, "block{}: ; offset 0x{:x}", n, start)?;
|
||||
|
||||
let op_str = i.op_str().unwrap_or("");
|
||||
if let Some(s) = i.mnemonic() {
|
||||
write!(buf, "{}", s)?;
|
||||
if !op_str.is_empty() {
|
||||
write!(buf, " ")?;
|
||||
let buffer = &self.buffer.data()[start as usize..end as usize];
|
||||
let insns = cs.disasm_all(buffer, start as u64).map_err(map_caperr)?;
|
||||
for i in insns.iter() {
|
||||
write!(buf, " ")?;
|
||||
|
||||
let op_str = i.op_str().unwrap_or("");
|
||||
if let Some(s) = i.mnemonic() {
|
||||
write!(buf, "{}", s)?;
|
||||
if !op_str.is_empty() {
|
||||
write!(buf, " ")?;
|
||||
}
|
||||
}
|
||||
|
||||
write!(buf, "{}", op_str)?;
|
||||
|
||||
let end = i.address() + i.bytes().len() as u64;
|
||||
let contains = |off| i.address() <= off && off < end;
|
||||
|
||||
if let Some(reloc) = relocs.iter().find(|reloc| contains(reloc.offset as u64)) {
|
||||
write!(
|
||||
buf,
|
||||
" ; reloc_external {} {} {}",
|
||||
reloc.kind,
|
||||
reloc.name.display(params),
|
||||
reloc.addend,
|
||||
)?;
|
||||
}
|
||||
|
||||
if let Some(trap) = traps.iter().find(|trap| contains(trap.offset as u64)) {
|
||||
write!(buf, " ; trap: {}", trap.code)?;
|
||||
}
|
||||
|
||||
writeln!(buf)?;
|
||||
}
|
||||
|
||||
write!(buf, "{}", op_str)?;
|
||||
|
||||
let end = i.address() + i.bytes().len() as u64;
|
||||
let contains = |off| i.address() <= off && off < end;
|
||||
|
||||
if let Some(reloc) = relocs.iter().find(|reloc| contains(reloc.offset as u64)) {
|
||||
write!(
|
||||
buf,
|
||||
" ; reloc_external {} {} {}",
|
||||
reloc.kind,
|
||||
reloc.name.display(params),
|
||||
reloc.addend,
|
||||
)?;
|
||||
}
|
||||
|
||||
if let Some(trap) = traps.iter().find(|trap| contains(trap.offset as u64)) {
|
||||
write!(buf, " ; trap: {}", trap.code)?;
|
||||
}
|
||||
|
||||
writeln!(buf)?;
|
||||
}
|
||||
|
||||
return Ok(buf);
|
||||
|
||||
Reference in New Issue
Block a user