Skip to content

Commit 8a42cba

Browse files
xusheng6claude
andcommitted
[emulator] Place call arguments using the emulated function's calling convention
SetArgument always used the platform's default calling convention, contradicting the documented behavior of using the function's own convention. Derive the calling convention from the function being emulated (via its LLIL function), falling back to the platform default only when the function has none. Also note the address-size-as-stack-slot-size assumption for exotic ABIs. Addresses emesare review comments on PR #8314. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 53fab4b commit 8a42cba

2 files changed

Lines changed: 18 additions & 7 deletions

File tree

plugins/emulator/core/llilemulator.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,19 @@ void LLILEmulator::SetArgument(size_t index, const intx::uint512& value)
7272
if (!m_view)
7373
return;
7474

75-
Ref<Platform> platform = m_view->GetDefaultPlatform();
76-
if (!platform)
77-
return;
78-
79-
Ref<CallingConvention> cc = platform->GetDefaultCallingConvention();
75+
// Place arguments using the calling convention of the function being emulated, falling
76+
// back to the platform default only when the function has none.
77+
Ref<CallingConvention> cc;
78+
if (m_il)
79+
{
80+
if (Ref<Function> func = m_il->GetFunction())
81+
cc = func->GetCallingConvention().GetValue();
82+
}
83+
if (!cc)
84+
{
85+
if (Ref<Platform> platform = m_view->GetDefaultPlatform())
86+
cc = platform->GetDefaultCallingConvention();
87+
}
8088
if (!cc)
8189
return;
8290

@@ -87,7 +95,9 @@ void LLILEmulator::SetArgument(size_t index, const intx::uint512& value)
8795
return;
8896
}
8997

90-
// Stack argument
98+
// Stack argument. Note: the stack slot size is taken to be the address size, which holds
99+
// for the common ABIs but not exotic ones like the x86-64 x32 ABI (4-byte address size,
100+
// 8-byte stack slots).
91101
size_t addrSize = m_arch->GetAddressSize();
92102
uint32_t sp = m_arch->GetStackPointerRegister();
93103
uint64_t spVal = static_cast<uint64_t>(GetRegister(sp));

plugins/emulator/core/llilemulator.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ namespace BinaryNinjaEmulator
160160
bool SetEntryPoint(uint64_t addr);
161161
void SetEntryPoint(BinaryNinja::LowLevelILFunction* il, size_t instrIndex);
162162

163-
// Argument setup (uses default calling convention)
163+
// Argument setup (uses the emulated function's calling convention, falling back to
164+
// the platform default)
164165
void SetArgument(size_t index, const intx::uint512& value);
165166
void SetArguments(const std::vector<uint64_t>& values);
166167

0 commit comments

Comments
 (0)