1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-22 07:37:38 +01:00

Add PPC64 support.

This commit is contained in:
Jose Flavio Aguilar Paulino 2007-08-02 09:59:43 -06:00 committed by David Mosberger-Tang
parent a6393c0be1
commit b33021e4b2
43 changed files with 2900 additions and 3 deletions

View file

@ -9,6 +9,10 @@ include_HEADERS_tdep = include/libunwind-x86.h
else
if ARCH_X86_64
include_HEADERS_tdep = include/libunwind-x86_64.h
else
if ARCH_PPC64
include_HEADERS_tdep = include/libunwind-ppc64.h
endif # ARCH_PPC64
endif # ARCH_X86_64
endif # ARCH_X86
endif # ARCH_HPPA
@ -40,6 +44,8 @@ EXTRA_DIST = include/dwarf.h include/dwarf_i.h include/dwarf-eh.h \
include/libunwind-x86.h include/tdep-x86/libunwind_i.h \
include/tdep-x86/jmpbuf.h include/tdep-x86/dwarf-config.h \
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/tdep-x86_64/jmpbuf.h include/tdep-x86_64/dwarf-config.h \
include/libunwind-ppc64.h include/tdep-ppc64/dwarf-config.h \
include/tdep-ppc64/jmpbuf.h include/tdep-ppc64/libunwind_i.h
DISTCLEANFILES = include/libunwind.h include/tdep

View file

@ -56,11 +56,18 @@ AC_FUNC_MEMCMP
AC_TYPE_SIGNAL
AC_CHECK_FUNCS(dl_iterate_phdr dl_phdr_removals_counter dlmodinfo getunwind \
ttrace)
is_gcc_m64() {
if test `echo $CFLAGS | grep "\-m64" -c` -eq 1 ; then echo ppc64;
else
if test `echo $CC | grep "\-m64" -c` -eq 1 ; then echo ppc64; else echo ppc32; fi;
fi;
}
get_arch() {
case "$1" in
i?86) echo x86;;
hppa*) echo hppa;;
powerpc64) is_gcc_m64;;
*) echo $1;;
esac
}
@ -73,6 +80,8 @@ AM_CONDITIONAL(ARCH_IA64, test x$target_arch = xia64)
AM_CONDITIONAL(ARCH_HPPA, test x$target_arch = xhppa)
AM_CONDITIONAL(ARCH_X86, test x$target_arch = xx86)
AM_CONDITIONAL(ARCH_X86_64, test x$target_arch = xx86_64)
AM_CONDITIONAL(ARCH_PPC32, test x$target_arch = xppc32)
AM_CONDITIONAL(ARCH_PPC64, test x$target_arch = xppc64)
AM_CONDITIONAL(OS_LINUX, expr x$target_os : xlinux >/dev/null)
AM_CONDITIONAL(OS_HPUX, expr x$target_os : xhpux >/dev/null)

264
include/libunwind-ppc64.h Normal file
View file

@ -0,0 +1,264 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2006-2007 IBM
Contributed by
Corey Ashford <cjashfor@us.ibm.com>
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
Copied from libunwind-x86_64.h, modified slightly for building
frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
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 <inttypes.h>
#include <ucontext.h>
#define UNW_TARGET ppc64
#define UNW_TARGET_PPC64 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_PPC64_* 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;
/*
* Vector register (in PowerPC64 used for AltiVec registers)
*/
typedef struct {
uint64_t halves[2];
} unw_tdep_vreg_t;
typedef enum
{
UNW_PPC64_R0,
UNW_PPC64_R1, /* called STACK_POINTER in gcc */
UNW_PPC64_R2,
UNW_PPC64_R3,
UNW_PPC64_R4,
UNW_PPC64_R5,
UNW_PPC64_R6,
UNW_PPC64_R7,
UNW_PPC64_R8,
UNW_PPC64_R9,
UNW_PPC64_R10,
UNW_PPC64_R11, /* called STATIC_CHAIN in gcc */
UNW_PPC64_R12,
UNW_PPC64_R13,
UNW_PPC64_R14,
UNW_PPC64_R15,
UNW_PPC64_R16,
UNW_PPC64_R17,
UNW_PPC64_R18,
UNW_PPC64_R19,
UNW_PPC64_R20,
UNW_PPC64_R21,
UNW_PPC64_R22,
UNW_PPC64_R23,
UNW_PPC64_R24,
UNW_PPC64_R25,
UNW_PPC64_R26,
UNW_PPC64_R27,
UNW_PPC64_R28,
UNW_PPC64_R29,
UNW_PPC64_R30,
UNW_PPC64_R31, /* called HARD_FRAME_POINTER in gcc */
UNW_PPC64_F0 = 32,
UNW_PPC64_F1,
UNW_PPC64_F2,
UNW_PPC64_F3,
UNW_PPC64_F4,
UNW_PPC64_F5,
UNW_PPC64_F6,
UNW_PPC64_F7,
UNW_PPC64_F8,
UNW_PPC64_F9,
UNW_PPC64_F10,
UNW_PPC64_F11,
UNW_PPC64_F12,
UNW_PPC64_F13,
UNW_PPC64_F14,
UNW_PPC64_F15,
UNW_PPC64_F16,
UNW_PPC64_F17,
UNW_PPC64_F18,
UNW_PPC64_F19,
UNW_PPC64_F20,
UNW_PPC64_F21,
UNW_PPC64_F22,
UNW_PPC64_F23,
UNW_PPC64_F24,
UNW_PPC64_F25,
UNW_PPC64_F26,
UNW_PPC64_F27,
UNW_PPC64_F28,
UNW_PPC64_F29,
UNW_PPC64_F30,
UNW_PPC64_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_PPC64_LR = 65,
UNW_PPC64_CTR = 66,
UNW_PPC64_ARG_POINTER = 67,
UNW_PPC64_CR0 = 68,
UNW_PPC64_CR1,
UNW_PPC64_CR2,
UNW_PPC64_CR3,
UNW_PPC64_CR4,
/* CR5 .. CR7 are currently unused */
UNW_PPC64_CR5,
UNW_PPC64_CR6,
UNW_PPC64_CR7,
UNW_PPC64_XER = 76,
UNW_PPC64_V0 = 77,
UNW_PPC64_V1,
UNW_PPC64_V2,
UNW_PPC64_V3,
UNW_PPC64_V4,
UNW_PPC64_V5,
UNW_PPC64_V6,
UNW_PPC64_V7,
UNW_PPC64_V8,
UNW_PPC64_V9,
UNW_PPC64_V10,
UNW_PPC64_V11,
UNW_PPC64_V12,
UNW_PPC64_V13,
UNW_PPC64_V14,
UNW_PPC64_V15,
UNW_PPC64_V16,
UNW_PPC64_V17,
UNW_PPC64_V18,
UNW_PPC64_V19,
UNW_PPC64_V20,
UNW_PPC64_V21,
UNW_PPC64_V22,
UNW_PPC64_V23,
UNW_PPC64_V24,
UNW_PPC64_V25,
UNW_PPC64_V26,
UNW_PPC64_V27,
UNW_PPC64_V28,
UNW_PPC64_V29,
UNW_PPC64_V30,
UNW_PPC64_V31,
UNW_PPC64_VRSAVE = 109,
UNW_PPC64_VSCR = 110,
UNW_PPC64_SPE_ACC = 111,
UNW_PPC64_SPEFSCR = 112,
/* frame info (read-only) */
UNW_PPC64_FRAME_POINTER,
UNW_PPC64_NIP,
UNW_TDEP_LAST_REG = UNW_PPC64_NIP,
UNW_TDEP_IP = UNW_PPC64_NIP,
UNW_TDEP_SP = UNW_PPC64_R1,
UNW_TDEP_EH = UNW_PPC64_R12
}
ppc64_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 ppc64, 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 ppc64-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 */

