summaryrefslogtreecommitdiff
path: root/libdwfl
diff options
context:
space:
mode:
authorJan Kratochvil <jan.kratochvil@redhat.com>2013-12-15 18:56:17 +0100
committerJan Kratochvil <jan.kratochvil@redhat.com>2013-12-15 18:56:17 +0100
commit5cbf42aaf47195e2c41171786371d55b253a7667 (patch)
tree8def24d1108f287998fadbdc6348a925ce3d72ec /libdwfl
parent63572f42b04e1c3b752b113810ec642121c8090e (diff)
downloadelfutils-5cbf42aaf47195e2c41171786371d55b253a7667.tar.gz
unwinder: ppc and ppc64
Signed-off-by: Jan Kratochvil <jan.kratochvil@redhat.com>
Diffstat (limited to 'libdwfl')
-rw-r--r--libdwfl/ChangeLog10
-rw-r--r--libdwfl/frame_unwind.c4
-rw-r--r--libdwfl/linux-core-attach.c26
-rw-r--r--libdwfl/linux-pid-attach.c8
4 files changed, 48 insertions, 0 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 7e87e173..ff38108e 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,13 @@
+2013-12-15 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ unwinder: ppc and ppc64
+ * frame_unwind.c (__libdwfl_frame_reg_get, __libdwfl_frame_reg_set):
+ Call ebl_dwarf_to_regno.
+ * linux-core-attach.c (core_set_initial_registers): Implement
+ pc_register support.
+ * linux-pid-attach.c (pid_thread_state_registers_cb): Implement
+ FIRSTREG -1.
+
2013-11-30 Jan Kratochvil <jan.kratochvil@redhat.com>
Introduce process_attach_error.
diff --git a/libdwfl/frame_unwind.c b/libdwfl/frame_unwind.c
index 1aed8cb5..2973f955 100644
--- a/libdwfl/frame_unwind.c
+++ b/libdwfl/frame_unwind.c
@@ -52,6 +52,8 @@ internal_function
__libdwfl_frame_reg_get (Dwfl_Frame *state, unsigned regno, Dwarf_Addr *val)
{
Ebl *ebl = state->thread->process->ebl;
+ if (! ebl_dwarf_to_regno (ebl, &regno))
+ return false;
if (regno >= ebl_frame_nregs (ebl))
return false;
if ((state->regs_set[regno / sizeof (*state->regs_set) / 8]
@@ -67,6 +69,8 @@ internal_function
__libdwfl_frame_reg_set (Dwfl_Frame *state, unsigned regno, Dwarf_Addr val)
{
Ebl *ebl = state->thread->process->ebl;
+ if (! ebl_dwarf_to_regno (ebl, &regno))
+ return false;
if (regno >= ebl_frame_nregs (ebl))
return false;
/* For example i386 user_regs_struct has signed fields. */
diff --git a/libdwfl/linux-core-attach.c b/libdwfl/linux-core-attach.c
index 237c6f36..11379ba1 100644
--- a/libdwfl/linux-core-attach.c
+++ b/libdwfl/linux-core-attach.c
@@ -198,6 +198,32 @@ core_set_initial_registers (Dwfl_Thread *thread, void *thread_arg_voidp)
}
/* core_next_thread already found this TID there. */
assert (tid == INTUSE(dwfl_thread_tid) (thread));
+ for (item = items; item < items + nitems; item++)
+ if (item->pc_register)
+ break;
+ if (item < items + nitems)
+ {
+ Dwarf_Word pc;
+ switch (gelf_getclass (core) == ELFCLASS32 ? 32 : 64)
+ {
+ case 32:;
+ uint32_t val32 = *(const uint32_t *) (desc + item->offset);
+ val32 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB
+ ? be32toh (val32) : le32toh (val32));
+ /* Do a host width conversion. */
+ pc = val32;
+ break;
+ case 64:;
+ uint64_t val64 = *(const uint64_t *) (desc + item->offset);
+ val64 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB
+ ? be64toh (val64) : le64toh (val64));
+ pc = val64;
+ break;
+ default:
+ abort ();
+ }
+ INTUSE(dwfl_thread_state_register_pc) (thread, pc);
+ }
desc += regs_offset;
for (size_t regloci = 0; regloci < nregloc; regloci++)
{
diff --git a/libdwfl/linux-pid-attach.c b/libdwfl/linux-pid-attach.c
index e4eb6212..45a0732d 100644
--- a/libdwfl/linux-pid-attach.c
+++ b/libdwfl/linux-pid-attach.c
@@ -205,6 +205,14 @@ pid_thread_state_registers_cb (int firstreg, unsigned nregs,
const Dwarf_Word *regs, void *arg)
{
Dwfl_Thread *thread = (Dwfl_Thread *) arg;
+ if (firstreg < 0)
+ {
+ assert (firstreg == -1);
+ assert (nregs == 1);
+ INTUSE(dwfl_thread_state_register_pc) (thread, *regs);
+ return true;
+ }
+ assert (nregs > 0);
return INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs);
}