On 7/2/20 12:55, Alexandre Julliard wrote:
Paul Gofman pgofman@codeweavers.com writes:
On 7/2/20 12:09, Alexandre Julliard wrote:
Paul Gofman pgofman@codeweavers.com writes:
Context record may be stored on stack below context stack. This happens, e. g., with RtlRaiseException().
That doesn't seem right, there may be other things on the stack too. Is there a reason to switch stack to context->Rsp at all?
Exception unwinding does not work otherwise, and that matches stack layout on Windows: the context and exception record on stack has a fixed gap after context's Rsp. But it looks we don't need anything else from the stack besides the context, or am I missing something?
Potentially the exception record, if we allow things to be below context->Rsp. Maybe RtlRaiseException is not setting the right Rsp? This could use a few more tests.
We could change RtlRaiseException() to set up the stack in a way it is usable for passing to KiUserExceptionDispatcher and thus avoid copying context at all, but this way NtRaiseException() would rely on being called from RtlRaiseException(), while it works other ways too.
What I see from additional tests on Windows is that in KiUserExceptionDispatcher hook the rsp (that is, context pointer) has offset 0x710 from context->Rsp, regardless of how NtRaiseException is called: directly or through RtlRaiseException() with BeingDebugged set to TRUE. The same offset is from fault. So I am not sure how changing RtlRaiseException() can bring that all in line? Maybe I can just save exception record on the current stack before copying context to avoid potential problems?
I guess some part of trickiness here comes from the fact that unlike Windows kernel part we have the same stack in unix part.
As a separate note, I noticed during testing that NtRaiseException() can capture the context itself if the context flags don't have CONTEXT_CONTROL flag (otherwise it uses the given context even if it is completely bogus). But this doesn't seem related here.