From: Mark Wielaard Date: Sun, 26 Jan 2014 19:16:48 +0000 (+0100) Subject: backends: Add arm frame_nregs and set_initial_registers_tid. X-Git-Tag: elfutils-0.159~40 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=225dddfda38c1cd90e2daa3e72da2a9d01013336;p=thirdparty%2Felfutils.git 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 --- diff --git a/backends/ChangeLog b/backends/ChangeLog index c8e2b3017..212b9f6dd 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,10 @@ +2014-01-26 Mark Wielaard + + * 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 * arm_cfi.c (arm_abi_cfi): Restore SP (r13) from CFA. diff --git a/backends/Makefile.am b/backends/Makefile.am index 90e93a88b..4129eee52 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 cf661cea6..14b263566 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 , 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 000000000..c03146eb9 --- /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 . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if defined __arm__ +# include +# include +# include +#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 +} diff --git a/tests/ChangeLog b/tests/ChangeLog index fa8a42a27..a279982c9 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,7 @@ +2014-01-26 Mark Wielaard + + * backtrace-subr.sh (check_unsupported): Special case arm*. + 2014-01-25 Mark Wielaard * run-addrcfi.sh (EM_ARM): Change reg13 (sp) from undefined to diff --git a/tests/backtrace-subr.sh b/tests/backtrace-subr.sh index 62b873c79..1df935648 100644 --- a/tests/backtrace-subr.sh +++ b/tests/backtrace-subr.sh @@ -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()