diff options
| author | Jan Kratochvil <[email protected]> | 2013-12-17 18:49:54 +0100 |
|---|---|---|
| committer | Jan Kratochvil <[email protected]> | 2013-12-18 13:01:05 +0100 |
| commit | c6a41483f2986d5542c554981348f75b815ef9b1 (patch) | |
| tree | afbd87ebb664bfe07a7d03790920fdbbc3be9e38 /libebl | |
| parent | c8c610bcfb9e90ab2d43c019da7eaade7017baec (diff) | |
unwinder: s390 and s390x
Signed-off-by: Jan Kratochvil <[email protected]>
Diffstat (limited to 'libebl')
| -rw-r--r-- | libebl/ChangeLog | 12 | ||||
| -rw-r--r-- | libebl/Makefile.am | 3 | ||||
| -rw-r--r-- | libebl/ebl-hooks.h | 17 | ||||
| -rw-r--r-- | libebl/eblnormalizepc.c | 40 | ||||
| -rw-r--r-- | libebl/eblunwind.c | 43 | ||||
| -rw-r--r-- | libebl/libebl.h | 29 |
6 files changed, 143 insertions, 1 deletions
diff --git a/libebl/ChangeLog b/libebl/ChangeLog index a27de82d..f1aa242b 100644 --- a/libebl/ChangeLog +++ b/libebl/ChangeLog @@ -1,3 +1,15 @@ +2013-12-18 Jan Kratochvil <[email protected]> + + unwinder: s390 and s390x + * Makefile.am (gen_SOURCES): Add eblnormalizepc.c and eblunwind.c. + * ebl-hooks.h (normalize_pc, unwind): New. + * eblnormalizepc.c: New file. + * eblunwind.c: New file. + * libebl.h (Ebl_Register_Location): Add field pc_register. + (ebl_normalize_pc): New declaration. + (ebl_tid_registers_get_t, ebl_pid_memory_read_t): New definitions. + (ebl_unwind): New declaration. + 2013-12-15 Jan Kratochvil <[email protected]> unwinder: ppc and ppc64 diff --git a/libebl/Makefile.am b/libebl/Makefile.am index 2f3b7308..fc4f1b6f 100644 --- a/libebl/Makefile.am +++ b/libebl/Makefile.am @@ -54,7 +54,8 @@ 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 ebldwarftoregno.c + eblstother.c eblinitreg.c ebldwarftoregno.c eblnormalizepc.c \ + eblunwind.c libebl_a_SOURCES = $(gen_SOURCES) diff --git a/libebl/ebl-hooks.h b/libebl/ebl-hooks.h index f721bc49..22438953 100644 --- a/libebl/ebl-hooks.h +++ b/libebl/ebl-hooks.h @@ -166,5 +166,22 @@ bool EBLHOOK(set_initial_registers_tid) (pid_t tid, Dwarf_Frame->REGS indexing. */ bool EBLHOOK(dwarf_to_regno) (Ebl *ebl, unsigned *regno); +/* Optionally modify *PC as fetched from inferior data into valid PC + instruction pointer. */ +void EBLHOOK(normalize_pc) (Ebl *ebl, Dwarf_Addr *pc); + +/* Get previous frame state for an existing frame state. Method is called only + if unwinder could not find CFI for current PC. PC is for the + existing frame. SETFUNC sets register in the previous frame. GETFUNC gets + register from the existing frame. Note that GETFUNC vs. SETFUNC act on + a disjunct set of registers. READFUNC reads memory. ARG has to be passed + for SETFUNC, GETFUNC and READFUNC. *SIGNAL_FRAMEP is initialized to false, + it can be set to true if existing frame is a signal frame. SIGNAL_FRAMEP is + never NULL. */ +bool EBLHOOK(unwind) (Ebl *ebl, Dwarf_Addr pc, ebl_tid_registers_t *setfunc, + ebl_tid_registers_get_t *getfunc, + ebl_pid_memory_read_t *readfunc, void *arg, + bool *signal_framep); + /* Destructor for ELF backend handle. */ void EBLHOOK(destr) (struct ebl *); diff --git a/libebl/eblnormalizepc.c b/libebl/eblnormalizepc.c new file mode 100644 index 00000000..a5fea77e --- /dev/null +++ b/libebl/eblnormalizepc.c @@ -0,0 +1,40 @@ +/* Modify PC as fetched from inferior data into valid PC. + 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> + +void +ebl_normalize_pc (Ebl *ebl, Dwarf_Addr *pc) +{ + if (ebl != NULL && ebl->normalize_pc != NULL) + ebl->normalize_pc (ebl, pc); +} diff --git a/libebl/eblunwind.c b/libebl/eblunwind.c new file mode 100644 index 00000000..1251c1b5 --- /dev/null +++ b/libebl/eblunwind.c @@ -0,0 +1,43 @@ +/* Get previous frame state for an existing frame state. + 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_unwind (Ebl *ebl, Dwarf_Addr pc, ebl_tid_registers_t *setfunc, + ebl_tid_registers_get_t *getfunc, ebl_pid_memory_read_t *readfunc, + void *arg, bool *signal_framep) +{ + if (ebl == NULL || ebl->unwind == NULL) + return false; + return ebl->unwind (ebl, pc, setfunc, getfunc, readfunc, arg, signal_framep); +} diff --git a/libebl/libebl.h b/libebl/libebl.h index 7080b4a5..84c2f4cd 100644 --- a/libebl/libebl.h +++ b/libebl/libebl.h @@ -356,6 +356,7 @@ typedef struct uint8_t bits; /* Bits of data for one register. */ uint8_t pad; /* Bytes of padding after register's data. */ Dwarf_Half count; /* Consecutive register numbers here. */ + bool pc_register; } Ebl_Register_Location; /* Non-register data items in core notes. */ @@ -410,6 +411,34 @@ extern size_t ebl_frame_nregs (Ebl *ebl) extern bool ebl_dwarf_to_regno (Ebl *ebl, unsigned *regno) __nonnull_attribute__ (1, 2); +/* Modify PC as fetched from inferior data into valid PC. */ +extern void ebl_normalize_pc (Ebl *ebl, Dwarf_Addr *pc) + __nonnull_attribute__ (1, 2); + +/* Callback type for ebl_unwind's parameter getfunc. */ +typedef bool (ebl_tid_registers_get_t) (int firstreg, unsigned nregs, + Dwarf_Word *regs, void *arg) + __nonnull_attribute__ (3); + +/* Callback type for ebl_unwind's parameter readfunc. */ +typedef bool (ebl_pid_memory_read_t) (Dwarf_Addr addr, Dwarf_Word *data, + void *arg) + __nonnull_attribute__ (3); + +/* Get previous frame state for an existing frame state. Method is called only + if unwinder could not find CFI for current PC. PC is for the + existing frame. SETFUNC sets register in the previous frame. GETFUNC gets + register from the existing frame. Note that GETFUNC vs. SETFUNC act on + a disjunct set of registers. READFUNC reads memory. ARG has to be passed + for SETFUNC, GETFUNC and READFUNC. *SIGNAL_FRAMEP is initialized to false, + it can be set to true if existing frame is a signal frame. SIGNAL_FRAMEP is + never NULL. */ +extern bool ebl_unwind (Ebl *ebl, Dwarf_Addr pc, ebl_tid_registers_t *setfunc, + ebl_tid_registers_get_t *getfunc, + ebl_pid_memory_read_t *readfunc, void *arg, + bool *signal_framep) + __nonnull_attribute__ (1, 3, 4, 5, 7); + #ifdef __cplusplus } #endif |
