So I've just read the following article:
GCC 4.3.0 exposes a kernel bug http://lwn.net/SubscriberLink/272048/ecf14f359bcdcd15/
And my question is: could this be relevant to Wine? And I don't mean about GCC 4.3.0 but about MSVC.
Here's the core of the issue:
The problem revolves around the x86 direction flag (DF), which governs whether block memory operations operate forward through memory or backwards. GCC [...] 4.3.0, assumes that the direction flag has been cleared [...] at the entry of each function, as is specified by the ABI [...] Prior to 4.3, GCC would emit a cld (clear direction flag) opcode before doing inline string or memory operations.
So any compiler that not clear the direction flag at the start of each function can cause kernel crashes when running on a buggy Linux or BSD kernel.
So the questions are:
Does anyone know if MSVC does a cld in the right places?
What about other popular compilers used to compile Windows applications?
Mac OS X being (loosely) based on the BSD kernels, does it have this issue too?
On Wed, 19 Mar 2008, Francois Gouget wrote: [...]
So any compiler that not clear the direction flag at the start of each function can cause kernel crashes when running on a buggy Linux or BSD kernel.
^^^^^^ remove
Sorry, it's just regular application crashes, not kernel crashes. It would still be interesting to know if that can impact Wine.
Am Mittwoch, 19. März 2008 16:06:34 schrieb Francois Gouget:
On Wed, 19 Mar 2008, Francois Gouget wrote: [...]
So any compiler that not clear the direction flag at the start of each function can cause kernel crashes when running on a buggy Linux or BSD kernel.
^^^^^^ remove
Sorry, it's just regular application crashes, not kernel crashes. It would still be interesting to know if that can impact Wine.
Wouldn't the WINAPI function declaration sort this sort of issues out, if GCC implements it correctly?
Francois Gouget skrev:
The problem revolves around the x86 direction flag (DF), which governs whether block memory operations operate forward through memory or backwards. GCC [...] 4.3.0, assumes that the direction flag has been cleared [...] at the entry of each function, as is specified by the ABI [...] Prior to 4.3, GCC would emit a cld (clear direction flag) opcode before doing inline string or memory operations.
So any compiler that not clear the direction flag at the start of each function can cause kernel crashes when running on a buggy Linux or BSD kernel.
No, it doesn't say that. The kernel is unaffected. The problem is only with user-mode signal handlers; if DF is set when a signal occurs, the signal handler may get confused.
Does anyone know if MSVC does a cld in the right places?
Maybe. But it hardly matters. Only GCC-generated code is affected. The problem might then show up in Wine signal/exception handling. Things like, say, copying the CONTEXT structures around, for example.
In Wine, you can probably easily manually clear the flag on Wine signal handler entry (init_handler), if you're worried.
Ove Kaaven skrev:
Does anyone know if MSVC does a cld in the right places?
Maybe. But it hardly matters. Only GCC-generated code is affected.
In order to avoid confusion about my answer, I should probably clarify. I was answering this question only:
"Could this kernel bug affect MSVC code?"
To this, the answer is "no", as Wine doesn't run application code from signal handlers. However, some may wonder what we can *learn* from the kernel bug, and maybe formulate a different question:
"Could the new *GCC* cause trouble for Wine, then?"
It's a completely different question, and it also goes far beyond whether Wine's own setup_exception clears DF before invoking exception handlers (currently it doesn't), and into the realm of differences between the Win32 and the Linux ABI. Here, the answer is "yes", but this is the case regardless of the kernel issue, and it is also not limited to exceptions, but applies to *any* call from application code to Wine.
Ove Kaaven ovek@arcticnet.no writes:
Francois Gouget skrev:
Does anyone know if MSVC does a cld in the right places?
Maybe. But it hardly matters. Only GCC-generated code is affected. The problem might then show up in Wine signal/exception handling. Things like, say, copying the CONTEXT structures around, for example.
It matters in the sense that Wine currently doesn't clear the direction flag before calling an exception handler, so if MSVC doesn't do a cld then we'd have the same bug WRT msvc as the Linux kernel has WRT gcc. Of course now that gcc is changed we'll have to make sure to clear the flag regardless of what MSVC does.
Alexandre Julliard skrev:
Ove Kaaven ovek@arcticnet.no writes:
Francois Gouget skrev:
Does anyone know if MSVC does a cld in the right places?
Maybe. But it hardly matters. Only GCC-generated code is affected. The problem might then show up in Wine signal/exception handling. Things like, say, copying the CONTEXT structures around, for example.
It matters in the sense that Wine currently doesn't clear the direction flag before calling an exception handler, so if MSVC doesn't do a cld then we'd have the same bug WRT msvc as the Linux kernel has WRT gcc.
But that's a bit of a different issue, unrelated to the kernel flaw. I was only talking about that flaw. I kind of tried to clarify that in my next followup... oh well.
When it comes to ABI issues with MSVC code, the question isn't so much whether it uses cld, but what Windows does when throwing exceptions. Does Windows clear the DF when it calls exception handlers? If not, then there's hardly any Wine bug here (that doesn't exist on Windows anyway). Perhaps someone should test, but my guess is that Windows doesn't clear it.
(And anyway, my experience is that MSVC assumes DF is undefined, and does the cld.)
Of course now that gcc is changed we'll have to make sure to clear the flag regardless of what MSVC does.
But not just in the exception handling. Everywhere... there's no special case here.
Ove Kaaven ovek@arcticnet.no writes:
But that's a bit of a different issue, unrelated to the kernel flaw. I was only talking about that flaw. I kind of tried to clarify that in my next followup... oh well.
Sure, it has nothing to do with the kernel bug, except that it points to a similar bug in the Wine kernel.
Of course now that gcc is changed we'll have to make sure to clear the flag regardless of what MSVC does.
But not just in the exception handling. Everywhere... there's no special case here.
It depends if MSVC respects that ABI constraint or not. If it doesn't and calls API functions with the flag set then yes, we'd have to clear it everywhere. But if it does respect the ABI, then exception handling is definitely a special case, and we have to clear the flag there, and nowhere else.
Alexandre Julliard skrev:
Ove Kaaven ovek@arcticnet.no writes:
But that's a bit of a different issue, unrelated to the kernel flaw. I was only talking about that flaw. I kind of tried to clarify that in my next followup... oh well.
Sure, it has nothing to do with the kernel bug, except that it points to a similar bug in the Wine kernel.
Yeah, I mentioned that.
Of course now that gcc is changed we'll have to make sure to clear the flag regardless of what MSVC does.
But not just in the exception handling. Everywhere... there's no special case here.
It depends if MSVC respects that ABI constraint or not.
Only if you want to make Wine depend on the compiler used to compile Windows applications. Not all of them are called "MSVC". I know Borland Delphi is used by some these days, and its ABI expectations might be different.
Well, I took a look to see what msvcrt expects these days. Looks like it expects DF clear now. But I don't think this was always the case in the past... (though it's also possible I'm thinking back to win16 here.)
Ove Kaaven ovek@arcticnet.no writes:
Alexandre Julliard skrev:
It depends if MSVC respects that ABI constraint or not.
Only if you want to make Wine depend on the compiler used to compile Windows applications. Not all of them are called "MSVC". I know Borland Delphi is used by some these days, and its ABI expectations might be different.
All other Windows compilers have to respect the ABI as defined by MSVC, if only because all the system dlls are built with MSVC.
Alexandre Julliard skrev:
Ove Kaaven ovek@arcticnet.no writes:
Alexandre Julliard skrev:
It depends if MSVC respects that ABI constraint or not.
Only if you want to make Wine depend on the compiler used to compile Windows applications. Not all of them are called "MSVC". I know Borland Delphi is used by some these days, and its ABI expectations might be different.
All other Windows compilers have to respect the ABI as defined by MSVC, if only because all the system dlls are built with MSVC.
Well, we don't really know how the system dlls are built, they could have different compiler flags and pragmas than the msvcrt, just to protect them against this sort of thing (I doubt a system like Delphi would really need msvcrt, so it wouldn't have to conform to the MSVC ABI, it'd just have to not crash the system DLLs). I don't know, but it's a possibility I wouldn't dismiss out of hand.
Ove Kaaven ovek@arcticnet.no writes:
Alexandre Julliard skrev:
All other Windows compilers have to respect the ABI as defined by MSVC, if only because all the system dlls are built with MSVC.
Well, we don't really know how the system dlls are built, they could have different compiler flags and pragmas than the msvcrt, just to protect them against this sort of thing (I doubt a system like Delphi would really need msvcrt, so it wouldn't have to conform to the MSVC ABI, it'd just have to not crash the system DLLs). I don't know, but it's a possibility I wouldn't dismiss out of hand.
My test with lstrcat demonstrates that this is not the case (lstrcat is in kernel32, not in msvcrt). I don't see any reason to believe that msvcrt is built with a different ABI than the rest of the system.
Ove Kaaven ovek@arcticnet.no writes:
When it comes to ABI issues with MSVC code, the question isn't so much whether it uses cld, but what Windows does when throwing exceptions. Does Windows clear the DF when it calls exception handlers? If not, then there's hardly any Wine bug here (that doesn't exist on Windows anyway). Perhaps someone should test, but my guess is that Windows doesn't clear it.
(And anyway, my experience is that MSVC assumes DF is undefined, and does the cld.)
A quick test on Vista shows that the flag is cleared when calling exception handlers, and that API functions (at least lstrcat) expect it to be cleared on entry and don't do a cld.