[Mono-list] Nasty x86_magic_trampoline gremlin: ambiguous call sequences
Eric Kidd
eric.kidd@pobox.com
23 Feb 2002 19:27:13 -0500
--=-f3CcZpZ8zNVUzNBsQ7RH
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
It took me most of the day to get some idea of what's going on here. :-/
I'm running mcs under mono (not mint) on a Debian Linux x86 system.
Compiling certain programs causes the JIT to fail with the following
error:
** ERROR **: file emit-x86.c: line 400 (x86_magic_trampoline): should
not be reached
This error occurs when x86_magic_trampoline is trying to decode the
instruction stream, and finds that 'reg' == 4 (the code for X86_ESP,
which is complete nonsense in a relative jump instruction).
Here's where it gets sticky...
Starting 6 bytes behind the return address, the code stream contains the
following bytes:
53 e8 f3 ff 54 c1
x86_magic_trampoline can match three types of call sites:
.. .. .. ff MR ** // Pattern 1: absolute indirect
ff MR ** ** ** ** // Pattern 2: absolute indirect
.. e8 ** ** ** ** // Pattern 3: PC-relative
.. = unused
MR = ModR/M byte
** = addressing data
The code stream in question should be interpreted as pattern 3 (I
think), but x86_magic_trampoline tries to match against pattern 1
first--and gets confused. Yuck.
Interestingly enough, patterns 2 and 3 are not ambiguous--Mono never
generates an MR byte such that (mr_byte & 0xF8 == 0xe8).
Could somebody who understands this code take a look at this bug?
I've attached some ugly C# source code which causes the mono-0.9 release
to die in this fashion. You may not be able to trigger it; this bug is
heavily dependent on where things are located in memory.
Cheers,
Eric
--=-f3CcZpZ8zNVUzNBsQ7RH
Content-Disposition: attachment; filename=delegate_test.cs
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ANSI_X3.4-1968
using System;
delegate void PersonArrivedHandler (object source, PersonArrivedArgs args);
class PersonArrivedArgs /*: EventArgs*/ {
public string name;
public PersonArrivedArgs (string name) {
this.name =3D name;
}
}
class Greeter {
string greeting;
public Greeter (string greeting) {
this.greeting =3D greeting;
}
public void HandlePersonArrived (object source, PersonArrivedArgs args)=
{
Console.WriteLine(greeting, args.name);
}
}
class Room {
public event PersonArrivedHandler PersonArrived;
public Room () {}
public void AddPerson (string name) {
PersonArrived(this, null); //(this, PersonArrivedArgs(name));
}
}
class DelegateTest {
static void Main () {
Console.WriteLine("Hello, world!");
}
}
--=-f3CcZpZ8zNVUzNBsQ7RH--