View file

@ -0,0 +1,56 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2006-2007 IBM
Contributed by
Corey Ashford <cjashfor@us.ibm.com>
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
Copied from libunwind-x86_64.h, modified slightly for building
frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
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 */

View file

@ -0,0 +1,37 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2006-2007 IBM
Contributed by
Corey Ashford <cjashfor@us.ibm.com>
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
Copied from libunwind-x86_64.h, modified slightly for building
frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
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

View file

@ -0,0 +1,297 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2006-2007 IBM
Contributed by
Corey Ashford <cjashfor@us.ibm.com>
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
Copied from libunwind-x86_64.h, modified slightly for building
frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
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 PPC64_LIBUNWIND_I_H
#define PPC64_LIBUNWIND_I_H
/* Target-dependent definitions that are internal to libunwind but need
to be shared with target-independent code. */
#include <stdlib.h>
#include <libunwind.h>
#include "elf64.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
{
PPC64_SCF_NONE, /* no signal frame encountered */
PPC64_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_access_vreg UNW_OBJ(access_vreg)
#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);
#endif /* PPC64_LIBUNWIND_I_H */

View file

@ -38,6 +38,7 @@ libunwind_setjmp_la_SOURCES_ia64 = ia64/setjmp.S ia64/sigsetjmp.S \
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:
@ -203,6 +204,34 @@ libunwind_x86_64_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common) \
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 files that go both into libunwind and libunwind-ppc64:
libunwind_la_SOURCES_ppc64_common = $(libunwind_la_SOURCES_common) \
$(dwarf_SOURCES_common) \
elf64.c elf64.h \
ppc64/init.h ppc64/unwind_i.h ppc64/ucontext_i.h \
ppc64/is_fpreg.c ppc64/regname.c
# The list of files that go into libunwind:
libunwind_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \
$(libunwind_la_SOURCES_local) \
$(dwarf_SOURCES_local) \
dwarf/Lfind_proc_info-lsb.c \
ppc64/Lglobal.c ppc64/Linit.c ppc64/Linit_local.c \
ppc64/Lis_signal_frame.c ppc64/Lget_proc_info.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) \
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
if REMOTE_ONLY
install-exec-hook:
# Nothing to do here....
@ -283,6 +312,20 @@ if !REMOTE_ONLY
endif
libunwind_setjmp_la_SOURCES = $(libunwind_setjmp_la_SOURCES_common) \
$(libunwind_setjmp_la_SOURCES_x86_64)
else
if ARCH_PPC64
lib_LTLIBRARIES_arch = libunwind-ppc64.la
libunwind_la_SOURCES = $(libunwind_la_SOURCES_ppc64)
libunwind_ppc64_la_SOURCES = $(libunwind_ppc64_la_SOURCES_ppc64)
libunwind_ppc64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION)
if !REMOTE_ONLY
libunwind_ppc64_la_LIBADD = libunwind.la -lc
endif
libunwind_setjmp_la_SOURCES = $(libunwind_setjmp_la_SOURCES_common) \
$(libunwind_setjmp_la_SOURCES_ppc64)
endif # ARCH_PPC64
endif # ARCH_X86_64
endif # ARCH_X86
endif # ARCH_HPPA
@ -321,7 +364,9 @@ EXTRA_DIST = elfxx.h elfxx.c unwind/unwind-internal.h \
$(libunwind_setjmp_la_SOURCES_hppa) \
$(libunwind_setjmp_la_SOURCES_ia64) \
$(libunwind_setjmp_la_SOURCES_x86) \
$(libunwind_setjmp_la_SOURCES_x86_64)
$(libunwind_setjmp_la_SOURCES_x86_64) \
$(libunwind_setjmp_la_SOURCES_ppc64)
# The -version-info flag accepts an argument of the form
# `current[:revision[:age]]'. So, passing `-version-info 3:12:1' sets

View file

@ -0,0 +1,54 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2006-2007 IBM
Contributed by
Corey Ashford <cjashfor@us.ibm.com>
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
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 <stdlib.h>
#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
}

View file

@ -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 <woodzltc@cn.ibm.com>
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;
}

34
src/ppc64/Gget_save_loc.c Normal file
View file

@ -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 <woodzltc@cn.ibm.com>
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;
}

184
src/ppc64/Gglobal.c Normal file
View file

