[libunwind] libunwind: Implement the unw_strerror function for better nongnu libunwind compatibility (PR #160887)
Gleb Popov via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 26 06:40:32 PDT 2025
https://github.com/arrowd created https://github.com/llvm/llvm-project/pull/160887
As it was explained to me in https://discourse.llvm.org/t/libunwinds-raison-detre/88283/2 the LLVM version of libunwind is mostly compatible with nongnu one. This change improves the compatibility a bit further.
>From f892211da547a857beeec279c2e493fbd75d0865 Mon Sep 17 00:00:00 2001
From: Gleb Popov <6yearold at gmail.com>
Date: Fri, 26 Sep 2025 12:58:47 +0300
Subject: [PATCH] libunwind: Implement the unw_strerror function for better
nongnu libunwind compatibility
---
libunwind/include/libunwind.h | 1 +
libunwind/src/libunwind.cpp | 23 +++++++++++++++++++++++
libunwind/src/libunwind_ext.h | 1 +
3 files changed, 25 insertions(+)
diff --git a/libunwind/include/libunwind.h b/libunwind/include/libunwind.h
index 94928f436025a..9d2ccc4dda7fa 100644
--- a/libunwind/include/libunwind.h
+++ b/libunwind/include/libunwind.h
@@ -130,6 +130,7 @@ extern int unw_is_fpreg(unw_cursor_t *, unw_regnum_t) LIBUNWIND_AVAIL;
extern int unw_is_signal_frame(unw_cursor_t *) LIBUNWIND_AVAIL;
extern int unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *) LIBUNWIND_AVAIL;
//extern int unw_get_save_loc(unw_cursor_t*, int, unw_save_loc_t*);
+extern const char *unw_strerror (int) LIBUNWIND_AVAIL;
extern unw_addr_space_t unw_local_addr_space;
diff --git a/libunwind/src/libunwind.cpp b/libunwind/src/libunwind.cpp
index cf39ec5f7dbdf..23335ba577e52 100644
--- a/libunwind/src/libunwind.cpp
+++ b/libunwind/src/libunwind.cpp
@@ -347,6 +347,29 @@ void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start) {
}
#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
+
+/// Maps the UNW_* error code to a textual representation
+_LIBUNWIND_HIDDEN const char *__unw_strerror(int error_code) {
+ switch (error_code) {
+ case UNW_ESUCCESS: return "no error";
+ case UNW_EUNSPEC: return "unspecified (general) error";
+ case UNW_ENOMEM: return "out of memory";
+ case UNW_EBADREG: return "bad register number";
+ case UNW_EREADONLYREG: return "attempt to write read-only register";
+ case UNW_ESTOPUNWIND: return "stop unwinding";
+ case UNW_EINVALIDIP: return "invalid IP";
+ case UNW_EBADFRAME: return "bad frame";
+ case UNW_EINVAL: return "unsupported operation or bad value";
+ case UNW_EBADVERSION: return "unwind info has unsupported version";
+ case UNW_ENOINFO: return "no unwind info found";
+#if defined(_LIBUNWIND_TARGET_AARCH64) && !defined(_LIBUNWIND_IS_NATIVE_ONLY)
+ case UNW_ECROSSRASIGNING: return "return address require authentication";
+#endif
+ }
+ return "invalid error code";
+}
+_LIBUNWIND_WEAK_ALIAS(__unw_strerror, unw_strerror)
+
#endif // !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__)
#ifdef __APPLE__
diff --git a/libunwind/src/libunwind_ext.h b/libunwind/src/libunwind_ext.h
index 28db43a4f6eef..ed503ceb70c5a 100644
--- a/libunwind/src/libunwind_ext.h
+++ b/libunwind/src/libunwind_ext.h
@@ -42,6 +42,7 @@ extern int __unw_get_proc_info(unw_cursor_t *, unw_proc_info_t *);
extern int __unw_is_fpreg(unw_cursor_t *, unw_regnum_t);
extern int __unw_is_signal_frame(unw_cursor_t *);
extern int __unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *);
+extern const char *__unw_strerror(int);
#if defined(_AIX)
extern uintptr_t __unw_get_data_rel_base(unw_cursor_t *);
More information about the cfe-commits
mailing list