[Mono-list] Nasty x86_magic_trampoline gremlin: ambiguous call sequences

Eric Kidd eric.kidd@pobox.com
23 Feb 2002 19:27:13 -0500

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 **: 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.


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!");