@ -0,0 +1,184 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2006-2007 IBM
Contributed by
Corey Ashford <cjashfor@us.ibm.com>
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
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 ppc64_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_PPC64_R0]=UNW_PPC64_R0,
[UNW_PPC64_R1]=UNW_PPC64_R1,
[UNW_PPC64_R2]=UNW_PPC64_R2,
[UNW_PPC64_R3]=UNW_PPC64_R3,
[UNW_PPC64_R4]=UNW_PPC64_R4,
[UNW_PPC64_R5]=UNW_PPC64_R5,
[UNW_PPC64_R6]=UNW_PPC64_R6,
[UNW_PPC64_R7]=UNW_PPC64_R7,
[UNW_PPC64_R8]=UNW_PPC64_R8,
[UNW_PPC64_R9]=UNW_PPC64_R9,
[UNW_PPC64_R10]=UNW_PPC64_R10,
[UNW_PPC64_R11]=UNW_PPC64_R11,
[UNW_PPC64_R12]=UNW_PPC64_R12,
[UNW_PPC64_R13]=UNW_PPC64_R13,
[UNW_PPC64_R14]=UNW_PPC64_R14,
[UNW_PPC64_R15]=UNW_PPC64_R15,
[UNW_PPC64_R16]=UNW_PPC64_R16,
[UNW_PPC64_R17]=UNW_PPC64_R17,
[UNW_PPC64_R18]=UNW_PPC64_R18,
[UNW_PPC64_R19]=UNW_PPC64_R19,
[UNW_PPC64_R20]=UNW_PPC64_R20,
[UNW_PPC64_R21]=UNW_PPC64_R21,
[UNW_PPC64_R22]=UNW_PPC64_R22,
[UNW_PPC64_R23]=UNW_PPC64_R23,
[UNW_PPC64_R24]=UNW_PPC64_R24,
[UNW_PPC64_R25]=UNW_PPC64_R25,
[UNW_PPC64_R26]=UNW_PPC64_R26,
[UNW_PPC64_R27]=UNW_PPC64_R27,
[UNW_PPC64_R28]=UNW_PPC64_R28,
[UNW_PPC64_R29]=UNW_PPC64_R29,
[UNW_PPC64_R30]=UNW_PPC64_R30,
[UNW_PPC64_R31]=UNW_PPC64_R31,
[UNW_PPC64_F0]=UNW_PPC64_F0,
[UNW_PPC64_F1]=UNW_PPC64_F1,
[UNW_PPC64_F2]=UNW_PPC64_F2,
[UNW_PPC64_F3]=UNW_PPC64_F3,
[UNW_PPC64_F4]=UNW_PPC64_F4,
[UNW_PPC64_F5]=UNW_PPC64_F5,
[UNW_PPC64_F6]=UNW_PPC64_F6,
[UNW_PPC64_F7]=UNW_PPC64_F7,
[UNW_PPC64_F8]=UNW_PPC64_F8,
[UNW_PPC64_F9]=UNW_PPC64_F9,
[UNW_PPC64_F10]=UNW_PPC64_F10,
[UNW_PPC64_F11]=UNW_PPC64_F11,
[UNW_PPC64_F12]=UNW_PPC64_F12,
[UNW_PPC64_F13]=UNW_PPC64_F13,
[UNW_PPC64_F14]=UNW_PPC64_F14,
[UNW_PPC64_F15]=UNW_PPC64_F15,
[UNW_PPC64_F16]=UNW_PPC64_F16,
[UNW_PPC64_F17]=UNW_PPC64_F17,
[UNW_PPC64_F18]=UNW_PPC64_F18,
[UNW_PPC64_F19]=UNW_PPC64_F19,
[UNW_PPC64_F20]=UNW_PPC64_F20,
[UNW_PPC64_F21]=UNW_PPC64_F21,
[UNW_PPC64_F22]=UNW_PPC64_F22,
[UNW_PPC64_F23]=UNW_PPC64_F23,
[UNW_PPC64_F24]=UNW_PPC64_F24,
[UNW_PPC64_F25]=UNW_PPC64_F25,
[UNW_PPC64_F26]=UNW_PPC64_F26,
[UNW_PPC64_F27]=UNW_PPC64_F27,
[UNW_PPC64_F28]=UNW_PPC64_F28,
[UNW_PPC64_F29]=UNW_PPC64_F29,
[UNW_PPC64_F30]=UNW_PPC64_F30,
[UNW_PPC64_F31]=UNW_PPC64_F31,
[UNW_PPC64_LR]=UNW_PPC64_LR,
[UNW_PPC64_CTR]=UNW_PPC64_CTR,
[UNW_PPC64_ARG_POINTER]=UNW_PPC64_ARG_POINTER,
[UNW_PPC64_CR0]=UNW_PPC64_CR0,
[UNW_PPC64_CR1]=UNW_PPC64_CR1,
[UNW_PPC64_CR2]=UNW_PPC64_CR2,
[UNW_PPC64_CR3]=UNW_PPC64_CR3,
[UNW_PPC64_CR4]=UNW_PPC64_CR4,
[UNW_PPC64_CR5]=UNW_PPC64_CR5,
[UNW_PPC64_CR6]=UNW_PPC64_CR6,
[UNW_PPC64_CR7]=UNW_PPC64_CR7,
[UNW_PPC64_XER]=UNW_PPC64_XER,
[UNW_PPC64_V0]=UNW_PPC64_V0,
[UNW_PPC64_V1]=UNW_PPC64_V1,
[UNW_PPC64_V2]=UNW_PPC64_V2,
[UNW_PPC64_V3]=UNW_PPC64_V3,
[UNW_PPC64_V4]=UNW_PPC64_V4,
[UNW_PPC64_V5]=UNW_PPC64_V5,
[UNW_PPC64_V6]=UNW_PPC64_V6,
[UNW_PPC64_V7]=UNW_PPC64_V7,
[UNW_PPC64_V8]=UNW_PPC64_V8,
[UNW_PPC64_V9]=UNW_PPC64_V9,
[UNW_PPC64_V10]=UNW_PPC64_V10,
[UNW_PPC64_V11]=UNW_PPC64_V11,
[UNW_PPC64_V12]=UNW_PPC64_V12,
[UNW_PPC64_V13]=UNW_PPC64_V13,
[UNW_PPC64_V14]=UNW_PPC64_V14,
[UNW_PPC64_V15]=UNW_PPC64_V15,
[UNW_PPC64_V16]=UNW_PPC64_V16,
[UNW_PPC64_V17]=UNW_PPC64_V17,
[UNW_PPC64_V18]=UNW_PPC64_V18,
[UNW_PPC64_V19]=UNW_PPC64_V19,
[UNW_PPC64_V20]=UNW_PPC64_V20,
[UNW_PPC64_V21]=UNW_PPC64_V21,
[UNW_PPC64_V22]=UNW_PPC64_V22,
[UNW_PPC64_V23]=UNW_PPC64_V23,
[UNW_PPC64_V24]=UNW_PPC64_V24,
[UNW_PPC64_V25]=UNW_PPC64_V25,
[UNW_PPC64_V26]=UNW_PPC64_V26,
[UNW_PPC64_V27]=UNW_PPC64_V27,
[UNW_PPC64_V28]=UNW_PPC64_V28,
[UNW_PPC64_V29]=UNW_PPC64_V29,
[UNW_PPC64_V30]=UNW_PPC64_V30,
[UNW_PPC64_V31]=UNW_PPC64_V31,
[UNW_PPC64_VRSAVE]=UNW_PPC64_VRSAVE,
[UNW_PPC64_VSCR]=UNW_PPC64_VSCR,
[UNW_PPC64_SPE_ACC]=UNW_PPC64_SPE_ACC,
[UNW_PPC64_SPEFSCR]=UNW_PPC64_SPEFSCR,
};
HIDDEN void
tdep_init (void)
{
intrmask_t saved_mask;
sigfillset (&unwi_full_mask);
sigprocmask (SIG_SETMASK, &unwi_full_mask, &saved_mask);
mutex_lock (&ppc64_lock);
{
if (!tdep_needs_initialization)
/* another thread else beat us to it... */
goto out;
mi_init ();
dwarf_init ();
#ifndef UNW_REMOTE_ONLY
ppc64_local_addr_space_init ();
#endif
tdep_needs_initialization = 0; /* signal that we're initialized... */
}
out:
mutex_unlock (&ppc64_lock);
sigprocmask (SIG_SETMASK, &saved_mask, NULL);
}

