This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
Re: [patch v5] unwinder: The unwinder (x86* only)
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: elfutils-devel at lists dot fedorahosted dot org
- Date: Fri, 11 Oct 2013 22:07:00 +0200
- Subject: Re: [patch v5] unwinder: The unwinder (x86* only)
On Fri, 11 Oct 2013 14:34:48 +0200, Mark Wielaard wrote:
> So I was thinking something like the attached (it compiles, might not
> actually work).
FYI this part I have applied from your patch, as discussed in the other mail.
Thanks,
Jan
diff --git a/backends/i386_initreg.c b/backends/i386_initreg.c
index 9d904a4..b776e01 100644
--- a/backends/i386_initreg.c
+++ b/backends/i386_initreg.c
@@ -40,8 +40,9 @@
#include "libebl_CPU.h"
bool
-i386_set_initial_registers_tid (struct Dwfl_Thread *thread, pid_t tid,
- dwfl_thread_state_registers_t *setfunc)
+i386_set_initial_registers_tid (pid_t tid,
+ ebl_tid_registers_t *setfunc,
+ void *arg)
{
#if !defined __i386__ && !defined __x86_64__
return false;
@@ -73,7 +74,7 @@ i386_set_initial_registers_tid (struct Dwfl_Thread *thread, pid_t tid,
# else /* (__i386__ || __x86_64__) && (!__i386__ && !__x86_64__) */
# error
# endif /* (__i386__ || __x86_64__) && (!__i386__ && !__x86_64__) */
- return setfunc (thread, 0, 9, dwarf_regs);
+ return setfunc (0, 9, dwarf_regs, arg);
#endif /* __i386__ || __x86_64__ */
return true;
}
diff --git a/backends/x86_64_initreg.c b/backends/x86_64_initreg.c
index 9f7c119..1cc9b9f 100644
--- a/backends/x86_64_initreg.c
+++ b/backends/x86_64_initreg.c
@@ -40,8 +40,9 @@
#include "libebl_CPU.h"
bool
-x86_64_set_initial_registers_tid (struct Dwfl_Thread *thread, pid_t tid,
- dwfl_thread_state_registers_t *setfunc)
+x86_64_set_initial_registers_tid (pid_t tid,
+ ebl_tid_registers_t *setfunc,
+ void *arg)
{
#ifndef __x86_64__
return false;
@@ -67,6 +68,6 @@ x86_64_set_initial_registers_tid (struct Dwfl_Thread *thread, pid_t tid,
dwarf_regs[14] = user_regs.r14;
dwarf_regs[15] = user_regs.r15;
dwarf_regs[16] = user_regs.rip;
- return setfunc (thread, 0, 17, dwarf_regs);
+ return setfunc (0, 17, dwarf_regs, arg);
#endif /* __x86_64__ */
}
diff --git a/libdwfl/dwfl_frame_pid.c b/libdwfl/dwfl_frame_pid.c
index e91e82f..1998589 100644
--- a/libdwfl/dwfl_frame_pid.c
+++ b/libdwfl/dwfl_frame_pid.c
@@ -134,6 +134,16 @@ pid_next_thread (Dwfl *dwfl __attribute__ ((unused)),
}
static bool
+pid_thread_state_registers_cb (const int firstreg,
+ unsigned nregs,
+ const Dwarf_Word *regs,
+ void *arg)
+{
+ Dwfl_Thread *thread = (Dwfl_Thread *) arg;
+ return INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs);
+}
+
+static bool
pid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg)
{
struct pid_arg *pid_arg = thread_arg;
@@ -151,8 +161,8 @@ pid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg)
pid_arg->tids_attached[pid_arg->tids_attached_used++] = tid;
Dwfl_Process *process = thread->process;
Ebl *ebl = process->ebl;
- return ebl_set_initial_registers_tid (ebl, thread, tid,
- INTUSE(dwfl_thread_state_registers));
+ return ebl_set_initial_registers_tid (ebl, tid,
+ pid_thread_state_registers_cb, thread);
}
static void
diff --git a/libebl/ebl-hooks.h b/libebl/ebl-hooks.h
index 05ca18b..32ca37c 100644
--- a/libebl/ebl-hooks.h
+++ b/libebl/ebl-hooks.h
@@ -156,8 +156,9 @@ int EBLHOOK(disasm) (const uint8_t **startp, const uint8_t *end,
int EBLHOOK(abi_cfi) (Ebl *ebl, Dwarf_CIE *abi_info);
/* Fetch process data from live TID into THREAD->unwound. */
-bool EBLHOOK(set_initial_registers_tid) (struct Dwfl_Thread *thread, pid_t tid,
- dwfl_thread_state_registers_t *setfunc);
+bool EBLHOOK(set_initial_registers_tid) (pid_t tid,
+ ebl_tid_registers_t *setfunc,
+ void *arg);
/* Destructor for ELF backend handle. */
void EBLHOOK(destr) (struct ebl *);
diff --git a/libebl/eblinitreg.c b/libebl/eblinitreg.c
index 4aa9d9b..8909c50 100644
--- a/libebl/eblinitreg.c
+++ b/libebl/eblinitreg.c
@@ -34,13 +34,14 @@
#include <assert.h>
bool
-ebl_set_initial_registers_tid (Ebl *ebl, struct Dwfl_Thread *thread, pid_t tid,
- dwfl_thread_state_registers_t *setfunc)
+ebl_set_initial_registers_tid (Ebl *ebl, pid_t tid,
+ ebl_tid_registers_t *setfunc,
+ void *arg)
{
/* Otherwise caller could not allocate THREAD frame of proper size.
If set_initial_registers_tid is unsupported then FRAME_NREGS is zero. */
assert (ebl->set_initial_registers_tid != NULL);
- return ebl->set_initial_registers_tid (thread, tid, setfunc);
+ return ebl->set_initial_registers_tid (tid, setfunc, arg);
}
size_t
diff --git a/libebl/libebl.h b/libebl/libebl.h
index e3185b4..7c04355 100644
--- a/libebl/libebl.h
+++ b/libebl/libebl.h
@@ -383,17 +383,18 @@ extern int ebl_auxv_info (Ebl *ebl, GElf_Xword a_type,
const char **name, const char **format)
__nonnull_attribute__ (1, 3, 4);
-/* Fetch process data from live TID into THREAD->unwound. */
-struct Dwfl_Thread;
-typedef bool (dwfl_thread_state_registers_t) (struct Dwfl_Thread *thread,
- const int firstreg,
- unsigned nregs,
- const Dwarf_Word *regs)
- __nonnull_attribute__ (1, 4);
-extern bool ebl_set_initial_registers_tid (Ebl *ebl, struct Dwfl_Thread *thread,
+/* Callback to fetch process data from live TID. */
+typedef bool (ebl_tid_registers_t) (const int firstreg,
+ unsigned nregs,
+ const Dwarf_Word *regs,
+ void *arg)
+ __nonnull_attribute__ (3);
+
+extern bool ebl_set_initial_registers_tid (Ebl *ebl,
pid_t tid,
- dwfl_thread_state_registers_t *setfunc)
- __nonnull_attribute__ (1);
+ ebl_tid_registers_t *setfunc,
+ void *arg)
+ __nonnull_attribute__ (1, 3);
/* Number of registers to allocate
for STATE of ebl_set_initial_registers_tid. */