[PATCH] ntdll: Properly test for LLVM libunwind error codes.

Jinoh Kang jinoh.kang.kr at gmail.com
Fri Dec 10 09:50:45 CST 2021


Commit f37b953e07f (ntdll: Support both HP-UX-like libunwind and LLVM
libunwind error codes., 2021-12-10) made an unsuccessful attempt to fix
UNW_ENOINFO detection on LLVM libunwind.  It turns out that UNW_ENOINFO
is actually negative in LLVM, so there's no need to flip the sign.

Fix this by flipping the return value sign only when UNW_ENOINFO < 0
(LLVM libunwind), and then comparing it against the negated error code.
Overall, all flavours of libunwind return a negative value on error.

Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
---

Notes:
    It turns out my last-minute patch change was based on a faulty assumption.
    I sincerely apologise for the extra hassle.  I'll make sure to test this
    more extensively next time.

 dlls/ntdll/unix/signal_arm.c    | 6 +++---
 dlls/ntdll/unix/signal_arm64.c  | 6 +++---
 dlls/ntdll/unix/signal_x86_64.c | 6 +++---
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c
index b65d6f2ddeb..eaa41d9e139 100644
--- a/dlls/ntdll/unix/signal_arm.c
+++ b/dlls/ntdll/unix/signal_arm.c
@@ -248,13 +248,13 @@ NTSTATUS CDECL unwind_builtin_dll( ULONG type, struct _DISPATCHER_CONTEXT *dispa
         return STATUS_INVALID_DISPOSITION;
     }
     rc = unw_get_proc_info( &cursor, &info );
-    if (rc < 0) rc = -rc;  /* libunwind may return negative error codes */
-    if (rc != UNW_ESUCCESS && rc != UNW_ENOINFO)
+    if (UNW_ENOINFO < 0) rc = -rc;  /* LLVM libunwind has negative error codes */
+    if (rc != UNW_ESUCCESS && rc != -UNW_ENOINFO)
     {
         WARN( "failed to get info: %d\n", rc );
         return STATUS_INVALID_DISPOSITION;
     }
-    if (rc == UNW_ENOINFO || ip < info.start_ip || ip > info.end_ip)
+    if (rc == -UNW_ENOINFO || ip < info.start_ip || ip > info.end_ip)
     {
         NTSTATUS status = context->Pc != context->Lr ?
                           STATUS_SUCCESS : STATUS_INVALID_DISPOSITION;
diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c
index 1a01bb13c85..26910173b81 100644
--- a/dlls/ntdll/unix/signal_arm64.c
+++ b/dlls/ntdll/unix/signal_arm64.c
@@ -212,13 +212,13 @@ NTSTATUS CDECL unwind_builtin_dll( ULONG type, DISPATCHER_CONTEXT *dispatch, CON
         return STATUS_INVALID_DISPOSITION;
     }
     rc = unw_get_proc_info( &cursor, &info );
-    if (rc < 0) rc = -rc;  /* libunwind may return negative error codes */
-    if (rc != UNW_ESUCCESS && rc != UNW_ENOINFO)
+    if (UNW_ENOINFO < 0) rc = -rc;  /* LLVM libunwind has negative error codes */
+    if (rc != UNW_ESUCCESS && rc != -UNW_ENOINFO)
     {
         WARN( "failed to get info: %d\n", rc );
         return STATUS_INVALID_DISPOSITION;
     }
-    if (rc == UNW_ENOINFO || ip < info.start_ip || ip > info.end_ip)
+    if (rc == -UNW_ENOINFO || ip < info.start_ip || ip > info.end_ip)
     {
         TRACE( "no info found for %lx ip %lx-%lx, assuming leaf function\n",
                ip, info.start_ip, info.end_ip );
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index fa73ebb5a10..90fa04f0309 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -1415,13 +1415,13 @@ static NTSTATUS libunwind_virtual_unwind( ULONG64 ip, ULONG64 *frame, CONTEXT *c
     *frame = context->Rsp;
 
     rc = unw_get_proc_info(&cursor, &info);
-    if (rc < 0) rc = -rc;  /* libunwind may return negative error codes */
-    if (rc != UNW_ESUCCESS && rc != UNW_ENOINFO)
+    if (UNW_ENOINFO < 0) rc = -rc;  /* LLVM libunwind has negative error codes */
+    if (rc != UNW_ESUCCESS && rc != -UNW_ENOINFO)
     {
         WARN( "failed to get info: %d\n", rc );
         return STATUS_INVALID_DISPOSITION;
     }
-    if (rc == UNW_ENOINFO || ip < info.start_ip || ip > info.end_ip || info.end_ip == info.start_ip + 1)
+    if (rc == -UNW_ENOINFO || ip < info.start_ip || ip > info.end_ip || info.end_ip == info.start_ip + 1)
         return STATUS_UNSUCCESSFUL;
 
     TRACE( "ip %#lx function %#lx-%#lx personality %#lx lsda %#lx fde %#lx\n",
-- 
2.31.1




More information about the wine-devel mailing list