* avr-tdep.c (avr_skip_prologue): Return PC unchanged if no prologue found.
authorTheodore A. Roth <troth@openavr.org>
Wed, 16 Jul 2003 23:20:51 +0000 (23:20 +0000)
committerTheodore A. Roth <troth@openavr.org>
Wed, 16 Jul 2003 23:20:51 +0000 (23:20 +0000)
(avr_frame_unwind_cache): Don't unwind FP for main.
Update a comment.
Save the computed prev_sp.
(avr_saved_regs_unwinder): Remove function.
(avr_frame_prev_register): Use PC unwind logic from
avr_saved_regs_unwinder, otherwise use trad_frame_prev_register.

gdb/ChangeLog
gdb/avr-tdep.c

index 2d74ba23ba52cce85d4a8da3438a670627d83d60..35dab2eb86891f271f3707eb357ff16ec6420c0b 100644 (file)
@@ -1,3 +1,14 @@
+2003-07-16  Theodore A. Roth  <troth@openavr.org>
+
+       * avr-tdep.c (avr_skip_prologue): Return PC unchanged if no prologue
+       found.
+       (avr_frame_unwind_cache): Don't unwind FP for main.
+       Update a comment.
+       Save the computed prev_sp.
+       (avr_saved_regs_unwinder): Remove function.
+       (avr_frame_prev_register): Use PC unwind logic from 
+       avr_saved_regs_unwinder(), otherwise use trad_frame_prev_register().
+
 2003-07-16  Andrew Cagney  <cagney@redhat.com>
 
        * frame-base.h (frame_base_p_ftype): Delete definition.
index 3e3d26446ea604dce3cdd18a874eb8210ae7c5d6..477aa82cb83f7556088c8545181d0c75eaf914bd 100644 (file)
@@ -796,7 +796,9 @@ avr_skip_prologue (CORE_ADDR pc)
 
       prologue_end = avr_scan_prologue (pc, &info);
 
-      if (info.prologue_type != AVR_PROLOGUE_NONE)
+      if (info.prologue_type == AVR_PROLOGUE_NONE)
+        return pc;
+      else
         {
           sal = find_pc_line (func_addr, 0);
 
@@ -856,76 +858,6 @@ avr_extract_return_value (struct type *type, struct regcache *regcache,
     }
 }
 
-static void
-avr_saved_regs_unwinder (struct frame_info *next_frame,
-                         struct trad_frame_saved_reg *this_saved_regs,
-                         int regnum, int *optimizedp,
-                         enum lval_type *lvalp, CORE_ADDR *addrp,
-                         int *realnump, void *bufferp)
-{
-  if (this_saved_regs[regnum].addr != 0)
-    {
-      *optimizedp = 0;
-      *lvalp = lval_memory;
-      *addrp = this_saved_regs[regnum].addr;
-      *realnump = -1;
-      if (bufferp != NULL)
-        {
-          /* Read the value in from memory.  */
-
-          if (regnum == AVR_PC_REGNUM)
-            {
-              /* Reading the return PC from the PC register is slightly
-                 abnormal.  register_size(AVR_PC_REGNUM) says it is 4 bytes,
-                 but in reality, only two bytes (3 in upcoming mega256) are
-                 stored on the stack.
-
-                 Also, note that the value on the stack is an addr to a word
-                 not a byte, so we will need to multiply it by two at some
-                 point. 
-
-                 And to confuse matters even more, the return address stored
-                 on the stack is in big endian byte order, even though most
-                 everything else about the avr is little endian. Ick!  */
-
-              /* FIXME: number of bytes read here will need updated for the
-                 mega256 when it is available.  */
-
-              ULONGEST pc;
-              unsigned char tmp;
-              unsigned char buf[2];
-
-              read_memory (this_saved_regs[regnum].addr, buf, 2);
-
-              /* Convert the PC read from memory as a big-endian to
-                 little-endian order. */
-              tmp = buf[0];
-              buf[0] = buf[1];
-              buf[1] = tmp;
-
-              pc = (extract_unsigned_integer (buf, 2) * 2);
-              store_unsigned_integer (bufferp,
-                                      register_size (current_gdbarch, regnum),
-                                      pc);
-            }
-          else
-            {
-              read_memory (this_saved_regs[regnum].addr, bufferp,
-                           register_size (current_gdbarch, regnum));
-            }
-        }
-
-      return;
-    }
-
-  /* No luck, assume this and the next frame have the same register
-     value.  If a value is needed, pass the request on down the chain;
-     otherwise just return an indication that the value is in the same
-     register as the next frame.  */
-  frame_register_unwind (next_frame, regnum, optimizedp, lvalp, addrp,
-                        realnump, bufferp);
-}
-
 /* Put here the code to store, into fi->saved_regs, the addresses of
    the saved registers of frame described by FRAME_INFO.  This
    includes special registers such as pc and fp saved in special ways
@@ -957,7 +889,8 @@ avr_frame_unwind_cache (struct frame_info *next_frame,
   if ((pc > 0) && (pc < frame_pc_unwind (next_frame)))
     avr_scan_prologue (pc, info);
 
-  if (info->prologue_type != AVR_PROLOGUE_NONE)
+  if ((info->prologue_type != AVR_PROLOGUE_NONE)
+      && (info->prologue_type != AVR_PROLOGUE_MAIN))
     {
       ULONGEST high_base;       /* High byte of FP */
 
