mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-12-22 19:43:42 +01:00
SuperH port
Add support for the 32bit SuperH architecture running Linux. Specifically, support is added for SH4, and support for earlier SH versions and to the 64bit SH5 are left out. This was tested in qemu with a little-endian SH4 debian image & GCC 4.7 cross compiler.
This commit is contained in:
parent
7d77ef4d82
commit
8d5b1aeeff
42 changed files with 1893 additions and 2 deletions
|
@ -26,6 +26,9 @@ endif
|
|||
if ARCH_PPC64
|
||||
include_HEADERS += include/libunwind-ppc64.h
|
||||
endif
|
||||
if ARCH_SH
|
||||
include_HEADERS += include/libunwind-sh.h
|
||||
endif
|
||||
|
||||
if !REMOTE_ONLY
|
||||
include_HEADERS += include/libunwind.h include/unwind.h
|
||||
|
@ -54,6 +57,8 @@ noinst_HEADERS = include/dwarf.h include/dwarf_i.h include/dwarf-eh.h \
|
|||
include/tdep-ppc32/jmpbuf.h include/tdep-ppc32/libunwind_i.h \
|
||||
include/tdep-ppc64/dwarf-config.h \
|
||||
include/tdep-ppc64/jmpbuf.h include/tdep-ppc64/libunwind_i.h \
|
||||
include/tdep-sh/dwarf-config.h \
|
||||
include/tdep-sh/jmpbuf.h include/tdep-sh/libunwind_i.h \
|
||||
include/tdep/libunwind_i.h \
|
||||
include/tdep/jmpbuf.h include/tdep/dwarf-config.h
|
||||
|
||||
|
|
1
README
1
README
|
@ -10,6 +10,7 @@ several architecture/operating-system combinations:
|
|||
Linux/PARISC: Works well, but C library missing unwind-info.
|
||||
HP-UX/IA-64: Mostly works but known to have some serious limitations.
|
||||
Linux/PPC64: Newly added.
|
||||
Linux/SuperH: Newly added.
|
||||
FreeBSD/i386: Newly added.
|
||||
FreeBSD/x86-64: Newly added (FreeBSD architecture is known as amd64).
|
||||
|
||||
|
|
|
@ -93,6 +93,7 @@ AC_DEFUN([SET_ARCH],[
|
|||
[hppa*],[$2=hppa],
|
||||
[mips*],[$2=mips],
|
||||
[powerpc*],[$2=ppc$ppc_bits],
|
||||
[sh*],[$2=sh],
|
||||
[amd64],[$2=x86_64],
|
||||
[$2=$1])
|
||||
]) dnl SET_ARCH
|
||||
|
@ -103,7 +104,7 @@ SET_ARCH([$target_cpu],[target_arch])
|
|||
|
||||
AC_ARG_ENABLE(coredump,
|
||||
AS_HELP_STRING([--enable-coredump],[building libunwind-coredump library]),,
|
||||
[AS_CASE([$host_arch], [arm*|mips*|x86*], [enable_coredump=yes], [enable_coredump=no])]
|
||||
[AS_CASE([$host_arch], [arm*|mips*|sh*|x86*], [enable_coredump=yes], [enable_coredump=no])]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([if we should build libunwind-coredump])
|
||||
|
@ -128,13 +129,14 @@ 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(ARCH_SH, test x$target_arch = xsh)
|
||||
AM_CONDITIONAL(OS_LINUX, expr x$target_os : xlinux >/dev/null)
|
||||
AM_CONDITIONAL(OS_HPUX, expr x$target_os : xhpux >/dev/null)
|
||||
AM_CONDITIONAL(OS_FREEBSD, expr x$target_os : xfreebsd >/dev/null)
|
||||
|
||||
AC_MSG_CHECKING([for ELF helper width])
|
||||
case "${target_arch}" in
|
||||
(arm|hppa|ppc32|x86) use_elf32=yes; AC_MSG_RESULT([32]);;
|
||||
(arm|hppa|ppc32|x86|sh) use_elf32=yes; AC_MSG_RESULT([32]);;
|
||||
(ia64|ppc64|x86_64) use_elf64=yes; AC_MSG_RESULT([64]);;
|
||||
(mips) use_elfxx=yes; AC_MSG_RESULT([xx]);;
|
||||
*) AC_MSG_ERROR([Unknown ELF target: ${target_arch}])
|
||||
|
|
114
include/libunwind-sh.h
Normal file
114
include/libunwind-sh.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2008 CodeSourcery
|
||||
Copyright (C) 2012 Tommi Rantala <tt.rantala@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 LIBUNWIND_H
|
||||
#define LIBUNWIND_H
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#define UNW_TARGET sh
|
||||
#define UNW_TARGET_SH 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. */
|
||||
|
||||
#define UNW_TDEP_CURSOR_LEN 4096
|
||||
|
||||
typedef uint32_t unw_word_t;
|
||||
typedef int32_t unw_sword_t;
|
||||
|
||||
typedef long double unw_tdep_fpreg_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNW_SH_R0,
|
||||
UNW_SH_R1,
|
||||
UNW_SH_R2,
|
||||
UNW_SH_R3,
|
||||
UNW_SH_R4,
|
||||
UNW_SH_R5,
|
||||
UNW_SH_R6,
|
||||
UNW_SH_R7,
|
||||
UNW_SH_R8,
|
||||
UNW_SH_R9,
|
||||
UNW_SH_R10,
|
||||
UNW_SH_R11,
|
||||
UNW_SH_R12,
|
||||
UNW_SH_R13,
|
||||
UNW_SH_R14,
|
||||
UNW_SH_R15,
|
||||
|
||||
UNW_SH_PC,
|
||||
UNW_SH_PR,
|
||||
|
||||
UNW_TDEP_LAST_REG = UNW_SH_PR,
|
||||
|
||||
UNW_TDEP_IP = UNW_SH_PR,
|
||||
UNW_TDEP_SP = UNW_SH_R15,
|
||||
UNW_TDEP_EH = UNW_SH_R0
|
||||
}
|
||||
sh_regnum_t;
|
||||
|
||||
#define UNW_TDEP_NUM_EH_REGS 2
|
||||
|
||||
typedef ucontext_t unw_tdep_context_t;
|
||||
|
||||
#define unw_tdep_getcontext(uc) (getcontext (uc), 0)
|
||||
|
||||
typedef struct unw_tdep_save_loc
|
||||
{
|
||||
/* Additional target-dependent info on a save location. */
|
||||
}
|
||||
unw_tdep_save_loc_t;
|
||||
|
||||
#include "libunwind-dynamic.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* no sh-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 */
|
|
@ -15,6 +15,8 @@
|
|||
# include "libunwind-ppc32.h"
|
||||
#elif defined __powerpc64__
|
||||
# include "libunwind-ppc64.h"
|
||||
#elif defined __sh__
|
||||
# include "libunwind-sh.h"
|
||||
#elif defined __i386__
|
||||
# include "libunwind-x86.h"
|
||||
#elif defined __x86_64__
|
||||
|
|
49
include/tdep-sh/dwarf-config.h
Normal file
49
include/tdep-sh/dwarf-config.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2008 CodeSourcery
|
||||
Copyright (C) 2012 Tommi Rantala <tt.rantala@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 dwarf_config_h
|
||||
#define dwarf_config_h
|
||||
|
||||
#define DWARF_NUM_PRESERVED_REGS 18
|
||||
|
||||
#define dwarf_to_unw_regnum(reg) (((reg) <= UNW_SH_PR) ? (reg) : 0)
|
||||
|
||||
/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */
|
||||
#define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian)
|
||||
|
||||
/* 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 DWARF_LOC_TYPE_* macros. */
|
||||
#endif
|
||||
}
|
||||
dwarf_loc_t;
|
||||
|
||||
#endif /* dwarf_config_h */
|
48
include/tdep-sh/jmpbuf.h
Normal file
48
include/tdep-sh/jmpbuf.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2012 Tommi Rantala <tt.rantala@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. */
|
||||
|
||||
/* Use glibc's jump-buffer indices; NPTL peeks at SP: */
|
||||
|
||||
/* SH4 glibc jump buffer contents:
|
||||
* 0. r8
|
||||
* 1. r9
|
||||
* 2. r10
|
||||
* 3. r11
|
||||
* 4. r12
|
||||
* 5. r13
|
||||
* 6. r14
|
||||
* 7. r15
|
||||
* 8. pr/pc
|
||||
* 9. gbr
|
||||
* 10. fpscr
|
||||
* 11. fr12
|
||||
* 12. fr13
|
||||
* 13. fr14
|
||||
* 14. fr15
|
||||
*/
|
||||
|
||||
#define JB_SP 7
|
||||
#define JB_RP 8
|
||||
#define JB_MASK_SAVED 15
|
||||
#define JB_MASK 16
|
278
include/tdep-sh/libunwind_i.h
Normal file
278
include/tdep-sh/libunwind_i.h
Normal file
|
@ -0,0 +1,278 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2008 CodeSourcery
|
||||
Copyright (C) 2012 Tommi Rantala <tt.rantala@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 SH_LIBUNWIND_I_H
|
||||
#define SH_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 "elf32.h"
|
||||
#include "mempool.h"
|
||||
#include "dwarf.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* no sh-specific fast trace */
|
||||
}
|
||||
unw_tdep_frame_t;
|
||||
|
||||
struct unw_addr_space
|
||||
{
|
||||
struct unw_accessors acc;
|
||||
int big_endian;
|
||||
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;
|
||||
struct unw_debug_frame_list *debug_frames;
|
||||
};
|
||||
|
||||
struct cursor
|
||||
{
|
||||
struct dwarf_cursor dwarf; /* must be first */
|
||||
enum
|
||||
{
|
||||
SH_SCF_NONE, /* no signal frame */
|
||||
SH_SCF_LINUX_SIGFRAME, /* non-RT signal frame */
|
||||
SH_SCF_LINUX_RT_SIGFRAME, /* RT signal frame */
|
||||
}
|
||||
sigcontext_format;
|
||||
unw_word_t sigcontext_addr;
|
||||
unw_word_t sigcontext_sp;
|
||||
unw_word_t sigcontext_pc;
|
||||
};
|
||||
|
||||
#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_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \
|
||||
tdep_uc_addr((c)->as_arg, (r)), 0))
|
||||
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
|
||||
# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \
|
||||
tdep_uc_addr((c)->as_arg, (r)), 0))
|
||||
|
||||
static inline int
|
||||
dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
|
||||
{
|
||||
if (!DWARF_GET_LOC (loc))
|
||||
return -1;
|
||||
*val = *(unw_fpreg_t *) DWARF_GET_LOC (loc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
|
||||
{
|
||||
if (!DWARF_GET_LOC (loc))
|
||||
return -1;
|
||||
*(unw_fpreg_t *) DWARF_GET_LOC (loc) = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
|
||||
{
|
||||
if (!DWARF_GET_LOC (loc))
|
||||
return -1;
|
||||
*val = *(unw_word_t *) DWARF_GET_LOC (loc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
|
||||
{
|
||||
if (!DWARF_GET_LOC (loc))
|
||||
return -1;
|
||||
*(unw_word_t *) DWARF_GET_LOC (loc) = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* !UNW_LOCAL_ONLY */
|
||||
# define DWARF_LOC_TYPE_FP (1 << 0)
|
||||
# define DWARF_LOC_TYPE_REG (1 << 1)
|
||||
# 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_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG)
|
||||
# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
|
||||
# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \
|
||||
| DWARF_LOC_TYPE_FP))
|
||||
|
||||
static inline int
|
||||
dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
|
||||
{
|
||||
char *valp = (char *) &val;
|
||||
unw_word_t addr;
|
||||
int ret;
|
||||
|
||||
if (DWARF_IS_NULL_LOC (loc))
|
||||
return -UNW_EBADREG;
|
||||
|
||||
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, (unw_word_t *) valp,
|
||||
0, c->as_arg)) < 0)
|
||||
return ret;
|
||||
|
||||
return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0,
|
||||
c->as_arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
|
||||
{
|
||||
char *valp = (char *) &val;
|
||||
unw_word_t addr;
|
||||
int ret;
|
||||
|
||||
if (DWARF_IS_NULL_LOC (loc))
|
||||
return -UNW_EBADREG;
|
||||
|
||||
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, (unw_word_t *) valp,
|
||||
1, c->as_arg)) < 0)
|
||||
return ret;
|
||||
|
||||
return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1,
|
||||
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));
|
||||
|
||||
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));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#endif /* !UNW_LOCAL_ONLY */
|
||||
|
||||
#define tdep_getcontext_trace unw_getcontext
|
||||
#define tdep_init_done UNW_OBJ(init_done)
|
||||
#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_find_unwind_table dwarf_find_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_fetch_frame(c,ip,n) do {} while(0)
|
||||
#define tdep_cache_frame(c,rs) do {} while(0)
|
||||
#define tdep_reuse_frame(c,rs) do {} while(0)
|
||||
#define tdep_stash_frame(c,rs) do {} while(0)
|
||||
#define tdep_trace(cur,addr,n) (-UNW_ENOINFO)
|
||||
|
||||
#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
|
||||
|
||||
#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) ((as)->big_endian)
|
||||
|
||||
extern int tdep_init_done;
|
||||
|
||||
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 (unw_tdep_context_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,
|
||||
char *path, size_t pathlen);
|
||||
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 /* SH_LIBUNWIND_I_H */
|
|
@ -13,6 +13,8 @@
|
|||
# include "tdep-ppc32/dwarf-config.h"
|
||||
#elif defined __powerpc64__
|
||||
# include "tdep-ppc64/dwarf-config.h"
|
||||
#elif defined __sh__
|
||||
# include "tdep-sh/dwarf-config.h"
|
||||
#elif defined __i386__
|
||||
# include "tdep-x86/dwarf-config.h"
|
||||
#elif defined __x86_64__ || defined __amd64__
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
# include "tdep-ppc32/libunwind_i.h"
|
||||
#elif defined __powerpc64__
|
||||
# include "tdep-ppc64/libunwind_i.h"
|
||||
#elif defined __sh__
|
||||
# include "tdep-sh/libunwind_i.h"
|
||||
#elif defined __i386__
|
||||
# include "tdep-x86/libunwind_i.h"
|
||||
#elif defined __x86_64__
|
||||
|
|
|
@ -356,6 +356,24 @@ libunwind_ppc64_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \
|
|||
ppc64/Gglobal.c ppc64/Ginit.c \
|
||||
ppc64/Gregs.c ppc64/Gresume.c ppc64/Gstep.c
|
||||
|
||||
# The list of files that go into libunwind and libunwind-sh:
|
||||
noinst_HEADERS += sh/init.h sh/offsets.h sh/unwind_i.h
|
||||
libunwind_la_SOURCES_sh_common = $(libunwind_la_SOURCES_common) \
|
||||
sh/is_fpreg.c sh/regname.c
|
||||
|
||||
# The list of files that go into libunwind:
|
||||
libunwind_la_SOURCES_sh = $(libunwind_la_SOURCES_sh_common) \
|
||||
$(libunwind_la_SOURCES_local) \
|
||||
sh/Lcreate_addr_space.c sh/Lget_proc_info.c sh/Lget_save_loc.c \
|
||||
sh/Lglobal.c sh/Linit.c sh/Linit_local.c sh/Linit_remote.c \
|
||||
sh/Lis_signal_frame.c sh/Lregs.c sh/Lresume.c sh/Lstep.c
|
||||
|
||||
libunwind_sh_la_SOURCES_sh = $(libunwind_la_SOURCES_sh_common) \
|
||||
$(libunwind_la_SOURCES_generic) \
|
||||
sh/Gcreate_addr_space.c sh/Gget_proc_info.c sh/Gget_save_loc.c \
|
||||
sh/Gglobal.c sh/Ginit.c sh/Ginit_local.c sh/Ginit_remote.c \
|
||||
sh/Gis_signal_frame.c sh/Gregs.c sh/Gresume.c sh/Gstep.c
|
||||
|
||||
if REMOTE_ONLY
|
||||
install-exec-hook:
|
||||
# Nothing to do here....
|
||||
|
@ -506,7 +524,20 @@ if !REMOTE_ONLY
|
|||
libunwind_ppc64_la_LIBADD += libunwind.la -lc
|
||||
endif
|
||||
libunwind_setjmp_la_SOURCES += ppc/longjmp.S ppc/siglongjmp.S
|
||||
else
|
||||
if ARCH_SH
|
||||
lib_LTLIBRARIES += libunwind-sh.la
|
||||
libunwind_la_SOURCES = $(libunwind_la_SOURCES_sh)
|
||||
libunwind_sh_la_SOURCES = $(libunwind_sh_la_SOURCES_sh)
|
||||
libunwind_sh_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION)
|
||||
libunwind_sh_la_LIBADD = libunwind-dwarf-generic.la
|
||||
libunwind_sh_la_LIBADD += libunwind-elf32.la
|
||||
if !REMOTE_ONLY
|
||||
libunwind_sh_la_LIBADD += libunwind.la -lc
|
||||
endif
|
||||
libunwind_setjmp_la_SOURCES += sh/siglongjmp.S
|
||||
|
||||
endif # ARCH_SH
|
||||
endif # ARCH_PPC64
|
||||
endif # ARCH_PPC32
|
||||
endif # ARCH_X86_64
|
||||
|
@ -541,6 +572,7 @@ EXTRA_DIST = $(libunwind_la_SOURCES_arm) \
|
|||
$(libunwind_la_SOURCES_hppa) \
|
||||
$(libunwind_la_SOURCES_ia64) \
|
||||
$(libunwind_la_SOURCES_mips) \
|
||||
$(libunwind_la_SOURCES_sh) \
|
||||
$(libunwind_la_SOURCES_x86) \
|
||||
$(libunwind_la_SOURCES_os_freebsd) \
|
||||
$(libunwind_la_SOURCES_os_linux) \
|
||||
|
@ -552,6 +584,7 @@ EXTRA_DIST = $(libunwind_la_SOURCES_arm) \
|
|||
$(libunwind_hppa_la_SOURCES_hppa) \
|
||||
$(libunwind_ia64_la_SOURCES_ia64) \
|
||||
$(libunwind_mips_la_SOURCES_mips) \
|
||||
$(libunwind_sh_la_SOURCES_sh) \
|
||||
$(libunwind_x86_la_SOURCES_x86) \
|
||||
$(libunwind_x86_64_la_SOURCES_x86_64)
|
||||
|
||||
|
|
|
@ -42,6 +42,9 @@ _UCD_access_reg (unw_addr_space_t as,
|
|||
#if defined(UNW_TARGET_ARM)
|
||||
if (regnum < 0 || regnum >= 16)
|
||||
goto badreg;
|
||||
#elif defined(UNW_TARGET_SH)
|
||||
if (regnum < 0 || regnum > UNW_SH_PR)
|
||||
goto badreg;
|
||||
#else
|
||||
#if defined(UNW_TARGET_MIPS)
|
||||
static const uint8_t remap_regs[] =
|
||||
|
|
|
@ -500,6 +500,7 @@ int _UPT_reg_offset[UNW_REG_LAST + 1] =
|
|||
[UNW_ARM_R14] = 0x38,
|
||||
[UNW_ARM_R15] = 0x3c,
|
||||
#elif defined(UNW_TARGET_MIPS)
|
||||
#elif defined(UNW_TARGET_SH)
|
||||
#else
|
||||
# error Fix me.
|
||||
#endif
|
||||
|
|
59
src/sh/Gcreate_addr_space.c
Normal file
59
src/sh/Gcreate_addr_space.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2012 Tommi Rantala <tt.rantala@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 <string.h>
|
||||
#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;
|
||||
|
||||
/* SH supports little-endian and big-endian. */
|
||||
if (byte_order != 0 && byte_order != __LITTLE_ENDIAN
|
||||
&& byte_order != __BIG_ENDIAN)
|
||||
return NULL;
|
||||
|
||||
as = malloc (sizeof (*as));
|
||||
if (!as)
|
||||
return NULL;
|
||||
|
||||
memset (as, 0, sizeof (*as));
|
||||
|
||||
as->acc = *a;
|
||||
|
||||
/* Default to little-endian for SH. */
|
||||
if (byte_order == 0 || byte_order == __LITTLE_ENDIAN)
|
||||
as->big_endian = 0;
|
||||
else
|
||||
as->big_endian = 1;
|
||||
|
||||
return as;
|
||||
#endif
|
||||
}
|
39
src/sh/Gget_proc_info.c
Normal file
39
src/sh/Gget_proc_info.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2008 CodeSourcery
|
||||
|
||||
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)
|
||||
{
|
||||
struct cursor *c = (struct cursor *) cursor;
|
||||
int ret;
|
||||
|
||||
ret = dwarf_make_proc_info (&c->dwarf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*pi = c->dwarf.pi;
|
||||
return 0;
|
||||
}
|
83
src/sh/Gget_save_loc.c
Normal file
83
src/sh/Gget_save_loc.c
Normal file
|
@ -0,0 +1,83 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2008 CodeSourcery
|
||||
Copyright (C) 2012 Tommi Rantala <tt.rantala@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_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc)
|
||||
{
|
||||
struct cursor *c = (struct cursor *) cursor;
|
||||
dwarf_loc_t loc;
|
||||
|
||||
switch (reg)
|
||||
{
|
||||
case UNW_SH_R0:
|
||||
case UNW_SH_R1:
|
||||
case UNW_SH_R2:
|
||||
case UNW_SH_R3:
|
||||
case UNW_SH_R4:
|
||||
case UNW_SH_R5:
|
||||
case UNW_SH_R6:
|
||||
case UNW_SH_R7:
|
||||
case UNW_SH_R8:
|
||||
case UNW_SH_R9:
|
||||
case UNW_SH_R10:
|
||||
case UNW_SH_R11:
|
||||
case UNW_SH_R12:
|
||||
case UNW_SH_R13:
|
||||
case UNW_SH_R14:
|
||||
case UNW_SH_R15:
|
||||
case UNW_SH_PC:
|
||||
case UNW_SH_PR:
|
||||
loc = c->dwarf.loc[reg];
|
||||
break;
|
||||
|
||||
default:
|
||||
loc = DWARF_NULL_LOC; /* default to "not saved" */
|
||||
break;
|
||||
}
|
||||
|
||||
memset (sloc, 0, sizeof (*sloc));
|
||||
|
||||
if (DWARF_IS_NULL_LOC (loc))
|
||||
{
|
||||
sloc->type = UNW_SLT_NONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(UNW_LOCAL_ONLY)
|
||||
if (DWARF_IS_REG_LOC (loc))
|
||||
{
|
||||
sloc->type = UNW_SLT_REG;
|
||||
sloc->u.regnum = DWARF_GET_LOC (loc);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
sloc->type = UNW_SLT_MEMORY;
|
||||
sloc->u.addr = DWARF_GET_LOC (loc);
|
||||
}
|
||||
return 0;
|
||||
}
|
56
src/sh/Gglobal.c
Normal file
56
src/sh/Gglobal.c
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2008 CodeSourcery
|
||||
Copyright (C) 2012 Tommi Rantala <tt.rantala@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 define_lock (sh_lock);
|
||||
HIDDEN int tdep_init_done;
|
||||
|
||||
HIDDEN void
|
||||
tdep_init (void)
|
||||
{
|
||||
intrmask_t saved_mask;
|
||||
|
||||
sigfillset (&unwi_full_mask);
|
||||
|
||||
lock_acquire (&sh_lock, saved_mask);
|
||||
{
|
||||
if (tdep_init_done)
|
||||
/* another thread else beat us to it... */
|
||||
goto out;
|
||||
|
||||
mi_init ();
|
||||
|
||||
dwarf_init ();
|
||||
|
||||
#ifndef UNW_REMOTE_ONLY
|
||||
sh_local_addr_space_init ();
|
||||
#endif
|
||||
tdep_init_done = 1; /* signal that we're initialized... */
|
||||
}
|
||||
out:
|
||||
lock_release (&sh_lock, saved_mask);
|
||||
}
|
186
src/sh/Ginit.c
Normal file
186
src/sh/Ginit.c
Normal file
|
@ -0,0 +1,186 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2008 CodeSourcery
|
||||
Copyright (C) 2012 Tommi Rantala <tt.rantala@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 "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;
|
||||
|
||||
static inline void *
|
||||
uc_addr (ucontext_t *uc, int reg)
|
||||
{
|
||||
if (reg >= UNW_SH_R0 && reg <= UNW_SH_PR)
|
||||
return &uc->uc_mcontext.gregs[reg];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
# 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;
|
||||
|
||||
/* XXX fix me: there is currently no way to locate the dyn-info list
|
||||
by a remote unwinder. On ia64, this is done via a special
|
||||
unwind-table entry. Perhaps something similar can be done with
|
||||
DWARF2 unwind info. */
|
||||
|
||||
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 (16, "mem[%x] <- %x\n", addr, *val);
|
||||
*(unw_word_t *) addr = *val;
|
||||
}
|
||||
else
|
||||
{
|
||||
*val = *(unw_word_t *) addr;
|
||||
Debug (16, "mem[%x] -> %x\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 (unw_is_fpreg (reg))
|
||||
goto badreg;
|
||||
|
||||
if (!(addr = uc_addr (uc, reg)))
|
||||
goto badreg;
|
||||
|
||||
if (write)
|
||||
{
|
||||
*(unw_word_t *) addr = *val;
|
||||
Debug (12, "%s <- %x\n", unw_regname (reg), *val);
|
||||
}
|
||||
else
|
||||
{
|
||||
*val = *(unw_word_t *) addr;
|
||||
Debug (12, "%s -> %x\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 (!unw_is_fpreg (reg))
|
||||
goto badreg;
|
||||
|
||||
if (!(addr = uc_addr (uc, reg)))
|
||||
goto badreg;
|
||||
|
||||
if (write)
|
||||
{
|
||||
Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg),
|
||||
((long *)val)[0], ((long *)val)[1], ((long *)val)[2]);
|
||||
*(unw_fpreg_t *) addr = *val;
|
||||
}
|
||||
else
|
||||
{
|
||||
*val = *(unw_fpreg_t *) addr;
|
||||
Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg),
|
||||
((long *)val)[0], ((long *)val)[1], ((long *)val)[2]);
|
||||
}
|
||||
return 0;
|
||||
|
||||
badreg:
|
||||
Debug (1, "bad register number %u\n", reg);
|
||||
/* attempt to access a non-preserved register */
|
||||
return -UNW_EBADREG;
|
||||
}
|
||||
|
||||
static int
|
||||
get_static_proc_name (unw_addr_space_t as, unw_word_t ip,
|
||||
char *buf, size_t buf_len, unw_word_t *offp,
|
||||
void *arg)
|
||||
{
|
||||
return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp);
|
||||
}
|
||||
|
||||
HIDDEN void
|
||||
sh_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 = sh_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 */
|
55
src/sh/Ginit_local.c
Normal file
55
src/sh/Ginit_local.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2008 CodeSourcery
|
||||
Copyright 2011 Linaro Limited
|
||||
|
||||
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, unw_context_t *uc)
|
||||
{
|
||||
return -UNW_EINVAL;
|
||||
}
|
||||
|
||||
#else /* !UNW_REMOTE_ONLY */
|
||||
|
||||
PROTECTED int
|
||||
unw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
|
||||
{
|
||||
struct cursor *c = (struct cursor *) cursor;
|
||||
|
||||
if (!tdep_init_done)
|
||||
tdep_init ();
|
||||
|
||||
Debug (1, "(cursor=%p)\n", c);
|
||||
|
||||
c->dwarf.as = unw_local_addr_space;
|
||||
c->dwarf.as_arg = uc;
|
||||
|
||||
return common_init (c, 1);
|
||||
}
|
||||
|
||||
#endif /* !UNW_REMOTE_ONLY */
|
45
src/sh/Ginit_remote.c
Normal file
45
src/sh/Ginit_remote.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2008 CodeSourcery
|
||||
|
||||
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_init_done)
|
||||
tdep_init ();
|
||||
|
||||
Debug (1, "(cursor=%p)\n", c);
|
||||
|
||||
c->dwarf.as = as;
|
||||
c->dwarf.as_arg = as_arg;
|
||||
return common_init (c, 0);
|
||||
#endif /* !UNW_LOCAL_ONLY */
|
||||
}
|
119
src/sh/Gis_signal_frame.c
Normal file
119
src/sh/Gis_signal_frame.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2012 Tommi Rantala <tt.rantala@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"
|
||||
|
||||
/* Disassembly of the Linux VDSO sigreturn functions:
|
||||
|
||||
00000000 <__kernel_sigreturn>:
|
||||
0: 05 93 mov.w e <__kernel_sigreturn+0xe>,r3 ! 77
|
||||
2: 10 c3 trapa #16
|
||||
4: 0b 20 or r0,r0
|
||||
6: 0b 20 or r0,r0
|
||||
8: 0b 20 or r0,r0
|
||||
a: 0b 20 or r0,r0
|
||||
c: 0b 20 or r0,r0
|
||||
e: 77 00 .word 0x0077
|
||||
10: 09 00 nop
|
||||
12: 09 00 nop
|
||||
14: 09 00 nop
|
||||
16: 09 00 nop
|
||||
18: 09 00 nop
|
||||
1a: 09 00 nop
|
||||
1c: 09 00 nop
|
||||
1e: 09 00 nop
|
||||
|
||||
00000020 <__kernel_rt_sigreturn>:
|
||||
20: 05 93 mov.w 2e <__kernel_rt_sigreturn+0xe>,r3 ! ad
|
||||
22: 10 c3 trapa #16
|
||||
24: 0b 20 or r0,r0
|
||||
26: 0b 20 or r0,r0
|
||||
28: 0b 20 or r0,r0
|
||||
2a: 0b 20 or r0,r0
|
||||
2c: 0b 20 or r0,r0
|
||||
2e: ad 00 mov.w @(r0,r10),r0
|
||||
30: 09 00 nop
|
||||
32: 09 00 nop
|
||||
34: 09 00 nop
|
||||
36: 09 00 nop
|
||||
38: 09 00 nop
|
||||
3a: 09 00 nop
|
||||
3c: 09 00 nop
|
||||
3e: 09 00 nop
|
||||
*/
|
||||
|
||||
PROTECTED int
|
||||
unw_is_signal_frame (unw_cursor_t *cursor)
|
||||
{
|
||||
#ifdef __linux__
|
||||
struct cursor *c = (struct cursor *) cursor;
|
||||
unw_word_t w0, ip;
|
||||
unw_addr_space_t as;
|
||||
unw_accessors_t *a;
|
||||
void *arg;
|
||||
int ret;
|
||||
|
||||
as = c->dwarf.as;
|
||||
a = unw_get_accessors (as);
|
||||
arg = c->dwarf.as_arg;
|
||||
|
||||
ip = c->dwarf.ip;
|
||||
|
||||
ret = (*a->access_mem) (as, ip, &w0, 0, arg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (w0 != 0xc3109305)
|
||||
return 0;
|
||||
|
||||
ret = (*a->access_mem) (as, ip+4, &w0, 0, arg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (w0 != 0x200b200b)
|
||||
return 0;
|
||||
|
||||
ret = (*a->access_mem) (as, ip+8, &w0, 0, arg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (w0 != 0x200b200b)
|
||||
return 0;
|
||||
|
||||
ret = (*a->access_mem) (as, ip+12, &w0, 0, arg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (w0 == 0x0077200b)
|
||||
return 1; /* non-RT */
|
||||
else if (w0 == 0x00ad200b)
|
||||
return 2; /* RT */
|
||||
|
||||
/* does not look like a signal frame */
|
||||
return 0;
|
||||
|
||||
#else
|
||||
return -UNW_ENOINFO;
|
||||
#endif
|
||||
}
|
79
src/sh/Gregs.c
Normal file
79
src/sh/Gregs.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2008 CodeSourcery
|
||||
Copyright (C) 2012 Tommi Rantala <tt.rantala@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)
|
||||
{
|
||||
dwarf_loc_t loc = DWARF_NULL_LOC;
|
||||
|
||||
switch (reg)
|
||||
{
|
||||
case UNW_SH_R0:
|
||||
case UNW_SH_R1:
|
||||
case UNW_SH_R2:
|
||||
case UNW_SH_R3:
|
||||
case UNW_SH_R4:
|
||||
case UNW_SH_R5:
|
||||
case UNW_SH_R6:
|
||||
case UNW_SH_R7:
|
||||
case UNW_SH_R8:
|
||||
case UNW_SH_R9:
|
||||
case UNW_SH_R10:
|
||||
case UNW_SH_R11:
|
||||
case UNW_SH_R12:
|
||||
case UNW_SH_R13:
|
||||
case UNW_SH_R14:
|
||||
case UNW_SH_PC:
|
||||
case UNW_SH_PR:
|
||||
loc = c->dwarf.loc[reg];
|
||||
break;
|
||||
|
||||
case UNW_SH_R15:
|
||||
if (write)
|
||||
return -UNW_EREADONLYREG;
|
||||
*valp = c->dwarf.cfa;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
Debug (1, "bad register number %u\n", reg);
|
||||
return -UNW_EBADREG;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
Debug (1, "bad register number %u\n", reg);
|
||||
return -UNW_EBADREG;
|
||||
}
|
165
src/sh/Gresume.c
Normal file
165
src/sh/Gresume.c
Normal file
|
@ -0,0 +1,165 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2008 CodeSourcery
|
||||
Copyright 2011 Linaro Limited
|
||||
Copyright (C) 2012 Tommi Rantala <tt.rantala@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 "offsets.h"
|
||||
|
||||
#ifndef UNW_REMOTE_ONLY
|
||||
|
||||
HIDDEN inline int
|
||||
sh_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
|
||||
{
|
||||
#ifdef __linux__
|
||||
struct cursor *c = (struct cursor *) cursor;
|
||||
unw_tdep_context_t *uc = c->dwarf.as_arg;
|
||||
|
||||
if (c->sigcontext_format == SH_SCF_NONE)
|
||||
{
|
||||
/* Since there are no signals involved here we restore the non scratch
|
||||
registers only. */
|
||||
unsigned long regs[8];
|
||||
regs[0] = uc->uc_mcontext.gregs[8];
|
||||
regs[1] = uc->uc_mcontext.gregs[9];
|
||||
regs[2] = uc->uc_mcontext.gregs[10];
|
||||
regs[3] = uc->uc_mcontext.gregs[11];
|
||||
regs[4] = uc->uc_mcontext.gregs[12];
|
||||
regs[5] = uc->uc_mcontext.gregs[13];
|
||||
regs[6] = uc->uc_mcontext.gregs[14];
|
||||
regs[7] = uc->uc_mcontext.gregs[15];
|
||||
unsigned long pc = uc->uc_mcontext.pr;
|
||||
|
||||
struct regs_overlay {
|
||||
char x[sizeof(regs)];
|
||||
};
|
||||
|
||||
asm volatile (
|
||||
"mov.l @%0+, r8\n"
|
||||
"mov.l @%0+, r9\n"
|
||||
"mov.l @%0+, r10\n"
|
||||
"mov.l @%0+, r11\n"
|
||||
"mov.l @%0+, r12\n"
|
||||
"mov.l @%0+, r13\n"
|
||||
"mov.l @%0+, r14\n"
|
||||
"mov.l @%0, r15\n"
|
||||
"lds %1, pr\n"
|
||||
"rts\n"
|
||||
"nop\n"
|
||||
:
|
||||
: "r" (regs),
|
||||
"r" (pc),
|
||||
"m" (*(struct regs_overlay *)regs)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* In case a signal frame is involved, we're using its trampoline which
|
||||
calls sigreturn. */
|
||||
struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
|
||||
sc->sc_regs[0] = uc->uc_mcontext.gregs[0];
|
||||
sc->sc_regs[1] = uc->uc_mcontext.gregs[1];
|
||||
sc->sc_regs[2] = uc->uc_mcontext.gregs[2];
|
||||
sc->sc_regs[3] = uc->uc_mcontext.gregs[3];
|
||||
sc->sc_regs[4] = uc->uc_mcontext.gregs[4];
|
||||
sc->sc_regs[5] = uc->uc_mcontext.gregs[5];
|
||||
sc->sc_regs[6] = uc->uc_mcontext.gregs[6];
|
||||
sc->sc_regs[7] = uc->uc_mcontext.gregs[7];
|
||||
sc->sc_regs[8] = uc->uc_mcontext.gregs[8];
|
||||
sc->sc_regs[9] = uc->uc_mcontext.gregs[9];
|
||||
sc->sc_regs[10] = uc->uc_mcontext.gregs[10];
|
||||
sc->sc_regs[11] = uc->uc_mcontext.gregs[11];
|
||||
sc->sc_regs[12] = uc->uc_mcontext.gregs[12];
|
||||
sc->sc_regs[13] = uc->uc_mcontext.gregs[13];
|
||||
sc->sc_regs[14] = uc->uc_mcontext.gregs[14];
|
||||
sc->sc_regs[15] = uc->uc_mcontext.gregs[15];
|
||||
sc->sc_pc = uc->uc_mcontext.pc;
|
||||
sc->sc_pr = uc->uc_mcontext.pr;
|
||||
|
||||
/* Set the SP and the PC in order to continue execution at the modified
|
||||
trampoline which restores the signal mask and the registers. */
|
||||
asm __volatile__ (
|
||||
"mov %0, r15\n"
|
||||
"lds %1, pr\n"
|
||||
"rts\n"
|
||||
"nop\n"
|
||||
:
|
||||
: "r" (c->sigcontext_sp),
|
||||
"r" (c->sigcontext_pc)
|
||||
);
|
||||
}
|
||||
__builtin_unreachable();
|
||||
#endif
|
||||
return -UNW_EINVAL;
|
||||
}
|
||||
|
||||
#endif /* !UNW_REMOTE_ONLY */
|
||||
|
||||
static inline void
|
||||
establish_machine_state (struct cursor *c)
|
||||
{
|
||||
unw_addr_space_t as = c->dwarf.as;
|
||||
void *arg = c->dwarf.as_arg;
|
||||
unw_fpreg_t fpval;
|
||||
unw_word_t val;
|
||||
int reg;
|
||||
|
||||
Debug (8, "copying out cursor state\n");
|
||||
|
||||
for (reg = 0; reg <= UNW_REG_LAST; ++reg)
|
||||
{
|
||||
Debug (16, "copying %s %d\n", unw_regname (reg), reg);
|
||||
if (unw_is_fpreg (reg))
|
||||
{
|
||||
if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0)
|
||||
as->acc.access_fpreg (as, reg, &fpval, 1, arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tdep_access_reg (c, reg, &val, 0) >= 0)
|
||||
as->acc.access_reg (as, reg, &val, 1, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PROTECTED int
|
||||
unw_resume (unw_cursor_t *cursor)
|
||||
{
|
||||
struct cursor *c = (struct cursor *) cursor;
|
||||
|
||||
Debug (1, "(cursor=%p)\n", c);
|
||||
|
||||
if (!c->dwarf.ip)
|
||||
{
|
||||
/* This can happen easily when the frame-chain gets truncated
|
||||
due to bad or missing unwind-info. */
|
||||
Debug (1, "refusing to resume execution at address 0\n");
|
||||
return -UNW_EINVAL;
|
||||
}
|
||||
|
||||
establish_machine_state (c);
|
||||
|
||||
return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c,
|
||||
c->dwarf.as_arg);
|
||||
}
|
117
src/sh/Gstep.c
Normal file
117
src/sh/Gstep.c
Normal file
|
@ -0,0 +1,117 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2008 CodeSourcery
|
||||
Copyright 2011 Linaro Limited
|
||||
Copyright (C) 2012 Tommi Rantala <tt.rantala@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 "offsets.h"
|
||||
|
||||
PROTECTED int
|
||||
unw_handle_signal_frame (unw_cursor_t *cursor)
|
||||
{
|
||||
struct cursor *c = (struct cursor *) cursor;
|
||||
int ret;
|
||||
unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa;
|
||||
struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0);
|
||||
|
||||
if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0)
|
||||
return -UNW_EUNSPEC;
|
||||
|
||||
ret = unw_is_signal_frame (cursor);
|
||||
Debug(1, "unw_is_signal_frame()=%d\n", ret);
|
||||
|
||||
/* Save the SP and PC to be able to return execution at this point
|
||||
later in time (unw_resume). */
|
||||
c->sigcontext_sp = c->dwarf.cfa;
|
||||
c->sigcontext_pc = c->dwarf.ip;
|
||||
|
||||
if (ret == 1)
|
||||
{
|
||||
/* Handle non-RT signal frame. */
|
||||
c->sigcontext_format = SH_SCF_LINUX_SIGFRAME;
|
||||
sc_addr = sp_addr;
|
||||
}
|
||||
else if (ret == 2)
|
||||
{
|
||||
/* Handle RT signal frame. */
|
||||
c->sigcontext_format = SH_SCF_LINUX_RT_SIGFRAME;
|
||||
sc_addr = sp_addr + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF;
|
||||
}
|
||||
else
|
||||
return -UNW_EUNSPEC;
|
||||
|
||||
c->sigcontext_addr = sc_addr;
|
||||
|
||||
/* Update the dwarf cursor.
|
||||
Set the location of the registers to the corresponding addresses of the
|
||||
uc_mcontext / sigcontext structure contents. */
|
||||
c->dwarf.loc[UNW_SH_R0] = DWARF_LOC (sc_addr + LINUX_SC_R0_OFF, 0);
|
||||
c->dwarf.loc[UNW_SH_R1] = DWARF_LOC (sc_addr + LINUX_SC_R1_OFF, 0);
|
||||
c->dwarf.loc[UNW_SH_R2] = DWARF_LOC (sc_addr + LINUX_SC_R2_OFF, 0);
|
||||
c->dwarf.loc[UNW_SH_R3] = DWARF_LOC (sc_addr + LINUX_SC_R3_OFF, 0);
|
||||
c->dwarf.loc[UNW_SH_R4] = DWARF_LOC (sc_addr + LINUX_SC_R4_OFF, 0);
|
||||
c->dwarf.loc[UNW_SH_R5] = DWARF_LOC (sc_addr + LINUX_SC_R5_OFF, 0);
|
||||
c->dwarf.loc[UNW_SH_R6] = DWARF_LOC (sc_addr + LINUX_SC_R6_OFF, 0);
|
||||
c->dwarf.loc[UNW_SH_R7] = DWARF_LOC (sc_addr + LINUX_SC_R7_OFF, 0);
|
||||
c->dwarf.loc[UNW_SH_R8] = DWARF_LOC (sc_addr + LINUX_SC_R8_OFF, 0);
|
||||
c->dwarf.loc[UNW_SH_R9] = DWARF_LOC (sc_addr + LINUX_SC_R9_OFF, 0);
|
||||
c->dwarf.loc[UNW_SH_R10] = DWARF_LOC (sc_addr + LINUX_SC_R10_OFF, 0);
|
||||
c->dwarf.loc[UNW_SH_R11] = DWARF_LOC (sc_addr + LINUX_SC_R11_OFF, 0);
|
||||
c->dwarf.loc[UNW_SH_R12] = DWARF_LOC (sc_addr + LINUX_SC_R12_OFF, 0);
|
||||
c->dwarf.loc[UNW_SH_R13] = DWARF_LOC (sc_addr + LINUX_SC_R13_OFF, 0);
|
||||
c->dwarf.loc[UNW_SH_R14] = DWARF_LOC (sc_addr + LINUX_SC_R14_OFF, 0);
|
||||
c->dwarf.loc[UNW_SH_R15] = DWARF_LOC (sc_addr + LINUX_SC_R15_OFF, 0);
|
||||
c->dwarf.loc[UNW_SH_PR] = DWARF_LOC (sc_addr + LINUX_SC_PR_OFF, 0);
|
||||
c->dwarf.loc[UNW_SH_PC] = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0);
|
||||
|
||||
/* Set SP/CFA and PC/IP. */
|
||||
dwarf_get (&c->dwarf, c->dwarf.loc[UNW_SH_R15], &c->dwarf.cfa);
|
||||
dwarf_get (&c->dwarf, c->dwarf.loc[UNW_SH_PC], &c->dwarf.ip);
|
||||
|
||||
c->dwarf.pi_valid = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
PROTECTED int
|
||||
unw_step (unw_cursor_t *cursor)
|
||||
{
|
||||
struct cursor *c = (struct cursor *) cursor;
|
||||
int ret;
|
||||
|
||||
Debug (1, "(cursor=%p)\n", c);
|
||||
|
||||
if (unw_is_signal_frame (cursor))
|
||||
return unw_handle_signal_frame (cursor);
|
||||
|
||||
ret = dwarf_step (&c->dwarf);
|
||||
|
||||
if (unlikely (ret == -UNW_ESTOPUNWIND))
|
||||
return ret;
|
||||
|
||||
if (unlikely (ret < 0))
|
||||
return 0;
|
||||
|
||||
return (c->dwarf.ip == 0) ? 0 : 1;
|
||||
}
|
5
src/sh/Lcreate_addr_space.c
Normal file
5
src/sh/Lcreate_addr_space.c
Normal 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
|
5
src/sh/Lget_proc_info.c
Normal file
5
src/sh/Lget_proc_info.c
Normal 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
|
5
src/sh/Lget_save_loc.c
Normal file
5
src/sh/Lget_save_loc.c
Normal 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/sh/Lglobal.c
Normal file
5
src/sh/Lglobal.c
Normal 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/sh/Linit.c
Normal file
5
src/sh/Linit.c
Normal 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/sh/Linit_local.c
Normal file
5
src/sh/Linit_local.c
Normal 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/sh/Linit_remote.c
Normal file
5
src/sh/Linit_remote.c
Normal 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
|
5
src/sh/Lis_signal_frame.c
Normal file
5
src/sh/Lis_signal_frame.c
Normal 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/sh/Lregs.c
Normal file
5
src/sh/Lregs.c
Normal 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/sh/Lresume.c
Normal file
5
src/sh/Lresume.c
Normal 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/sh/Lstep.c
Normal file
5
src/sh/Lstep.c
Normal 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
|
51
src/sh/gen-offsets.c
Normal file
51
src/sh/gen-offsets.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <ucontext.h>
|
||||
#include <asm/sigcontext.h>
|
||||
|
||||
#define UC(N,X) \
|
||||
printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X))
|
||||
|
||||
#define SC(N,X) \
|
||||
printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X))
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
printf (
|
||||
"/* Linux-specific definitions: */\n\n"
|
||||
|
||||
"/* Define various structure offsets to simplify cross-compilation. */\n\n"
|
||||
|
||||
"/* Offsets for SH Linux \"ucontext_t\": */\n\n");
|
||||
|
||||
UC ("FLAGS", uc_flags);
|
||||
UC ("LINK", uc_link);
|
||||
UC ("STACK", uc_stack);
|
||||
UC ("MCONTEXT", uc_mcontext);
|
||||
UC ("SIGMASK", uc_sigmask);
|
||||
|
||||
printf ("\n/* Offsets for SH Linux \"struct sigcontext\": */\n\n");
|
||||
|
||||
SC ("R0", sc_regs[0]);
|
||||
SC ("R1", sc_regs[1]);
|
||||
SC ("R2", sc_regs[2]);
|
||||
SC ("R3", sc_regs[3]);
|
||||
SC ("R4", sc_regs[4]);
|
||||
SC ("R5", sc_regs[5]);
|
||||
SC ("R6", sc_regs[6]);
|
||||
SC ("R7", sc_regs[7]);
|
||||
SC ("R8", sc_regs[8]);
|
||||
SC ("R9", sc_regs[9]);
|
||||
SC ("R10", sc_regs[10]);
|
||||
SC ("R11", sc_regs[11]);
|
||||
SC ("R12", sc_regs[12]);
|
||||
SC ("R13", sc_regs[13]);
|
||||
SC ("R14", sc_regs[14]);
|
||||
SC ("R15", sc_regs[15]);
|
||||
|
||||
SC ("PC", sc_pc);
|
||||
SC ("PR", sc_pr);
|
||||
|
||||
return 0;
|
||||
}
|
74
src/sh/init.h
Normal file
74
src/sh/init.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2012 Tommi Rantala <tt.rantala@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, unsigned use_prev_instr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
c->dwarf.loc[UNW_SH_R0] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R0);
|
||||
c->dwarf.loc[UNW_SH_R1] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R1);
|
||||
c->dwarf.loc[UNW_SH_R2] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R2);
|
||||
c->dwarf.loc[UNW_SH_R3] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R3);
|
||||
c->dwarf.loc[UNW_SH_R4] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R4);
|
||||
c->dwarf.loc[UNW_SH_R5] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R5);
|
||||
c->dwarf.loc[UNW_SH_R6] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R6);
|
||||
c->dwarf.loc[UNW_SH_R7] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R7);
|
||||
c->dwarf.loc[UNW_SH_R8] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R8);
|
||||
c->dwarf.loc[UNW_SH_R9] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R9);
|
||||
c->dwarf.loc[UNW_SH_R10] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R10);
|
||||
c->dwarf.loc[UNW_SH_R11] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R11);
|
||||
c->dwarf.loc[UNW_SH_R12] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R12);
|
||||
c->dwarf.loc[UNW_SH_R13] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R13);
|
||||
c->dwarf.loc[UNW_SH_R14] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R14);
|
||||
c->dwarf.loc[UNW_SH_R15] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R15);
|
||||
c->dwarf.loc[UNW_SH_PC] = DWARF_REG_LOC (&c->dwarf, UNW_SH_PC);
|
||||
c->dwarf.loc[UNW_SH_PR] = DWARF_REG_LOC (&c->dwarf, UNW_SH_PR);
|
||||
|
||||
ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_SH_PC], &c->dwarf.ip);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_TDEP_SP], &c->dwarf.cfa);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
c->sigcontext_format = SH_SCF_NONE;
|
||||
c->sigcontext_addr = 0;
|
||||
c->sigcontext_sp = 0;
|
||||
c->sigcontext_pc = 0;
|
||||
|
||||
c->dwarf.args_size = 0;
|
||||
c->dwarf.ret_addr_column = 0;
|
||||
c->dwarf.stash_frames = 0;
|
||||
c->dwarf.use_prev_instr = use_prev_instr;
|
||||
c->dwarf.pi_valid = 0;
|
||||
c->dwarf.pi_is_dynamic = 0;
|
||||
c->dwarf.hint = 0;
|
||||
c->dwarf.prev_rs = 0;
|
||||
|
||||
return 0;
|
||||
}
|
32
src/sh/is_fpreg.c
Normal file
32
src/sh/is_fpreg.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2008 CodeSourcery
|
||||
|
||||
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)
|
||||
{
|
||||
/* FIXME: Support FP. */
|
||||
return 0;
|
||||
}
|
32
src/sh/offsets.h
Normal file
32
src/sh/offsets.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* Linux-specific definitions: */
|
||||
|
||||
/* Define various structure offsets to simplify cross-compilation. */
|
||||
|
||||
/* Offsets for SH Linux "ucontext_t": */
|
||||
|
||||
#define LINUX_UC_FLAGS_OFF 0x0
|
||||
#define LINUX_UC_LINK_OFF 0x4
|
||||
#define LINUX_UC_STACK_OFF 0x8
|
||||
#define LINUX_UC_MCONTEXT_OFF 0x14
|
||||
#define LINUX_UC_SIGMASK_OFF 0xFC
|
||||
|
||||
/* Offsets for SH Linux "struct sigcontext": */
|
||||
|
||||
#define LINUX_SC_R0_OFF 0x4
|
||||
#define LINUX_SC_R1_OFF 0x8
|
||||
#define LINUX_SC_R2_OFF 0xC
|
||||
#define LINUX_SC_R3_OFF 0x10
|
||||
#define LINUX_SC_R4_OFF 0x14
|
||||
#define LINUX_SC_R5_OFF 0x18
|
||||
#define LINUX_SC_R6_OFF 0x1C
|
||||
#define LINUX_SC_R7_OFF 0x20
|
||||
#define LINUX_SC_R8_OFF 0x24
|
||||
#define LINUX_SC_R9_OFF 0x28
|
||||
#define LINUX_SC_R10_OFF 0x2C
|
||||
#define LINUX_SC_R11_OFF 0x30
|
||||
#define LINUX_SC_R12_OFF 0x34
|
||||
#define LINUX_SC_R13_OFF 0x38
|
||||
#define LINUX_SC_R14_OFF 0x3C
|
||||
#define LINUX_SC_R15_OFF 0x40
|
||||
#define LINUX_SC_PC_OFF 0x44
|
||||
#define LINUX_SC_PR_OFF 0x48
|
56
src/sh/regname.c
Normal file
56
src/sh/regname.c
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2012 Tommi Rantala <tt.rantala@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 *const regname[] =
|
||||
{
|
||||
[UNW_SH_R0] = "r0",
|
||||
[UNW_SH_R1] = "r1",
|
||||
[UNW_SH_R2] = "r2",
|
||||
[UNW_SH_R3] = "r3",
|
||||
[UNW_SH_R4] = "r4",
|
||||
[UNW_SH_R5] = "r5",
|
||||
[UNW_SH_R6] = "r6",
|
||||
[UNW_SH_R7] = "r7",
|
||||
[UNW_SH_R8] = "r8",
|
||||
[UNW_SH_R9] = "r9",
|
||||
[UNW_SH_R10] = "r10",
|
||||
[UNW_SH_R11] = "r11",
|
||||
[UNW_SH_R12] = "r12",
|
||||
[UNW_SH_R13] = "r13",
|
||||
[UNW_SH_R14] = "r14",
|
||||
[UNW_SH_R15] = "r15",
|
||||
[UNW_SH_PC] = "pc",
|
||||
[UNW_SH_PR] = "pr",
|
||||
};
|
||||
|
||||
PROTECTED const char *
|
||||
unw_regname (unw_regnum_t reg)
|
||||
{
|
||||
if (reg < (unw_regnum_t) ARRAY_SIZE (regname) && regname[reg] != NULL)
|
||||
return regname[reg];
|
||||
else
|
||||
return "???";
|
||||
}
|
8
src/sh/siglongjmp.S
Normal file
8
src/sh/siglongjmp.S
Normal file
|
@ -0,0 +1,8 @@
|
|||
/* Dummy implementation for now. */
|
||||
|
||||
.globl _UI_siglongjmp_cont
|
||||
.globl _UI_longjmp_cont
|
||||
|
||||
_UI_siglongjmp_cont:
|
||||
_UI_longjmp_cont:
|
||||
rts
|
40
src/sh/unwind_i.h
Normal file
40
src/sh/unwind_i.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2012 Tommi Rantala <tt.rantala@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 <libunwind-sh.h>
|
||||
|
||||
#include "libunwind_i.h"
|
||||
|
||||
#define sh_lock UNW_OBJ(lock)
|
||||
#define sh_local_resume UNW_OBJ(local_resume)
|
||||
#define sh_local_addr_space_init UNW_OBJ(local_addr_space_init)
|
||||
|
||||
extern void sh_local_addr_space_init (void);
|
||||
extern int sh_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
|
||||
void *arg);
|
||||
|
||||
#endif /* unwind_i_h */
|
Loading…
Reference in a new issue