1d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm/* libunwind - a platform-independent unwind library
2d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm   Copyright (C) 2001-2005 Hewlett-Packard Co
3e6b9f350f78ecd9ef3b8a3e721f9435c94fc2562David Mosberger-Tang   Copyright (C) 2007 David Mosberger-Tang
4e6b9f350f78ecd9ef3b8a3e721f9435c94fc2562David Mosberger-Tang	Contributed by David Mosberger-Tang <dmosberger@gmail.com>
5d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
6d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmThis file is part of libunwind.
7d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
8d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmPermission is hereby granted, free of charge, to any person obtaining
9d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidma copy of this software and associated documentation files (the
10d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm"Software"), to deal in the Software without restriction, including
11d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmwithout limitation the rights to use, copy, modify, merge, publish,
12d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmdistribute, sublicense, and/or sell copies of the Software, and to
13d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmpermit persons to whom the Software is furnished to do so, subject to
14d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmthe following conditions:
15d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
16d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmThe above copyright notice and this permission notice shall be
17d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmincluded in all copies or substantial portions of the Software.
18d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
19d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
26d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
27d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm/* This files contains libunwind-internal definitions which are
28d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm   subject to frequent change and are not to be exposed to
29d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm   libunwind-users.  */
30d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
31d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#ifndef libunwind_i_h
32d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define libunwind_i_h
33d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
34d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#ifdef HAVE_CONFIG_H
35d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm# include "config.h"
36d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#endif
37d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
38dc680c0b52a4113cf9cf5b924714d79fb1654ee2Tommi Rantala#include "compiler.h"
39dc680c0b52a4113cf9cf5b924714d79fb1654ee2Tommi Rantala
40d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#ifdef HAVE___THREAD
41d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm  /* For now, turn off per-thread caching.  It uses up too much TLS
42d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm     memory per thread even when the thread never uses libunwind at
43d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm     all.  */
44d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm# undef HAVE___THREAD
45d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#endif
46d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
47d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm/* Platform-independent libunwind-internal declarations.  */
48d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
49d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#include <sys/types.h>	/* HP-UX needs this before include of pthread.h */
50d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
51d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#include <assert.h>
52d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#include <libunwind.h>
53d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#include <pthread.h>
54d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#include <signal.h>
55d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#include <stdlib.h>
56d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#include <string.h>
57d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#include <unistd.h>
582c865b6ed3833ec591c7972f545b8ed5cadfd246Ken Werner#include <sys/mman.h>
59eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer
60eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer#if defined(HAVE_ELF_H)
61eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer# include <elf.h>
62eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer#elif defined(HAVE_SYS_ELF_H)
63eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer# include <sys/elf.h>
64eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer#else
65eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer# error Could not locate <elf.h>
66eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer#endif
67d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
68905034ce728e84b2a1652ac4b44a2d8a5147a0d1Konstantin Belousov#if defined(HAVE_ENDIAN_H)
69d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm# include <endian.h>
70905034ce728e84b2a1652ac4b44a2d8a5147a0d1Konstantin Belousov#elif defined(HAVE_SYS_ENDIAN_H)
71905034ce728e84b2a1652ac4b44a2d8a5147a0d1Konstantin Belousov# include <sys/endian.h>
72d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#else
73d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm# define __LITTLE_ENDIAN	1234
74d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm# define __BIG_ENDIAN		4321
75d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm# if defined(__hpux)
76d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#   define __BYTE_ORDER __BIG_ENDIAN
77eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer# elif defined(__QNX__)
78eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer#   if defined(__BIGENDIAN__)
79eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer#     define __BYTE_ORDER __BIG_ENDIAN
80eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer#   elif defined(__LITTLEENDIAN__)
81eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer#     define __BYTE_ORDER __LITTLE_ENDIAN
82eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer#   else
83eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer#     error Host has unknown byte-order.
84eac65dc9b8cc18fa4c65c0485878a11c470357b6Matt Fischer#   endif
85d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm# else
86d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#   error Host has unknown byte-order.
87d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm# endif
88d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#endif
89d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
9010b064ffe902d5af31bb49bd8e4f03c545f8d462Ladislav Michl#if defined(HAVE__BUILTIN_UNREACHABLE)
9110b064ffe902d5af31bb49bd8e4f03c545f8d462Ladislav Michl# define unreachable() __builtin_unreachable()
9210b064ffe902d5af31bb49bd8e4f03c545f8d462Ladislav Michl#else
9310b064ffe902d5af31bb49bd8e4f03c545f8d462Ladislav Michl# define unreachable() do { } while (1)
9410b064ffe902d5af31bb49bd8e4f03c545f8d462Ladislav Michl#endif
9510b064ffe902d5af31bb49bd8e4f03c545f8d462Ladislav Michl
96d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#ifdef DEBUG
97d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm# define UNW_DEBUG	1
98d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#else
99d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm# define UNW_DEBUG	0
100d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#endif
101d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
102d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm/* Make it easy to write thread-safe code which may or may not be
103d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm   linked against libpthread.  The macros below can be used
104d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm   unconditionally and if -lpthread is around, they'll call the
105d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm   corresponding routines otherwise, they do nothing.  */
106d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
107d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#pragma weak pthread_mutex_init
108d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#pragma weak pthread_mutex_lock
109d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#pragma weak pthread_mutex_unlock
110d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
111d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define mutex_init(l)							\
112890e23eb9d3ffd9be2a025189a21794b5ed0e0ffTommi Rantala	(pthread_mutex_init != NULL ? pthread_mutex_init ((l), NULL) : 0)
113d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define mutex_lock(l)							\
114890e23eb9d3ffd9be2a025189a21794b5ed0e0ffTommi Rantala	(pthread_mutex_lock != NULL ? pthread_mutex_lock (l) : 0)
115d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define mutex_unlock(l)							\
116890e23eb9d3ffd9be2a025189a21794b5ed0e0ffTommi Rantala	(pthread_mutex_unlock != NULL ? pthread_mutex_unlock (l) : 0)
117d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
118d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#ifdef HAVE_ATOMIC_OPS_H
119d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm# include <atomic_ops.h>
120d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmstatic inline int
121d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmcmpxchg_ptr (void *addr, void *old, void *new)
122d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm{
123d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm  union
124d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm    {
125d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm      void *vp;
126d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm      AO_t *aop;
127d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm    }
128d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm  u;
129d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
130d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm  u.vp = addr;
131d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm  return AO_compare_and_swap(u.aop, (AO_t) old, (AO_t) new);
132d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm}
133d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm# define fetch_and_add1(_ptr)		AO_fetch_and_add1(_ptr)
1349a3565ddc1e956ef1f52806093e949c7809f6e79Tommi Rantala# define fetch_and_add(_ptr, value)	AO_fetch_and_add(_ptr, value)
135d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm   /* GCC 3.2.0 on HP-UX crashes on cmpxchg_ptr() */
136d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#  if !(defined(__hpux) && __GNUC__ == 3 && __GNUC_MINOR__ == 2)
137d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#   define HAVE_CMPXCHG
138d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#  endif
1399a3565ddc1e956ef1f52806093e949c7809f6e79Tommi Rantala# define HAVE_FETCH_AND_ADD
140c2d6f85a0ac0562f9edaaefd584376af89412a17Tommi Rantala#elif defined(HAVE_SYNC_ATOMICS) || defined(HAVE_IA64INTRIN_H)
141d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm# ifdef HAVE_IA64INTRIN_H
142d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#  include <ia64intrin.h>
143c2d6f85a0ac0562f9edaaefd584376af89412a17Tommi Rantala# endif
144d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmstatic inline int
145d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmcmpxchg_ptr (void *addr, void *old, void *new)
146d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm{
147d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm  union
148d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm    {
149d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm      void *vp;
150d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm      long *vlp;
151d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm    }
152d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm  u;
153d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
154d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm  u.vp = addr;
155d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm  return __sync_bool_compare_and_swap(u.vlp, (long) old, (long) new);
156d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm}
157c2d6f85a0ac0562f9edaaefd584376af89412a17Tommi Rantala# define fetch_and_add1(_ptr)		__sync_fetch_and_add(_ptr, 1)
158c2d6f85a0ac0562f9edaaefd584376af89412a17Tommi Rantala# define fetch_and_add(_ptr, value)	__sync_fetch_and_add(_ptr, value)
159c2d6f85a0ac0562f9edaaefd584376af89412a17Tommi Rantala# define HAVE_CMPXCHG
160c2d6f85a0ac0562f9edaaefd584376af89412a17Tommi Rantala# define HAVE_FETCH_AND_ADD
161d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#endif
162d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define atomic_read(ptr)	(*(ptr))
163d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
164d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define UNWI_OBJ(fn)	  UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn))
165d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn)
166d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
167d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define unwi_full_mask    UNWI_ARCH_OBJ(full_mask)
168d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
169d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm/* Type of a mask that can be used to inhibit preemption.  At the
170d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm   userlevel, preemption is caused by signals and hence sigset_t is
171d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm   appropriate.  In constrast, the Linux kernel uses "unsigned long"
172d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm   to hold the processor "flags" instead.  */
173d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmtypedef sigset_t intrmask_t;
174d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
175d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmextern intrmask_t unwi_full_mask;
176d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
177491d576529a3b01208accb37627a075d7ce07093Arun Sharma/* Silence compiler warnings about variables which are used only if libunwind
178491d576529a3b01208accb37627a075d7ce07093Arun Sharma   is configured in a certain way */
179a15874f2cbcbfffd20b8bad61ca4e37b655b1cbeTommi Rantalastatic inline void mark_as_used(void *v UNUSED) {
180491d576529a3b01208accb37627a075d7ce07093Arun Sharma}
181491d576529a3b01208accb37627a075d7ce07093Arun Sharma
1829aa0d6d6805b3b4a852f7e478364301bb31230aePaul Pluzhnikov#if defined(CONFIG_BLOCK_SIGNALS)
183af9daf66afde3c92b2c7c4f171bf3414c623892cArun Sharma# define SIGPROCMASK(how, new_mask, old_mask) \
184af9daf66afde3c92b2c7c4f171bf3414c623892cArun Sharma  sigprocmask((how), (new_mask), (old_mask))
1859aa0d6d6805b3b4a852f7e478364301bb31230aePaul Pluzhnikov#else
1864ab26bcdaafce0e7f34dfaafd14c7837d8bb5435Arun Sharma# define SIGPROCMASK(how, new_mask, old_mask) mark_as_used(old_mask)
1879aa0d6d6805b3b4a852f7e478364301bb31230aePaul Pluzhnikov#endif
1889aa0d6d6805b3b4a852f7e478364301bb31230aePaul Pluzhnikov
189b8627d92164f67864e806afb9f461f2db161f13cChristopher Ferris/* ANDROID support update. */
190f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris#define __lock_acquire_internal(l, m, acquire_func)	\
191f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferrisdo {							\
192f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris  SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &(m));	\
193f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris  acquire_func (l);					\
194f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris} while (0)
195f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris#define __lock_release_internal(l, m, release_func)	\
196f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferrisdo {							\
197f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris  release_func (l);					\
198f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris  SIGPROCMASK (SIG_SETMASK, &(m), NULL);		\
199f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris} while (0)
200f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris
201f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris#define lock_rdwr_var(name)				\
202f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris  pthread_rwlock_t name
203f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris#define lock_rdwr_init(l)	pthread_rwlock_init (l, NULL)
204f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris#define lock_rdwr_wr_acquire(l, m)			\
205f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris  __lock_acquire_internal(l, m, pthread_rwlock_wrlock)
206f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris#define lock_rdwr_rd_acquire(l, m)			\
207f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris  __lock_acquire_internal(l, m, pthread_rwlock_rdlock)
208f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris#define lock_rdwr_release(l, m)				\
209f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris  __lock_release_internal(l, m, pthread_rwlock_unlock)
210f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris
211b8627d92164f67864e806afb9f461f2db161f13cChristopher Ferris#define lock_var(name) \
212b8627d92164f67864e806afb9f461f2db161f13cChristopher Ferris  pthread_mutex_t name
213d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define define_lock(name) \
214b8627d92164f67864e806afb9f461f2db161f13cChristopher Ferris  lock_var (name) = PTHREAD_MUTEX_INITIALIZER
215d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define lock_init(l)		mutex_init (l)
216d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define lock_acquire(l,m)				\
217f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris  __lock_acquire_internal(l, m, mutex_lock)
218d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define lock_release(l,m)			\
219f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris  __lock_release_internal(l, m, mutex_unlock)
220f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris/* End of ANDROID update. */
221d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
222d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define SOS_MEMORY_SIZE 16384	/* see src/mi/mempool.c */
223d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
2248ccebc9307edda6c2315cc81f0381192b2db9df1Konstantin Belousov#ifndef MAP_ANONYMOUS
2258ccebc9307edda6c2315cc81f0381192b2db9df1Konstantin Belousov# define MAP_ANONYMOUS MAP_ANON
2268ccebc9307edda6c2315cc81f0381192b2db9df1Konstantin Belousov#endif
227c0a9d0c7c1858f934aac0046d8e508ec218bc56bArun Sharma#define GET_MEMORY(mem, size)				    		    \
228d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmdo {									    \
229d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm  /* Hopefully, mmap() goes straight through to a system call stub...  */   \
230890e23eb9d3ffd9be2a025189a21794b5ed0e0ffTommi Rantala  mem = mmap (NULL, size, PROT_READ | PROT_WRITE,			    \
231890e23eb9d3ffd9be2a025189a21794b5ed0e0ffTommi Rantala	      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);			    \
232d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm  if (mem == MAP_FAILED)						    \
233d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm    mem = NULL;								    \
234d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm} while (0)
235d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
236d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define unwi_find_dynamic_proc_info	UNWI_OBJ(find_dynamic_proc_info)
237d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define unwi_extract_dynamic_proc_info	UNWI_OBJ(extract_dynamic_proc_info)
238d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define unwi_put_dynamic_unwind_info	UNWI_OBJ(put_dynamic_unwind_info)
239d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define unwi_dyn_remote_find_proc_info	UNWI_OBJ(dyn_remote_find_proc_info)
240d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define unwi_dyn_remote_put_unwind_info	UNWI_OBJ(dyn_remote_put_unwind_info)
241d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define unwi_dyn_validate_cache		UNWI_OBJ(dyn_validate_cache)
242d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
243d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmextern int unwi_find_dynamic_proc_info (unw_addr_space_t as,
244d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm					unw_word_t ip,
245d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm					unw_proc_info_t *pi,
246d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm					int need_unwind_info, void *arg);
247d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmextern int unwi_extract_dynamic_proc_info (unw_addr_space_t as,
248d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm					   unw_word_t ip,
249d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm					   unw_proc_info_t *pi,
250d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm					   unw_dyn_info_t *di,
251d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm					   int need_unwind_info,
252d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm					   void *arg);
253d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmextern void unwi_put_dynamic_unwind_info (unw_addr_space_t as,
254d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm					  unw_proc_info_t *pi, void *arg);
255d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
256d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm/* These handle the remote (cross-address-space) case of accessing
257d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm   dynamic unwind info. */
258d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
259d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmextern int unwi_dyn_remote_find_proc_info (unw_addr_space_t as,
260d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm					   unw_word_t ip,
261d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm					   unw_proc_info_t *pi,
262d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm					   int need_unwind_info,
263d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm					   void *arg);
264d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmextern void unwi_dyn_remote_put_unwind_info (unw_addr_space_t as,
265d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm					     unw_proc_info_t *pi,
266d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm					     void *arg);
267d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmextern int unwi_dyn_validate_cache (unw_addr_space_t as, void *arg);
268d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
269d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmextern unw_dyn_info_list_t _U_dyn_info_list;
270d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmextern pthread_mutex_t _U_dyn_info_list_lock;
271d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
272d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#if UNW_DEBUG
27376dbee53bb2c38f31159531e5fdd7c2b0218b134Christopher Ferris# define unwi_debug_level		UNWI_ARCH_OBJ(debug_level)
274d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmextern long unwi_debug_level;
275d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
27676dbee53bb2c38f31159531e5fdd7c2b0218b134Christopher Ferris# ifdef ANDROID
27776dbee53bb2c38f31159531e5fdd7c2b0218b134Christopher Ferris# define LOG_TAG "libunwind"
2787e10fa72f0d9e6160b917a62d9d91a87c9b47ffbElliott Hughes# include <log/log.h>
27976dbee53bb2c38f31159531e5fdd7c2b0218b134Christopher Ferris
28076dbee53bb2c38f31159531e5fdd7c2b0218b134Christopher Ferris# define Debug(level, format, ...)					\
28176dbee53bb2c38f31159531e5fdd7c2b0218b134Christopher Ferrisdo {									\
28276dbee53bb2c38f31159531e5fdd7c2b0218b134Christopher Ferris  if (unwi_debug_level >= (level))					\
28376dbee53bb2c38f31159531e5fdd7c2b0218b134Christopher Ferris    { 									\
28476dbee53bb2c38f31159531e5fdd7c2b0218b134Christopher Ferris      ALOGI("%*c>%s: " format, ((level) <= 16) ? (level) : 16, ' ',	\
28576dbee53bb2c38f31159531e5fdd7c2b0218b134Christopher Ferris            __FUNCTION__, ##__VA_ARGS__);				\
28676dbee53bb2c38f31159531e5fdd7c2b0218b134Christopher Ferris    } 									\
28776dbee53bb2c38f31159531e5fdd7c2b0218b134Christopher Ferris} while (0)
28876dbee53bb2c38f31159531e5fdd7c2b0218b134Christopher Ferris# define Dprintf(format, ...) ALOGI(format, ##__VA_ARGS__);
28976dbee53bb2c38f31159531e5fdd7c2b0218b134Christopher Ferris#else
290d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm# include <stdio.h>
291d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm# define Debug(level,format...)						\
292d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmdo {									\
293d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm  if (unwi_debug_level >= level)					\
294d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm    {									\
295d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm      int _n = level;							\
296d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm      if (_n > 16)							\
297d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm	_n = 16;							\
298d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm      fprintf (stderr, "%*c>%s: ", _n, ' ', __FUNCTION__);		\
299d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm      fprintf (stderr, format);						\
300d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm    }									\
301d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm} while (0)
302ec53de82ec7c00adb56c9e8b1b03d489a69c494bArun Sharma# define Dprintf(format...) 	    fprintf (stderr, format)
303d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm# ifdef __GNUC__
304d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#  undef inline
305d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#  define inline	UNUSED
306d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm# endif
30776dbee53bb2c38f31159531e5fdd7c2b0218b134Christopher Ferris# endif
308d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#else
309d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm# define Debug(level,format...)
310ec53de82ec7c00adb56c9e8b1b03d489a69c494bArun Sharma# define Dprintf(format...)
311d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#endif
312d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
313491d576529a3b01208accb37627a075d7ce07093Arun Sharmastatic ALWAYS_INLINE int
314d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmprint_error (const char *string)
315d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm{
316491d576529a3b01208accb37627a075d7ce07093Arun Sharma  return write (2, string, strlen (string));
317d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm}
318d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
319d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#define mi_init		UNWI_ARCH_OBJ(mi_init)
320d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
321d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmextern void mi_init (void);	/* machine-independent initializations */
322d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmextern unw_word_t _U_dyn_info_list_addr (void);
323d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
324d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm/* This is needed/used by ELF targets only.  */
325d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
326d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidmstruct elf_image
327d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm  {
328d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm    void *image;		/* pointer to mmap'd image */
329d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm    size_t size;		/* (file-) size of the image */
330d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm  };
331d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
33225ee9f81727616f3269032c52483e4421d451291Arun Sharmastruct elf_dyn_info
33325ee9f81727616f3269032c52483e4421d451291Arun Sharma  {
33416b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris    /* ANDROID support update.*/
33516b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris    /* Removed: struct elf_image ei; */
33616b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris    /* End of ANDROID update. */
33725ee9f81727616f3269032c52483e4421d451291Arun Sharma    unw_dyn_info_t di_cache;
33825ee9f81727616f3269032c52483e4421d451291Arun Sharma    unw_dyn_info_t di_debug;    /* additional table info for .debug_frame */
33925ee9f81727616f3269032c52483e4421d451291Arun Sharma#if UNW_TARGET_IA64
34025ee9f81727616f3269032c52483e4421d451291Arun Sharma    unw_dyn_info_t ktab;
34125ee9f81727616f3269032c52483e4421d451291Arun Sharma#endif
34225ee9f81727616f3269032c52483e4421d451291Arun Sharma#if UNW_TARGET_ARM
34325ee9f81727616f3269032c52483e4421d451291Arun Sharma    unw_dyn_info_t di_arm;      /* additional table info for .ARM.exidx */
34425ee9f81727616f3269032c52483e4421d451291Arun Sharma#endif
34525ee9f81727616f3269032c52483e4421d451291Arun Sharma  };
34625ee9f81727616f3269032c52483e4421d451291Arun Sharma
34718c26d4a7eae02abcae817b97bb8571b1c2f4b8eTommi Rantalastatic inline void invalidate_edi (struct elf_dyn_info *edi)
34825ee9f81727616f3269032c52483e4421d451291Arun Sharma{
34916b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris  /* ANDROID support update.*/
35016b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris  /* Removed: if (edi->ei.image) */
35116b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris  /*            munmap (edi->ei.image, edi->ei.size); */
35216b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris  /* End of ANDROID update. */
35325ee9f81727616f3269032c52483e4421d451291Arun Sharma  memset (edi, 0, sizeof (*edi));
35425ee9f81727616f3269032c52483e4421d451291Arun Sharma  edi->di_cache.format = -1;
35525ee9f81727616f3269032c52483e4421d451291Arun Sharma  edi->di_debug.format = -1;
35625ee9f81727616f3269032c52483e4421d451291Arun Sharma#if UNW_TARGET_ARM
35725ee9f81727616f3269032c52483e4421d451291Arun Sharma  edi->di_arm.format = -1;
35825ee9f81727616f3269032c52483e4421d451291Arun Sharma#endif
35925ee9f81727616f3269032c52483e4421d451291Arun Sharma}
36025ee9f81727616f3269032c52483e4421d451291Arun Sharma
36125ee9f81727616f3269032c52483e4421d451291Arun Sharma
362ae5c1f2adf4da04235d87d024d4d942c01b2b447Lassi Tuura/* Provide a place holder for architecture to override for fast access
363ae5c1f2adf4da04235d87d024d4d942c01b2b447Lassi Tuura   to memory when known not to need to validate and know the access
364ae5c1f2adf4da04235d87d024d4d942c01b2b447Lassi Tuura   will be local to the process. A suitable override will improve
365ae5c1f2adf4da04235d87d024d4d942c01b2b447Lassi Tuura   unw_tdep_trace() performance in particular. */
366ae5c1f2adf4da04235d87d024d4d942c01b2b447Lassi Tuura#define ACCESS_MEM_FAST(ret,validate,cur,addr,to) \
367ae5c1f2adf4da04235d87d024d4d942c01b2b447Lassi Tuura  do { (ret) = dwarf_get ((cur), DWARF_MEM_LOC ((cur), (addr)), &(to)); } \
368ae5c1f2adf4da04235d87d024d4d942c01b2b447Lassi Tuura  while (0)
369ae5c1f2adf4da04235d87d024d4d942c01b2b447Lassi Tuura
37091494b732b28d14af47f5433c6dc904d5d27e0d0Ken Werner/* Define GNU and processor specific values for the Phdr p_type field in case
37191494b732b28d14af47f5433c6dc904d5d27e0d0Ken Werner   they aren't defined by <elf.h>.  */
37291494b732b28d14af47f5433c6dc904d5d27e0d0Ken Werner#ifndef PT_GNU_EH_FRAME
37391494b732b28d14af47f5433c6dc904d5d27e0d0Ken Werner# define PT_GNU_EH_FRAME	0x6474e550
37491494b732b28d14af47f5433c6dc904d5d27e0d0Ken Werner#endif /* !PT_GNU_EH_FRAME */
37591494b732b28d14af47f5433c6dc904d5d27e0d0Ken Werner#ifndef PT_ARM_EXIDX
37691494b732b28d14af47f5433c6dc904d5d27e0d0Ken Werner# define PT_ARM_EXIDX		0x70000001	/* ARM unwind segment */
37791494b732b28d14af47f5433c6dc904d5d27e0d0Ken Werner#endif /* !PT_ARM_EXIDX */
37891494b732b28d14af47f5433c6dc904d5d27e0d0Ken Werner
379d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#include "tdep/libunwind_i.h"
380d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm
381e6b9f350f78ecd9ef3b8a3e721f9435c94fc2562David Mosberger-Tang#ifndef tdep_get_func_addr
382e6b9f350f78ecd9ef3b8a3e721f9435c94fc2562David Mosberger-Tang# define tdep_get_func_addr(as,addr,v)		(*(v) = addr, 0)
383e6b9f350f78ecd9ef3b8a3e721f9435c94fc2562David Mosberger-Tang#endif
384e6b9f350f78ecd9ef3b8a3e721f9435c94fc2562David Mosberger-Tang
385c2f7574187cfbb36dbcdc85bc61a027a4025f394Tommi Rantala#define UNW_ALIGN(x,a) (((x)+(a)-1UL)&~((a)-1UL))
386c2f7574187cfbb36dbcdc85bc61a027a4025f394Tommi Rantala
387d5ab898cdf886486fa78171b247538ccde5e073ehp.com!davidm#endif /* libunwind_i_h */
388