* avr-tdep.c: Include frame.h, frame-unwind.h, frame-base.h, and
[deliverable/binutils-gdb.git] / gdb / frame.c
index b881a74d3453c1d38fe2cae10ef798334eb96b86..55e9dc580b535d4454299ae39d8974e8534bb969 100644 (file)
@@ -376,7 +376,7 @@ frame_pc_unwind (struct frame_info *this_frame)
             implementation is no more than:
           
             frame_unwind_register (this_frame, ISA_PC_REGNUM, buf);
-            return extract_address (buf, size of ISA_PC_REGNUM);
+            return extract_unsigned_integer (buf, size of ISA_PC_REGNUM);
 
             Note: this method is very heavily dependent on a correct
             register-unwind implementation, it pays to fix that
@@ -618,7 +618,7 @@ void
 frame_unwind_signed_register (struct frame_info *frame, int regnum,
                              LONGEST *val)
 {
-  void *buf = alloca (MAX_REGISTER_RAW_SIZE);
+  char buf[MAX_REGISTER_SIZE];
   frame_unwind_register (frame, regnum, buf);
   (*val) = extract_signed_integer (buf, REGISTER_VIRTUAL_SIZE (regnum));
 }
@@ -627,7 +627,7 @@ void
 frame_unwind_unsigned_register (struct frame_info *frame, int regnum,
                                ULONGEST *val)
 {
-  void *buf = alloca (MAX_REGISTER_RAW_SIZE);
+  char buf[MAX_REGISTER_SIZE];
   frame_unwind_register (frame, regnum, buf);
   (*val) = extract_unsigned_integer (buf, REGISTER_VIRTUAL_SIZE (regnum));
 }
@@ -674,12 +674,42 @@ frame_read_signed_register (struct frame_info *frame, int regnum,
 }
 
 void
