diff options
author | Jan Kratochvil <jan.kratochvil@redhat.com> | 2013-12-15 18:56:17 +0100 |
---|---|---|
committer | Jan Kratochvil <jan.kratochvil@redhat.com> | 2013-12-15 18:56:17 +0100 |
commit | 5cbf42aaf47195e2c41171786371d55b253a7667 (patch) | |
tree | 8def24d1108f287998fadbdc6348a925ce3d72ec /libdwfl | |
parent | 63572f42b04e1c3b752b113810ec642121c8090e (diff) | |
download | elfutils-5cbf42aaf47195e2c41171786371d55b253a7667.tar.gz |
unwinder: ppc and ppc64
Signed-off-by: Jan Kratochvil <jan.kratochvil@redhat.com>
Diffstat (limited to 'libdwfl')
-rw-r--r-- | libdwfl/ChangeLog | 10 | ||||
-rw-r--r-- | libdwfl/frame_unwind.c | 4 | ||||
-rw-r--r-- | libdwfl/linux-core-attach.c | 26 | ||||
-rw-r--r-- | libdwfl/linux-pid-attach.c | 8 |
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, ®no)) + 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, ®no)) + 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); } |