Hello,

I am working on the Wine project(www.winehq.org), which (obviously) uses gcc
to compile its own code. There are some Windows applications like
Steam(www.steampowered.com) and others which try to hook Win32 API functions
by patching the first 5 bytes of the Windows API functions exported by our
DLLs with a jump. Unfortunately these applications are rather picky
regarding the instructions they expect in the prolog. I'm trying to add some
function attributes to give Wine more control over that, but I am afraid
that I need some help.

This is what the average Win32 API prolog looks like:

XXXXXXXX:   8b ff          mov    %edi,%edi
XXXXXXXX:   55             push   %ebp
XXXXXXXX:   8b ec          mov    %esp,%ebp

There are two differences to the code gcc generates that hurt us:

8b ff          mov    %edi,%edi
This instruction was added by Microsoft in XP Service Pack 2 to make hooking
the Win32 API functions easier. Microsoft uses it themselves for a feature
they call "hotpatching", to avoid reboots after updates. Consequently many
other applications try to use it. I think Microsoft generates it using the
__naked__ function attribute by writing the function prolog and epilog by
hand, but I saw some mails on this list which make it pretty clear that this
will never ever be supported in gcc, and we don't like it ourselves and
would prefer some other solution.

The attached file gcc.diff contains a kinda helpless attempt to generate
this instruction. My first problem is that any optimization optimizes it
away because it is a NOP. Is there any way to prevent the optimizer from
removing it?

The second problem is that I haven't found yet how to read my attribute
"ms_hook" in that code. The different trees still confuse me.

Finally, is there a nicer way to specify the %edi register? Hardcoding the
value 5 doesn't look pretty.


8b ec          mov    %esp,%ebp
The problem here is the "8b ec". Binutils generates "89 e5". It’s the same
instruction, but the Microsoft version has the direction inversion flag set.
Unfortunately the Windows apps only know the 8b ec version because that is
all they find on Windows.
(This flag is also set on the mov %edi, %edi above - gcc currently generates
89 ff)

I talked to the binutils maintainers and they helped me by adding a new
instruction suffix .s:
movl    %esp, %ebp   => 89 e5
movl.s  %esp, %ebp   => eb ec

Now I need gcc to set this suffix, but here I am pretty lost. I haven't
found out yet how to add this to the gcc code. The other issue is
compatibility with old binutils versions, since so far this feature is in
svn only and no release has it. Does gcc attempt to detect binutils
features, or does it just assume that everything it needs is there?

Thanks for your help,
Stefan Dösinger

Attachment: gcc.diff
Description: Binary data

Reply via email to