From c365aaf08a7596de516302326bf9c0146619370c Mon Sep 17 00:00:00 2001 From: Joe Rozner Date: Sat, 10 Oct 2026 04:46:42 +0000 Subject: [PATCH 1/3] [Rust] Add Platform::register_calling_convention Expose BNRegisterPlatformCallingConvention so a platform can be given calling conventions beyond the default/cdecl/stdcall/fastcall/syscall roles. Like the role setters, it asserts that the calling convention's architecture matches the platform's. --- rust/src/platform.rs | 21 +++++++++++++++++++++ rust/tests/platform.rs | 18 ++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/rust/src/platform.rs b/rust/src/platform.rs index 9de125a1c3..7e41b496b6 100644 --- a/rust/src/platform.rs +++ b/rust/src/platform.rs @@ -247,6 +247,27 @@ impl Platform { BNSetPlatformSystemCallConvention ); + /// Register a calling convention with the platform, adding it to [`Platform::calling_conventions`]. + /// + /// Unlike [`Platform::set_default_calling_convention`] and the other role setters, this does not + /// assign the calling convention to a role, it only makes it available on the platform. + /// + /// # Panics + /// + /// Panics if the calling convention's architecture does not match the platform's architecture. + pub fn register_calling_convention(&self, cc: &CoreCallingConvention) { + let arch = self.arch(); + + assert!( + cc.arch_handle.borrow().as_ref().handle == arch.handle, + "use of calling convention with non-matching Platform architecture!" + ); + + unsafe { + BNRegisterPlatformCallingConvention(self.handle, cc.handle); + } + } + pub fn calling_conventions(&self) -> Array { unsafe { let mut count = 0; diff --git a/rust/tests/platform.rs b/rust/tests/platform.rs index 09022ec1c3..fa2136e103 100644 --- a/rust/tests/platform.rs +++ b/rust/tests/platform.rs @@ -1,3 +1,4 @@ +use binaryninja::architecture::{ArchitectureExt, CoreArchitecture}; use binaryninja::headless::Session; use binaryninja::platform::Platform; @@ -38,3 +39,20 @@ fn test_platform_calling_conventions() { let platform = Platform::by_name("windows-x86_64").expect("windows-x86_64 exists"); assert_eq!(platform.calling_conventions().len(), 1); } + +#[test] +fn test_platform_register_calling_convention() { + let _session = Session::new().expect("Failed to initialize session"); + let arch = CoreArchitecture::by_name("x86_64").expect("x86_64 exists"); + let platform = Platform::new(&arch, "test-register-cc-x86_64"); + assert_eq!(platform.calling_conventions().len(), 0); + + let cc = arch + .calling_convention_by_name("win64") + .expect("win64 calling convention exists"); + platform.register_calling_convention(&cc); + + let calling_conventions = platform.calling_conventions(); + assert_eq!(calling_conventions.len(), 1); + assert_eq!(calling_conventions.get(0).name(), "win64"); +} From c7e43b9af80af1378a2b7b54523b073b948fd254 Mon Sep 17 00:00:00 2001 From: Joe Rozner Date: Sat, 10 Oct 2026 08:07:26 +0000 Subject: [PATCH 2/3] [Rust] Drop a useless as_ref in Platform::register_calling_convention arch_handle is already a CoreArchitecture, so .borrow().as_ref() was a no-op that clippy flags as useless_asref. Compare the handles directly. --- rust/src/platform.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/src/platform.rs b/rust/src/platform.rs index 7e41b496b6..78001f2e37 100644 --- a/rust/src/platform.rs +++ b/rust/src/platform.rs @@ -259,7 +259,7 @@ impl Platform { let arch = self.arch(); assert!( - cc.arch_handle.borrow().as_ref().handle == arch.handle, + cc.arch_handle.handle == arch.handle, "use of calling convention with non-matching Platform architecture!" ); From a777f1908c59bb2697f26c7e6e9a3429a1993f0c Mon Sep 17 00:00:00 2001 From: Mason Reed Date: Sat, 10 Oct 2026 22:17:29 -0700 Subject: [PATCH 3/3] Use assert_eq --- rust/src/platform.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/src/platform.rs b/rust/src/platform.rs index 78001f2e37..b32dec8afd 100644 --- a/rust/src/platform.rs +++ b/rust/src/platform.rs @@ -258,8 +258,8 @@ impl Platform { pub fn register_calling_convention(&self, cc: &CoreCallingConvention) { let arch = self.arch(); - assert!( - cc.arch_handle.handle == arch.handle, + assert_eq!( + cc.arch_handle.handle, arch.handle, "use of calling convention with non-matching Platform architecture!" );