[patchv2 3/4] unwinder: ppc and ppc64
Jan Kratochvil
jan.kratochvil at redhat.com
Tue Dec 3 13:09:21 UTC 2013
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 at 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 at 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 at 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 at 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 at 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 at 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
More information about the elfutils-devel
mailing list