1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-05-29 07:32:37 +02:00

Initial revision

This commit is contained in:
hp.com!davidm 2005-05-20 09:48:08 +00:00
parent 3e8a50255c
commit 180a1ececa
16 changed files with 0 additions and 1446 deletions

View file

@ -1,286 +0,0 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2001-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.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. */
/* This files contains libunwind-internal definitions which are
subject to frequent change and are not to be exposed to
libunwind-users. */
#ifndef libunwind_i_h
#define libunwind_i_h
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE___THREAD
/* For now, turn off per-thread caching. It uses up too much TLS
memory per thread even when the thread never uses libunwind at
all. */
# undef HAVE___THREAD
#endif
/* Platform-independent libunwind-internal declarations. */
#include <sys/types.h> /* HP-UX needs this before include of pthread.h */
#include <assert.h>
#include <libunwind.h>
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef HAVE_ENDIAN_H
# include <endian.h>
#else
# define __LITTLE_ENDIAN 1234
# define __BIG_ENDIAN 4321
# if defined(__hpux)
# define __BYTE_ORDER __BIG_ENDIAN
# else
# error Host has unknown byte-order.
# endif
#endif
#ifdef __GNUC__
# define UNUSED __attribute__((unused))
# define NORETURN __attribute__((noreturn))
# define ALIAS(name) __attribute__((alias (#name)))
# if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
# define ALWAYS_INLINE inline __attribute__((always_inline))
# define HIDDEN __attribute__((visibility ("hidden")))
# define PROTECTED __attribute__((visibility ("protected")))
# else
# define ALWAYS_INLINE
# define HIDDEN
# define PROTECTED
# endif
# if (__GNUC__ >= 3)
# define likely(x) __builtin_expect ((x), 1)
# define unlikely(x) __builtin_expect ((x), 0)
# else
# define likely(x) (x)
# define unlikely(x) (x)
# endif
#else
# define ALWAYS_INLINE
# define UNUSED
# define NORETURN
# define ALIAS(name)
# define HIDDEN
# define PROTECTED
# define likely(x) (x)
# define unlikely(x) (x)
#endif
#ifdef DEBUG
# define UNW_DEBUG 1
#else
# define UNW_DEBUG 0
#endif
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
/* Make it easy to write thread-safe code which may or may not be
linked against libpthread. The macros below can be used
unconditionally and if -lpthread is around, they'll call the
corresponding routines otherwise, they do nothing. */
#pragma weak pthread_mutex_init
#pragma weak pthread_mutex_lock
#pragma weak pthread_mutex_unlock
#define mutex_init(l) \
(pthread_mutex_init != 0 ? pthread_mutex_init ((l), 0) : 0)
#define mutex_lock(l) \
(pthread_mutex_lock != 0 ? pthread_mutex_lock (l) : 0)
#define mutex_unlock(l) \
(pthread_mutex_unlock != 0 ? pthread_mutex_unlock (l) : 0)
#ifdef HAVE_ATOMIC_OPS_H
# include <atomic_ops.h>
static inline int
cmpxchg_ptr (void *addr, void *old, void *new)
{
union
{
void *vp;
AO_t *aop;
}
u;
u.vp = addr;
return AO_compare_and_swap(u.aop, (AO_t) old, (AO_t) new);
}
# define fetch_and_add1(_ptr) AO_fetch_and_add1(_ptr)
/* GCC 3.2.0 on HP-UX crashes on cmpxchg_ptr() */
# if !(defined(__hpux) && __GNUC__ == 3 && __GNUC_MINOR__ == 2)
# define HAVE_CMPXCHG
# endif
# define HAVE_FETCH_AND_ADD1
#else
# ifdef HAVE_IA64INTRIN_H
# include <ia64intrin.h>
static inline int
cmpxchg_ptr (void *addr, void *old, void *new)
{
union
{
void *vp;
long *vlp;
}
u;
u.vp = addr;
return __sync_bool_compare_and_swap(u.vlp, (long) old, (long) new);
}
# define fetch_and_add1(_ptr) __sync_fetch_and_add(_ptr, 1)
# define HAVE_CMPXCHG
# define HAVE_FETCH_AND_ADD1
# endif
#endif
#define atomic_read(ptr) (*(ptr))
#define UNWI_OBJ(fn) UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn))
#define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn)
#define unwi_full_mask UNWI_ARCH_OBJ(full_mask)
/* Type of a mask that can be used to inhibit preemption. At the
userlevel, preemption is caused by signals and hence sigset_t is
appropriate. In constrast, the Linux kernel uses "unsigned long"
to hold the processor "flags" instead. */
typedef sigset_t intrmask_t;
extern intrmask_t unwi_full_mask;
#define define_lock(name) \
pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER
#define lock_init(l) mutex_init (l)
#define lock_acquire(l,m) \
do { \
sigprocmask (SIG_SETMASK, &unwi_full_mask, &(m)); \
mutex_lock (l); \
} while (0)
#define lock_release(l,m) \
do { \
mutex_unlock (l); \
sigprocmask (SIG_SETMASK, &(m), NULL); \
} while (0)
#define GET_MEMORY(mem, size_in_bytes) \
do { \
/* Hopefully, mmap() goes straight through to a system call stub... */ \
mem = mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, \
-1, 0); \
if (mem == MAP_FAILED) \
mem = NULL; \
} while (0)
#define unwi_find_dynamic_proc_info UNWI_OBJ(find_dynamic_proc_info)
#define unwi_extract_dynamic_proc_info UNWI_OBJ(extract_dynamic_proc_info)
#define unwi_put_dynamic_unwind_info UNWI_OBJ(put_dynamic_unwind_info)
#define unwi_dyn_remote_find_proc_info UNWI_OBJ(dyn_remote_find_proc_info)
#define unwi_dyn_remote_put_unwind_info UNWI_OBJ(dyn_remote_put_unwind_info)
#define unwi_dyn_validate_cache UNWI_OBJ(dyn_validate_cache)
extern int unwi_find_dynamic_proc_info (unw_addr_space_t as,
unw_word_t ip,
unw_proc_info_t *pi,
int need_unwind_info, void *arg);
extern int unwi_extract_dynamic_proc_info (unw_addr_space_t as,
unw_word_t ip,
unw_proc_info_t *pi,
unw_dyn_info_t *di,
int need_unwind_info,
void *arg);
extern void unwi_put_dynamic_unwind_info (unw_addr_space_t as,
unw_proc_info_t *pi, void *arg);
/* These handle the remote (cross-address-space) case of accessing
dynamic unwind info. */
extern int unwi_dyn_remote_find_proc_info (unw_addr_space_t as,
unw_word_t ip,
unw_proc_info_t *pi,
int need_unwind_info,
void *arg);
extern void unwi_dyn_remote_put_unwind_info (unw_addr_space_t as,
unw_proc_info_t *pi,
void *arg);
extern int unwi_dyn_validate_cache (unw_addr_space_t as, void *arg);
extern unw_dyn_info_list_t _U_dyn_info_list;
extern pthread_mutex_t _U_dyn_info_list_lock;
#if UNW_DEBUG
#define unwi_debug_level UNWI_ARCH_OBJ(debug_level)
extern long unwi_debug_level;
# include <stdio.h>
# define Debug(level,format...) \
do { \
if (unwi_debug_level >= level) \
{ \
int _n = level; \
if (_n > 16) \
_n = 16; \
fprintf (stderr, "%*c>%s: ", _n, ' ', __FUNCTION__); \
fprintf (stderr, format); \
} \
} while (0)
# define dprintf(format...) fprintf (stderr, format)
# ifdef __GNUC__
# undef inline
# define inline UNUSED
# endif
#else
# define Debug(level,format...)
# define dprintf(format...)
#endif
static ALWAYS_INLINE void
print_error (const char *string)
{
write (2, string, strlen (string));
}
#define mi_init UNWI_ARCH_OBJ(mi_init)
extern void mi_init (void); /* machine-independent initializations */
extern unw_word_t _U_dyn_info_list_addr (void);
/* This is needed/used by ELF targets only. */
struct elf_image
{
void *image; /* pointer to mmap'd image */
size_t size; /* (file-) size of the image */
};
#include "tdep/libunwind_i.h"
#endif /* libunwind_i_h */

