diff --git a/Assets/dll/libwaterboxhost.so b/Assets/dll/libwaterboxhost.so
index 3cfbdbf5e5..8d78ea5ad6 100644
Binary files a/Assets/dll/libwaterboxhost.so and b/Assets/dll/libwaterboxhost.so differ
diff --git a/output/dll/waterboxhost.dll b/output/dll/waterboxhost.dll
index c085e8137d..95569f3fd3 100644
Binary files a/output/dll/waterboxhost.dll and b/output/dll/waterboxhost.dll differ
diff --git a/src/BizHawk.BizInvoke/CallingConventionAdapter.cs b/src/BizHawk.BizInvoke/CallingConventionAdapter.cs
index 038d481c1b..65c081d475 100644
--- a/src/BizHawk.BizInvoke/CallingConventionAdapter.cs
+++ b/src/BizHawk.BizInvoke/CallingConventionAdapter.cs
@@ -228,46 +228,22 @@ namespace BizHawk.BizInvoke
}
}
+ ///
+ /// Calling Convention Adapter for where host code expects msabi and guest code is sysv.
+ /// Does not handle anything Waterbox specific.
+ ///
private class MsHostSysVGuest : ICallingConventionAdapter
{
- private const ulong Placeholder = 0xdeadbeeffeedface;
- private const byte Padding = 0x06;
- private const int BlockSize = 256;
- private static readonly byte[][] Arrive =
- {
- new byte[] { 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x48, 0x83, 0xec, 0x28, 0xff, 0xd0, 0x48, 0x83, 0xc4, 0x28, 0xc3, 0x66, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, },
- new byte[] { 0x48, 0x83, 0xec, 0x28, 0x48, 0x89, 0xf9, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0xff, 0xd0, 0x48, 0x83, 0xc4, 0x28, 0xc3, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, },
- new byte[] { 0x48, 0x83, 0xec, 0x28, 0x48, 0x89, 0xf9, 0x48, 0x89, 0xf2, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0xff, 0xd0, 0x48, 0x83, 0xc4, 0x28, 0xc3, 0x0f, 0x1f, 0x44, 0x00, 0x00, },
- new byte[] { 0x48, 0x83, 0xec, 0x28, 0x49, 0x89, 0xd0, 0x48, 0x89, 0xf9, 0x48, 0x89, 0xf2, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0xff, 0xd0, 0x48, 0x83, 0xc4, 0x28, 0xc3, 0x66, 0x90, },
- new byte[] { 0x48, 0x83, 0xec, 0x28, 0x49, 0x89, 0xd0, 0x49, 0x89, 0xc9, 0x48, 0x89, 0xf2, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x48, 0x89, 0xf9, 0xff, 0xd0, 0x48, 0x83, 0xc4, 0x28, 0xc3, 0x66, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x1f, 0x40, 0x00, },
- new byte[] { 0x48, 0x83, 0xec, 0x10, 0x49, 0x89, 0xc9, 0x48, 0x89, 0xf9, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x41, 0x50, 0x49, 0x89, 0xd0, 0x48, 0x89, 0xf2, 0x48, 0x83, 0xec, 0x20, 0xff, 0xd0, 0x48, 0x83, 0xc4, 0x38, 0xc3, 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, },
- new byte[] { 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x48, 0x83, 0xec, 0x08, 0x41, 0x51, 0x49, 0x89, 0xc9, 0x48, 0x89, 0xf9, 0x41, 0x50, 0x49, 0x89, 0xd0, 0x48, 0x89, 0xf2, 0x48, 0x83, 0xec, 0x20, 0xff, 0xd0, 0x48, 0x83, 0xc4, 0x38, 0xc3, 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, },
- };
- private static readonly byte[][] Depart =
- {
- new byte[] { 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x57, 0x56, 0x48, 0x81, 0xec, 0xa8, 0x00, 0x00, 0x00, 0x0f, 0x29, 0x34, 0x24, 0x0f, 0x29, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x29, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x29, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x29, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x29, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x29, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x29, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x29, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x29, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x0f, 0x28, 0x34, 0x24, 0x0f, 0x28, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x28, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x28, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x28, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x28, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x28, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x28, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x28, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x28, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0x48, 0x81, 0xc4, 0xa8, 0x00, 0x00, 0x00, 0x5e, 0x5f, 0xc3, 0x0f, 0x1f, 0x00, },
- new byte[] { 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x57, 0x48, 0x89, 0xcf, 0x56, 0x48, 0x81, 0xec, 0xa8, 0x00, 0x00, 0x00, 0x0f, 0x29, 0x34, 0x24, 0x0f, 0x29, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x29, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x29, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x29, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x29, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x29, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x29, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x29, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x29, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x0f, 0x28, 0x34, 0x24, 0x0f, 0x28, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x28, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x28, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x28, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x28, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x28, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x28, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x28, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x28, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0x48, 0x81, 0xc4, 0xa8, 0x00, 0x00, 0x00, 0x5e, 0x5f, 0xc3, },
- new byte[] { 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x57, 0x48, 0x89, 0xcf, 0x56, 0x48, 0x89, 0xd6, 0x48, 0x81, 0xec, 0xa8, 0x00, 0x00, 0x00, 0x0f, 0x29, 0x34, 0x24, 0x0f, 0x29, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x29, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x29, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x29, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x29, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x29, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x29, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x29, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x29, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x0f, 0x28, 0x34, 0x24, 0x0f, 0x28, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x28, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x28, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x28, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x28, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x28, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x28, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x28, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x28, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0x48, 0x81, 0xc4, 0xa8, 0x00, 0x00, 0x00, 0x5e, 0x5f, 0xc3, 0x66, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x90, },
- new byte[] { 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x57, 0x48, 0x89, 0xcf, 0x56, 0x48, 0x89, 0xd6, 0x4c, 0x89, 0xc2, 0x48, 0x81, 0xec, 0xa8, 0x00, 0x00, 0x00, 0x0f, 0x29, 0x34, 0x24, 0x0f, 0x29, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x29, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x29, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x29, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x29, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x29, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x29, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x29, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x29, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x0f, 0x28, 0x34, 0x24, 0x0f, 0x28, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x28, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x28, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x28, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x28, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x28, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x28, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x28, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x28, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0x48, 0x81, 0xc4, 0xa8, 0x00, 0x00, 0x00, 0x5e, 0x5f, 0xc3, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, },
- new byte[] { 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x57, 0x48, 0x89, 0xcf, 0x4c, 0x89, 0xc9, 0x56, 0x48, 0x89, 0xd6, 0x4c, 0x89, 0xc2, 0x48, 0x81, 0xec, 0xa8, 0x00, 0x00, 0x00, 0x0f, 0x29, 0x34, 0x24, 0x0f, 0x29, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x29, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x29, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x29, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x29, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x29, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x29, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x29, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x29, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x0f, 0x28, 0x34, 0x24, 0x0f, 0x28, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x28, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x28, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x28, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x28, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x28, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x28, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x28, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x28, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0x48, 0x81, 0xc4, 0xa8, 0x00, 0x00, 0x00, 0x5e, 0x5f, 0xc3, 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, },
- new byte[] { 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x57, 0x48, 0x89, 0xcf, 0x4c, 0x89, 0xc9, 0x56, 0x48, 0x89, 0xd6, 0x4c, 0x89, 0xc2, 0x48, 0x81, 0xec, 0xa8, 0x00, 0x00, 0x00, 0x0f, 0x29, 0x34, 0x24, 0x4c, 0x8b, 0x84, 0x24, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0x29, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x29, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x29, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x29, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x29, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x29, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x29, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x29, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x29, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x0f, 0x28, 0x34, 0x24, 0x0f, 0x28, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x28, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x28, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x28, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x28, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x28, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x28, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x28, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x28, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0x48, 0x81, 0xc4, 0xa8, 0x00, 0x00, 0x00, 0x5e, 0x5f, 0xc3, 0x66, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x1f, 0x40, 0x00, },
- new byte[] { 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x57, 0x48, 0x89, 0xcf, 0x4c, 0x89, 0xc9, 0x56, 0x48, 0x89, 0xd6, 0x4c, 0x89, 0xc2, 0x48, 0x81, 0xec, 0xa8, 0x00, 0x00, 0x00, 0x0f, 0x29, 0x34, 0x24, 0x4c, 0x8b, 0x8c, 0x24, 0xe8, 0x00, 0x00, 0x00, 0x4c, 0x8b, 0x84, 0x24, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0x29, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x29, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x29, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x29, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x29, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x29, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x29, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x29, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x29, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x0f, 0x28, 0x34, 0x24, 0x0f, 0x28, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x28, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x28, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x28, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x28, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x28, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x28, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x28, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x28, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0x48, 0x81, 0xc4, 0xa8, 0x00, 0x00, 0x00, 0x5e, 0x5f, 0xc3, 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, },
- };
- private static readonly int[] DepartPlaceholderIndices;
- private static readonly int[] ArrivePlaceholderIndices;
+ // This is implemented by using thunks defined in the waterbox native code, and putting stubs on top of them that close over the
+ // function pointer parameter.
- private static int FindPlaceholderIndex(byte[] data)
- {
- return Enumerable.Range(0, data.Length - 7)
- .Single(i => BitConverter.ToUInt64(data, i) == Placeholder);
- }
+ private const int BlockSize = 32;
+ private static readonly IImportResolver ThunkDll;
static MsHostSysVGuest()
{
- DepartPlaceholderIndices = Depart.Select(FindPlaceholderIndex).ToArray();
- ArrivePlaceholderIndices = Arrive.Select(FindPlaceholderIndex).ToArray();
- if (Depart.Any(b => b.Length > BlockSize) || Arrive.Any(b => b.Length > BlockSize))
- throw new InvalidOperationException();
+ // If needed, these can be split out from waterboxhost.dll; they're not directly related to anything waterbox does.
+ ThunkDll = new DynamicLibraryImportResolver(OSTailoredCode.IsUnixHost ? "libwaterboxhost.so" : "waterboxhost.dll", hasLimitedLifetime: false);
}
private readonly MemoryBlock _memory;
@@ -320,21 +296,33 @@ namespace BizHawk.BizInvoke
foreach (var ppp in pp.ParameterTypes)
VerifyParameter(ppp);
var ret = pp.ParameterTypes.Count;
- if (ret >= Arrive.Length)
+ if (ret >= 7)
throw new InvalidOperationException("Too many parameters to marshal!");
return ret;
}
- private void WriteThunk(byte[] data, int placeholderIndex, IntPtr p, int index)
+ private void WriteThunk(IntPtr thunkFunctionAddress, IntPtr calleeAddress, int index)
{
_memory.Protect(_memory.Start, _memory.Size, MemoryBlock.Protection.RW);
var ss = _memory.GetStream(_memory.Start + (ulong)index * BlockSize, BlockSize, true);
- ss.Write(data, 0, data.Length);
- for (int i = data.Length; i < BlockSize; i++)
- ss.WriteByte(Padding);
- ss.Position = placeholderIndex;
var bw = new BinaryWriter(ss);
- bw.Write((long)p);
+
+ // The thunks all take the expected parameters in the expected places, but additionally take the parameter
+ // of the function to call as a hidden extra parameter in rax.
+
+ // mov r10, thunkFunctionAddress
+ bw.Write((byte)0x49);
+ bw.Write((byte)0xba);
+ bw.Write((long)thunkFunctionAddress);
+ // mov rax, calleeAddress
+ bw.Write((byte)0x48);
+ bw.Write((byte)0xb8);
+ bw.Write((long)calleeAddress);
+ // jmp r10
+ bw.Write((byte)0x41);
+ bw.Write((byte)0xff);
+ bw.Write((byte)0xe2);
+
_memory.Protect(_memory.Start, _memory.Size, MemoryBlock.Protection.RX);
}
@@ -376,7 +364,7 @@ namespace BizHawk.BizInvoke
{
var index = FindFreeIndex();
var count = VerifyDelegateSignature(pp);
- WriteThunk(Arrive[count], ArrivePlaceholderIndices[count], p, index);
+ WriteThunk(ThunkDll.GetProcAddrOrThrow($"arrive{count}"), p, index);
SetLifetime(index, lifetime);
return GetThunkAddress(index);
}
@@ -388,7 +376,7 @@ namespace BizHawk.BizInvoke
{
var index = FindFreeIndex();
var count = VerifyDelegateSignature(new ParameterInfo(delegateType));
- WriteThunk(Depart[count], DepartPlaceholderIndices[count], p, index);
+ WriteThunk(ThunkDll.GetProcAddrOrThrow($"depart{count}"), p, index);
var ret = Marshal.GetDelegateForFunctionPointer(GetThunkAddress(index), delegateType);
SetLifetime(index, ret);
return ret;
@@ -401,7 +389,7 @@ namespace BizHawk.BizInvoke
{
var index = FindFreeIndex();
var count = VerifyDelegateSignature(pp);
- WriteThunk(Depart[count], DepartPlaceholderIndices[count], p, index);
+ WriteThunk(ThunkDll.GetProcAddrOrThrow($"depart{count}"), p, index);
SetLifetime(index, lifetime);
return GetThunkAddress(index);
}
diff --git a/waterbox/thunk/Makefile b/waterbox/thunk/Makefile
deleted file mode 100644
index 7319f07b81..0000000000
--- a/waterbox/thunk/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-all: test.txt
-
-.PHONY: all
-
-test: test.c Makefile
- gcc test.c -o test -Wall -O3 -fcf-protection=none
-
-test.txt: test Makefile
- ./test > test.txt
diff --git a/waterbox/thunk/test b/waterbox/thunk/test
deleted file mode 100644
index fe11735c2e..0000000000
Binary files a/waterbox/thunk/test and /dev/null differ
diff --git a/waterbox/thunk/test.c b/waterbox/thunk/test.c
deleted file mode 100644
index 867406a8d1..0000000000
--- a/waterbox/thunk/test.c
+++ /dev/null
@@ -1,109 +0,0 @@
-#include
-
-typedef int64_t ll;
-
-__attribute__((sysv_abi)) ll Depart0(void)
-{
- return ((__attribute__((ms_abi)) ll (*)(void))0xdeadbeeffeedface)();
-}
-
-__attribute__((sysv_abi)) ll Depart1(ll a)
-{
- return ((__attribute__((ms_abi)) ll (*)(ll))0xdeadbeeffeedface)(a);
-}
-
-__attribute__((sysv_abi)) ll Depart2(ll a, ll b)
-{
- return ((__attribute__((ms_abi)) ll (*)(ll, ll))0xdeadbeeffeedface)(a, b);
-}
-
-__attribute__((sysv_abi)) ll Depart3(ll a, ll b, ll c)
-{
- return ((__attribute__((ms_abi)) ll (*)(ll, ll, ll))0xdeadbeeffeedface)(a, b, c);
-}
-
-__attribute__((sysv_abi)) ll Depart4(ll a, ll b, ll c, ll d)
-{
- return ((__attribute__((ms_abi)) ll (*)(ll, ll, ll, ll))0xdeadbeeffeedface)(a, b, c, d);
-}
-
-__attribute__((sysv_abi)) ll Depart5(ll a, ll b, ll c, ll d, ll e)
-{
- return ((__attribute__((ms_abi)) ll (*)(ll, ll, ll, ll, ll))0xdeadbeeffeedface)(a, b, c, d, e);
-}
-
-__attribute__((sysv_abi)) ll Depart6(ll a, ll b, ll c, ll d, ll e, ll f)
-{
- return ((__attribute__((ms_abi)) ll (*)(ll, ll, ll, ll, ll, ll))0xdeadbeeffeedface)(a, b, c, d, e, f);
-}
-
-__attribute__((ms_abi)) ll Arrive0(void)
-{
- return ((__attribute__((sysv_abi)) ll (*)(void))0xdeadbeeffeedface)();
-}
-
-__attribute__((ms_abi)) ll Arrive1(ll a)
-{
- return ((__attribute__((sysv_abi)) ll (*)(ll))0xdeadbeeffeedface)(a);
-}
-
-__attribute__((ms_abi)) ll Arrive2(ll a, ll b)
-{
- return ((__attribute__((sysv_abi)) ll (*)(ll, ll))0xdeadbeeffeedface)(a, b);
-}
-
-__attribute__((ms_abi)) ll Arrive3(ll a, ll b, ll c)
-{
- return ((__attribute__((sysv_abi)) ll (*)(ll, ll, ll))0xdeadbeeffeedface)(a, b, c);
-}
-
-__attribute__((ms_abi)) ll Arrive4(ll a, ll b, ll c, ll d)
-{
- return ((__attribute__((sysv_abi)) ll (*)(ll, ll, ll, ll))0xdeadbeeffeedface)(a, b, c, d);
-}
-
-__attribute__((ms_abi)) ll Arrive5(ll a, ll b, ll c, ll d, ll e)
-{
- return ((__attribute__((sysv_abi)) ll (*)(ll, ll, ll, ll, ll))0xdeadbeeffeedface)(a, b, c, d, e);
-}
-
-__attribute__((ms_abi)) ll Arrive6(ll a, ll b, ll c, ll d, ll e, ll f)
-{
- return ((__attribute__((sysv_abi)) ll (*)(ll, ll, ll, ll, ll, ll))0xdeadbeeffeedface)(a, b, c, d, e, f);
-}
-
-void End(void)
-{
-}
-
-#include
-const void* ptrs[] =
-{
- Depart0, Depart1, Depart2, Depart3, Depart4, Depart5, Depart6,
- Arrive0, Arrive1, Arrive2, Arrive3, Arrive4, Arrive5, Arrive6,
- End
-};
-
-void print(const char* name, int offs)
-{
- printf("\t\t\tprivate static readonly byte[][] %s =\n\t\t\t{\n", name);
- for (int i = offs; i < offs + 7; i++)
- {
- printf("\t\t\t\tnew byte[] { ");
- const uint8_t* start = ptrs[i];
- const uint8_t* end = ptrs[i + 1];
- while (start < end)
- printf("0x%02x, ", *start++);
- printf("},\n");
- }
- printf("\t\t\t};\n");
-}
-
-int main(void)
-{
- // "Depart" and "Arrive" are switched here relative to the function names because this code was originally created for
- // sysv host ms guest, but now it's the other way around
- print("Arrive", 0);
- print("Depart", 7);
- return 0;
-}
diff --git a/waterbox/thunk/test.txt b/waterbox/thunk/test.txt
deleted file mode 100644
index 8aa235697e..0000000000
--- a/waterbox/thunk/test.txt
+++ /dev/null
@@ -1,20 +0,0 @@
- private static readonly byte[][] Arrive =
- {
- new byte[] { 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x48, 0x83, 0xec, 0x28, 0xff, 0xd0, 0x48, 0x83, 0xc4, 0x28, 0xc3, 0x66, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, },
- new byte[] { 0x48, 0x83, 0xec, 0x28, 0x48, 0x89, 0xf9, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0xff, 0xd0, 0x48, 0x83, 0xc4, 0x28, 0xc3, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, },
- new byte[] { 0x48, 0x83, 0xec, 0x28, 0x48, 0x89, 0xf9, 0x48, 0x89, 0xf2, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0xff, 0xd0, 0x48, 0x83, 0xc4, 0x28, 0xc3, 0x0f, 0x1f, 0x44, 0x00, 0x00, },
- new byte[] { 0x48, 0x83, 0xec, 0x28, 0x49, 0x89, 0xd0, 0x48, 0x89, 0xf9, 0x48, 0x89, 0xf2, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0xff, 0xd0, 0x48, 0x83, 0xc4, 0x28, 0xc3, 0x66, 0x90, },
- new byte[] { 0x48, 0x83, 0xec, 0x28, 0x49, 0x89, 0xd0, 0x49, 0x89, 0xc9, 0x48, 0x89, 0xf2, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x48, 0x89, 0xf9, 0xff, 0xd0, 0x48, 0x83, 0xc4, 0x28, 0xc3, 0x66, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x1f, 0x40, 0x00, },
- new byte[] { 0x48, 0x83, 0xec, 0x10, 0x49, 0x89, 0xc9, 0x48, 0x89, 0xf9, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x41, 0x50, 0x49, 0x89, 0xd0, 0x48, 0x89, 0xf2, 0x48, 0x83, 0xec, 0x20, 0xff, 0xd0, 0x48, 0x83, 0xc4, 0x38, 0xc3, 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, },
- new byte[] { 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x48, 0x83, 0xec, 0x08, 0x41, 0x51, 0x49, 0x89, 0xc9, 0x48, 0x89, 0xf9, 0x41, 0x50, 0x49, 0x89, 0xd0, 0x48, 0x89, 0xf2, 0x48, 0x83, 0xec, 0x20, 0xff, 0xd0, 0x48, 0x83, 0xc4, 0x38, 0xc3, 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, },
- };
- private static readonly byte[][] Depart =
- {
- new byte[] { 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x57, 0x56, 0x48, 0x81, 0xec, 0xa8, 0x00, 0x00, 0x00, 0x0f, 0x29, 0x34, 0x24, 0x0f, 0x29, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x29, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x29, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x29, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x29, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x29, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x29, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x29, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x29, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x0f, 0x28, 0x34, 0x24, 0x0f, 0x28, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x28, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x28, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x28, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x28, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x28, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x28, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x28, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x28, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0x48, 0x81, 0xc4, 0xa8, 0x00, 0x00, 0x00, 0x5e, 0x5f, 0xc3, 0x0f, 0x1f, 0x00, },
- new byte[] { 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x57, 0x48, 0x89, 0xcf, 0x56, 0x48, 0x81, 0xec, 0xa8, 0x00, 0x00, 0x00, 0x0f, 0x29, 0x34, 0x24, 0x0f, 0x29, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x29, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x29, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x29, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x29, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x29, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x29, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x29, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x29, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x0f, 0x28, 0x34, 0x24, 0x0f, 0x28, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x28, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x28, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x28, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x28, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x28, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x28, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x28, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x28, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0x48, 0x81, 0xc4, 0xa8, 0x00, 0x00, 0x00, 0x5e, 0x5f, 0xc3, },
- new byte[] { 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x57, 0x48, 0x89, 0xcf, 0x56, 0x48, 0x89, 0xd6, 0x48, 0x81, 0xec, 0xa8, 0x00, 0x00, 0x00, 0x0f, 0x29, 0x34, 0x24, 0x0f, 0x29, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x29, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x29, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x29, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x29, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x29, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x29, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x29, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x29, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x0f, 0x28, 0x34, 0x24, 0x0f, 0x28, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x28, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x28, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x28, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x28, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x28, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x28, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x28, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x28, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0x48, 0x81, 0xc4, 0xa8, 0x00, 0x00, 0x00, 0x5e, 0x5f, 0xc3, 0x66, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x90, },
- new byte[] { 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x57, 0x48, 0x89, 0xcf, 0x56, 0x48, 0x89, 0xd6, 0x4c, 0x89, 0xc2, 0x48, 0x81, 0xec, 0xa8, 0x00, 0x00, 0x00, 0x0f, 0x29, 0x34, 0x24, 0x0f, 0x29, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x29, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x29, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x29, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x29, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x29, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x29, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x29, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x29, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x0f, 0x28, 0x34, 0x24, 0x0f, 0x28, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x28, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x28, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x28, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x28, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x28, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x28, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x28, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x28, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0x48, 0x81, 0xc4, 0xa8, 0x00, 0x00, 0x00, 0x5e, 0x5f, 0xc3, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, },
- new byte[] { 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x57, 0x48, 0x89, 0xcf, 0x4c, 0x89, 0xc9, 0x56, 0x48, 0x89, 0xd6, 0x4c, 0x89, 0xc2, 0x48, 0x81, 0xec, 0xa8, 0x00, 0x00, 0x00, 0x0f, 0x29, 0x34, 0x24, 0x0f, 0x29, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x29, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x29, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x29, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x29, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x29, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x29, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x29, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x29, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x0f, 0x28, 0x34, 0x24, 0x0f, 0x28, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x28, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x28, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x28, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x28, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x28, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x28, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x28, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x28, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0x48, 0x81, 0xc4, 0xa8, 0x00, 0x00, 0x00, 0x5e, 0x5f, 0xc3, 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, },
- new byte[] { 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x57, 0x48, 0x89, 0xcf, 0x4c, 0x89, 0xc9, 0x56, 0x48, 0x89, 0xd6, 0x4c, 0x89, 0xc2, 0x48, 0x81, 0xec, 0xa8, 0x00, 0x00, 0x00, 0x0f, 0x29, 0x34, 0x24, 0x4c, 0x8b, 0x84, 0x24, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0x29, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x29, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x29, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x29, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x29, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x29, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x29, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x29, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x29, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x0f, 0x28, 0x34, 0x24, 0x0f, 0x28, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x28, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x28, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x28, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x28, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x28, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x28, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x28, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x28, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0x48, 0x81, 0xc4, 0xa8, 0x00, 0x00, 0x00, 0x5e, 0x5f, 0xc3, 0x66, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x1f, 0x40, 0x00, },
- new byte[] { 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x57, 0x48, 0x89, 0xcf, 0x4c, 0x89, 0xc9, 0x56, 0x48, 0x89, 0xd6, 0x4c, 0x89, 0xc2, 0x48, 0x81, 0xec, 0xa8, 0x00, 0x00, 0x00, 0x0f, 0x29, 0x34, 0x24, 0x4c, 0x8b, 0x8c, 0x24, 0xe8, 0x00, 0x00, 0x00, 0x4c, 0x8b, 0x84, 0x24, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0x29, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x29, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x29, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x29, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x29, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x29, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x29, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x29, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x29, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x0f, 0x28, 0x34, 0x24, 0x0f, 0x28, 0x7c, 0x24, 0x10, 0x44, 0x0f, 0x28, 0x44, 0x24, 0x20, 0x44, 0x0f, 0x28, 0x4c, 0x24, 0x30, 0x44, 0x0f, 0x28, 0x54, 0x24, 0x40, 0x44, 0x0f, 0x28, 0x5c, 0x24, 0x50, 0x44, 0x0f, 0x28, 0x64, 0x24, 0x60, 0x44, 0x0f, 0x28, 0x6c, 0x24, 0x70, 0x44, 0x0f, 0x28, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x28, 0xbc, 0x24, 0x90, 0x00, 0x00, 0x00, 0x48, 0x81, 0xc4, 0xa8, 0x00, 0x00, 0x00, 0x5e, 0x5f, 0xc3, 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, },
- };
diff --git a/waterbox/waterboxhost/src/calling_convention_adapters.rs b/waterbox/waterboxhost/src/calling_convention_adapters.rs
new file mode 100644
index 0000000000..d7f7ef002a
--- /dev/null
+++ b/waterbox/waterboxhost/src/calling_convention_adapters.rs
@@ -0,0 +1,127 @@
+// These are mostly unrelated to Waterbox, and are only here because I was too lazy to put them elsewhere.
+
+/// win64 function that calls a sysv64 function and returns its result.
+/// The function is passed as a hidden parameter in rax, and should take 0 arguments, all of which are pointer or integer type.
+#[no_mangle]
+pub unsafe extern "win64" fn depart0() -> usize {
+ let mut fp: extern "sysv64" fn() -> usize;
+ asm!("", out("rax") fp); // Technically, this is wrong as the function could have mangled rax already. In practice, that doesn't happen.
+ fp()
+}
+
+/// win64 function that calls a sysv64 function and returns its result.
+/// The function is passed as a hidden parameter in rax, and should take 1 arguments, all of which are pointer or integer type.
+#[no_mangle]
+pub unsafe extern "win64" fn depart1(a: usize) -> usize {
+ let mut fp: extern "sysv64" fn(a: usize) -> usize;
+ asm!("", out("rax") fp); // Technically, this is wrong as the function could have mangled rax already. In practice, that doesn't happen.
+ fp(a)
+}
+
+/// win64 function that calls a sysv64 function and returns its result.
+/// The function is passed as a hidden parameter in rax, and should take 2 arguments, all of which are pointer or integer type.
+#[no_mangle]
+pub unsafe extern "win64" fn depart2(a: usize, b: usize) -> usize {
+ let mut fp: extern "sysv64" fn(a: usize, b: usize) -> usize;
+ asm!("", out("rax") fp); // Technically, this is wrong as the function could have mangled rax already. In practice, that doesn't happen.
+ fp(a, b)
+}
+
+/// win64 function that calls a sysv64 function and returns its result.
+/// The function is passed as a hidden parameter in rax, and should take 3 arguments, all of which are pointer or integer type.
+#[no_mangle]
+pub unsafe extern "win64" fn depart3(a: usize, b: usize, c: usize) -> usize {
+ let mut fp: extern "sysv64" fn(a: usize, b: usize, c: usize) -> usize;
+ asm!("", out("rax") fp); // Technically, this is wrong as the function could have mangled rax already. In practice, that doesn't happen.
+ fp(a, b, c)
+}
+
+/// win64 function that calls a sysv64 function and returns its result.
+/// The function is passed as a hidden parameter in rax, and should take 4 arguments, all of which are pointer or integer type.
+#[no_mangle]
+pub unsafe extern "win64" fn depart4(a: usize, b: usize, c: usize, d: usize) -> usize {
+ let mut fp: extern "sysv64" fn(a: usize, b: usize, c: usize, d: usize) -> usize;
+ asm!("", out("rax") fp); // Technically, this is wrong as the function could have mangled rax already. In practice, that doesn't happen.
+ fp(a, b, c, d)
+}
+
+/// win64 function that calls a sysv64 function and returns its result.
+/// The function is passed as a hidden parameter in rax, and should take 5 arguments, all of which are pointer or integer type.
+#[no_mangle]
+pub unsafe extern "win64" fn depart5(a: usize, b: usize, c: usize, d: usize, e: usize) -> usize {
+ let mut fp: extern "sysv64" fn(a: usize, b: usize, c: usize, d: usize, e: usize) -> usize;
+ asm!("", out("rax") fp); // Technically, this is wrong as the function could have mangled rax already. In practice, that doesn't happen.
+ fp(a, b, c, d, e)
+}
+
+/// win64 function that calls a sysv64 function and returns its result.
+/// The function is passed as a hidden parameter in rax, and should take 6 arguments, all of which are pointer or integer type.
+#[no_mangle]
+pub unsafe extern "win64" fn depart6(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> usize {
+ let mut fp: extern "sysv64" fn(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> usize;
+ asm!("", out("rax") fp); // Technically, this is wrong as the function could have mangled rax already. In practice, that doesn't happen.
+ fp(a, b, c, d, e, f)
+}
+
+/// sysv64 function that calls a win64 function and returns its result.
+/// The function is passed as a hidden parameter in rax, and should take 0 arguments, all of which are pointer or integer type.
+#[no_mangle]
+pub unsafe extern "sysv64" fn arrive0() -> usize {
+ let mut fp: extern "win64" fn() -> usize;
+ asm!("", out("rax") fp); // Technically, this is wrong as the function could have mangled rax already. In practice, that doesn't happen.
+ fp()
+}
+
+/// sysv64 function that calls a win64 function and returns its result.
+/// The function is passed as a hidden parameter in rax, and should take 1 arguments, all of which are pointer or integer type.
+#[no_mangle]
+pub unsafe extern "sysv64" fn arrive1(a: usize) -> usize {
+ let mut fp: extern "win64" fn(a: usize) -> usize;
+ asm!("", out("rax") fp); // Technically, this is wrong as the function could have mangled rax already. In practice, that doesn't happen.
+ fp(a)
+}
+
+/// sysv64 function that calls a win64 function and returns its result.
+/// The function is passed as a hidden parameter in rax, and should take 2 arguments, all of which are pointer or integer type.
+#[no_mangle]
+pub unsafe extern "sysv64" fn arrive2(a: usize, b: usize) -> usize {
+ let mut fp: extern "win64" fn(a: usize, b: usize) -> usize;
+ asm!("", out("rax") fp); // Technically, this is wrong as the function could have mangled rax already. In practice, that doesn't happen.
+ fp(a, b)
+}
+
+/// sysv64 function that calls a win64 function and returns its result.
+/// The function is passed as a hidden parameter in rax, and should take 3 arguments, all of which are pointer or integer type.
+#[no_mangle]
+pub unsafe extern "sysv64" fn arrive3(a: usize, b: usize, c: usize) -> usize {
+ let mut fp: extern "win64" fn(a: usize, b: usize, c: usize) -> usize;
+ asm!("", out("rax") fp); // Technically, this is wrong as the function could have mangled rax already. In practice, that doesn't happen.
+ fp(a, b, c)
+}
+
+/// sysv64 function that calls a win64 function and returns its result.
+/// The function is passed as a hidden parameter in rax, and should take 4 arguments, all of which are pointer or integer type.
+#[no_mangle]
+pub unsafe extern "sysv64" fn arrive4(a: usize, b: usize, c: usize, d: usize) -> usize {
+ let mut fp: extern "win64" fn(a: usize, b: usize, c: usize, d: usize) -> usize;
+ asm!("", out("rax") fp); // Technically, this is wrong as the function could have mangled rax already. In practice, that doesn't happen.
+ fp(a, b, c, d)
+}
+
+/// sysv64 function that calls a win64 function and returns its result.
+/// The function is passed as a hidden parameter in rax, and should take 5 arguments, all of which are pointer or integer type.
+#[no_mangle]
+pub unsafe extern "sysv64" fn arrive5(a: usize, b: usize, c: usize, d: usize, e: usize) -> usize {
+ let mut fp: extern "win64" fn(a: usize, b: usize, c: usize, d: usize, e: usize) -> usize;
+ asm!("", out("rax") fp); // Technically, this is wrong as the function could have mangled rax already. In practice, that doesn't happen.
+ fp(a, b, c, d, e)
+}
+
+/// sysv64 function that calls a win64 function and returns its result.
+/// The function is passed as a hidden parameter in rax, and should take 6 arguments, all of which are pointer or integer type.
+#[no_mangle]
+pub unsafe extern "sysv64" fn arrive6(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> usize {
+ let mut fp: extern "win64" fn(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> usize;
+ asm!("", out("rax") fp); // Technically, this is wrong as the function could have mangled rax already. In practice, that doesn't happen.
+ fp(a, b, c, d, e, f)
+}
diff --git a/waterbox/waterboxhost/src/context/interop.bin b/waterbox/waterboxhost/src/context/interop.bin
index 7ec18f6622..5cc50eea9a 100644
Binary files a/waterbox/waterboxhost/src/context/interop.bin and b/waterbox/waterboxhost/src/context/interop.bin differ
diff --git a/waterbox/waterboxhost/src/context/interop.s b/waterbox/waterboxhost/src/context/interop.s
index 030b698b79..66a100cd26 100644
--- a/waterbox/waterboxhost/src/context/interop.s
+++ b/waterbox/waterboxhost/src/context/interop.s
@@ -1,5 +1,6 @@
bits 64
org 0x35f00000000
+%define RVA(addr) (addr - 0x35f00000000)
struc Context
.thread_area resq 1
@@ -63,7 +64,11 @@ guest_syscall:
mov r11, [rsp + 8]
mov [gs:0x08], r11
- sub rsp, 8 ; align
+ ; save and then null out SubSystemTib
+ push r10
+ xor r11, r11
+ mov [gs:0x18], r11
+
mov r11, [r10 + Context.host_ptr]
push r11 ; arg 8 to dispatch_syscall: host
push rax ; arg 7 to dispatch_syscall: nr
@@ -76,10 +81,14 @@ guest_syscall:
sub r10, 1
mov [gs:0x08], r10
- mov r10, [gs:0x18]
+ ; Restore SubSystemTib (aka context ptr)
+ mov r10, [rsp + 16]
+ mov [gs:0x18], r10
+
mov rsp, [r10 + Context.guest_rsp]
pop rbp
ret
+guest_syscall_end:
times 0x100-($-$$) int3 ; CALL_GUEST_SIMPLE_ADDR
; alternative to guest call thunks for functions with 0 args
@@ -119,8 +128,12 @@ guest_extcall_impl:
mov r11, [rsp + 8]
mov [gs:0x08], r11
+ ; save and then null out SubSystemTib
+ push r10
+ xor r11, r11
+ mov [gs:0x18], r11
+
mov r11, [r10 + Context.extcall_slots + rax * 8] ; get slot ptr
- sub rsp, 8 ; align
call r11
; set guest TIB data
@@ -129,6 +142,40 @@ guest_extcall_impl:
sub r10, 1
mov [gs:0x08], r10
- mov r10, [gs:0x18]
+ ; Restore SubSystemTib (aka context ptr)
+ mov r10, [rsp]
+ mov [gs:0x18], r10
+
mov rsp, [r10 + Context.guest_rsp]
ret
+guest_extcall_impl_end:
+
+times 0x700-($-$$) int3 ; RUNTIME_TABLE_ADDR
+runtime_function_table:
+ ; https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-runtime_function
+ dd RVA(guest_syscall)
+ dd RVA(guest_syscall_end)
+ dd RVA(guest_syscall_unwind)
+
+ dd RVA(guest_extcall_impl)
+ dd RVA(guest_extcall_impl_end)
+ dd RVA(guest_extcall_impl_unwind)
+guest_syscall_unwind:
+ ; https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64
+ db 1
+ db 5 ; fake prolog
+ db 1
+ db 0
+
+ db 5 ; fake prolog offset
+ db 0x42 ; 40 bytes of stack (remember to count the 16 in call_guest_impl)
+ dw 0 ; unused entry
+guest_extcall_impl_unwind:
+ db 1
+ db 5 ; fake prolog
+ db 1
+ db 0
+
+ db 5 ; fake prolog offset
+ db 0x22 ; 24 bytes of stack (remember to count the 16 in call_guest_impl)
+ dw 0 ; unused entry
diff --git a/waterbox/waterboxhost/src/context/mod.rs b/waterbox/waterboxhost/src/context/mod.rs
index df1bd10f38..9a696e1cba 100644
--- a/waterbox/waterboxhost/src/context/mod.rs
+++ b/waterbox/waterboxhost/src/context/mod.rs
@@ -12,6 +12,7 @@ const ORG: usize = 0x35f00000000;
const CALL_GUEST_IMPL_ADDR: usize = ORG;
const CALL_GUEST_SIMPLE_ADDR: usize = ORG + 0x100;
const EXTCALL_THUNK_ADDR: usize = ORG + 0x200;
+const RUNTIME_TABLE_ADDR: usize = ORG + 0x700;
pub const CALLBACK_SLOTS: usize = 64;
/// Retrieves a function pointer suitable for sending to the guest that will cause
@@ -29,6 +30,15 @@ fn init_interop_area() -> AddressRange {
Protection::RW).unwrap();
addr.slice_mut()[0..bytes.len()].copy_from_slice(bytes);
pal::protect(addr, Protection::RX).unwrap();
+
+ #[cfg(windows)]
+ {
+ let res = winapi::um::winnt::RtlAddFunctionTable(RUNTIME_TABLE_ADDR as *mut _, 2, ORG as u64);
+ if res == 0 {
+ panic!("RtlAddFunctionTable() failed");
+ }
+ }
+
addr
}
}
diff --git a/waterbox/waterboxhost/src/lib.rs b/waterbox/waterboxhost/src/lib.rs
index cb38268653..52645961f4 100644
--- a/waterbox/waterboxhost/src/lib.rs
+++ b/waterbox/waterboxhost/src/lib.rs
@@ -25,6 +25,7 @@ mod cinterface;
mod gdb;
mod context;
mod threading;
+mod calling_convention_adapters;
pub trait IStateable {
fn save_state(&mut self, stream: &mut dyn Write) -> anyhow::Result<()>;