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