On Tue, 22 Apr 2025, Jacek Caban wrote:

+    memcpy( &context.Xmm6, &buf->Xmm6, 10 * sizeof(context.Xmm6) );
+    unwind_one_frame( &context );
+    if (!RtlIsEcCode( context.Rip ))  /* caller is x64, use its context instead of the ARM one */
+    {
+        buf->Rbx = context.Rbx;
+        buf->Rsp = context.Rsp;

Hmm, this feels odd. If we're not called from x86_64 code, we'd keep the values as they were within __intrinsic_setjmpex, but if we're called from x86_64, we update the jmp_buf contents with that of one stack frame further up.

Is that specifically what we need to do? Wouldn't it be more consistent if we'd e.g. always store the output after this one unwind step?

But I guess there's something more to it than I realize here?

In any case, this perhaps could use some more comments for clarity.


Note that __intrinsic_setjmpex stores x30 (the link register) as Rip, so the context in the buffer already represents the caller’s stack frame state.

Oh, right, I missed that detail.

If we’re called from x64 code, there’s an additional entry thunk between the x64 code and __intrinsic_setjmpex. My understanding is that this unwinding is intended to skip over the entry thunk’s frame, so that the context points to the x64 caller, matching what we’d see on a real x86 system. I will extend the comment.

Thanks, that makes sense!

// Martin

_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to