Skip to content

Commit

Permalink
[amd64] Fix tailcall with arguments passed on stack (dotnet#34814)
Browse files Browse the repository at this point in the history
On all platforms, OP_TAILCALL copies the arguments (that are passed on the stack) from the param area in the current frame, to the param area in the caller frame, meaning that it expects the arguments to be passed normally on the stack. However, on amd64, mono_arch_emit_call was storing these arguments directly in the param area of the caller (EMIT_NEW_ARGSTORE), instead of the param area of the current frame. OP_TAILCALL would then override the already set stack parameters with random data from the uninitialized param area of the current frame.
  • Loading branch information
BrzVlad authored Apr 22, 2020
1 parent 84ec25f commit 4334034
Showing 1 changed file with 2 additions and 12 deletions.
14 changes: 2 additions & 12 deletions src/mono/mono/mini/mini-amd64.c
Original file line number Diff line number Diff line change
Expand Up @@ -2242,8 +2242,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)

t = mini_get_underlying_type (t);
//XXX what about ArgGSharedVtOnStack here?
// FIXME tailcall is not always yet initialized.
if (ainfo->storage == ArgOnStack && !MONO_TYPE_ISSTRUCT (t) && !call->tailcall) {
if (ainfo->storage == ArgOnStack && !MONO_TYPE_ISSTRUCT (t)) {
if (!t->byref) {
if (t->type == MONO_TYPE_R4)
MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER4_MEMBASE_REG, AMD64_RSP, ainfo->offset, in->dreg);
Expand Down Expand Up @@ -2302,18 +2301,9 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
case ArgValuetypeAddrOnStack:
case ArgGSharedVtInReg:
case ArgGSharedVtOnStack: {
// FIXME tailcall is not always yet initialized.
if (ainfo->storage == ArgOnStack && !MONO_TYPE_ISSTRUCT (t) && !call->tailcall)
if (ainfo->storage == ArgOnStack && !MONO_TYPE_ISSTRUCT (t))
/* Already emitted above */
break;
//FIXME what about ArgGSharedVtOnStack ?
// FIXME tailcall is not always yet initialized.
if (ainfo->storage == ArgOnStack && call->tailcall) {
MonoInst *call_inst = (MonoInst*)call;
cfg->args [i]->flags |= MONO_INST_VOLATILE;
EMIT_NEW_ARGSTORE (cfg, call_inst, i, in);
break;
}

guint32 align;
guint32 size;
Expand Down

0 comments on commit 4334034

Please sign in to comment.