Skip to content

Commit

Permalink
Detect tail calls in stack size estimation
Browse files Browse the repository at this point in the history
  • Loading branch information
mkeeter committed Feb 7, 2025
1 parent 12f3b21 commit bfcd37a
Showing 1 changed file with 9 additions and 2 deletions.
11 changes: 9 additions & 2 deletions build/xtask/src/dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1236,17 +1236,24 @@ pub fn get_max_stack(
}
chunks.extend(chunk); // don't forget the trailing chunk!

let frame_size = addr_to_frame_size.get(&base_addr).copied();
let mut calls = BTreeSet::new();
for (addr, chunk) in chunks {
let instrs = cs
.disasm_all(&chunk, addr.into())
.map_err(|e| anyhow!("disassembly failed: {e:?}"))?;
for instr in instrs.iter() {
for (i, instr) in instrs.iter().enumerate() {
let detail = cs.insn_detail(instr).map_err(|e| {
anyhow!("could not get instruction details: {e}")
})?;

// Detect tail calls, which are jumps at the final instruction
// when the function itself has no stack frame.
let can_tail = frame_size == Some(0) && i == instrs.len() - 1;
if detail.groups().iter().any(|g| {
g == &InsnGroupId(InsnGroupType::CS_GRP_CALL as u8)
|| (g == &InsnGroupId(InsnGroupType::CS_GRP_JUMP as u8)
&& can_tail)
}) {
let arch = detail.arch_detail();
let ops = arch.operands();
Expand Down Expand Up @@ -1290,7 +1297,7 @@ pub fn get_max_stack(
FunctionData {
name,
short_name,
frame_size: addr_to_frame_size.get(&base_addr).map(|i| *i),
frame_size,
calls,
},
);
Expand Down

0 comments on commit bfcd37a

Please sign in to comment.