Skip to content

Commit 1b4826b

Browse files
authored
Support using llvm-libunwind
This commit adds support for using llvm-libunwind for kernels built using llvm and clang. The two differences are that the largest register index is given by _LIBUNWIND_HIGHEST_DWARF_REGISTER, we need to check whether the register is a floating point register and the prototype for unw_regname takes the unwind cursor as the first argument. Reviewed-by: Rob Norris <[email protected]> Reviewed-by: Tony Hutter <[email protected]> Signed-off-by: Sebastian Pauka <[email protected]> Closes openzfs#17230
1 parent 7031a48 commit 1b4826b

File tree

2 files changed

+65
-17
lines changed

2 files changed

+65
-17
lines changed

config/user-libunwind.m4

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,22 @@ AC_DEFUN([ZFS_AC_CONFIG_USER_LIBUNWIND], [
3434
], [
3535
AC_MSG_RESULT([no])
3636
])
37+
dnl LLVM includes it's own libunwind library, which
38+
dnl defines the highest numbered register in a different
39+
dnl way, and has an incompatible unw_resname function.
40+
AC_MSG_CHECKING([whether libunwind is llvm libunwind])
41+
AC_COMPILE_IFELSE([
42+
AC_LANG_PROGRAM([
43+
#include <libunwind.h>
44+
#if !defined(_LIBUNWIND_HIGHEST_DWARF_REGISTER)
45+
#error "_LIBUNWIND_HIGHEST_DWARF_REGISTER is not defined"
46+
#endif
47+
], [])], [
48+
AC_MSG_RESULT([yes])
49+
AC_DEFINE(IS_LIBUNWIND_LLVM, 1, [libunwind is llvm libunwind])
50+
], [
51+
AC_MSG_RESULT([no])
52+
])
3753
AX_RESTORE_FLAGS
3854
], [
3955
AS_IF([test "x$with_libunwind" = "xyes"], [

lib/libspl/backtrace.c

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,26 @@
4141
do { ssize_t r __maybe_unused = write(fd, s, n); } while (0)
4242
#define spl_bt_write(fd, s) spl_bt_write_n(fd, s, sizeof (s)-1)
4343

44-
#if defined(HAVE_LIBUNWIND)
44+
#ifdef HAVE_LIBUNWIND
45+
/*
46+
* libunwind-gcc and libunwind-llvm both list registers using an enum,
47+
* unw_regnum_t, however they indicate the highest numbered register for
48+
* a given architecture in different ways. We can check which one is defined
49+
* and mark which libunwind is in use
50+
*/
51+
#ifdef IS_LIBUNWIND_LLVM
52+
#include <libunwind.h>
53+
#define LAST_REG_INDEX _LIBUNWIND_HIGHEST_DWARF_REGISTER
54+
#else
55+
/*
56+
* Need to define UNW_LOCAL_ONLY before importing libunwind.h
57+
* if using libgcc libunwind.
58+
*/
4559
#define UNW_LOCAL_ONLY
4660
#include <libunwind.h>
61+
#define LAST_REG_INDEX UNW_TDEP_LAST_REG
62+
#endif
63+
4764

4865
/*
4966
* Convert `v` to ASCII hex characters. The bottom `n` nybbles (4-bits ie one
@@ -102,14 +119,13 @@ libspl_backtrace(int fd)
102119
unw_init_local(&cp, &uc);
103120

104121
/*
105-
* libunwind's list of possible registers for this architecture is an
106-
* enum, unw_regnum_t. UNW_TDEP_LAST_REG is the highest-numbered
107-
* register in that list, however, not all register numbers in this
108-
* range are defined by the architecture, and not all defined registers
109-
* will be present on every implementation of that architecture.
110-
* Moreover, libunwind provides nice names for most, but not all
111-
* registers, but these are hardcoded; a name being available does not
112-
* mean that register is available.
122+
* Iterate over all registers for the architecture. We've figured
123+
* out the highest number above, however, not all register numbers in
124+
* this range are defined by the architecture, and not all defined
125+
* registers will be present on every implementation of that
126+
* architecture. Moreover, libunwind provides nice names for most, but
127+
* not all registers, but these are hardcoded; a name being available
128+
* does not mean that register is available.
113129
*
114130
* So, we have to pull this all together here. We try to get the value
115131
* of every possible register. If we get a value for it, then the
@@ -120,26 +136,42 @@ libspl_backtrace(int fd)
120136
* thing.
121137
*/
122138
uint_t cols = 0;
123-
for (uint_t regnum = 0; regnum <= UNW_TDEP_LAST_REG; regnum++) {
139+
for (uint_t regnum = 0; regnum <= LAST_REG_INDEX; regnum++) {
124140
/*
125141
* Get the value. Any error probably means the register
126-
* doesn't exist, and we skip it.
142+
* doesn't exist, and we skip it. LLVM libunwind iterates over
143+
* fp registers in the same list, however they have to be
144+
* accessed using unw_get_fpreg instead. Here, we just ignore
145+
* them.
127146
*/
147+
#ifdef IS_LIBUNWIND_LLVM
148+
if (unw_is_fpreg(&cp, regnum) ||
149+
unw_get_reg(&cp, regnum, &v) < 0)
150+
continue;
151+
#else
128152
if (unw_get_reg(&cp, regnum, &v) < 0)
129153
continue;
154+
#endif
130155

131156
/*
132-
* Register name. If libunwind doesn't have a name for it,
157+
* Register name. If GCC libunwind doesn't have a name for it,
133158
* it will return "???". As a shortcut, we just treat '?'
134-
* is an alternate end-of-string character.
159+
* is an alternate end-of-string character. LLVM libunwind will
160+
* return the string 'unknown register', which we detect by
161+
* checking if the register name is longer than 5 characters.
135162
*/
163+
#ifdef IS_LIBUNWIND_LLVM
164+
const char *name = unw_regname(&cp, regnum);
165+
#else
136166
const char *name = unw_regname(regnum);
167+
#endif
137168
for (n = 0; name[n] != '\0' && name[n] != '?'; n++) {}
138-
if (n == 0) {
169+
if (n == 0 || n > 5) {
139170
/*
140-
* No valid name, so make one of the form "?xx", where
141-
* "xx" is the two-char hex of libunwind's register
142-
* number.
171+
* No valid name, or likely llvm_libunwind returned
172+
* unknown_register, so make one of the form "?xx",
173+
* where "xx" is the two-char hex of libunwind's
174+
* register number.
143175
*/
144176
buf[0] = '?';
145177
n = spl_bt_u64_to_hex_str(regnum, 2,

0 commit comments

Comments
 (0)