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

Add TileGx platform support to libunwind.

"make check" passed.
======================================================
All 34 tests behaved as expected (2 expected failures)
======================================================
Zhi-Gang Liu @ Tilera
This commit is contained in:
Zhi-Gang Liu 2014-09-02 17:35:41 -04:00
parent 4791a76d26
commit 790be1e40d
48 changed files with 1860 additions and 3 deletions

View file

@ -17,6 +17,9 @@ endif
if ARCH_MIPS if ARCH_MIPS
include_HEADERS += include/libunwind-mips.h include_HEADERS += include/libunwind-mips.h
endif endif
if ARCH_TILEGX
include_HEADERS += include/libunwind-tilegx.h
endif
if ARCH_X86 if ARCH_X86
include_HEADERS += include/libunwind-x86.h include_HEADERS += include/libunwind-x86.h
endif endif
@ -55,6 +58,8 @@ noinst_HEADERS = include/dwarf.h include/dwarf_i.h include/dwarf-eh.h \
include/tdep-hppa/jmpbuf.h include/tdep-hppa/dwarf-config.h \ include/tdep-hppa/jmpbuf.h include/tdep-hppa/dwarf-config.h \
include/tdep-mips/libunwind_i.h \ include/tdep-mips/libunwind_i.h \
include/tdep-mips/jmpbuf.h include/tdep-mips/dwarf-config.h \ include/tdep-mips/jmpbuf.h include/tdep-mips/dwarf-config.h \
include/tdep-tilegx/libunwind_i.h \
include/tdep-tilegx/jmpbuf.h include/tdep-tilegx/dwarf-config.h \
include/tdep-x86/libunwind_i.h \ include/tdep-x86/libunwind_i.h \
include/tdep-x86/jmpbuf.h include/tdep-x86/dwarf-config.h \ include/tdep-x86/jmpbuf.h include/tdep-x86/dwarf-config.h \
include/tdep-x86_64/libunwind_i.h \ include/tdep-x86_64/libunwind_i.h \
@ -84,3 +89,4 @@ MAINTAINERCLEANFILES = \
config/missing \ config/missing \
include/config.h.in \ include/config.h.in \
include/config.h.in~ include/config.h.in~

2
README
View file

@ -14,7 +14,7 @@ several architecture/operating-system combinations:
Linux/SuperH: Newly added. Linux/SuperH: Newly added.
FreeBSD/i386: Newly added. FreeBSD/i386: Newly added.
FreeBSD/x86-64: Newly added (FreeBSD architecture is known as amd64). FreeBSD/x86-64: Newly added (FreeBSD architecture is known as amd64).
Linux/Tilegx: Newly added (64-bit mode only).
* General Build Instructions * General Build Instructions

View file

@ -95,6 +95,7 @@ AC_DEFUN([SET_ARCH],[
[powerpc*],[$2=ppc$ppc_bits], [powerpc*],[$2=ppc$ppc_bits],
[sh*],[$2=sh], [sh*],[$2=sh],
[amd64],[$2=x86_64], [amd64],[$2=x86_64],
[tile*],[$2=tilegx],
[$2=$1]) [$2=$1])
]) dnl SET_ARCH ]) dnl SET_ARCH
@ -104,7 +105,7 @@ SET_ARCH([$target_cpu],[target_arch])
AC_ARG_ENABLE(coredump, AC_ARG_ENABLE(coredump,
AS_HELP_STRING([--enable-coredump],[building libunwind-coredump library]),, AS_HELP_STRING([--enable-coredump],[building libunwind-coredump library]),,
[AS_CASE([$host_arch], [aarch64*|arm*|mips*|sh*|x86*], [enable_coredump=yes], [enable_coredump=no])] [AS_CASE([$host_arch], [aarch64*|arm*|mips*|sh*|x86*|tile*], [enable_coredump=yes], [enable_coredump=no])]
) )
AC_MSG_CHECKING([if we should build libunwind-coredump]) AC_MSG_CHECKING([if we should build libunwind-coredump])
@ -149,6 +150,7 @@ AM_CONDITIONAL(ARCH_X86_64, test x$target_arch = xx86_64)
AM_CONDITIONAL(ARCH_PPC32, test x$target_arch = xppc32) AM_CONDITIONAL(ARCH_PPC32, test x$target_arch = xppc32)
AM_CONDITIONAL(ARCH_PPC64, test x$target_arch = xppc64) AM_CONDITIONAL(ARCH_PPC64, test x$target_arch = xppc64)
AM_CONDITIONAL(ARCH_SH, test x$target_arch = xsh) AM_CONDITIONAL(ARCH_SH, test x$target_arch = xsh)
AM_CONDITIONAL(ARCH_TILEGX, test x$target_arch = xtilegx)
AM_CONDITIONAL(OS_LINUX, expr x$target_os : xlinux >/dev/null) 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_HPUX, expr x$target_os : xhpux >/dev/null)
AM_CONDITIONAL(OS_FREEBSD, expr x$target_os : xfreebsd >/dev/null) AM_CONDITIONAL(OS_FREEBSD, expr x$target_os : xfreebsd >/dev/null)
@ -157,7 +159,7 @@ AM_CONDITIONAL(OS_QNX, expr x$target_os : xnto-qnx >/dev/null)
AC_MSG_CHECKING([for ELF helper width]) AC_MSG_CHECKING([for ELF helper width])
case "${target_arch}" in case "${target_arch}" in
(arm|hppa|ppc32|x86|sh) use_elf32=yes; AC_MSG_RESULT([32]);; (arm|hppa|ppc32|x86|sh) use_elf32=yes; AC_MSG_RESULT([32]);;
(aarch64|ia64|ppc64|x86_64) use_elf64=yes; AC_MSG_RESULT([64]);; (aarch64|ia64|ppc64|x86_64|tilegx) use_elf64=yes; AC_MSG_RESULT([64]);;
(mips) use_elfxx=yes; AC_MSG_RESULT([xx]);; (mips) use_elfxx=yes; AC_MSG_RESULT([xx]);;
*) AC_MSG_ERROR([Unknown ELF target: ${target_arch}]) *) AC_MSG_ERROR([Unknown ELF target: ${target_arch}])
esac esac
@ -209,6 +211,7 @@ case $target_arch in
aarch64*) enable_cxx_exceptions=no;; aarch64*) enable_cxx_exceptions=no;;
arm*) enable_cxx_exceptions=no;; arm*) enable_cxx_exceptions=no;;
mips*) enable_cxx_exceptions=no;; mips*) enable_cxx_exceptions=no;;
tile*) enable_cxx_exceptions=no;;
*) enable_cxx_exceptions=yes;; *) enable_cxx_exceptions=yes;;
esac esac
]) ])

