]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
backends: Add arm frame_nregs and set_initial_registers_tid.
authorMark Wielaard <mjw@redhat.com>
Sun, 26 Jan 2014 19:16:48 +0000 (20:16 +0100)
committerMark Wielaard <mjw@redhat.com>
Thu, 30 Jan 2014 10:08:32 +0000 (11:08 +0100)
This allows CFI unwinding for ARM. It relies on having .debug_frame around
which is always the case in our testsuite. All native backtrace tests PASS
on arm if debuginfo (for glibc) is installed on the system. Otherwise the
tests SKIP.

For non-debug unwinding ARM uses EXIDX tables, not .eh_frames, which
would have to be translated to CFI to do unwinding without .debug_frame
available.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
backends/ChangeLog
backends/Makefile.am
backends/arm_init.c
backends/arm_initreg.c [new file with mode: 0644]
tests/ChangeLog
tests/backtrace-subr.sh

index c8e2b3017bfec9c936ace027d6cf70959f8e1c45..212b9f6ddfe031c9c94e0a79fa580e01967f9ba5 100644 (file)
@@ -1,3 +1,10 @@
+2014-01-26  Mark Wielaard  <mjw@redhat.com>
+
+       * Makefile.am (arm_SRCS): Add arm_initreg.c.
+       * arm_init.c (arm_init): Define frame_nregs and hook
+       set_initial_registers_tid.
+       * arm_initreg.c: New file.
+
 2014-01-25  Mark Wielaard  <mjw@redhat.com>
 
        * arm_cfi.c (arm_abi_cfi): Restore SP (r13) from CFA.
index 90e93a88ba74e9573aa1e6d1da8820288810fdb6..4129eee529efc6527eb4a29452a3459d49d766fd 100644 (file)
@@ -78,7 +78,7 @@ libebl_alpha_pic_a_SOURCES = $(alpha_SRCS)
 am_libebl_alpha_pic_a_OBJECTS = $(alpha_SRCS:.c=.os)
 
 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_auxv.c arm_attrs.c arm_retval.c arm_cfi.c arm_initreg.c
 libebl_arm_pic_a_SOURCES = $(arm_SRCS)
 am_libebl_arm_pic_a_OBJECTS = $(arm_SRCS:.c=.os)
 
index cf661cea64a7a5e356eb8abd38d2ed5b851bf7ac..14b2635669d31671385cc716088e35893209c118 100644 (file)
@@ -1,5 +1,5 @@
 /* Initialization of Arm specific backend library.
-   Copyright (C) 2002, 2005, 2009, 2013 Red Hat, Inc.
+   Copyright (C) 2002, 2005, 2009, 2013, 2014 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -64,5 +64,9 @@ arm_init (elf, machine, eh, ehlen)
   HOOK (eh, return_value_location);
   HOOK (eh, abi_cfi);
 
+  /* We only unwind the core integer registers.  */
+  eh->frame_nregs = 16;
+  HOOK (eh, set_initial_registers_tid);
+
   return MODVERSION;
 }
diff --git a/backends/arm_initreg.c b/backends/arm_initreg.c
new file mode 100644 (file)
index 0000000..c03146e
--- /dev/null
@@ -0,0 +1,58 @@
+/* Fetch live process registers from TID.
+   Copyright (C) 2014 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
+
+#if defined __arm__
+# include <sys/types.h>
+# include <sys/user.h>
+# include <sys/ptrace.h>
+#endif
+
+#define BACKEND arm_
+#include "libebl_CPU.h"
+
+bool
+arm_set_initial_registers_tid (pid_t tid __attribute__ ((unused)),
+                         ebl_tid_registers_t *setfunc __attribute__ ((unused)),
+                              void *arg __attribute__ ((unused)))
+{
+#if ! defined __arm__
+  return false;
+#else
+  struct user_regs user_regs;
+  if (ptrace (PTRACE_GETREGS, tid, NULL, &user_regs) != 0)
+    return false;
+  Dwarf_Word dwarf_regs[16];
+  for (int i = 0; i < 16; i++)
+    dwarf_regs[i] = user_regs.uregs[i];
+  return setfunc (0, 16, dwarf_regs, arg);
+#endif
+}
index fa8a42a274db884c6375fabb7608024bd8cec62d..a279982c94a0585009190fec7a0a3c1a473d8f34 100644 (file)
@@ -1,3 +1,7 @@
+2014-01-26  Mark Wielaard  <mjw@redhat.com>
+
+       * backtrace-subr.sh (check_unsupported): Special case arm*.
+
 2014-01-25  Mark Wielaard  <mjw@redhat.com>
 
        * run-addrcfi.sh (EM_ARM): Change reg13 (sp) from undefined to
index 62b873c79675ba2291462a3950b594417d299e40..1df9356486ce137c9fff94b877f9413bdc415619 100644 (file)
@@ -74,6 +74,18 @@ check_unsupported()
     echo >&2 $testname: arch not supported
     exit 77
   fi
+
+  # ARM is special. It is supported, but it doesn't use .eh_frame by default
+  # making the native tests fail unless debuginfo (for glibc) is installed
+  # and we can fall back on .debug_frame for the CFI.
+  case "`uname -m`" in
+    arm* )
+      if grep 'dwfl_thread_getframes: No DWARF information found' $1; then
+       echo >&2 $testname: arm needs debuginfo installed for all libraries
+       exit 77
+      fi
+    ;;
+  esac
 }
 
 check_core()