Hi Mark,
jankratochvil/ppc64bidir-unwindppc
(a new name of the branch, single-commit now)
(the patch below does not contain the binary blobs)
The patch seems ready to me, it just waits for the review of:
jankratochvil/ppc64bidir
On Fri, 29 Nov 2013 11:32:08 +0100, Mark Wielaard wrote:
Aha, yes of course, "nip" isn't associated with any
regno. I think I
would have used the "nip" name as marker or maybe introduced a
"fake/special" regno for it. Instead of adding a new pc_register boolean
field to every register to save a little space, but I guess this works
too and there aren't so many registers that it really matters.
It is ugly to add named-exceptions in the code.
There is now such ugly "pid" checking in libdwfl/linux-core-attach.c from the
checked-in unwinder patch. It will be fixed up later (related to s390).
> +bool
> +ppc_dwarf_to_regno (Ebl *ebl __attribute__ ((unused)), unsigned *regno)
> +{
> + switch (*regno)
> + {
> + case 108:
// LR uses both 65 and 108 numbers, there is no consistency for it.
> + *regno = 65;
> + return true;
> + case 0 ... 107:
> + case 109 ... (114 - 1) -1:
> + return true;
> + case 1200 ... 1231:
> + *regno = *regno - 1200 + (114 - 1);
> + return true;
> + default:
> + return false;
> + }
> + abort ();
> +}
OK. I would also have added a comment here about the 108/65 regno mess.
Done.
> +bool
> +ppc_set_initial_registers_tid (pid_t tid __attribute__ ((unused)),
> + ebl_tid_registers_t *setfunc __attribute__ ((unused)),
> + void *arg __attribute__ ((unused)))
> +{
> +#ifndef __powerpc__
> + return false;
> +#else /* __powerpc__ */
> + union
> + {
> + struct pt_regs r;
> + long l[sizeof (struct pt_regs) / sizeof (long)];
> + }
> + user_regs;
> + eu_static_assert (sizeof (struct pt_regs) % sizeof (long) == 0);
> + /* PTRACE_GETREGS is EIO on kernel-2.6.18-308.el5.ppc64. */
> + errno = 0;
> + for (unsigned regno = 0; regno < sizeof (user_regs) / sizeof (long);
> + regno++)
> + {
> + user_regs.l[regno] = ptrace (PTRACE_PEEKUSER, tid,
> + (void *) (uintptr_t) (regno
> + * sizeof (long)),
> + NULL);
> + if (errno != 0)
> + return false;
> + }
> + const size_t gprs = sizeof (user_regs.r.gpr) / sizeof (*user_regs.r.gpr);
> + Dwarf_Word dwarf_regs[gprs];
> + for (unsigned gpr = 0; gpr < gprs; gpr++)
> + dwarf_regs[gpr] = user_regs.r.gpr[gpr];
> + if (! setfunc (0, gprs, dwarf_regs, arg))
> + return false;
> + dwarf_regs[0] = user_regs.r.link;
// LR uses both 65 and 108 numbers, there is no consistency for it.
if (! setfunc (65, 1, dwarf_regs, arg))
> + if (! setfunc (65, 1, dwarf_regs, arg)) // or 108
> + return false;
> + /* Registers like msr, ctr, xer, dar, dsisr etc. are probably irrelevant
> + for CFI. */
> + dwarf_regs[0] = user_regs.r.nip;
> + return setfunc (-1, 1, dwarf_regs, arg);
> +#endif /* __powerpc__ */
> +}
OK. Maybe extend to comment for 65/108 to refer to ppc_dwarf_to_regno.
Done.
> diff --git a/libdwfl/linux-core-attach.c
b/libdwfl/linux-core-attach.c
> index b2d703f..2853c3c 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);
> + }
OK, but just below this code is another loop over the items/regs which
contains some FIXMEs that you seem to have fixed now. Can't these loops
be combined? It currently seems to duplicate the value extraction code
and seems to depend on the order of notes/items. It would be better if
it was just one loop that only depended on the regno (and/or pc_register
flag or special PC name).
This new Ebl_Core_Item based code is unrelated to the Ebl_Register_Location
code below it. The Ebl_Core_Item code above sets PC register which has no
DWARF register number. The Ebl_Register_Location code below sets LR register
which has either 65 or 108 DWARF register number.
The Ebl_Register_Location hack there is ugly but it is unrelated to the code
above.
So I have left everything as is for now.
Thanks,
Jan
4516ce4755a598fc14ed62839d9160a27079b656 Mon Sep 17 00:00:00 2001
From: Jan Kratochvil <jan.kratochvil(a)redhat.com>
Date: Tue, 3 Dec 2013 14:06:47 +0100
Subject: [PATCH] unwinder: ppc and ppc64
backends/
2013-11-10 Jan Kratochvil <jan.kratochvil(a)redhat.com>
unwinder: ppc and ppc64
* Makefile.am (ppc_SRCS, ppc64_SRCS): Add ppc_initreg.c.
* ppc64_init.c (ppc64_init): Initialize also frame_nregs,
set_initial_registers_tid and dwarf_to_regno.
* ppc_corenote.c (PRSTATUS_REGSET_ITEMS) <nip>: Set PC_REGISTER.
* ppc_init.c (ppc64_init): Initialize also frame_nregs,
set_initial_registers_tid and dwarf_to_regno.
* ppc_initreg.c: New file.
libdwfl/
2013-11-10 Jan Kratochvil <jan.kratochvil(a)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.
libebl/
2013-11-10 Jan Kratochvil <jan.kratochvil(a)redhat.com>
unwinder: ppc and ppc64
* Makefile.am (gen_SOURCES): Add ebldwarftoregno.c.
* ebl-hooks.h (dwarf_to_regno): New.
* ebldwarftoregno.c: New file.
* libebl.h (Ebl_Core_Item): New field pc_register.
(ebl_tid_registers_t): Add FIRSTREG -1 to the comment.
(ebl_dwarf_to_regno): New.
tests/
2013-11-10 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* Makefile.am (TESTS): Add run-backtrace-core-ppc64.sh and
run-backtrace-core-ppc.sh.
(EXTRA_DIST): Add backtrace.ppc.core.bz2,
backtrace.ppc.exec.bz2, backtrace.ppc64.core.bz2,
backtrace.ppc64.exec.bz2, run-backtrace-core-ppc64.sh and
run-backtrace-core-ppc.sh.
* backtrace.ppc.core.bz2: New file.
* backtrace.ppc.exec.bz2: New file.
* backtrace.ppc64.core.bz2: New file.
* backtrace.ppc64.exec.bz2: New file.
* run-backtrace-core-ppc.sh: New file.
* run-backtrace-core-ppc64.sh: New file.
Signed-off-by: Jan Kratochvil <jan.kratochvil(a)redhat.com>
---
backends/Makefile.am | 4 +-
backends/ppc64_init.c | 4 ++
backends/ppc_corenote.c | 2 +-
backends/ppc_init.c | 4 ++
backends/ppc_initreg.c | 114 ++++++++++++++++++++++++++++++++++++++
libdwfl/frame_unwind.c | 4 ++
libdwfl/linux-core-attach.c | 26 +++++++++
libdwfl/linux-pid-attach.c | 8 +++
libebl/Makefile.am | 2 +-
libebl/ebl-hooks.h | 4 ++
libebl/ebldwarftoregno.c | 41 ++++++++++++++
libebl/libebl.h | 10 +++-
tests/Makefile.am | 8 ++-
tests/backtrace.ppc.core.bz2 | Bin 0 -> 46357 bytes
tests/backtrace.ppc.exec.bz2 | Bin 0 -> 352898 bytes
tests/backtrace.ppc64.core.bz2 | Bin 0 -> 53120 bytes
tests/backtrace.ppc64.exec.bz2 | Bin 0 -> 343483 bytes
tests/run-backtrace-core-ppc.sh | 20 +++++++
tests/run-backtrace-core-ppc64.sh | 20 +++++++
19 files changed, 264 insertions(+), 7 deletions(-)
create mode 100644 backends/ppc_initreg.c
create mode 100644 libebl/ebldwarftoregno.c
create mode 100644 tests/backtrace.ppc.core.bz2
create mode 100644 tests/backtrace.ppc.exec.bz2
create mode 100644 tests/backtrace.ppc64.core.bz2
create mode 100644 tests/backtrace.ppc64.exec.bz2
create mode 100755 tests/run-backtrace-core-ppc.sh
create mode 100755 tests/run-backtrace-core-ppc64.sh
diff --git a/backends/Makefile.am b/backends/Makefile.am
index 40460ae..9785e24 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -95,13 +95,13 @@ am_libebl_sparc_pic_a_OBJECTS = $(sparc_SRCS:.c=.os)
ppc_SRCS = ppc_init.c ppc_symbol.c ppc_retval.c ppc_regs.c \
ppc_corenote.c ppc_auxv.c ppc_attrs.c ppc_syscall.c \
- ppc_cfi.c
+ ppc_cfi.c ppc_initreg.c
libebl_ppc_pic_a_SOURCES = $(ppc_SRCS)
am_libebl_ppc_pic_a_OBJECTS = $(ppc_SRCS:.c=.os)
ppc64_SRCS = ppc64_init.c ppc64_symbol.c ppc64_retval.c \
ppc64_corenote.c ppc_regs.c ppc_auxv.c ppc_attrs.c ppc_syscall.c \
- ppc_cfi.c ppc64_get_symbol.c
+ ppc_cfi.c ppc64_get_symbol.c ppc_initreg.c
libebl_ppc64_pic_a_SOURCES = $(ppc64_SRCS)
am_libebl_ppc64_pic_a_OBJECTS = $(ppc64_SRCS:.c=.os)
diff --git a/backends/ppc64_init.c b/backends/ppc64_init.c
index 3ed882b..8fd4575 100644
--- a/backends/ppc64_init.c
+++ b/backends/ppc64_init.c
@@ -68,6 +68,10 @@ ppc64_init (elf, machine, eh, ehlen)
HOOK (eh, init_symbols);
HOOK (eh, get_symbol);
HOOK (eh, destr);
+ /* gcc/config/ #define DWARF_FRAME_REGISTERS. */
+ eh->frame_nregs = (114 - 1) + 32;
+ HOOK (eh, set_initial_registers_tid);
+ HOOK (eh, dwarf_to_regno);
return MODVERSION;
}
diff --git a/backends/ppc_corenote.c b/backends/ppc_corenote.c
index 707a395..9ac8871 100644
--- a/backends/ppc_corenote.c
+++ b/backends/ppc_corenote.c
@@ -123,7 +123,7 @@ static const Ebl_Register_Location spe_regs[] =
{ \
.name = "nip", .type = ELF_T_ADDR, .format = 'x', \
.offset = offsetof (struct EBLHOOK(prstatus), pr_reg[32]), \
- .group = "register" \
+ .group = "register", .pc_register = true \
}, \
{ \
.name = "orig_gpr3", .type = TYPE_LONG, .format = 'd', \
diff --git a/backends/ppc_init.c b/backends/ppc_init.c
index 004c601..ad92765 100644
--- a/backends/ppc_init.c
+++ b/backends/ppc_init.c
@@ -65,6 +65,10 @@ ppc_init (elf, machine, eh, ehlen)
HOOK (eh, auxv_info);
HOOK (eh, check_object_attribute);
HOOK (eh, abi_cfi);
+ /* gcc/config/ #define DWARF_FRAME_REGISTERS. */
+ eh->frame_nregs = (114 - 1) + 32;
+ HOOK (eh, set_initial_registers_tid);
+ HOOK (eh, dwarf_to_regno);
return MODVERSION;
}
diff --git a/backends/ppc_initreg.c b/backends/ppc_initreg.c
new file mode 100644
index 0000000..64f5379
--- /dev/null
+++ b/backends/ppc_initreg.c
@@ -0,0 +1,114 @@
+/* Fetch live process registers from TID.
+ Copyright (C) 2013 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <
http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "system.h"
+#include <stdlib.h>
+#ifdef __powerpc__
+# include <sys/user.h>
+# include <sys/ptrace.h>
+#endif
+
+#define BACKEND ppc_
+#include "libebl_CPU.h"
+
+bool
+ppc_dwarf_to_regno (Ebl *ebl __attribute__ ((unused)), unsigned *regno)
+{
+ switch (*regno)
+ {
+ case 108:
+ // LR uses both 65 and 108 numbers, there is no consistency for it.
+ *regno = 65;
+ return true;
+ case 0 ... 107:
+ case 109 ... (114 - 1) -1:
+ return true;
+ case 1200 ... 1231:
+ *regno = *regno - 1200 + (114 - 1);
+ return true;
+ default:
+ return false;
+ }
+ abort ();
+}
+
+__typeof (ppc_dwarf_to_regno)
+ ppc64_dwarf_to_regno
+ __attribute__ ((alias ("ppc_dwarf_to_regno")));
+
+bool
+ppc_set_initial_registers_tid (pid_t tid __attribute__ ((unused)),
+ ebl_tid_registers_t *setfunc __attribute__ ((unused)),
+ void *arg __attribute__ ((unused)))
+{
+#ifndef __powerpc__
+ return false;
+#else /* __powerpc__ */
+ union
+ {
+ struct pt_regs r;
+ long l[sizeof (struct pt_regs) / sizeof (long)];
+ }
+ user_regs;
+ eu_static_assert (sizeof (struct pt_regs) % sizeof (long) == 0);
+ /* PTRACE_GETREGS is EIO on kernel-2.6.18-308.el5.ppc64. */
+ errno = 0;
+ for (unsigned regno = 0; regno < sizeof (user_regs) / sizeof (long);
+ regno++)
+ {
+ user_regs.l[regno] = ptrace (PTRACE_PEEKUSER, tid,
+ (void *) (uintptr_t) (regno
+ * sizeof (long)),
+ NULL);
+ if (errno != 0)
+ return false;
+ }
+ const size_t gprs = sizeof (user_regs.r.gpr) / sizeof (*user_regs.r.gpr);
+ Dwarf_Word dwarf_regs[gprs];
+ for (unsigned gpr = 0; gpr < gprs; gpr++)
+ dwarf_regs[gpr] = user_regs.r.gpr[gpr];
+ if (! setfunc (0, gprs, dwarf_regs, arg))
+ return false;
+ dwarf_regs[0] = user_regs.r.link;
+ // LR uses both 65 and 108 numbers, there is no consistency for it.
+ if (! setfunc (65, 1, dwarf_regs, arg))
+ return false;
+ /* Registers like msr, ctr, xer, dar, dsisr etc. are probably irrelevant
+ for CFI. */
+ dwarf_regs[0] = user_regs.r.nip;
+ return setfunc (-1, 1, dwarf_regs, arg);
+#endif /* __powerpc__ */
+}
+
+__typeof (ppc_set_initial_registers_tid)
+ ppc64_set_initial_registers_tid
+ __attribute__ ((alias ("ppc_set_initial_registers_tid")));
diff --git a/libdwfl/frame_unwind.c b/libdwfl/frame_unwind.c
index 1aed8cb..2973f95 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 237c6f3..11379ba 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 e4eb621..45a0732 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);
}
diff --git a/libebl/Makefile.am b/libebl/Makefile.am
index 1fb3da3..6c03af8 100644
--- a/libebl/Makefile.am
+++ b/libebl/Makefile.am
@@ -54,7 +54,7 @@ gen_SOURCES = eblopenbackend.c eblclosebackend.c eblstrtab.c \
eblreginfo.c eblnonerelocp.c eblrelativerelocp.c \
eblsysvhashentrysize.c eblauxvinfo.c eblcheckobjattr.c \
ebl_check_special_section.c ebl_syscall_abi.c eblabicfi.c \
- eblstother.c eblinitreg.c eblgetsymbol.c
+ eblstother.c eblinitreg.c eblgetsymbol.c ebldwarftoregno.c
libebl_a_SOURCES = $(gen_SOURCES)
diff --git a/libebl/ebl-hooks.h b/libebl/ebl-hooks.h
index 7204514..fdb97f7 100644
--- a/libebl/ebl-hooks.h
+++ b/libebl/ebl-hooks.h
@@ -171,5 +171,9 @@ bool EBLHOOK(init_symbols) (Ebl *ebl, size_t syments, GElf_Addr
main_bias,
const char *EBLHOOK(get_symbol) (Ebl *ebl, size_t ndx, GElf_Sym *symp,
GElf_Word *shndxp);
+/* Convert *REGNO as is in DWARF to a lower range suitable for
+ Dwarf_Frame->REGS indexing. */
+bool EBLHOOK(dwarf_to_regno) (Ebl *ebl, unsigned *regno);
+
/* Destructor for ELF backend handle. */
void EBLHOOK(destr) (struct ebl *);
diff --git a/libebl/ebldwarftoregno.c b/libebl/ebldwarftoregno.c
new file mode 100644
index 0000000..8fb8540
--- /dev/null
+++ b/libebl/ebldwarftoregno.c
@@ -0,0 +1,41 @@
+/* Convert *REGNO as is in DWARF to a lower range.
+ Copyright (C) 2013 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <
http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+bool
+ebl_dwarf_to_regno (Ebl *ebl, unsigned *regno)
+{
+ if (ebl == NULL)
+ return false;
+ return ebl->dwarf_to_regno == NULL ? true : ebl->dwarf_to_regno (ebl, regno);
+}
diff --git a/libebl/libebl.h b/libebl/libebl.h
index d817153..e561ff3 100644
--- a/libebl/libebl.h
+++ b/libebl/libebl.h
@@ -368,6 +368,7 @@ typedef struct
Elf_Type type;
char format;
bool thread_identifier;
+ bool pc_register;
} Ebl_Core_Item;
/* Describe the format of a core file note with the given header and NAME.
@@ -383,7 +384,9 @@ extern int ebl_auxv_info (Ebl *ebl, GElf_Xword a_type,
const char **name, const char **format)
__nonnull_attribute__ (1, 3, 4);
-/* Callback type for ebl_set_initial_registers_tid. */
+/* Callback type for ebl_set_initial_registers_tid.
+ Register -1 is mapped to PC (if arch PC has no DWARF number).
+ If FIRSTREG is -1 then NREGS has to be 1. */
typedef bool (ebl_tid_registers_t) (int firstreg, unsigned nregs,
const Dwarf_Word *regs, void *arg)
__nonnull_attribute__ (3);
@@ -430,6 +433,11 @@ extern const char *ebl_get_symbol (Ebl *ebl, size_t ndx, GElf_Sym
*symp,
GElf_Word *shndxp)
__nonnull_attribute__ (1, 3);
+/* Convert *REGNO as is in DWARF to a lower range suitable for
+ Dwarf_Frame->REGS indexing. */
+extern bool ebl_dwarf_to_regno (Ebl *ebl, unsigned *regno)
+ __nonnull_attribute__ (1, 2);
+
#ifdef __cplusplus
}
#endif
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f57333c..923d68f 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -106,7 +106,8 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \
run-backtrace-native.sh run-backtrace-data.sh run-backtrace-dwarf.sh \
run-backtrace-native-biarch.sh run-backtrace-native-core.sh \
run-backtrace-native-core-biarch.sh run-backtrace-core-x86_64.sh \
- run-backtrace-core-i386.sh
+ run-backtrace-core-i386.sh run-backtrace-core-ppc64.sh \
+ run-backtrace-core-ppc.sh
if !BIARCH
export ELFUTILS_DISABLE_BIARCH = 1
@@ -246,7 +247,10 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
run-backtrace-core-x86_64.sh run-backtrace-core-i386.sh \
backtrace-subr.sh backtrace.i386.core.bz2 backtrace.i386.exec.bz2 \
backtrace.x86_64.core.bz2 backtrace.x86_64.exec.bz2 \
- testfile66.bz2 testfile66.core.bz2
+ testfile66.bz2 testfile66.core.bz2 \
+ backtrace.ppc64.core.bz2 backtrace.ppc64.exec.bz2 \
+ backtrace.ppc.core.bz2 backtrace.ppc.exec.bz2 \
+ run-backtrace-core-ppc64.sh run-backtrace-core-ppc.sh
if USE_VALGRIND
valgrind_cmd='valgrind -q --trace-children=yes --error-exitcode=1
--run-libc-freeres=no'
diff --git a/tests/run-backtrace-core-ppc.sh b/tests/run-backtrace-core-ppc.sh
new file mode 100755
index 0000000..65c9279
--- /dev/null
+++ b/tests/run-backtrace-core-ppc.sh
@@ -0,0 +1,20 @@
+#! /bin/bash
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <
http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+check_core ppc
diff --git a/tests/run-backtrace-core-ppc64.sh b/tests/run-backtrace-core-ppc64.sh
new file mode 100755
index 0000000..aaf186e
--- /dev/null
+++ b/tests/run-backtrace-core-ppc64.sh
@@ -0,0 +1,20 @@
+#! /bin/bash
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <
http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+check_core ppc64
--
1.8.3.1