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". Its 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
gcc.diff
Description: Binary data