2003-10-23 Jeff Johnston <jjohnstn@redhat.com>
authorJeff Johnston <jjohnstn@redhat.com>
Thu, 23 Oct 2003 22:06:37 +0000 (22:06 +0000)
committerJeff Johnston <jjohnstn@redhat.com>
Thu, 23 Oct 2003 22:06:37 +0000 (22:06 +0000)
        * ia64-tdep.c: (ia64_frame_cache): Add new prev_cfm field.
        (pseudo_regs): Add comment regarding register stack registers.
        (ia64_alloc_frame_cache):  Initialize new prev_cfm field to 0.
        (floatformat_valid): New static routine.
        (floatformat_ia64_ext): Add name field and set up is_valid routine
        to floatformat_valid().
        (examine_prologue):  For the previous cfm, use
        frame_unwind_register()
        if the cfm is not stored in a register-stack register.  Save the
        previous cfm value in the prev_cfm field.  Add debug output.
        (ia64_frame_this_id): Use frame_id_build_special() to also register
        the bsp.  Add debug output.
        (ia64_sigtramp_frame_this_id): Ditto.
        (ia64_frame_prev_register):  Look at cache saved_regs for a few more
        registers and also add some checks for framelessness before accepting
        current register values for fields such as return address.  For cfm,
        use the cached prev_cfm field if available.  Add comment to explain
        PSR logic.  Add debug output.
        (ia64_sigtramp_frame_init_saved_regs): Save the bsp and sp addresses
        as part of initialization.
        (ia64_sigtramp_frame_cache): Hard-code stack size as it can't be
        calculated.  Cache the bsp and cfm values.
        (ia64_sigtramp_frame_prev_register): Add logic to this routine out
        instead of using ia64_frame_prev_register() which doesn't expect most
        registers to be saved.  The saved values for bsp and sp
        can be taken from the cache.  Add debug output.
        (ia64_push_dummy_call): Use frame_id_build_special() to also register
        the bsp.

gdb/ChangeLog
gdb/ia64-tdep.c

index 0c29461ef0aad29e73bf8232b05423c331ba5636..1ea1b4fb8d05aacddc8ffd35dbfd1be903609a40 100644 (file)
@@ -1,3 +1,34 @@
+2003-10-23  Jeff Johnston  <jjohnstn@redhat.com>
+
+       * ia64-tdep.c: (ia64_frame_cache): Add new prev_cfm field.
+       (pseudo_regs): Add comment regarding register stack registers.
+       (ia64_alloc_frame_cache):  Initialize new prev_cfm field to 0.
+       (floatformat_valid): New static routine.
+       (floatformat_ia64_ext): Add name field and set up is_valid routine
+       to floatformat_valid().
+       (examine_prologue):  For the previous cfm, use
+       frame_unwind_register()
+       if the cfm is not stored in a register-stack register.  Save the
+       previous cfm value in the prev_cfm field.  Add debug output.
+       (ia64_frame_this_id): Use frame_id_build_special() to also register
+       the bsp.  Add debug output.
+       (ia64_sigtramp_frame_this_id): Ditto.
+       (ia64_frame_prev_register):  Look at cache saved_regs for a few more
+       registers and also add some checks for framelessness before accepting
+       current register values for fields such as return address.  For cfm,
+       use the cached prev_cfm field if available.  Add comment to explain
+       PSR logic.  Add debug output.
+       (ia64_sigtramp_frame_init_saved_regs): Save the bsp and sp addresses
+       as part of initialization.
+       (ia64_sigtramp_frame_cache): Hard-code stack size as it can't be
+       calculated.  Cache the bsp and cfm values.
+       (ia64_sigtramp_frame_prev_register): Add logic to this routine out
+       instead of using ia64_frame_prev_register() which doesn't expect most
+       registers to be saved.  The saved values for bsp and sp
+       can be taken from the cache.  Add debug output.
+       (ia64_push_dummy_call): Use frame_id_build_special() to also register
+       the bsp.
+
 2003-10-23  Jim Blandy  <jimb@redhat.com>
 
        * osabi.c (gdbarch_init_osabi): A handler is okay if it's for an
index 703493feb552f11660928c92d04f06e110dc51b3..7f973b98bb9a75b8bb2b28d7c56eb6391eee2a37 100644 (file)
@@ -108,7 +108,7 @@ static int fp_regnum = IA64_VFP_REGNUM;
 static int lr_regnum = IA64_VRAP_REGNUM;
 
 /* NOTE: we treat the register stack registers r32-r127 as pseudo-registers because
-   they are in memory and must be calculated via the bsp register.  */
+   they may not be accessible via the ptrace register get/set interfaces.  */
 enum pseudo_regs { FIRST_PSEUDO_REGNUM = NUM_IA64_RAW_REGS, VBOF_REGNUM = IA64_NAT127_REGNUM + 1, V32_REGNUM, 
                   V127_REGNUM = V32_REGNUM + 95, 
                   VP0_REGNUM, VP16_REGNUM = VP0_REGNUM + 16, VP63_REGNUM = VP0_REGNUM + 63, LAST_PSEUDO_REGNUM };
