Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save goertzenator/fc679993ef92fa63545bccd80a78d9d3 to your computer and use it in GitHub Desktop.

Select an option

Save goertzenator/fc679993ef92fa63545bccd80a78d9d3 to your computer and use it in GitHub Desktop.
struct vs int calling convention issue
I had a Rust plugin for Erlang that exposed the following function type:
extern "C" fn(env: *mut ErlNifEnv, argc: c_int, argv: *const ERL_NIF_TERM) -> ERL_NIF_TERM;
where...
#[allow(non_camel_case_types)]
pub type size_t = usize;
#[allow(non_camel_case_types)]
pub type ERL_NIF_UINT = size_t;
#[derive(Debug, Copy, Clone)]
#[repr(C)]
pub struct ERL_NIF_TERM(ERL_NIF_UINT);
The actual C API uses ERL_NIF_UINT as an alias for ERL_NIF_TERM instead of wrapping in a struct like we've done here.
The resulting assembly is...
00099f80 <_ZN8test_nif20dynamic_atom_wrapper17h62a8bfa9d53631aaE>:
99f80: 53 push %ebx
99f81: 57 push %edi
99f82: 56 push %esi
99f83: 83 ec 50 sub $0x50,%esp
99f86: e8 00 00 00 00 call 99f8b <_ZN8test_nif20dynamic_atom_wrapper17h62a8bfa9d53631aaE+0xb>
99f8b: 5b pop %ebx
99f8c: 81 c3 75 e0 0e 00 add $0xee075,%ebx
99f92: 8b 74 24 60 mov 0x60(%esp),%esi
99f96: 8b 44 24 6c mov 0x6c(%esp),%eax
99f9a: 8b 4c 24 68 mov 0x68(%esp),%ecx
99f9e: 8b 54 24 64 mov 0x64(%esp),%edx
99fa2: 89 54 24 4c mov %edx,0x4c(%esp)
99fa6: 89 4c 24 48 mov %ecx,0x48(%esp)
99faa: 89 44 24 44 mov %eax,0x44(%esp)
99fae: 8d 83 70 2a f1 ff lea -0xed590(%ebx),%eax
99fb4: 89 44 24 14 mov %eax,0x14(%esp)
99fb8: 8d 44 24 4c lea 0x4c(%esp),%eax
99fbc: 89 44 24 10 mov %eax,0x10(%esp)
99fc0: 8b 83 88 ff ff ff mov -0x78(%ebx),%eax
99fc6: 89 44 24 1c mov %eax,0x1c(%esp)
99fca: 8d 44 24 48 lea 0x48(%esp),%eax
99fce: 89 44 24 18 mov %eax,0x18(%esp)
99fd2: 8d 83 90 2c f1 ff lea -0xed370(%ebx),%eax
99fd8: 89 44 24 24 mov %eax,0x24(%esp)
99fdc: 8d 44 24 44 lea 0x44(%esp),%eax
99fe0: 89 44 24 20 mov %eax,0x20(%esp)
99fe4: 8d 83 e0 ce ff ff lea -0x3120(%ebx),%eax
99fea: 89 44 24 28 mov %eax,0x28(%esp)
99fee: c7 44 24 2c 04 00 00 movl $0x4,0x2c(%esp)
99ff5: 00
99ff6: c7 44 24 34 00 00 00 movl $0x0,0x34(%esp)
99ffd: 00
99ffe: c7 44 24 30 00 00 00 movl $0x0,0x30(%esp)
9a005: 00
9a006: 8d 44 24 10 lea 0x10(%esp),%eax
9a00a: 89 44 24 38 mov %eax,0x38(%esp)
9a00e: c7 44 24 3c 03 00 00 movl $0x3,0x3c(%esp)
9a015: 00
9a016: 8d 44 24 28 lea 0x28(%esp),%eax
9a01a: 89 04 24 mov %eax,(%esp)
9a01d: e8 de df ff ff call 98000 <_ZN3std2io5stdio6_print17h03730948b3f63a9bE@plt>
9a022: 8b 44 24 4c mov 0x4c(%esp),%eax
9a026: 8b 4c 24 48 mov 0x48(%esp),%ecx
9a02a: 8b 54 24 44 mov 0x44(%esp),%edx
9a02e: 8d bb 20 2d f1 ff lea -0xed2e0(%ebx),%edi
9a034: 89 7c 24 0c mov %edi,0xc(%esp)
9a038: 89 54 24 08 mov %edx,0x8(%esp)
9a03c: 89 4c 24 04 mov %ecx,0x4(%esp)
9a040: 89 04 24 mov %eax,(%esp)
9a043: e8 48 f9 ff ff call 99990 <_ZN6ruster17ruster_fn_wrapper17h867f47a209f21e0dE@plt>
9a048: 89 06 mov %eax,(%esi)
9a04a: 89 f0 mov %esi,%eax
9a04c: 83 c4 50 add $0x50,%esp
9a04f: 5e pop %esi
9a050: 5f pop %edi
9a051: 5b pop %ebx
9a052: c2 04 00 ret $0x4
9a055: 66 90 xchg %ax,%ax
9a057: 66 90 xchg %ax,%ax
9a059: 66 90 xchg %ax,%ax
9a05b: 66 90 xchg %ax,%ax
9a05d: 66 90 xchg %ax,%ax
9a05f: 90 nop
Now we change ERL_NIF_TERM to be a more faithful replication of the C API
#[allow(non_camel_case_types)]
pub type ERL_NIF_TERM = ERL_NIF_UINT;
00099d90 <_ZN8test_nif20dynamic_atom_wrapper17hfc271a2aec098dd6E>:
99d90: 53 push %ebx
99d91: 56 push %esi
99d92: 83 ec 54 sub $0x54,%esp
99d95: e8 00 00 00 00 call 99d9a <_ZN8test_nif20dynamic_atom_wrapper17hfc271a2aec098dd6E+0xa>
99d9a: 5b pop %ebx
99d9b: 81 c3 66 e2 0e 00 add $0xee266,%ebx
99da1: 8b 44 24 68 mov 0x68(%esp),%eax
99da5: 8b 4c 24 64 mov 0x64(%esp),%ecx
99da9: 8b 54 24 60 mov 0x60(%esp),%edx
99dad: 89 54 24 50 mov %edx,0x50(%esp)
99db1: 89 4c 24 4c mov %ecx,0x4c(%esp)
99db5: 89 44 24 48 mov %eax,0x48(%esp)
99db9: 8d 83 c0 27 f1 ff lea -0xed840(%ebx),%eax
99dbf: 89 44 24 1c mov %eax,0x1c(%esp)
99dc3: 8d 44 24 50 lea 0x50(%esp),%eax
99dc7: 89 44 24 18 mov %eax,0x18(%esp)
99dcb: 8b 83 88 ff ff ff mov -0x78(%ebx),%eax
99dd1: 89 44 24 24 mov %eax,0x24(%esp)
99dd5: 8d 44 24 4c lea 0x4c(%esp),%eax
99dd9: 89 44 24 20 mov %eax,0x20(%esp)
99ddd: 8d 83 e0 29 f1 ff lea -0xed620(%ebx),%eax
99de3: 89 44 24 2c mov %eax,0x2c(%esp)
99de7: 8d 44 24 48 lea 0x48(%esp),%eax
99deb: 89 44 24 28 mov %eax,0x28(%esp)
99def: 8d 83 f0 ce ff ff lea -0x3110(%ebx),%eax
99df5: 89 44 24 30 mov %eax,0x30(%esp)
99df9: c7 44 24 34 04 00 00 movl $0x4,0x34(%esp)
99e00: 00
99e01: c7 44 24 3c 00 00 00 movl $0x0,0x3c(%esp)
99e08: 00
99e09: c7 44 24 38 00 00 00 movl $0x0,0x38(%esp)
99e10: 00
99e11: 8d 44 24 18 lea 0x18(%esp),%eax
99e15: 89 44 24 40 mov %eax,0x40(%esp)
99e19: c7 44 24 44 03 00 00 movl $0x3,0x44(%esp)
99e20: 00
99e21: 8d 44 24 30 lea 0x30(%esp),%eax
99e25: 89 04 24 mov %eax,(%esp)
99e28: e8 f3 df ff ff call 97e20 <_ZN3std2io5stdio6_print17h03730948b3f63a9bE@plt>
99e2d: 8b 44 24 50 mov 0x50(%esp),%eax
99e31: 8b 4c 24 4c mov 0x4c(%esp),%ecx
99e35: 8b 54 24 48 mov 0x48(%esp),%edx
99e39: 8d b3 70 2a f1 ff lea -0xed590(%ebx),%esi
99e3f: 89 74 24 0c mov %esi,0xc(%esp)
99e43: 89 54 24 08 mov %edx,0x8(%esp)
99e47: 89 4c 24 04 mov %ecx,0x4(%esp)
99e4b: 89 04 24 mov %eax,(%esp)
99e4e: e8 1d e9 ff ff call 98770 <_ZN6ruster17ruster_fn_wrapper17h750f0afac017b19fE@plt>
99e53: 83 c4 54 add $0x54,%esp
99e56: 5e pop %esi
99e57: 5b pop %ebx
99e58: c3 ret
99e59: 66 90 xchg %ax,%ax
99e5b: 66 90 xchg %ax,%ax
99e5d: 66 90 xchg %ax,%ax
99e5f: 90 nop
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment