summaryrefslogtreecommitdiff
path: root/src/crash-stack
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
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')
-rw-r--r--src/crash-stack/CMakeLists.txt19
-rw-r--r--src/crash-stack/crash-stack-aarch64.c74
-rw-r--r--src/crash-stack/crash-stack-arm.c129
-rw-r--r--src/crash-stack/crash-stack-libelf-helpers.c117
-rw-r--r--src/crash-stack/crash-stack-libelf.c35
-rw-r--r--src/crash-stack/crash-stack-stub.c11
-rw-r--r--src/crash-stack/crash-stack-x86_64.c23
-rw-r--r--src/crash-stack/crash-stack.c31
-rw-r--r--src/crash-stack/crash-stack.h8
9 files changed, 325 insertions, 122 deletions
diff --git a/src/crash-stack/CMakeLists.txt b/src/crash-stack/CMakeLists.txt
index b11c4d0..ab878bc 100644
--- a/src/crash-stack/CMakeLists.txt
+++ b/src/crash-stack/CMakeLists.txt
@@ -1,23 +1,38 @@
option(WITH_CORE_DUMP "builds with support for core dump files (with GPL2 license)")
set(CRASH_STACK_BIN "crash-stack")
-set(CRASH_STACK_SRCS crash-stack.c)
+# Common source code files
+set(CRASH_STACK_SRCS crash-stack.c crash-stack-libelf-helpers.c)
+# Add architecture dependent source files
if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "armv7l")
set(CRASH_STACK_SRCS ${CRASH_STACK_SRCS} crash-stack-arm.c wind/unwarm.c wind/unwarm_thumb.c wind/unwarm_arm.c wind/unwarmmem.c)
else()
- set(CRASH_STACK_SRCS ${CRASH_STACK_SRCS} crash-stack-libelf.c)
+ if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
+ set(CRASH_STACK_SRCS ${CRASH_STACK_SRCS} crash-stack-aarch64.c)
+ elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
+ set(CRASH_STACK_SRCS ${CRASH_STACK_SRCS} crash-stack-libelf.c)
+ set(CRASH_STACK_SRCS ${CRASH_STACK_SRCS} crash-stack-x86_64.c)
+ else()
+ set(CRASH_STACK_SRCS ${CRASH_STACK_SRCS} crash-stack-libelf.c)
+ set(CRASH_STACK_SRCS ${CRASH_STACK_SRCS} crash-stack-stub.c)
+ endif()
endif()
+# Binary
add_executable(${CRASH_STACK_BIN} ${CRASH_STACK_SRCS})
+# Set architecture dependent options for the binary - it must be already added
if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "armv7l")
set_property(TARGET ${CRASH_STACK_BIN} APPEND_STRING PROPERTY COMPILE_FLAGS " -DUPGRADE_ARM_STACK_UNWIND")
# set_property(TARGET ${CRASH_STACK_BIN} APPEND_STRING PROPERTY COMPILE_FLAGS "-DUPGRADE_ARM_STACK_UNWIND -DUNW_DEBUG")
endif()
+# Set compilation options for core dump support
if (${WITH_CORE_DUMP} STREQUAL "ON")
set_property(TARGET ${CRASH_STACK_BIN} APPEND_STRING PROPERTY COMPILE_FLAGS " -DWITH_CORE_DUMP")
endif()
+# Linking
target_link_libraries(${CRASH_STACK_BIN} dw elf ebl dl stdc++)
+# Installing
install(TARGETS ${CRASH_STACK_BIN} DESTINATION libexec)
diff --git a/src/crash-stack/crash-stack-aarch64.c b/src/crash-stack/crash-stack-aarch64.c
new file mode 100644
index 0000000..f9cac96
--- /dev/null
+++ b/src/crash-stack/crash-stack-aarch64.c
@@ -0,0 +1,74 @@
+#include "crash-stack.h"
+#include <sys/user.h>
+#include <string.h>
+
+static struct user_regs_struct g_registers;
+
+struct Regs {
+ Dwarf_Addr x29;
+ Dwarf_Addr x30;
+ Dwarf_Addr pc;
+ Dwarf_Addr sp;
+};
+
+#define REG_SP 32
+#define REG_PC 33
+#define REG_X29 29
+#define REG_X30 30
+
+typedef struct Regs Regs;
+static Regs g_regs;
+
+void *crash_stack_get_memory_for_ptrace_registers(size_t *size)
+{
+ if (NULL != size)
+ *size = sizeof(g_registers);
+ return &g_registers;
+}
+
+void crash_stack_set_ptrace_registers(void *regbuf)
+{
+ struct user_regs_struct *regs = regbuf;
+
+ memcpy(get_place_for_register_value("sp", 0), &regs->sp, sizeof(regs->sp));
+ memcpy(get_place_for_register_value("pc", 0), &regs->pc, sizeof(regs->pc));
+ memcpy(get_place_for_register_value("x29", 0), &regs->regs[29], sizeof(regs->regs[29]));
+ memcpy(get_place_for_register_value("x30", 0), &regs->regs[30], sizeof(regs->regs[30]));
+}
+
+void create_crash_stack(Dwfl *dwfl, Elf *core, pid_t pid, Mappings *mappings, Callstack *callstack)
+{
+ callstack->elems = 0;
+ callstack->tab[callstack->elems++] = g_regs.pc;
+ callstack->tab[callstack->elems++] = g_regs.x30;
+
+ bool end = false;
+
+ do {
+ uint64_t newx29, newx30;
+ bool read29 = crash_stack_libelf_read_value(dwfl, core, pid,
+ g_regs.x29,
+ &newx29, sizeof(newx29), mappings);
+ bool read30 = crash_stack_libelf_read_value(dwfl, core, pid,
+ g_regs.x29 + sizeof(newx29),
+ &newx30, sizeof(newx30), mappings);
+ if (read29 && read30) {
+ callstack->tab[callstack->elems++] = newx30;
+ g_regs.x29 = newx29;
+ }
+ else end = true;
+ } while (!end);
+}
+
+void *get_place_for_register_value(const char *regname, int regnum)
+{
+ if (strcmp(regname, "pc") == 0 || REG_PC == regnum)
+ return &g_regs.pc;
+ else if (strcmp(regname, "sp") == 0 || REG_SP == regnum)
+ return &g_regs.sp;
+ else if (strcmp(regname, "x29") == 0 || REG_X29 == regnum)
+ return &g_regs.x29;
+ else if (strcmp(regname, "x30") == 0 || REG_X30 == regnum)
+ return &g_regs.x30;
+ return NULL;
+}
diff --git a/src/crash-stack/crash-stack-arm.c b/src/crash-stack/crash-stack-arm.c
index c1d2628..acb3ead 100644
--- a/src/crash-stack/crash-stack-arm.c
+++ b/src/crash-stack/crash-stack-arm.c
@@ -3,6 +3,7 @@
#include <string.h>
#include <sys/ptrace.h>
+#include <sys/user.h>
static Elf *g_core = NULL;
static Dwfl *g_dwfl = NULL;
@@ -20,6 +21,15 @@ struct Regs {
typedef struct Regs Regs;
static Regs g_regs;
+static struct user_regs g_ptrace_registers;
+
+void *crash_stack_get_memory_for_ptrace_registers(size_t *size)
+{
+ if (NULL != size)
+ *size = sizeof(g_ptrace_registers);
+ return &g_ptrace_registers;
+}
+
void *get_place_for_register_value(const char *regname, int regnum)
{
if (strcmp(regname, "pc") == 0 || REG_PC == regnum)
@@ -35,6 +45,17 @@ void *get_place_for_register_value(const char *regname, int regnum)
return NULL;
}
+void crash_stack_set_ptrace_registers(void *regbuf)
+{
+ struct user_regs *registers = regbuf;
+ int i;
+ for (i = 0; i < sizeof(registers->uregs)/sizeof(registers->uregs[0]); i++) {
+ void *regmem = get_place_for_register_value("", i);
+ if (NULL != regmem)
+ memcpy(regmem, &registers->uregs[i], sizeof(registers->uregs[i]));
+ }
+}
+
static Boolean report(void *data, Int32 address)
{
Callstack *callstack = (Callstack *)(data);
@@ -45,68 +66,7 @@ static Boolean report(void *data, Int32 address)
Boolean readT(Int32 a, void *v, size_t size)
{
- Dwfl_Module *module = 0;
- Elf_Data *data = NULL;
-
- int segment = dwfl_addrsegment(g_dwfl, a, &module);
-
- if (module != NULL) {
- Dwarf_Addr start;
- dwfl_module_info(module, NULL, &start, NULL, NULL, NULL, NULL, NULL);
-
- GElf_Addr bias;
- Elf *elf = dwfl_module_getelf(module, &bias);
-
- data = elf_getdata_rawchunk(elf, a-start, size, ELF_T_BYTE);
- }
- if (NULL == data && segment != -1) {
- // get data from segment
- GElf_Phdr mem;
- GElf_Phdr *phdr;
- Dwarf_Addr offset_in_segment;
-
- phdr = gelf_getphdr(g_core, segment, &mem);
- if (phdr != NULL) {
- offset_in_segment = a - phdr->p_vaddr;
- if (offset_in_segment < phdr->p_filesz) {
- Dwarf_Addr offset_in_file = phdr->p_offset + offset_in_segment;
-
- data = elf_getdata_rawchunk(g_core, offset_in_file, size, ELF_T_BYTE);
- }
- }
- }
-
- if (NULL == data && module != NULL) {
- const char *name = dwfl_module_info(module, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
- if (name != NULL && name[0] == '[') {
- int i;
- // get module from mappings
- for (i = 0; i < g_mappings->elems; i++) {
- if (g_mappings->tab[i].m_start <= a && a < g_mappings->tab[i].m_end) {
- // compute offset relative to the start of the mapping
- Int32 offset = a - g_mappings->tab[i].m_start;
- // read from the file, but also account file offset
- data = elf_getdata_rawchunk(g_mappings->tab[i].m_elf,
- offset + g_mappings->tab[i].m_offset, size, ELF_T_BYTE);
- break;
- }
- }
- }
- }
-
- if (data != NULL) {
- memcpy(v, data->d_buf, size);
- return TRUE;
- }
-
- /* Still no data, but we have a process - read memory with ptrace */
- if (NULL == data && g_pid > 1) {
- long val = ptrace(PTRACE_PEEKDATA, g_pid, a, NULL);
- memcpy(v, &val, size);
- return TRUE;
- }
-
- return FALSE;
+ return crash_stack_libelf_read_value(g_dwfl, g_core, g_pid, a, v, size, g_mappings);
}
static Boolean readW(Int32 a, Int32 *v)
@@ -126,50 +86,7 @@ static Boolean readB(Int32 a, Int8 *v)
static Int32 getProloguePC(Int32 current_pc)
{
- Int32 result = 0;
- Dwfl_Module *module = dwfl_addrmodule(g_dwfl, current_pc);
- if (module) {
- // GElf_Off offset;
- GElf_Sym sym;
- // dwfl_module_addrinfo (module, current_pc, &offset, &sym, NULL, NULL, NULL);
- dwfl_module_addrsym(module, current_pc, &sym, NULL);
- // result = current_pc - offset;
- result = sym.st_value;
- }
- if (0 == result) {
- int i;
- for (i = 0; i < g_mappings->elems; i++) {
- if (g_mappings->tab[i].m_start <= current_pc && current_pc < g_mappings->tab[i].m_end) {
- /* go through symbols to find the nearest */
- Elf_Scn *scn = NULL;
- Elf *elf = g_mappings->tab[i].m_elf;
- while ((scn = elf_nextscn(elf, scn)) != NULL) {
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr(scn, &shdr_mem);
- if (shdr != NULL && (shdr->sh_type == SHT_SYMTAB || shdr->sh_type == SHT_DYNSYM)) {
- Elf_Data *sdata = elf_getdata(scn, NULL);
- unsigned int nsyms = sdata->d_size / (gelf_getclass(elf) == ELFCLASS32 ?
- sizeof(Elf32_Sym) :
- sizeof(Elf64_Sym));
- unsigned int cnt;
- uintptr_t address_offset = current_pc;
- if (shdr->sh_type == SHT_DYNSYM)
- address_offset -= g_mappings->tab[i].m_start;
- for (cnt = 0; cnt < nsyms; ++cnt) {
- GElf_Sym sym_mem;
- Elf32_Word xndx;
- GElf_Sym *sym = gelf_getsymshndx(sdata, NULL, cnt, &sym_mem, &xndx);
- if (sym != NULL && sym->st_shndx != SHN_UNDEF) {
- if (sym->st_value <= address_offset && address_offset < sym->st_value + sym->st_size)
- return sym->st_value;
- }
- }
- }
- }
- }
- }
- }
- return result;
+ return crash_stack_libelf_get_prologue_pc(g_dwfl, current_pc, g_mappings);
}
void create_crash_stack(Dwfl *dwfl, Elf *core, pid_t pid, Mappings *mappings, Callstack *callstack)
diff --git a/src/crash-stack/crash-stack-libelf-helpers.c b/src/crash-stack/crash-stack-libelf-helpers.c
new file mode 100644
index 0000000..7dab540
--- /dev/null
+++ b/src/crash-stack/crash-stack-libelf-helpers.c
@@ -0,0 +1,117 @@
+#include "crash-stack.h"
+#include <string.h>
+#include <sys/ptrace.h>
+#include <errno.h>
+
+bool crash_stack_libelf_read_value(Dwfl *dwfl, Elf *core, pid_t pid,
+ Dwarf_Addr a, void *v, size_t size,
+ Mappings *mappings)
+{
+ Dwfl_Module *module = 0;
+ Elf_Data *data = NULL;
+
+ int segment = dwfl_addrsegment(dwfl, a, &module);
+
+ if (module != NULL) {
+ Dwarf_Addr start;
+ dwfl_module_info(module, NULL, &start, NULL, NULL, NULL, NULL, NULL);
+
+ GElf_Addr bias;
+ Elf *elf = dwfl_module_getelf(module, &bias);
+
+ data = elf_getdata_rawchunk(elf, a-start, size, ELF_T_BYTE);
+ }
+ if (NULL == data && segment != -1) {
+ // get data from segment
+ GElf_Phdr mem;
+ GElf_Phdr *phdr = gelf_getphdr(core, segment, &mem);
+ Dwarf_Addr offset_in_segment = a - phdr->p_vaddr;
+ if (offset_in_segment < phdr->p_filesz) {
+ Dwarf_Addr offset_in_file = phdr->p_offset + offset_in_segment;
+
+ data = elf_getdata_rawchunk(core, offset_in_file, size, ELF_T_BYTE);
+ }
+ }
+
+ if (NULL == data && module != NULL) {
+ const char *name = dwfl_module_info(module, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ if (name != NULL && name[0] == '[') {
+ int i;
+ // get module from mappings
+ for (i = 0; i < mappings->elems; i++) {
+ if (mappings->tab[i].m_start <= a && a < mappings->tab[i].m_end) {
+ // compute offset relative to the start of the mapping
+ long offset = a - mappings->tab[i].m_start;
+ // read from the file, but also account file offset
+ data = elf_getdata_rawchunk(mappings->tab[i].m_elf,
+ offset + mappings->tab[i].m_offset, size, ELF_T_BYTE);
+ break;
+ }
+ }
+ }
+ }
+
+ if (data != NULL) {
+ memcpy(v, data->d_buf, size);
+ return true;
+ }
+
+ /* Still no data, but we have a process - read memory with ptrace */
+ /* FIXME need to know if we are still in the mapped area */
+ /* Bigger issue is that dwfl does not have modules */
+ if (pid > 1) {
+ long val = ptrace(PTRACE_PEEKDATA, pid, a, NULL);
+ if (-1 == val && errno)
+ return false;
+ memcpy(v, &val, size);
+ return true;
+ }
+
+ return false;
+}
+
+Dwarf_Addr crash_stack_libelf_get_prologue_pc(Dwfl *dwfl, Dwarf_Addr current_pc, Mappings *mappings)
+{
+ Dwarf_Addr result = 0;
+ Dwfl_Module *module = dwfl_addrmodule(dwfl, current_pc);
+ if (module) {
+ GElf_Sym sym;
+ dwfl_module_addrsym(module, current_pc, &sym, NULL);
+ result = sym.st_value;
+ }
+ if (0 == result) {
+ int i;
+ for (i=0; i < mappings->elems; i++) {
+ if (mappings->tab[i].m_start <= current_pc && current_pc < mappings->tab[i].m_end) {
+ /* go through symbols to find the nearest */
+ Elf_Scn *scn = NULL;
+ Elf *elf = mappings->tab[i].m_elf;
+ while ((scn = elf_nextscn(elf, scn)) != NULL) {
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr(scn, &shdr_mem);
+ if (shdr != NULL && (shdr->sh_type == SHT_SYMTAB || shdr->sh_type == SHT_DYNSYM)) {
+ Elf_Data *sdata = elf_getdata(scn, NULL);
+ unsigned int nsyms = sdata->d_size / (gelf_getclass(elf) == ELFCLASS32 ?
+ sizeof(Elf32_Sym) :
+ sizeof(Elf64_Sym));
+ unsigned int cnt;
+ uintptr_t address_offset = current_pc;
+ if (shdr->sh_type == SHT_DYNSYM)
+ address_offset -= mappings->tab[i].m_start;
+ for (cnt = 0; cnt < nsyms; ++cnt) {
+ GElf_Sym sym_mem;
+ Elf32_Word xndx;
+ GElf_Sym *sym = gelf_getsymshndx(sdata, NULL, cnt, &sym_mem, &xndx);
+ if (sym != NULL && sym->st_shndx != SHN_UNDEF) {
+ if (sym->st_value <= address_offset && address_offset < sym->st_value + sym->st_size) {
+ return sym->st_value;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return result;
+}
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)
diff --git a/src/crash-stack/crash-stack-stub.c b/src/crash-stack/crash-stack-stub.c
new file mode 100644
index 0000000..d0dc46b
--- /dev/null
+++ b/src/crash-stack/crash-stack-stub.c
@@ -0,0 +1,11 @@
+#include "crash-stack.h"
+
+void *crash_stack_get_memory_for_ptrace_registers(size_t *size)
+{
+ return NULL;
+}
+
+void crash_stack_set_ptrace_registers(void *regbuf)
+{
+}
+
diff --git a/src/crash-stack/crash-stack-x86_64.c b/src/crash-stack/crash-stack-x86_64.c
new file mode 100644
index 0000000..934ee72
--- /dev/null
+++ b/src/crash-stack/crash-stack-x86_64.c
@@ -0,0 +1,23 @@
+#include "crash-stack.h"
+#include <sys/user.h>
+#include <string.h>
+
+struct user_regs_struct g_registers;
+
+void *crash_stack_get_memory_for_ptrace_registers(size_t *size)
+{
+ if (NULL != size)
+ *size = sizeof(g_registers);
+ return &g_registers;
+}
+
+void crash_stack_set_ptrace_registers(void *regbuf)
+{
+ void *rsp = get_place_for_register_value("rsp", 0);
+ void *rip = get_place_for_register_value("rip", 0);
+
+ struct user_regs_struct *regs = regbuf;
+
+ memcpy(rsp, &regs->rsp, sizeof(regs->rsp));
+ memcpy(rip, &regs->rip, sizeof(regs->rip));
+}
diff --git a/src/crash-stack/crash-stack.c b/src/crash-stack/crash-stack.c
index 609ac2f..ef733e0 100644
--- a/src/crash-stack/crash-stack.c
+++ b/src/crash-stack/crash-stack.c
@@ -62,9 +62,19 @@ static int module_callback(Dwfl_Module *module, void **userdata,
static void getvalue(Elf *core, const void *from, size_t size, void *to)
{
+ Elf_Type type = ELF_T_BYTE;
+ switch (size) {
+ case 8: type = ELF_T_BYTE; break;
+ case 16: type = ELF_T_HALF; break;
+ case 32: type = ELF_T_WORD; break;
+ case 64: type = ELF_T_XWORD; break;
+ default:
+ fprintf(stderr, "getvalue for strange size: %llu\n", (unsigned long long)size);
+ break;
+ }
Elf_Data out = {
.d_buf = to,
- .d_type = size == 32 ? ELF_T_WORD : ELF_T_XWORD,
+ .d_type = type,
.d_version = EV_CURRENT,
.d_size = size/8,
.d_off = 0,
@@ -282,25 +292,20 @@ static Dwfl *open_dwfl_with_core(Elf *core, const char *core_file_name)
static int get_registers_ptrace(pid_t pid)
{
struct iovec data;
- uintptr_t regbuf[20];
+ data.iov_base = crash_stack_get_memory_for_ptrace_registers( &data.iov_len );
- data.iov_base = regbuf;
- data.iov_len = sizeof(regbuf);
+ if (NULL == data.iov_base) {
+ fprintf(errfile, "Cannot get memory for registers for ptrace (not implemented for this architecture\n");
+ return -1;
+ }
if (ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &data) != 0) {
fprintf(errfile, "PTRACE_GETREGSET failed on PID %d: %m\n", pid);
return -1;
}
- size_t i;
- for (i = 0;
- i * sizeof(regbuf[0]) < data.iov_len && i < sizeof(regbuf)/sizeof(regbuf[0]);
- i++) {
- void *reg = get_place_for_register_value("", i);
+ crash_stack_set_ptrace_registers(data.iov_base);
- if (NULL != reg)
- memcpy(reg, &regbuf[i], sizeof(regbuf[i]));
- }
return 0;
}
@@ -335,7 +340,7 @@ static Elf_Data *get_registers_core(Elf *core, const char *core_file_name, Mappi
return NULL;
}
- Elf_Data *notes = elf_getdata_rawchunk(core, phdr->p_offset, phdr->p_filesz, ELF_T_NHDR);
+ notes = elf_getdata_rawchunk(core, phdr->p_offset, phdr->p_filesz, ELF_T_NHDR);
if (notes == NULL) {
fprintf(errfile, "%s : error getting notes (%s)\n", core_file_name, dwfl_errmsg(-1));
return NULL;
diff --git a/src/crash-stack/crash-stack.h b/src/crash-stack/crash-stack.h
index bf712c0..195bce5 100644
--- a/src/crash-stack/crash-stack.h
+++ b/src/crash-stack/crash-stack.h
@@ -31,4 +31,12 @@ typedef struct Mappings {
void *get_place_for_register_value(const char *regname, int regnum);
void create_crash_stack(Dwfl *dwfl, Elf *core, pid_t pid, Mappings *mappings, Callstack *callstack);
+Dwarf_Addr crash_stack_libelf_get_prologue_pc(Dwfl *dwfl, Dwarf_Addr current_pc, Mappings *mappings);
+bool crash_stack_libelf_read_value(Dwfl *dwfl, Elf *core, pid_t pid,
+ Dwarf_Addr a, void *v, size_t size,
+ Mappings *mappings);
+
+void *crash_stack_get_memory_for_ptrace_registers(size_t *size);
+void crash_stack_set_ptrace_registers(void *regbuf);
+
#endif /* CRASH_STACK_H */