161
include/libunwind-tilegx.h Normal file
View file

@ -0,0 +1,161 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2008 CodeSourcery
Copyright (C) 2014 Tilera Corp.
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 tilegx
#define UNW_TARGET_TILEGX 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
/* The size of a "word" varies on TILEGX. This type is used for memory
addresses and register values. */
typedef uint64_t unw_word_t;
typedef int64_t unw_sword_t;
typedef long double unw_tdep_fpreg_t;
typedef enum
{
UNW_TILEGX_R0,
UNW_TILEGX_R1,
UNW_TILEGX_R2,
UNW_TILEGX_R3,
UNW_TILEGX_R4,
UNW_TILEGX_R5,
UNW_TILEGX_R6,
UNW_TILEGX_R7,
UNW_TILEGX_R8,
UNW_TILEGX_R9,
UNW_TILEGX_R10,
UNW_TILEGX_R11,
UNW_TILEGX_R12,
UNW_TILEGX_R13,
UNW_TILEGX_R14,
UNW_TILEGX_R15,
UNW_TILEGX_R16,
UNW_TILEGX_R17,
UNW_TILEGX_R18,
UNW_TILEGX_R19,
UNW_TILEGX_R20,
UNW_TILEGX_R21,
UNW_TILEGX_R22,
UNW_TILEGX_R23,
UNW_TILEGX_R24,
UNW_TILEGX_R25,
UNW_TILEGX_R26,
UNW_TILEGX_R27,
UNW_TILEGX_R28,
UNW_TILEGX_R29,
UNW_TILEGX_R30,
UNW_TILEGX_R31,
UNW_TILEGX_R32,
UNW_TILEGX_R33,
UNW_TILEGX_R34,
UNW_TILEGX_R35,
UNW_TILEGX_R36,
UNW_TILEGX_R37,
UNW_TILEGX_R38,
UNW_TILEGX_R39,
UNW_TILEGX_R40,
UNW_TILEGX_R41,
UNW_TILEGX_R42,
UNW_TILEGX_R43,
UNW_TILEGX_R44,
UNW_TILEGX_R45,
UNW_TILEGX_R46,
UNW_TILEGX_R47,
UNW_TILEGX_R48,
UNW_TILEGX_R49,
UNW_TILEGX_R50,
UNW_TILEGX_R51,
UNW_TILEGX_R52,
UNW_TILEGX_R53,
UNW_TILEGX_R54,
UNW_TILEGX_R55,
/* FIXME: Other registers! */
UNW_TILEGX_PC,
/* For TILEGX, the CFA is the value of SP (r54) at the call site in the
previous frame. */
UNW_TILEGX_CFA,
UNW_TDEP_LAST_REG = UNW_TILEGX_PC,
UNW_TDEP_IP = UNW_TILEGX_R55, /* R55 is link register for Tilegx */
UNW_TDEP_SP = UNW_TILEGX_R54,
UNW_TDEP_EH = UNW_TILEGX_R0 /* FIXME. */
} tilegx_regnum_t;
typedef enum
{
UNW_TILEGX_ABI_N64 = 2
} tilegx_abi_t;
#define UNW_TDEP_NUM_EH_REGS 2 /* FIXME for TILEGX. */
typedef struct unw_tdep_save_loc
{
/* Additional target-dependent info on a save location. */
} unw_tdep_save_loc_t;
typedef ucontext_t unw_tdep_context_t;
#include "libunwind-dynamic.h"
typedef struct
{
/* no tilegx-specific auxiliary proc-info */
} unw_tdep_proc_info_t;
#include "libunwind-common.h"
#define unw_tdep_getcontext getcontext
#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

