2007-06-13 Claudio Fontana <claudio.fontana@gmail.com>
[deliverable/binutils-gdb.git] / gdb / ia64-tdep.c
index 1aed60d99820598548a48a0a226cd63c1e13d3b8..a462f6493fbe2b36f31c9366a42ca990343700af 100644 (file)
@@ -25,6 +25,7 @@
 #include "gdbcore.h"
 #include "arch-utils.h"
 #include "floatformat.h"
+#include "gdbtypes.h"
 #include "regcache.h"
 #include "reggroups.h"
 #include "frame.h"
@@ -691,7 +692,7 @@ ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
       /* First try and use the libunwind special reg accessor, otherwise fallback to
         standard logic.  */
       if (!libunwind_is_initialized ()
-         || libunwind_get_reg_special (gdbarch, regnum, buf) != 0)
+         || libunwind_get_reg_special (gdbarch, regcache, regnum, buf) != 0)
 #endif
        {
          /* The fallback position is to assume that r32-r127 are found sequentially
@@ -1554,7 +1555,7 @@ ia64_frame_cache (struct frame_info *next_frame, void **this_cache)
 
   cache->cfm = cfm;
 
-  cache->pc = frame_func_unwind (next_frame);
+  cache->pc = frame_func_unwind (next_frame, NORMAL_FRAME);
 
   if (cache->pc != 0)
     examine_prologue (cache->pc, frame_pc_unwind (next_frame), next_frame, cache);
@@ -2077,12 +2078,14 @@ static const struct frame_unwind ia64_sigtramp_frame_unwind =
 static const struct frame_unwind *
 ia64_sigtramp_frame_sniffer (struct frame_info *next_frame)
 {
-  char *name;
-  CORE_ADDR pc = frame_pc_unwind (next_frame);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (next_frame));
+  if (tdep->pc_in_sigtramp)
+    {
+      CORE_ADDR pc = frame_pc_unwind (next_frame);
 
-  find_pc_partial_function (pc, &name, NULL, NULL);
-  if (legacy_pc_in_sigtramp (pc, name))
-    return &ia64_sigtramp_frame_unwind;
+      if (tdep->pc_in_sigtramp (pc))
+       return &ia64_sigtramp_frame_unwind;
+    }
 
   return NULL;
 }
@@ -2215,106 +2218,53 @@ ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
   long new_sof, old_sof;
   char buf[MAX_REGISTER_SIZE];
   
-  if (write)
-    {
-      if (regnum < 0)
-       /* ignore writes to pseudo-registers such as UNW_IA64_PROC_STARTI.  */
-       return 0;
-  
-      switch (uw_regnum)
-       {
-       case UNW_REG_IP:
-         ia64_write_pc (*val, inferior_ptid);
-         break;
+  /* We never call any libunwind routines that need to write registers.  */
+  gdb_assert (!write);
+
+  switch (uw_regnum)
+    {
+      case UNW_REG_IP:
+       /* Libunwind expects to see the pc value which means the slot number
+          from the psr must be merged with the ip word address.  */
+       frame_unwind_register (next_frame, IA64_IP_REGNUM, buf);
+       ip = extract_unsigned_integer (buf, 8); 
+       frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
+       psr = extract_unsigned_integer (buf, 8); 
+       *val = ip | ((psr >> 41) & 0x3);
+       break;
+      case UNW_IA64_AR_BSP:
+       /* Libunwind expects to see the beginning of the current register
+          frame so we must account for the fact that ptrace() will return a value
+          for bsp that points *after* the current register frame.  */
+       frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
+       bsp = extract_unsigned_integer (buf, 8);
+       frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
+       cfm = extract_unsigned_integer (buf, 8); 
+       sof = (cfm & 0x7f);
+       *val = ia64_rse_skip_regs (bsp, -sof);
+       break;
 
-       case UNW_IA64_AR_BSPSTORE:
-         write_register (IA64_BSP_REGNUM, *val);
-         break;
-         
-       case UNW_IA64_AR_BSP:
-       case UNW_IA64_BSP:
-         /* Account for the fact that ptrace() expects bsp to point
-            after the current register frame.  */
-         cfm = read_register (IA64_CFM_REGNUM);
-         sof = (cfm & 0x7f);
-         bsp = ia64_rse_skip_regs (*val, sof);
-         write_register (IA64_BSP_REGNUM, bsp);
-         break;
-         
-       case UNW_IA64_CFM:
-         /* If we change CFM, we need to adjust ptrace's notion of
-            bsp accordingly, so that the real bsp remains
-            unchanged.  */
-         bsp = read_register (IA64_BSP_REGNUM);
-         cfm = read_register (IA64_CFM_REGNUM);
-         old_sof = (cfm & 0x7f);
-         new_sof = (*val & 0x7f);
-         if (old_sof != new_sof)
-           {
-             bsp = ia64_rse_skip_regs (bsp, -old_sof + new_sof);
-             write_register (IA64_BSP_REGNUM, bsp);
-           }
-         write_register (IA64_CFM_REGNUM, *val);
-         break;
-         
-       default:
-         write_register (regnum, *val);
-         break;
-       }
-      if (gdbarch_debug >= 1)
-       fprintf_unfiltered (gdb_stdlog, 
-                           "  access_reg: to cache: %4s=0x%s\n",
-                           (((unsigned) regnum <= IA64_NAT127_REGNUM)
-                            ? ia64_register_names[regnum] : "r??"), 
-                           paddr_nz (*val));
-    }
-  else
-    {
-      switch (uw_regnum)
-       {
-       case UNW_REG_IP:
-         /* Libunwind expects to see the pc value which means the slot number
-            from the psr must be merged with the ip word address.  */
-         frame_unwind_register (next_frame, IA64_IP_REGNUM, buf);
-         ip = extract_unsigned_integer (buf, 8); 
-         frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
-         psr = extract_unsigned_integer (buf, 8); 
-         *val = ip | ((psr >> 41) & 0x3);
-         break;
-         
-       case UNW_IA64_AR_BSP:
-         /* Libunwind expects to see the beginning of the current register
-            frame so we must account for the fact that ptrace() will return a value
-            for bsp that points *after* the current register frame.  */
-         frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
-         bsp = extract_unsigned_integer (buf, 8);
-         frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
-         cfm = extract_unsigned_integer (buf, 8); 
-         sof = (cfm & 0x7f);
-         *val = ia64_rse_skip_regs (bsp, -sof);
-         break;
-         
-       case UNW_IA64_AR_BSPSTORE:
-         /* Libunwind wants bspstore to be after the current register frame.
-            This is what ptrace() and gdb treats as the regular bsp value.  */
-         frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
-         *val = extract_unsigned_integer (buf, 8);
-         break;
+      case UNW_IA64_AR_BSPSTORE:
+       /* Libunwind wants bspstore to be after the current register frame.
+          This is what ptrace() and gdb treats as the regular bsp value.  */
+       frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
+       *val = extract_unsigned_integer (buf, 8);
+       break;
 
-       default:
-         /* For all other registers, just unwind the value directly.  */
-         frame_unwind_register (next_frame, regnum, buf);
-         *val = extract_unsigned_integer (buf, 8); 
-         break;
-       }
-      
-      if (gdbarch_debug >= 1)
-       fprintf_unfiltered (gdb_stdlog, 
-                           "  access_reg: from cache: %4s=0x%s\n",
-                           (((unsigned) regnum <= IA64_NAT127_REGNUM)
-                            ? ia64_register_names[regnum] : "r??"), 
-                           paddr_nz (*val));
+      default:
+       /* For all other registers, just unwind the value directly.  */
+       frame_unwind_register (next_frame, regnum, buf);
+       *val = extract_unsigned_integer (buf, 8); 
+       break;
     }
+      
+  if (gdbarch_debug >= 1)
+    fprintf_unfiltered (gdb_stdlog, 
+                       "  access_reg: from cache: %4s=0x%s\n",
+                       (((unsigned) regnum <= IA64_NAT127_REGNUM)
+                       ? ia64_register_names[regnum] : "r??"), 
+                       paddr_nz (*val));
   return 0;
 }
 
