diff options
| author | Mark Wielaard <[email protected]> | 2014-04-09 11:48:23 +0200 |
|---|---|---|
| committer | Mark Wielaard <[email protected]> | 2014-04-14 11:31:28 +0200 |
| commit | 66637fa21044ac0058b25522f473669e73de328b (patch) | |
| tree | e3faa5f63f822ebad19dceaca203727443a79fa9 /backends | |
| parent | 7f1eec317db79627b473c5b149a22a1b20d1f68f (diff) | |
backends: Add aarch64 native and core unwind support.
Add aarch64 backend functions frame_nregs and set_initial_registers_tid.
Mark pc_register in aarch64 prstatus_regs as pc_register.
Add backtrace-core-aarch64 testcase.
Signed-off-by: Mark Wielaard <[email protected]>
Diffstat (limited to 'backends')
| -rw-r--r-- | backends/ChangeLog | 7 | ||||
| -rw-r--r-- | backends/Makefile.am | 3 | ||||
| -rw-r--r-- | backends/aarch64_corenote.c | 3 | ||||
| -rw-r--r-- | backends/aarch64_init.c | 6 | ||||
| -rw-r--r-- | backends/aarch64_initreg.c | 87 |
5 files changed, 104 insertions, 2 deletions
diff --git a/backends/ChangeLog b/backends/ChangeLog index 38a433d8..bfe23019 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,10 @@ +2014-04-09 Mark Wielaard <[email protected]> + + * Makefile.am (aarch64_SRCS): Add aarch64_initreg.c. + * aarch64_corenote.c (prstatus_regs): Mark pc_register. + * aarch64_init.c: Assign frame_nregs. Hook set_initial_registers_tid. + * aarch64_initreg: New file. + 2014-03-28 Jean Pihet <[email protected]> * arm_initreg.c (arm_set_initial_registers_tid): Handle compat mode. diff --git a/backends/Makefile.am b/backends/Makefile.am index 4129eee5..49593ac0 100644 --- a/backends/Makefile.am +++ b/backends/Makefile.am @@ -83,7 +83,8 @@ libebl_arm_pic_a_SOURCES = $(arm_SRCS) am_libebl_arm_pic_a_OBJECTS = $(arm_SRCS:.c=.os) aarch64_SRCS = aarch64_init.c aarch64_regs.c aarch64_symbol.c \ - aarch64_corenote.c aarch64_retval.c aarch64_cfi.c + aarch64_corenote.c aarch64_retval.c aarch64_cfi.c \ + aarch64_initreg.c libebl_aarch64_pic_a_SOURCES = $(aarch64_SRCS) am_libebl_aarch64_pic_a_OBJECTS = $(aarch64_SRCS:.c=.os) diff --git a/backends/aarch64_corenote.c b/backends/aarch64_corenote.c index 8f5b9d5d..9b424859 100644 --- a/backends/aarch64_corenote.c +++ b/backends/aarch64_corenote.c @@ -64,7 +64,8 @@ static const Ebl_Register_Location prstatus_regs[] = .name = "pc", .type = ELF_T_XWORD, .format = 'x', \ .offset = (offsetof (struct EBLHOOK(prstatus), pr_reg) \ + PRSTATUS_REGS_SIZE - 16), \ - .group = "register" \ + .group = "register", \ + .pc_register = true \ }, \ { \ .name = "pstate", .type = ELF_T_XWORD, .format = 'x', \ diff --git a/backends/aarch64_init.c b/backends/aarch64_init.c index a1a70606..b0fd17a7 100644 --- a/backends/aarch64_init.c +++ b/backends/aarch64_init.c @@ -59,5 +59,11 @@ aarch64_init (elf, machine, eh, ehlen) HOOK (eh, check_special_symbol); HOOK (eh, abi_cfi); + /* X0-X30 (31 regs) + SP + 1 Reserved + ELR, 30 Reserved regs (34-43) + + V0-V31 (32 regs, least significant 64 bits only) + + ALT_FRAME_RETURN_COLUMN (used when LR isn't used) = 97 DWARF regs. */ + eh->frame_nregs = 97; + HOOK (eh, set_initial_registers_tid); + return MODVERSION; } diff --git a/backends/aarch64_initreg.c b/backends/aarch64_initreg.c new file mode 100644 index 00000000..2492d561 --- /dev/null +++ b/backends/aarch64_initreg.c @@ -0,0 +1,87 @@ +/* Fetch live process registers from TID. + Copyright (C) 2013 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 + +#include "system.h" +#include <assert.h> +#ifdef __aarch64__ +# include <linux/uio.h> +# include <sys/user.h> +# include <sys/ptrace.h> +#endif + +#define BACKEND aarch64_ +#include "libebl_CPU.h" + +bool +aarch64_set_initial_registers_tid (pid_t tid __attribute__ ((unused)), + ebl_tid_registers_t *setfunc __attribute__ ((unused)), + void *arg __attribute__ ((unused))) +{ +#ifndef __aarch64__ + return false; +#else /* __aarch64__ */ + + /* General registers. */ + struct user_pt_regs gregs; + struct iovec iovec; + iovec.iov_base = &gregs; + iovec.iov_len = sizeof (gregs); + if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iovec) != 0) + return false; + + /* X0..X30 plus SP. */ + if (! setfunc (0, 32, (Dwarf_Word *) &gregs.regs[0], arg)) + return false; + + /* PC. */ + if (! setfunc (-1, 1, (Dwarf_Word *) &gregs.pc, arg)) + return false; + + /* ELR cannot be found. */ + + /* FP registers (only 64bits are used). */ + struct user_fpsimd_state fregs; + iovec.iov_base = &fregs; + iovec.iov_len = sizeof (fregs); + if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iovec) != 0) + return false; + + Dwarf_Word dwarf_fregs[32]; + for (int r = 0; r < 32; r++) + dwarf_fregs[r] = fregs.vregs[r] & 0xFFFFFFFF; + + if (! setfunc (64, 32, dwarf_fregs, arg)) + return false; + + return true; +#endif /* __aarch64__ */ +} |
