Hi Mark, jankratochvil/ynonx86base-attach-firstreg..jankratochvil/ynonx86base-attach-firstreg-ppc
Not a single commit, it has dependency on various pending patches. Therefore also not a git format-patch attachment. I can fix it up after approval of: jankratochvil/ppc64bidir jankratochvil/unwindx86 (=the testcases) On Mon, 18 Nov 2013 22:40:18 +0100, Mark Wielaard wrote: > Please do add a short description on why the extensions were needed in > this case to the commit message (or in the intro of an email). It really > makes things easier to review and might be useful for people looking > back on this code/commit later. OK, sorry. > Given the "interesting" DWARF register numbering on ppc, I see why we > want a dwarf_to_regno () to flatten things out. The firstreg -1 > indicating PC seems reasonable, if the architecture doesn't define a > PC/return address DWARF register number. Yes. > I had some trouble > understanding the core_pc_offset one at first though. It is gone now. > > --- a/backends/ppc64_init.c > > +++ b/backends/ppc64_init.c > > @@ -68,6 +68,11 @@ 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; > > + eh->core_pc_offset = 0x170; > > + HOOK (eh, set_initial_registers_tid); > > + HOOK (eh, dwarf_to_regno); > > OK, but the 0x170 magic number really should have a comment where it was > specified. It is gone now. > OK, but again do add a comment for the core_pc_offset magic value. Gone now. > > +bool > > +ppc_dwarf_to_regno (Ebl *ebl __attribute__ ((unused)), unsigned *regno) > > +{ > > + switch (*regno) > > + { > > + case 108: > > + *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"))); > > OK. The abort () really means unreachable here. Yes. > > + /* PTRACE_GETREGS is EIO on kernel-2.6.18-308.el5.ppc64. */ > > You could try it anyway as optimization and fallback on the iteration > over PTRACE_PEEKUSER if it fails. But if you feel that is just a > micro-optimization don't. The comment shows we could do it later if we > really care. It could be useful but I find it OK to add only later. > > + if (! setfunc (65, 1, dwarf_regs, arg)) // or 108 > > + return false; > > This might need an extra comment. If I remember right 108 is the > official DWARF register number, but GCC always produces 65? I do not know what is the real reason. I tried to read some docs but 65 vs. 108 seems to me just as a bug/mess. I can add // LR uses both 65 and 108 numbers, there is no consistency for it. > > > + /* 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__ */ > > +} > > Nitpick. You could probably use &user_regs.r.link and &user_regs.r.nip > instead of reusing dwarf_regs[0]. Though maybe the compiler will > complain about that. But again a micro optimization that is probably not > worth it. Yes, I do not find it somehow clean to mix types when passing a pointer. > > + size_t core_pc_offset = ebl_core_pc_offset (core_arg->ebl); > > + if (core_pc_offset) > > + { > > + Dwarf_Word pc; > > + switch (gelf_getclass (core) == ELFCLASS32 ? 32 : 64) > > + { > > + case 32:; > > + uint32_t val32 = *(const uint32_t *) (desc + core_pc_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 + core_pc_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); > > + } > > return true; > > } > > hmmm. I think I now understand the core_pc_offset. > It is the offset into the PRSTATUS note where to find the register that > represents the pc. But you reparse that location here instead of using > Ebl_Register_Location which you have just iterated through just above. > > Why don't you use the loop above and check the regloc->offset there > before calling either dwfl_thread_state_registers or > dwfl_thread_state_register_pc on the value? One cannot use regloc, backends/ppc_corenote.c does not list PC in Ebl_Register_Location prstatus_regs[]. But you are right it is listed in PRSTATUS_REGSET_ITEMS so I use it now. And the whole ebl->core_pc_offset could be removed. > > --- a/libdwfl/linux-pid-attach.c > > +++ b/libdwfl/linux-pid-attach.c > > @@ -202,6 +202,17 @@ 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 > 0); > > + INTUSE(dwfl_thread_state_register_pc) (thread, *regs); > > + firstreg++; > > + nregs--; > > + regs++; > > + } > > + if (! nregs) > > + return true; > > return INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, > > regs); > > } > > OK. Though in practice I assume it will always be firstreg == -1 && > nregs == 1. Which would result it slightly simpler code. OK, simplified the code. > > --- a/libebl/libebl.h > > +++ b/libebl/libebl.h > > @@ -383,7 +383,8 @@ 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). */ > > typedef bool (ebl_tid_registers_t) (int firstreg, unsigned nregs, > > const Dwarf_Word *regs, void *arg) > > OK. I would suggest to just say that if firstreg == -1 then nregs == 1. > To simplify the code. If that makes sense. Done. > > +/* PC register location stored in core file. It is a number of bytes from > > + descriptor of NT_PRSTATUS core note. It is 0 if unused. */ > > +extern size_t ebl_core_pc_offset (Ebl *ebl) > > + __nonnull_attribute__ (1); > > It really should mention that the offset is one of the valid offsets of > the Ebl_Register_Location returned by ebl_core_note. > > Or better. It should be named ebl_core_pc_regno. If not zero, it is the > Ebl_Register_Location regno that (double) as initial pc value. It is gone now. > > --- a/libebl/libeblP.h > > +++ b/libebl/libeblP.h > > @@ -64,6 +64,10 @@ struct ebl > > Ebl architecture can unwind iff FRAME_NREGS > 0. */ > > size_t frame_nregs; > > > > + /* PC register location stored in core file. It is a number of bytes > > from > > + descriptor of NT_PRSTATUS core note. It is 0 if unused. */ > > + size_t core_pc_offset; > > See above. Would it make sense to rename/define it as core_pc_regno? It is gone now. > > --- a/tests/run-backtrace.sh > > +++ b/tests/run-backtrace.sh > > @@ -91,4 +91,12 @@ for child in backtrace-child{,-biarch}; do > > > > done > > > > +for arch in ppc ppc64; do > > + testfiles backtrace.$arch.{exec,core} > > + tempfiles backtrace.$arch.{bt,err} > > + echo ./backtrace ./backtrace.$arch.{exec,core} > > + testrun ${abs_builddir}/backtrace ./backtrace.$arch.{exec,core} > > 1>backtrace.$arch.bt 2>backtrace.$arch.err || true > > + check_all backtrace.$arch.{bt,err} backtrace.$arch.core > > +done > > Do see the comments I made about the tests in an earlier email. It is very different now. Thanks, Jan unwinder: ppc and ppc64 backends/ 2013-11-10 Jan Kratochvil <jan.kratoch...@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.kratoch...@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.kratoch...@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.kratoch...@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.kratoch...@redhat.com>
diff --git a/backends/Makefile.am b/backends/Makefile.am index 0e00329..653b56e 100644 --- a/backends/Makefile.am +++ b/backends/Makefile.am @@ -88,13 +88,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..ae3f138 --- /dev/null +++ b/backends/ppc_initreg.c @@ -0,0 +1,112 @@ +/* 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: + *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; + 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__ */ +} + +__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 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); + } 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 2ad18ec..f2b3857 100644 --- a/libebl/ebl-hooks.h +++ b/libebl/ebl-hooks.h @@ -172,5 +172,9 @@ void EBLHOOK(init_symbols) (Ebl *ebl, size_t syments, int first_global, 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 2446cc9..7fe5456 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); @@ -428,6 +431,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 10fdc21..50a1f94 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -109,7 +109,8 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \ 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 endif @@ -246,7 +247,10 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \ run-backtrace-native-core.sh run-backtrace-native-core-biarch.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 + backtrace.x86_64.core.bz2 backtrace.x86_64.exec.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/backtrace.ppc.core.bz2 b/tests/backtrace.ppc.core.bz2 new file mode 100644 index 0000000..2dca8f1 Binary files /dev/null and b/tests/backtrace.ppc.core.bz2 differ diff --git a/tests/backtrace.ppc.exec.bz2 b/tests/backtrace.ppc.exec.bz2 new file mode 100644 index 0000000..15070a9 Binary files /dev/null and b/tests/backtrace.ppc.exec.bz2 differ diff --git a/tests/backtrace.ppc64.core.bz2 b/tests/backtrace.ppc64.core.bz2 new file mode 100644 index 0000000..a07aa61 Binary files /dev/null and b/tests/backtrace.ppc64.core.bz2 differ diff --git a/tests/backtrace.ppc64.exec.bz2 b/tests/backtrace.ppc64.exec.bz2 new file mode 100644 index 0000000..21a7e0d Binary files /dev/null and b/tests/backtrace.ppc64.exec.bz2 differ 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