Index: libunwind/include/libunwind-ppc32.h =================================================================== --- /dev/null +++ libunwind/include/libunwind-ppc32.h @@ -0,0 +1,226 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + Will be replaced when libunwind is ready on ppc64 platform. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef LIBUNWIND_H +#define LIBUNWIND_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include +#include + +#define UNW_TARGET ppc32 +#define UNW_TARGET_PPC32 1 + +#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ + +/* + * This needs to be big enough to accommodate "struct cursor", while + * leaving some slack for future expansion. Changing this value will + * require recompiling all users of this library. Stack allocation is + * relatively cheap and unwind-state copying is relatively rare, so we want + * to err on making it rather too big than too small. + * + * To simplify this whole process, we are at least initially taking the + * tack that UNW_PPC32_* map straight across to the .eh_frame column register + * numbers. These register numbers come from gcc's source in + * gcc/config/rs6000/rs6000.h + * + * UNW_TDEP_CURSOR_LEN is in terms of unw_word_t size. Since we have 115 + * elements in the loc array, each sized 2 * unw_word_t, plus the rest of + * the cursor struct, this puts us at about 2 * 115 + 40 = 270. Let's + * round that up to 280. + */ + +#define UNW_TDEP_CURSOR_LEN 280 + +#if __WORDSIZE==32 +typedef uint32_t unw_word_t; +typedef int32_t unw_sword_t; +#else +typedef uint64_t unw_word_t; +typedef int64_t unw_sword_t; +#endif + +typedef long double unw_tdep_fpreg_t; + +typedef enum + { + UNW_PPC32_R0, + UNW_PPC32_R1, /* called STACK_POINTER in gcc */ + UNW_PPC32_R2, + UNW_PPC32_R3, + UNW_PPC32_R4, + UNW_PPC32_R5, + UNW_PPC32_R6, + UNW_PPC32_R7, + UNW_PPC32_R8, + UNW_PPC32_R9, + UNW_PPC32_R10, + UNW_PPC32_R11, /* called STATIC_CHAIN in gcc */ + UNW_PPC32_R12, + UNW_PPC32_R13, + UNW_PPC32_R14, + UNW_PPC32_R15, + UNW_PPC32_R16, + UNW_PPC32_R17, + UNW_PPC32_R18, + UNW_PPC32_R19, + UNW_PPC32_R20, + UNW_PPC32_R21, + UNW_PPC32_R22, + UNW_PPC32_R23, + UNW_PPC32_R24, + UNW_PPC32_R25, + UNW_PPC32_R26, + UNW_PPC32_R27, + UNW_PPC32_R28, + UNW_PPC32_R29, + UNW_PPC32_R30, + UNW_PPC32_R31, /* called HARD_FRAME_POINTER in gcc */ + + UNW_PPC32_F0 = 32, + UNW_PPC32_F1, + UNW_PPC32_F2, + UNW_PPC32_F3, + UNW_PPC32_F4, + UNW_PPC32_F5, + UNW_PPC32_F6, + UNW_PPC32_F7, + UNW_PPC32_F8, + UNW_PPC32_F9, + UNW_PPC32_F10, + UNW_PPC32_F11, + UNW_PPC32_F12, + UNW_PPC32_F13, + UNW_PPC32_F14, + UNW_PPC32_F15, + UNW_PPC32_F16, + UNW_PPC32_F17, + UNW_PPC32_F18, + UNW_PPC32_F19, + UNW_PPC32_F20, + UNW_PPC32_F21, + UNW_PPC32_F22, + UNW_PPC32_F23, + UNW_PPC32_F24, + UNW_PPC32_F25, + UNW_PPC32_F26, + UNW_PPC32_F27, + UNW_PPC32_F28, + UNW_PPC32_F29, + UNW_PPC32_F30, + UNW_PPC32_F31, + +/* Note that there doesn't appear to be an .eh_frame register column + for the FPSCR register. I don't know why this is. Since .eh_frame + info is what this implementation uses for unwinding, we have no way + to unwind this register, and so we will not expose an FPSCR register + number in the libunwind API. + */ + + UNW_PPC32_LR = 65, + UNW_PPC32_CTR = 66, + UNW_PPC32_ARG_POINTER = 67, + + UNW_PPC32_CR0 = 68, + UNW_PPC32_CR1, + UNW_PPC32_CR2, + UNW_PPC32_CR3, + UNW_PPC32_CR4, + + /* CR5 .. CR7 are currently unused */ + UNW_PPC32_CR5, + UNW_PPC32_CR6, + UNW_PPC32_CR7, + + UNW_PPC32_XER = 76, + + UNW_PPC32_VRSAVE = 109, + UNW_PPC32_VSCR = 110, + UNW_PPC32_SPE_ACC = 111, + UNW_PPC32_SPEFSCR = 112, + + /* frame info (read-only) */ + UNW_PPC32_FRAME_POINTER, + UNW_PPC32_NIP, + + + UNW_TDEP_LAST_REG = UNW_PPC32_NIP, + + UNW_TDEP_IP = UNW_PPC32_NIP, + UNW_TDEP_SP = UNW_PPC32_R1, + UNW_TDEP_EH = UNW_PPC32_R12 + } +ppc32_regnum_t; + +/* + * According to David Edelsohn, GNU gcc uses R3, R4, R5, and maybe R6 for + * passing parameters to exception handlers. + */ + +#define UNW_TDEP_NUM_EH_REGS 4 + +typedef struct unw_tdep_save_loc + { + /* Additional target-dependent info on a save location. */ + } +unw_tdep_save_loc_t; + +/* On ppc, we can directly use ucontext_t as the unwind context. */ +typedef ucontext_t unw_tdep_context_t; + +/* XXX this is not ideal: an application should not be prevented from + using the "getcontext" name just because it's using libunwind. We + can't just use __getcontext() either, because that isn't exported + by glibc... */ +#define unw_tdep_getcontext(uc) (getcontext (uc), 0) + +#include "libunwind-dynamic.h" + +typedef struct + { + /* no ppc32-specific auxiliary proc-info */ + } +unw_tdep_proc_info_t; + +#include "libunwind-common.h" + +#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) +extern int unw_tdep_is_fpreg (int); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* LIBUNWIND_H */ Index: libunwind/src/Makefile.am =================================================================== --- libunwind/src/Makefile.am +++ libunwind/src/Makefile.am @@ -38,7 +38,8 @@ libunwind_setjmp_la_SOURCES_ia64 = ia64/ libunwind_setjmp_la_SOURCES_hppa = hppa/siglongjmp.S libunwind_setjmp_la_SOURCES_x86 = x86/longjmp.S x86/siglongjmp.S libunwind_setjmp_la_SOURCES_x86_64 = x86_64/longjmp.S x86_64/siglongjmp.S -libunwind_setjmp_la_SOURCES_ppc64 = ppc64/longjmp.S ppc64/siglongjmp.S +libunwind_setjmp_la_SOURCES_ppc64 = ppc/longjmp.S ppc/siglongjmp.S +libunwind_setjmp_la_SOURCES_ppc32 = ppc/longjmp.S ppc/siglongjmp.S ### libunwind: @@ -105,7 +106,6 @@ libunwind_la_SOURCES_ia64 = $(libunwind_ $(libunwind_la_SOURCES_local) \ \ ia64/dyn_info_list.S ia64/getcontext.S \ - \ ia64/Lcreate_addr_space.c ia64/Lget_proc_info.c ia64/Lget_save_loc.c \ ia64/Lglobal.c ia64/Linit.c ia64/Linit_local.c ia64/Linit_remote.c \ ia64/Linstall_cursor.S ia64/Lis_signal_frame.c ia64/Lparser.c \ @@ -188,7 +188,7 @@ libunwind_la_SOURCES_x86_64 = $(libunwin $(libunwind_la_SOURCES_local) \ $(dwarf_SOURCES_local) \ dwarf/Lfind_proc_info-lsb.c \ - x86_64/setcontext.S \ + x86_64/setcontext.S \ x86_64/Lcreate_addr_space.c x86_64/Lget_save_loc.c x86_64/Lglobal.c \ x86_64/Linit.c x86_64/Linit_local.c x86_64/Linit_remote.c \ x86_64/Lis_signal_frame.c x86_64/Lget_proc_info.c x86_64/Lregs.c \ @@ -204,6 +204,41 @@ libunwind_x86_64_la_SOURCES_x86_64 = $(l x86_64/Gis_signal_frame.c x86_64/Gget_proc_info.c x86_64/Gregs.c \ x86_64/Gresume.c x86_64/Gstep.c +# The list of local files that go to Power 64 and 32: +libunwind_la_SOURCES_ppc = ppc/Lcreate_addr_space.c \ + ppc/Lget_proc_info.c ppc/Lget_save_loc.c ppc/Linit_local.c \ + ppc/Linit_remote.c ppc/Lis_signal_frame.c + +# The list of generic files that go to Power 64 and 32: +libunwind_ppc_la_SOURCES_ppc_generic = ppc/Gcreate_addr_space.c \ + ppc/Gget_proc_info.c ppc/Gget_save_loc.c ppc/Ginit_local.c \ + ppc/Ginit_remote.c ppc/Gis_signal_frame.c + +# The list of files that go both into libunwind and libunwind-ppc32: +libunwind_la_SOURCES_ppc32_common = $(libunwind_la_SOURCES_common) \ + $(dwarf_SOURCES_common) \ + elf32.c elf32.h \ + ppc32/init.h ppc32/unwind_i.h ppc32/ucontext_i.h \ + ppc32/is_fpreg.c ppc32/regname.c ppc32/get_func_addr.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_ppc32 = $(libunwind_la_SOURCES_ppc32_common) \ + $(libunwind_la_SOURCES_local) \ + $(dwarf_SOURCES_local) \ + $(libunwind_la_SOURCES_ppc) \ + dwarf/Lfind_proc_info-lsb.c \ + ppc32/Lglobal.c ppc32/Linit.c \ + ppc32/Lregs.c ppc32/Lresume.c ppc32/Lstep.c + +# The list of files that go into libunwind-ppc32: +libunwind_ppc32_la_SOURCES_ppc32 = $(libunwind_la_SOURCES_ppc32_common) \ + $(libunwind_la_SOURCES_generic) \ + $(dwarf_SOURCES_generic) \ + $(libunwind_ppc_la_SOURCES_ppc_generic) \ + dwarf/Gfind_proc_info-lsb.c \ + ppc32/Gglobal.c ppc32/Ginit.c \ + ppc32/Gregs.c ppc32/Gresume.c ppc32/Gstep.c + # The list of files that go both into libunwind and libunwind-ppc64: libunwind_la_SOURCES_ppc64_common = $(libunwind_la_SOURCES_common) \ $(dwarf_SOURCES_common) \ @@ -215,24 +250,19 @@ libunwind_la_SOURCES_ppc64_common = $(li libunwind_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \ $(libunwind_la_SOURCES_local) \ $(dwarf_SOURCES_local) \ + $(libunwind_la_SOURCES_ppc) \ dwarf/Lfind_proc_info-lsb.c \ - ppc64/Lcreate_addr_space.c ppc64/Lget_save_loc.c \ - ppc64/Lglobal.c ppc64/Linit.c ppc64/Linit_local.c \ - ppc64/Linit_remote.c ppc64/Lis_signal_frame.c \ - ppc64/Lget_proc_info.c ppc64/Lregs.c \ - ppc64/Lresume.c ppc64/Lstep.c + ppc64/Lglobal.c ppc64/Linit.c \ + ppc64/Lregs.c ppc64/Lresume.c ppc64/Lstep.c # The list of files that go into libunwind-ppc64: libunwind_ppc64_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \ $(libunwind_la_SOURCES_generic) \ $(dwarf_SOURCES_generic) \ + $(libunwind_ppc_la_SOURCES_ppc_generic) \ dwarf/Gfind_proc_info-lsb.c \ - ppc64/Gcreate_addr_space.c \ - ppc64/Gget_proc_info.c \ - ppc64/Gget_save_loc.c ppc64/Gglobal.c \ - ppc64/Ginit.c ppc64/Ginit_local.c ppc64/Ginit_remote.c \ - ppc64/Gis_signal_frame.c ppc64/Gregs.c ppc64/Gresume.c \ - ppc64/Gstep.c + ppc64/Gglobal.c ppc64/Ginit.c \ + ppc64/Gregs.c ppc64/Gresume.c ppc64/Gstep.c if REMOTE_ONLY install-exec-hook: @@ -309,7 +339,17 @@ if !REMOTE_ONLY endif libunwind_setjmp_la_SOURCES = $(libunwind_setjmp_la_SOURCES_common) \ $(libunwind_setjmp_la_SOURCES_x86_64) - +else +if ARCH_PPC32 + lib_LTLIBRARIES_arch = libunwind-ppc32.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_ppc32) + libunwind_ppc32_la_SOURCES = $(libunwind_ppc32_la_SOURCES_ppc32) + libunwind_ppc32_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) +if !REMOTE_ONLY + libunwind_ppc32_la_LIBADD = libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES = $(libunwind_setjmp_la_SOURCES_common) \ + $(libunwind_setjmp_la_SOURCES_ppc32) else if ARCH_PPC64 lib_LTLIBRARIES_arch = libunwind-ppc64.la @@ -323,6 +363,7 @@ endif $(libunwind_setjmp_la_SOURCES_ppc64) endif # ARCH_PPC64 +endif # ARCH_PPC32 endif # ARCH_X86_64 endif # ARCH_X86 endif # ARCH_HPPA @@ -362,6 +403,7 @@ EXTRA_DIST = elfxx.h elfxx.c unwind/unwi $(libunwind_setjmp_la_SOURCES_ia64) \ $(libunwind_setjmp_la_SOURCES_x86) \ $(libunwind_setjmp_la_SOURCES_x86_64) \ + $(libunwind_setjmp_la_SOURCES_ppc32) \ $(libunwind_setjmp_la_SOURCES_ppc64) Index: libunwind/src/ppc/longjmp.S =================================================================== --- /dev/null +++ libunwind/src/ppc/longjmp.S @@ -0,0 +1,31 @@ +/* libunwind - a platform-independent unwind library + + Copied from src/x86_64/, modified slightly (or made empty stubs) for + building frysk successfully on ppc64, by Wu Zhou + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + + .globl _UI_longjmp_cont + + .type _UI_longjmp_cont, @function +_UI_longjmp_cont: + .size _UI_longjmp_cont, .-_UI_longjmp_cont Index: libunwind/src/ppc/siglongjmp.S =================================================================== --- /dev/null +++ libunwind/src/ppc/siglongjmp.S @@ -0,0 +1,26 @@ +/* libunwind - a platform-independent unwind library + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + + .globl _UI_siglongjmp_cont + + _UI_siglongjmp_cont: Index: libunwind/include/tdep-ppc32/dwarf-config.h =================================================================== --- /dev/null +++ libunwind/include/tdep-ppc32/dwarf-config.h @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + Will be replaced when libunwind is ready on ppc64 platform. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef dwarf_config_h +#define dwarf_config_h + +/* For PPC64, 48 GPRs + 33 FPRs + 33 AltiVec + 1 SPE */ +#define DWARF_NUM_PRESERVED_REGS 115 + +#define DWARF_REGNUM_MAP_LENGTH 115 + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) 1 + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see X86_LOC_TYPE_* macros. */ +#endif + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ Index: libunwind/include/tdep-ppc32/libunwind_i.h =================================================================== --- /dev/null +++ libunwind/include/tdep-ppc32/libunwind_i.h @@ -0,0 +1,299 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + Will be replaced when libunwind is ready on ppc64 platform. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef PPC32_LIBUNWIND_I_H +#define PPC32_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf32.h" +#include "mempool.h" +#include "dwarf.h" + +struct unw_addr_space +{ + struct unw_accessors acc; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + int validate; +}; + +struct cursor +{ + struct dwarf_cursor dwarf; /* must be first */ + + /* Format of sigcontext structure and address at which it is + stored: */ + enum + { + PPC_SCF_NONE, /* no signal frame encountered */ + PPC_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */ + } + sigcontext_format; + unw_word_t sigcontext_addr; +}; + +#define DWARF_GET_LOC(l) ((l).val) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +# define DWARF_IS_REG_LOC(l) 0 +# define DWARF_IS_FP_LOC(l) 0 +# define DWARF_IS_V_LOC(l) 0 +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_VREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +#else /* !UNW_LOCAL_ONLY */ + +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_LOC_TYPE_V (1 << 2) +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_IS_V_LOC(l) (((l).type & DWARF_LOC_TYPE_V) != 0) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) +# define DWARF_VREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_V)) + +#endif /* !UNW_LOCAL_ONLY */ + +static inline int +dwarf_getvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val) +{ + unw_word_t *valp = (unw_word_t *) val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_V_LOC (loc)); + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp, + 0, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 0, c->as_arg); +} + +static inline int +dwarf_putvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + unw_word_t *valp = (unw_word_t *) & val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_V_LOC (loc)); + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp, + 1, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 1, c->as_arg); +} + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val) +{ + unw_word_t *valp = (unw_word_t *) val; + unw_word_t addr; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 0, c->as_arg); + +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + unw_word_t *valp = (unw_word_t *) & val; + unw_word_t addr; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + + return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t * val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + + + +#define tdep_needs_initialization UNW_OBJ(needs_initialization) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_get_func_addr UNW_OBJ(get_func_addr) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +extern int tdep_fetch_proc_info_post (struct dwarf_cursor *c, unw_word_t ip, + int need_unwind_info); + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) 1 + +extern int tdep_needs_initialization; + +extern void tdep_init (void); +extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, + unw_dyn_info_t * di, + unw_proc_info_t * pi, + int need_unwind_info, void *arg); +extern void *tdep_uc_addr (ucontext_t * uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t * valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t * valp, int write); +extern int tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr, + unw_word_t *entry_point); + +#endif /* PPC64_LIBUNWIND_I_H */ Index: libunwind/include/tdep-ppc32/jmpbuf.h =================================================================== --- /dev/null +++ libunwind/include/tdep-ppc32/jmpbuf.h @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + Will be replaced when libunwind is ready on ppc64 platform. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +#define JB_SP 6 +#define JB_RP 7 +#define JB_MASK_SAVED 8 +#define JB_MASK 9 Index: libunwind/src/ppc/Gcreate_addr_space.c =================================================================== --- /dev/null +++ libunwind/src/ppc/Gcreate_addr_space.c @@ -0,0 +1,54 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include + +PROTECTED unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as = malloc (sizeof (*as)); + + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + /* + * Linux ppc64 supports only big-endian. + */ + if (byte_order != 0 && byte_order != __BIG_ENDIAN) + return NULL; + return as; +#endif +} Index: libunwind/src/ppc/Gget_proc_info.c =================================================================== --- /dev/null +++ libunwind/src/ppc/Gget_proc_info.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + + Copied from src/x86_64/, modified slightly (or made empty stubs) for + building frysk successfully on ppc64, by Wu Zhou + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +PROTECTED int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + /* XXX: empty stub. */ + return 0; +} Index: libunwind/src/ppc/Gget_save_loc.c =================================================================== --- /dev/null +++ libunwind/src/ppc/Gget_save_loc.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + + Copied from src/x86_64/, modified slightly (or made empty stubs) for + building frysk successfully on ppc64, by Wu Zhou + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +PROTECTED int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + /* XXX: empty stub. */ + return 0; +} Index: libunwind/src/ppc/Ginit_local.c =================================================================== --- /dev/null +++ libunwind/src/ppc/Ginit_local.c @@ -0,0 +1,65 @@ +/* libunwind - a platform-independent unwind library + + Copied from src/x86_64/, modified slightly (or made empty stubs) for + building frysk successfully on ppc64, by Wu Zhou + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#ifdef UNW_TARGET_PPC64 +#include "../ppc64/init.h" +#else +#include "../ppc32/init.h" +#endif + +#ifdef UNW_REMOTE_ONLY + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + /* XXX: empty stub. */ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +PROTECTED int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + struct cursor *c = (struct cursor *) cursor; + + if (tdep_needs_initialization) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = uc; + #ifdef UNW_TARGET_PPC64 + return common_init_ppc64 (c); + #else + return common_init_ppc32 (c); + #endif +} + +#endif /* !UNW_REMOTE_ONLY */ Index: libunwind/src/ppc/Ginit_remote.c =================================================================== --- /dev/null +++ libunwind/src/ppc/Ginit_remote.c @@ -0,0 +1,60 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#ifdef UNW_TARGET_PPC64 +#include "../ppc64/init.h" +#else +#include "../ppc32/init.h" +#endif + +PROTECTED int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (tdep_needs_initialization) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + c->dwarf.as_arg = as_arg; + + #ifdef UNW_TARGET_PPC64 + return common_init_ppc64(c); + #elif UNW_TARGET_PPC32 + return common_init_ppc32 (c); + #else + #error init_remote :: NO VALID PPC ARCH! + #endif +#endif /* !UNW_LOCAL_ONLY */ +} Index: libunwind/src/ppc/Gis_signal_frame.c =================================================================== --- /dev/null +++ libunwind/src/ppc/Gis_signal_frame.c @@ -0,0 +1,66 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +PROTECTED int +unw_is_signal_frame (unw_cursor_t * cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, w1, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + as->validate = 1; /* Don't trust the ip */ + arg = c->dwarf.as_arg; + + /* Check if return address points at sigreturn sequence. + on ppc64 Linux that is (see libc.so): + 0x38210080 addi r1, r1, 128 // pop the stack + 0x380000ac li r0, 172 // invoke system service 172 + 0x44000002 sc + */ + + ip = c->dwarf.ip; + if (ip == 0) + return 0; + + /* Read up two 8-byte words at the IP. We are only looking at 3 + consecutive 32-bit words, so the second 8-byte word needs to be + shifted right by 32 bits (think big-endian) */ + + a = unw_get_accessors (as); + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0 + || (ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0) + return 0; + w1 >>= 32; + return (w0 == 0x38210080380000ac && w1 == 0x44000002); + +} Index: libunwind/src/ppc/Lcreate_addr_space.c =================================================================== --- /dev/null +++ libunwind/src/ppc/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif Index: libunwind/src/ppc/Lget_proc_info.c =================================================================== --- /dev/null +++ libunwind/src/ppc/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif Index: libunwind/src/ppc/Lget_save_loc.c =================================================================== --- /dev/null +++ libunwind/src/ppc/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif Index: libunwind/src/ppc/Linit_local.c =================================================================== --- /dev/null +++ libunwind/src/ppc/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif Index: libunwind/src/ppc/Linit_remote.c =================================================================== --- /dev/null +++ libunwind/src/ppc/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif Index: libunwind/src/ppc/Lis_signal_frame.c =================================================================== --- /dev/null +++ libunwind/src/ppc/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif Index: libunwind/src/ppc32/Gglobal.c =================================================================== --- /dev/null +++ libunwind/src/ppc32/Gglobal.c @@ -0,0 +1,150 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN pthread_mutex_t ppc32_lock = PTHREAD_MUTEX_INITIALIZER; +HIDDEN int tdep_needs_initialization = 1; + +/* The API register numbers are exactly the same as the .eh_frame + registers, for now at least. */ +uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH] = + { + [UNW_PPC32_R0]=UNW_PPC32_R0, + [UNW_PPC32_R1]=UNW_PPC32_R1, + [UNW_PPC32_R2]=UNW_PPC32_R2, + [UNW_PPC32_R3]=UNW_PPC32_R3, + [UNW_PPC32_R4]=UNW_PPC32_R4, + [UNW_PPC32_R5]=UNW_PPC32_R5, + [UNW_PPC32_R6]=UNW_PPC32_R6, + [UNW_PPC32_R7]=UNW_PPC32_R7, + [UNW_PPC32_R8]=UNW_PPC32_R8, + [UNW_PPC32_R9]=UNW_PPC32_R9, + [UNW_PPC32_R10]=UNW_PPC32_R10, + [UNW_PPC32_R11]=UNW_PPC32_R11, + [UNW_PPC32_R12]=UNW_PPC32_R12, + [UNW_PPC32_R13]=UNW_PPC32_R13, + [UNW_PPC32_R14]=UNW_PPC32_R14, + [UNW_PPC32_R15]=UNW_PPC32_R15, + [UNW_PPC32_R16]=UNW_PPC32_R16, + [UNW_PPC32_R17]=UNW_PPC32_R17, + [UNW_PPC32_R18]=UNW_PPC32_R18, + [UNW_PPC32_R19]=UNW_PPC32_R19, + [UNW_PPC32_R20]=UNW_PPC32_R20, + [UNW_PPC32_R21]=UNW_PPC32_R21, + [UNW_PPC32_R22]=UNW_PPC32_R22, + [UNW_PPC32_R23]=UNW_PPC32_R23, + [UNW_PPC32_R24]=UNW_PPC32_R24, + [UNW_PPC32_R25]=UNW_PPC32_R25, + [UNW_PPC32_R26]=UNW_PPC32_R26, + [UNW_PPC32_R27]=UNW_PPC32_R27, + [UNW_PPC32_R28]=UNW_PPC32_R28, + [UNW_PPC32_R29]=UNW_PPC32_R29, + [UNW_PPC32_R30]=UNW_PPC32_R30, + [UNW_PPC32_R31]=UNW_PPC32_R31, + + [UNW_PPC32_F0]=UNW_PPC32_F0, + [UNW_PPC32_F1]=UNW_PPC32_F1, + [UNW_PPC32_F2]=UNW_PPC32_F2, + [UNW_PPC32_F3]=UNW_PPC32_F3, + [UNW_PPC32_F4]=UNW_PPC32_F4, + [UNW_PPC32_F5]=UNW_PPC32_F5, + [UNW_PPC32_F6]=UNW_PPC32_F6, + [UNW_PPC32_F7]=UNW_PPC32_F7, + [UNW_PPC32_F8]=UNW_PPC32_F8, + [UNW_PPC32_F9]=UNW_PPC32_F9, + [UNW_PPC32_F10]=UNW_PPC32_F10, + [UNW_PPC32_F11]=UNW_PPC32_F11, + [UNW_PPC32_F12]=UNW_PPC32_F12, + [UNW_PPC32_F13]=UNW_PPC32_F13, + [UNW_PPC32_F14]=UNW_PPC32_F14, + [UNW_PPC32_F15]=UNW_PPC32_F15, + [UNW_PPC32_F16]=UNW_PPC32_F16, + [UNW_PPC32_F17]=UNW_PPC32_F17, + [UNW_PPC32_F18]=UNW_PPC32_F18, + [UNW_PPC32_F19]=UNW_PPC32_F19, + [UNW_PPC32_F20]=UNW_PPC32_F20, + [UNW_PPC32_F21]=UNW_PPC32_F21, + [UNW_PPC32_F22]=UNW_PPC32_F22, + [UNW_PPC32_F23]=UNW_PPC32_F23, + [UNW_PPC32_F24]=UNW_PPC32_F24, + [UNW_PPC32_F25]=UNW_PPC32_F25, + [UNW_PPC32_F26]=UNW_PPC32_F26, + [UNW_PPC32_F27]=UNW_PPC32_F27, + [UNW_PPC32_F28]=UNW_PPC32_F28, + [UNW_PPC32_F29]=UNW_PPC32_F29, + [UNW_PPC32_F30]=UNW_PPC32_F30, + [UNW_PPC32_F31]=UNW_PPC32_F31, + + [UNW_PPC32_LR]=UNW_PPC32_LR, + [UNW_PPC32_CTR]=UNW_PPC32_CTR, + [UNW_PPC32_ARG_POINTER]=UNW_PPC32_ARG_POINTER, + + [UNW_PPC32_CR0]=UNW_PPC32_CR0, + [UNW_PPC32_CR1]=UNW_PPC32_CR1, + [UNW_PPC32_CR2]=UNW_PPC32_CR2, + [UNW_PPC32_CR3]=UNW_PPC32_CR3, + [UNW_PPC32_CR4]=UNW_PPC32_CR4, + [UNW_PPC32_CR5]=UNW_PPC32_CR5, + [UNW_PPC32_CR6]=UNW_PPC32_CR6, + [UNW_PPC32_CR7]=UNW_PPC32_CR7, + + [UNW_PPC32_XER]=UNW_PPC32_XER, + [UNW_PPC32_VRSAVE]=UNW_PPC32_VRSAVE, + [UNW_PPC32_VSCR]=UNW_PPC32_VSCR, + [UNW_PPC32_SPE_ACC]=UNW_PPC32_SPE_ACC, + [UNW_PPC32_SPEFSCR]=UNW_PPC32_SPEFSCR, + }; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + sigprocmask (SIG_SETMASK, &unwi_full_mask, &saved_mask); + mutex_lock (&ppc32_lock); + { + if (!tdep_needs_initialization) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + ppc32_local_addr_space_init (); +#endif + tdep_needs_initialization = 0; /* signal that we're initialized... */ + } + out: + mutex_unlock (&ppc32_lock); + sigprocmask (SIG_SETMASK, &saved_mask, NULL); +} Index: libunwind/src/ppc32/Ginit.c =================================================================== --- /dev/null +++ libunwind/src/ppc32/Ginit.c @@ -0,0 +1,221 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "ucontext_i.h" +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +PROTECTED unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space; + + +#define PAGE_SIZE 4096 +#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1)) + + +static void * +uc_addr (ucontext_t *uc, int reg) +{ + void *addr; + + if ((unsigned) (reg - UNW_PPC32_R0) < 32) + addr = &uc->uc_mcontext.uc_regs->gregs[reg - UNW_PPC32_R0]; + + else if ((unsigned) (reg - UNW_PPC32_F0) < 32) + addr = &uc->uc_mcontext.uc_regs->fpregs.fpregs[reg - UNW_PPC32_F0]; + + else + { + unsigned gregs_idx; + + switch (reg) + { + case UNW_PPC32_NIP: + gregs_idx = NIP_IDX; + break; + case UNW_PPC32_CTR: + gregs_idx = CTR_IDX; + break; + case UNW_PPC32_LR: + gregs_idx = LINK_IDX; + break; + case UNW_PPC32_XER: + gregs_idx = XER_IDX; + break; + case UNW_PPC32_CR0: + gregs_idx = CCR_IDX; + break; + default: + return NULL; + } + addr = &uc->uc_mcontext.uc_regs->gregs[gregs_idx]; + } + return addr; +} + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (ucontext_t *uc, int reg) +{ + return uc_addr (uc, reg); +} + +# endif /* UNW_LOCAL_ONLY */ + +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write) + { + Debug (12, "mem[%lx] <- %lx\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "mem[%lx] -> %lx\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, + int write, void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = arg; + + if ((unsigned int) (reg - UNW_PPC32_F0) < 32) + goto badreg; + + addr = uc_addr (uc, reg); + if (!addr) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- %lx\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> %lx\n", unw_regname (reg), *val); + } + return 0; + +badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = arg; + unw_fpreg_t *addr; + + if ((unsigned) (reg - UNW_PPC32_F0) < 0) + goto badreg; + + addr = uc_addr (uc, reg); + if (!addr) + goto badreg; + + if (write) + { + Debug (12, "%s <- %016Lf\n", unw_regname (reg), *val); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %016Lf\n", unw_regname (reg), *val); + } + return 0; + +badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +ppc32_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = ppc32_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ Index: libunwind/src/ppc32/Gregs.c =================================================================== --- /dev/null +++ libunwind/src/ppc32/Gregs.c @@ -0,0 +1,90 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + struct dwarf_loc loc; + + switch (reg) + { + case UNW_TDEP_IP: + if (write) + { + c->dwarf.ip = *valp; /* update the IP cache */ + if (c->dwarf.pi_valid && (*valp < c->dwarf.pi.start_ip + || *valp >= c->dwarf.pi.end_ip)) + c->dwarf.pi_valid = 0; /* new IP outside of current proc */ + } + else + *valp = c->dwarf.ip; + return 0; + + case UNW_TDEP_SP: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + + default: + break; + } + + /* make sure it's not an FP or VR register */ + if ((((unsigned) (reg - UNW_PPC32_F0)) <= 31)) + return -UNW_EBADREG; + + loc = c->dwarf.loc[reg]; + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + struct dwarf_loc loc; + + if ((unsigned) (reg - UNW_PPC32_F0) < 32) + { + loc = c->dwarf.loc[reg]; + if (write) + return dwarf_putfp (&c->dwarf, loc, *valp); + else + return dwarf_getfp (&c->dwarf, loc, valp); + } + + return -UNW_EBADREG; +} + Index: libunwind/src/ppc32/Gresume.c =================================================================== --- /dev/null +++ libunwind/src/ppc32/Gresume.c @@ -0,0 +1,77 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford address@hidden + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +#ifndef UNW_REMOTE_ONLY + +#include + +/* sigreturn() is a no-op on x86_64 glibc. */ + +static NORETURN inline long +my_rt_sigreturn (void *new_sp) +{ + /* XXX: empty stub. */ + abort (); +} + +HIDDEN inline int +ppc32_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + /* XXX: empty stub. */ + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +/* This routine is responsible for copying the register values in + cursor C and establishing them as the current machine state. */ + +static inline int +establish_machine_state (struct cursor *c) +{ + /* XXX: empty stub. */ + return 0; +} + +PROTECTED int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p)\n", c); + + if ((ret = establish_machine_state (c)) < 0) + return ret; + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} Index: libunwind/src/ppc32/Gstep.c =================================================================== --- /dev/null +++ libunwind/src/ppc32/Gstep.c @@ -0,0 +1,317 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "ucontext_i.h" +#include + +/* This definition originates in /usr/include/asm-ppc64/ptrace.h, but is + defined there only when __KERNEL__ is defined. We reproduce it here for + our use at the user level in order to locate the ucontext record, which + appears to be at this offset relative to the stack pointer when in the + context of the signal handler return trampoline code - + __kernel_sigtramp_rt64. */ +#define __SIGNAL_FRAMESIZE 128 + +/* This definition comes from the document "64-bit PowerPC ELF Application + Binary Interface Supplement 1.9", section 3.2.2. + http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK */ + +typedef struct +{ + long unsigned back_chain; + long unsigned cr_save; + long unsigned lr_save; + /* many more fields here, but they are unused by this code */ +} stack_frame_t; + + +PROTECTED int +unw_step (unw_cursor_t * cursor) +{ + struct cursor *c = (struct cursor *) cursor; + stack_frame_t dummy; + unw_word_t back_chain_offset, lr_save_offset, v_regs_ptr; + struct dwarf_loc back_chain_loc, lr_save_loc, sp_loc, ip_loc, v_regs_loc; + int ret; + + Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->dwarf.ip); + + if (c->dwarf.ip == 0) + { + /* Unless the cursor or stack is corrupt or uninitialized, + we've most likely hit the top of the stack */ + return 0; + } + + /* Try DWARF-based unwinding... */ + + ret = dwarf_step (&c->dwarf); + + if (ret < 0 && ret != -UNW_ENOINFO) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + if (unlikely (ret < 0)) + { + if (likely (!unw_is_signal_frame (cursor))) + { + /* DWARF unwinding failed. As of 09/26/2006, gcc in 64-bit mode + produces the mandatory level of traceback record in the code, but + I get the impression that this is transitory, that eventually gcc + will not produce any traceback records at all. So, for now, we + won't bother to try to find and use these records. + + We can, however, attempt to unwind the frame by using the callback + chain. This is very crude, however, and won't be able to unwind + any registers besides the IP, SP, and LR . */ + + back_chain_offset = ((void *) &dummy.back_chain - (void *) &dummy); + lr_save_offset = ((void *) &dummy.lr_save - (void *) &dummy); + + back_chain_loc = DWARF_LOC (c->dwarf.cfa + back_chain_offset, 0); + + if ((ret = + dwarf_get (&c->dwarf, back_chain_loc, &c->dwarf.cfa)) < 0) + { + Debug + ("Unable to retrieve CFA from back chain in stack frame - %d\n", + ret); + return ret; + } + if (c->dwarf.cfa == 0) + /* Unless the cursor or stack is corrupt or uninitialized we've most + likely hit the top of the stack */ + return 0; + + lr_save_loc = DWARF_LOC (c->dwarf.cfa + lr_save_offset, 0); + + if ((ret = dwarf_get (&c->dwarf, lr_save_loc, &c->dwarf.ip)) < 0) + { + Debug + ("Unable to retrieve IP from lr save in stack frame - %d\n", + ret); + return ret; + } + ret = 1; + } + else + { + /* Find the sigcontext record by taking the CFA and adjusting by + the dummy signal frame size. + + Note that there isn't any way to determined if SA_SIGINFO was + set in the sa_flags parameter to sigaction when the signal + handler was established. If it was not set, the ucontext + record is not required to be on the stack, in which case the + following code will likely cause a seg fault or other crash + condition. */ + + unw_word_t ucontext = c->dwarf.cfa + __SIGNAL_FRAMESIZE; + + Debug (1, "signal frame, skip over trampoline\n"); + + c->sigcontext_format = PPC_SCF_LINUX_RT_SIGFRAME; + c->sigcontext_addr = ucontext; + + sp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0); + ip_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_NIP, 0); + + ret = dwarf_get (&c->dwarf, sp_loc, &c->dwarf.cfa); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + ret = dwarf_get (&c->dwarf, ip_loc, &c->dwarf.ip); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + /* Instead of just restoring the non-volatile registers, do all + of the registers for now. This will incur a performance hit, + but it's rare enough not to cause too much of a problem, and + might be useful in some cases. */ + c->dwarf.loc[UNW_PPC32_R0] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R0, 0); + c->dwarf.loc[UNW_PPC32_R1] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0); + c->dwarf.loc[UNW_PPC32_R2] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R2, 0); + c->dwarf.loc[UNW_PPC32_R3] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R3, 0); + c->dwarf.loc[UNW_PPC32_R4] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R4, 0); + c->dwarf.loc[UNW_PPC32_R5] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R5, 0); + c->dwarf.loc[UNW_PPC32_R6] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R6, 0); + c->dwarf.loc[UNW_PPC32_R7] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R7, 0); + c->dwarf.loc[UNW_PPC32_R8] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0); + c->dwarf.loc[UNW_PPC32_R9] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0); + c->dwarf.loc[UNW_PPC32_R10] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0); + c->dwarf.loc[UNW_PPC32_R11] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0); + c->dwarf.loc[UNW_PPC32_R12] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0); + c->dwarf.loc[UNW_PPC32_R13] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0); + c->dwarf.loc[UNW_PPC32_R14] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0); + c->dwarf.loc[UNW_PPC32_R15] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0); + c->dwarf.loc[UNW_PPC32_R16] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R16, 0); + c->dwarf.loc[UNW_PPC32_R17] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R17, 0); + c->dwarf.loc[UNW_PPC32_R18] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R18, 0); + c->dwarf.loc[UNW_PPC32_R19] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R19, 0); + c->dwarf.loc[UNW_PPC32_R20] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R20, 0); + c->dwarf.loc[UNW_PPC32_R21] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R21, 0); + c->dwarf.loc[UNW_PPC32_R22] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R22, 0); + c->dwarf.loc[UNW_PPC32_R23] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R23, 0); + c->dwarf.loc[UNW_PPC32_R24] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R24, 0); + c->dwarf.loc[UNW_PPC32_R25] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R25, 0); + c->dwarf.loc[UNW_PPC32_R26] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R26, 0); + c->dwarf.loc[UNW_PPC32_R27] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R27, 0); + c->dwarf.loc[UNW_PPC32_R28] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R28, 0); + c->dwarf.loc[UNW_PPC32_R29] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R29, 0); + c->dwarf.loc[UNW_PPC32_R30] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R30, 0); + c->dwarf.loc[UNW_PPC32_R31] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R31, 0); + + c->dwarf.loc[UNW_PPC32_LR] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0); + c->dwarf.loc[UNW_PPC32_CTR] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CTR, 0); + /* This CR0 assignment is probably wrong. There are 8 dwarf columns + assigned to the CR registers, but only one CR register in the + mcontext structure */ + c->dwarf.loc[UNW_PPC32_CR0] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CCR, 0); + c->dwarf.loc[UNW_PPC32_XER] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_XER, 0); + c->dwarf.loc[UNW_PPC32_NIP] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_NIP, 0); + + /* TODO: Is there a way of obtaining the value of the + pseudo frame pointer (which is sp + some fixed offset, I + assume), based on the contents of the ucontext record + structure? For now, set this loc to null. */ + c->dwarf.loc[UNW_PPC32_FRAME_POINTER] = DWARF_NULL_LOC; + + c->dwarf.loc[UNW_PPC32_F0] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R0, 0); + c->dwarf.loc[UNW_PPC32_F1] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R1, 0); + c->dwarf.loc[UNW_PPC32_F2] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R2, 0); + c->dwarf.loc[UNW_PPC32_F3] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R3, 0); + c->dwarf.loc[UNW_PPC32_F4] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R4, 0); + c->dwarf.loc[UNW_PPC32_F5] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R5, 0); + c->dwarf.loc[UNW_PPC32_F6] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R6, 0); + c->dwarf.loc[UNW_PPC32_F7] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R7, 0); + c->dwarf.loc[UNW_PPC32_F8] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R8, 0); + c->dwarf.loc[UNW_PPC32_F9] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R9, 0); + c->dwarf.loc[UNW_PPC32_F10] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R10, 0); + c->dwarf.loc[UNW_PPC32_F11] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R11, 0); + c->dwarf.loc[UNW_PPC32_F12] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R12, 0); + c->dwarf.loc[UNW_PPC32_F13] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R13, 0); + c->dwarf.loc[UNW_PPC32_F14] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R14, 0); + c->dwarf.loc[UNW_PPC32_F15] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R15, 0); + c->dwarf.loc[UNW_PPC32_F16] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R16, 0); + c->dwarf.loc[UNW_PPC32_F17] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R17, 0); + c->dwarf.loc[UNW_PPC32_F18] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R18, 0); + c->dwarf.loc[UNW_PPC32_F19] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R19, 0); + c->dwarf.loc[UNW_PPC32_F20] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R20, 0); + c->dwarf.loc[UNW_PPC32_F21] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R21, 0); + c->dwarf.loc[UNW_PPC32_F22] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R22, 0); + c->dwarf.loc[UNW_PPC32_F23] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R23, 0); + c->dwarf.loc[UNW_PPC32_F24] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R24, 0); + c->dwarf.loc[UNW_PPC32_F25] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R25, 0); + c->dwarf.loc[UNW_PPC32_F26] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R26, 0); + c->dwarf.loc[UNW_PPC32_F27] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R27, 0); + c->dwarf.loc[UNW_PPC32_F28] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R28, 0); + c->dwarf.loc[UNW_PPC32_F29] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R29, 0); + c->dwarf.loc[UNW_PPC32_F30] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R30, 0); + c->dwarf.loc[UNW_PPC32_F31] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R31, 0); + + ret = 1; + } + } + return ret; +} Index: libunwind/src/ppc32/Lglobal.c =================================================================== --- /dev/null +++ libunwind/src/ppc32/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif Index: libunwind/src/ppc32/Linit.c =================================================================== --- /dev/null +++ libunwind/src/ppc32/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif Index: libunwind/src/ppc32/Lregs.c =================================================================== --- /dev/null +++ libunwind/src/ppc32/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif Index: libunwind/src/ppc32/Lresume.c =================================================================== --- /dev/null +++ libunwind/src/ppc32/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif Index: libunwind/src/ppc32/Lstep.c =================================================================== --- /dev/null +++ libunwind/src/ppc32/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif Index: libunwind/src/ppc32/Make-arch.in =================================================================== --- /dev/null +++ libunwind/src/ppc32/Make-arch.in @@ -0,0 +1,11 @@ +# Word size. +ELFW = 64 +# Does use dwarf2 unwind info. +dwarf_target = true + +libunwind_setjmp_OBJS += \ + $(arch)/longjmp.o \ + $(arch)/siglongjmp.o + +libunwind_OBJS_common += \ + $(arch)/is_fpreg.o Index: libunwind/src/ppc32/get_func_addr.c =================================================================== --- /dev/null +++ libunwind/src/ppc32/get_func_addr.c @@ -0,0 +1,45 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr, + unw_word_t *entry_point) +{ + unw_accessors_t *a; + int ret; + + a = unw_get_accessors (as); + /* Entry-point is stored in the 1st word of the function descriptor. + In case that changes in the future, we'd have to update the line + below and read the word at addr + offset: */ + ret = (*a->access_mem) (as, addr, entry_point, 0, NULL); + if (ret < 0) + return ret; + return 0; +} Index: libunwind/src/ppc32/init.h =================================================================== --- /dev/null +++ libunwind/src/ppc32/init.h @@ -0,0 +1,80 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +/* Here is the "common" init, for remote and local debuging" */ + +static inline int +common_init_ppc32 (struct cursor *c) +{ + int ret; + int i; + + for (i = UNW_PPC32_R0; i <= UNW_PPC32_R31; i++) { + c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, i); + } + for (i = UNW_PPC32_F0; i <= UNW_PPC32_F31; i++) { + c->dwarf.loc[i] = DWARF_FPREG_LOC (&c->dwarf, i); + } + + for (i = UNW_PPC32_CR0; i <= UNW_PPC32_CR7; i++) { + c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, i); + } + c->dwarf.loc[UNW_PPC32_ARG_POINTER] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_ARG_POINTER); + c->dwarf.loc[UNW_PPC32_CTR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_CTR); + c->dwarf.loc[UNW_PPC32_VSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_VSCR); + + c->dwarf.loc[UNW_PPC32_XER] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_XER); + c->dwarf.loc[UNW_PPC32_LR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_LR); + c->dwarf.loc[UNW_PPC32_VRSAVE] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_VRSAVE); + c->dwarf.loc[UNW_PPC32_SPEFSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_SPEFSCR); + c->dwarf.loc[UNW_PPC32_SPE_ACC] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_SPE_ACC); + + c->dwarf.loc[UNW_PPC32_NIP] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_NIP); + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_PPC32_NIP], &c->dwarf.ip); + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_PPC32_R1), + &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->sigcontext_format = PPC_SCF_NONE; + c->sigcontext_addr = 0; + + c->dwarf.args_size = 0; + c->dwarf.ret_addr_column = 0; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + + return 0; +} Index: libunwind/src/ppc32/is_fpreg.c =================================================================== --- /dev/null +++ libunwind/src/ppc32/is_fpreg.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +PROTECTED int +unw_is_fpreg (int regnum) +{ + return (regnum >= UNW_PPC32_F0 && regnum <= UNW_PPC32_F31); +} Index: libunwind/src/ppc32/regname.c =================================================================== --- /dev/null +++ libunwind/src/ppc32/regname.c @@ -0,0 +1,128 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static const char *regname[] = + { + [UNW_PPC32_R0]="GPR0", + [UNW_PPC32_R1]="GPR1", + [UNW_PPC32_R2]="GPR2", + [UNW_PPC32_R3]="GPR3", + [UNW_PPC32_R4]="GPR4", + [UNW_PPC32_R5]="GPR5", + [UNW_PPC32_R6]="GPR6", + [UNW_PPC32_R7]="GPR7", + [UNW_PPC32_R8]="GPR8", + [UNW_PPC32_R9]="GPR9", + [UNW_PPC32_R10]="GPR10", + [UNW_PPC32_R11]="GPR11", + [UNW_PPC32_R12]="GPR12", + [UNW_PPC32_R13]="GPR13", + [UNW_PPC32_R14]="GPR14", + [UNW_PPC32_R15]="GPR15", + [UNW_PPC32_R16]="GPR16", + [UNW_PPC32_R17]="GPR17", + [UNW_PPC32_R18]="GPR18", + [UNW_PPC32_R19]="GPR19", + [UNW_PPC32_R20]="GPR20", + [UNW_PPC32_R21]="GPR21", + [UNW_PPC32_R22]="GPR22", + [UNW_PPC32_R23]="GPR23", + [UNW_PPC32_R24]="GPR24", + [UNW_PPC32_R25]="GPR25", + [UNW_PPC32_R26]="GPR26", + [UNW_PPC32_R27]="GPR27", + [UNW_PPC32_R28]="GPR28", + [UNW_PPC32_R29]="GPR29", + [UNW_PPC32_R30]="GPR30", + [UNW_PPC32_R31]="GPR31", + + [UNW_PPC32_F0]="FPR0", + [UNW_PPC32_F1]="FPR1", + [UNW_PPC32_F2]="FPR2", + [UNW_PPC32_F3]="FPR3", + [UNW_PPC32_F4]="FPR4", + [UNW_PPC32_F5]="FPR5", + [UNW_PPC32_F6]="FPR6", + [UNW_PPC32_F7]="FPR7", + [UNW_PPC32_F8]="FPR8", + [UNW_PPC32_F9]="FPR9", + [UNW_PPC32_F10]="FPR10", + [UNW_PPC32_F11]="FPR11", + [UNW_PPC32_F12]="FPR12", + [UNW_PPC32_F13]="FPR13", + [UNW_PPC32_F14]="FPR14", + [UNW_PPC32_F15]="FPR15", + [UNW_PPC32_F16]="FPR16", + [UNW_PPC32_F17]="FPR17", + [UNW_PPC32_F18]="FPR18", + [UNW_PPC32_F19]="FPR19", + [UNW_PPC32_F20]="FPR20", + [UNW_PPC32_F21]="FPR21", + [UNW_PPC32_F22]="FPR22", + [UNW_PPC32_F23]="FPR23", + [UNW_PPC32_F24]="FPR24", + [UNW_PPC32_F25]="FPR25", + [UNW_PPC32_F26]="FPR26", + [UNW_PPC32_F27]="FPR27", + [UNW_PPC32_F28]="FPR28", + [UNW_PPC32_F29]="FPR29", + [UNW_PPC32_F30]="FPR30", + [UNW_PPC32_F31]="FPR31", + + [UNW_PPC32_LR]="LR", + [UNW_PPC32_CTR]="CTR", + [UNW_PPC32_ARG_POINTER]="ARG_POINTER", + + [UNW_PPC32_CR0]="CR0", + [UNW_PPC32_CR1]="CR1", + [UNW_PPC32_CR2]="CR2", + [UNW_PPC32_CR3]="CR3", + [UNW_PPC32_CR4]="CR4", + [UNW_PPC32_CR5]="CR5", + [UNW_PPC32_CR6]="CR6", + [UNW_PPC32_CR7]="CR7", + + [UNW_PPC32_XER]="XER", + + [UNW_PPC32_VSCR]="VSCR", + + [UNW_PPC32_VRSAVE]="VRSAVE", + [UNW_PPC32_SPE_ACC]="SPE_ACC", + [UNW_PPC32_SPEFSCR]="SPEFSCR", + + }; + +PROTECTED const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else + return "???"; +} Index: libunwind/src/ppc32/setcontext.S =================================================================== --- /dev/null +++ libunwind/src/ppc32/setcontext.S @@ -0,0 +1,4 @@ + .global _UI_setcontext + +_UI_setcontext: + retq Index: libunwind/src/ppc32/ucontext_i.h =================================================================== --- /dev/null +++ libunwind/src/ppc32/ucontext_i.h @@ -0,0 +1,173 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef ucontext_i_h +#define ucontext_i_h + +#include + +/* These values were derived by reading + /usr/src/linux-2.6.18-1.8/arch/um/include/sysdep-ppc/ptrace.h and + /usr/src/linux-2.6.18-1.8/arch/powerpc/kernel/ppc32.h +*/ + +#define NIP_IDX 32 +#define MSR_IDX 33 +#define ORIG_GPR3_IDX 34 +#define CTR_IDX 35 +#define LINK_IDX 36 +#define XER_IDX 37 +#define CCR_IDX 38 +#define SOFTE_IDX 39 +#define TRAP_IDX 40 +#define DAR_IDX 41 +#define DSISR_IDX 42 +#define RESULT_IDX 43 + +#define VSCR_IDX 32 +#define VRSAVE_IDX 33 + +/* These are dummy structures used only for obtaining the offsets of the + various structure members. */ +static ucontext_t dmy_ctxt; +static vrregset_t dmy_vrregset; + +#define UC_MCONTEXT_GREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[0] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[1] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[2] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[3] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[4] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[5] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[6] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[7] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[8] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[9] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[10] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[11] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[12] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[13] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[14] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[15] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[16] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[17] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[18] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[19] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[20] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[21] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[22] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[23] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[24] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[25] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[26] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[27] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[28] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[29] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[30] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[31] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_NIP ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[NIP_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_MSR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[MSR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_ORIG_GPR3 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[ORIG_GPR3_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_CTR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[CTR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_LINK ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[LINK_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_XER ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[XER_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_CCR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[CCR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_SOFTE ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[SOFTE_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_TRAP ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[TRAP_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_DAR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[DAR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_DSISR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[DSISR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_RESULT ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[RESULT_IDX] - (void *)&dmy_ctxt) + +#define UC_MCONTEXT_FREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[0] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[1] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[2] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[3] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[4] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[5] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[6] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[7] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[8] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[9] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[10] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[11] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[12] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[13] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[14] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[15] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[16] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[17] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[18] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[19] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[20] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[21] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[22] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[23] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[24] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[25] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[26] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[27] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[28] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[29] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[30] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[31] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_FPSCR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[32] - (void *)&dmy_ctxt) + +#define UC_MCONTEXT_V_REGS ((void *)&dmy_ctxt.uc_mcontext.v_regs - (void *)&dmy_ctxt) + +#define UC_MCONTEXT_VREGS_R0 ((void *)&dmy_vrregset.vrregs[0] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R1 ((void *)&dmy_vrregset.vrregs[1] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R2 ((void *)&dmy_vrregset.vrregs[2] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R3 ((void *)&dmy_vrregset.vrregs[3] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R4 ((void *)&dmy_vrregset.vrregs[4] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R5 ((void *)&dmy_vrregset.vrregs[5] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R6 ((void *)&dmy_vrregset.vrregs[6] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R7 ((void *)&dmy_vrregset.vrregs[7] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R8 ((void *)&dmy_vrregset.vrregs[8] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R9 ((void *)&dmy_vrregset.vrregs[9] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R10 ((void *)&dmy_vrregset.vrregs[10] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R11 ((void *)&dmy_vrregset.vrregs[11] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R12 ((void *)&dmy_vrregset.vrregs[12] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R13 ((void *)&dmy_vrregset.vrregs[13] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R14 ((void *)&dmy_vrregset.vrregs[14] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R15 ((void *)&dmy_vrregset.vrregs[15] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R16 ((void *)&dmy_vrregset.vrregs[16] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R17 ((void *)&dmy_vrregset.vrregs[17] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R18 ((void *)&dmy_vrregset.vrregs[18] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R19 ((void *)&dmy_vrregset.vrregs[19] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R20 ((void *)&dmy_vrregset.vrregs[20] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R21 ((void *)&dmy_vrregset.vrregs[21] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R22 ((void *)&dmy_vrregset.vrregs[22] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R23 ((void *)&dmy_vrregset.vrregs[23] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R24 ((void *)&dmy_vrregset.vrregs[24] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R25 ((void *)&dmy_vrregset.vrregs[25] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R26 ((void *)&dmy_vrregset.vrregs[26] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R27 ((void *)&dmy_vrregset.vrregs[27] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R28 ((void *)&dmy_vrregset.vrregs[28] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R29 ((void *)&dmy_vrregset.vrregs[29] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R30 ((void *)&dmy_vrregset.vrregs[30] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R31 ((void *)&dmy_vrregset.vrregs[31] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_VSCR ((void *)&dmy_vrregset.vscr - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_VRSAVE ((void *)&dmy_vrregset.vrsave - (void *)&dmy_vrregset) + +#endif Index: libunwind/src/ppc32/unwind_i.h =================================================================== --- /dev/null +++ libunwind/src/ppc32/unwind_i.h @@ -0,0 +1,47 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef unwind_i_h +#define unwind_i_h + +#include +#include + +#include + +#include +#include + +#define ppc32_lock UNW_OBJ(lock) +#define ppc32_local_resume UNW_OBJ(local_resume) +#define ppc32_local_addr_space_init UNW_OBJ(local_addr_space_init) + +extern void ppc32_local_addr_space_init (void); +extern int ppc32_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); + +#endif /* unwind_i_h */ Index: libunwind/src/ppc64/Gcreate_addr_space.c =================================================================== --- libunwind/src/ppc64/Gcreate_addr_space.c +++ /dev/null @@ -1,54 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "unwind_i.h" - -PROTECTED unw_addr_space_t -unw_create_addr_space (unw_accessors_t *a, int byte_order) -{ -#ifdef UNW_LOCAL_ONLY - return NULL; -#else - unw_addr_space_t as = malloc (sizeof (*as)); - - if (!as) - return NULL; - - memset (as, 0, sizeof (*as)); - - as->acc = *a; - - /* - * Linux ppc64 supports only big-endian. - */ - if (byte_order != 0 && byte_order != __BIG_ENDIAN) - return NULL; - return as; -#endif -} Index: libunwind/src/ppc64/Gget_proc_info.c =================================================================== --- libunwind/src/ppc64/Gget_proc_info.c +++ /dev/null @@ -1,34 +0,0 @@ -/* libunwind - a platform-independent unwind library - - Copied from src/x86_64/, modified slightly (or made empty stubs) for - building frysk successfully on ppc64, by Wu Zhou - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -PROTECTED int -unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) -{ - /* XXX: empty stub. */ - return 0; -} Index: libunwind/src/ppc64/Gget_save_loc.c =================================================================== --- libunwind/src/ppc64/Gget_save_loc.c +++ /dev/null @@ -1,34 +0,0 @@ -/* libunwind - a platform-independent unwind library - - Copied from src/x86_64/, modified slightly (or made empty stubs) for - building frysk successfully on ppc64, by Wu Zhou - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -PROTECTED int -unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) -{ - /* XXX: empty stub. */ - return 0; -} Index: libunwind/src/ppc64/Ginit_local.c =================================================================== --- libunwind/src/ppc64/Ginit_local.c +++ /dev/null @@ -1,56 +0,0 @@ -/* libunwind - a platform-independent unwind library - - Copied from src/x86_64/, modified slightly (or made empty stubs) for - building frysk successfully on ppc64, by Wu Zhou - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "init.h" - -#ifdef UNW_REMOTE_ONLY - -PROTECTED int -unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) -{ - /* XXX: empty stub. */ - return -UNW_EINVAL; -} - -#else /* !UNW_REMOTE_ONLY */ - -PROTECTED int -unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) -{ - struct cursor *c = (struct cursor *) cursor; - - if (tdep_needs_initialization) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = unw_local_addr_space; - c->dwarf.as_arg = uc; - return common_init (c); -} - -#endif /* !UNW_REMOTE_ONLY */ Index: libunwind/src/ppc64/Ginit_remote.c =================================================================== --- libunwind/src/ppc64/Ginit_remote.c +++ /dev/null @@ -1,48 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "init.h" -#include "unwind_i.h" - -PROTECTED int -unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) -{ -#ifdef UNW_LOCAL_ONLY - return -UNW_EINVAL; -#else /* !UNW_LOCAL_ONLY */ - struct cursor *c = (struct cursor *) cursor; - - if (tdep_needs_initialization) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = as; - c->dwarf.as_arg = as_arg; - return common_init (c); -#endif /* !UNW_LOCAL_ONLY */ -} Index: libunwind/src/ppc64/Gis_signal_frame.c =================================================================== --- libunwind/src/ppc64/Gis_signal_frame.c +++ /dev/null @@ -1,66 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -PROTECTED int -unw_is_signal_frame (unw_cursor_t * cursor) -{ - struct cursor *c = (struct cursor *) cursor; - unw_word_t w0, w1, ip; - unw_addr_space_t as; - unw_accessors_t *a; - void *arg; - int ret; - - as = c->dwarf.as; - as->validate = 1; /* Don't trust the ip */ - arg = c->dwarf.as_arg; - - /* Check if return address points at sigreturn sequence. - on ppc64 Linux that is (see libc.so): - 0x38210080 addi r1, r1, 128 // pop the stack - 0x380000ac li r0, 172 // invoke system service 172 - 0x44000002 sc - */ - - ip = c->dwarf.ip; - if (ip == 0) - return 0; - - /* Read up two 8-byte words at the IP. We are only looking at 3 - consecutive 32-bit words, so the second 8-byte word needs to be - shifted right by 32 bits (think big-endian) */ - - a = unw_get_accessors (as); - if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0 - || (ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0) - return 0; - w1 >>= 32; - return (w0 == 0x38210080380000ac && w1 == 0x44000002); - -} Index: libunwind/src/ppc64/Lcreate_addr_space.c =================================================================== --- libunwind/src/ppc64/Lcreate_addr_space.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gcreate_addr_space.c" -#endif Index: libunwind/src/ppc64/Lget_proc_info.c =================================================================== --- libunwind/src/ppc64/Lget_proc_info.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_proc_info.c" -#endif Index: libunwind/src/ppc64/Lget_save_loc.c =================================================================== --- libunwind/src/ppc64/Lget_save_loc.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_save_loc.c" -#endif Index: libunwind/src/ppc64/Linit_local.c =================================================================== --- libunwind/src/ppc64/Linit_local.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_local.c" -#endif Index: libunwind/src/ppc64/Linit_remote.c =================================================================== --- libunwind/src/ppc64/Linit_remote.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_remote.c" -#endif Index: libunwind/src/ppc64/Lis_signal_frame.c =================================================================== --- libunwind/src/ppc64/Lis_signal_frame.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gis_signal_frame.c" -#endif Index: libunwind/src/ppc64/Make-arch.in =================================================================== --- libunwind/src/ppc64/Make-arch.in +++ /dev/null @@ -1,11 +0,0 @@ -# Word size. -ELFW = 64 -# Does use dwarf2 unwind info. -dwarf_target = true - -libunwind_setjmp_OBJS += \ - $(arch)/longjmp.o \ - $(arch)/siglongjmp.o - -libunwind_OBJS_common += \ - $(arch)/is_fpreg.o Index: libunwind/src/ppc64/longjmp.S =================================================================== --- libunwind/src/ppc64/longjmp.S +++ /dev/null @@ -1,31 +0,0 @@ -/* libunwind - a platform-independent unwind library - - Copied from src/x86_64/, modified slightly (or made empty stubs) for - building frysk successfully on ppc64, by Wu Zhou - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - - .globl _UI_longjmp_cont - - .type _UI_longjmp_cont, @function -_UI_longjmp_cont: - .size _UI_longjmp_cont, .-_UI_longjmp_cont Index: libunwind/src/ppc64/siglongjmp.S =================================================================== --- libunwind/src/ppc64/siglongjmp.S +++ /dev/null @@ -1,26 +0,0 @@ -/* libunwind - a platform-independent unwind library - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - - .globl _UI_siglongjmp_cont - - _UI_siglongjmp_cont: Index: libunwind/src/ptrace/_UPT_reg_offset.c =================================================================== --- libunwind/src/ptrace/_UPT_reg_offset.c +++ libunwind/src/ptrace/_UPT_reg_offset.c @@ -286,6 +286,7 @@ int _UPT_reg_offset[UNW_REG_LAST + 1] = // [UNW_X86_64_EFLAGS] = 0x90, // [UNW_X86_64_RSP] = 0x98, // [UNW_X86_64_SS] = 0xa0 +#elif defined(UNW_TARGET_PPC32) #elif defined(UNW_TARGET_PPC64) #else # error Fix me. Index: libunwind/src/ppc64/init.h =================================================================== --- libunwind/src/ppc64/init.h +++ libunwind/src/ppc64/init.h @@ -28,7 +28,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DE #include "unwind_i.h" static inline int -common_init (struct cursor *c) +common_init_ppc64 (struct cursor *c) { int ret; int i; @@ -67,7 +67,7 @@ common_init (struct cursor *c) if (ret < 0) return ret; - c->sigcontext_format = PPC64_SCF_NONE; + c->sigcontext_format = PPC_SCF_NONE; c->sigcontext_addr = 0; c->dwarf.args_size = 0; Index: libunwind/tests/flush-cache.S =================================================================== --- libunwind/tests/flush-cache.S +++ libunwind/tests/flush-cache.S @@ -47,7 +47,17 @@ flush_cache: bv %r0(%rp) .procend #elif defined(__powerpc64__) -# warning IMPLEMENT ME!! +# warning IMPLEMENT ME FOR PPC64!! + .globl flush_cache +flush_cache: + lwz 11, 0(1) ; + lwz 0, 4(11) ; + mtlr 0 ; + lwz 31, -4(11) ; + mr 1, 11 ; + blr +#elif defined(__powerpc__) +# warning IMPLEMENT ME FOR PPC32!! .globl flush_cache flush_cache: lwz 11, 0(1) ; Index: libunwind/include/tdep-ppc64/libunwind_i.h =================================================================== --- libunwind/include/tdep-ppc64/libunwind_i.h +++ libunwind/include/tdep-ppc64/libunwind_i.h @@ -65,8 +65,8 @@ struct cursor stored: */ enum { - PPC64_SCF_NONE, /* no signal frame encountered */ - PPC64_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */ + PPC_SCF_NONE, /* no signal frame encountered */ + PPC_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */ } sigcontext_format; unw_word_t sigcontext_addr; Index: libunwind/src/ppc64/Gstep.c =================================================================== --- libunwind/src/ppc64/Gstep.c +++ libunwind/src/ppc64/Gstep.c @@ -137,7 +137,7 @@ unw_step (unw_cursor_t * cursor) Debug (1, "signal frame, skip over trampoline\n"); - c->sigcontext_format = PPC64_SCF_LINUX_RT_SIGFRAME; + c->sigcontext_format = PPC_SCF_LINUX_RT_SIGFRAME; c->sigcontext_addr = ucontext; sp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0); Index: libunwind/Makefile.am =================================================================== --- libunwind/Makefile.am +++ libunwind/Makefile.am @@ -10,9 +10,13 @@ else if ARCH_X86_64 include_HEADERS_tdep = include/libunwind-x86_64.h else +if ARCH_PPC32 +include_HEADERS_tdep = include/libunwind-ppc32.h +else if ARCH_PPC64 include_HEADERS_tdep = include/libunwind-ppc64.h endif # ARCH_PPC64 +endif # ARCH_PPC32 endif # ARCH_X86_64 endif # ARCH_X86 endif # ARCH_HPPA @@ -46,6 +50,7 @@ EXTRA_DIST = include/dwarf.h include/dwa include/libunwind-x86_64.h include/tdep-x86_64/libunwind_i.h \ include/tdep-x86_64/jmpbuf.h include/tdep-x86_64/dwarf-config.h \ include/libunwind-ppc64.h include/tdep-ppc64/dwarf-config.h \ + include/tdep-ppc32/jmpbuf.h include/tdep-ppc32/libunwind_i.h \ include/tdep-ppc64/jmpbuf.h include/tdep-ppc64/libunwind_i.h DISTCLEANFILES = include/libunwind.h include/tdep