-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Open
Labels
Milestone
Description
GenericPInvokeCalliHelper produces a problem on linux.
GenericPInvokeCalliHelper takes away VASigCookie argument from the stack and moves on its place return address value. It breaks 16 byte stack alignment and leads to further problems on esp usage: execution could break inside CHECK_STACK_ALIGNMENT macro or on movap [esp+offset] instruction. The problem spreads until caller of GenericPInvokeCalliHelper will restore esp from ebp on self epilog.
runtime/src/coreclr/vm/i386/asmhelpers.S
Lines 619 to 677 in aa52611
| // ========================================================================== | |
| // Invoked for marshaling-required unmanaged CALLI calls as a stub. | |
| // EAX - the unmanaged target | |
| // ECX, EDX - arguments | |
| // [ESP + 4] - the VASigCookie | |
| // | |
| LEAF_ENTRY GenericPInvokeCalliHelper, _TEXT | |
| // save the target | |
| push eax | |
| // EAX <- VASigCookie | |
| mov eax, [esp + 8] // skip target and retaddr | |
| mov eax, [eax + VASigCookie__StubOffset] | |
| test eax, eax | |
| jz LOCAL_LABEL(GoCallCalliWorker) | |
| // --------------------------------------- | |
| push eax | |
| // stack layout at this point: | |
| // | |
| // | ... | | |
| // | stack arguments | ESP + 16 | |
| // +----------------------+ | |
| // | VASigCookie* | ESP + 12 | |
| // +----------------------+ | |
| // | return address | ESP + 8 | |
| // +----------------------+ | |
| // | CALLI target address | ESP + 4 | |
| // +----------------------+ | |
| // | stub entry point | ESP + 0 | |
| // ------------------------ | |
| // remove VASigCookie from the stack | |
| mov eax, [esp + 8] | |
| mov [esp + 12], eax | |
| // move stub entry point below the RA | |
| mov eax, [esp] | |
| mov [esp + 8], eax | |
| // load EAX with the target address | |
| pop eax | |
| pop eax | |
| // stack layout at this point: | |
| // | |
| // | ... | | |
| // | stack arguments | ESP + 8 | |
| // +----------------------+ | |
| // | return address | ESP + 4 | |
| // +----------------------+ | |
| // | stub entry point | ESP + 0 | |
| // ------------------------ | |
| // CALLI target address is in EAX | |
| ret |
I see couple of options to resolve the problem:
- Besides
VASigCookieGenericPInvokeCalliHelpertakesthe unmanaged targetargument viaeaxregister. Caller could create a structure{the unmanaged target; VASigCookie}and pass a pointer to the structure viaeax.GenericPInvokeCalliHelperable to read the structure and placethe unmanaged targetineaxto the moment ofIL_STUB_PIvokecall. So this option changes only caller->GenericPInvokeCalliHelperinterface,GenericPInvokeCalliHelper->IL_STUB_PIvokeinterface remains unchanged. - Change all caller->
IL_STUB_PIvokecalling convention to use only stack instead ofecx+edx+ stack to pass arguments. It will freeecxregister which could be used during caller->GenericPInvokeCalliHelperto keepVASigCookievalue.
@jkotas Will such changes break some code outside of GenericPInvokeCalliHelper case? Which variant is preferable?
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
No status