Martin Storsjo : ntdll: Fix byte vs register units in unwind_packed_data.

Alexandre Julliard julliard at winehq.org
Thu May 28 17:11:10 CDT 2020


Module: wine
Branch: master
Commit: d6e9795223f0c978132342d77b36f8284ab1aed3
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=d6e9795223f0c978132342d77b36f8284ab1aed3

Author: Martin Storsjo <martin at martin.st>
Date:   Thu May 28 11:14:39 2020 +0300

ntdll: Fix byte vs register units in unwind_packed_data.

restore_regs and restore_fpregs take offsets in units of registers,
not bytes.

Signed-off-by: Martin Storsjo <martin at martin.st>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/signal_arm64.c | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c
index 7a3625b706..8ccf3da57e 100644
--- a/dlls/ntdll/signal_arm64.c
+++ b/dlls/ntdll/signal_arm64.c
@@ -1517,6 +1517,7 @@ static void *unwind_packed_data( ULONG_PTR base, ULONG_PTR pc, RUNTIME_FUNCTION
     int i;
     unsigned int len, offset, skip = 0;
     unsigned int int_size = func->u.s.RegI * 8, fp_size = func->u.s.RegF * 8, regsave, local_size;
+    unsigned int int_regs, fp_regs, saved_regs, local_size_regs;
 
     TRACE( "function %lx-%lx: len=%#x flag=%x regF=%u regI=%u H=%u CR=%u frame=%x\n",
            base + func->BeginAddress, base + func->BeginAddress + func->u.s.FunctionLength * 4,
@@ -1529,6 +1530,11 @@ static void *unwind_packed_data( ULONG_PTR base, ULONG_PTR pc, RUNTIME_FUNCTION
     regsave = ((int_size + fp_size + 8 * 8 * func->u.s.H) + 0xf) & ~0xf;
     local_size = func->u.s.FrameSize * 16 - regsave;
 
+    int_regs = int_size / 8;
+    fp_regs = fp_size / 8;
+    saved_regs = regsave / 8;
+    local_size_regs = local_size / 8;
+
     /* check for prolog/epilog */
     if (func->u.s.Flag == 1)
     {
@@ -1568,9 +1574,9 @@ static void *unwind_packed_data( ULONG_PTR base, ULONG_PTR pc, RUNTIME_FUNCTION
             context->u.X[30] = fp[1];
         }
         context->Sp += local_size;
-        if (fp_size) restore_fpregs( 8, fp_size / 8, int_size, context, ptrs );
-        if (func->u.s.CR == 1) restore_regs( 30, 1, int_size - 8, context, ptrs );
-        restore_regs( 19, func->u.s.RegI, -regsave, context, ptrs );
+        if (fp_size) restore_fpregs( 8, fp_regs, int_regs, context, ptrs );
+        if (func->u.s.CR == 1) restore_regs( 30, 1, int_regs - 1, context, ptrs );
+        restore_regs( 19, func->u.s.RegI, -saved_regs, context, ptrs );
     }
     else
     {
@@ -1582,7 +1588,7 @@ static void *unwind_packed_data( ULONG_PTR base, ULONG_PTR pc, RUNTIME_FUNCTION
             if (local_size <= 512)
             {
                 /* stp x29,lr,[sp,-#local_size]! */
-                if (pos++ > skip) restore_regs( 29, 2, -local_size, context, ptrs );
+                if (pos++ > skip) restore_regs( 29, 2, -local_size_regs, context, ptrs );
                 break;
             }
             /* stp x29,lr,[sp,0] */
@@ -1603,16 +1609,16 @@ static void *unwind_packed_data( ULONG_PTR base, ULONG_PTR pc, RUNTIME_FUNCTION
         {
             if (func->u.s.RegF % 2 == 0 && pos++ > skip)
                 /* str d%u,[sp,#fp_size] */
-                restore_fpregs( 8 + func->u.s.RegF, 1, int_size + fp_size - 8, context, ptrs );
+                restore_fpregs( 8 + func->u.s.RegF, 1, int_regs + fp_regs - 1, context, ptrs );
             for (i = func->u.s.RegF / 2 - 1; i >= 0; i--)
             {
                 if (pos++ <= skip) continue;
                 if (!i && !int_size)
                      /* stp d8,d9,[sp,-#regsave]! */
-                    restore_fpregs( 8, 2, -regsave, context, ptrs );
+                    restore_fpregs( 8, 2, -saved_regs, context, ptrs );
                 else
                      /* stp dn,dn+1,[sp,#offset] */
-                    restore_fpregs( 8 + 2 * i, 2, int_size + 16 * i, context, ptrs );
+                    restore_fpregs( 8 + 2 * i, 2, int_regs + 2 * i, context, ptrs );
             }
         }
 
@@ -1621,15 +1627,15 @@ static void *unwind_packed_data( ULONG_PTR base, ULONG_PTR pc, RUNTIME_FUNCTION
             if (func->u.s.RegI % 2)
             {
                 /* stp xn,lr,[sp,#offset] */
-                if (func->u.s.CR == 1) restore_regs( 30, 1, int_size - 8, context, ptrs );
+                if (func->u.s.CR == 1) restore_regs( 30, 1, int_regs - 1, context, ptrs );
                 /* str xn,[sp,#offset] */
                 restore_regs( 18 + func->u.s.RegI, 1,
-                              (func->u.s.RegI > 1) ? 8 * func->u.s.RegI - 8 : -regsave,
+                              (func->u.s.RegI > 1) ? func->u.s.RegI - 1 : -saved_regs,
                               context, ptrs );
             }
             else if (func->u.s.CR == 1)
                 /* str lr,[sp,#offset] */
-                restore_regs( 30, 1, func->u.s.RegI ? int_size - 8 : -regsave, context, ptrs );
+                restore_regs( 30, 1, func->u.s.RegI ? int_regs - 1 : -saved_regs, context, ptrs );
         }
 
         for (i = func->u.s.RegI / 2 - 1; i >= 0; i--)
@@ -1637,10 +1643,10 @@ static void *unwind_packed_data( ULONG_PTR base, ULONG_PTR pc, RUNTIME_FUNCTION
             if (pos++ <= skip) continue;
             if (i)
                 /* stp xn,xn+1,[sp,#offset] */
-                restore_regs( 19 + 2 * i, 2, 16 * i, context, ptrs );
+                restore_regs( 19 + 2 * i, 2, 2 * i, context, ptrs );
             else
                 /* stp x19,x20,[sp,-#regsave]! */
-                restore_regs( 19, 2, -regsave, context, ptrs );
+                restore_regs( 19, 2, -saved_regs, context, ptrs );
         }
     }
     return NULL;




More information about the wine-cvs mailing list