View file

View file

View file

@ -1,260 +0,0 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2003-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.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 HPPA_LIBUNWIND_I_H
#define HPPA_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 "dwarf.h"
struct unw_addr_space
{
struct unw_accessors acc;
unw_caching_policy_t caching_policy;
#ifdef HAVE_ATOMIC_OPS_H
AO_t cache_generation;
#else
uint32_t cache_generation;
#endif
unw_word_t dyn_generation; /* see dyn-common.h */
unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
};
struct cursor
{
struct dwarf_cursor dwarf; /* must be first */
/* Format of sigcontext structure and address at which it is
stored: */
enum
{
HPPA_SCF_NONE, /* no signal frame encountered */
HPPA_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */
}
sigcontext_format;
unw_word_t sigcontext_addr;
};
#define DWARF_GET_LOC(l) ((l).val)
#ifdef UNW_LOCAL_ONLY
# define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0)
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) })
# define DWARF_IS_REG_LOC(l) 0
# define DWARF_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_needs_initialization UNW_OBJ(needs_initialization)
#define tdep_init UNW_OBJ(init)
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
tdep_search_unwind_table. */
#define tdep_search_unwind_table dwarf_search_unwind_table
#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr)
#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image)
#define tdep_access_reg UNW_OBJ(access_reg)
#define tdep_access_fpreg UNW_OBJ(access_fpreg)
#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(c,pi) \
dwarf_put_unwind_info((c)->as, (pi), (c)->as_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(c,pi) \
(*(c)->as->acc.put_unwind_info)((c)->as, (pi), (c)->as_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) 1
extern int tdep_needs_initialization;
extern void tdep_init (void);
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
unw_dyn_info_t *di, unw_proc_info_t *pi,
int need_unwind_info, void *arg);
extern void *tdep_uc_addr (ucontext_t *uc, int reg);
extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff);
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write);
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t *valp, int write);
#endif /* HPPA_LIBUNWIND_I_H */