@@ -987,8 +920,7 @@ avr_frame_unwind_cache (struct frame_info *next_frame,
   info->base = avr_make_saddr (this_base);
 
   /* Adjust all the saved registers so that they contain addresses and not
-     offsets.  We need to add one to the addresses since push ops are post
-     decrement on the avr.  */
+     offsets.  */
   for (i = 0; i < NUM_REGS - 1; i++)
     if (info->saved_regs[i].addr)
       {
@@ -1003,6 +935,10 @@ avr_frame_unwind_cache (struct frame_info *next_frame,
       info->saved_regs[AVR_PC_REGNUM].addr = info->prev_sp;
     }  
 
+  /* The previous frame's SP needed to be computed.  Save the computed
+     value.  */
+  trad_frame_set_value (info->saved_regs, AVR_SP_REGNUM, info->prev_sp+1);
+
   return info;
 }
 
@@ -1069,8 +1005,54 @@ avr_frame_prev_register (struct frame_info *next_frame,
   struct avr_unwind_cache *info
     = avr_frame_unwind_cache (next_frame, this_prologue_cache);
 
-  avr_saved_regs_unwinder (next_frame, info->saved_regs, regnum, optimizedp,
-                           lvalp, addrp, realnump, bufferp);
+  if (regnum == AVR_PC_REGNUM)
+    {
+      if (trad_frame_addr_p (info->saved_regs, regnum))
+        {
+          *optimizedp = 0;
+          *lvalp = lval_memory;
+          *addrp = info->saved_regs[regnum].addr;
+          *realnump = -1;
+          if (bufferp != NULL)
+            {
+              /* Reading the return PC from the PC register is slightly
+                 abnormal.  register_size(AVR_PC_REGNUM) says it is 4 bytes,
+                 but in reality, only two bytes (3 in upcoming mega256) are
+                 stored on the stack.
+
+                 Also, note that the value on the stack is an addr to a word
+                 not a byte, so we will need to multiply it by two at some
+                 point. 
+
+                 And to confuse matters even more, the return address stored
+                 on the stack is in big endian byte order, even though most
+                 everything else about the avr is little endian. Ick!  */
+
+              /* FIXME: number of bytes read here will need updated for the
+                 mega256 when it is available.  */
+
+              ULONGEST pc;
+              unsigned char tmp;
+              unsigned char buf[2];
+
+              read_memory (info->saved_regs[regnum].addr, buf, 2);
+
+              /* Convert the PC read from memory as a big-endian to
+                 little-endian order. */
+              tmp = buf[0];
+              buf[0] = buf[1];
+              buf[1] = tmp;
+
+              pc = (extract_unsigned_integer (buf, 2) * 2);
+              store_unsigned_integer (bufferp,
+                                      register_size (current_gdbarch, regnum),
+                                      pc);
+            }
+        }
+    }
+  else
+    trad_frame_prev_register (next_frame, info->saved_regs, regnum,
+                              optimizedp, lvalp, addrp, realnump, bufferp);
 }
 
 static const struct frame_unwind avr_frame_unwind = {