@ -23,6 +23,8 @@
# include "libunwind-x86.h" # include "libunwind-x86.h"
#elif defined __x86_64__ #elif defined __x86_64__
# include "libunwind-x86_64.h" # include "libunwind-x86_64.h"
#elif defined __tilegx__
# include "libunwind-tilegx.h"
#else #else
# error "Unsupported arch" # error "Unsupported arch"
#endif #endif

View file

@ -0,0 +1,50 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2008 CodeSourcery
Copyright (C) 2014 Tilera Corp.
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
/* This is FIRST_PSEUDO_REGISTER in GCC, since DWARF_FRAME_REGISTERS is not
explicitly defined. */
#define DWARF_NUM_PRESERVED_REGS 188
#define DWARF_REGNUM_MAP_LENGTH (56 + 2)
/* 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 */

View file

@ -0,0 +1,33 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2008 CodeSourcery
Copyright (C) 2014 Tilera Corp.
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: */
/* FIXME for Tilegx! */
#define JB_SP 4
#define JB_RP 5
#define JB_MASK_SAVED 6
#define JB_MASK 7

View file

@ -0,0 +1,265 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2008 CodeSourcery
Copyright (C) 2014 Tilera Corp.
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 TILEGX_LIBUNWIND_I_H
#define TILEGX_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"
#ifdef HAVE___THREAD
# undef HAVE___THREAD
#endif
typedef struct
{
/* no Tilegx-specific fast trace */
} unw_tdep_frame_t;
struct unw_addr_space
{
struct unw_accessors acc;
int big_endian;
tilegx_abi_t abi;
unsigned int addr_size;
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;
};
#define tdep_big_endian(as) ((as)->big_endian)
struct cursor
{
struct dwarf_cursor dwarf; /* must be first */
unw_word_t sigcontext_addr;
unw_word_t sigcontext_sp;
unw_word_t sigcontext_pc;
};
#define DWARF_GET_LOC(l) ((l).val)
#ifndef UNW_REMOTE_ONLY
typedef long tilegx_reg_t;
#endif
#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) (intptr_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) (intptr_t) \
tdep_uc_addr((c)->as_arg, (r)), 0))
/* Tilegx has no FP. */
static inline int
dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
{
Debug (1, "Tielgx has no fp!\n");
abort();
return 0;
}
static inline int
dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
{
Debug (1, "Tielgx has no fp!\n");
abort();
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 = *(tilegx_reg_t *) (intptr_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;
*(tilegx_reg_t *) (intptr_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))
/* TILEGX has no fp. */
static inline int
dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
{
Debug (1, "Tielgx has no fp!\n");
abort();
return 0;
}
static inline int
dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
{
Debug (1, "Tielgx has no fp!\n");
abort();
return 0;
}
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);
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);
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_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_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)
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 (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,
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 /* TILEGX_LIBUNWIND_I_H */

View file

@ -21,6 +21,8 @@
# include "tdep-x86/dwarf-config.h" # include "tdep-x86/dwarf-config.h"
#elif defined __x86_64__ || defined __amd64__ #elif defined __x86_64__ || defined __amd64__
# include "tdep-x86_64/dwarf-config.h" # include "tdep-x86_64/dwarf-config.h"
#elif defined __tilegx__
# include "tdep-tilegx/dwarf-config.h"
#else #else
# error "Unsupported arch" # error "Unsupported arch"
#endif #endif

View file

@ -21,6 +21,8 @@
# include "tdep-x86/jmpbuf.h" # include "tdep-x86/jmpbuf.h"
#elif defined __x86_64__ #elif defined __x86_64__
# include "tdep-x86_64/jmpbuf.h" # include "tdep-x86_64/jmpbuf.h"
#elif defined __tilegx__
# include "tdep-tilegx/jmpbuf.h"
#else #else
# error "Unsupported arch" # error "Unsupported arch"
#endif #endif

View file

@ -23,6 +23,8 @@
# include "tdep-x86/libunwind_i.h" # include "tdep-x86/libunwind_i.h"
#elif defined __x86_64__ #elif defined __x86_64__
# include "tdep-x86_64/libunwind_i.h" # include "tdep-x86_64/libunwind_i.h"
#elif defined __tilegx__
# include "tdep-tilegx/libunwind_i.h"
#else #else
# error "Unsupported arch" # error "Unsupported arch"
#endif #endif

View file

@ -297,6 +297,26 @@ libunwind_mips_la_SOURCES_mips = $(libunwind_la_SOURCES_mips_common) \
mips/Gglobal.c mips/Ginit.c mips/Ginit_local.c mips/Ginit_remote.c \ mips/Gglobal.c mips/Ginit.c mips/Ginit_local.c mips/Ginit_remote.c \
mips/Gis_signal_frame.c mips/Gregs.c mips/Gresume.c mips/Gstep.c mips/Gis_signal_frame.c mips/Gregs.c mips/Gresume.c mips/Gstep.c
# The list of files that go info libunwind and libunwind-tilegx:
noinst_HEADERS += tilegx/init.h tilegx/offsets.h
libunwind_la_SOURCES_tilegx_common = $(libunwind_la_SOURCES_common) \
tilegx/is_fpreg.c tilegx/regname.c
# The list of files that go into libunwind:
libunwind_la_SOURCES_tilegx = $(libunwind_la_SOURCES_tilegx_common) \
$(libunwind_la_SOURCES_local) \
tilegx/getcontext.S \
tilegx/Lcreate_addr_space.c tilegx/Lget_proc_info.c tilegx/Lget_save_loc.c \
tilegx/Lglobal.c tilegx/Linit.c tilegx/Linit_local.c tilegx/Linit_remote.c \
tilegx/Lis_signal_frame.c tilegx/Lregs.c tilegx/Lresume.c tilegx/Lstep.c
libunwind_tilegx_la_SOURCES_tilegx = $(libunwind_la_SOURCES_tilegx_common) \
$(libunwind_la_SOURCES_generic) \
tilegx/Gcreate_addr_space.c tilegx/Gget_proc_info.c tilegx/Gget_save_loc.c \
tilegx/Gglobal.c tilegx/Ginit.c tilegx/Ginit_local.c tilegx/Ginit_remote.c \
tilegx/Gis_signal_frame.c tilegx/Gregs.c tilegx/Gresume.c tilegx/Gstep.c
# The list of files that go both into libunwind and libunwind-x86: # The list of files that go both into libunwind and libunwind-x86:
noinst_HEADERS += x86/init.h x86/offsets.h x86/unwind_i.h noinst_HEADERS += x86/init.h x86/offsets.h x86/unwind_i.h
libunwind_la_SOURCES_x86_common = $(libunwind_la_SOURCES_common) \ libunwind_la_SOURCES_x86_common = $(libunwind_la_SOURCES_common) \
@ -535,6 +555,18 @@ if !REMOTE_ONLY
endif endif
libunwind_setjmp_la_SOURCES += mips/siglongjmp.S libunwind_setjmp_la_SOURCES += mips/siglongjmp.S
else else
if ARCH_TILEGX
lib_LTLIBRARIES += libunwind-tilegx.la
libunwind_la_SOURCES = $(libunwind_la_SOURCES_tilegx)
libunwind_tilegx_la_SOURCES = $(libunwind_tilegx_la_SOURCES_tilegx)
libunwind_tilegx_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION)
libunwind_tilegx_la_LIBADD = libunwind-dwarf-generic.la
libunwind_tilegx_la_LIBADD += libunwind-elfxx.la
if !REMOTE_ONLY
libunwind_tilegx_la_LIBADD += libunwind.la -lc
endif
libunwind_setjmp_la_SOURCES += tilegx/siglongjmp.S
else
if ARCH_X86 if ARCH_X86
lib_LTLIBRARIES += libunwind-x86.la lib_LTLIBRARIES += libunwind-x86.la
libunwind_la_SOURCES = $(libunwind_la_SOURCES_x86) $(libunwind_x86_la_SOURCES_os) libunwind_la_SOURCES = $(libunwind_la_SOURCES_x86) $(libunwind_x86_la_SOURCES_os)
@ -600,6 +632,7 @@ endif # ARCH_PPC64
endif # ARCH_PPC32 endif # ARCH_PPC32
endif # ARCH_X86_64 endif # ARCH_X86_64
endif # ARCH_X86 endif # ARCH_X86
endif # ARCH_TILEGX
endif # ARCH_MIPS endif # ARCH_MIPS
endif # ARCH_HPPA endif # ARCH_HPPA
endif # ARCH_IA64 endif # ARCH_IA64