230
src/ppc64/Ginit.c Normal file
View file

@ -0,0 +1,230 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2006-2007 IBM
Contributed by
Corey Ashford <cjashfor@us.ibm.com>
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
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 <stdlib.h>
#include <string.h>
#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_PPC64_R0) < 32)
addr = &uc->uc_mcontext.gp_regs[reg - UNW_PPC64_R0];
else if ((unsigned) (reg - UNW_PPC64_F0) < 32)
addr = &uc->uc_mcontext.fp_regs[reg - UNW_PPC64_F0];
else if ((unsigned) (reg - UNW_PPC64_V0) < 32)
addr = (uc->uc_mcontext.v_regs == 0) ? NULL : &uc->uc_mcontext.v_regs->vrregs[reg - UNW_PPC64_V0][0];
else
{
unsigned gregs_idx;
switch (reg)
{
case UNW_PPC64_NIP:
gregs_idx = NIP_IDX;
break;
case UNW_PPC64_CTR:
gregs_idx = CTR_IDX;
break;
case UNW_PPC64_LR:
gregs_idx = LINK_IDX;
break;
case UNW_PPC64_XER:
gregs_idx = XER_IDX;
break;
case UNW_PPC64_CR0:
gregs_idx = CCR_IDX;
break;
default:
return NULL;
}
addr = &uc->uc_mcontext.gp_regs[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_PPC64_F0) < 32)
goto badreg;
if ((unsigned int) (reg - UNW_PPC64_V0) < 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_PPC64_F0) < 0)
goto badreg;
if ((unsigned) (reg - UNW_PPC64_V0) >= 32)
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 _Uelf64_get_proc_name (getpid (), ip, buf, buf_len, offp);
}
HIDDEN void
ppc64_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 = ppc64_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 */

56
src/ppc64/Ginit_local.c Normal file
View file

@ -0,0 +1,56 @@
/* 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 <woodzltc@cn.ibm.com>
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 */

48
src/ppc64/Ginit_remote.c Normal file
View file

@ -0,0 +1,48 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2006-2007 IBM
Contributed by
Corey Ashford <cjashfor@us.ibm.com>
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
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 */
}

View file

@ -0,0 +1,66 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2006-2007 IBM
Contributed by
Corey Ashford <cjashfor@us.ibm.com>
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
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);
}

100
src/ppc64/Gregs.c Normal file
View file

@ -0,0 +1,100 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2006-2007 IBM
Contributed by
Corey Ashford <cjashfor@us.ibm.com>
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
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_PPC64_F0)) <= 31) ||
(((unsigned) (reg - UNW_PPC64_V0)) <= 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_PPC64_F0) < 32)
{
loc = c->dwarf.loc[reg];
if (write)
return dwarf_putfp (&c->dwarf, loc, *valp);
else
return dwarf_getfp (&c->dwarf, loc, valp);
}
else
if ((unsigned) (reg - UNW_PPC64_V0) < 32)
{
loc = c->dwarf.loc[reg];
if (write)
return dwarf_putvr (&c->dwarf, loc, *valp);
else
return dwarf_getvr (&c->dwarf, loc, valp);
}
return -UNW_EBADREG;
}

77
src/ppc64/Gresume.c Normal file
View file