View file

View file

@ -1,255 +0,0 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2001-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.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 IA64_LIBUNWIND_I_H
#define IA64_LIBUNWIND_I_H
/* Target-dependent definitions that are internal to libunwind but need
to be shared with target-independent code. */
#include "elf64.h"
#include "mempool.h"
enum ia64_pregnum
{
/* primary unat: */
IA64_REG_PRI_UNAT_GR,
IA64_REG_PRI_UNAT_MEM,
/* memory stack (order matters: see build_script() */
IA64_REG_PSP, /* previous memory stack pointer */
/* register stack */
IA64_REG_BSP, /* register stack pointer */
IA64_REG_BSPSTORE,
IA64_REG_PFS, /* previous function state */
IA64_REG_RNAT,
/* instruction pointer: */
IA64_REG_IP,
/* preserved registers: */
IA64_REG_R4, IA64_REG_R5, IA64_REG_R6, IA64_REG_R7,
IA64_REG_NAT4, IA64_REG_NAT5, IA64_REG_NAT6, IA64_REG_NAT7,
IA64_REG_UNAT, IA64_REG_PR, IA64_REG_LC, IA64_REG_FPSR,
IA64_REG_B1, IA64_REG_B2, IA64_REG_B3, IA64_REG_B4, IA64_REG_B5,
IA64_REG_F2, IA64_REG_F3, IA64_REG_F4, IA64_REG_F5,
IA64_REG_F16, IA64_REG_F17, IA64_REG_F18, IA64_REG_F19,
IA64_REG_F20, IA64_REG_F21, IA64_REG_F22, IA64_REG_F23,
IA64_REG_F24, IA64_REG_F25, IA64_REG_F26, IA64_REG_F27,
IA64_REG_F28, IA64_REG_F29, IA64_REG_F30, IA64_REG_F31,
IA64_NUM_PREGS
};
#ifdef UNW_LOCAL_ONLY
typedef unw_word_t ia64_loc_t;
#else /* !UNW_LOCAL_ONLY */
typedef struct ia64_loc
{
unw_word_t w0, w1;
}
ia64_loc_t;
#endif /* !UNW_LOCAL_ONLY */
#include "script.h"
#define ABI_UNKNOWN 0
#define ABI_LINUX 1
#define ABI_HPUX 2
#define ABI_FREEBSD 3
#define ABI_OPENVMS 4
#define ABI_NSK 5 /* Tandem/HP Non-Stop Kernel */
#define ABI_WINDOWS 6
struct unw_addr_space
{
struct unw_accessors acc;
int big_endian;
int abi; /* abi < 0 => unknown, 0 => SysV, 1 => HP-UX, 2 => Windows */
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;
unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
#ifndef UNW_REMOTE_ONLY
unsigned long long shared_object_removals;
#endif
struct ia64_script_cache global_cache;
};
/* Note: The ABI numbers in the ABI-markers (.unwabi directive) are
not the same as the above ABI numbers. */
#define ABI_MARKER_OLD_LINUX_SIGTRAMP ((0 << 8) | 's')
#define ABI_MARKER_OLD_LINUX_INTERRUPT ((0 << 8) | 'i')
#define ABI_MARKER_HP_UX_SIGTRAMP ((1 << 8) | 1)
#define ABI_MARKER_LINUX_SIGTRAMP ((3 << 8) | 's')
#define ABI_MARKER_LINUX_INTERRUPT ((3 << 8) | 'i')
struct cursor
{
void *as_arg; /* argument to address-space callbacks */
unw_addr_space_t as; /* reference to per-address-space info */
/* IP, CFM, and predicate cache (these are always equal to the
values stored in ip_loc, cfm_loc, and pr_loc,
respectively). */
unw_word_t ip; /* instruction pointer value */
unw_word_t cfm; /* current frame mask */
unw_word_t pr; /* current predicate values */
/* current frame info: */
unw_word_t bsp; /* backing store pointer value */
unw_word_t sp; /* stack pointer value */
unw_word_t psp; /* previous sp value */
ia64_loc_t cfm_loc; /* cfm save location (or NULL) */
ia64_loc_t ec_loc; /* ar.ec save location (usually cfm_loc) */
ia64_loc_t loc[IA64_NUM_PREGS];
unw_word_t eh_args[4]; /* exception handler arguments */
unw_word_t sigcontext_addr; /* address of sigcontext or 0 */
unw_word_t sigcontext_off; /* sigcontext-offset relative to signal sp */
short hint;
short prev_script;
uint8_t nat_bitnr[4]; /* NaT bit numbers for r4-r7 */
uint16_t abi_marker; /* abi_marker for current frame (if any) */
uint16_t last_abi_marker; /* last abi_marker encountered so far */
uint8_t eh_valid_mask;
unsigned int pi_valid :1; /* is proc_info valid? */
unsigned int pi_is_dynamic :1; /* proc_info found via dynamic proc info? */
unw_proc_info_t pi; /* info about current procedure */
/* In case of stack-discontiguities, such as those introduced by
signal-delivery on an alternate signal-stack (see
sigaltstack(2)), we use the following data-structure to keep
track of the register-backing-store areas across on which the
current frame may be backed up. Since there are at most 96
stacked registers and since we only have to track the current
frame and only areas that are not empty, this puts an upper
limit on the # of backing-store areas we have to track.
Note that the rbs-area indexed by rbs_curr identifies the
rbs-area that was in effect at the time AR.BSP had the value
c->bsp. However, this rbs area may not actually contain the
value in the register that c->bsp corresponds to because that
register may not have gotten spilled until much later, when a
possibly different rbs-area might have been in effect
already. */
uint8_t rbs_curr; /* index of curr. rbs-area (contains c->bsp) */
uint8_t rbs_left_edge; /* index of inner-most valid rbs-area */
struct rbs_area
{
unw_word_t end;
unw_word_t size;
ia64_loc_t rnat_loc;
}
rbs_area[96 + 2]; /* 96 stacked regs + 1 extra stack on each side... */
};
struct ia64_global_unwind_state
{
pthread_mutex_t lock; /* global data lock */
volatile char needs_initialization;
/* Table of registers that prologues can save (and order in which
they're saved). */
const unsigned char save_order[8];
/*
* uc_addr() may return pointers to these variables. We need to
* make sure they don't get written via ia64_put() or
* ia64_putfp(). To make it possible to test for these variables
* quickly, we collect them in a single sub-structure.
*/
struct
{
unw_word_t r0; /* r0 is byte-order neutral */
unw_fpreg_t f0; /* f0 is byte-order neutral */
unw_fpreg_t f1_le, f1_be; /* f1 is byte-order dependent */
}
read_only;
unw_fpreg_t nat_val_le, nat_val_be;
unw_fpreg_t int_val_le, int_val_be;
struct mempool reg_state_pool;
struct mempool labeled_state_pool;
# if UNW_DEBUG
const char *preg_name[IA64_NUM_PREGS];
# endif
};
#define tdep_needs_initialization unw.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 unw_search_ia64_unwind_table
#define tdep_find_proc_info UNW_OBJ(find_proc_info)
#define tdep_uc_addr UNW_OBJ(uc_addr)
#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image)
#define tdep_access_reg UNW_OBJ(access_reg)
#define tdep_access_fpreg UNW_OBJ(access_fpreg)
#define tdep_get_as(c) ((c)->as)
#define tdep_get_as_arg(c) ((c)->as_arg)
#define tdep_get_ip(c) ((c)->ip)
#define tdep_big_endian(as) ((c)->as->big_endian != 0)
#ifndef UNW_LOCAL_ONLY
# define tdep_put_unwind_info UNW_OBJ(put_unwind_info)
#endif
/* This can't be an UNW_ARCH_OBJ() because we need separate
unw.initialized flags for the local-only and generic versions of
the library. Also, if we wanted to have a single, shared global
data structure, we couldn't declare "unw" as HIDDEN/PROTECTED. */
#define unw UNW_OBJ(data)
extern void tdep_init (void);
extern int tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip,
unw_proc_info_t *pi, int need_unwind_info,
void *arg);
extern void tdep_put_unwind_info (unw_addr_space_t as,
unw_proc_info_t *pi, void *arg);
extern void *tdep_uc_addr (ucontext_t *uc, unw_regnum_t regnum,
uint8_t *nat_bitnr);
extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff);
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write);
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t *valp, int write);
extern struct ia64_global_unwind_state unw;
#endif /* IA64_LIBUNWIND_I_H */

