| OLD | NEW |
| 1 /* Frame unwinder for frames using the libunwind library. | 1 /* Frame unwinder for ia64 frames using the libunwind library. |
| 2 | 2 |
| 3 Copyright (C) 2003-2004, 2006-2012 Free Software Foundation, Inc. | 3 Copyright (C) 2003-2004, 2006-2012 Free Software Foundation, Inc. |
| 4 | 4 |
| 5 Written by Jeff Johnston, contributed by Red Hat Inc. | 5 Written by Jeff Johnston, contributed by Red Hat Inc. |
| 6 | 6 |
| 7 This file is part of GDB. | 7 This file is part of GDB. |
| 8 | 8 |
| 9 This program is free software; you can redistribute it and/or modify | 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 | 10 it under the terms of the GNU General Public License as published by |
| 11 the Free Software Foundation; either version 3 of the License, or | 11 the Free Software Foundation; either version 3 of the License, or |
| (...skipping 17 matching lines...) Expand all Loading... |
| 29 #include "gdbtypes.h" | 29 #include "gdbtypes.h" |
| 30 #include "symtab.h" | 30 #include "symtab.h" |
| 31 #include "objfiles.h" | 31 #include "objfiles.h" |
| 32 #include "regcache.h" | 32 #include "regcache.h" |
| 33 | 33 |
| 34 #include <dlfcn.h> | 34 #include <dlfcn.h> |
| 35 | 35 |
| 36 #include "gdb_assert.h" | 36 #include "gdb_assert.h" |
| 37 #include "gdb_string.h" | 37 #include "gdb_string.h" |
| 38 | 38 |
| 39 #include "libunwind-frame.h" | 39 #include "ia64-libunwind-tdep.h" |
| 40 | 40 |
| 41 #include "complaints.h" | 41 #include "complaints.h" |
| 42 | 42 |
| 43 /* IA-64 is the only target that currently uses ia64-libunwind-tdep. |
| 44 Note how UNW_TARGET, UNW_OBJ, etc. are compile time constants below. |
| 45 Those come from libunwind's headers, and are target dependent. |
| 46 Also, some of libunwind's typedefs are target dependent, as e.g., |
| 47 unw_word_t. If some other target wants to use this, we will need |
| 48 to do some abstracting in order to make it possible to select which |
| 49 libunwind we're talking to at runtime (and have one per arch). */ |
| 50 |
| 43 /* The following two macros are normally defined in <endian.h>. | 51 /* The following two macros are normally defined in <endian.h>. |
| 44 But systems such as ia64-hpux do not provide such header, so | 52 But systems such as ia64-hpux do not provide such header, so |
| 45 we just define them here if not already defined. */ | 53 we just define them here if not already defined. */ |
| 46 #ifndef __LITTLE_ENDIAN | 54 #ifndef __LITTLE_ENDIAN |
| 47 #define __LITTLE_ENDIAN 1234 | 55 #define __LITTLE_ENDIAN 1234 |
| 48 #endif | 56 #endif |
| 49 #ifndef __BIG_ENDIAN | 57 #ifndef __BIG_ENDIAN |
| 50 #define __BIG_ENDIAN 4321 | 58 #define __BIG_ENDIAN 4321 |
| 51 #endif | 59 #endif |
| 52 | 60 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 80 | 88 |
| 81 /* We need to qualify the function names with a platform-specific prefix | 89 /* We need to qualify the function names with a platform-specific prefix |
| 82 to match the names used by the libunwind library. The UNW_OBJ macro is | 90 to match the names used by the libunwind library. The UNW_OBJ macro is |
| 83 provided by the libunwind.h header file. */ | 91 provided by the libunwind.h header file. */ |
| 84 #define STRINGIFY2(name) #name | 92 #define STRINGIFY2(name) #name |
| 85 #define STRINGIFY(name) STRINGIFY2(name) | 93 #define STRINGIFY(name) STRINGIFY2(name) |
| 86 | 94 |
| 87 #ifndef LIBUNWIND_SO | 95 #ifndef LIBUNWIND_SO |
| 88 /* Use the stable ABI major version number. `libunwind-ia64.so' is a link time | 96 /* Use the stable ABI major version number. `libunwind-ia64.so' is a link time |
| 89 only library, not a runtime one. */ | 97 only library, not a runtime one. */ |
| 90 #define LIBUNWIND_SO "libunwind-" STRINGIFY(UNW_TARGET) ".so.7" | 98 #define LIBUNWIND_SO "libunwind-" STRINGIFY(UNW_TARGET) ".so.8" |
| 99 |
| 100 /* Provide also compatibility with older .so. The two APIs are compatible, .8 |
| 101 is only extended a bit, GDB does not use the extended API at all. */ |
| 102 #define LIBUNWIND_SO_7 "libunwind-" STRINGIFY(UNW_TARGET) ".so.7" |
| 91 #endif | 103 #endif |
| 92 | 104 |
| 93 static char *get_reg_name = STRINGIFY(UNW_OBJ(get_reg)); | 105 static char *get_reg_name = STRINGIFY(UNW_OBJ(get_reg)); |
| 94 static char *get_fpreg_name = STRINGIFY(UNW_OBJ(get_fpreg)); | 106 static char *get_fpreg_name = STRINGIFY(UNW_OBJ(get_fpreg)); |
| 95 static char *get_saveloc_name = STRINGIFY(UNW_OBJ(get_save_loc)); | 107 static char *get_saveloc_name = STRINGIFY(UNW_OBJ(get_save_loc)); |
| 96 static char *is_signal_frame_name = STRINGIFY(UNW_OBJ(is_signal_frame)); | 108 static char *is_signal_frame_name = STRINGIFY(UNW_OBJ(is_signal_frame)); |
| 97 static char *step_name = STRINGIFY(UNW_OBJ(step)); | 109 static char *step_name = STRINGIFY(UNW_OBJ(step)); |
| 98 static char *init_remote_name = STRINGIFY(UNW_OBJ(init_remote)); | 110 static char *init_remote_name = STRINGIFY(UNW_OBJ(init_remote)); |
| 99 static char *create_addr_space_name = STRINGIFY(UNW_OBJ(create_addr_space)); | 111 static char *create_addr_space_name = STRINGIFY(UNW_OBJ(create_addr_space)); |
| 100 static char *destroy_addr_space_name = STRINGIFY(UNW_OBJ(destroy_addr_space)); | 112 static char *destroy_addr_space_name = STRINGIFY(UNW_OBJ(destroy_addr_space)); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 if (cache->as) | 238 if (cache->as) |
| 227 unw_destroy_addr_space_p (cache->as); | 239 unw_destroy_addr_space_p (cache->as); |
| 228 } | 240 } |
| 229 | 241 |
| 230 unw_word_t | 242 unw_word_t |
| 231 libunwind_find_dyn_list (unw_addr_space_t as, unw_dyn_info_t *di, void *arg) | 243 libunwind_find_dyn_list (unw_addr_space_t as, unw_dyn_info_t *di, void *arg) |
| 232 { | 244 { |
| 233 return unw_find_dyn_list_p (as, di, arg); | 245 return unw_find_dyn_list_p (as, di, arg); |
| 234 } | 246 } |
| 235 | 247 |
| 236 static const struct frame_unwind libunwind_frame_unwind = | |
| 237 { | |
| 238 NORMAL_FRAME, | |
| 239 default_frame_unwind_stop_reason, | |
| 240 libunwind_frame_this_id, | |
| 241 libunwind_frame_prev_register, | |
| 242 NULL, | |
| 243 libunwind_frame_sniffer, | |
| 244 libunwind_frame_dealloc_cache, | |
| 245 }; | |
| 246 | |
| 247 /* Verify if there is sufficient libunwind information for the frame to use | 248 /* Verify if there is sufficient libunwind information for the frame to use |
| 248 libunwind frame unwinding. */ | 249 libunwind frame unwinding. */ |
| 249 int | 250 int |
| 250 libunwind_frame_sniffer (const struct frame_unwind *self, | 251 libunwind_frame_sniffer (const struct frame_unwind *self, |
| 251 struct frame_info *this_frame, void **this_cache) | 252 struct frame_info *this_frame, void **this_cache) |
| 252 { | 253 { |
| 253 unw_cursor_t cursor; | 254 unw_cursor_t cursor; |
| 254 unw_accessors_t *acc; | 255 unw_accessors_t *acc; |
| 255 unw_addr_space_t as; | 256 unw_addr_space_t as; |
| 256 struct libunwind_descr *descr; | 257 struct libunwind_descr *descr; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 return frame_unwind_got_constant (this_frame, regnum, 0); | 370 return frame_unwind_got_constant (this_frame, regnum, 0); |
| 370 val = frame_unwind_got_constant (this_frame, regnum, intval); | 371 val = frame_unwind_got_constant (this_frame, regnum, intval); |
| 371 } | 372 } |
| 372 break; | 373 break; |
| 373 } | 374 } |
| 374 } | 375 } |
| 375 | 376 |
| 376 return val; | 377 return val; |
| 377 } | 378 } |
| 378 | 379 |
| 379 CORE_ADDR | |
| 380 libunwind_frame_base_address (struct frame_info *this_frame, void **this_cache) | |
| 381 { | |
| 382 struct libunwind_frame_cache *cache = | |
| 383 libunwind_frame_cache (this_frame, this_cache); | |
| 384 | |
| 385 if (cache == NULL) | |
| 386 return (CORE_ADDR)NULL; | |
| 387 return cache->base; | |
| 388 } | |
| 389 | |
| 390 /* The following is a glue routine to call the libunwind unwind table | 380 /* The following is a glue routine to call the libunwind unwind table |
| 391 search function to get unwind information for a specified ip address. */ | 381 search function to get unwind information for a specified ip address. */ |
| 392 int | 382 int |
| 393 libunwind_search_unwind_table (void *as, long ip, void *di, | 383 libunwind_search_unwind_table (void *as, long ip, void *di, |
| 394 void *pi, int need_unwind_info, void *args) | 384 void *pi, int need_unwind_info, void *args) |
| 395 { | 385 { |
| 396 return unw_search_unwind_table_p (*(unw_addr_space_t *)as, (unw_word_t )ip, | 386 return unw_search_unwind_table_p (*(unw_addr_space_t *)as, (unw_word_t )ip, |
| 397 di, pi, need_unwind_info, args); | 387 di, pi, need_unwind_info, args); |
| 398 } | 388 } |
| 399 | 389 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 if (buf) | 488 if (buf) |
| 499 memcpy (buf, ptr, register_size (gdbarch, regnum)); | 489 memcpy (buf, ptr, register_size (gdbarch, regnum)); |
| 500 | 490 |
| 501 return 0; | 491 return 0; |
| 502 } | 492 } |
| 503 | 493 |
| 504 static int | 494 static int |
| 505 libunwind_load (void) | 495 libunwind_load (void) |
| 506 { | 496 { |
| 507 void *handle; | 497 void *handle; |
| 498 char *so_error = NULL; |
| 508 | 499 |
| 509 handle = dlopen (LIBUNWIND_SO, RTLD_NOW); | 500 handle = dlopen (LIBUNWIND_SO, RTLD_NOW); |
| 510 if (handle == NULL) | 501 if (handle == NULL) |
| 502 { |
| 503 so_error = xstrdup (dlerror ()); |
| 504 #ifdef LIBUNWIND_SO_7 |
| 505 handle = dlopen (LIBUNWIND_SO_7, RTLD_NOW); |
| 506 #endif /* LIBUNWIND_SO_7 */ |
| 507 } |
| 508 if (handle == NULL) |
| 509 { |
| 510 fprintf_unfiltered (gdb_stderr, _("[GDB failed to load %s: %s]\n"), |
| 511 LIBUNWIND_SO, so_error); |
| 512 #ifdef LIBUNWIND_SO_7 |
| 513 fprintf_unfiltered (gdb_stderr, _("[GDB failed to load %s: %s]\n"), |
| 514 LIBUNWIND_SO_7, dlerror ()); |
| 515 #endif /* LIBUNWIND_SO_7 */ |
| 516 } |
| 517 xfree (so_error); |
| 518 if (handle == NULL) |
| 511 return 0; | 519 return 0; |
| 512 | 520 |
| 513 /* Initialize pointers to the dynamic library functions we will use. */ | 521 /* Initialize pointers to the dynamic library functions we will use. */ |
| 514 | 522 |
| 515 unw_get_reg_p = dlsym (handle, get_reg_name); | 523 unw_get_reg_p = dlsym (handle, get_reg_name); |
| 516 if (unw_get_reg_p == NULL) | 524 if (unw_get_reg_p == NULL) |
| 517 return 0; | 525 return 0; |
| 518 | 526 |
| 519 unw_get_fpreg_p = dlsym (handle, get_fpreg_name); | 527 unw_get_fpreg_p = dlsym (handle, get_fpreg_name); |
| 520 if (unw_get_fpreg_p == NULL) | 528 if (unw_get_fpreg_p == NULL) |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 void _initialize_libunwind_frame (void); | 573 void _initialize_libunwind_frame (void); |
| 566 | 574 |
| 567 void | 575 void |
| 568 _initialize_libunwind_frame (void) | 576 _initialize_libunwind_frame (void) |
| 569 { | 577 { |
| 570 libunwind_descr_handle | 578 libunwind_descr_handle |
| 571 = gdbarch_data_register_post_init (libunwind_descr_init); | 579 = gdbarch_data_register_post_init (libunwind_descr_init); |
| 572 | 580 |
| 573 libunwind_initialized = libunwind_load (); | 581 libunwind_initialized = libunwind_load (); |
| 574 } | 582 } |
| OLD | NEW |