AaronRobinsonMSFT / DNNE

Prototype native exports for a .NET Assembly.
MIT License
397 stars 41 forks source link

x86 provides export functions with @2 names #52

Closed mikasoukhov closed 3 years ago

mikasoukhov commented 3 years ago

For x64 export is well. For x86 exports provides function_name@2 for all functions.

AaronRobinsonMSFT commented 3 years ago

@mikasoukhov My original intent here was to consider this behavior as "by-design". I am assuming it is only observed on Windows since the default export calling convention on Windows-x86 is stdcall - non-Windows the default is cdecl. Using the UnmanagedCallersOnly.CallConvs property one can override this default. Using CallConvCdecl would address the issue; however, if stdcall is desired then we may need to consider other options.

On Windows, stdcall isn't common on non-Windows in my experience, MSVC decorates the export as defined here. There are ways default decoration can be overridden as defined here and I am more than willing to expose hooks to accomplish this (e.g. user supplied .def file). I don't know if GCC/Clang decorate stdcall in the same way, but it is possible.

As mentioned, my gut reaction is that this is "by-design" but I do appreciate the expectation of the "EntryPoint" contract. My biggest concern with attempting to properly support this is that DNNE would need to compute the anticipated export when using stdcall and although that is likely straight forward I am sure there are corner cases to be missed and cause more grief. Ideally one would always avoid using stdcall and defer to cdecl on x86 or be comfortable with supplying a .def file on Windows.

Do you have a strong opinion in this case?

mikasoukhov commented 3 years ago

1) I am mentioned Windows x86. 2) I am not familiar with C++ and my report was related about DNNE. Generated assembly not work with x86 unmanaged apps.

AaronRobinsonMSFT commented 3 years ago

@mikasoukhov Thanks for the additional context. My recommendation then is to update your exports to define the cdecl calling convention. For example:

[UnmanagedCallersOnly(CallConvs = new []{typeof(System.Runtime.CompilerServices.CallConvCdecl)})]

I will update the documentation with details about this issue and the appropriate mitigation.