-generic_unwind_get_saved_register (char *raw_buffer,
-                                  int *optimizedp,
-                                  CORE_ADDR *addrp,
-                                  struct frame_info *frame,
-                                  int regnum,
-                                  enum lval_type *lvalp)
+put_frame_register (struct frame_info *frame, int regnum, const void *buf)
+{
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  int realnum;
+  int optim;
+  enum lval_type lval;
+  CORE_ADDR addr;
+  frame_register (frame, regnum, &optim, &lval, &addr, &realnum, NULL);
+  if (optim)
+    error ("Attempt to assign to a value that was optimized out.");
+  switch (lval)
+    {
+    case lval_memory:
+      {
+       /* FIXME: write_memory doesn't yet take constant buffers.
+           Arrrg!  */
+       char tmp[MAX_REGISTER_SIZE];
+       memcpy (tmp, buf, register_size (gdbarch, regnum));
+       write_memory (addr, tmp, register_size (gdbarch, regnum));
+       break;
+      }
+    case lval_register:
+      regcache_cooked_write (current_regcache, realnum, buf);
+      break;
+    default:
+      error ("Attempt to assign to an unmodifiable value.");
+    }
+}
+
+void
+deprecated_unwind_get_saved_register (char *raw_buffer,
+                                     int *optimizedp,
+                                     CORE_ADDR *addrp,
+                                     struct frame_info *frame,
+                                     int regnum,
+                                     enum lval_type *lvalp)
 {
   int optimizedx;
   CORE_ADDR addrx;
@@ -778,7 +808,7 @@ frame_map_regnum_to_name (int regnum)
 
 /* Create a sentinel frame.  */
 
-struct frame_info *
+static struct frame_info *
 create_sentinel_frame (struct regcache *regcache)
 {
   struct frame_info *frame = FRAME_OBSTACK_ZALLOC (struct frame_info);
@@ -963,14 +993,13 @@ legacy_saved_regs_prev_register (struct frame_info *next_frame,
   struct frame_info *frame = next_frame->prev;
   gdb_assert (frame != NULL);
 
-  /* Only (older) architectures that implement the
-     DEPRECATED_FRAME_INIT_SAVED_REGS method should be using this
-     function.  */
-  gdb_assert (DEPRECATED_FRAME_INIT_SAVED_REGS_P ());
-
-  /* Load the saved_regs register cache.  */
   if (get_frame_saved_regs (frame) == NULL)
-    DEPRECATED_FRAME_INIT_SAVED_REGS (frame);
+    {
+      /* If nothing's initialized the saved regs, do it now.  */
+      gdb_assert (DEPRECATED_FRAME_INIT_SAVED_REGS_P ());
+      DEPRECATED_FRAME_INIT_SAVED_REGS (frame);
+      gdb_assert (get_frame_saved_regs (frame) != NULL);
+    }
 
   if (get_frame_saved_regs (frame) != NULL
       && get_frame_saved_regs (frame)[regnum] != 0)
@@ -983,8 +1012,10 @@ legacy_saved_regs_prev_register (struct frame_info *next_frame,
          *addrp = 0;
          *realnump = -1;
          if (bufferp != NULL)
-           store_address (bufferp, REGISTER_RAW_SIZE (regnum),
-                          get_frame_saved_regs (frame)[regnum]);
+           /* NOTE: cagney/2003-05-09: In-lined store_address with
+               it's body - store_unsigned_integer.  */
+           store_unsigned_integer (bufferp, REGISTER_RAW_SIZE (regnum),
+                                   get_frame_saved_regs (frame)[regnum]);
        }
       else
        {
@@ -1080,8 +1111,6 @@ deprecated_generic_get_saved_register (char *raw_buffer, int *optimized,
   if (!target_has_registers)
     error ("No registers.");
 
-  gdb_assert (DEPRECATED_FRAME_INIT_SAVED_REGS_P ());
-
   /* Normal systems don't optimize out things with register numbers.  */
   if (optimized != NULL)
     *optimized = 0;
@@ -1110,8 +1139,8 @@ deprecated_generic_get_saved_register (char *raw_buffer, int *optimized,
                   fly, constructs either a raw or pseudo register
                   from the raw register cache.  */
                regcache_raw_read
-                 (generic_find_dummy_frame (get_frame_pc (frame),
-                                            get_frame_base (frame)),
+                 (deprecated_find_dummy_frame_regcache (get_frame_pc (frame),
+                                                        get_frame_base (frame)),
                   regnum, raw_buffer);
              return;
            }
@@ -1125,8 +1154,11 @@ deprecated_generic_get_saved_register (char *raw_buffer, int *optimized,
              if (regnum == SP_REGNUM)
                {
                  if (raw_buffer)       /* SP register treated specially */
-                   store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
-                                  get_frame_saved_regs (frame)[regnum]);
+                   /* NOTE: cagney/2003-05-09: In-line store_address
+                       with it's body - store_unsigned_integer.  */
+                   store_unsigned_integer (raw_buffer,
+                                           REGISTER_RAW_SIZE (regnum),
+                                           get_frame_saved_regs (frame)[regnum]);
                }
              else
                {
@@ -1232,6 +1264,12 @@ get_next_frame (struct frame_info *this_frame)
     return NULL;
 }
 
+struct frame_info *
+deprecated_get_next_frame_hack (struct frame_info *this_frame)
+{
+  return this_frame->next;
+}
+
 /* Flush the entire frame cache.  */
 
 void
@@ -1368,10 +1406,6 @@ legacy_get_prev_frame (struct frame_info *this_frame)
             or some random address on the stack.  Trying to use that
             PC to apply standard frame ID unwind techniques is just
             asking for trouble.  */
-         /* Assume call_function_by_hand(), via SAVE_DUMMY_FRAME_TOS,
-            previously saved the dummy frame's ID.  Things only work
-            if the two return the same value.  */
-         gdb_assert (SAVE_DUMMY_FRAME_TOS_P ());
          /* Use an architecture specific method to extract the prev's
             dummy ID from the next frame.  Note that this method uses
             frame_register_unwind to obtain the register values
@@ -1470,6 +1504,12 @@ legacy_get_prev_frame (struct frame_info *this_frame)
     /* FIXME: 2002-11-09: There isn't any reason to special case this
        edge condition.  Instead the per-architecture code should hande
        it locally.  */
+    /* FIXME: cagney/2003-06-16: This returns the inner most stack
+       address for the previous frame, that, however, is wrong.  It
+       should be the inner most stack address for the previous to
+       previous frame.  This is because it is the previous to previous
+       frame's innermost stack address that is constant through out
+       the lifetime of the previous frame (trust me :-).  */
     address = get_frame_base (this_frame);
   else
     {
@@ -1488,8 +1528,29 @@ legacy_get_prev_frame (struct frame_info *this_frame)
          this to after the ffi test; I'd rather have backtraces from
          start go curfluy than have an abort called from main not show
          main.  */
-      gdb_assert (DEPRECATED_FRAME_CHAIN_P ());
-      address = DEPRECATED_FRAME_CHAIN (this_frame);
+      if (DEPRECATED_FRAME_CHAIN_P ())
+       address = DEPRECATED_FRAME_CHAIN (this_frame);
+      else
+       {
+         /* Someone is part way through coverting an old architecture
+             to the new frame code.  Implement FRAME_CHAIN the way the
+             new frame will.  */
+         /* Find PREV frame's unwinder.  */
+         prev->unwind = frame_unwind_find_by_pc (current_gdbarch,
+                                                 frame_pc_unwind (this_frame));
+         /* FIXME: cagney/2003-04-02: Rather than storing the frame's
+            type in the frame, the unwinder's type should be returned
+            directly.  Unfortunatly, legacy code, called by
+            legacy_get_prev_frame, explicitly set the frames type
+            using the method deprecated_set_frame_type().  */
+         prev->type = prev->unwind->type;
+         /* Find PREV frame's ID.  */
+         prev->unwind->this_id (this_frame,
+                                &prev->prologue_cache,
+                                &prev->this_id.value);
+         prev->this_id.p = 1;
+         address = prev->this_id.value.stack_addr;
+       }
 
       if (!legacy_frame_chain_valid (address, this_frame))
        {
@@ -1632,9 +1693,13 @@ legacy_get_prev_frame (struct frame_info *this_frame)
   /* Initialize the code used to unwind the frame PREV based on the PC
      (and probably other architectural information).  The PC lets you
      check things like the debug info at that point (dwarf2cfi?) and
-     use that to decide how the frame should be unwound.  */
-  prev->unwind = frame_unwind_find_by_pc (current_gdbarch,
-                                         get_frame_pc (prev));
+     use that to decide how the frame should be unwound.
+
+     If there isn't a FRAME_CHAIN, the code above will have already
+     done this.  */
+  if (prev->unwind == NULL)
+    prev->unwind = frame_unwind_find_by_pc (current_gdbarch,
+                                           get_frame_pc (prev));
 
   /* If the unwinder provides a frame type, use it.  Otherwize
      continue on to that heuristic mess.  */
@@ -1642,6 +1707,7 @@ legacy_get_prev_frame (struct frame_info *this_frame)
     {
       prev->type = prev->unwind->type;
       if (prev->type == NORMAL_FRAME)
+       /* FIXME: cagney/2003-06-16: would get_frame_pc() be better?  */
        prev->this_id.value.code_addr
          = get_pc_function_start (prev->this_id.value.code_addr);
       if (frame_debug)
@@ -1939,11 +2005,11 @@ get_prev_frame (struct frame_info *this_frame)
      Doing this makes it possible for the user to examine a frame that
      has an invalid frame ID.
 
-     The very old VAX frame_args_address_correct() method noted: [...]
-     For the sake of argument, suppose that the stack is somewhat
-     trashed (which is one reason that "info frame" exists).  So,
-     return 0 (indicating we don't know the address of the arglist) if
-     we don't know what frame this frame calls.  */
+     Some very old VAX code noted: [...]  For the sake of argument,
+     suppose that the stack is somewhat trashed (which is one reason
+     that "info frame" exists).  So, return 0 (indicating we don't
+     know the address of the arglist) if we don't know what frame this
+     frame calls.  */
 
   /* Link it in.  */
   this_frame->prev = prev_frame;
@@ -2069,7 +2135,12 @@ get_frame_type (struct frame_info *frame)
   if (!DEPRECATED_USE_GENERIC_DUMMY_FRAMES
       && deprecated_frame_in_dummy (frame))
     return DUMMY_FRAME;
-  if (frame->unwind == NULL)
+
+  /* Some legacy code, e.g, mips_init_extra_frame_info() wants
+     to determine the frame's type prior to it being completely
+     initialized.  Don't attempt to lazily initialize ->unwind for
+     legacy code.  It will be initialized in legacy_get_prev_frame().  */
+  if (frame->unwind == NULL && !legacy_frame_p (current_gdbarch))
     {
       /* Initialize the frame's unwinder because it is that which
          provides the frame's type.  */
@@ -2209,6 +2280,68 @@ deprecated_frame_xmalloc_with_cleanup (long sizeof_saved_regs,
   return frame;
 }
 
+/* Memory access methods.  */
+
+void
+get_frame_memory (struct frame_info *this_frame, CORE_ADDR addr, void *buf,
+                 int len)
+{
+  read_memory (addr, buf, len);
+}
+
+LONGEST
+get_frame_memory_signed (struct frame_info *this_frame, CORE_ADDR addr,
+                        int len)
+{
+  return read_memory_integer (addr, len);
+}
+
+ULONGEST
+get_frame_memory_unsigned (struct frame_info *this_frame, CORE_ADDR addr,
+                          int len)
+{
+  return read_memory_unsigned_integer (addr, len);
+}
+
+/* Architecture method.  */
+
+struct gdbarch *
+get_frame_arch (struct frame_info *this_frame)
+{
+  return current_gdbarch;
+}
+
+/* Stack pointer methods.  */
+
+CORE_ADDR
+get_frame_sp (struct frame_info *this_frame)
+{
+  return frame_sp_unwind (this_frame->next);
+}
+
+CORE_ADDR
+frame_sp_unwind (struct frame_info *next_frame)
+{
+  /* Normality, an architecture that provides a way of obtaining any
+     frame inner-most address.  */
+  if (gdbarch_unwind_sp_p (current_gdbarch))
+    return gdbarch_unwind_sp (current_gdbarch, next_frame);
+  /* Things are looking grim.  If it's the inner-most frame and there
+     is a TARGET_READ_SP then that can be used.  */
+  if (next_frame->level < 0 && TARGET_READ_SP_P ())
+    return TARGET_READ_SP ();
+  /* Now things are really are grim.  Hope that the value returned by
+     the SP_REGNUM register is meaningful.  */
+  if (SP_REGNUM >= 0)
+    {
+      ULONGEST sp;
+      frame_unwind_unsigned_register (next_frame, SP_REGNUM, &sp);
+      return sp;
+    }
+  internal_error (__FILE__, __LINE__, "Missing unwind SP method");
+}
+
+
 int
 legacy_frame_p (struct gdbarch *current_gdbarch)
 {
@@ -2216,10 +2349,11 @@ legacy_frame_p (struct gdbarch *current_gdbarch)
          || DEPRECATED_INIT_FRAME_PC_FIRST_P ()
          || DEPRECATED_INIT_EXTRA_FRAME_INFO_P ()
          || DEPRECATED_FRAME_CHAIN_P ()
-         || !gdbarch_unwind_dummy_id_p (current_gdbarch)
-         || !SAVE_DUMMY_FRAME_TOS_P ());
+         || !gdbarch_unwind_dummy_id_p (current_gdbarch));
 }
 
+extern initialize_file_ftype _initialize_frame; /* -Wmissing-prototypes */
+
 void
 _initialize_frame (void)
 {
This page took 0.038873 seconds and 4 git commands to generate.