summaryrefslogtreecommitdiffstats
path: root/backends
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2014-04-09 11:48:23 +0200
committerMark Wielaard <[email protected]>2014-04-14 11:31:28 +0200
commit66637fa21044ac0058b25522f473669e73de328b (patch)
treee3faa5f63f822ebad19dceaca203727443a79fa9 /backends
parent7f1eec317db79627b473c5b149a22a1b20d1f68f (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/ChangeLog7
-rw-r--r--backends/Makefile.am3
-rw-r--r--backends/aarch64_corenote.c3
-rw-r--r--backends/aarch64_init.c6
-rw-r--r--backends/aarch64_initreg.c87
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__ */
+}