]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
backends/: fixup x86 initreg_sample to share code with aarch64
authorSerhei Makarov <serhei@serhei.io>
Fri, 6 Mar 2026 17:33:49 +0000 (12:33 -0500)
committerSerhei Makarov <serhei@serhei.io>
Fri, 20 Mar 2026 18:12:42 +0000 (14:12 -0400)
In particular, sample_sp_pc() implementation looks to be uniform
across architectures apart from the register positions.

{changelog TBA pending testing}

backends/i386_init.c
backends/i386_initreg_sample.c
backends/libebl_PERF_FLAGS.h
backends/x86_64_init.c
backends/x86_64_initreg_sample.c
backends/x86_initreg_sample.c

index a980e71ac5949f2bf903c6631b43a3b7c2647e1f..bdd075089cc546a6f532489aaf484beaf7557c4f 100644 (file)
@@ -1,5 +1,5 @@
 /* Initialization of i386 specific backend library.
-   Copyright (C) 2000-2009, 2013, 2017, 2025 Red Hat, Inc.
+   Copyright (C) 2000-2009, 2013, 2017, 2025-2026 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
 
@@ -60,13 +60,11 @@ i386_init (Elf *elf __attribute__ ((unused)),
      (Likely an artifact of reusing that header between i386/x86_64.)  */
   eh->frame_nregs = 9;
   HOOK (eh, set_initial_registers_tid);
-  /* set_initial_registers_sample is default ver */
+  /* set_initial_registers_sample is default ver  */
   HOOK (eh, sample_sp_pc);
   HOOK (eh, sample_perf_regs_mapping);
   eh->perf_frame_regs_mask = PERF_FRAME_REGISTERS_I386;
-  eh->cached_perf_regs_mask = 0;
-  eh->cached_regs_mapping = NULL;
-  eh->cached_n_regs_mapping = -1;
+  __libebl_init_cached_regs_mapping (eh);
   HOOK (eh, unwind);
 
   return eh;
index d7d312b069032c97b7140f01bb9bdc5926f21486..ae3ab11e9183d6b4d8708eee453c3b4a41f993b0 100644 (file)
@@ -1,5 +1,5 @@
 /* Populate process registers from a linux perf_events sample.
-   Copyright (C) 2025 Red Hat, Inc.
+   Copyright (C) 2025-2026 Red Hat, Inc.
    This file is part of elfutils.
 
    This file is free software; you can redistribute it and/or modify
 
 bool
 i386_sample_sp_pc (const Dwarf_Word *regs, uint32_t n_regs,
-                   const int *regs_mapping, uint32_t n_regs_mapping,
-                   Dwarf_Word *sp, Dwarf_Word *pc)
+                  const int *regs_mapping, uint32_t n_regs_mapping,
+                  Dwarf_Word *sp, Dwarf_Word *pc)
 {
-#ifdef HAVE_X86_INITREG_SAMPLE
   /* XXX for dwarf_regs indices, compare i386_initreg.c */
-  return x86_sample_sp_pc (regs, n_regs, regs_mapping, n_regs_mapping,
+  return generic_sample_sp_pc (regs, n_regs, regs_mapping, n_regs_mapping,
                           sp, 4 /* index of sp in dwarf_regs */,
                           pc, 8 /* index of pc in dwarf_regs */);
-#else
-  (void) regs;
-  (void) n_regs;
-  (void) regs_mapping;
-  (void) n_regs_mapping;
-  (void) sp;
-  (void) pc;
-  return false;
-#endif
 }
 
 bool
index f0ed9f5988ab335694bd07a9dbc6e633f8432868..fe35adb71a2dc038fd530675d1e040efe4698545 100644 (file)
@@ -54,7 +54,7 @@
    and note how regs are added in the same order as the perf_regs.h enum.  */
 #else
 /* Since asm/perf_regs.h is absent, or gives the register layout for a
-   different arch, we can't unwind i386 and x86_64 frames. */
+   different arch, we can't unwind i386 and x86_64 perf sample frames.  */
 #define PERF_FRAME_REGISTERS_I386 0
 #define PERF_FRAME_REGISTERS_X86_64 0
 #endif /* _ASM_X86_PERF_REGS_H */
index 5f929758e653257d831bad6f708605be5db27ca4..a3190fbc7ab6618bc4632a7c6609fb9a31d7ada0 100644 (file)
@@ -1,5 +1,5 @@
 /* Initialization of x86-64 specific backend library.
-   Copyright (C) 2002-2009, 2013, 2018, 2025 Red Hat, Inc.
+   Copyright (C) 2002-2009, 2013, 2018, 2025-2026 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.
@@ -63,13 +63,11 @@ x86_64_init (Elf *elf __attribute__ ((unused)),
   /* gcc/config/ #define DWARF_FRAME_REGISTERS.  */
   eh->frame_nregs = 17;
   HOOK (eh, set_initial_registers_tid);