@@ -2324,11 +2274,13 @@ ia64_access_fpreg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_fpreg_t *val
                   int write, void *arg)
 {
   int regnum = ia64_uw2gdb_regnum (uw_regnum);
+  struct frame_info *next_frame = arg;
   
-  if (write)
-    regcache_cooked_write (current_regcache, regnum, (char *) val);
-  else
-    regcache_cooked_read (current_regcache, regnum, (char *) val);
+  /* We never call any libunwind routines that need to write registers.  */
+  gdb_assert (!write);
+
+  frame_unwind_register (next_frame, regnum, (char *) val);
+
   return 0;
 }
 
@@ -2339,94 +2291,49 @@ ia64_access_rse_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *va
 {
   int regnum = ia64_uw2gdb_regnum (uw_regnum);
   unw_word_t bsp, sof, sol, cfm, psr, ip;
+  struct regcache *regcache = arg;
   long new_sof, old_sof;
+  char buf[MAX_REGISTER_SIZE];
   
-  if (write)
-    {
-      if (regnum < 0)
-       /* ignore writes to pseudo-registers such as UNW_IA64_PROC_STARTI.  */
-       return 0;
-  
-      switch (uw_regnum)
-       {
-       case UNW_REG_IP:
-         ia64_write_pc (*val, inferior_ptid);
-         break;
-
-       case UNW_IA64_AR_BSPSTORE:
-         write_register (IA64_BSP_REGNUM, *val);
-         break;
-         
-       case UNW_IA64_AR_BSP:
-       case UNW_IA64_BSP:
-         /* Account for the fact that ptrace() expects bsp to point
-            after the current register frame.  */
-         cfm = read_register (IA64_CFM_REGNUM);
-         sof = (cfm & 0x7f);
-         bsp = ia64_rse_skip_regs (*val, sof);
-         write_register (IA64_BSP_REGNUM, bsp);
-         break;
-         
-       case UNW_IA64_CFM:
-         /* If we change CFM, we need to adjust ptrace's notion of
-            bsp accordingly, so that the real bsp remains
-            unchanged.  */
-         bsp = read_register (IA64_BSP_REGNUM);
-         cfm = read_register (IA64_CFM_REGNUM);
-         old_sof = (cfm & 0x7f);
-         new_sof = (*val & 0x7f);
-         if (old_sof != new_sof)
-           {
-             bsp = ia64_rse_skip_regs (bsp, -old_sof + new_sof);
-             write_register (IA64_BSP_REGNUM, bsp);
-           }
-         write_register (IA64_CFM_REGNUM, *val);
-         break;
-         
-       default:
-         write_register (regnum, *val);
-         break;
-       }
-      if (gdbarch_debug >= 1)
-       fprintf_unfiltered (gdb_stdlog, 
-                           "  access_rse_reg: to cache: %4s=0x%s\n",
-                           (((unsigned) regnum <= IA64_NAT127_REGNUM)
-                            ? ia64_register_names[regnum] : "r??"), 
-                           paddr_nz (*val));
-    }
-  else
-    {
-      switch (uw_regnum)
-       {
-       case UNW_REG_IP:
-         /* Libunwind expects to see the pc value which means the slot number
-            from the psr must be merged with the ip word address.  */
-         ip = read_register (IA64_IP_REGNUM); 
-         psr = read_register (IA64_PSR_REGNUM);
-         *val = ip | ((psr >> 41) & 0x3);
-         break;
+  /* We never call any libunwind routines that need to write registers.  */
+  gdb_assert (!write);
+
+  switch (uw_regnum)
+    {
+      case UNW_REG_IP:
+       /* Libunwind expects to see the pc value which means the slot number
+          from the psr must be merged with the ip word address.  */
+       regcache_cooked_read (regcache, IA64_IP_REGNUM, buf);
+       ip = extract_unsigned_integer (buf, 8); 
+       regcache_cooked_read (regcache, IA64_PSR_REGNUM, buf);
+       psr = extract_unsigned_integer (buf, 8); 
+       *val = ip | ((psr >> 41) & 0x3);
+       break;
          
-       case UNW_IA64_AR_BSP:
-         /* Libunwind expects to see the beginning of the current register
-            frame so we must account for the fact that ptrace() will return a value
-            for bsp that points *after* the current register frame.  */
-         bsp = read_register (IA64_BSP_REGNUM);
-         cfm = read_register (IA64_CFM_REGNUM);
-         sof = (cfm & 0x7f);
-         *val = ia64_rse_skip_regs (bsp, -sof);
-         break;
+      case UNW_IA64_AR_BSP:
+       /* Libunwind expects to see the beginning of the current register
+          frame so we must account for the fact that ptrace() will return a value
+          for bsp that points *after* the current register frame.  */
+       regcache_cooked_read (regcache, IA64_BSP_REGNUM, buf);
+       bsp = extract_unsigned_integer (buf, 8);
+       regcache_cooked_read (regcache, IA64_CFM_REGNUM, buf);
+       cfm = extract_unsigned_integer (buf, 8); 
+       sof = (cfm & 0x7f);
+       *val = ia64_rse_skip_regs (bsp, -sof);
+       break;
          
-       case UNW_IA64_AR_BSPSTORE:
-         /* Libunwind wants bspstore to be after the current register frame.
-            This is what ptrace() and gdb treats as the regular bsp value.  */
-         *val = read_register (IA64_BSP_REGNUM);
-         break;
+      case UNW_IA64_AR_BSPSTORE:
+       /* Libunwind wants bspstore to be after the current register frame.
+          This is what ptrace() and gdb treats as the regular bsp value.  */
+       regcache_cooked_read (regcache, IA64_BSP_REGNUM, buf);
+       *val = extract_unsigned_integer (buf, 8);
+       break;
 
-       default:
-         /* For all other registers, just read the value directly.  */
-         *val = read_register (regnum);
-         break;
-       }
+      default:
+        /* For all other registers, just unwind the value directly.  */
+       regcache_cooked_read (regcache, regnum, buf);
+       *val = extract_unsigned_integer (buf, 8); 
+       break;
     }
       
   if (gdbarch_debug >= 1)
@@ -2439,6 +2346,22 @@ ia64_access_rse_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *va
   return 0;
 }
 
+/* Libunwind callback accessor function for top-level fp registers.  */
+static int
+ia64_access_rse_fpreg (unw_addr_space_t as, unw_regnum_t uw_regnum,
+                      unw_fpreg_t *val, int write, void *arg)
+{
+  int regnum = ia64_uw2gdb_regnum (uw_regnum);
+  struct regcache *regcache = arg;
+  
+  /* We never call any libunwind routines that need to write registers.  */
+  gdb_assert (!write);
+
+  regcache_cooked_read (regcache, regnum, (char *) val);
+
+  return 0;
+}
+
 /* Libunwind callback accessor function for accessing memory.  */
 static int
 ia64_access_mem (unw_addr_space_t as,
@@ -2855,7 +2778,11 @@ static const struct frame_unwind ia64_libunwind_frame_unwind =
 {
   NORMAL_FRAME,
   ia64_libunwind_frame_this_id,
-  ia64_libunwind_frame_prev_register
+  ia64_libunwind_frame_prev_register,
+  NULL,
+  NULL,
+  NULL,
+  libunwind_frame_dealloc_cache
 };
 
 static const struct frame_unwind *
@@ -2973,7 +2900,7 @@ static unw_accessors_t ia64_unw_rse_accessors =
   ia64_get_dyn_info_list,
   ia64_access_mem,
   ia64_access_rse_reg,
-  ia64_access_fpreg,
+  ia64_access_rse_fpreg,
   /* resume */
   /* get_proc_name */
 };
@@ -3537,22 +3464,12 @@ ia64_store_return_value (struct type *type, struct regcache *regcache,
       char to[MAX_REGISTER_SIZE];
       convert_typed_floating (valbuf, type, to, builtin_type_ia64_ext);
       regcache_cooked_write (regcache, IA64_FR8_REGNUM, (void *)to);
-      target_store_registers (IA64_FR8_REGNUM);
+      target_store_registers (regcache, IA64_FR8_REGNUM);
     }
   else
     regcache_cooked_write (regcache, IA64_GR8_REGNUM, valbuf);
 }
 
-static void
-ia64_remote_translate_xfer_address (struct gdbarch *gdbarch,
-                                   struct regcache *regcache,
-                                   CORE_ADDR memaddr, int nr_bytes,
-                                   CORE_ADDR *targ_addr, int *targ_len)
-{
-  *targ_addr = memaddr;
-  *targ_len  = nr_bytes;
-}
-
 static int
 ia64_print_insn (bfd_vma memaddr, struct disassemble_info *info)
 {
@@ -3575,6 +3492,7 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   gdbarch = gdbarch_alloc (&info, tdep);
 
   tdep->sigcontext_register_address = 0;
+  tdep->pc_in_sigtramp = 0;
 
   /* Define the ia64 floating-point format to gdb.  */
   builtin_type_ia64_ext =
@@ -3653,9 +3571,6 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Settings that should be unnecessary.  */
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
 
-  set_gdbarch_remote_translate_xfer_address (
-    gdbarch, ia64_remote_translate_xfer_address);
-
   set_gdbarch_print_insn (gdbarch, ia64_print_insn);
   set_gdbarch_convert_from_func_ptr_addr (gdbarch, ia64_convert_from_func_ptr_addr);
 
This page took 0.027684 seconds and 4 git commands to generate.