Commit 5c101ed58f5 (ntdll: Fix unwinding of leaf functions on ARM64., 2019-10-23) changed the sign of UNW_ENOINFO when testing for error from libunwind. However, unw_get_proc_info() does not return a sign-flipped error code. Thus, comparing it with -UNW_ENOINFO is a no-op.
Fix this by not negating UNW_ENOINFO.
Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com ---
Notes: As a result of this change, Unix-side non-leaf functions that lack asynchronous unwind tables may erroneously be recognised as leaf functions.
To fix this, ideally unwind_builtin_dll shall never be called for PE modules (builtin or not).
dlls/ntdll/unix/signal_arm.c | 4 ++-- dlls/ntdll/unix/signal_arm64.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c index f4987f902e0..4f65a03793e 100644 --- a/dlls/ntdll/unix/signal_arm.c +++ b/dlls/ntdll/unix/signal_arm.c @@ -248,12 +248,12 @@ NTSTATUS CDECL unwind_builtin_dll( ULONG type, struct _DISPATCHER_CONTEXT *dispa return STATUS_INVALID_DISPOSITION; } rc = unw_get_proc_info( &cursor, &info ); - if (rc != UNW_ESUCCESS && rc != -UNW_ENOINFO) + 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 ae44fb02982..40c484c530b 100644 --- a/dlls/ntdll/unix/signal_arm64.c +++ b/dlls/ntdll/unix/signal_arm64.c @@ -212,12 +212,12 @@ NTSTATUS CDECL unwind_builtin_dll( ULONG type, DISPATCHER_CONTEXT *dispatch, CON return STATUS_INVALID_DISPOSITION; } rc = unw_get_proc_info( &cursor, &info ); - if (rc != UNW_ESUCCESS && rc != -UNW_ENOINFO) + 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 );
Jinoh Kang jinoh.kang.kr@gmail.com writes:
Commit 5c101ed58f5 (ntdll: Fix unwinding of leaf functions on ARM64., 2019-10-23) changed the sign of UNW_ENOINFO when testing for error from libunwind. However, unw_get_proc_info() does not return a sign-flipped error code. Thus, comparing it with -UNW_ENOINFO is a no-op.
That seems specific to the LLVM version, the standalone libunwind definitely returns negative values:
https://github.com/libunwind/libunwind/blob/master/src/dwarf/Gparser.c#L468
On 12/9/21 23:28, Alexandre Julliard wrote:
Jinoh Kang jinoh.kang.kr@gmail.com writes:
Commit 5c101ed58f5 (ntdll: Fix unwinding of leaf functions on ARM64., 2019-10-23) changed the sign of UNW_ENOINFO when testing for error from libunwind. However, unw_get_proc_info() does not return a sign-flipped error code. Thus, comparing it with -UNW_ENOINFO is a no-op.
That seems specific to the LLVM version, the standalone libunwind definitely returns negative values:
https://github.com/libunwind/libunwind/blob/master/src/dwarf/Gparser.c#L468
I just learned that libunwind functions may return *both* positive and negative error codes. Probably wise to test for both?
Quoting https://github.com/libunwind/libunwind/blob/a8609062849f8261a40c170941400e6b...
/* Error codes. The unwind routines return the *negated* values of these error codes on error and a non-negative value on success. */ typedef enum { UNW_ESUCCESS = 0, /* no error */ UNW_EUNSPEC, /* unspecified (general) error */