summaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2014-01-26 20:16:48 +0100
committerMark Wielaard <mjw@redhat.com>2014-01-30 11:08:32 +0100
commit225dddfda38c1cd90e2daa3e72da2a9d01013336 (patch)
tree1cf63b5901216ed21a3b4d68bf283cfaee6730f3 /backends
parenta02d90ae12c5386b85332536b516da435150dd88 (diff)
downloadelfutils-225dddfda38c1cd90e2daa3e72da2a9d01013336.tar.gz
backends: Add arm frame_nregs and set_initial_registers_tid.
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>
Diffstat (limited to 'backends')
-rw-r--r--backends/ChangeLog7
-rw-r--r--backends/Makefile.am2
-rw-r--r--backends/arm_init.c6
-rw-r--r--backends/arm_initreg.c58
4 files changed, 71 insertions, 2 deletions
diff --git a/backends/ChangeLog b/backends/ChangeLog
index c8e2b301..212b9f6d 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -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.
diff --git a/backends/Makefile.am b/backends/Makefile.am
index 90e93a88..4129eee5 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -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)
diff --git a/backends/arm_init.c b/backends/arm_init.c
index cf661cea..14b26356 100644
--- a/backends/arm_init.c
+++ b/backends/arm_init.c
@@ -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
index 00000000..c03146eb
--- /dev/null
+++ b/backends/arm_initreg.c
@@ -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
+}