summaryrefslogtreecommitdiff
path: root/src/crash-stack/crash-stack-libelf.c
diff options
context:
space:
mode:
authorAdrian Szyndela <adrian.s@samsung.com>2016-09-07 11:46:01 +0200
committerƁukasz Stelmach <l.stelmach@samsung.com>2016-12-08 12:25:06 +0100
commitb387718c185590e39e2ea15665c65db2d3e23fdc (patch)
treefb774371df1ddefd78b85c73f35b717e2c2dba78 /src/crash-stack/crash-stack-libelf.c
parent32bf01526b74ff60d211094088716377baf7983e (diff)
downloadcrash-worker-b387718c185590e39e2ea15665c65db2d3e23fdc.tar.gz
crash-worker-b387718c185590e39e2ea15665c65db2d3e23fdc.tar.bz2
crash-worker-b387718c185590e39e2ea15665c65db2d3e23fdc.zip
crash-stack: unwinding by frame pointer on aarch64
This fixes and adds again commit 269790304eea1bde27644962efa7803c7ab611df. Thus, this reverts commit ba3f2151f97c3e4bba1ac04c953f28ac4eb1e463, which reverted commit 269790304eea1bde27644962efa7803c7ab611df. To unwind call stack on aarch64 we need to use external method, as libelf 0.153 does not support unwinding yet. Possible methods are: - using libunwind; - manual walk with frame pointers; - heuristic unwind by inspecting data stack. This patch adds support for unwinding on aarch64 with frame pointers, along with changes needed to modularize unwinding. Change-Id: I461a06c96d56804fefb7167550e44074e734c94b
Diffstat (limited to 'src/crash-stack/crash-stack-libelf.c')
-rw-r--r--src/crash-stack/crash-stack-libelf.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/src/crash-stack/crash-stack-libelf.c b/src/crash-stack/crash-stack-libelf.c
index f4c10bc..b152bea 100644
--- a/src/crash-stack/crash-stack-libelf.c
+++ b/src/crash-stack/crash-stack-libelf.c
@@ -1,6 +1,16 @@
#include "crash-stack.h"
#include <elfutils/libdwfl.h>
#include <elfutils/version.h>
+#include <string.h>
+
+typedef union {
+ uint16_t reg16;
+ uint32_t reg32;
+ uint64_t reg64;
+} Register;
+
+static Register g_pc;
+static Register g_sp;
#if _ELFUTILS_PREREQ(0, 158)
static int frame_callback(Dwfl_Frame *state, void *arg)
@@ -19,9 +29,32 @@ static int thread_callback(Dwfl_Thread *thread, void *thread_arg)
}
#endif
+static const char *pc_names[] = {
+ "pc", "rip", "eip", "ip"
+};
+
+static const char *sp_names[] = {
+ "sp", "rsp", "esp"
+};
+
+static bool is_in(const char *name, const char **names, int elems)
+{
+ int nit;
+ for (nit = 0; nit < elems; ++nit) {
+ if (strcmp(name, names[nit]) == 0)
+ return true;
+ }
+ return false;
+}
+
+#define IS_IN(name,names) is_in((name), (names), sizeof(names)/sizeof(names[0]))
+
void *get_place_for_register_value(const char *regname, int regnum)
{
- return 0;
+ if (IS_IN(regname, pc_names)) return &g_pc;
+ else if (IS_IN(regname, sp_names)) return &g_sp;
+
+ return 0;
}
void create_crash_stack(Dwfl *dwfl, Elf *core, pid_t pid, Mappings *mappings, Callstack *callstack)