@@ -232,6 +232,7 @@ struct ia64_frame_cache
   CORE_ADDR saved_sp;  /* stack pointer for frame */
   CORE_ADDR bsp;       /* points at r32 for the current frame */
   CORE_ADDR cfm;       /* cfm value for current frame */
+  CORE_ADDR prev_cfm;   /* cfm value for previous frame */
   int   frameless;
   int   sof;           /* Size of frame  (decoded from cfm value) */
   int  sol;            /* Size of locals (decoded from cfm value) */
@@ -316,10 +317,18 @@ ia64_dwarf_reg_to_regnum (int reg)
   return reg;
 }
 
+static int
+floatformat_valid (fmt, from)
+     const struct floatformat *fmt;
+     const char *from;
+{
+  return 1;
+}
+
 const struct floatformat floatformat_ia64_ext =
 {
   floatformat_little, 82, 0, 1, 17, 65535, 0x1ffff, 18, 64,
-  floatformat_intbit_yes
+  floatformat_intbit_yes, "floatformat_ia64_ext", floatformat_valid
 };
 
 
@@ -1030,6 +1039,7 @@ ia64_alloc_frame_cache (void)
   cache->base = 0;
   cache->pc = 0;
   cache->cfm = 0;
+  cache->prev_cfm = 0;
   cache->sof = 0;
   cache->sol = 0;
   cache->sor = 0;
@@ -1450,9 +1460,20 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
 
       /* For the previous argument registers we require the previous bof.  
         If we can't find the previous cfm, then we can do nothing.  */
+      cfm = 0;
       if (cache->saved_regs[IA64_CFM_REGNUM] != 0)
        {
          cfm = read_memory_integer (cache->saved_regs[IA64_CFM_REGNUM], 8);
+       }
+      else if (cfm_reg != 0)
+       {
+         frame_unwind_register (next_frame, cfm_reg, buf);
+         cfm = extract_unsigned_integer (buf, 8);
+       }
+      cache->prev_cfm = cfm;
+      
+      if (cfm != 0)
+       {
          sor = ((cfm >> 14) & 0xf) * 8;
          sof = (cfm & 0x7f);
          sol = (cfm >> 7) & 0x7f;
@@ -1564,7 +1585,11 @@ ia64_frame_this_id (struct frame_info *next_frame, void **this_cache,
   if (cache->base == 0)
     return;
 
-  (*this_id) = frame_id_build (cache->base, cache->pc);
+  (*this_id) = frame_id_build_special (cache->base, cache->pc, cache->bsp);
+  if (gdbarch_debug >= 1)
+    fprintf_unfiltered (gdb_stdlog,
+                       "regular frame id: code %lx, stack %lx, special %lx, next_frame %p\n",
+                       this_id->code_addr, this_id->stack_addr, cache->bsp, next_frame);
 }
 
 static void
@@ -1628,18 +1653,20 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
     }
   else if (regnum == IA64_CFM_REGNUM)
     {
-      CORE_ADDR addr = 0;
-
-      if (cache->frameless)
+      CORE_ADDR addr = cache->saved_regs[IA64_CFM_REGNUM];
+      
+      if (addr != 0)
        {
-         CORE_ADDR cfm = 0;
-         frame_unwind_register (next_frame, IA64_PFS_REGNUM, valuep);
+         *lvalp = lval_memory;
+         *addrp = addr;
+         read_memory (addr, valuep, register_size (current_gdbarch, regnum));
        }
-      else
+      else if (cache->prev_cfm)
+       store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), cache->prev_cfm);
+      else if (cache->frameless)
        {
-         addr = cache->saved_regs[IA64_CFM_REGNUM];
-         if (addr != 0)
-           read_memory (addr, valuep, register_size (current_gdbarch, regnum));
+         CORE_ADDR cfm = 0;
+         frame_unwind_register (next_frame, IA64_PFS_REGNUM, valuep);
        }
     }
   else if (regnum == IA64_VFP_REGNUM)
@@ -1727,53 +1754,68 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
   else if (regnum == IA64_IP_REGNUM)
     {
       CORE_ADDR pc = 0;
+      CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
 
-      if (cache->frameless)
+      if (addr != 0)
        {
-         frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf);
+         *lvalp = lval_memory;
+         *addrp = addr;
+         read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
          pc = extract_unsigned_integer (buf, 8);
        }