@ -0,0 +1,77 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2006-2007 IBM
Contributed by
Corey Ashford cjashfor@us.ibm.com
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
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 <stdlib.h>
#include "unwind_i.h"
#ifndef UNW_REMOTE_ONLY
#include <sys/syscall.h>
/* 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
ppc64_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);
}

436
src/ppc64/Gstep.c Normal file
View file

@ -0,0 +1,436 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2006-2007 IBM
Contributed by
Corey Ashford <cjashfor@us.ibm.com>
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
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 <signal.h>
/* 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 = PPC64_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_PPC64_R0] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R0, 0);
c->dwarf.loc[UNW_PPC64_R1] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0);
c->dwarf.loc[UNW_PPC64_R2] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R2, 0);
c->dwarf.loc[UNW_PPC64_R3] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R3, 0);
c->dwarf.loc[UNW_PPC64_R4] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R4, 0);
c->dwarf.loc[UNW_PPC64_R5] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R5, 0);
c->dwarf.loc[UNW_PPC64_R6] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R6, 0);
c->dwarf.loc[UNW_PPC64_R7] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R7, 0);
c->dwarf.loc[UNW_PPC64_R8] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0);
c->dwarf.loc[UNW_PPC64_R9] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0);
c->dwarf.loc[UNW_PPC64_R10] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0);
c->dwarf.loc[UNW_PPC64_R11] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0);
c->dwarf.loc[UNW_PPC64_R12] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0);
c->dwarf.loc[UNW_PPC64_R13] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0);
c->dwarf.loc[UNW_PPC64_R14] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0);
c->dwarf.loc[UNW_PPC64_R15] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0);
c->dwarf.loc[UNW_PPC64_R16] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R16, 0);
c->dwarf.loc[UNW_PPC64_R17] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R17, 0);
c->dwarf.loc[UNW_PPC64_R18] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R18, 0);
c->dwarf.loc[UNW_PPC64_R19] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R19, 0);
c->dwarf.loc[UNW_PPC64_R20] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R20, 0);
c->dwarf.loc[UNW_PPC64_R21] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R21, 0);
c->dwarf.loc[UNW_PPC64_R22] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R22, 0);
c->dwarf.loc[UNW_PPC64_R23] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R23, 0);
c->dwarf.loc[UNW_PPC64_R24] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R24, 0);
c->dwarf.loc[UNW_PPC64_R25] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R25, 0);
c->dwarf.loc[UNW_PPC64_R26] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R26, 0);
c->dwarf.loc[UNW_PPC64_R27] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R27, 0);
c->dwarf.loc[UNW_PPC64_R28] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R28, 0);
c->dwarf.loc[UNW_PPC64_R29] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R29, 0);
c->dwarf.loc[UNW_PPC64_R30] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R30, 0);
c->dwarf.loc[UNW_PPC64_R31] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R31, 0);
c->dwarf.loc[UNW_PPC64_LR] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0);
c->dwarf.loc[UNW_PPC64_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_PPC64_CR0] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CCR, 0);
c->dwarf.loc[UNW_PPC64_XER] =
DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_XER, 0);
c->dwarf.loc[UNW_PPC64_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_PPC64_FRAME_POINTER] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_F0] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R0, 0);
c->dwarf.loc[UNW_PPC64_F1] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R1, 0);
c->dwarf.loc[UNW_PPC64_F2] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R2, 0);
c->dwarf.loc[UNW_PPC64_F3] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R3, 0);
c->dwarf.loc[UNW_PPC64_F4] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R4, 0);
c->dwarf.loc[UNW_PPC64_F5] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R5, 0);
c->dwarf.loc[UNW_PPC64_F6] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R6, 0);
c->dwarf.loc[UNW_PPC64_F7] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R7, 0);
c->dwarf.loc[UNW_PPC64_F8] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R8, 0);
c->dwarf.loc[UNW_PPC64_F9] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R9, 0);
c->dwarf.loc[UNW_PPC64_F10] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R10, 0);
c->dwarf.loc[UNW_PPC64_F11] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R11, 0);
c->dwarf.loc[UNW_PPC64_F12] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R12, 0);
c->dwarf.loc[UNW_PPC64_F13] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R13, 0);
c->dwarf.loc[UNW_PPC64_F14] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R14, 0);
c->dwarf.loc[UNW_PPC64_F15] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R15, 0);
c->dwarf.loc[UNW_PPC64_F16] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R16, 0);
c->dwarf.loc[UNW_PPC64_F17] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R17, 0);
c->dwarf.loc[UNW_PPC64_F18] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R18, 0);
c->dwarf.loc[UNW_PPC64_F19] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R19, 0);
c->dwarf.loc[UNW_PPC64_F20] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R20, 0);
c->dwarf.loc[UNW_PPC64_F21] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R21, 0);
c->dwarf.loc[UNW_PPC64_F22] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R22, 0);
c->dwarf.loc[UNW_PPC64_F23] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R23, 0);
c->dwarf.loc[UNW_PPC64_F24] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R24, 0);
c->dwarf.loc[UNW_PPC64_F25] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R25, 0);
c->dwarf.loc[UNW_PPC64_F26] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R26, 0);
c->dwarf.loc[UNW_PPC64_F27] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R27, 0);
c->dwarf.loc[UNW_PPC64_F28] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R28, 0);
c->dwarf.loc[UNW_PPC64_F29] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R29, 0);
c->dwarf.loc[UNW_PPC64_F30] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R30, 0);
c->dwarf.loc[UNW_PPC64_F31] =
DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R31, 0);
/* Note that there is no .eh_section register column for the
FPSCR register. I don't know why this is. */
v_regs_loc = DWARF_LOC (ucontext + UC_MCONTEXT_V_REGS, 0);
ret = dwarf_get (&c->dwarf, v_regs_loc, &v_regs_ptr);
if (ret < 0)
{
Debug (2, "returning %d\n", ret);
return ret;
}
if (v_regs_ptr != 0)
{
/* The v_regs_ptr is not null. Set all of the AltiVec locs */
c->dwarf.loc[UNW_PPC64_V0] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R0, 0);
c->dwarf.loc[UNW_PPC64_V1] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R1, 0);
c->dwarf.loc[UNW_PPC64_V2] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R2, 0);
c->dwarf.loc[UNW_PPC64_V3] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R3, 0);
c->dwarf.loc[UNW_PPC64_V4] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R4, 0);
c->dwarf.loc[UNW_PPC64_V5] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R5, 0);
c->dwarf.loc[UNW_PPC64_V6] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R6, 0);
c->dwarf.loc[UNW_PPC64_V7] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R7, 0);
c->dwarf.loc[UNW_PPC64_V8] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R8, 0);
c->dwarf.loc[UNW_PPC64_V9] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R9, 0);
c->dwarf.loc[UNW_PPC64_V10] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R10, 0);
c->dwarf.loc[UNW_PPC64_V11] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R11, 0);
c->dwarf.loc[UNW_PPC64_V12] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R12, 0);
c->dwarf.loc[UNW_PPC64_V13] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R13, 0);
c->dwarf.loc[UNW_PPC64_V14] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R14, 0);
c->dwarf.loc[UNW_PPC64_V15] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R15, 0);
c->dwarf.loc[UNW_PPC64_V16] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R16, 0);
c->dwarf.loc[UNW_PPC64_V17] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R17, 0);
c->dwarf.loc[UNW_PPC64_V18] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R18, 0);
c->dwarf.loc[UNW_PPC64_V19] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R19, 0);
c->dwarf.loc[UNW_PPC64_V20] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R20, 0);
c->dwarf.loc[UNW_PPC64_V21] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R21, 0);
c->dwarf.loc[UNW_PPC64_V22] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R22, 0);
c->dwarf.loc[UNW_PPC64_V23] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R23, 0);
c->dwarf.loc[UNW_PPC64_V24] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R24, 0);
c->dwarf.loc[UNW_PPC64_V25] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R25, 0);
c->dwarf.loc[UNW_PPC64_V26] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R26, 0);
c->dwarf.loc[UNW_PPC64_V27] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R27, 0);
c->dwarf.loc[UNW_PPC64_V28] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R28, 0);
c->dwarf.loc[UNW_PPC64_V29] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R29, 0);
c->dwarf.loc[UNW_PPC64_V30] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R30, 0);
c->dwarf.loc[UNW_PPC64_V31] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R31, 0);
c->dwarf.loc[UNW_PPC64_VRSAVE] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_VRSAVE, 0);
c->dwarf.loc[UNW_PPC64_VSCR] =
DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_VSCR, 0);
}
else
{
c->dwarf.loc[UNW_PPC64_V0] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V1] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V2] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V3] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V4] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V5] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V6] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V7] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V8] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V9] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V10] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V11] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V12] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V13] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V14] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V15] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V16] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V17] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V18] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V19] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V20] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V21] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V22] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V23] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V24] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V25] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V26] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V27] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V28] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V29] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V30] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_V31] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_VRSAVE] = DWARF_NULL_LOC;
c->dwarf.loc[UNW_PPC64_VSCR] = DWARF_NULL_LOC;
}
ret = 1;
}
}
return ret;
}

