## Process this file with automake to create Makefile.in
##
-## Copyright (C) 2000-2010, 2013, 2014 Red Hat, Inc.
+## Copyright (C) 2000-2010, 2013, 2014, 2025 Red Hat, Inc.
## Copyright (C) 2012 Tilera Corporation
## This file is part of elfutils.
##
i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c i386_cfi.c \
i386_retval.c i386_regs.c i386_auxv.c \
- i386_initreg.c i386_unwind.c
+ i386_initreg.c i386_initreg_sample.c i386_unwind.c
sh_SRCS = sh_init.c sh_symbol.c sh_corenote.c sh_regs.c sh_retval.c
x86_64_SRCS = x86_64_init.c x86_64_symbol.c x86_64_corenote.c x86_64_cfi.c \
x86_64_retval.c x86_64_regs.c x86_64_initreg.c \
- x86_64_unwind.c x32_corenote.c
+ x86_64_initreg_sample.c x86_64_unwind.c x32_corenote.c
ia64_SRCS = ia64_init.c ia64_symbol.c ia64_regs.c ia64_retval.c
libebl_backends_pic_a_SOURCES =
am_libebl_backends_pic_a_OBJECTS = $(libebl_backends_a_SOURCES:.c=.os)
-noinst_HEADERS = libebl_CPU.h common-reloc.c linux-core-note.c x86_corenote.c
+noinst_HEADERS = libebl_CPU.h libebl_PERF_FLAGS.h common-reloc.c \
+ linux-core-note.c x86_corenote.c \
+ linux-perf-regs.c x86_initreg_sample.c
EXTRA_DIST = $(modules:=_reloc.def)
/* Initialization of i386 specific backend library.
- Copyright (C) 2000-2009, 2013, 2017 Red Hat, Inc.
+ Copyright (C) 2000-2009, 2013, 2017, 2025 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
#define BACKEND i386_
#define RELOC_PREFIX R_386_
#include "libebl_CPU.h"
+#include "libebl_PERF_FLAGS.h"
/* This defines the common reloc hooks based on i386_reloc.def. */
#include "common-reloc.c"
HOOK (eh, auxv_info);
HOOK (eh, disasm);
HOOK (eh, abi_cfi);
- /* gcc/config/ #define DWARF_FRAME_REGISTERS. For i386 it is 17, why? */
+ /* gcc/config/ #define DWARF_FRAME_REGISTERS. For i386 it is 17, why?
+ (Likely an artifact of reusing that header between i386/x86_64.) */
eh->frame_nregs = 9;
HOOK (eh, set_initial_registers_tid);
+ HOOK (eh, set_initial_registers_sample);
+ HOOK (eh, sample_base_addr);
+ HOOK (eh, sample_pc);
+ eh->perf_frame_regs_mask = PERF_FRAME_REGISTERS_I386;
HOOK (eh, unwind);
return eh;
--- /dev/null
+/* Populate process registers from a linux perf_events sample.
+ Copyright (C) 2025 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#if (defined __i386__ || defined __x86_64__) && defined(__linux__)
+# include <linux/perf_event.h>
+# include <asm/perf_regs.h>
+#endif
+
+#define BACKEND i386_
+#include "libebl_CPU.h"
+#include "libebl_PERF_FLAGS.h"
+#if (defined __i386__ || defined __x86_64__) && defined(__linux__)
+# include "linux-perf-regs.c"
+# include "x86_initreg_sample.c"
+#endif
+
+/* Register ordering cf. linux arch/x86/include/uapi/asm/perf_regs.h,
+ enum perf_event_x86_regs: */
+Dwarf_Word
+i386_sample_base_addr (const Dwarf_Word *regs, uint32_t n_regs,
+ uint64_t regs_mask,
+ /* XXX hypothetically needed if abi varies
+ between samples in the same process;
+ not needed on x86 */
+ uint32_t abi __attribute__((unused)))
+{
+#if (!defined __i386__ && !defined __x86_64__) || !defined(__linux__)
+ (void)regs;
+ (void)n_regs;
+ (void)regs_mask;
+ return 0;
+#else /* __i386__ || __x86_64__ */
+ (void)regs;
+ (void)n_regs;
+ (void)regs_mask;
+ return perf_sample_find_reg (regs, n_regs, regs_mask,
+ 7 /* index into perf_event_x86_regs */);
+#endif
+}
+
+Dwarf_Word
+i386_sample_pc (const Dwarf_Word *regs, uint32_t n_regs,
+ uint64_t regs_mask,
+ uint32_t abi __attribute__((unused)))
+{
+#if (!defined __i386__ && !defined __x86_64__) || !defined(__linux__)
+ (void)regs;
+ (void)n_regs;
+ (void)regs_mask;
+ return 0;
+#else /* __i386__ || __x86_64__ */
+ return perf_sample_find_reg (regs, n_regs, regs_mask,
+ 8 /* index into perf_event_x86_regs */);
+#endif
+}
+
+bool
+i386_set_initial_registers_sample (const Dwarf_Word *regs, uint32_t n_regs,
+ uint64_t regs_mask, uint32_t abi,
+ ebl_tid_registers_t *setfunc,
+ void *arg)
+{
+#if (!defined __i386__ && !defined __x86_64__) || !defined(__linux__)
+ (void)regs;
+ (void)n_regs;
+ (void)regs_mask;
+ (void)abi;
+ (void)setfunc;
+ (void)arg;
+ return false;
+#else /* __i386__ || __x86_64__ */
+ Dwarf_Word dwarf_regs[9];
+ if (!x86_set_initial_registers_sample (regs, n_regs, regs_mask,
+ abi, dwarf_regs, 9))
+ return false;
+ return setfunc (0, 9, dwarf_regs, arg);
+#endif
+}
--- /dev/null
+/* Linux perf_events sample_regs_user flags required for unwinding.
+ Internal only; elfutils library users should use ebl_perf_frame_regs_mask().
+
+ Copyright (C) 2025 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBEBL_PERF_FLAGS_H
+#define _LIBEBL_PERF_FLAGS_H 1
+
+#if defined(__linux__)
+# include <asm/perf_regs.h>
+#endif
+
+#if defined(_ASM_X86_PERF_REGS_H)
+/* See the code in x86_initreg_sample.c for list of required regs and
+ linux arch/.../include/asm/ptrace.h for matching pt_regs struct. */
+#define REG(R) (1ULL << PERF_REG_X86_ ## R)
+/* FLAGS and segment regs are excluded from the following masks,
+ since they're not needed for unwinding. */
+#define PERF_FRAME_REGISTERS_I386 (REG(AX) | REG(BX) | REG(CX) | REG(DX) \
+ | REG(SI) | REG(DI) | REG(BP) | REG(SP) | REG(IP))
+#define PERF_FRAME_REGISTERS_X86_64 (PERF_FRAME_REGISTERS_I386 | REG(R8) \
+ | REG(R9) | REG(R10) | REG(R11) | REG(R12) | REG(R13) | REG(R14) | REG(R15))
+/* Register ordering defined in linux arch/x86/include/uapi/asm/perf_regs.h;
+ see the code in tools/perf/util/intel-pt.c intel_pt_add_gp_regs()
+ and note how regs are added in the same order as the perf_regs.h enum. */
+#else
+/* Since asm/perf_regs.h gives the register layout for a different arch,
+ we can't unwind x86_64 frames. */
+#define PERF_FRAME_REGISTERS_I386 0
+#define PERF_FRAME_REGISTERS_X86_64 0
+#endif
+
+#endif /* libebl_PERF_FLAGS.h */
--- /dev/null
+/* Common pieces for handling registers in a linux perf_events sample.
+ Copyright (C) 2025 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+static Dwarf_Word
+perf_sample_find_reg (const Dwarf_Word *regs, uint32_t n_regs,
+ uint64_t regs_mask,
+ int target)
+{
+ int j, k; uint64_t bit;
+ for (j = 0, k = 0, bit = 1; k < PERF_REG_X86_64_MAX; k++, bit <<= 1)
+ {
+ if (bit & regs_mask) {
+ if (n_regs <= (uint32_t) j)
+ return 0; /* regs_mask count doesn't match n_regs */
+ if (k == target)
+ return regs[j];
+ if (k > target)
+ return 0; /* regs_mask doesn't include desired reg */
+ j++;
+ }
+ }
+ return 0;
+}
/* Initialization of x86-64 specific backend library.
- Copyright (C) 2002-2009, 2013, 2018 Red Hat, Inc.
+ Copyright (C) 2002-2009, 2013, 2018, 2025 Red Hat, Inc.
Copyright (C) H.J. Lu <hjl.tools@gmail.com>, 2015.
This file is part of elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
#define BACKEND x86_64_
#define RELOC_PREFIX R_X86_64_
#include "libebl_CPU.h"
+#include "libebl_PERF_FLAGS.h"
/* This defines the common reloc hooks based on x86_64_reloc.def. */
#include "common-reloc.c"
/* gcc/config/ #define DWARF_FRAME_REGISTERS. */
eh->frame_nregs = 17;
HOOK (eh, set_initial_registers_tid);
+ HOOK (eh, set_initial_registers_sample);
+ HOOK (eh, sample_base_addr);
+ HOOK (eh, sample_pc);
+ eh->perf_frame_regs_mask = PERF_FRAME_REGISTERS_X86_64;
HOOK (eh, unwind);
HOOK (eh, check_reloc_target_type);
--- /dev/null
+/* Populate process registers from a linux perf_events sample.
+ Copyright (C) 2025 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#if defined(__x86_64__) && defined(__linux__)
+# include <linux/perf_event.h>
+# include <asm/perf_regs.h>
+#endif
+
+#define BACKEND x86_64_
+#include "libebl_CPU.h"
+#include "libebl_PERF_FLAGS.h"
+#if defined(__x86_64__) && defined(__linux__)
+# include "linux-perf-regs.c"
+# include "x86_initreg_sample.c"
+#endif
+
+/* Register ordering cf. linux arch/x86/include/uapi/asm/perf_regs.h,
+ enum perf_event_x86_regs: */
+Dwarf_Word
+x86_64_sample_base_addr (const Dwarf_Word *regs, uint32_t n_regs,
+ uint64_t regs_mask,
+ /* XXX hypothetically needed if abi varies
+ between samples in the same process;
+ not needed on x86*/
+ uint32_t abi __attribute__((unused)))
+{
+#if !defined(__x86_64__) || !defined(__linux__)
+ (void)regs;
+ (void)n_regs;
+ (void)regs_mask;
+ return 0;
+#else /* __x86_64__ */
+ return perf_sample_find_reg (regs, n_regs, regs_mask,
+ 7 /* index into perf_event_x86_regs */);
+#endif
+}
+
+Dwarf_Word
+x86_64_sample_pc (const Dwarf_Word *regs, uint32_t n_regs,
+ uint64_t regs_mask,
+ uint32_t abi __attribute__((unused)))
+{
+#if !defined(__x86_64__) || !defined(__linux__)
+ (void)regs;
+ (void)n_regs;
+ (void)regs_mask;
+ return 0;
+#else /* __x86_64__ */
+ return perf_sample_find_reg (regs, n_regs, regs_mask,
+ 8 /* index into perf_event_x86_regs */);
+#endif
+}
+
+bool
+x86_64_set_initial_registers_sample (const Dwarf_Word *regs, uint32_t n_regs,
+ uint64_t regs_mask, uint32_t abi,
+ ebl_tid_registers_t *setfunc,
+ void *arg)
+{
+#if !defined(__x86_64__) || !defined(__linux__)
+ (void)regs;
+ (void)n_regs;
+ (void)regs_mask;
+ (void)abi;
+ (void)setfunc;
+ (void)arg;
+ return false;
+#else /* __x86_64__ */
+ Dwarf_Word dwarf_regs[17];
+ if (!x86_set_initial_registers_sample (regs, n_regs, regs_mask,
+ abi, dwarf_regs, 9))
+ return false;
+ return setfunc (0, 17, dwarf_regs, arg);
+#endif
+}
+
--- /dev/null
+/* x86 linux perf_events register handling, pieces common to x86-64 and i386.
+ Copyright (C) 2025 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+static bool
+x86_set_initial_registers_sample (const Dwarf_Word *regs, uint32_t n_regs,
+ uint64_t regs_mask, uint32_t abi,
+ Dwarf_Word *dwarf_regs, int expected_regs)
+{
+#if (!defined __i386__ && !defined __x86_64__) || !defined(__linux__)
+ return false;
+#else /* __i386__ || __x86_64__ */
+ /* The following facts are needed to translate x86 registers correctly:
+ - perf register order seen in linux arch/x86/include/uapi/asm/perf_regs.h
+ The registers array is built in the same order as the enum!
+ (See the code in tools/perf/util/intel-pt.c intel_pt_add_gp_regs().)
+ - EBL PERF_FRAME_REGS_MASK specifies all registers except segment and
+ flags. However, regs_mask might be a different set of registers.
+ Again, regs_mask bits are in asm/perf_regs.h enum order.
+ - dwarf register order seen in elfutils backends/{x86_64,i386}_initreg.c
+ (matching pt_regs struct in linux arch/x86/include/asm/ptrace.h)
+ and it's a fairly different register order!
+
+ For comparison, you can study codereview.qt-project.org/gitweb?p=qt-creator/perfparser.git;a=blob;f=app/perfregisterinfo.cpp;hb=HEAD
+ and follow the code which uses those tables of magic numbers.
+ But it's better to follow original sources of truth for this. */
+
+ bool is_abi32 = (abi == PERF_SAMPLE_REGS_ABI_32);
+
+ /* Locations of dwarf_regs in the perf_event_x86_regs enum order,
+ not the regs[i] array (which will include a subset of the regs): */
+ static const int regs_i386[] = {0, 2, 3, 1, 7/*sp*/, 6, 4, 5, 8/*ip*/};
+ static const int regs_x86_64[] = {0, 3, 2, 1, 4, 5, 6, 7/*sp*/,
+ 16/*r8 after flags+segment*/, 17, 18, 19, 20, 21, 22, 23,
+ 8/*ip*/};
+ const int *dwarf_to_perf = is_abi32 ? regs_i386 : regs_x86_64;
+
+ /* Locations of perf_regs in the regs[] array, according to regs_mask: */
+ int perf_to_regs[PERF_REG_X86_64_MAX];
+ uint64_t expected_mask = is_abi32 ? PERF_FRAME_REGISTERS_I386 : PERF_FRAME_REGISTERS_X86_64;
+ int j, k; uint64_t bit;
+ /* TODO: Is it worth caching this perf_to_regs computation as long
+ as regs_mask is kept the same across repeated calls? */
+ for (j = 0, k = 0, bit = 1; k < PERF_REG_X86_64_MAX; k++, bit <<= 1)
+ {
+ if ((bit & expected_mask) && (bit & regs_mask)) {
+ if (n_regs <= (uint32_t)j)
+ return false; /* regs_mask count doesn't match n_regs */
+ perf_to_regs[k] = j;
+ j++;
+ } else {
+ perf_to_regs[k] = -1;
+ }
+ }
+
+ for (int i = 0; i < expected_regs; i++)
+ {
+ k = dwarf_to_perf[i];
+ j = perf_to_regs[k];
+ if (j < 0) continue;
+ if (n_regs <= (uint32_t)j) continue;
+ dwarf_regs[i] = regs[j];
+ }
+ return true;
+#endif /* __i386__ || __x86_64__ */
+}
## Process this file with automake to create Makefile.in
##
-## Copyright (C) 2000-2010, 2013, 2016, 2017 Red Hat, Inc.
+## Copyright (C) 2000-2010, 2013, 2016, 2017, 2025 Red Hat, Inc.
## This file is part of elfutils.
##
## This file is free software; you can redistribute it and/or modify
eblbsspltp.c eblretval.c eblreginfo.c eblnonerelocp.c \
eblrelativerelocp.c eblsysvhashentrysize.c eblauxvinfo.c \
eblcheckobjattr.c ebl_check_special_section.c \
- eblabicfi.c eblstother.c eblinitreg.c \
+ eblabicfi.c eblstother.c eblinitreg.c eblinitreg_sample.c \
ebldwarftoregno.c eblnormalizepc.c eblunwind.c \
eblresolvesym.c eblcheckreloctargettype.c \
ebl_data_marker_symbol.c
/* Backend hook signatures internal interface for libebl.
- Copyright (C) 2000-2011, 2013, 2014, 2016, 2017 Red Hat, Inc.
+ Copyright (C) 2000-2011, 2013, 2014, 2016, 2017, 2025 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
ebl_tid_registers_t *setfunc,
void *arg);
+/* Set process data from a perf_events sample and call SETFUNC one or more times.
+ Method should be present only when EBL_PERF_FRAME_REGS_MASK > 0, otherwise the
+ backend doesn't support unwinding from perf_events data. */
+bool EBLHOOK(set_initial_registers_sample) (const Dwarf_Word *regs, uint32_t n_regs,
+ uint64_t regs_mask, uint32_t abi,
+ ebl_tid_registers_t *setfunc,
+ void *arg);
+
+/* Extract the stack address from a perf_events register sample. */
+Dwarf_Word EBLHOOK(sample_base_addr) (const Dwarf_Word *regs, uint32_t n_regs,
+ uint64_t regs_mask, uint32_t abi);
+
+/* Extract the instruction pointer from a perf_events register sample. */
+Dwarf_Word EBLHOOK(sample_pc) (const Dwarf_Word *regs, uint32_t n_regs,
+ uint64_t regs_mask, uint32_t abi);
+
/* Convert *REGNO as is in DWARF to a lower range suitable for
Dwarf_Frame->REGS indexing. */
bool EBLHOOK(dwarf_to_regno) (Ebl *ebl, unsigned *regno);
--- /dev/null
+/* Populate process Dwfl_Frame from perf_events sample.
+
+ Copyright (C) 2025 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+#include <assert.h>
+
+Dwarf_Word
+ebl_sample_base_addr (Ebl *ebl,
+ const Dwarf_Word *regs, uint32_t n_regs,
+ uint64_t regs_mask, uint32_t abi)
+{
+ assert (ebl->sample_base_addr != NULL);
+ return ebl->sample_base_addr (regs, n_regs, regs_mask, abi);
+}
+
+Dwarf_Word
+ebl_sample_pc (Ebl *ebl,
+ const Dwarf_Word *regs, uint32_t n_regs,
+ uint64_t regs_mask, uint32_t abi)
+{
+ assert (ebl->sample_pc != NULL);
+ return ebl->sample_pc (regs, n_regs, regs_mask, abi);
+}
+
+bool
+ebl_set_initial_registers_sample (Ebl *ebl,
+ const Dwarf_Word *regs, uint32_t n_regs,
+ uint64_t regs_mask, uint32_t abi,
+ ebl_tid_registers_t *setfunc,
+ void *arg)
+{
+ /* If set_initial_registers_sample is unsupported then PERF_FRAME_REGS_MASK is zero. */
+ assert (ebl->set_initial_registers_sample != NULL);
+ return ebl->set_initial_registers_sample (regs, n_regs, regs_mask, abi, setfunc, arg);
+}
+
+uint64_t
+ebl_perf_frame_regs_mask (Ebl *ebl)
+{
+ /* ebl is declared NN */
+ return ebl->perf_frame_regs_mask;
+}
/* Interface for libebl.
- Copyright (C) 2000-2010, 2013, 2014, 2015, 2016, 2017 Red Hat, Inc.
+ Copyright (C) 2000-2010, 2013, 2014, 2015, 2016, 2017, 2025 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
extern size_t ebl_frame_nregs (Ebl *ebl)
__nonnull_attribute__ (1);
+/* Callback to set process data from a linux perf_events sample.
+ EBL architecture has to have EBL_PERF_FRAME_REGS_MASK > 0, otherwise the
+ backend doesn't support unwinding from perf_events sample data. */
+extern bool ebl_set_initial_registers_sample (Ebl *ebl,
+ const Dwarf_Word *regs, uint32_t n_regs,
+ uint64_t regs_mask, uint32_t abi,
+ ebl_tid_registers_t *setfunc,
+ void *arg)
+ __nonnull_attribute__ (1, 2, 6);
+
+/* Extract the stack address from a perf_events register sample. */
+Dwarf_Word ebl_sample_base_addr (Ebl *ebl,
+ const Dwarf_Word *regs, uint32_t n_regs,
+ uint64_t regs_mask, uint32_t abi)
+ __nonnull_attribute__ (1, 2);
+
+/* Extract the instruction pointer from a perf_events register sample. */
+Dwarf_Word ebl_sample_pc (Ebl *ebl,
+ const Dwarf_Word *regs, uint32_t n_regs,
+ uint64_t regs_mask, uint32_t abi)
+ __nonnull_attribute__ (1, 2);
+
+
+/* Preferred sample_regs_user mask to request from linux perf_events
+ to allow unwinding on EBL architecture. Omitting some of these
+ registers may result in failed or inaccurate unwinding. */
+extern uint64_t ebl_perf_frame_regs_mask (Ebl *ebl)
+ __nonnull_attribute__ (1);
+
/* Offset to apply to the value of the return_address_register, as
fetched from a Dwarf CFI. This is used by some backends, where the
return_address_register actually contains the call address. */
/* Internal definitions for interface for libebl.
- Copyright (C) 2000-2009, 2013, 2014 Red Hat, Inc.
+ Copyright (C) 2000-2009, 2013, 2014, 2025 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
Ebl architecture can unwind iff FRAME_NREGS > 0. */
size_t frame_nregs;
+ /* Preferred sample_regs_user mask to request from linux perf_events
+ to allow unwinding. Ebl architecture supports unwinding from
+ perf_events sample data iff PERF_FRAME_REGS_MASK > 0. */
+ uint64_t perf_frame_regs_mask;
+
/* Offset to apply to the value of the return_address_register, as
fetched from a Dwarf CFI. This is used by some backends, where
the return_address_register actually contains the call