
x86 ABI assumptions in OpenAL aren't portable to other platforms
Posted Friday, 23 October, 2009 - 15:32 by jonp inOpenTK/Audio/OpenAL/Alc/Alc.cs has embedded assumptions about the ABI it's running on that mirror those of x86. Unfortunately, those assumptions aren't portable.
In this case, the assumption is this: you can treat a structure <= 8 bytes as if it were an integral type. This allows you to transparently treat a pointer return value as a structure return value:
unsafe public static extern ContextHandle CreateContext([In] IntPtr device, [In] int* attrlist);
alcCreateContext() returns an actual pointer, ContextHandle is a struct, and on x86 things Just Work because, as it happens, sizeof(ContextHandle) == sizeof(IntPtr) so x86 registers are used for the return value.
Other platforms aren't as forgiving. Case in point: ARM. ARM only uses registers for integral types & pointers, and NEVER uses registers for returned structures. Structures always use a "pointer indirection" (as x86 does for structures larger than 8 bytes).
Consequently, that CreateContext() call breaks when running under ARM (at least the ARM ABI as used by the iPhone).
The fix is to use respect the ABI and return IntPtr when actual pointers are being returned. (Or use SafeHandles, which are reference types and thus pointers already.)
The following patch allows OpenAL to be used on the iPhone with MonoTouch's OpenTK.dll:
Index: OpenTK/Audio/OpenAL/Alc/Alc.cs =================================================================== --- OpenTK/Audio/OpenAL/Alc/Alc.cs (revision 2360) +++ OpenTK/Audio/OpenAL/Alc/Alc.cs (working copy) @@ -89,7 +89,14 @@ /// <returns>Returns a pointer to the new context (NULL on failure). The attribute list can be NULL, or a zero terminated list of integer pairs composed of valid ALC attribute tokens and requested values.</returns> [DllImport(Alc.Lib, EntryPoint = "alcCreateContext", ExactSpelling = true, CallingConvention = Alc.Style), SuppressUnmanagedCodeSecurity] [CLSCompliant(false)] - unsafe public static extern ContextHandle CreateContext([In] IntPtr device, [In] int* attrlist); + unsafe private static extern IntPtr sys_CreateContext([In] IntPtr device, [In] int* attrlist); + + [CLSCompliant(false)] + unsafe public static ContextHandle CreateContext([In] IntPtr device, [In] int* attrlist) + { + return new ContextHandle(sys_CreateContext(device, attrlist)); + } + // ALC_API ALCcontext * ALC_APIENTRY alcCreateContext( ALCdevice *device, const ALCint* attrlist ); /// <summary>This function creates a context using a specified device.</summary> @@ -138,7 +145,12 @@ /// <summary>This function retrieves the current context.</summary> /// <returns>Returns a pointer to the current context.</returns> [DllImport(Alc.Lib, EntryPoint = "alcGetCurrentContext", ExactSpelling = true, CallingConvention = Alc.Style), SuppressUnmanagedCodeSecurity()] - public static extern ContextHandle GetCurrentContext(); + private static extern IntPtr sys_GetCurrentContext(); + + public static ContextHandle GetCurrentContext() + { + return new ContextHandle(sys_GetCurrentContext()); + } // ALC_API ALCcontext * ALC_APIENTRY alcGetCurrentContext( void ); /// <summary>This function retrieves a context's device pointer.</summary>


Comments
Re: x86 ABI assumptions in OpenAL aren't portable to other ...
Thanks, this patch is committed in rev. 2386.
Does the same issue affect structure parameters? For example:
Re: x86 ABI assumptions in OpenAL aren't portable to other ...
Yes, this same issue does effect method parameters. Looks like I need to cook up another patch...
Re: x86 ABI assumptions in OpenAL aren't portable to other ...
And a patch:
This really only impacts Alc.cs (at least,
grep -rl --include=\*.cs 'extern.*ContextHandle' .didn't find any other references to files I'm using in MonoTouch).Re: x86 ABI assumptions in OpenAL aren't portable to other ...
Thanks for the patch. A quick audit didn't reveal any other instances of this issue, but I'll add this to the documentation just in case.
Re: x86 ABI assumptions in OpenAL aren't portable to other ...
Will you be committing this soon? I don't see it in r2387.
Thanks.
Re: x86 ABI assumptions in OpenAL aren't portable to other ...
r2387 is the version you created the patch against and I lack time-traveling abilities, so... :)
Committed to r2390.