View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Gcreate_addr_space.c"
#endif

View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Gget_proc_info.c"
#endif

View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Gget_save_loc.c"
#endif

5
src/ppc64/Lglobal.c Normal file
View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Gglobal.c"
#endif

5
src/ppc64/Linit.c Normal file
View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Ginit.c"
#endif

5
src/ppc64/Linit_local.c Normal file
View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Ginit_local.c"
#endif

5
src/ppc64/Linit_remote.c Normal file
View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Ginit_remote.c"
#endif

View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Gis_signal_frame.c"
#endif

5
src/ppc64/Lregs.c Normal file
View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Gregs.c"
#endif

5
src/ppc64/Lresume.c Normal file
View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Gresume.c"
#endif

5
src/ppc64/Lstep.c Normal file
View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Gstep.c"
#endif

11
src/ppc64/Make-arch.in Normal file
View file

@ -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

81
src/ppc64/init.h Normal file
View file

@ -0,0 +1,81 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2006-2007 IBM
Contributed by
Corey Ashford <cjashfor@us.ibm.com>
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
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 inline int
common_init (struct cursor *c)
{
int ret;
int i;
for (i = UNW_PPC64_R0; i <= UNW_PPC64_R31; i++) {
c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, i);
}
for (i = UNW_PPC64_F0; i <= UNW_PPC64_F31; i++) {
c->dwarf.loc[i] = DWARF_FPREG_LOC (&c->dwarf, i);
}
for (i = UNW_PPC64_V0; i <= UNW_PPC64_V31; i++) {
c->dwarf.loc[i] = DWARF_VREG_LOC (&c->dwarf, i);
}
for (i = UNW_PPC64_CR0; i <= UNW_PPC64_CR7; i++) {
c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, i);
}
c->dwarf.loc[UNW_PPC64_ARG_POINTER] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_ARG_POINTER);
c->dwarf.loc[UNW_PPC64_CTR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_CTR);
c->dwarf.loc[UNW_PPC64_VSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_VSCR);
c->dwarf.loc[UNW_PPC64_XER] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_XER);
c->dwarf.loc[UNW_PPC64_LR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_LR);
c->dwarf.loc[UNW_PPC64_VRSAVE] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_VRSAVE);
c->dwarf.loc[UNW_PPC64_SPEFSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_SPEFSCR);
c->dwarf.loc[UNW_PPC64_SPE_ACC] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_SPE_ACC);
c->dwarf.loc[UNW_PPC64_NIP] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_NIP);
ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_PPC64_NIP], &c->dwarf.ip);
if (ret < 0)
return ret;
ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_PPC64_R1),
&c->dwarf.cfa);
if (ret < 0)
return ret;
c->sigcontext_format = PPC64_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;
}

34
src/ppc64/is_fpreg.c Normal file
View file

@ -0,0 +1,34 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2006-2007 IBM
Contributed by
Corey Ashford <cjashfor@us.ibm.com>
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
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_PPC64_F0 && regnum <= UNW_PPC64_F31);
}

31
src/ppc64/longjmp.S Normal file
View file

@ -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 <woodzltc@cn.ibm.com>
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

161
src/ppc64/regname.c Normal file
View file

@ -0,0 +1,161 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2006-2007 IBM
Contributed by
Corey Ashford <cjashfor@us.ibm.com>
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
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_PPC64_R0]="GPR0",
[UNW_PPC64_R1]="GPR1",
[UNW_PPC64_R2]="GPR2",
[UNW_PPC64_R3]="GPR3",
[UNW_PPC64_R4]="GPR4",
[UNW_PPC64_R5]="GPR5",
[UNW_PPC64_R6]="GPR6",
[UNW_PPC64_R7]="GPR7",
[UNW_PPC64_R8]="GPR8",
[UNW_PPC64_R9]="GPR9",
[UNW_PPC64_R10]="GPR10",
[UNW_PPC64_R11]="GPR11",
[UNW_PPC64_R12]="GPR12",
[UNW_PPC64_R13]="GPR13",
[UNW_PPC64_R14]="GPR14",
[UNW_PPC64_R15]="GPR15",
[UNW_PPC64_R16]="GPR16",
[UNW_PPC64_R17]="GPR17",
[UNW_PPC64_R18]="GPR18",
[UNW_PPC64_R19]="GPR19",
[UNW_PPC64_R20]="GPR20",
[UNW_PPC64_R21]="GPR21",
[UNW_PPC64_R22]="GPR22",
[UNW_PPC64_R23]="GPR23",
[UNW_PPC64_R24]="GPR24",
[UNW_PPC64_R25]="GPR25",
[UNW_PPC64_R26]="GPR26",
[UNW_PPC64_R27]="GPR27",
[UNW_PPC64_R28]="GPR28",
[UNW_PPC64_R29]="GPR29",
[UNW_PPC64_R30]="GPR30",
[UNW_PPC64_R31]="GPR31",
[UNW_PPC64_F0]="FPR0",
[UNW_PPC64_F1]="FPR1",
[UNW_PPC64_F2]="FPR2",
[UNW_PPC64_F3]="FPR3",
[UNW_PPC64_F4]="FPR4",
[UNW_PPC64_F5]="FPR5",
[UNW_PPC64_F6]="FPR6",
[UNW_PPC64_F7]="FPR7",
[UNW_PPC64_F8]="FPR8",
[UNW_PPC64_F9]="FPR9",
[UNW_PPC64_F10]="FPR10",
[UNW_PPC64_F11]="FPR11",
[UNW_PPC64_F12]="FPR12",
[UNW_PPC64_F13]="FPR13",
[UNW_PPC64_F14]="FPR14",
[UNW_PPC64_F15]="FPR15",
[UNW_PPC64_F16]="FPR16",
[UNW_PPC64_F17]="FPR17",
[UNW_PPC64_F18]="FPR18",
[UNW_PPC64_F19]="FPR19",
[UNW_PPC64_F20]="FPR20",
[UNW_PPC64_F21]="FPR21",
[UNW_PPC64_F22]="FPR22",
[UNW_PPC64_F23]="FPR23",
[UNW_PPC64_F24]="FPR24",
[UNW_PPC64_F25]="FPR25",
[UNW_PPC64_F26]="FPR26",
[UNW_PPC64_F27]="FPR27",
[UNW_PPC64_F28]="FPR28",
[UNW_PPC64_F29]="FPR29",
[UNW_PPC64_F30]="FPR30",
[UNW_PPC64_F31]="FPR31",
[UNW_PPC64_LR]="LR",
[UNW_PPC64_CTR]="CTR",
[UNW_PPC64_ARG_POINTER]="ARG_POINTER",
[UNW_PPC64_CR0]="CR0",
[UNW_PPC64_CR1]="CR1",
[UNW_PPC64_CR2]="CR2",
[UNW_PPC64_CR3]="CR3",
[UNW_PPC64_CR4]="CR4",
[UNW_PPC64_CR5]="CR5",
[UNW_PPC64_CR6]="CR6",
[UNW_PPC64_CR7]="CR7",
[UNW_PPC64_XER]="XER",
[UNW_PPC64_V0]="VR0",
[UNW_PPC64_V1]="VR1",
[UNW_PPC64_V2]="VR2",
[UNW_PPC64_V3]="VR3",
[UNW_PPC64_V4]="VR4",
[UNW_PPC64_V5]="VR5",
[UNW_PPC64_V6]="VR6",
[UNW_PPC64_V7]="VR7",
[UNW_PPC64_V8]="VR8",
[UNW_PPC64_V9]="VR9",
[UNW_PPC64_V10]="VR10",
[UNW_PPC64_V11]="VR11",
[UNW_PPC64_V12]="VR12",
[UNW_PPC64_V13]="VR13",
[UNW_PPC64_V14]="VR14",
[UNW_PPC64_V15]="VR15",
[UNW_PPC64_V16]="VR16",
[UNW_PPC64_V17]="VR17",
[UNW_PPC64_V18]="VR18",
[UNW_PPC64_V19]="VR19",
[UNW_PPC64_V20]="VR20",
[UNW_PPC64_V21]="VR21",
[UNW_PPC64_V22]="VR22",
[UNW_PPC64_V23]="VR23",
[UNW_PPC64_V24]="VR24",
[UNW_PPC64_V25]="VR25",
[UNW_PPC64_V26]="VR26",
[UNW_PPC64_V27]="VR27",
[UNW_PPC64_V28]="VR28",
[UNW_PPC64_V29]="VR29",
[UNW_PPC64_V30]="VR30",
[UNW_PPC64_V31]="VR31",
[UNW_PPC64_VSCR]="VSCR",
[UNW_PPC64_VRSAVE]="VRSAVE",
[UNW_PPC64_SPE_ACC]="SPE_ACC",
[UNW_PPC64_SPEFSCR]="SPEFSCR",
};
PROTECTED const char *
unw_regname (unw_regnum_t reg)
{
if (reg < (unw_regnum_t) ARRAY_SIZE (regname))
return regname[reg];
else
return "???";
}

