Add support to GDB for the Renesas rl78 architecture.
[external/binutils.git] / gdb / libunwind-frame.c
index 231d909..893fe1e 100644 (file)
@@ -1,7 +1,6 @@
 /* Frame unwinder for frames using the libunwind library.
 
-   Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 2003-2004, 2006-2012 Free Software Foundation, Inc.
 
    Written by Jeff Johnston, contributed by Red Hat Inc.
 
 
 #include "complaints.h"
 
+/* The following two macros are normally defined in <endian.h>.
+   But systems such as ia64-hpux do not provide such header, so
+   we just define them here if not already defined.  */
+#ifndef __LITTLE_ENDIAN
+#define __LITTLE_ENDIAN 1234
+#endif
+#ifndef __BIG_ENDIAN
+#define __BIG_ENDIAN    4321
+#endif
+
 static int libunwind_initialized;
 static struct gdbarch_data *libunwind_descr_handle;
 
 /* Required function pointers from libunwind.  */
 static int (*unw_get_reg_p) (unw_cursor_t *, unw_regnum_t, unw_word_t *);
 static int (*unw_get_fpreg_p) (unw_cursor_t *, unw_regnum_t, unw_fpreg_t *);
-static int (*unw_get_saveloc_p) (unw_cursor_t *, unw_regnum_t, unw_save_loc_t *);
+static int (*unw_get_saveloc_p) (unw_cursor_t *, unw_regnum_t,
+                                unw_save_loc_t *);
 static int (*unw_is_signal_frame_p) (unw_cursor_t *);
 static int (*unw_step_p) (unw_cursor_t *);
 static int (*unw_init_remote_p) (unw_cursor_t *, unw_addr_space_t, void *);
 static unw_addr_space_t (*unw_create_addr_space_p) (unw_accessors_t *, int);
 static void (*unw_destroy_addr_space_p) (unw_addr_space_t);
-static int (*unw_search_unwind_table_p) (unw_addr_space_t, unw_word_t, unw_dyn_info_t *,
+static int (*unw_search_unwind_table_p) (unw_addr_space_t, unw_word_t,
+                                        unw_dyn_info_t *,
                                         unw_proc_info_t *, int, void *);
 static unw_word_t (*unw_find_dyn_list_p) (unw_addr_space_t, unw_dyn_info_t *,
                                          void *);
@@ -87,7 +98,8 @@ static char *step_name = STRINGIFY(UNW_OBJ(step));
 static char *init_remote_name = STRINGIFY(UNW_OBJ(init_remote));
 static char *create_addr_space_name = STRINGIFY(UNW_OBJ(create_addr_space));
 static char *destroy_addr_space_name = STRINGIFY(UNW_OBJ(destroy_addr_space));
-static char *search_unwind_table_name = STRINGIFY(UNW_OBJ(search_unwind_table));
+static char *search_unwind_table_name
+  = STRINGIFY(UNW_OBJ(search_unwind_table));
 static char *find_dyn_list_name = STRINGIFY(UNW_OBJ(find_dyn_list));
 
 static struct libunwind_descr *
@@ -99,14 +111,15 @@ libunwind_descr (struct gdbarch *gdbarch)
 static void *
 libunwind_descr_init (struct gdbarch *gdbarch)
 {
-  struct libunwind_descr *descr = GDBARCH_OBSTACK_ZALLOC (gdbarch,
-                                                         struct libunwind_descr);
+  struct libunwind_descr *descr
+    = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct libunwind_descr);
 
   return descr;
 }
 
 void
-libunwind_frame_set_descr (struct gdbarch *gdbarch, struct libunwind_descr *descr)
+libunwind_frame_set_descr (struct gdbarch *gdbarch,
+                          struct libunwind_descr *descr)
 {
   struct libunwind_descr *arch_descr;
 
@@ -118,7 +131,8 @@ libunwind_frame_set_descr (struct gdbarch *gdbarch, struct libunwind_descr *desc
     {
       /* First time here.  Must initialize data area.  */
       arch_descr = libunwind_descr_init (gdbarch);
-      deprecated_set_gdbarch_data (gdbarch, libunwind_descr_handle, arch_descr);
+      deprecated_set_gdbarch_data (gdbarch,
+                                  libunwind_descr_handle, arch_descr);
     }
 
   /* Copy new descriptor info into arch descriptor.  */
@@ -147,14 +161,20 @@ libunwind_frame_cache (struct frame_info *this_frame, void **this_cache)
   /* Allocate a new cache.  */
   cache = FRAME_OBSTACK_ZALLOC (struct libunwind_frame_cache);
 
-  /* We can assume we are unwinding a normal frame.  Even if this is
-     for a signal trampoline, ia64 signal "trampolines" use a normal
-     subroutine call to start the signal handler.  */
   cache->func_addr = get_frame_func (this_frame);
-  if (cache->func_addr == 0
-      && get_next_frame (this_frame)
-      && get_frame_type (get_next_frame (this_frame)) == NORMAL_FRAME)
-    return NULL;
+  if (cache->func_addr == 0)
+    /* This can happen when the frame corresponds to a function for which
+       there is no debugging information nor any entry in the symbol table.
+       This is probably a static function for which an entry in the symbol
+       table was not created when the objfile got linked (observed in
+       libpthread.so on ia64-hpux).
+
+       The best we can do, in that case, is use the frame PC as the function
+       address.  We don't need to give up since we still have the unwind
+       record to help us perform the unwinding.  There is also another
+       compelling to continue, because abandonning now means stopping
+       the backtrace, which can never be helpful for the user.  */
+    cache->func_addr = get_frame_pc (this_frame);
 
   /* Get a libunwind cursor to the previous frame.
   
@@ -216,6 +236,7 @@ libunwind_find_dyn_list (unw_addr_space_t as, unw_dyn_info_t *di, void *arg)
 static const struct frame_unwind libunwind_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   libunwind_frame_this_id,
   libunwind_frame_prev_register,
   NULL,
@@ -348,7 +369,6 @@ libunwind_frame_prev_register (struct frame_info *this_frame,
               return frame_unwind_got_constant (this_frame, regnum, 0);
             val = frame_unwind_got_constant (this_frame, regnum, intval);
           }
-        set_value_optimized_out (val, 1);
         break;
       }
     }
@@ -488,7 +508,11 @@ libunwind_load (void)
 
   handle = dlopen (LIBUNWIND_SO, RTLD_NOW);
   if (handle == NULL)
-    return 0;
+    {
+      fprintf_unfiltered (gdb_stderr, _("[GDB failed to load %s: %s]\n"),
+                          LIBUNWIND_SO, dlerror ());
+      return 0;
+    }
 
   /* Initialize pointers to the dynamic library functions we will use.  */
 
@@ -547,7 +571,8 @@ void _initialize_libunwind_frame (void);
 void
 _initialize_libunwind_frame (void)
 {
-  libunwind_descr_handle = gdbarch_data_register_post_init (libunwind_descr_init);
+  libunwind_descr_handle
+    = gdbarch_data_register_post_init (libunwind_descr_init);
 
   libunwind_initialized = libunwind_load ();
 }