]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ia64-libunwind-tdep.c
Unify gdb printf functions
[thirdparty/binutils-gdb.git] / gdb / ia64-libunwind-tdep.c
CommitLineData
05e7c244 1/* Frame unwinder for ia64 frames using the libunwind library.
0e5d83e3 2
4a94e368 3 Copyright (C) 2003-2022 Free Software Foundation, Inc.
0e5d83e3
JJ
4
5 Written by Jeff Johnston, contributed by Red Hat Inc.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
0e5d83e3
JJ
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
0e5d83e3
JJ
21
22#include "defs.h"
23
24#include "inferior.h"
25#include "frame.h"
26#include "frame-base.h"
27#include "frame-unwind.h"
28#include "gdbcore.h"
29#include "gdbtypes.h"
30#include "symtab.h"
31#include "objfiles.h"
32#include "regcache.h"
33
34#include <dlfcn.h>
35
05e7c244 36#include "ia64-libunwind-tdep.h"
0e5d83e3 37
268a13a5 38#include "gdbsupport/preprocessor.h"
0e5d83e3 39
05e7c244
JK
40/* IA-64 is the only target that currently uses ia64-libunwind-tdep.
41 Note how UNW_TARGET, UNW_OBJ, etc. are compile time constants below.
b54a8fd7
PA
42 Those come from libunwind's headers, and are target dependent.
43 Also, some of libunwind's typedefs are target dependent, as e.g.,
44 unw_word_t. If some other target wants to use this, we will need
45 to do some abstracting in order to make it possible to select which
46 libunwind we're talking to at runtime (and have one per arch). */
47
3e5e6e2a
JB
48/* The following two macros are normally defined in <endian.h>.
49 But systems such as ia64-hpux do not provide such header, so
50 we just define them here if not already defined. */
51#ifndef __LITTLE_ENDIAN
52#define __LITTLE_ENDIAN 1234
53#endif
54#ifndef __BIG_ENDIAN
55#define __BIG_ENDIAN 4321
56#endif
57
0e5d83e3
JJ
58static int libunwind_initialized;
59static struct gdbarch_data *libunwind_descr_handle;
60
0e5d83e3 61/* Required function pointers from libunwind. */
bfb0d950
AS
62typedef int (unw_get_reg_p_ftype) (unw_cursor_t *, unw_regnum_t, unw_word_t *);
63static unw_get_reg_p_ftype *unw_get_reg_p;
64typedef int (unw_get_fpreg_p_ftype) (unw_cursor_t *, unw_regnum_t,
65 unw_fpreg_t *);
66static unw_get_fpreg_p_ftype *unw_get_fpreg_p;
67typedef int (unw_get_saveloc_p_ftype) (unw_cursor_t *, unw_regnum_t,
68 unw_save_loc_t *);
69static unw_get_saveloc_p_ftype *unw_get_saveloc_p;
70typedef int (unw_is_signal_frame_p_ftype) (unw_cursor_t *);
71static unw_is_signal_frame_p_ftype *unw_is_signal_frame_p;
72typedef int (unw_step_p_ftype) (unw_cursor_t *);
73static unw_step_p_ftype *unw_step_p;
74typedef int (unw_init_remote_p_ftype) (unw_cursor_t *, unw_addr_space_t,
75 void *);
76static unw_init_remote_p_ftype *unw_init_remote_p;
77typedef unw_addr_space_t (unw_create_addr_space_p_ftype) (unw_accessors_t *,
78 int);
79static unw_create_addr_space_p_ftype *unw_create_addr_space_p;
80typedef void (unw_destroy_addr_space_p_ftype) (unw_addr_space_t);
81static unw_destroy_addr_space_p_ftype *unw_destroy_addr_space_p;
82typedef int (unw_search_unwind_table_p_ftype) (unw_addr_space_t, unw_word_t,
83 unw_dyn_info_t *,
84 unw_proc_info_t *, int, void *);
85static unw_search_unwind_table_p_ftype *unw_search_unwind_table_p;
86typedef unw_word_t (unw_find_dyn_list_p_ftype) (unw_addr_space_t,
87 unw_dyn_info_t *, void *);
88static unw_find_dyn_list_p_ftype *unw_find_dyn_list_p;
0e5d83e3
JJ
89
90
91struct libunwind_frame_cache
92{
93 CORE_ADDR base;
94 CORE_ADDR func_addr;
95 unw_cursor_t cursor;
272dfcfd 96 unw_addr_space_t as;
0e5d83e3
JJ
97};
98
15c1e57f
JB
99/* We need to qualify the function names with a platform-specific prefix
100 to match the names used by the libunwind library. The UNW_OBJ macro is
101 provided by the libunwind.h header file. */
0e5d83e3 102
38e400fa 103#ifndef LIBUNWIND_SO
70f575cc
JK
104/* Use the stable ABI major version number. `libunwind-ia64.so' is a link time
105 only library, not a runtime one. */
75528772
JK
106#define LIBUNWIND_SO "libunwind-" STRINGIFY(UNW_TARGET) ".so.8"
107
108/* Provide also compatibility with older .so. The two APIs are compatible, .8
109 is only extended a bit, GDB does not use the extended API at all. */
110#define LIBUNWIND_SO_7 "libunwind-" STRINGIFY(UNW_TARGET) ".so.7"
38e400fa
JJ
111#endif
112
e83f4d97
SM
113static const char *get_reg_name = STRINGIFY(UNW_OBJ(get_reg));
114static const char *get_fpreg_name = STRINGIFY(UNW_OBJ(get_fpreg));
115static const char *get_saveloc_name = STRINGIFY(UNW_OBJ(get_save_loc));
116static const char *is_signal_frame_name = STRINGIFY(UNW_OBJ(is_signal_frame));
117static const char *step_name = STRINGIFY(UNW_OBJ(step));
118static const char *init_remote_name = STRINGIFY(UNW_OBJ(init_remote));
119static const char *create_addr_space_name
120 = STRINGIFY(UNW_OBJ(create_addr_space));
121static const char *destroy_addr_space_name
122 = STRINGIFY(UNW_OBJ(destroy_addr_space));
123static const char *search_unwind_table_name
3e43a32a 124 = STRINGIFY(UNW_OBJ(search_unwind_table));
e83f4d97 125static const char *find_dyn_list_name = STRINGIFY(UNW_OBJ(find_dyn_list));
0e5d83e3
JJ
126
127static struct libunwind_descr *
128libunwind_descr (struct gdbarch *gdbarch)
129{
bfb0d950
AS
130 return ((struct libunwind_descr *)
131 gdbarch_data (gdbarch, libunwind_descr_handle));
0e5d83e3
JJ
132}
133
134static void *
3bc98c0c 135libunwind_descr_init (struct obstack *obstack)
0e5d83e3 136{
3e43a32a 137 struct libunwind_descr *descr
3bc98c0c 138 = OBSTACK_ZALLOC (obstack, struct libunwind_descr);
e0881a8e 139
0e5d83e3
JJ
140 return descr;
141}
142
143void
3e43a32a
MS
144libunwind_frame_set_descr (struct gdbarch *gdbarch,
145 struct libunwind_descr *descr)
0e5d83e3
JJ
146{
147 struct libunwind_descr *arch_descr;
148
149 gdb_assert (gdbarch != NULL);
150
bfb0d950
AS
151 arch_descr = ((struct libunwind_descr *)
152 gdbarch_data (gdbarch, libunwind_descr_handle));
3bc98c0c 153 gdb_assert (arch_descr != NULL);
0e5d83e3
JJ
154
155 /* Copy new descriptor info into arch descriptor. */
156 arch_descr->gdb2uw = descr->gdb2uw;
157 arch_descr->uw2gdb = descr->uw2gdb;
158 arch_descr->is_fpreg = descr->is_fpreg;
159 arch_descr->accessors = descr->accessors;
c5a27d9c 160 arch_descr->special_accessors = descr->special_accessors;
0e5d83e3
JJ
161}
162
163static struct libunwind_frame_cache *
15c1e57f 164libunwind_frame_cache (struct frame_info *this_frame, void **this_cache)
0e5d83e3
JJ
165{
166 unw_accessors_t *acc;
167 unw_addr_space_t as;
168 unw_word_t fp;
169 unw_regnum_t uw_sp_regnum;
170 struct libunwind_frame_cache *cache;
171 struct libunwind_descr *descr;
15c1e57f 172 struct gdbarch *gdbarch = get_frame_arch (this_frame);
b4792091 173 int ret;
0e5d83e3
JJ
174
175 if (*this_cache)
bfb0d950 176 return (struct libunwind_frame_cache *) *this_cache;
0e5d83e3
JJ
177
178 /* Allocate a new cache. */
179 cache = FRAME_OBSTACK_ZALLOC (struct libunwind_frame_cache);
180
15c1e57f 181 cache->func_addr = get_frame_func (this_frame);
1b89e62f
JB
182 if (cache->func_addr == 0)
183 /* This can happen when the frame corresponds to a function for which
184 there is no debugging information nor any entry in the symbol table.
185 This is probably a static function for which an entry in the symbol
186 table was not created when the objfile got linked (observed in
187 libpthread.so on ia64-hpux).
188
189 The best we can do, in that case, is use the frame PC as the function
190 address. We don't need to give up since we still have the unwind
191 record to help us perform the unwinding. There is also another
85102364 192 compelling to continue, because abandoning now means stopping
1b89e62f
JB
193 the backtrace, which can never be helpful for the user. */
194 cache->func_addr = get_frame_pc (this_frame);
0e5d83e3 195
15c1e57f
JB
196 /* Get a libunwind cursor to the previous frame.
197
198 We do this by initializing a cursor. Libunwind treats a new cursor
199 as the top of stack and will get the current register set via the
200 libunwind register accessor. Now, we provide the platform-specific
201 accessors and we set up the register accessor to use the frame
202 register unwinding interfaces so that we properly get the registers
203 for the current frame rather than the top. We then use the unw_step
204 function to move the libunwind cursor back one frame. We can later
205 use this cursor to find previous registers via the unw_get_reg
206 interface which will invoke libunwind's special logic. */
8cff2ae6 207 descr = libunwind_descr (gdbarch);
bfb0d950 208 acc = (unw_accessors_t *) descr->accessors;
0e5d83e3 209 as = unw_create_addr_space_p (acc,
8cff2ae6 210 gdbarch_byte_order (gdbarch)
4c6b5505 211 == BFD_ENDIAN_BIG
0e5d83e3
JJ
212 ? __BIG_ENDIAN
213 : __LITTLE_ENDIAN);
214
15c1e57f 215 unw_init_remote_p (&cache->cursor, as, this_frame);
c5a27d9c 216 if (unw_step_p (&cache->cursor) < 0)
f43ae3f1
AS
217 {
218 unw_destroy_addr_space_p (as);
219 return NULL;
220 }
0e5d83e3
JJ
221
222 /* To get base address, get sp from previous frame. */
8cff2ae6 223 uw_sp_regnum = descr->gdb2uw (gdbarch_sp_regnum (gdbarch));
0e5d83e3
JJ
224 ret = unw_get_reg_p (&cache->cursor, uw_sp_regnum, &fp);
225 if (ret < 0)
f43ae3f1
AS
226 {
227 unw_destroy_addr_space_p (as);
228 error (_("Can't get libunwind sp register."));
229 }
0e5d83e3
JJ
230
231 cache->base = (CORE_ADDR)fp;
272dfcfd 232 cache->as = as;
0e5d83e3
JJ
233
234 *this_cache = cache;
235 return cache;
236}
237
272dfcfd
AS
238void
239libunwind_frame_dealloc_cache (struct frame_info *self, void *this_cache)
240{
bfb0d950
AS
241 struct libunwind_frame_cache *cache
242 = (struct libunwind_frame_cache *) this_cache;
e0881a8e 243
272dfcfd
AS
244 if (cache->as)
245 unw_destroy_addr_space_p (cache->as);
246}
247
503ff15d
KB
248unw_word_t
249libunwind_find_dyn_list (unw_addr_space_t as, unw_dyn_info_t *di, void *arg)
0e5d83e3 250{
503ff15d 251 return unw_find_dyn_list_p (as, di, arg);
0e5d83e3
JJ
252}
253
0e5d83e3
JJ
254/* Verify if there is sufficient libunwind information for the frame to use
255 libunwind frame unwinding. */
15c1e57f
JB
256int
257libunwind_frame_sniffer (const struct frame_unwind *self,
dda83cd7 258 struct frame_info *this_frame, void **this_cache)
0e5d83e3
JJ
259{
260 unw_cursor_t cursor;
261 unw_accessors_t *acc;
262 unw_addr_space_t as;
263 struct libunwind_descr *descr;
15c1e57f 264 struct gdbarch *gdbarch = get_frame_arch (this_frame);
b4792091 265 int ret;
0e5d83e3 266
15c1e57f
JB
267 /* To test for libunwind unwind support, initialize a cursor to
268 the current frame and try to back up. We use this same method
269 when setting up the frame cache (see libunwind_frame_cache()).
270 If libunwind returns success for this operation, it means that
271 it has found sufficient libunwind unwinding information to do so. */
0e5d83e3 272
8cff2ae6 273 descr = libunwind_descr (gdbarch);
bfb0d950 274 acc = (unw_accessors_t *) descr->accessors;
0e5d83e3 275 as = unw_create_addr_space_p (acc,
8cff2ae6 276 gdbarch_byte_order (gdbarch)
4c6b5505 277 == BFD_ENDIAN_BIG
0e5d83e3
JJ
278 ? __BIG_ENDIAN
279 : __LITTLE_ENDIAN);
280
15c1e57f 281 ret = unw_init_remote_p (&cursor, as, this_frame);
0e5d83e3 282
c5a27d9c 283 if (ret < 0)
f43ae3f1
AS
284 {
285 unw_destroy_addr_space_p (as);
15c1e57f 286 return 0;
f43ae3f1 287 }
c5a27d9c
JJ
288
289
290 /* Check to see if we have libunwind info by checking if we are in a
291 signal frame. If it doesn't return an error, we have libunwind info
292 and can use libunwind. */
293 ret = unw_is_signal_frame_p (&cursor);
f43ae3f1 294 unw_destroy_addr_space_p (as);
0e5d83e3
JJ
295
296 if (ret < 0)
15c1e57f 297 return 0;
0e5d83e3 298
15c1e57f 299 return 1;
0e5d83e3
JJ
300}
301
302void
15c1e57f 303libunwind_frame_this_id (struct frame_info *this_frame, void **this_cache,
dda83cd7 304 struct frame_id *this_id)
0e5d83e3
JJ
305{
306 struct libunwind_frame_cache *cache =
15c1e57f 307 libunwind_frame_cache (this_frame, this_cache);
0e5d83e3 308
c5a27d9c
JJ
309 if (cache != NULL)
310 (*this_id) = frame_id_build (cache->base, cache->func_addr);
0e5d83e3
JJ
311}
312
15c1e57f
JB
313struct value *
314libunwind_frame_prev_register (struct frame_info *this_frame,
dda83cd7 315 void **this_cache, int regnum)
0e5d83e3
JJ
316{
317 struct libunwind_frame_cache *cache =
15c1e57f 318 libunwind_frame_cache (this_frame, this_cache);
0e5d83e3 319
0e5d83e3 320 unw_save_loc_t sl;
b4792091 321 int ret;
0e5d83e3
JJ
322 unw_word_t intval;
323 unw_fpreg_t fpval;
324 unw_regnum_t uw_regnum;
325 struct libunwind_descr *descr;
15c1e57f 326 struct value *val = NULL;
0e5d83e3 327
c5a27d9c 328 if (cache == NULL)
15c1e57f 329 return frame_unwind_got_constant (this_frame, regnum, 0);
c5a27d9c 330
0e5d83e3 331 /* Convert from gdb register number to libunwind register number. */
15c1e57f 332 descr = libunwind_descr (get_frame_arch (this_frame));
0e5d83e3
JJ
333 uw_regnum = descr->gdb2uw (regnum);
334
335 gdb_assert (regnum >= 0);
336
9dccd06e 337 if (!target_has_registers ())
8a3fe4f8 338 error (_("No registers."));
0e5d83e3 339
0e5d83e3 340 if (uw_regnum < 0)
15c1e57f 341 return frame_unwind_got_constant (this_frame, regnum, 0);
0e5d83e3
JJ
342
343 if (unw_get_saveloc_p (&cache->cursor, uw_regnum, &sl) < 0)
15c1e57f 344 return frame_unwind_got_constant (this_frame, regnum, 0);
0e5d83e3
JJ
345
346 switch (sl.type)
347 {
0e5d83e3 348 case UNW_SLT_MEMORY:
15c1e57f 349 val = frame_unwind_got_memory (this_frame, regnum, sl.u.addr);
0e5d83e3
JJ
350 break;
351
352 case UNW_SLT_REG:
15c1e57f 353 val = frame_unwind_got_register (this_frame, regnum,
dda83cd7 354 descr->uw2gdb (sl.u.regnum));
0e5d83e3 355 break;
15c1e57f
JB
356 case UNW_SLT_NONE:
357 {
dda83cd7
SM
358 /* The register is not stored at a specific memory address nor
359 inside another register. So use libunwind to fetch the register
360 value for us, and create a constant value with the result. */
361 if (descr->is_fpreg (uw_regnum))
362 {
363 ret = unw_get_fpreg_p (&cache->cursor, uw_regnum, &fpval);
364 if (ret < 0)
365 return frame_unwind_got_constant (this_frame, regnum, 0);
366 val = frame_unwind_got_bytes (this_frame, regnum,
367 (gdb_byte *) &fpval);
368 }
369 else
370 {
371 ret = unw_get_reg_p (&cache->cursor, uw_regnum, &intval);
372 if (ret < 0)
373 return frame_unwind_got_constant (this_frame, regnum, 0);
374 val = frame_unwind_got_constant (this_frame, regnum, intval);
375 }
376 break;
15c1e57f 377 }
0e5d83e3 378 }
15c1e57f
JB
379
380 return val;
0e5d83e3
JJ
381}
382
0e5d83e3
JJ
383/* The following is a glue routine to call the libunwind unwind table
384 search function to get unwind information for a specified ip address. */
385int
386libunwind_search_unwind_table (void *as, long ip, void *di,
387 void *pi, int need_unwind_info, void *args)
388{
bfb0d950
AS
389 return unw_search_unwind_table_p (*(unw_addr_space_t *) as, (unw_word_t) ip,
390 (unw_dyn_info_t *) di,
391 (unw_proc_info_t *) pi, need_unwind_info,
392 args);
0e5d83e3
JJ
393}
394
c5a27d9c 395/* Verify if we are in a sigtramp frame and we can use libunwind to unwind. */
15c1e57f
JB
396int
397libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
dda83cd7
SM
398 struct frame_info *this_frame,
399 void **this_cache)
c5a27d9c
JJ
400{
401 unw_cursor_t cursor;
402 unw_accessors_t *acc;
403 unw_addr_space_t as;
404 struct libunwind_descr *descr;
15c1e57f 405 struct gdbarch *gdbarch = get_frame_arch (this_frame);
b4792091 406 int ret;
c5a27d9c
JJ
407
408 /* To test for libunwind unwind support, initialize a cursor to the
409 current frame and try to back up. We use this same method when
410 setting up the frame cache (see libunwind_frame_cache()). If
411 libunwind returns success for this operation, it means that it
412 has found sufficient libunwind unwinding information to do
413 so. */
414
8cff2ae6 415 descr = libunwind_descr (gdbarch);
bfb0d950 416 acc = (unw_accessors_t *) descr->accessors;
c5a27d9c 417 as = unw_create_addr_space_p (acc,
8cff2ae6 418 gdbarch_byte_order (gdbarch)
4c6b5505 419 == BFD_ENDIAN_BIG
c5a27d9c
JJ
420 ? __BIG_ENDIAN
421 : __LITTLE_ENDIAN);
422
15c1e57f 423 ret = unw_init_remote_p (&cursor, as, this_frame);
c5a27d9c
JJ
424
425 if (ret < 0)
f43ae3f1
AS
426 {
427 unw_destroy_addr_space_p (as);
15c1e57f 428 return 0;
f43ae3f1 429 }
c5a27d9c
JJ
430
431 /* Check to see if we are in a signal frame. */
432 ret = unw_is_signal_frame_p (&cursor);
f43ae3f1 433 unw_destroy_addr_space_p (as);
c5a27d9c 434 if (ret > 0)
15c1e57f 435 return 1;
c5a27d9c 436
15c1e57f 437 return 0;
c5a27d9c
JJ
438}
439
440/* The following routine is for accessing special registers of the top frame.
441 A special set of accessors must be given that work without frame info.
442 This is used by ia64 to access the rse registers r32-r127. While they
443 are usually located at BOF, this is not always true and only the libunwind
444 info can decipher where they actually are. */
445int
933522d1 446libunwind_get_reg_special (struct gdbarch *gdbarch, readable_regcache *regcache,
45ecac4b 447 int regnum, void *buf)
c5a27d9c
JJ
448{
449 unw_cursor_t cursor;
450 unw_accessors_t *acc;
451 unw_addr_space_t as;
452 struct libunwind_descr *descr;
453 int ret;
454 unw_regnum_t uw_regnum;
455 unw_word_t intval;
456 unw_fpreg_t fpval;
457 void *ptr;
458
459
460 descr = libunwind_descr (gdbarch);
bfb0d950 461 acc = (unw_accessors_t *) descr->special_accessors;
c5a27d9c 462 as = unw_create_addr_space_p (acc,
8cff2ae6 463 gdbarch_byte_order (gdbarch)
4c6b5505 464 == BFD_ENDIAN_BIG
c5a27d9c
JJ
465 ? __BIG_ENDIAN
466 : __LITTLE_ENDIAN);
467
45ecac4b 468 ret = unw_init_remote_p (&cursor, as, regcache);
c5a27d9c 469 if (ret < 0)
f43ae3f1
AS
470 {
471 unw_destroy_addr_space_p (as);
472 return -1;
473 }
c5a27d9c
JJ
474
475 uw_regnum = descr->gdb2uw (regnum);
476
477 if (descr->is_fpreg (uw_regnum))
478 {
479 ret = unw_get_fpreg_p (&cursor, uw_regnum, &fpval);
480 ptr = &fpval;
481 }
482 else
483 {
484 ret = unw_get_reg_p (&cursor, uw_regnum, &intval);
485 ptr = &intval;
486 }
487
f43ae3f1
AS
488 unw_destroy_addr_space_p (as);
489
c5a27d9c
JJ
490 if (ret < 0)
491 return -1;
492
493 if (buf)
8cff2ae6 494 memcpy (buf, ptr, register_size (gdbarch, regnum));
c5a27d9c
JJ
495
496 return 0;
497}
498
0e5d83e3
JJ
499static int
500libunwind_load (void)
501{
502 void *handle;
75528772 503 char *so_error = NULL;
0e5d83e3
JJ
504
505 handle = dlopen (LIBUNWIND_SO, RTLD_NOW);
75528772
JK
506 if (handle == NULL)
507 {
508 so_error = xstrdup (dlerror ());
509#ifdef LIBUNWIND_SO_7
510 handle = dlopen (LIBUNWIND_SO_7, RTLD_NOW);
511#endif /* LIBUNWIND_SO_7 */
512 }
0e5d83e3 513 if (handle == NULL)
47c1316c 514 {
6cb06a8c
TT
515 gdb_printf (gdb_stderr, _("[GDB failed to load %s: %s]\n"),
516 LIBUNWIND_SO, so_error);
75528772 517#ifdef LIBUNWIND_SO_7
6cb06a8c
TT
518 gdb_printf (gdb_stderr, _("[GDB failed to load %s: %s]\n"),
519 LIBUNWIND_SO_7, dlerror ());
75528772 520#endif /* LIBUNWIND_SO_7 */
47c1316c 521 }
75528772
JK
522 xfree (so_error);
523 if (handle == NULL)
524 return 0;
0e5d83e3
JJ
525
526 /* Initialize pointers to the dynamic library functions we will use. */
527
bfb0d950 528 unw_get_reg_p = (unw_get_reg_p_ftype *) dlsym (handle, get_reg_name);
0e5d83e3
JJ
529 if (unw_get_reg_p == NULL)
530 return 0;
531
bfb0d950 532 unw_get_fpreg_p = (unw_get_fpreg_p_ftype *) dlsym (handle, get_fpreg_name);
0e5d83e3
JJ
533 if (unw_get_fpreg_p == NULL)
534 return 0;
535
bfb0d950
AS
536 unw_get_saveloc_p
537 = (unw_get_saveloc_p_ftype *) dlsym (handle, get_saveloc_name);
0e5d83e3
JJ
538 if (unw_get_saveloc_p == NULL)
539 return 0;
540
bfb0d950
AS
541 unw_is_signal_frame_p
542 = (unw_is_signal_frame_p_ftype *) dlsym (handle, is_signal_frame_name);
c5a27d9c
JJ
543 if (unw_is_signal_frame_p == NULL)
544 return 0;
545
bfb0d950 546 unw_step_p = (unw_step_p_ftype *) dlsym (handle, step_name);
0e5d83e3
JJ
547 if (unw_step_p == NULL)
548 return 0;
549
bfb0d950
AS
550 unw_init_remote_p
551 = (unw_init_remote_p_ftype *) dlsym (handle, init_remote_name);
0e5d83e3
JJ
552 if (unw_init_remote_p == NULL)
553 return 0;
554
bfb0d950
AS
555 unw_create_addr_space_p
556 = (unw_create_addr_space_p_ftype *) dlsym (handle, create_addr_space_name);
0e5d83e3
JJ
557 if (unw_create_addr_space_p == NULL)
558 return 0;
559
bfb0d950
AS
560 unw_destroy_addr_space_p
561 = (unw_destroy_addr_space_p_ftype *) dlsym (handle,
562 destroy_addr_space_name);
f43ae3f1
AS
563 if (unw_destroy_addr_space_p == NULL)
564 return 0;
565
bfb0d950
AS
566 unw_search_unwind_table_p
567 = (unw_search_unwind_table_p_ftype *) dlsym (handle,
568 search_unwind_table_name);
0e5d83e3
JJ
569 if (unw_search_unwind_table_p == NULL)
570 return 0;
571
bfb0d950
AS
572 unw_find_dyn_list_p
573 = (unw_find_dyn_list_p_ftype *) dlsym (handle, find_dyn_list_name);
0e5d83e3
JJ
574 if (unw_find_dyn_list_p == NULL)
575 return 0;
576
577 return 1;
578}
579
580int
581libunwind_is_initialized (void)
582{
583 return libunwind_initialized;
584}
585
6c265988 586void _initialize_libunwind_frame ();
0e5d83e3 587void
6c265988 588_initialize_libunwind_frame ()
0e5d83e3 589{
3e43a32a 590 libunwind_descr_handle
3bc98c0c 591 = gdbarch_data_register_pre_init (libunwind_descr_init);
0e5d83e3
JJ
592
593 libunwind_initialized = libunwind_load ();
594}