View file

@ -48,6 +48,9 @@ _UCD_access_reg (unw_addr_space_t as,
#elif defined(UNW_TARGET_SH) #elif defined(UNW_TARGET_SH)
if (regnum < 0 || regnum > UNW_SH_PR) if (regnum < 0 || regnum > UNW_SH_PR)
goto badreg; goto badreg;
#elif defined(UNW_TARGET_TILEGX)
if (regnum < 0 || regnum > UNW_TILEGX_CFA)
goto badreg;
#else #else
#if defined(UNW_TARGET_MIPS) #if defined(UNW_TARGET_MIPS)
static const uint8_t remap_regs[] = static const uint8_t remap_regs[] =

View file

@ -537,6 +537,64 @@ const int _UPT_reg_offset[UNW_REG_LAST + 1] =
[UNW_AARCH64_SP] = 0xf8, [UNW_AARCH64_SP] = 0xf8,
[UNW_AARCH64_PC] = 0x100, [UNW_AARCH64_PC] = 0x100,
[UNW_AARCH64_PSTATE] = 0x108 [UNW_AARCH64_PSTATE] = 0x108
#elif defined(UNW_TARGET_TILEGX)
[UNW_TILEGX_R0] = 0x00,
[UNW_TILEGX_R1] = 0x08,
[UNW_TILEGX_R2] = 0x10,
[UNW_TILEGX_R3] = 0x08,
[UNW_TILEGX_R4] = 0x20,
[UNW_TILEGX_R5] = 0x28,
[UNW_TILEGX_R6] = 0x30,
[UNW_TILEGX_R7] = 0x38,
[UNW_TILEGX_R8] = 0x40,
[UNW_TILEGX_R9] = 0x48,
[UNW_TILEGX_R10] = 0x50,
[UNW_TILEGX_R11] = 0x58,
[UNW_TILEGX_R12] = 0x60,
[UNW_TILEGX_R13] = 0x68,
[UNW_TILEGX_R14] = 0x70,
[UNW_TILEGX_R15] = 0x78,
[UNW_TILEGX_R16] = 0x80,
[UNW_TILEGX_R17] = 0x88,
[UNW_TILEGX_R18] = 0x90,
[UNW_TILEGX_R19] = 0x98,
[UNW_TILEGX_R20] = 0xa0,
[UNW_TILEGX_R21] = 0xa8,
[UNW_TILEGX_R22] = 0xb0,
[UNW_TILEGX_R23] = 0xb8,
[UNW_TILEGX_R24] = 0xc0,
[UNW_TILEGX_R25] = 0xc8,
[UNW_TILEGX_R26] = 0xd0,
[UNW_TILEGX_R27] = 0xd8,
[UNW_TILEGX_R28] = 0xe0,
[UNW_TILEGX_R29] = 0xe8,
[UNW_TILEGX_R30] = 0xf0,
[UNW_TILEGX_R31] = 0xf8,
[UNW_TILEGX_R32] = 0x100,
[UNW_TILEGX_R33] = 0x108,
[UNW_TILEGX_R34] = 0x110,
[UNW_TILEGX_R35] = 0x118,
[UNW_TILEGX_R36] = 0x120,
[UNW_TILEGX_R37] = 0x128,
[UNW_TILEGX_R38] = 0x130,
[UNW_TILEGX_R39] = 0x138,
[UNW_TILEGX_R40] = 0x140,
[UNW_TILEGX_R41] = 0x148,
[UNW_TILEGX_R42] = 0x150,
[UNW_TILEGX_R43] = 0x158,
[UNW_TILEGX_R44] = 0x160,
[UNW_TILEGX_R45] = 0x168,
[UNW_TILEGX_R46] = 0x170,
[UNW_TILEGX_R47] = 0x178,
[UNW_TILEGX_R48] = 0x180,
[UNW_TILEGX_R49] = 0x188,
[UNW_TILEGX_R50] = 0x190,
[UNW_TILEGX_R51] = 0x198,
[UNW_TILEGX_R52] = 0x1a0,
[UNW_TILEGX_R53] = 0x1a8,
[UNW_TILEGX_R54] = 0x1b0,
[UNW_TILEGX_R55] = 0x1b8,
[UNW_TILEGX_PC] = 0x1a0
#else #else
# error Fix me. # error Fix me.
#endif #endif

View file

@ -0,0 +1,65 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2008 CodeSourcery
Copyright (C) 2014 Tilera Corp.
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;
/*
* Tilegx supports only big or little-endian, not weird stuff like
* PDP_ENDIAN.
*/
if (byte_order != 0
&& byte_order != __LITTLE_ENDIAN
&& byte_order != __BIG_ENDIAN)
return NULL;
if (byte_order == 0)
/* use host default: */
as->big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
else
as->big_endian = (byte_order == __BIG_ENDIAN);
as->abi = UNW_TILEGX_ABI_N64;
as->addr_size = 8;
return as;
#endif
}