-  /* set_initial_registers_sample is default ver */
+  /* set_initial_registers_sample is default ver  */
   HOOK (eh, sample_sp_pc);
   HOOK (eh, sample_perf_regs_mapping);
   eh->perf_frame_regs_mask = PERF_FRAME_REGISTERS_X86_64;
-  eh->cached_perf_regs_mask = 0;
-  eh->cached_regs_mapping = NULL;
-  eh->cached_n_regs_mapping = -1;
+  __libebl_init_cached_regs_mapping (eh);
   HOOK (eh, unwind);
   HOOK (eh, check_reloc_target_type);
 
index 200a94a1faa2d0e93decf6c198408cf83136aaf4..83966ff9e38b79b7f769a9b7cef13c63d1e64e88 100644 (file)
@@ -1,5 +1,5 @@
 /* Populate process registers from a linux perf_events sample.
-   Copyright (C) 2025 Red Hat, Inc.
+   Copyright (C) 2025-2026 Red Hat, Inc.
    This file is part of elfutils.
 
    This file is free software; you can redistribute it and/or modify
@@ -50,20 +50,10 @@ x86_64_sample_sp_pc (const Dwarf_Word *regs, uint32_t n_regs,
                     const int *regs_mapping, uint32_t n_regs_mapping,
                     Dwarf_Word *sp, Dwarf_Word *pc)
 {
-#ifdef HAVE_X86_INITREG_SAMPLE
   /* XXX for dwarf_regs indices, compare x86_64_initreg.c */
-  return x86_sample_sp_pc (regs, n_regs, regs_mapping, n_regs_mapping,
+  return generic_sample_sp_pc (regs, n_regs, regs_mapping, n_regs_mapping,
                           sp, 7 /* index of sp in dwarf_regs */,
                           pc, 16 /* index of pc in dwarf_regs */);
-#else
-  (void) regs;
-  (void) n_regs;
-  (void) regs_mapping;
-  (void) n_regs_mapping;
-  (void) sp;
-  (void) pc;
-  return false;
-#endif
 }
 
 bool
index 6f99bf5352cf9e1029edf43336703783cf19d2a6..fe870e618698ae9683700f556d53e0d794b63856 100644 (file)
@@ -1,5 +1,5 @@
-/* x86 stack sample register handling, pieces common to x86-64 and i386.
-   Copyright (C) 2025 Red Hat, Inc.
+/* x86 stack sample register handling helper common to x86-64 and i386.
+   Copyright (C) 2025-2026 Red Hat, Inc.
    This file is part of elfutils.
 
    This file is free software; you can redistribute it and/or modify
    the GNU Lesser General Public License along with this program.  If
    not, see <http://www.gnu.org/licenses/>.  */
 
-static bool
-x86_sample_sp_pc (const Dwarf_Word *regs, uint32_t n_regs,
-                 const int *regs_mapping, uint32_t n_regs_mapping,
-                 Dwarf_Word *sp, uint sp_index /* into dwarf_regs */,
-                 Dwarf_Word *pc, uint pc_index /* into dwarf_regs */)
-{
-  if (sp != NULL) *sp = 0;
-  if (pc != NULL) *pc = 0;
-#if !defined(__x86_64__)
-  (void)regs;
-  (void)n_regs;
-  (void)regs_mapping;
-  (void)n_regs_mapping;
-  (void)sp;
-  (void)sp_index;
-  (void)pc;
-  (void)pc_index;
-  return false;
-#else /* __x86_64__ */
-  /* TODO: Register locations could be cached and rechecked on a
-     fastpath without needing to loop? */
-  int j, need_sp = (sp != NULL), need_pc = (pc != NULL);
-  for (j = 0; (need_sp || need_pc) && n_regs_mapping > (uint32_t)j; j++)
-    {
-      if (n_regs < (uint32_t)j) break;
-      if (need_sp && regs_mapping[j] == (int)sp_index)
-       {
-         *sp = regs[j]; need_sp = false;
-       }
-      if (need_pc && regs_mapping[j] == (int)pc_index)
-       {
-         *pc = regs[j]; need_pc = false;
-       }
-    }
-  return (!need_sp && !need_pc);
-#endif
-}
-
-static bool
+static inline bool
 x86_sample_perf_regs_mapping (Ebl *ebl,
                              uint64_t perf_regs_mask, uint32_t abi,
                              const int **regs_mapping,