4
src/ppc64/setcontext.S Normal file
View file

@ -0,0 +1,4 @@
.global _UI_setcontext
_UI_setcontext:
retq

25
src/ppc64/siglongjmp.S Normal file
View file

@ -0,0 +1,25 @@
/* 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

173
src/ppc64/ucontext_i.h Normal file
View file

@ -0,0 +1,173 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2006-2007 IBM
Contributed by
Corey Ashford <cjashfor@us.ibm.com>
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
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 <ucontext.h>
/* 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.gp_regs[0] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[1] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[2] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[3] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[4] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[5] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[6] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[7] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[8] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[9] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[10] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[11] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[12] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[13] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[14] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[15] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[16] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[17] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[18] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[19] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[20] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[21] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[22] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[23] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[24] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[25] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[26] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[27] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[28] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[29] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[30] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[31] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_NIP ((void *)&dmy_ctxt.uc_mcontext.gp_regs[NIP_IDX] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_MSR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[MSR_IDX] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_ORIG_GPR3 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[ORIG_GPR3_IDX] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_CTR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[CTR_IDX] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_LINK ((void *)&dmy_ctxt.uc_mcontext.gp_regs[LINK_IDX] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_XER ((void *)&dmy_ctxt.uc_mcontext.gp_regs[XER_IDX] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_CCR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[CCR_IDX] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_SOFTE ((void *)&dmy_ctxt.uc_mcontext.gp_regs[SOFTE_IDX] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_TRAP ((void *)&dmy_ctxt.uc_mcontext.gp_regs[TRAP_IDX] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_DAR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[DAR_IDX] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_DSISR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[DSISR_IDX] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_GREGS_RESULT ((void *)&dmy_ctxt.uc_mcontext.gp_regs[RESULT_IDX] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[0] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[1] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[2] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[3] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[4] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[5] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[6] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[7] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[8] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[9] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[10] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[11] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[12] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[13] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[14] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[15] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[16] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[17] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[18] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[19] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[20] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[21] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[22] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[23] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[24] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[25] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[26] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[27] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[28] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[29] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[30] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[31] - (void *)&dmy_ctxt)
#define UC_MCONTEXT_FREGS_FPSCR ((void *)&dmy_ctxt.uc_mcontext.fp_regs[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

53
src/ppc64/unwind_i.h Normal file
View file

@ -0,0 +1,53 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2006-2007 IBM
Contributed by
Corey Ashford <cjashfor@us.ibm.com>
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
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 <memory.h>
#include <stdint.h>
#include <libunwind-ppc64.h>
#include <libunwind_i.h>
#include <sys/ucontext.h>
#define ppc64_lock UNW_OBJ(lock)
#define ppc64_local_resume UNW_OBJ(local_resume)
#define ppc64_local_addr_space_init UNW_OBJ(local_addr_space_init)
#if 0
#define ppc64_scratch_loc UNW_OBJ(scratch_loc)
#endif
extern void ppc64_local_addr_space_init (void);
extern int ppc64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
void *arg);
#if 0
extern dwarf_loc_t ppc64_scratch_loc (struct cursor *c, unw_regnum_t reg);
#endif
#endif /* unwind_i_h */

View file

@ -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_PPC64)
#else
# error Fix me.
#endif

View file

@ -25,7 +25,11 @@ if ARCH_IA64
Gia64-test-rbs Lia64-test-rbs \
Gia64-test-readonly Lia64-test-readonly \
ia64-test-setjmp ia64-test-sig
endif
else
if ARCH_PPC64
noinst_PROGRAMS_arch = ppc64-test-altivec ppc64-test-wchar
endif #ARCH_PPC64
endif #ARCH_IA64
check_SCRIPTS_cdep = run-ptrace-mapper run-ptrace-misc
check_PROGRAMS_cdep = Gtest-bt Ltest-bt Gtest-exc Ltest-exc \
Gtest-init Ltest-init \
@ -69,6 +73,8 @@ Gia64_test_rbs_SOURCES = Gia64-test-rbs.c ia64-test-rbs-asm.S ia64-test-rbs.h
Lia64_test_nat_SOURCES = Lia64-test-nat.c ia64-test-nat-asm.S
Gia64_test_nat_SOURCES = Gia64-test-nat.c ia64-test-nat-asm.S
ia64_test_dyn1_SOURCES = ia64-test-dyn1.c ia64-dyn-asm.S flush-cache.S
ppc64_test_altivec_SOURCES = ppc64-test-altivec.c ppc64-test-altivec-utils.c
ppc64_test_wchar_SOURCES = ppc64-test-wchar.c
Gtest_init_SOURCES = Gtest-init.cxx
Ltest_init_SOURCES = Ltest-init.cxx
Gtest_dyn1_SOURCES = Gtest-dyn1.c flush-cache.S

