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