Describe the default CFI for the alpha ABI: the CFA is $sp, the return
address is in $ra ($26), and $9-$15 and $f2-$f9 are callee-saved.

Set frame_nregs to 65. GCC's DWARF_ALT_FRAME_RETURN_COLUMN on alpha is
64, and glibc's signal trampolines use it as the return address column
(cfi_return_column (64)), so the unwinder needs a slot for it after
$0-$31 and $f0-$f31.

Together with the prstatus fix this makes eu-stack --core work on
alpha core files.

        * backends/alpha_cfi.c: New file.
        * backends/Makefile.am (alpha_SRCS): Add alpha_cfi.c.
        * backends/alpha_init.c (alpha_init): Hook abi_cfi and set
        frame_nregs.
---
 backends/Makefile.am  |  2 +-
 backends/alpha_cfi.c  | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++
 backends/alpha_init.c |  5 ++++
 3 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/backends/Makefile.am b/backends/Makefile.am
index d7dfc7bc..604673b6 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -53,7 +53,7 @@ x86_64_SRCS = x86_64_init.c x86_64_symbol.c x86_64_corenote.c 
x86_64_cfi.c \
 ia64_SRCS = ia64_init.c ia64_symbol.c ia64_regs.c ia64_retval.c
 
 alpha_SRCS = alpha_init.c alpha_symbol.c alpha_retval.c alpha_regs.c \
-            alpha_corenote.c alpha_auxv.c
+            alpha_corenote.c alpha_auxv.c alpha_cfi.c
 
 arm_SRCS = arm_init.c arm_symbol.c arm_regs.c arm_corenote.c \
           arm_auxv.c arm_attrs.c arm_retval.c arm_cfi.c arm_initreg.c \
diff --git a/backends/alpha_cfi.c b/backends/alpha_cfi.c
new file mode 100644
index 00000000..bb7de1da
--- /dev/null
+++ b/backends/alpha_cfi.c
@@ -0,0 +1,69 @@
+/* Alpha ABI-specified defaults for DWARF CFI.
+   Copyright (C) 2026 Matt Turner
+   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 <dwarf.h>
+
+#define BACKEND alpha_
+#include "libebl_CPU.h"
+
+int
+alpha_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info)
+{
+  static const uint8_t abi_cfi[] =
+    {
+      /* The CFA is the value of $sp ($30) in the previous frame.  */
+      DW_CFA_def_cfa, ULEB128_7 (30), ULEB128_7 (0),
+
+      /* $sp is restored from the CFA.  */
+      DW_CFA_val_offset, ULEB128_7 (30), ULEB128_7 (0),
+
+#define SV(n) DW_CFA_same_value, ULEB128_7 (n)
+      /* The return address in $ra ($26) is set up by the caller.  */
+      SV (26),
+
+      /* Callee-saved registers $s0-$s5 ($9-$14) and $fp ($15).  */
+      SV (9), SV (10), SV (11), SV (12), SV (13), SV (14), SV (15),
+
+      /* Callee-saved registers $f2-$f9.  */
+      SV (34), SV (35), SV (36), SV (37), SV (38), SV (39), SV (40), SV (41),
+#undef SV
+    };
+
+  abi_info->initial_instructions = abi_cfi;
+  abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi];
+  abi_info->data_alignment_factor = -8;
+
+  abi_info->return_address_register = 26; /* $ra */
+
+  return 0;
+}
diff --git a/backends/alpha_init.c b/backends/alpha_init.c
index c69aec6d..229c5beb 100644
--- a/backends/alpha_init.c
+++ b/backends/alpha_init.c
@@ -57,6 +57,11 @@ alpha_init (Elf *elf __attribute__ ((unused)),
   HOOK (eh, register_info);
   HOOK (eh, core_note);
   HOOK (eh, auxv_info);
+  HOOK (eh, abi_cfi);
+  /* $0-$31, $f0-$f31, and column 64 for the PC, which gcc's
+     DWARF_ALT_FRAME_RETURN_COLUMN and glibc's signal trampolines use
+     as the return address column.  */
+  eh->frame_nregs = 65;
   eh->sysvhash_entrysize = sizeof (Elf64_Xword);
 
   return eh;

-- 
2.55.0

Reply via email to