View file

@ -0,0 +1,32 @@
#include <stdio.h>
#include <altivec.h>
union si_overlay
{
vector signed int v;
int ints[4];
};
vector signed int
vec_init ()
{
vector signed int v;
static int count = 1;
((union si_overlay *) &v)->ints[0] = count++;
((union si_overlay *) &v)->ints[1] = count++;
((union si_overlay *) &v)->ints[2] = count++;
((union si_overlay *) &v)->ints[3] = count++;
return v;
}
void
vec_print (vector signed int v)
{
printf ("%08x %08x %08x %08x",
((union si_overlay *) &v)->ints[0],
((union si_overlay *) &v)->ints[1],
((union si_overlay *) &v)->ints[2],
((union si_overlay *) &v)->ints[3]);
}

177
tests/ppc64-test-altivec.c Normal file
View file

@ -0,0 +1,177 @@
#include <libunwind.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <altivec.h>
#include <sys/resource.h>
#define panic(args...) { fprintf (stderr, args); abort(); }
extern vector signed int vec_init ();
extern void vec_print (vector signed int v);
vector signed int vec_stack (int count);
int
main ()
{
printf ("&vec_stack = %016lx\n", (unsigned long) vec_stack);
vec_stack (3);
return 0;
}
vector signed int
vec_stack (int count)
{
register vector signed int v1;
register vector signed int v2;
register vector signed int v3;
register vector signed int v4;
register vector signed int v5;
register vector signed int v6;
register vector signed int v7;
register vector signed int v8;
register vector signed int v9;
unw_fpreg_t vr;
unw_cursor_t cursor;
unw_word_t ip, sp;
unw_context_t uc;
int ret;
int verbose = 1;
/* if (count == 0) return vec_init(); */
if (count == 0)
{
unw_getcontext (&uc);
if (unw_init_local (&cursor, &uc) < 0)
{
panic ("unw_init_local failed!\n");
}
else
{
do
{
if ((ret = unw_get_reg (&cursor, UNW_REG_IP, &ip)) < 0)
{
panic ("FAILURE: unw_get_reg returned %d for UNW_REG_IP\n",
ret);
}
if ((ret = unw_get_reg (&cursor, UNW_REG_SP, &sp)) < 0)
{
panic ("FAILURE: unw_get_reg returned %d for UNW_REG_SP\n",
ret);
}
if ((ret = unw_get_fpreg (&cursor, UNW_PPC64_V30, &vr)) < 0)
{
panic
("FAILURE: unw_get_vreg returned %d for UNW_PPC64_V30\n",
ret);
}
if (verbose)
{
const char *regname = unw_regname (UNW_PPC64_V30);
char proc_name_buffer[256];
unw_word_t offset;
unsigned int * vec_half1, * vec_half2;
vec_half1 = (unsigned int *)&vr;
vec_half2 = vec_half1 + 1;
printf ("ip = %016lx, sp=%016lx\n", (long) ip, (long) sp);
printf ("vr30 = %08x %08x %08x %08x\n",
(unsigned int) (*vec_half1 >> 16),
(unsigned int) (*vec_half1 & 0xffffffff),
(unsigned int) (*vec_half2 >> 16),
(unsigned int) (*vec_half2 & 0xffffffff));
ret =
unw_get_proc_name (&cursor, proc_name_buffer,
sizeof (proc_name_buffer), &offset);
if (ret == 0)
{
printf ("proc name = %s, offset = %lx\n",
proc_name_buffer, offset);
}
else
{
panic ("unw_get_proc_name returned %d\n", ret);
}
printf ("unw_regname(UNW_PPC_V30) = %s\n\n", regname);
}
ret = unw_step (&cursor);
if (ret < 0)
{
unw_get_reg (&cursor, UNW_REG_IP, &ip);
panic ("FAILURE: unw_step() returned %d for ip=%lx\n", ret,
(long) ip);
}
}
while (ret > 0);
}
}
v1 = vec_init ();
v2 = vec_init ();
v3 = vec_init ();
v4 = vec_init ();
v5 = vec_init ();
v6 = vec_init ();
/* make use of all of the registers in some calculation */
v7 =
vec_nor (v1, vec_add (v2, vec_sub (v3, vec_and (v4, vec_or (v5, v6)))));
/*
* "force" the registers to be non-volatile by making a call and also
* using the registers after the call.
*/
v8 = vec_stack (count - 1);
/*
* Use the result from the previous call, plus all of the non-volatile
* registers in another calculation.
*/
v9 =
vec_nor (v1,
vec_add (v2,
vec_sub (v3,
vec_and (v4, vec_or (v5, vec_xor (v6, v8))))));
printf ("v1 - ");
vec_print (v1);
printf ("\n");
printf ("v2 - ");
vec_print (v2);
printf ("\n");
printf ("v3 - ");
vec_print (v3);
printf ("\n");
printf ("v4 - ");
vec_print (v4);
printf ("\n");
printf ("v5 - ");
vec_print (v5);
printf ("\n");
printf ("v6 - ");
vec_print (v6);
printf ("\n");
printf ("v7 - ");
vec_print (v7);
printf ("\n");
printf ("v8 - ");
vec_print (v8);
printf ("\n");
printf ("v9 - ");
vec_print (v9);
printf ("\n");
return v9;
}

20
tests/ppc64-test-wchar.c Normal file
View file

@ -0,0 +1,20 @@
#include <wchar.h>
#include <stdio.h>
main ()
{
wchar_t *wstring =
L"Now is the time for all good men to come to the aid of their country";
int i;
int ret;
printf("wcslen(wstring) = %d\n", wcslen(wstring));
for (i = 0; i < wcslen (wstring); i++)
{
ret = printf ("%lc", wstring[i]);
if (ret != 1) {
printf("printf returned: %d\n", ret);
perror("Linux says");
}
}
printf("\n");
}