View file

@ -1,67 +0,0 @@
/*
* Copyright (C) 1998, 1999, 2002, 2003, 2005 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*
* Register stack engine related helper functions. This file may be
* used in applications, so be careful about the name-space and give
* some consideration to non-GNU C compilers (though __inline__ is
* fine).
*/
#ifndef RSE_H
#define RSE_H
#include <libunwind.h>
static inline uint64_t
rse_slot_num (uint64_t addr)
{
return (addr >> 3) & 0x3f;
}
/*
* Return TRUE if ADDR is the address of an RNAT slot.
*/
static inline uint64_t
rse_is_rnat_slot (uint64_t addr)
{
return rse_slot_num (addr) == 0x3f;
}
/*
* Returns the address of the RNAT slot that covers the slot at
* address SLOT_ADDR.
*/
static inline uint64_t
rse_rnat_addr (uint64_t slot_addr)
{
return slot_addr | (0x3f << 3);
}
/*
* Calculate the number of registers in the dirty partition starting at
* BSPSTORE and ending at BSP. This isn't simply (BSP-BSPSTORE)/8
* because every 64th slot stores ar.rnat.
*/
static inline uint64_t
rse_num_regs (uint64_t bspstore, uint64_t bsp)
{
uint64_t slots = (bsp - bspstore) >> 3;
return slots - (rse_slot_num(bspstore) + slots)/0x40;
}
/*
* The inverse of the above: given bspstore and the number of
* registers, calculate ar.bsp.
*/
static inline uint64_t
rse_skip_regs (uint64_t addr, long num_regs)
{
long delta = rse_slot_num(addr) + num_regs;
if (num_regs < 0)
delta -= 0x3e;
return addr + ((num_regs + delta/0x3f) << 3);
}
#endif /* RSE_H */

View file

View file

View file

View file

@ -1,261 +0,0 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2002-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.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 X86_LIBUNWIND_I_H
#define X86_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 "dwarf.h"
struct unw_addr_space
{
struct unw_accessors acc;
unw_caching_policy_t caching_policy;
#ifdef HAVE_ATOMIC_OPS_H
AO_t cache_generation;
#else
uint32_t cache_generation;
#endif
unw_word_t dyn_generation; /* see dyn-common.h */
unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
};
struct cursor
{
struct dwarf_cursor dwarf; /* must be first */
/* Format of sigcontext structure and address at which it is
stored: */
enum
{
X86_SCF_NONE, /* no signal frame encountered */
X86_SCF_LINUX_SIGFRAME, /* classic x86 sigcontext */
X86_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */
}
sigcontext_format;
unw_word_t sigcontext_addr;
};
#define DWARF_GET_LOC(l) ((l).val)
#ifdef UNW_LOCAL_ONLY
# define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0)
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) })
# define DWARF_IS_REG_LOC(l) 0
# define DWARF_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_needs_initialization UNW_OBJ(needs_initialization)
#define tdep_init UNW_OBJ(init)
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
tdep_search_unwind_table. */
#define tdep_search_unwind_table dwarf_search_unwind_table
#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr)
#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image)
#define tdep_access_reg UNW_OBJ(access_reg)
#define tdep_access_fpreg UNW_OBJ(access_fpreg)
#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) 0
extern int tdep_needs_initialization;
extern void tdep_init (void);
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
unw_dyn_info_t *di, unw_proc_info_t *pi,
int need_unwind_info, void *arg);
extern void *tdep_uc_addr (ucontext_t *uc, int reg);
extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff);
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write);
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t *valp, int write);
#endif /* X86_LIBUNWIND_I_H */

