[PATCH v5 4/7] perf unwind-libunwind: Make libunwind register reading cross platform

Ian Rogers irogers at google.com
Fri May 15 12:38:48 PDT 2026


On Fri, May 15, 2026 at 12:23 PM Arnaldo Carvalho de Melo
<acme at kernel.org> wrote:
>
> On Wed, May 13, 2026 at 04:31:48PM -0700, Ian Rogers wrote:
> > --- /dev/null
> > +++ b/tools/perf/util/libunwind-arch/libunwind-ppc32.c
> > @@ -0,0 +1,31 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +#include "libunwind-arch.h"
> > +#include "../debug.h"
> > +#include "../../../arch/powerpc/include/uapi/asm/perf_regs.h"
> > +#include <linux/compiler.h>
> > +#include <errno.h>
> > +
> > +#ifdef HAVE_LIBUNWIND_PPC32_SUPPORT
> > +#include <libunwind-ppc32.h>
> > +#endif
> > +
> > +int __get_perf_regnum_for_unw_regnum_ppc32(int unw_regnum __maybe_unused)
> > +{
> > +#ifndef HAVE_LIBUNWIND_PPC32_SUPPORT
> > +     return -EINVAL;
> > +#else
> > +     switch (unw_regnum) {
> > +     case UNW_PPC32_R0 ... UNW_PPC32_R31:
> > +             return unw_regnum - UNW_PPC32_R0 + PERF_REG_POWERPC_R0;
> > +     case UNW_PPC32_LR:
> > +             return PERF_REG_POWERPC_LINK;
> > +     case UNW_PPC32_CTR:
> > +             return PERF_REG_POWERPC_CTR;
> > +     case UNW_PPC32_XER:
> > +             return PERF_REG_POWERPC_XER;
> > +     default:
> > +             pr_err("unwind: invalid reg id %d\n", unw_regnum);
> > +             return -EINVAL;
> > +     }
> > +#endif // HAVE_LIBUNWIND_PPC32_SUPPORT
>
> To address this local sashiko comment:
>
> ------------------------------------------------------------
> Is the instruction pointer (NIP) intentionally omitted from this switch
> statement?
>
> When libunwind attempts to read the instruction pointer, will access_reg()
> hit the default case here and return -EINVAL, causing stack unwinding
> to fail on 32-bit PowerPC architectures?
> For comparison, the 64-bit implementation in libunwind-ppc64.c correctly
> maps UNW_PPC64_NIP to PERF_REG_POWERPC_NIP.
> ------------------------------------------------------------
>
> I ammended this patch with:
>
> ⬢ [acme at toolbx perf-tools-next]$ vim tools/perf/util/libunwind-arch/libunwind-ppc32.c
> ⬢ [acme at toolbx perf-tools-next]$ git diff
> diff --git a/tools/perf/util/libunwind-arch/libunwind-ppc32.c b/tools/perf/util/libunwind-arch/libunwind-ppc32.c
> index bcdeed34d0a81b8d..976a160304073582 100644
> --- a/tools/perf/util/libunwind-arch/libunwind-ppc32.c
> +++ b/tools/perf/util/libunwind-arch/libunwind-ppc32.c
> @@ -23,6 +23,8 @@ int __get_perf_regnum_for_unw_regnum_ppc32(int unw_regnum __maybe_unused)
>                 return PERF_REG_POWERPC_CTR;
>         case UNW_PPC32_XER:
>                 return PERF_REG_POWERPC_XER;
> +       case UNW_PPC32_NIP:
> +               return PERF_REG_POWERPC_NIP;
>         default:
>                 pr_err("unwind: invalid reg id %d\n", unw_regnum);
>                 return -EINVAL;
> ⬢ [acme at toolbx perf-tools-next]$
>
> Ok? It was the only issue found in this patch.

Looks good, the NIP is in the original code that I copied, so I don't
understand how I lost this, but good catch!

Thanks,
Ian

> - Arnaldo



More information about the linux-riscv mailing list