View file

@ -0,0 +1,48 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2008 CodeSourcery
Copyright (C) 2014 Tilera Corp.
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)
{
/* On Tilegx, some routines i.e. _start() etc has no dwarf info.
Just simply mark the end of the frames. */
memset (pi, 0, sizeof (*pi));
pi->start_ip = c->dwarf.ip;
pi->end_ip = c->dwarf.ip + 1;
return 0;
}
*pi = c->dwarf.pi;
return 0;
}

View file

@ -0,0 +1,62 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2008 CodeSourcery
Copyright (C) 2014 Tilera Corp.
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;
loc = DWARF_NULL_LOC; /* default to "not saved" */
if (reg <= UNW_TILEGX_R55)
loc = c->dwarf.loc[reg - UNW_TILEGX_R0];
else
printf("\nInvalid register!");
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;
}

64
src/tilegx/Gglobal.c Normal file
View file

@ -0,0 +1,64 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2008 CodeSourcery
Copyright (C) 2014 Tilera Corp.
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"
__attribute__((weak))
pthread_mutex_t tilegx_lock = PTHREAD_MUTEX_INITIALIZER;
HIDDEN int tdep_init_done;
HIDDEN const uint8_t dwarf_to_unw_regnum_map[] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55
};
HIDDEN void
tdep_init (void)
{
intrmask_t saved_mask;
sigfillset (&unwi_full_mask);
lock_acquire (&tilegx_lock, saved_mask);
if (tdep_init_done)
/* another thread else beat us to it... */
goto out;
mi_init ();
dwarf_init ();
#ifndef UNW_REMOTE_ONLY
tilegx_local_addr_space_init ();
#endif
tdep_init_done = 1; /* signal that we're initialized... */
out:
lock_release (&tilegx_lock, saved_mask);
}

167
src/tilegx/Ginit.c Normal file
View file

@ -0,0 +1,167 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2008 CodeSourcery
Copyright (C) 2014 Tilera Corp.
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;
/* Return the address of the 64-bit slot in UC for REG (even for o32,
where registers are 32-bit, the slots are still 64-bit). */
static inline void *
uc_addr (ucontext_t *uc, int reg)
{
if (reg >= UNW_TILEGX_R0 && reg < UNW_TILEGX_R0 + 56)
return &uc->uc_mcontext.gregs[reg - UNW_TILEGX_R0];
else if (reg == UNW_TILEGX_PC)
return &uc->uc_mcontext.pc;
else
return NULL;
}
# ifdef UNW_LOCAL_ONLY
HIDDEN void *
tdep_uc_addr (ucontext_t *uc, int reg)
{
char *addr = uc_addr (uc, reg);
return addr;
}
# 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) (intptr_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 ((long long)addr & (sizeof(unw_word_t) - 1))
return 0;
if (write)
{
Debug (16, "mem[%llx] <- %llx\n", (long long) addr, (long long) *val);
*(unw_word_t *) (intptr_t) addr = *val;
}
else
{
*val = *(unw_word_t *) (intptr_t) addr;
Debug (16, "mem[%llx] -> %llx\n", (long long) addr, (long long) *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;
Debug (16, "reg = %s\n", unw_regname (reg));
if (!(addr = uc_addr (uc, reg)))
goto badreg;
if (write)
{
*(unw_word_t *) (intptr_t) addr = (tilegx_reg_t) *val;
Debug (12, "%s <- %llx\n", unw_regname (reg), (long long) *val);
}
else
{
*val = (tilegx_reg_t) *(unw_word_t *) (intptr_t) addr;
Debug (12, "%s -> %llx\n", unw_regname (reg), (long long) *val);
}
return 0;
badreg:
Debug (1, "bad register number %u\n", reg);
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 elf_w (get_proc_name) (as, getpid (), ip, buf, buf_len, offp);
}
__attribute__((weak)) void
tilegx_local_addr_space_init (void)
{
memset (&local_addr_space, 0, sizeof (local_addr_space));
local_addr_space.big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
local_addr_space.abi = UNW_TILEGX_ABI_N64;
local_addr_space.addr_size = sizeof (void *);
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 = NULL;
local_addr_space.acc.resume = tilegx_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 */

57
src/tilegx/Ginit_local.c Normal file
View file

@ -0,0 +1,57 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2008 CodeSourcery
Copyright (C) 2014 Tilera Corp.
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)
{
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_init_done)
tdep_init ();
memset(c, 0, sizeof(unw_cursor_t));
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 */

47
src/tilegx/Ginit_remote.c Normal file
View file

@ -0,0 +1,47 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2008 CodeSourcery
Copyright (C) 2014 Tilera Corp.
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 */
}

View file

@ -0,0 +1,115 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2008 CodeSourcery
Copyright (C) 2014 Tilera Corp.
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 <stdio.h>
#include "offsets.h"
#ifdef __linux__
#include <sys/syscall.h>
#include <arch/abi.h>
#else
# error "Only support Linux!"
#endif
#define MOVELI_R10_RT_SIGRETURN \
( 0x000007e051483000ULL | \
((unsigned long)__NR_rt_sigreturn << 43) | \
((unsigned long)TREG_SYSCALL_NR << 31) )
#define SWINT1 0x286b180051485000ULL
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;
a = unw_get_accessors (as);
arg = c->dwarf.as_arg;
ip = c->dwarf.ip;
if (!ip || !a->access_mem || (ip & (sizeof(unw_word_t) - 1)))
return 0;
if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0)
return ret;
if ((ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0)
return ret;
/* Return 1 if the IP points to a RT sigreturn sequence. */
if (w0 == MOVELI_R10_RT_SIGRETURN &&
w1 == SWINT1)
{
return 1;
}
return 0;
}
PROTECTED int
unw_handle_signal_frame (unw_cursor_t *cursor)
{
int i;
struct cursor *c = (struct cursor *) cursor;
unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa;
struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0);
int ret;
if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0)
return -UNW_EUNSPEC;
/* 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;
c->sigcontext_addr = sp_addr + sizeof (siginfo_t) +
C_ABI_SAVE_AREA_SIZE;
sc_addr = c->sigcontext_addr + LINUX_UC_MCONTEXT_OFF;
/* Update the dwarf cursor.
Set the location of the registers to the corresponding addresses of the
uc_mcontext / sigcontext structure contents. */
#define SC_REG_OFFSET(X) (8 * X)
for (i = UNW_TILEGX_R0; i <= UNW_TILEGX_R55; i++)
{
c->dwarf.loc[i] = DWARF_LOC (sc_addr + SC_REG_OFFSET(i), 0);
}
/* Set SP/CFA and PC/IP. */
dwarf_get (&c->dwarf, c->dwarf.loc[UNW_TILEGX_R54], &c->dwarf.cfa);
dwarf_get (&c->dwarf, c->dwarf.loc[UNW_TILEGX_R55], &c->dwarf.ip);
return 1;
}

66
src/tilegx/Gregs.c Normal file
View file

@ -0,0 +1,66 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2008 CodeSourcery
Copyright (C) 2014 Tilera Corp.
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;
if (reg == UNW_TILEGX_R54 && !write)
{
reg = UNW_TILEGX_CFA;
}
if (reg <= UNW_TILEGX_R55)
loc = c->dwarf.loc[reg - UNW_TILEGX_R0];
else if (reg == UNW_TILEGX_CFA)
{
if (write)
return -UNW_EREADONLYREG;
*valp = c->dwarf.cfa;
return 0;
}
else
{
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;
}

94
src/tilegx/Gresume.c Normal file
View file

@ -0,0 +1,94 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2008 CodeSourcery
Copyright (C) 2014 Tilera Corp.
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"
#include <ucontext.h>
#ifndef UNW_REMOTE_ONLY
HIDDEN inline int
tilegx_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
{
int i;
struct cursor *c = (struct cursor *) cursor;
ucontext_t *uc = c->dwarf.as_arg;
Debug (1, "(cursor=%p\n", c);
return setcontext(uc);
}
#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))
{
Debug (1, "no fp!");
abort ();
}
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) ip=0x%lx\n", c, c->dwarf.ip);
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);
}

53
src/tilegx/Gstep.c Normal file
View file

@ -0,0 +1,53 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2008 CodeSourcery
Copyright (C) 2014 Tilera Corp.
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_step (unw_cursor_t *cursor)
{
struct cursor *c = (struct cursor *) cursor;
int ret;
Debug (1, "(cursor=%p, ip=0x%016lx, sp=0x%016lx)\n",
c, c->dwarf.ip, c->dwarf.cfa);
/* Special handling the singal frame. */
if (unw_is_signal_frame (cursor))
return unw_handle_signal_frame (cursor);
/* Try DWARF-based unwinding... */
ret = dwarf_step (&c->dwarf);
if (unlikely (ret == -UNW_ESTOPUNWIND))
return ret;
/* Dwarf unwinding didn't work, stop. */
if (unlikely (ret < 0))
return 0;
return (c->dwarf.ip == 0) ? 0 : 1;
}

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/tilegx/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/tilegx/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/tilegx/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

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/tilegx/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/tilegx/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/tilegx/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

27
src/tilegx/elfxx.c Normal file
View file

@ -0,0 +1,27 @@
/* 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"
#include "../src/elfxx.c"

30
src/tilegx/gen-offsets.c Normal file
View file

@ -0,0 +1,30 @@
#include <stdio.h>
#include <stddef.h>
#include <ucontext.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 TILEGX 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);
UC ("MCONTEXT_GREGS", uc_mcontext.gregs);
return 0;
}

36
src/tilegx/getcontext.S Normal file
View file

@ -0,0 +1,36 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2008 CodeSourcery
Copyright (C) 2014 Tilera Corp.
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 "offsets.h"
#include <endian.h>
.text
# define REG(X) LINUX_UC_MCONTEXT_GREGS + 8 * (X)
.global _Utilegx_getcontext
.type _Utilegx_getcontext, %function
# This is a stub version of getcontext() for TILEGX.
_Utilegx_getcontext:

64
src/tilegx/init.h Normal file
View file

@ -0,0 +1,64 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2008 CodeSourcery
Copyright (C) 2014 Tilera Corp.
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, i;
for (i = 0; i < 56; i++)
c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_R0 + i);
for (i = 56; i < DWARF_NUM_PRESERVED_REGS; ++i)
c->dwarf.loc[i] = DWARF_NULL_LOC;
if (use_prev_instr == 0)
ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_PC),
&c->dwarf.ip);
else
ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_R55),
&c->dwarf.ip);
if (ret < 0)
return ret;
ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_R54),
&c->dwarf.cfa);
if (ret < 0)
return ret;
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;
}

33
src/tilegx/is_fpreg.c Normal file
View file

@ -0,0 +1,33 @@
/* 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"
/* TILEGX has no FP. */
PROTECTED int
unw_is_fpreg (int regnum)
{
return 0;
}

12
src/tilegx/offsets.h Normal file
View file

@ -0,0 +1,12 @@
/* Linux-specific definitions: */
/* Define various structure offsets to simplify cross-compilation. */
/* Offsets for TILEGX Linux "ucontext_t": */
#define LINUX_UC_FLAGS_OFF 0x0
#define LINUX_UC_LINK_OFF 0x8
#define LINUX_UC_STACK_OFF 0x10
#define LINUX_UC_MCONTEXT_OFF 0x28
#define LINUX_UC_SIGMASK_OFF 0x228
#define LINUX_UC_MCONTEXT_GREGS 0x28

55
src/tilegx/regname.c Normal file
View file

@ -0,0 +1,55 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2008 CodeSourcery
Copyright (C) 2014 Tilera Corp.
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[] =
{
/* 0. */
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
/* 8. */
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
/* 16. */
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
/* 24. */
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
/* 32. */
"r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
/* 40. */
"r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
/* 48. */
"r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
/* pc, cfa */
"pc", "cfa"
};
PROTECTED const char *
unw_regname (unw_regnum_t reg)
{
if (reg < (unw_regnum_t) ARRAY_SIZE (regname))
return regname[reg];
else
return "???";
}

7
src/tilegx/siglongjmp.S Normal file
View file

@ -0,0 +1,7 @@
/* Dummy implementation for now. */
.globl _UI_siglongjmp_cont
.globl _UI_longjmp_cont
_UI_siglongjmp_cont:
_UI_longjmp_cont:
jrp lr

44
src/tilegx/unwind_i.h Normal file
View file

@ -0,0 +1,44 @@
/* 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. */
#ifndef unwind_i_h
#define unwind_i_h
#include <memory.h>
#include <stdint.h>
#include <libunwind-tilegx.h>
#include "libunwind_i.h"
#define tilegx_local_resume UNW_OBJ(local_resume)
#define tilegx_local_addr_space_init UNW_OBJ(local_addr_space_init)
extern int tilegx_local_resume (unw_addr_space_t as,
unw_cursor_t *cursor,
void *arg);
extern void tilegx_local_addr_space_init (void);
#endif /* unwind_i_h */

View file

@ -115,6 +115,11 @@ handler (int sig)
if ((ret = unw_step (&c)) < 0) /* step to kill() */ if ((ret = unw_step (&c)) < 0) /* step to kill() */
panic ("unw_step(2) failed: ret=%d\n", ret); panic ("unw_step(2) failed: ret=%d\n", ret);
#if defined(UNW_TARGET_TILEGX)
if ((ret = unw_step (&c)) < 0) /* step to signal trampoline */
panic ("unw_step(2) failed: ret=%d\n", ret);
#endif
if ((ret = unw_get_reg (&c, UNW_REG_IP, &ip)) < 0) if ((ret = unw_get_reg (&c, UNW_REG_IP, &ip)) < 0)
panic ("unw_get_reg(IP) failed: ret=%d\n", ret); panic ("unw_get_reg(IP) failed: ret=%d\n", ret);
if (verbose) if (verbose)

View file

@ -158,6 +158,15 @@ check_local_unw_abi () {
match _UL${plat}_dwarf_search_unwind_table match _UL${plat}_dwarf_search_unwind_table
match _UL${plat}_dwarf_find_unwind_table match _UL${plat}_dwarf_find_unwind_table
;; ;;
tilegx)
match _U${plat}_is_fpreg
match _UL${plat}_dwarf_search_unwind_table
match _UL${plat}_dwarf_find_unwind_table
match _UL${plat}_local_addr_space_init
match _U${plat}_get_elf_image
match ${plat}_lock
;;
*) *)
match _U${plat}_is_fpreg match _U${plat}_is_fpreg
match _UL${plat}_dwarf_search_unwind_table match _UL${plat}_dwarf_search_unwind_table
@ -239,6 +248,14 @@ check_generic_unw_abi () {
match _U${plat}_dwarf_search_unwind_table match _U${plat}_dwarf_search_unwind_table
match _U${plat}_dwarf_find_unwind_table match _U${plat}_dwarf_find_unwind_table
;; ;;
tilegx)
match _U${plat}_dwarf_search_unwind_table
match _U${plat}_dwarf_find_unwind_table
match _U${plat}_get_elf_image
match _U${plat}_is_fpreg
match _U${plat}_local_addr_space_init
match ${plat}_lock
;;
*) *)
match _U${plat}_is_fpreg match _U${plat}_is_fpreg
match _U${plat}_dwarf_search_unwind_table match _U${plat}_dwarf_search_unwind_table

View file

@ -77,7 +77,21 @@ flush_cache:
.globl flush_cache .globl flush_cache
flush_cache: flush_cache:
bx lr bx lr
#elif defined(__tilegx__)
.text
.globl flush_cache
flush_cache:
andi r0, r0, -64
1: {
flush r0 ;
addi r0, r0, 64
}
{
bgtz r1, 1b ;
addi r1, r1, -64
}
jrp lr
#else #else
# error Need flush_cache code for this architecture. # error Need flush_cache code for this architecture.
#endif #endif