Skip to content

[mono][interp] Offset allocation of call args is incorrect #80175

Closed
@BrzVlad

Description

@BrzVlad

The algorithm for allocating offsets for the arguments of a call must respect the following constraint: The base offset of the call must be greater than the offset of any argument of other active call args. (An active call is a call that has not yet been made and at least one of its arguments has been set already). This constraint must be respected because a call can freely overwrite the stack starting at the base offset.

The current algorithm doesn't fully respect this constraint but the issue does not reproduce currently by chance. Consider the following test case (built in Release).

using System;

public class Program
{
	public static int global1 = 1;

	public static void Call1 (int arg)
	{
		Console.WriteLine (arg);
		arg = 0;
	}

	public static void Main (string[] args)
	{
		int call2_arg1 = global1;
		Call1 (global1); // 1st
		int call3_arg1 = global1;
		Call1 (call2_arg1); // 2nd
		Call1 (call3_arg1); // 3rd
		// Should print 1, 1, 1. If buggy, call2_arg1 gets overwritten with 0 during 1st call
	}
}

The current algorithm works as follows. 2nd call becomes first active call because call2_arg gets stored first. 1st call becomes resolved with only one argument. Because 2nd call is active, the argument of 1st call will have to get stored at an offset greater than 2nd call param_area. Because the param area size of 2nd call is 8, the base offset of 1st call is determined to be 8, which is grossly incorrect, because the base offset of 2nd call hasn't yet been determined, while the current offset is basically assuming that it would be 0. In test case, after 1st call, 3rd call becomes active, which forces 2nd call to have its offset higher than 3rd call, therefore not 0.

As a fix, 1st call offset computation should somehow be deferred once 2nd call offset has been computed.

This testcase can be made to fail by simply removing the cprop dreg optimization

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions