Add support to GDB for the Renesas rl78 architecture.
[external/binutils.git] / gdb / libunwind-frame.c
index 66ffb8e..893fe1e 100644 (file)
@@ -1,6 +1,6 @@
 /* Frame unwinder for frames using the libunwind library.
 
-   Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2003-2004, 2006-2012 Free Software Foundation, Inc.
 
    Written by Jeff Johnston, contributed by Red Hat Inc.
 
@@ -8,7 +8,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -17,9 +17,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 
 
 #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 int (*unw_search_unwind_table_p) (unw_addr_space_t, unw_word_t, unw_dyn_info_t *,
+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 *,
                                         unw_proc_info_t *, int, void *);
 static unw_word_t (*unw_find_dyn_list_p) (unw_addr_space_t, unw_dyn_info_t *,
                                          void *);
@@ -64,11 +75,12 @@ struct libunwind_frame_cache
   CORE_ADDR base;
   CORE_ADDR func_addr;
   unw_cursor_t cursor;
+  unw_addr_space_t as;
 };
 
-/* We need to qualify the function names with a platform-specific prefix to match 
-   the names used by the libunwind library.  The UNW_OBJ macro is provided by the
-   libunwind.h header file.  */
+/* We need to qualify the function names with a platform-specific prefix
+   to match the names used by the libunwind library.  The UNW_OBJ macro is
+   provided by the libunwind.h header file.  */
 #define STRINGIFY2(name)       #name
 #define STRINGIFY(name)                STRINGIFY2(name)
 
@@ -85,7 +97,9 @@ static char *is_signal_frame_name = STRINGIFY(UNW_OBJ(is_signal_frame));
 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 *search_unwind_table_name = STRINGIFY(UNW_OBJ(search_unwind_table));
+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 *find_dyn_list_name = STRINGIFY(UNW_OBJ(find_dyn_list));
 
 static struct libunwind_descr *
@@ -97,13 +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;
 
@@ -115,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.  */
@@ -127,7 +144,7 @@ libunwind_frame_set_descr (struct gdbarch *gdbarch, struct libunwind_descr *desc
 }
 
 static struct libunwind_frame_cache *