-      else
+      else if (cache->frameless)
        {
-         CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
-         if (addr != 0)
-           {
-             read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
-             pc = extract_unsigned_integer (buf, 8);
-           }
+         frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf);
+         pc = extract_unsigned_integer (buf, 8);
        }
       pc &= ~0xf;
       store_unsigned_integer (valuep, 8, pc);
     }
   else if (regnum == IA64_PSR_REGNUM)
     {
+      /* We don't know how to get the complete previous PSR, but we need it for
+        the slot information when we unwind the pc (pc is formed of IP register
+        plus slot information from PSR).  To get the previous slot information, 
+        we mask it off the return address.  */
       ULONGEST slot_num = 0;
       CORE_ADDR pc= 0;
       CORE_ADDR psr = 0;
+      CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
 
       frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
       psr = extract_unsigned_integer (buf, 8);
 
-      if (cache->frameless)
+      if (addr != 0)
        {
-         CORE_ADDR pc;
-         frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf);
+         *lvalp = lval_memory;
+         *addrp = addr;
+         read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
          pc = extract_unsigned_integer (buf, 8);
        }
-      else
+      else if (cache->frameless)
        {
-         CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
-         if (addr != 0)
-           {
-             read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
-             pc = extract_unsigned_integer (buf, 8);
-           }
+         CORE_ADDR pc;
+         frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf);
+         pc = extract_unsigned_integer (buf, 8);
        }
       psr &= ~(3LL << 41);
       slot_num = pc & 0x3LL;
       psr |= (CORE_ADDR)slot_num << 41;
       store_unsigned_integer (valuep, 8, psr);
     }
+  else if (regnum == IA64_BR0_REGNUM)
+    {
+      CORE_ADDR br0 = 0;
+      CORE_ADDR addr = cache->saved_regs[IA64_BR0_REGNUM];
+      if (addr != 0)
+       {
+         *lvalp = lval_memory;
+         *addrp = addr;
+         read_memory (addr, buf, register_size (current_gdbarch, IA64_BR0_REGNUM));
+         br0 = extract_unsigned_integer (buf, 8);
+       }
+      store_unsigned_integer (valuep, 8, br0);
+    }
  else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM) ||
           (regnum >= V32_REGNUM && regnum <= V127_REGNUM))
     {
@@ -1839,6 +1881,12 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
       else 
        frame_unwind_register (next_frame, regnum, valuep);
     }
+
+  if (gdbarch_debug >= 1)
+    fprintf_unfiltered (gdb_stdlog,
+                       "regular prev register <%d> <%s> is %lx\n", regnum, 
+                       (((unsigned) regnum <= IA64_NAT127_REGNUM)
+                        ? ia64_register_names[regnum] : "r??"), extract_unsigned_integer (valuep, 8));
 }
  
 static const struct frame_unwind ia64_frame_unwind =
@@ -1869,10 +1917,8 @@ ia64_sigtramp_frame_init_saved_regs (struct ia64_frame_cache *cache)
        SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_CFM_REGNUM);
       cache->saved_regs[IA64_PSR_REGNUM] = 
        SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_PSR_REGNUM);
-#if 0
       cache->saved_regs[IA64_BSP_REGNUM] = 
-       SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_BSP_REGNUM);
-#endif
+       SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_BSP_REGNUM);
       cache->saved_regs[IA64_RNAT_REGNUM] = 
        SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_RNAT_REGNUM);
       cache->saved_regs[IA64_CCV_REGNUM] = 
@@ -1886,9 +1932,8 @@ ia64_sigtramp_frame_init_saved_regs (struct ia64_frame_cache *cache)
       cache->saved_regs[IA64_LC_REGNUM] = 
        SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_LC_REGNUM);
       for (regno = IA64_GR1_REGNUM; regno <= IA64_GR31_REGNUM; regno++)
-       if (regno != sp_regnum)
-         cache->saved_regs[regno] =
-           SIGCONTEXT_REGISTER_ADDRESS (cache->base, regno);
+       cache->saved_regs[regno] =
+         SIGCONTEXT_REGISTER_ADDRESS (cache->base, regno);
       for (regno = IA64_BR0_REGNUM; regno <= IA64_BR7_REGNUM; regno++)
        cache->saved_regs[regno] =
          SIGCONTEXT_REGISTER_ADDRESS (cache->base, regno);
@@ -1912,7 +1957,16 @@ ia64_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
   cache = ia64_alloc_frame_cache ();
 
   frame_unwind_register (next_frame, sp_regnum, buf);
-  cache->base = extract_unsigned_integer (buf, 8) + cache->mem_stack_frame_size;
+  /* Note that frame size is hard-coded below.  We cannot calculate it
+     via prologue examination.  */
+  cache->base = extract_unsigned_integer (buf, 8) + 16;
+
+  frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
+  cache->bsp = extract_unsigned_integer (buf, 8);
+
+  frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
+  cache->cfm = extract_unsigned_integer (buf, 8);
+  cache->sof = cache->cfm & 0x7f;
 
   ia64_sigtramp_frame_init_saved_regs (cache);
 
@@ -1927,7 +1981,11 @@ ia64_sigtramp_frame_this_id (struct frame_info *next_frame,
   struct ia64_frame_cache *cache =
     ia64_sigtramp_frame_cache (next_frame, this_cache);
 
-  (*this_id) = frame_id_build (cache->base, frame_pc_unwind (next_frame));
+  (*this_id) = frame_id_build_special (cache->base, frame_pc_unwind (next_frame), cache->bsp);
+  if (gdbarch_debug >= 1)
+    fprintf_unfiltered (gdb_stdlog,
+                       "sigtramp frame id: code %lx, stack %lx, special %lx, next_frame %p\n",
+                       this_id->code_addr, this_id->stack_addr, cache->bsp, next_frame);
 }
 
 static void
@@ -1937,11 +1995,75 @@ ia64_sigtramp_frame_prev_register (struct frame_info *next_frame,
                                   enum lval_type *lvalp, CORE_ADDR *addrp,
                                   int *realnump, void *valuep)
 {
-  /* Make sure we've initialized the cache.  */
-  ia64_sigtramp_frame_cache (next_frame, this_cache);
+  char dummy_valp[MAX_REGISTER_SIZE];
+  char buf[MAX_REGISTER_SIZE];
+
+  struct ia64_frame_cache *cache =
+    ia64_sigtramp_frame_cache (next_frame, this_cache);
+
+  gdb_assert (regnum >= 0);
+
+  if (!target_has_registers)
+    error ("No registers.");
+
+  *optimizedp = 0;
+  *addrp = 0;
+  *lvalp = not_lval;
+  *realnump = -1;
+
+  /* Rather than check each time if valuep is non-null, supply a dummy buffer
+     when valuep is not supplied.  */
+  if (!valuep)
+    valuep = dummy_valp;
+  
+  memset (valuep, 0, register_size (current_gdbarch, regnum));
+  if (regnum == IA64_IP_REGNUM)
+    {
+      CORE_ADDR pc = 0;
+      CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
+
+      if (addr != 0)
+       {
+         *lvalp = lval_memory;
+         *addrp = addr;
+         read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
+         pc = extract_unsigned_integer (buf, 8);
+       }
+      pc &= ~0xf;
+      store_unsigned_integer (valuep, 8, pc);
+    }
+ else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM) ||
+          (regnum >= V32_REGNUM && regnum <= V127_REGNUM))
+    {
+      CORE_ADDR addr = 0;
+      if (regnum >= V32_REGNUM)
+       regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
+      addr = cache->saved_regs[regnum];
+      if (addr != 0)
+       {
+         *lvalp = lval_memory;
+         *addrp = addr;
+         read_memory (addr, valuep, register_size (current_gdbarch, regnum));
+       }
+    }
+  else
+    {
+      /* All other registers not listed above.  */
+      CORE_ADDR addr = cache->saved_regs[regnum];
+      if (addr != 0)
+       {
+         *lvalp = lval_memory;
+         *addrp = addr;
+         read_memory (addr, valuep, register_size (current_gdbarch, regnum));
+       }
+    }
 
-  ia64_frame_prev_register (next_frame, this_cache, regnum,
-                           optimizedp, lvalp, addrp, realnump, valuep);
+  if (gdbarch_debug >= 1)
+    fprintf_unfiltered (gdb_stdlog,
+                       "sigtramp prev register <%s> is %lx\n",
+                       (((unsigned) regnum <= IA64_NAT127_REGNUM)
+                        ? ia64_register_names[regnum] : "r??"), extract_unsigned_integer (valuep, 8));
 }
 
 static const struct frame_unwind ia64_sigtramp_frame_unwind =
@@ -2474,12 +2596,20 @@ static struct frame_id
 ia64_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
   char buf[8];
-  CORE_ADDR sp;
+  CORE_ADDR sp, bsp;
 
   frame_unwind_register (next_frame, sp_regnum, buf);
   sp = extract_unsigned_integer (buf, 8);
 
-  return frame_id_build (sp, frame_pc_unwind (next_frame));
+  frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
+  bsp = extract_unsigned_integer (buf, 8);
+
+  if (gdbarch_debug >= 1)
+    fprintf_unfiltered (gdb_stdlog,
+                       "dummy frame id: code %lx, stack %lx, special %lx\n",
+                       frame_pc_unwind (next_frame), sp, bsp);
+
+  return frame_id_build_special (sp, frame_pc_unwind (next_frame), bsp);
 }
 
 static CORE_ADDR