diff options
author | Mark Wielaard <mjw@redhat.com> | 2014-01-26 20:16:48 +0100 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2014-01-30 11:08:32 +0100 |
commit | 225dddfda38c1cd90e2daa3e72da2a9d01013336 (patch) | |
tree | 1cf63b5901216ed21a3b4d68bf283cfaee6730f3 /backends | |
parent | a02d90ae12c5386b85332536b516da435150dd88 (diff) | |
download | elfutils-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/ChangeLog | 7 | ||||
-rw-r--r-- | backends/Makefile.am | 2 | ||||
-rw-r--r-- | backends/arm_init.c | 6 | ||||
-rw-r--r-- | backends/arm_initreg.c | 58 |
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 +} |