Skip to content

Conversation

@LukeSerne
Copy link
Contributor

@LukeSerne LukeSerne commented Oct 12, 2025

Previously, when decompiling a function with a call to an inlined function that is the result of a call_return flow override, the inline would fail with a Return address prevents inlining here warning. This was due to an overly restrictive check in
FlowInfo::testHardInlineRestrictions. With this PR applied, these function calls are inlined again.

This PR also allows CALL pcode-ops in EZ model functions, since CALL operations don't end basic blocks. This also significantly improves Ghidra's ability to inline functions with function calls inside (such as those generated by the call_return override).

This PR also makes the warning more explicit on why the return address prevents inlining.

Sample
FUN_a7d3fb00_ret_addr_prevents_inline.xml (manually edited to ensure the flow overrides are assigned to the correct function).

Before
Decompiler output without this PR applied:

/* WARNING: This is an inlined function */

void FUN_a7d3fb00(undefined4 *param_1) {
  param_1[0x1c] = 0;
  memset(param_1 + 0x1e,0,800);
  *param_1 = 0;
                    /* WARNING: Return address prevents inlining here */
  FUN_a7d42a0c(param_1 + 1);
  return;
}

After
Decompiler output with this PR applied:

/* WARNING: This is an inlined function */
/* WARNING: Inlined function: FUN_a7d42a0c */

void FUN_a7d3fb00(undefined4 *param_1) {
  param_1[0x1c] = 0;
  memset(param_1 + 0x1e,0,800);
  *param_1 = 0;
  memset(param_1 + 1,0,0x6c);
  return;
}

Previously, when decompiling a function with a call to an inlined
function that is the result of a call_return flow override, the inline
would fail with a "Return address prevents inlining here" warning. This
was due to an overly restrictive check in
FlowInfo::testHardInlineRestrictions. With this commit, these function
calls are inlined again.
The EZ inline model causes all inlined ops to share the same address. As
such, we have to be careful not to inline operations that would end the
basic block, since every address needs to belong to exactly one basic
block. Still, we can allow CALL operations just fine, since they don't
end a basic block.
These branch ops have destinations inside the same adress in the
original flow already, so it makes little sense to exclude those from
inlining using the EZ model.
This commit also allows CALLIND ops in the EZ model.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature: Decompiler Status: Triage Information is being gathered

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants