blob: 5008970a8bbc566b1ebb3c16848798d23211fffd [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>
32#include <pthread.h>
33#include <libunwind.h>
34
35#ifdef __GNUC__
mostang.com!davidm313653f2003-01-21 08:08:32 +000036# define HIDDEN __attribute__((visibility ("hidden")))
37# define likely(x) __builtin_expect ((x), 1)
38# define unlikely(x) __builtin_expect ((x), 0)
mostang.com!davidmbf070a92002-12-19 07:16:50 +000039#else
40# define HIDDEN
mostang.com!davidm313653f2003-01-21 08:08:32 +000041# define likely(x)
42# define unlikely(x)
mostang.com!davidmbf070a92002-12-19 07:16:50 +000043#endif
44
45#ifdef DEBUG
46# define UNW_DEBUG 1
47#endif
48
49#if UNW_DEBUG
50# include <stdio.h>
51# define debug(level,format...) \
52 do { if (tdep_debug_level > level) printf (format); } while (0)
53# define dprintf(format...) \
54 printf (format)
55# ifdef __GNUC__
56# define inline __attribute__ ((unused))
57# endif
58#else
59# define debug(level,format...)
60# define dprintf(format...)
mostang.com!davidmbf070a92002-12-19 07:16:50 +000061#endif
62
mostang.com!davidm313653f2003-01-21 08:08:32 +000063#define NELEMS(a) (sizeof (a) / sizeof ((a)[0]))
64
mostang.com!davidmbf070a92002-12-19 07:16:50 +000065/* Make it easy to write thread-safe code which may or may not be
66 linked against libpthread. The macros below can be used
67 unconditionally and if -lpthread is around, they'll call the
68 corresponding routines otherwise, they do nothing. */
69
70#pragma weak pthread_mutex_lock
71#pragma weak pthread_mutex_unlock
72
73#define mutex_lock(l) (pthread_mutex_lock ? pthread_mutex_lock (l) : 0)
74#define mutex_unlock(l) (pthread_mutex_unlock ? pthread_mutex_unlock (l) : 0)
75
76#define UNWI_OBJ(fn) UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn))
77#define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn)
78
79extern int UNWI_OBJ(find_dynamic_proc_info) (unw_addr_space_t as,
80 unw_word_t ip,
81 unw_proc_info_t *pi,
82 int need_unwind_info, void *arg);
83extern int UNWI_ARCH_OBJ(extract_dynamic_proc_info) (unw_addr_space_t as,
84 unw_word_t ip,
85 unw_proc_info_t *pi,
86 unw_dyn_info_t *di,
87 int need_unwind_info,
88 void *arg);
89extern void UNWI_OBJ(put_dynamic_unwind_info) (unw_addr_space_t as,
90 unw_proc_info_t *pi, void *arg);
91extern int UNWI_ARCH_OBJ(dyn_remote_find_proc_info) (unw_addr_space_t as,
92 unw_word_t ip,
93 unw_proc_info_t *pi,
94 unw_word_t *generation,
95 int need_unwind_info,
96 void *arg);
97extern void UNWI_ARCH_OBJ(dyn_remote_put_unwind_info) (unw_addr_space_t as,
98 unw_proc_info_t *pi,
99 void *arg);
100extern int UNWI_ARCH_OBJ(get_proc_name) (unw_addr_space_t as,
101 unw_word_t ip, int is_local,
102 char *buf, size_t buf_len, void *arg);
103
104#define unwi_find_dynamic_proc_info(as,ip,pi,n,arg) \
105 UNWI_OBJ(find_dynamic_proc_info)(as, ip, pi, n, arg)
106
107#define unwi_extract_dynamic_proc_info(as,ip,pi,di,n,arg) \
108 UNWI_ARCH_OBJ(extract_dynamic_proc_info)(as, ip, pi, di, n, arg)
109
110#define unwi_put_dynamic_unwind_info(as,pi,arg) \
111 UNWI_OBJ(put_dynamic_unwind_info)(as, pi, arg)
112
113/* These handle the remote (cross-address-space) case of accessing
114 dynamic unwind info. */
115
116#define unwi_dyn_remote_find_proc_info(as,i,p,g,n,arg) \
117 UNWI_ARCH_OBJ(dyn_remote_find_proc_info)(as, i, p, g, n, arg)
118
119#define unwi_dyn_remote_put_unwind_info(as,p,arg) \
120 UNWI_ARCH_OBJ(dyn_remote_put_unwind_info)(as, p, arg)
121
122#define unwi_get_proc_name(as,ip,l,b,s,arg) \
123 UNWI_ARCH_OBJ(get_proc_name)(as, ip, l, b, s, arg)
124
125extern unw_dyn_info_list_t _U_dyn_info_list;
126extern pthread_mutex_t _U_dyn_info_list_lock;
127
128#define WSIZE (sizeof (unw_word_t))
129
130static inline int
131fetch8 (unw_addr_space_t as, unw_accessors_t *a,
132 unw_word_t *addr, int8_t *valp, void *arg)
133{
134 unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr;
135 int ret;
136
137 *addr += 1;
138
139 ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg);
140
141#if __BYTE_ORDER == __LITTLE_ENDIAN
142 val >>= 8*off;
143#else
144 val >>= 8*(WSIZE - 1 - off);
145#endif
146 *valp = val & 0xff;
147 return ret;
148}
149
150static inline int
151fetch16 (unw_addr_space_t as, unw_accessors_t *a,
152 unw_word_t *addr, int16_t *valp, void *arg)
153{
154 unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr;
155 int ret;
156
157 assert ((off & 0x1) == 0);
158
159 *addr += 2;
160
161 ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg);
162
163#if __BYTE_ORDER == __LITTLE_ENDIAN
164 val >>= 8*off;
165#else
166 val >>= 8*(WSIZE - 2 - off);
167#endif
168 *valp = val & 0xffff;
169 return ret;
170}
171
172static inline int
173fetch32 (unw_addr_space_t as, unw_accessors_t *a,
174 unw_word_t *addr, int32_t *valp, void *arg)
175{
176 unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr;
177 int ret;
178
179 assert ((off & 0x3) == 0);
180
181 *addr += 4;
182
183 ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg);
184
185#if __BYTE_ORDER == __LITTLE_ENDIAN
186 val >>= 8*off;
187#else
188 val >>= 8*(WSIZE - 4 - off);
189#endif
190 *valp = val & 0xffffffff;
191 return ret;
192}
193
194static inline int
195fetchw (unw_addr_space_t as, unw_accessors_t *a,
196 unw_word_t *addr, unw_word_t *valp, void *arg)
197{
198 int ret;
199
200 ret = (*a->access_mem) (as, *addr, valp, 0, arg);
201 *addr += WSIZE;
202 return ret;
203}
204
205extern void mi_init (void); /* machine-independent initializations */
206
207#include <tdep.h>
208
209#endif /* internal_h */