View file

@ -1,55 +0,0 @@
/* libunwind - a platform-independent unwind library
Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
This file is part of libunwind.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* copy of include/tdep-x86/dwarf-config.h, modified slightly for x86-64
some consolidation is possible here */
#ifndef dwarf_config_h
#define dwarf_config_h
/* XXX need to verify if this value is correct */
#define DWARF_NUM_PRESERVED_REGS 17
#define DWARF_REGNUM_MAP_LENGTH 17
/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */
#define dwarf_is_big_endian(addr_space) 0
/* Convert a pointer to a dwarf_cursor structure to a pointer to
unw_cursor_t. */
#define dwarf_to_cursor(c) ((unw_cursor_t *) (c))
typedef struct dwarf_loc
{
unw_word_t val;
#ifndef UNW_LOCAL_ONLY
unw_word_t type; /* see X86_LOC_TYPE_* macros. */
#endif
}
dwarf_loc_t;
#endif /* dwarf_config_h */

View file

View file

@ -1,232 +0,0 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2002-2005 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
This file is part of libunwind.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#ifndef X86_64_LIBUNWIND_I_H
#define X86_64_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 "dwarf.h"
struct unw_addr_space
{
struct unw_accessors acc;
unw_caching_policy_t caching_policy;
#ifdef HAVE_ATOMIC_OPS_H
AO_t cache_generation;
#else
uint32_t cache_generation;
#endif
unw_word_t dyn_generation; /* see dyn-common.h */
unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
};
struct cursor
{
struct dwarf_cursor dwarf; /* must be first */
/* Format of sigcontext structure and address at which it is
stored: */
enum
{
X86_64_SCF_NONE, /* no signal frame encountered */
X86_64_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */
}
sigcontext_format;
unw_word_t sigcontext_addr;
};
#define DWARF_GET_LOC(l) ((l).val)
#ifdef UNW_LOCAL_ONLY
# define DWARF_NULL_LOC DWARF_LOC (0, 0)
# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0)
# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) })
# define DWARF_IS_REG_LOC(l) 0
# define DWARF_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)
{
if (DWARF_IS_NULL_LOC (loc))
return -UNW_EBADREG;
//# warning fix me
abort ();
}
static inline int
dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
{
if (DWARF_IS_NULL_LOC (loc))
return -UNW_EBADREG;
//# warning fix me
abort ();
}
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 (DWARF_IS_FP_LOC (loc))
//# warning fix me
abort ();
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 (DWARF_IS_FP_LOC (loc))
//# warning fix me
abort ();
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_needs_initialization UNW_OBJ(needs_initialization)
#define tdep_init UNW_OBJ(init)
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
tdep_search_unwind_table. */
#define tdep_search_unwind_table dwarf_search_unwind_table
#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr)
#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image)
#define tdep_access_reg UNW_OBJ(access_reg)
#define tdep_access_fpreg UNW_OBJ(access_fpreg)
#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) 0
extern int tdep_needs_initialization;
extern void tdep_init (void);
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
unw_dyn_info_t *di, unw_proc_info_t *pi,
int need_unwind_info, void *arg);
extern void *tdep_uc_addr (ucontext_t *uc, int reg);
extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff);
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write);
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t *valp, int write);
#endif /* X86_64_LIBUNWIND_I_H */