-libunwind_frame_cache (struct frame_info *next_frame, void **this_cache)
+libunwind_frame_cache (struct frame_info *this_frame, void **this_cache)
 {
   unw_accessors_t *acc;
   unw_addr_space_t as;
@@ -135,6 +152,7 @@ libunwind_frame_cache (struct frame_info *next_frame, void **this_cache)
   unw_regnum_t uw_sp_regnum;
   struct libunwind_frame_cache *cache;
   struct libunwind_descr *descr;
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   int i, ret;
 
   if (*this_cache)
@@ -143,46 +161,72 @@ libunwind_frame_cache (struct frame_info *next_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 = frame_func_unwind (next_frame, NORMAL_FRAME);
-  if (cache->func_addr == 0
-      && frame_relative_level (next_frame) > 0
-      && get_frame_type (next_frame) != SIGTRAMP_FRAME)
-    return NULL;
-
-  /* Get a libunwind cursor to the previous frame.  We do this by initializing
-     a cursor.  Libunwind treats a new cursor as the top of stack and will get
-     the current register set via the libunwind register accessor.  Now, we
-     provide the platform-specific accessors and we set up the register accessor to use
-     the frame register unwinding interfaces so that we properly get the registers for
-     the current frame rather than the top.  We then use the  unw_step function to 
-     move the libunwind cursor back one frame.  We can later use this cursor to find previous 
-     registers via the unw_get_reg interface which will invoke libunwind's special logic.  */
-  descr = libunwind_descr (get_frame_arch (next_frame));
+  cache->func_addr = get_frame_func (this_frame);
+  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.
+  
+     We do this by initializing a cursor.  Libunwind treats a new cursor
+     as the top of stack and will get the current register set via the
+     libunwind register accessor.  Now, we provide the platform-specific
+     accessors and we set up the register accessor to use the frame
+     register unwinding interfaces so that we properly get the registers
+     for the current frame rather than the top.  We then use the unw_step
+     function to move the libunwind cursor back one frame.  We can later
+     use this cursor to find previous registers via the unw_get_reg
+     interface which will invoke libunwind's special logic.  */
+  descr = libunwind_descr (gdbarch);
   acc = descr->accessors;
   as =  unw_create_addr_space_p (acc,
-                                TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+                                gdbarch_byte_order (gdbarch)
+                                == BFD_ENDIAN_BIG
                                 ? __BIG_ENDIAN
                                 : __LITTLE_ENDIAN);
 
-  unw_init_remote_p (&cache->cursor, as, next_frame);
+  unw_init_remote_p (&cache->cursor, as, this_frame);
   if (unw_step_p (&cache->cursor) < 0)
-    return NULL;
+    {
+      unw_destroy_addr_space_p (as);
+      return NULL;
+    }
 
   /* To get base address, get sp from previous frame.  */
-  uw_sp_regnum = descr->gdb2uw (SP_REGNUM);
+  uw_sp_regnum = descr->gdb2uw (gdbarch_sp_regnum (gdbarch));
   ret = unw_get_reg_p (&cache->cursor, uw_sp_regnum, &fp);
   if (ret < 0)
-    error (_("Can't get libunwind sp register."));
+    {
+      unw_destroy_addr_space_p (as);
+      error (_("Can't get libunwind sp register."));
+    }
 
   cache->base = (CORE_ADDR)fp;
+  cache->as = as;
 
   *this_cache = cache;
   return cache;
 }
 
+void
+libunwind_frame_dealloc_cache (struct frame_info *self, void *this_cache)
+{
+  struct libunwind_frame_cache *cache = this_cache;
+
+  if (cache->as)
+    unw_destroy_addr_space_p (cache->as);
+}
+
 unw_word_t
 libunwind_find_dyn_list (unw_addr_space_t as, unw_dyn_info_t *di, void *arg)
 {
@@ -192,71 +236,80 @@ 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
+  libunwind_frame_prev_register,
+  NULL,
+  libunwind_frame_sniffer,
+  libunwind_frame_dealloc_cache,
 };
 
 /* Verify if there is sufficient libunwind information for the frame to use
    libunwind frame unwinding.  */
-const struct frame_unwind *
-libunwind_frame_sniffer (struct frame_info *next_frame)
+int
+libunwind_frame_sniffer (const struct frame_unwind *self,
+                         struct frame_info *this_frame, void **this_cache)
 {
   unw_cursor_t cursor;
   unw_accessors_t *acc;
   unw_addr_space_t as;
   struct libunwind_descr *descr;
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   int i, ret;
 
-  /* To test for libunwind unwind support, initialize a cursor to the current frame and try to back
-     up.  We use this same method when setting up the frame cache (see libunwind_frame_cache()).
-     If libunwind returns success for this operation, it means that it has found sufficient
-     libunwind unwinding information to do so.  */
+  /* To test for libunwind unwind support, initialize a cursor to
+     the current frame and try to back up.  We use this same method
+     when setting up the frame cache (see libunwind_frame_cache()).
+     If libunwind returns success for this operation, it means that
+     it has found sufficient libunwind unwinding information to do so.  */
 
-  descr = libunwind_descr (get_frame_arch (next_frame));
+  descr = libunwind_descr (gdbarch);
   acc = descr->accessors;
   as =  unw_create_addr_space_p (acc,
-                                TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+                                gdbarch_byte_order (gdbarch)
+                                == BFD_ENDIAN_BIG
                                 ? __BIG_ENDIAN
                                 : __LITTLE_ENDIAN);
 
-  ret = unw_init_remote_p (&cursor, as, next_frame);
+  ret = unw_init_remote_p (&cursor, as, this_frame);
 
   if (ret < 0)
-    return NULL;
+    {
+      unw_destroy_addr_space_p (as);
+      return 0;
+    }
 
  
   /* Check to see if we have libunwind info by checking if we are in a 
      signal frame.  If it doesn't return an error, we have libunwind info
      and can use libunwind.  */
   ret = unw_is_signal_frame_p (&cursor);
+  unw_destroy_addr_space_p (as);
 
   if (ret < 0)
-    return NULL;
+    return 0;
 
-  return &libunwind_frame_unwind;
+  return 1;
 }
 
 void
-libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
-                     struct frame_id *this_id)
+libunwind_frame_this_id (struct frame_info *this_frame, void **this_cache,
+                        struct frame_id *this_id)
 {
   struct libunwind_frame_cache *cache =
-    libunwind_frame_cache (next_frame, this_cache);
+    libunwind_frame_cache (this_frame, this_cache);
 
   if (cache != NULL)
     (*this_id) = frame_id_build (cache->base, cache->func_addr);
-  else
-    (*this_id) = null_frame_id;
 }
 
-void
-libunwind_frame_prev_register (struct frame_info *next_frame, void **this_cache,
-                              int regnum, int *optimizedp,
-                              enum lval_type *lvalp, CORE_ADDR *addrp,
-                              int *realnump, gdb_byte *valuep)
+struct value *
+libunwind_frame_prev_register (struct frame_info *this_frame,
+                               void **this_cache, int regnum)
 {
   struct libunwind_frame_cache *cache =
-    libunwind_frame_cache (next_frame, this_cache);
+    libunwind_frame_cache (this_frame, this_cache);
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
 
   void *ptr;
   unw_cursor_t *c;
@@ -266,12 +319,13 @@ libunwind_frame_prev_register (struct frame_info *next_frame, void **this_cache,
   unw_fpreg_t fpval;
   unw_regnum_t uw_regnum;
   struct libunwind_descr *descr;
+  struct value *val = NULL;
 
   if (cache == NULL)
-    return;
+    return frame_unwind_got_constant (this_frame, regnum, 0);
   
   /* Convert from gdb register number to libunwind register number.  */
-  descr = libunwind_descr (get_frame_arch (next_frame));
+  descr = libunwind_descr (get_frame_arch (this_frame));
   uw_regnum = descr->gdb2uw (regnum);
 
   gdb_assert (regnum >= 0);
@@ -279,63 +333,54 @@ libunwind_frame_prev_register (struct frame_info *next_frame, void **this_cache,
   if (!target_has_registers)
     error (_("No registers."));
 
-  *optimizedp = 0;
-  *addrp = 0;
-  *lvalp = not_lval;
-  *realnump = -1;
-
-  if (valuep)
-    memset (valuep, 0, register_size (current_gdbarch, regnum));
-
   if (uw_regnum < 0)
-    return;
-
-  /* To get the previous register, we use the libunwind register APIs with
-     the cursor we have already pushed back to the previous frame.  */
-
-  if (descr->is_fpreg (uw_regnum))
-    {
-      ret = unw_get_fpreg_p (&cache->cursor, uw_regnum, &fpval);
-      ptr = &fpval;
-    }
-  else
-    {
-      ret = unw_get_reg_p (&cache->cursor, uw_regnum, &intval);
-      ptr = &intval;
-    }
-
-  if (ret < 0)
-    return;
-
-  if (valuep)
-    memcpy (valuep, ptr, register_size (current_gdbarch, regnum));
+    return frame_unwind_got_constant (this_frame, regnum, 0);
 
   if (unw_get_saveloc_p (&cache->cursor, uw_regnum, &sl) < 0)
-    return;
+    return frame_unwind_got_constant (this_frame, regnum, 0);
 
   switch (sl.type)
     {
-    case UNW_SLT_NONE:
-      *optimizedp = 1;
-      break;
-
     case UNW_SLT_MEMORY:
-      *lvalp = lval_memory;
-      *addrp = sl.u.addr;
+      val = frame_unwind_got_memory (this_frame, regnum, sl.u.addr);
       break;
 
     case UNW_SLT_REG:
-      *lvalp = lval_register;
-      *realnump = regnum;
+      val = frame_unwind_got_register (this_frame, regnum,
+                                       descr->uw2gdb (sl.u.regnum));
       break;
+    case UNW_SLT_NONE:
+      {
+        /* The register is not stored at a specific memory address nor
+           inside another register.  So use libunwind to fetch the register
+           value for us, and create a constant value with the result.  */
+        if (descr->is_fpreg (uw_regnum))
+          {
+            ret = unw_get_fpreg_p (&cache->cursor, uw_regnum, &fpval);
+            if (ret < 0)
+              return frame_unwind_got_constant (this_frame, regnum, 0);
+            val = frame_unwind_got_bytes (this_frame, regnum,
+                                          (gdb_byte *) &fpval);
+          }
+        else
+          {
+            ret = unw_get_reg_p (&cache->cursor, uw_regnum, &intval);
+            if (ret < 0)
+              return frame_unwind_got_constant (this_frame, regnum, 0);
+            val = frame_unwind_got_constant (this_frame, regnum, intval);
+          }
+        break;
+      }
     }
+
+  return val;
 } 
 
 CORE_ADDR
-libunwind_frame_base_address (struct frame_info *next_frame, void **this_cache)
+libunwind_frame_base_address (struct frame_info *this_frame, void **this_cache)
 {
   struct libunwind_frame_cache *cache =
-    libunwind_frame_cache (next_frame, this_cache);
+    libunwind_frame_cache (this_frame, this_cache);
 
   if (cache == NULL)
     return (CORE_ADDR)NULL;
@@ -353,13 +398,16 @@ libunwind_search_unwind_table (void *as, long ip, void *di,
 }
 
 /* Verify if we are in a sigtramp frame and we can use libunwind to unwind.  */
-const struct frame_unwind *
-libunwind_sigtramp_frame_sniffer (struct frame_info *next_frame)
+int
+libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
+                                  struct frame_info *this_frame,
+                                  void **this_cache)
 {
   unw_cursor_t cursor;
   unw_accessors_t *acc;
   unw_addr_space_t as;
   struct libunwind_descr *descr;
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   int i, ret;
 
   /* To test for libunwind unwind support, initialize a cursor to the
@@ -369,24 +417,29 @@ libunwind_sigtramp_frame_sniffer (struct frame_info *next_frame)
      has found sufficient libunwind unwinding information to do
      so.  */
 
-  descr = libunwind_descr (get_frame_arch (next_frame));
+  descr = libunwind_descr (gdbarch);
   acc = descr->accessors;
   as =  unw_create_addr_space_p (acc,
-                                TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+                                gdbarch_byte_order (gdbarch)
+                                == BFD_ENDIAN_BIG
                                 ? __BIG_ENDIAN
                                 : __LITTLE_ENDIAN);
 
-  ret = unw_init_remote_p (&cursor, as, next_frame);
+  ret = unw_init_remote_p (&cursor, as, this_frame);
 
   if (ret < 0)
-    return NULL;
+    {
+      unw_destroy_addr_space_p (as);
+      return 0;
+    }
 
   /* Check to see if we are in a signal frame.  */
   ret = unw_is_signal_frame_p (&cursor);
+  unw_destroy_addr_space_p (as);
   if (ret > 0)
-    return &libunwind_frame_unwind;
+    return 1;
 
-  return NULL;
+  return 0;
 }
 
 /* The following routine is for accessing special registers of the top frame.
@@ -395,7 +448,8 @@ libunwind_sigtramp_frame_sniffer (struct frame_info *next_frame)
    are usually located at BOF, this is not always true and only the libunwind
    info can decipher where they actually are.  */
 int
-libunwind_get_reg_special (struct gdbarch *gdbarch, int regnum, void *buf)
+libunwind_get_reg_special (struct gdbarch *gdbarch, struct regcache *regcache,
+                          int regnum, void *buf)
 {
   unw_cursor_t cursor;
   unw_accessors_t *acc;
@@ -411,13 +465,17 @@ libunwind_get_reg_special (struct gdbarch *gdbarch, int regnum, void *buf)
   descr = libunwind_descr (gdbarch);
   acc = descr->special_accessors;
   as =  unw_create_addr_space_p (acc,
-                                TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+                                gdbarch_byte_order (gdbarch)
+                                == BFD_ENDIAN_BIG
                                 ? __BIG_ENDIAN
                                 : __LITTLE_ENDIAN);
 
-  ret = unw_init_remote_p (&cursor, as, NULL);
+  ret = unw_init_remote_p (&cursor, as, regcache);
   if (ret < 0)
-    return -1;
+    {
+      unw_destroy_addr_space_p (as);
+      return -1;
+    }
 
   uw_regnum = descr->gdb2uw (regnum);
 
@@ -432,11 +490,13 @@ libunwind_get_reg_special (struct gdbarch *gdbarch, int regnum, void *buf)
       ptr = &intval;
     }
 
+  unw_destroy_addr_space_p (as);
+
   if (ret < 0)
     return -1;
 
   if (buf)
-    memcpy (buf, ptr, register_size (current_gdbarch, regnum));
+    memcpy (buf, ptr, register_size (gdbarch, regnum));
 
   return 0;
 }
@@ -448,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.  */
 
@@ -480,6 +544,10 @@ libunwind_load (void)
   if (unw_create_addr_space_p == NULL)
     return 0;
 
+  unw_destroy_addr_space_p = dlsym (handle, destroy_addr_space_name);
+  if (unw_destroy_addr_space_p == NULL)
+    return 0;
+
   unw_search_unwind_table_p = dlsym (handle, search_unwind_table_name);
   if (unw_search_unwind_table_p == NULL)
     return 0;
@@ -503,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 ();
 }