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<()>;