summaryrefslogtreecommitdiffstats
path: root/3rdparty/elfutils
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@theqtcompany.com>2016-03-15 19:29:25 +0100
committerUlf Hermann <ulf.hermann@theqtcompany.com>2016-03-17 09:25:38 +0000
commit17ad3b57d613fede17a01b6cdd2d894850364f81 (patch)
tree6db562f557acb145d85e1a90eeeedb79c83bf5f1 /3rdparty/elfutils
parenteb8cb4749e8b30a4bc25f2c2adeeabc8481fab4b (diff)
Add frame pointer unwinding for aarch64
Change-Id: I43f184deba97ed57cc7efbfbda9432cfd8d99664 Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
Diffstat (limited to '3rdparty/elfutils')
-rw-r--r--3rdparty/elfutils/backends/aarch64/aarch64.pro3
-rw-r--r--3rdparty/elfutils/backends/aarch64_init.c1
-rw-r--r--3rdparty/elfutils/backends/aarch64_unwind.c78
3 files changed, 81 insertions, 1 deletions
diff --git a/3rdparty/elfutils/backends/aarch64/aarch64.pro b/3rdparty/elfutils/backends/aarch64/aarch64.pro
index 5489b1d..a53be98 100644
--- a/3rdparty/elfutils/backends/aarch64/aarch64.pro
+++ b/3rdparty/elfutils/backends/aarch64/aarch64.pro
@@ -8,7 +8,8 @@ SOURCES += \
../aarch64_initreg.c \
../aarch64_regs.c \
../aarch64_retval.c \
- ../aarch64_symbol.c
+ ../aarch64_symbol.c \
+ ../aarch64_unwind.c
HEADERS += \
../aarch64_reloc.def
diff --git a/3rdparty/elfutils/backends/aarch64_init.c b/3rdparty/elfutils/backends/aarch64_init.c
index b0fd17a..8a96f73 100644
--- a/3rdparty/elfutils/backends/aarch64_init.c
+++ b/3rdparty/elfutils/backends/aarch64_init.c
@@ -64,6 +64,7 @@ aarch64_init (elf, machine, eh, ehlen)
+ ALT_FRAME_RETURN_COLUMN (used when LR isn't used) = 97 DWARF regs. */
eh->frame_nregs = 97;
HOOK (eh, set_initial_registers_tid);
+ HOOK (eh, unwind);
return MODVERSION;
}
diff --git a/3rdparty/elfutils/backends/aarch64_unwind.c b/3rdparty/elfutils/backends/aarch64_unwind.c
new file mode 100644
index 0000000..5560c58
--- /dev/null
+++ b/3rdparty/elfutils/backends/aarch64_unwind.c
@@ -0,0 +1,78 @@
+/* Get previous frame state for an existing frame state.
+ Copyright (C) 2016 The Qt Company Ltd.
+ 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 <stdlib.h>
+#include <assert.h>
+
+#define BACKEND aarch64_
+#include "libebl_CPU.h"
+#include <stdio.h>
+
+/* There was no CFI. Maybe we happen to have a frame pointer and can unwind from that? */
+
+bool
+aarch64_unwind (Ebl *ebl __attribute__ ((unused)), Dwarf_Addr pc __attribute__ ((unused)),
+ ebl_tid_registers_t *setfunc, ebl_tid_registers_get_t *getfunc,
+ ebl_pid_memory_read_t *readfunc, void *arg, bool *signal_framep)
+{
+ const int fpReg = 29;
+ const int lrReg = 30;
+ const int spReg = 31;
+
+ Dwarf_Word fp;
+ if (!getfunc(fpReg, 1, &fp, arg) || fp == 0)
+ return false;
+
+ Dwarf_Word lr;
+ if (!getfunc(lrReg, 1, &lr, arg))
+ return false;
+
+ Dwarf_Word newFp, newLr;
+ if (!readfunc(fp, &newFp, arg))
+ return false;
+ fp += 8;
+ if (!readfunc(fp, &newLr, arg))
+ return false;
+
+ fp += 8;
+ if (!setfunc(spReg, 1, &fp, arg))
+ return false;
+ if (!setfunc(fpReg, 1, &newFp, arg))
+ return false;
+ if (!setfunc(-1, 1, &newLr, arg))
+ return false;
+ if (!setfunc(lrReg, 1, &newLr, arg))
+ return false;
+
+ *signal_framep = false;
+ return true;
+}