View file

@ -1,10 +0,0 @@
kdir=${1:-../kernel}
scriptdir=$(dirname $0)
udir=$(dirname $scriptdir)
cat $scriptdir/kernel-files.txt | \
(while read l r; do
left=$(eval echo $l)
right=$(eval echo $r)
# echo $left $right
diff -up $left $right
done)

View file

@ -1,20 +0,0 @@
$udir/include/ia64/rse.h $kdir/arch/ia64/unwind/rse.h
$udir/src/ia64/Ginit.c $kdir/arch/ia64/unwind/init.c
$udir/src/ia64/Ginit_local.c $kdir/arch/ia64/unwind/init_local.c
$udir/src/ia64/Gis_signal_frame.c $kdir/arch/ia64/unwind/is_signal_frame.c
$udir/src/ia64/Gparser.c $kdir/arch/ia64/unwind/parser.c
$udir/src/ia64/Grbs.c $kdir/arch/ia64/unwind/rbs.c
$udir/src/ia64/Gregs.c $kdir/arch/ia64/unwind/regs.c
$udir/src/ia64/Gscript.c $kdir/arch/ia64/unwind/script.c
$udir/src/ia64/Gstep.c $kdir/arch/ia64/unwind/step.c
$udir/src/ia64/init.h $kdir/arch/ia64/unwind/init.h
$udir/src/ia64/offsets.h $kdir/arch/ia64/unwind/offsets.h
$udir/src/ia64/regname.c $kdir/arch/ia64/unwind/regname.c
$udir/src/ia64/regs.h $kdir/arch/ia64/unwind/regs.h
$udir/src/ia64/unwind_decoder.h $kdir/arch/ia64/unwind/unwind_decoder.h
$udir/src/mi/Gget_fpreg.c $kdir/unwind/get_fpreg.c
$udir/src/mi/Gget_reg.c $kdir/unwind/get_reg.c
$udir/src/mi/Gset_fpreg.c $kdir/unwind/set_fpreg.c
$udir/src/mi/Gset_reg.c $kdir/unwind/set_reg.c
$udir/src/mi/flush_cache.c $kdir/unwind/flush_cache.c
$udir/src/mi/mempool.c $kdir/unwind/mempool.c