blob: 470bbfb8470d77cf3b5c50bf2fa42b28fd5deabc [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
mostang.com!davidm15693e22003-03-19 19:25:18 +000029#ifdef HAVE_CONFIG_H
30# include "config.h"
31#endif
32
mostang.com!davidmbf070a92002-12-19 07:16:50 +000033/* Platform-independent libunwind-internal declarations. */
34
mostang.com!davidm15693e22003-03-19 19:25:18 +000035#include <sys/types.h> /* HP-UX needs this before include of pthread.h */
36
mostang.com!davidmbf070a92002-12-19 07:16:50 +000037#include <assert.h>
mostang.com!davidmbf070a92002-12-19 07:16:50 +000038#include <libunwind.h>
mostang.com!davidm9003fd22003-03-06 06:14:36 +000039#include <pthread.h>
40#include <signal.h>
mostang.com!davidmbf070a92002-12-19 07:16:50 +000041
42#ifdef __GNUC__
mostang.com!davidmf5265f52003-02-08 10:10:59 +000043# if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
44# define HIDDEN __attribute__((visibility ("hidden")))
45# else
46# define HIDDEN
47# endif
hp.com!davidma45c8882003-02-15 03:10:30 +000048# if (__GNUC__ >= 3)
49# define likely(x) __builtin_expect ((x), 1)
50# define unlikely(x) __builtin_expect ((x), 0)
51# else
52# define likely(x) (x)
53# define unlikely(x) (x)
54# endif
mostang.com!davidmbf070a92002-12-19 07:16:50 +000055#else
56# define HIDDEN
hp.com!davidma45c8882003-02-15 03:10:30 +000057# define likely(x) (x)
58# define unlikely(x) (x)
mostang.com!davidmbf070a92002-12-19 07:16:50 +000059#endif
60
61#ifdef DEBUG
62# define UNW_DEBUG 1
63#endif
64
65#if UNW_DEBUG
66# include <stdio.h>
67# define debug(level,format...) \
hp.com!davidma45c8882003-02-15 03:10:30 +000068 do { if (tdep_debug_level > level) fprintf (stderr, format); } while (0)
mostang.com!davidmbf070a92002-12-19 07:16:50 +000069# define dprintf(format...) \
hp.com!davidma45c8882003-02-15 03:10:30 +000070 fprintf (stderr, format)
mostang.com!davidmbf070a92002-12-19 07:16:50 +000071# ifdef __GNUC__
72# define inline __attribute__ ((unused))
73# endif
74#else
75# define debug(level,format...)
76# define dprintf(format...)
mostang.com!davidmbf070a92002-12-19 07:16:50 +000077#endif
78
mostang.com!davidm313653f2003-01-21 08:08:32 +000079#define NELEMS(a) (sizeof (a) / sizeof ((a)[0]))
80
mostang.com!davidmbf070a92002-12-19 07:16:50 +000081/* Make it easy to write thread-safe code which may or may not be
82 linked against libpthread. The macros below can be used
83 unconditionally and if -lpthread is around, they'll call the
84 corresponding routines otherwise, they do nothing. */
85
86#pragma weak pthread_mutex_lock
87#pragma weak pthread_mutex_unlock
88
mostang.com!davidm9003fd22003-03-06 06:14:36 +000089#define mutex_init(l) (pthread_mutex_init ? pthread_mutex_init ((l), 0) : 0)
mostang.com!davidmbf070a92002-12-19 07:16:50 +000090#define mutex_lock(l) (pthread_mutex_lock ? pthread_mutex_lock (l) : 0)
91#define mutex_unlock(l) (pthread_mutex_unlock ? pthread_mutex_unlock (l) : 0)
92
mostang.com!davidm15693e22003-03-19 19:25:18 +000093#ifdef HAVE_IA64INTRIN_H
mostang.com!davidm9003fd22003-03-06 06:14:36 +000094# define HAVE_CMPXCHG
95# include <ia64intrin.h>
mostang.com!davidm28fe6a62003-03-27 04:29:07 +000096 /*
97 * ecc v7.0 is broken: it's missing __sync_val_compare_and_swap()
98 * even though the ia64 ABI requires it. Work around it:
99 */
100# ifndef __sync_val_compare_and_swap
101# define __sync_val_compare_and_swap(x,y,z) \
102 _InterlockedCompareExchange64_rel(x,y,z)
103# endif
104
mostang.com!davidm9003fd22003-03-06 06:14:36 +0000105# define cmpxchg_ptr(_ptr,_o,_n) \
106 ((void *) __sync_val_compare_and_swap((long *) (_ptr), \
107 (long) (_o), (long) (_n)))
108#endif
109
mostang.com!davidmbf070a92002-12-19 07:16:50 +0000110#define UNWI_OBJ(fn) UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn))
111#define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn)
112
mostang.com!davidm9003fd22003-03-06 06:14:36 +0000113#define unwi_full_sigmask UNWI_ARCH_OBJ(full_sigmask)
114
115extern sigset_t unwi_full_sigmask;
116
mostang.com!davidmbf070a92002-12-19 07:16:50 +0000117extern int UNWI_OBJ(find_dynamic_proc_info) (unw_addr_space_t as,
118 unw_word_t ip,
119 unw_proc_info_t *pi,
120 int need_unwind_info, void *arg);
121extern int UNWI_ARCH_OBJ(extract_dynamic_proc_info) (unw_addr_space_t as,
122 unw_word_t ip,
123 unw_proc_info_t *pi,
124 unw_dyn_info_t *di,
125 int need_unwind_info,
126 void *arg);
127extern void UNWI_OBJ(put_dynamic_unwind_info) (unw_addr_space_t as,
128 unw_proc_info_t *pi, void *arg);
129extern int UNWI_ARCH_OBJ(dyn_remote_find_proc_info) (unw_addr_space_t as,
130 unw_word_t ip,
131 unw_proc_info_t *pi,
132 unw_word_t *generation,
133 int need_unwind_info,
134 void *arg);
135extern void UNWI_ARCH_OBJ(dyn_remote_put_unwind_info) (unw_addr_space_t as,
136 unw_proc_info_t *pi,
137 void *arg);
mostang.com!davidme20ecc62003-02-22 08:19:43 +0000138extern int UNWI_OBJ(get_proc_name) (unw_addr_space_t as, unw_word_t ip,
139 char *buf, size_t buf_len,
140 unw_word_t *offp, void *arg);
mostang.com!davidmbf070a92002-12-19 07:16:50 +0000141
142#define unwi_find_dynamic_proc_info(as,ip,pi,n,arg) \
143 UNWI_OBJ(find_dynamic_proc_info)(as, ip, pi, n, arg)
144
145#define unwi_extract_dynamic_proc_info(as,ip,pi,di,n,arg) \
146 UNWI_ARCH_OBJ(extract_dynamic_proc_info)(as, ip, pi, di, n, arg)
147
148#define unwi_put_dynamic_unwind_info(as,pi,arg) \
149 UNWI_OBJ(put_dynamic_unwind_info)(as, pi, arg)
150
151/* These handle the remote (cross-address-space) case of accessing
152 dynamic unwind info. */
153
154#define unwi_dyn_remote_find_proc_info(as,i,p,g,n,arg) \
155 UNWI_ARCH_OBJ(dyn_remote_find_proc_info)(as, i, p, g, n, arg)
156
157#define unwi_dyn_remote_put_unwind_info(as,p,arg) \
158 UNWI_ARCH_OBJ(dyn_remote_put_unwind_info)(as, p, arg)
159
mostang.com!davidme20ecc62003-02-22 08:19:43 +0000160#define unwi_get_proc_name(as,ip,b,s,o,arg) \
161 UNWI_OBJ(get_proc_name)(as, ip, b, s, o, arg)
mostang.com!davidmbf070a92002-12-19 07:16:50 +0000162
163extern unw_dyn_info_list_t _U_dyn_info_list;
164extern pthread_mutex_t _U_dyn_info_list_lock;
165
166#define WSIZE (sizeof (unw_word_t))
167
168static inline int
169fetch8 (unw_addr_space_t as, unw_accessors_t *a,
170 unw_word_t *addr, int8_t *valp, void *arg)
171{
172 unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr;
173 int ret;
174
175 *addr += 1;
176
177 ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg);
178
179#if __BYTE_ORDER == __LITTLE_ENDIAN
180 val >>= 8*off;
181#else
182 val >>= 8*(WSIZE - 1 - off);
183#endif
184 *valp = val & 0xff;
185 return ret;
186}
187
188static inline int
189fetch16 (unw_addr_space_t as, unw_accessors_t *a,
190 unw_word_t *addr, int16_t *valp, void *arg)
191{
192 unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr;
193 int ret;
194
195 assert ((off & 0x1) == 0);
196
197 *addr += 2;
198
199 ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg);
200
201#if __BYTE_ORDER == __LITTLE_ENDIAN
202 val >>= 8*off;
203#else
204 val >>= 8*(WSIZE - 2 - off);
205#endif
206 *valp = val & 0xffff;
207 return ret;
208}
209
210static inline int
211fetch32 (unw_addr_space_t as, unw_accessors_t *a,
212 unw_word_t *addr, int32_t *valp, void *arg)
213{
214 unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr;
215 int ret;
216
217 assert ((off & 0x3) == 0);
218
219 *addr += 4;
220
221 ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg);
222
223#if __BYTE_ORDER == __LITTLE_ENDIAN
224 val >>= 8*off;
225#else
226 val >>= 8*(WSIZE - 4 - off);
227#endif
228 *valp = val & 0xffffffff;
229 return ret;
230}
231
232static inline int
233fetchw (unw_addr_space_t as, unw_accessors_t *a,
234 unw_word_t *addr, unw_word_t *valp, void *arg)
235{
236 int ret;
237
238 ret = (*a->access_mem) (as, *addr, valp, 0, arg);
239 *addr += WSIZE;
240 return ret;
241}
242
mostang.com!davidm7e268d22003-01-23 10:04:09 +0000243#define mi_init UNWI_ARCH_OBJ(mi_init)
244
mostang.com!davidmbf070a92002-12-19 07:16:50 +0000245extern void mi_init (void); /* machine-independent initializations */
246
mostang.com!davidmf5265f52003-02-08 10:10:59 +0000247/* This is needed/used by ELF targets only. */
248
249struct elf_image
250 {
251 void *image; /* pointer to mmap'd image */
252 size_t size; /* (file-) size of the image */
253 };
254
mostang.com!davidmbf070a92002-12-19 07:16:50 +0000255#endif /* internal_h */