blob: 74ed5de23d96781970d1762882a14cc390ccde70 [file] [log] [blame]
mostang.com!davidmbf070a92002-12-19 07:16:50 +00001/* libunwind - a platform-independent unwind library
mostang.com!davidm313653f2003-01-21 08:08:32 +00002 Copyright (C) 2001-2003 Hewlett-Packard Co
mostang.com!davidmbf070a92002-12-19 07:16:50 +00003 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4
5This file is part of libunwind.
6
7Permission is hereby granted, free of charge, to any person obtaining
8a copy of this software and associated documentation files (the
9"Software"), to deal in the Software without restriction, including
10without limitation the rights to use, copy, modify, merge, publish,
11distribute, sublicense, and/or sell copies of the Software, and to
12permit persons to whom the Software is furnished to do so, subject to
13the following conditions:
14
15The above copyright notice and this permission notice shall be
16included in all copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
25
26#ifndef internal_h
27#define internal_h
28
29/* Platform-independent libunwind-internal declarations. */
30
31#include <assert.h>
mostang.com!davidmbf070a92002-12-19 07:16:50 +000032#include <libunwind.h>
mostang.com!davidm9003fd22003-03-06 06:14:36 +000033#include <pthread.h>
34#include <signal.h>
mostang.com!davidmbf070a92002-12-19 07:16:50 +000035
36#ifdef __GNUC__
mostang.com!davidmf5265f52003-02-08 10:10:59 +000037# if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
38# define HIDDEN __attribute__((visibility ("hidden")))
39# else
40# define HIDDEN
41# endif
hp.com!davidma45c8882003-02-15 03:10:30 +000042# if (__GNUC__ >= 3)
43# define likely(x) __builtin_expect ((x), 1)
44# define unlikely(x) __builtin_expect ((x), 0)
45# else
46# define likely(x) (x)
47# define unlikely(x) (x)
48# endif
mostang.com!davidmbf070a92002-12-19 07:16:50 +000049#else
50# define HIDDEN
hp.com!davidma45c8882003-02-15 03:10:30 +000051# define likely(x) (x)
52# define unlikely(x) (x)
mostang.com!davidmbf070a92002-12-19 07:16:50 +000053#endif
54
55#ifdef DEBUG
56# define UNW_DEBUG 1
57#endif
58
59#if UNW_DEBUG
60# include <stdio.h>
61# define debug(level,format...) \
hp.com!davidma45c8882003-02-15 03:10:30 +000062 do { if (tdep_debug_level > level) fprintf (stderr, format); } while (0)
mostang.com!davidmbf070a92002-12-19 07:16:50 +000063# define dprintf(format...) \
hp.com!davidma45c8882003-02-15 03:10:30 +000064 fprintf (stderr, format)
mostang.com!davidmbf070a92002-12-19 07:16:50 +000065# ifdef __GNUC__
66# define inline __attribute__ ((unused))
67# endif
68#else
69# define debug(level,format...)
70# define dprintf(format...)
mostang.com!davidmbf070a92002-12-19 07:16:50 +000071#endif
72
mostang.com!davidm313653f2003-01-21 08:08:32 +000073#define NELEMS(a) (sizeof (a) / sizeof ((a)[0]))
74
mostang.com!davidmbf070a92002-12-19 07:16:50 +000075/* Make it easy to write thread-safe code which may or may not be
76 linked against libpthread. The macros below can be used
77 unconditionally and if -lpthread is around, they'll call the
78 corresponding routines otherwise, they do nothing. */
79
80#pragma weak pthread_mutex_lock
81#pragma weak pthread_mutex_unlock
82
mostang.com!davidm9003fd22003-03-06 06:14:36 +000083#define mutex_init(l) (pthread_mutex_init ? pthread_mutex_init ((l), 0) : 0)
mostang.com!davidmbf070a92002-12-19 07:16:50 +000084#define mutex_lock(l) (pthread_mutex_lock ? pthread_mutex_lock (l) : 0)
85#define mutex_unlock(l) (pthread_mutex_unlock ? pthread_mutex_unlock (l) : 0)
86
mostang.com!davidm9003fd22003-03-06 06:14:36 +000087#if UNW_TARGET_IA64
88# define HAVE_CMPXCHG
89# include <ia64intrin.h>
90# define cmpxchg_ptr(_ptr,_o,_n) \
91 ((void *) __sync_val_compare_and_swap((long *) (_ptr), \
92 (long) (_o), (long) (_n)))
93#endif
94
mostang.com!davidmbf070a92002-12-19 07:16:50 +000095#define UNWI_OBJ(fn) UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn))
96#define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn)
97
mostang.com!davidm9003fd22003-03-06 06:14:36 +000098#define unwi_full_sigmask UNWI_ARCH_OBJ(full_sigmask)
99
100extern sigset_t unwi_full_sigmask;
101
mostang.com!davidmbf070a92002-12-19 07:16:50 +0000102extern int UNWI_OBJ(find_dynamic_proc_info) (unw_addr_space_t as,
103 unw_word_t ip,
104 unw_proc_info_t *pi,
105 int need_unwind_info, void *arg);
106extern int UNWI_ARCH_OBJ(extract_dynamic_proc_info) (unw_addr_space_t as,
107 unw_word_t ip,
108 unw_proc_info_t *pi,
109 unw_dyn_info_t *di,
110 int need_unwind_info,
111 void *arg);
112extern void UNWI_OBJ(put_dynamic_unwind_info) (unw_addr_space_t as,
113 unw_proc_info_t *pi, void *arg);
114extern int UNWI_ARCH_OBJ(dyn_remote_find_proc_info) (unw_addr_space_t as,
115 unw_word_t ip,
116 unw_proc_info_t *pi,
117 unw_word_t *generation,
118 int need_unwind_info,
119 void *arg);
120extern void UNWI_ARCH_OBJ(dyn_remote_put_unwind_info) (unw_addr_space_t as,
121 unw_proc_info_t *pi,
122 void *arg);
mostang.com!davidme20ecc62003-02-22 08:19:43 +0000123extern int UNWI_OBJ(get_proc_name) (unw_addr_space_t as, unw_word_t ip,
124 char *buf, size_t buf_len,
125 unw_word_t *offp, void *arg);
mostang.com!davidmbf070a92002-12-19 07:16:50 +0000126
127#define unwi_find_dynamic_proc_info(as,ip,pi,n,arg) \
128 UNWI_OBJ(find_dynamic_proc_info)(as, ip, pi, n, arg)
129
130#define unwi_extract_dynamic_proc_info(as,ip,pi,di,n,arg) \
131 UNWI_ARCH_OBJ(extract_dynamic_proc_info)(as, ip, pi, di, n, arg)
132
133#define unwi_put_dynamic_unwind_info(as,pi,arg) \
134 UNWI_OBJ(put_dynamic_unwind_info)(as, pi, arg)
135
136/* These handle the remote (cross-address-space) case of accessing
137 dynamic unwind info. */
138
139#define unwi_dyn_remote_find_proc_info(as,i,p,g,n,arg) \
140 UNWI_ARCH_OBJ(dyn_remote_find_proc_info)(as, i, p, g, n, arg)
141
142#define unwi_dyn_remote_put_unwind_info(as,p,arg) \
143 UNWI_ARCH_OBJ(dyn_remote_put_unwind_info)(as, p, arg)
144
mostang.com!davidme20ecc62003-02-22 08:19:43 +0000145#define unwi_get_proc_name(as,ip,b,s,o,arg) \
146 UNWI_OBJ(get_proc_name)(as, ip, b, s, o, arg)
mostang.com!davidmbf070a92002-12-19 07:16:50 +0000147
148extern unw_dyn_info_list_t _U_dyn_info_list;
149extern pthread_mutex_t _U_dyn_info_list_lock;
150
151#define WSIZE (sizeof (unw_word_t))
152
153static inline int
154fetch8 (unw_addr_space_t as, unw_accessors_t *a,
155 unw_word_t *addr, int8_t *valp, void *arg)
156{
157 unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr;
158 int ret;
159
160 *addr += 1;
161
162 ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg);
163
164#if __BYTE_ORDER == __LITTLE_ENDIAN
165 val >>= 8*off;
166#else
167 val >>= 8*(WSIZE - 1 - off);
168#endif
169 *valp = val & 0xff;
170 return ret;
171}
172
173static inline int
174fetch16 (unw_addr_space_t as, unw_accessors_t *a,
175 unw_word_t *addr, int16_t *valp, void *arg)
176{
177 unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr;
178 int ret;
179
180 assert ((off & 0x1) == 0);
181
182 *addr += 2;
183
184 ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg);
185
186#if __BYTE_ORDER == __LITTLE_ENDIAN
187 val >>= 8*off;
188#else
189 val >>= 8*(WSIZE - 2 - off);
190#endif
191 *valp = val & 0xffff;
192 return ret;
193}
194
195static inline int
196fetch32 (unw_addr_space_t as, unw_accessors_t *a,
197 unw_word_t *addr, int32_t *valp, void *arg)
198{
199 unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr;
200 int ret;
201
202 assert ((off & 0x3) == 0);
203
204 *addr += 4;
205
206 ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg);
207
208#if __BYTE_ORDER == __LITTLE_ENDIAN
209 val >>= 8*off;
210#else
211 val >>= 8*(WSIZE - 4 - off);
212#endif
213 *valp = val & 0xffffffff;
214 return ret;
215}
216
217static inline int
218fetchw (unw_addr_space_t as, unw_accessors_t *a,
219 unw_word_t *addr, unw_word_t *valp, void *arg)
220{
221 int ret;
222
223 ret = (*a->access_mem) (as, *addr, valp, 0, arg);
224 *addr += WSIZE;
225 return ret;
226}
227
mostang.com!davidm7e268d22003-01-23 10:04:09 +0000228#define mi_init UNWI_ARCH_OBJ(mi_init)
229
mostang.com!davidmbf070a92002-12-19 07:16:50 +0000230extern void mi_init (void); /* machine-independent initializations */
231
mostang.com!davidmf5265f52003-02-08 10:10:59 +0000232/* This is needed/used by ELF targets only. */
233
234struct elf_image
235 {
236 void *image; /* pointer to mmap'd image */
237 size_t size; /* (file-) size of the image */
238 };
239
mostang.com!davidmbf070a92002-12-19 07:16:50 +0000240#endif /* internal_h */