* alphafbsd-tdep.c: Update for unwinder changes.
[deliverable/binutils-gdb.git] / gdb / avr-tdep.c
index c5d6ffe769d49b7469d008a3a13286d5f5ef6407..85f3c0a580942c01cbd56e4749d9f017331135fd 100644 (file)
@@ -1,12 +1,13 @@
 /* Target-dependent code for Atmel AVR, for GDB.
 /* Target-dependent code for Atmel AVR, for GDB.
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-   Free Software Foundation, Inc.
+
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+   2006, 2007, 2008 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    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
 
    This file is part of GDB.
 
    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,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -15,9 +16,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    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., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* Contributed by Theodore A. Roth, troth@openavr.org */
 
 
 /* Contributed by Theodore A. Roth, troth@openavr.org */
 
 #include "trad-frame.h"
 #include "gdbcmd.h"
 #include "gdbcore.h"
 #include "trad-frame.h"
 #include "gdbcmd.h"
 #include "gdbcore.h"
+#include "gdbtypes.h"
 #include "inferior.h"
 #include "symfile.h"
 #include "arch-utils.h"
 #include "regcache.h"
 #include "gdb_string.h"
 #include "inferior.h"
 #include "symfile.h"
 #include "arch-utils.h"
 #include "regcache.h"
 #include "gdb_string.h"
+#include "dis-asm.h"
 
 /* AVR Background:
 
 
 /* AVR Background:
 
@@ -187,7 +188,7 @@ struct gdbarch_tdep
 /* Lookup the name of a register given it's number. */
 
 static const char *
 /* Lookup the name of a register given it's number. */
 
 static const char *
-avr_register_name (int regnum)
+avr_register_name (struct gdbarch *gdbarch, int regnum)
 {
   static char *register_names[] = {
     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
 {
   static char *register_names[] = {
     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
@@ -225,12 +226,6 @@ avr_make_iaddr (CORE_ADDR x)
   return ((x) | AVR_IMEM_START);
 }
 
   return ((x) | AVR_IMEM_START);
 }
 
-static int
-avr_iaddr_p (CORE_ADDR x)
-{
-  return (((x) & AVR_MEM_MASK) == AVR_IMEM_START);
-}
-
 /* FIXME: TRoth: Really need to use a larger mask for instructions. Some
    devices are already up to 128KBytes of flash space.
 
 /* FIXME: TRoth: Really need to use a larger mask for instructions. Some
    devices are already up to 128KBytes of flash space.
 
@@ -250,12 +245,6 @@ avr_make_saddr (CORE_ADDR x)
   return ((x) | AVR_SMEM_START);
 }
 
   return ((x) | AVR_SMEM_START);
 }
 
-static int
-avr_saddr_p (CORE_ADDR x)
-{
-  return (((x) & AVR_MEM_MASK) == AVR_SMEM_START);
-}
-
 static CORE_ADDR
 avr_convert_saddr_to_raw (CORE_ADDR x)
 {
 static CORE_ADDR
 avr_convert_saddr_to_raw (CORE_ADDR x)
 {
@@ -289,7 +278,7 @@ avr_convert_saddr_to_raw (CORE_ADDR x)
 /* Convert from address to pointer and vice-versa. */
 
 static void
 /* Convert from address to pointer and vice-versa. */
 
 static void
-avr_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr)
+avr_address_to_pointer (struct type *type, gdb_byte *buf, CORE_ADDR addr)
 {
   /* Is it a code address?  */
   if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC
 {
   /* Is it a code address?  */
   if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC
@@ -307,7 +296,7 @@ avr_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr)
 }
 
 static CORE_ADDR
 }
 
 static CORE_ADDR
-avr_pointer_to_address (struct type *type, const void *buf)
+avr_pointer_to_address (struct type *type, const gdb_byte *buf)
 {
   CORE_ADDR addr = extract_unsigned_integer (buf, TYPE_LENGTH (type));
 
 {
   CORE_ADDR addr = extract_unsigned_integer (buf, TYPE_LENGTH (type));
 
@@ -321,38 +310,18 @@ avr_pointer_to_address (struct type *type, const void *buf)
 }
 
 static CORE_ADDR
 }
 
 static CORE_ADDR
-avr_read_pc (ptid_t ptid)
+avr_read_pc (struct regcache *regcache)
 {
 {
-  ptid_t save_ptid;
   ULONGEST pc;
   ULONGEST pc;
-  CORE_ADDR retval;
-
-  save_ptid = inferior_ptid;
-  inferior_ptid = ptid;
-  regcache_cooked_read_unsigned (current_regcache, AVR_PC_REGNUM, &pc);
-  inferior_ptid = save_ptid;
-  retval = avr_make_iaddr (pc);
-  return retval;
+  regcache_cooked_read_unsigned (regcache, AVR_PC_REGNUM, &pc);
+  return avr_make_iaddr (pc);
 }
 
 static void
 }
 
 static void
-avr_write_pc (CORE_ADDR val, ptid_t ptid)
+avr_write_pc (struct regcache *regcache, CORE_ADDR val)
 {
 {
-  ptid_t save_ptid;
-
-  save_ptid = inferior_ptid;
-  inferior_ptid = ptid;
-  write_register (AVR_PC_REGNUM, avr_convert_iaddr_to_raw (val));
-  inferior_ptid = save_ptid;
-}
-
-static CORE_ADDR
-avr_read_sp (void)
-{
-  ULONGEST sp;
-
-  regcache_cooked_read_unsigned (current_regcache, AVR_SP_REGNUM, &sp);
-  return (avr_make_saddr (sp));
+  regcache_cooked_write_unsigned (regcache, AVR_PC_REGNUM,
+                                 avr_convert_iaddr_to_raw (val));
 }
 
 static int
 }
 
 static int
@@ -599,7 +568,7 @@ avr_scan_prologue (CORE_ADDR pc, struct avr_unwind_cache *info)
 
       if (num_pushes > AVR_MAX_PUSHES)
         {
 
       if (num_pushes > AVR_MAX_PUSHES)
         {
-          fprintf_unfiltered (gdb_stderr, "Num pushes too large: %d\n",
+          fprintf_unfiltered (gdb_stderr, _("Num pushes too large: %d\n"),
                               num_pushes);
           num_pushes = 0;
         }
                               num_pushes);
           num_pushes = 0;
         }
@@ -678,7 +647,7 @@ avr_scan_prologue (CORE_ADDR pc, struct avr_unwind_cache *info)
 
   if (vpc >= AVR_MAX_PROLOGUE_SIZE)
      fprintf_unfiltered (gdb_stderr,
 
   if (vpc >= AVR_MAX_PROLOGUE_SIZE)
      fprintf_unfiltered (gdb_stderr,
-                         "Hit end of prologue while scanning pushes\n");
+                         _("Hit end of prologue while scanning pushes\n"));
 
   /* Second stage of the prologue scanning.
      Scan:
 
   /* Second stage of the prologue scanning.
      Scan:
@@ -774,16 +743,8 @@ avr_scan_prologue (CORE_ADDR pc, struct avr_unwind_cache *info)
   return pc + avr_scan_arg_moves (vpc, prologue);;
 }
 
   return pc + avr_scan_arg_moves (vpc, prologue);;
 }
 
-/* Returns the return address for a dummy. */
-
-static CORE_ADDR
-avr_call_dummy_address (void)
-{
-  return entry_point_address ();
-}
-
 static CORE_ADDR
 static CORE_ADDR
-avr_skip_prologue (CORE_ADDR pc)
+avr_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   CORE_ADDR func_addr, func_end;
   CORE_ADDR prologue_end = pc;
 {
   CORE_ADDR func_addr, func_end;
   CORE_ADDR prologue_end = pc;
@@ -804,7 +765,9 @@ avr_skip_prologue (CORE_ADDR pc)
 
       prologue_end = avr_scan_prologue (pc, &info);
 
 
       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);
 
         {
           sal = find_pc_line (func_addr, 0);
 
@@ -825,7 +788,7 @@ avr_skip_prologue (CORE_ADDR pc)
    only target, this shouldn't be a problem (I hope). TRoth/2003-05-14  */
 
 static const unsigned char *
    only target, this shouldn't be a problem (I hope). TRoth/2003-05-14  */
 
 static const unsigned char *
-avr_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr)
+avr_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR * pcptr, int *lenptr)
 {
     static unsigned char avr_break_insn [] = { 0x98, 0x95 };
     *lenptr = sizeof (avr_break_insn);
 {
     static unsigned char avr_break_insn [] = { 0x98, 0x95 };
     *lenptr = sizeof (avr_break_insn);
@@ -839,7 +802,7 @@ avr_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr)
 
 static void
 avr_extract_return_value (struct type *type, struct regcache *regcache,
 
 static void
 avr_extract_return_value (struct type *type, struct regcache *regcache,
-                          void *valbuf)
+                          gdb_byte *valbuf)
 {
   ULONGEST r24, r25;
   ULONGEST c;
 {
   ULONGEST r24, r25;
   ULONGEST c;
@@ -864,76 +827,44 @@ 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)
+/* Determine, for architecture GDBARCH, how a return value of TYPE
+   should be returned.  If it is supposed to be returned in registers,
+   and READBUF is non-zero, read the appropriate value from REGCACHE,
+   and copy it into READBUF.  If WRITEBUF is non-zero, write the value
+   from WRITEBUF into REGCACHE.  */
+
+enum return_value_convention
+avr_return_value (struct gdbarch *gdbarch, struct type *func_type,
+                 struct type *valtype, struct regcache *regcache,
+                 gdb_byte *readbuf, const gdb_byte *writebuf)
 {
 {
-  if (this_saved_regs[regnum].addr != 0)
+  int struct_return = ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
+                       || TYPE_CODE (valtype) == TYPE_CODE_UNION
+                       || TYPE_CODE (valtype) == TYPE_CODE_ARRAY)
+                      && !(TYPE_LENGTH (valtype) == 1
+                           || TYPE_LENGTH (valtype) == 2
+                           || TYPE_LENGTH (valtype) == 4
+                           || TYPE_LENGTH (valtype) == 8));
+
+  if (writebuf != NULL)
     {
     {
-      *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));
-            }
-        }
+      gdb_assert (!struct_return);
+      error (_("Cannot store return value."));
+    }
 
 
-      return;
+  if (readbuf != NULL)
+    {
+      gdb_assert (!struct_return);
+      avr_extract_return_value (valtype, regcache, readbuf);
     }
 
     }
 
-  /* 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);
+  if (struct_return)
+    return RETURN_VALUE_STRUCT_CONVENTION;
+  else
+    return RETURN_VALUE_REGISTER_CONVENTION;
 }
 
 }
 
+
 /* 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
 /* 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
@@ -941,7 +872,7 @@ avr_saved_regs_unwinder (struct frame_info *next_frame,
    for it IS the sp for the next frame. */
 
 struct avr_unwind_cache *
    for it IS the sp for the next frame. */
 
 struct avr_unwind_cache *
-avr_frame_unwind_cache (struct frame_info *next_frame,
+avr_frame_unwind_cache (struct frame_info *this_frame,
                         void **this_prologue_cache)
 {
   CORE_ADDR pc;
                         void **this_prologue_cache)
 {
   CORE_ADDR pc;
@@ -955,25 +886,26 @@ avr_frame_unwind_cache (struct frame_info *next_frame,
 
   info = FRAME_OBSTACK_ZALLOC (struct avr_unwind_cache);
   (*this_prologue_cache) = info;
 
   info = FRAME_OBSTACK_ZALLOC (struct avr_unwind_cache);
   (*this_prologue_cache) = info;
-  info->saved_regs = trad_frame_alloc_saved_regs (next_frame);
+  info->saved_regs = trad_frame_alloc_saved_regs (this_frame);
 
   info->size = 0;
   info->prologue_type = AVR_PROLOGUE_NONE;
 
 
   info->size = 0;
   info->prologue_type = AVR_PROLOGUE_NONE;
 
-  pc = frame_func_unwind (next_frame);
+  pc = get_frame_func (this_frame);
 
 
-  if ((pc > 0) && (pc < frame_pc_unwind (next_frame)))
+  if ((pc > 0) && (pc < get_frame_pc (this_frame)))
     avr_scan_prologue (pc, info);
 
     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 */
 
       /* The SP was moved to the FP.  This indicates that a new frame
          was created.  Get THIS frame's FP value by unwinding it from
          the next frame.  */
     {
       ULONGEST high_base;       /* High byte of FP */
 
       /* The SP was moved to the FP.  This indicates that a new frame
          was created.  Get THIS frame's FP value by unwinding it from
          the next frame.  */
-      frame_unwind_unsigned_register (next_frame, AVR_FP_REGNUM, &this_base);
-      frame_unwind_unsigned_register (next_frame, AVR_FP_REGNUM+1, &high_base);
+      this_base = get_frame_register_unsigned (this_frame, AVR_FP_REGNUM);
+      high_base = get_frame_register_unsigned (this_frame, AVR_FP_REGNUM+1);
       this_base += (high_base << 8);
       
       /* The FP points at the last saved register.  Adjust the FP back
       this_base += (high_base << 8);
       
       /* The FP points at the last saved register.  Adjust the FP back
@@ -984,7 +916,7 @@ avr_frame_unwind_cache (struct frame_info *next_frame,
     {
       /* Assume that the FP is this frame's SP but with that pushed
          stack space added back.  */
     {
       /* Assume that the FP is this frame's SP but with that pushed
          stack space added back.  */
-      frame_unwind_unsigned_register (next_frame, AVR_SP_REGNUM, &this_base);
+      this_base = get_frame_register_unsigned (this_frame, AVR_SP_REGNUM);
       prev_sp = this_base + info->size;
     }
 
       prev_sp = this_base + info->size;
     }
 
@@ -995,9 +927,8 @@ 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
   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.  */
-  for (i = 0; i < NUM_REGS - 1; i++)
+     offsets.  */
+  for (i = 0; i < gdbarch_num_regs (get_frame_arch (this_frame)) - 1; i++)
     if (info->saved_regs[i].addr)
       {
         info->saved_regs[i].addr = (info->prev_sp - info->saved_regs[i].addr);
     if (info->saved_regs[i].addr)
       {
         info->saved_regs[i].addr = (info->prev_sp - info->saved_regs[i].addr);
@@ -1011,6 +942,10 @@ avr_frame_unwind_cache (struct frame_info *next_frame,
       info->saved_regs[AVR_PC_REGNUM].addr = info->prev_sp;
     }  
 
       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;
 }
 
   return info;
 }
 
@@ -1019,32 +954,37 @@ avr_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
   ULONGEST pc;
 
 {
   ULONGEST pc;
 
-  frame_unwind_unsigned_register (next_frame, AVR_PC_REGNUM, &pc);
+  pc = frame_unwind_register_unsigned (next_frame, AVR_PC_REGNUM);
 
   return avr_make_iaddr (pc);
 }
 
 
   return avr_make_iaddr (pc);
 }
 
+static CORE_ADDR
+avr_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+  ULONGEST sp;
+
+  sp = frame_unwind_register_unsigned (next_frame, AVR_SP_REGNUM);
+
+  return avr_make_saddr (sp);
+}
+
 /* Given a GDB frame, determine the address of the calling function's
    frame.  This will be used to create a new GDB frame struct.  */
 
 static void
 /* Given a GDB frame, determine the address of the calling function's
    frame.  This will be used to create a new GDB frame struct.  */
 
 static void
-avr_frame_this_id (struct frame_info *next_frame,
+avr_frame_this_id (struct frame_info *this_frame,
                    void **this_prologue_cache,
                    struct frame_id *this_id)
 {
   struct avr_unwind_cache *info
                    void **this_prologue_cache,
                    struct frame_id *this_id)
 {
   struct avr_unwind_cache *info
-    = avr_frame_unwind_cache (next_frame, this_prologue_cache);
+    = avr_frame_unwind_cache (this_frame, this_prologue_cache);
   CORE_ADDR base;
   CORE_ADDR func;
   struct frame_id id;
 
   /* The FUNC is easy.  */
   CORE_ADDR base;
   CORE_ADDR func;
   struct frame_id id;
 
   /* The FUNC is easy.  */
-  func = frame_func_unwind (next_frame);
-
-  /* This is meant to halt the backtrace at "_start".  Make sure we
-     don't halt it at a generic dummy frame. */
-  if (inside_entry_file (func))
-    return;
+  func = get_frame_func (this_frame);
 
   /* Hopefully the prologue analysis either correctly determined the
      frame's base (which is the SP from the previous frame), or set
 
   /* Hopefully the prologue analysis either correctly determined the
      frame's base (which is the SP from the previous frame), or set
@@ -1054,50 +994,72 @@ avr_frame_this_id (struct frame_info *next_frame,
     return;
 
   id = frame_id_build (base, func);
     return;
 
   id = frame_id_build (base, func);
-
-  /* Check that we're not going round in circles with the same frame
-     ID (but avoid applying the test to sentinel frames which do go
-     round in circles).  Can't use frame_id_eq() as that doesn't yet
-     compare the frame's PC value.  */
-  if (frame_relative_level (next_frame) >= 0
-      && get_frame_type (next_frame) != DUMMY_FRAME
-      && frame_id_eq (get_frame_id (next_frame), id))
-    return;
-
   (*this_id) = id;
 }
 
   (*this_id) = id;
 }
 
-static void
-avr_frame_prev_register (struct frame_info *next_frame,
-                         void **this_prologue_cache,
-                         int regnum, int *optimizedp,
-                         enum lval_type *lvalp, CORE_ADDR *addrp,
-                         int *realnump, void *bufferp)
+static struct value *
+avr_frame_prev_register (struct frame_info *this_frame,
+                         void **this_prologue_cache, int regnum)
 {
   struct avr_unwind_cache *info
 {
   struct avr_unwind_cache *info
-    = avr_frame_unwind_cache (next_frame, this_prologue_cache);
+    = avr_frame_unwind_cache (this_frame, this_prologue_cache);
+
+  if (regnum == AVR_PC_REGNUM)
+    {
+      if (trad_frame_addr_p (info->saved_regs, 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 (info->saved_regs[regnum].addr, buf, 2);
 
 
-  avr_saved_regs_unwinder (next_frame, info->saved_regs, regnum, optimizedp,
-                           lvalp, addrp, realnump, bufferp);
+         /* 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);
+
+         return frame_unwind_got_constant (this_frame, regnum, pc);
+        }
+
+      return frame_unwind_got_optimized (this_frame, regnum);
+    }
+
+  return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
 }
 
 static const struct frame_unwind avr_frame_unwind = {
   NORMAL_FRAME,
   avr_frame_this_id,
 }
 
 static const struct frame_unwind avr_frame_unwind = {
   NORMAL_FRAME,
   avr_frame_this_id,
-  avr_frame_prev_register
+  avr_frame_prev_register,
+  NULL,
+  default_frame_sniffer
 };
 
 };
 
-const struct frame_unwind *
-avr_frame_p (CORE_ADDR pc)
-{
-  return &avr_frame_unwind;
-}
-
 static CORE_ADDR
 static CORE_ADDR
-avr_frame_base_address (struct frame_info *next_frame, void **this_cache)
+avr_frame_base_address (struct frame_info *this_frame, void **this_cache)
 {
   struct avr_unwind_cache *info
 {
   struct avr_unwind_cache *info
-    = avr_frame_unwind_cache (next_frame, this_cache);
+    = avr_frame_unwind_cache (this_frame, this_cache);
 
   return info->base;
 }
 
   return info->base;
 }
@@ -1109,18 +1071,17 @@ static const struct frame_base avr_frame_base = {
   avr_frame_base_address
 };
 
   avr_frame_base_address
 };
 
-/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
-   dummy frame.  The frame ID's base needs to match the TOS value
-   saved by save_dummy_frame_tos(), and the PC match the dummy frame's
-   breakpoint.  */
+/* Assuming THIS_FRAME is a dummy, return the frame ID of that dummy
+   frame.  The frame ID's base needs to match the TOS value saved by
+   save_dummy_frame_tos(), and the PC match the dummy frame's breakpoint.  */
 
 static struct frame_id
 
 static struct frame_id
-avr_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+avr_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 {
   ULONGEST base;
 
 {
   ULONGEST base;
 
-  frame_unwind_unsigned_register (next_frame, AVR_SP_REGNUM, &base);
-  return frame_id_build (avr_make_saddr (base), frame_pc_unwind (next_frame));
+  base = get_frame_register_unsigned (this_frame, AVR_SP_REGNUM);
+  return frame_id_build (avr_make_saddr (base), get_frame_pc (this_frame));
 }
 
 /* When arguments must be pushed onto the stack, they go on in reverse
 }
 
 /* When arguments must be pushed onto the stack, they go on in reverse
@@ -1133,10 +1094,8 @@ struct stack_item
   void *data;
 };
 
   void *data;
 };
 
-static struct stack_item *push_stack_item (struct stack_item *prev,
-                                          void *contents, int len);
 static struct stack_item *
 static struct stack_item *
-push_stack_item (struct stack_item *prev, void *contents, int len)
+push_stack_item (struct stack_item *prev, const bfd_byte *contents, int len)
 {
   struct stack_item *si;
   si = xmalloc (sizeof (struct stack_item));
 {
   struct stack_item *si;
   si = xmalloc (sizeof (struct stack_item));
@@ -1198,7 +1157,7 @@ pop_stack_item (struct stack_item *si)
    registers R0 to R2. */
 
 static CORE_ADDR
    registers R0 to R2. */
 
 static CORE_ADDR
-avr_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
+avr_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                      struct regcache *regcache, CORE_ADDR bp_addr,
                      int nargs, struct value **args, CORE_ADDR sp,
                      int struct_return, CORE_ADDR struct_addr)
                      struct regcache *regcache, CORE_ADDR bp_addr,
                      int nargs, struct value **args, CORE_ADDR sp,
                      int struct_return, CORE_ADDR struct_addr)
@@ -1214,8 +1173,8 @@ avr_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
   if (struct_return)
     {
       fprintf_unfiltered (gdb_stderr, "struct_return: 0x%lx\n", struct_addr);
   if (struct_return)
     {
       fprintf_unfiltered (gdb_stderr, "struct_return: 0x%lx\n", struct_addr);
-      write_register (argreg--, struct_addr & 0xff);
-      write_register (argreg--, (struct_addr >>8) & 0xff);
+      regcache_cooked_write_unsigned (regcache, argreg--, struct_addr & 0xff);
+      regcache_cooked_write_unsigned (regcache, argreg--, (struct_addr >>8) & 0xff);
     }
 #endif
 
     }
 #endif
 
@@ -1224,8 +1183,8 @@ avr_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
       int last_regnum;
       int j;
       struct value *arg = args[i];
       int last_regnum;
       int j;
       struct value *arg = args[i];
-      struct type *type = check_typedef (VALUE_TYPE (arg));
-      char *contents = VALUE_CONTENTS (arg);
+      struct type *type = check_typedef (value_type (arg));
+      const bfd_byte *contents = value_contents (arg);
       int len = TYPE_LENGTH (type);
 
       /* Calculate the potential last register needed. */
       int len = TYPE_LENGTH (type);
 
       /* Calculate the potential last register needed. */
@@ -1320,13 +1279,12 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
   set_gdbarch_long_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
 
   set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
   set_gdbarch_long_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
 
-  set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little);
-  set_gdbarch_double_format (gdbarch, &floatformat_ieee_single_little);
-  set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_single_little);
+  set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
+  set_gdbarch_double_format (gdbarch, floatformats_ieee_single);
+  set_gdbarch_long_double_format (gdbarch, floatformats_ieee_single);
 
   set_gdbarch_read_pc (gdbarch, avr_read_pc);
   set_gdbarch_write_pc (gdbarch, avr_write_pc);
 
   set_gdbarch_read_pc (gdbarch, avr_read_pc);
   set_gdbarch_write_pc (gdbarch, avr_write_pc);
-  set_gdbarch_read_sp (gdbarch, avr_read_sp);
 
   set_gdbarch_num_regs (gdbarch, AVR_NUM_REGS);
 
 
   set_gdbarch_num_regs (gdbarch, AVR_NUM_REGS);
 
@@ -1336,35 +1294,26 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_register_name (gdbarch, avr_register_name);
   set_gdbarch_register_type (gdbarch, avr_register_type);
 
   set_gdbarch_register_name (gdbarch, avr_register_name);
   set_gdbarch_register_type (gdbarch, avr_register_type);
 
-  set_gdbarch_extract_return_value (gdbarch, avr_extract_return_value);
+  set_gdbarch_return_value (gdbarch, avr_return_value);
   set_gdbarch_print_insn (gdbarch, print_insn_avr);
 
   set_gdbarch_print_insn (gdbarch, print_insn_avr);
 
-  set_gdbarch_call_dummy_address (gdbarch, avr_call_dummy_address);
   set_gdbarch_push_dummy_call (gdbarch, avr_push_dummy_call);
 
   set_gdbarch_address_to_pointer (gdbarch, avr_address_to_pointer);
   set_gdbarch_pointer_to_address (gdbarch, avr_pointer_to_address);
 
   set_gdbarch_push_dummy_call (gdbarch, avr_push_dummy_call);
 
   set_gdbarch_address_to_pointer (gdbarch, avr_address_to_pointer);
   set_gdbarch_pointer_to_address (gdbarch, avr_pointer_to_address);
 
-  set_gdbarch_use_struct_convention (gdbarch, generic_use_struct_convention);
-
   set_gdbarch_skip_prologue (gdbarch, avr_skip_prologue);
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
 
   set_gdbarch_skip_prologue (gdbarch, avr_skip_prologue);
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
 
-  set_gdbarch_decr_pc_after_break (gdbarch, 0);
   set_gdbarch_breakpoint_from_pc (gdbarch, avr_breakpoint_from_pc);
 
   set_gdbarch_breakpoint_from_pc (gdbarch, avr_breakpoint_from_pc);
 
-  set_gdbarch_function_start_offset (gdbarch, 0);
-
-  set_gdbarch_frame_args_skip (gdbarch, 0);
-  set_gdbarch_frameless_function_invocation (gdbarch,
-                                             frameless_look_for_prologue);
-
-  frame_unwind_append_predicate (gdbarch, avr_frame_p);
+  frame_unwind_append_unwinder (gdbarch, &avr_frame_unwind);
   frame_base_set_default (gdbarch, &avr_frame_base);
 
   frame_base_set_default (gdbarch, &avr_frame_base);
 
-  set_gdbarch_unwind_dummy_id (gdbarch, avr_unwind_dummy_id);
+  set_gdbarch_dummy_id (gdbarch, avr_dummy_id);
 
   set_gdbarch_unwind_pc (gdbarch, avr_unwind_pc);
 
   set_gdbarch_unwind_pc (gdbarch, avr_unwind_pc);
+  set_gdbarch_unwind_sp (gdbarch, avr_unwind_sp);
 
   return gdbarch;
 }
 
   return gdbarch;
 }
@@ -1385,48 +1334,39 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 static void
 avr_io_reg_read_command (char *args, int from_tty)
 {
 static void
 avr_io_reg_read_command (char *args, int from_tty)
 {
-  int bufsiz = 0;
-  char buf[400];
+  LONGEST bufsiz = 0;
+  gdb_byte *buf;
   char query[400];
   char *p;
   unsigned int nreg = 0;
   unsigned int val;
   int i, j, k, step;
 
   char query[400];
   char *p;
   unsigned int nreg = 0;
   unsigned int val;
   int i, j, k, step;
 
-  if (!current_target.to_query)
-    {
-      fprintf_unfiltered (gdb_stderr,
-                         "ERR: info io_registers NOT supported by current "
-                          "target\n");
-      return;
-    }
-
-  /* Just get the maximum buffer size. */
-  target_query ((int) 'R', 0, 0, &bufsiz);
-  if (bufsiz > sizeof (buf))
-    bufsiz = sizeof (buf);
-
   /* Find out how many io registers the target has. */
   /* Find out how many io registers the target has. */
-  strcpy (query, "avr.io_reg");
-  target_query ((int) 'R', query, buf, &bufsiz);
+  bufsiz = target_read_alloc (&current_target, TARGET_OBJECT_AVR,
+                             "avr.io_reg", &buf);
 
 
-  if (strncmp (buf, "", bufsiz) == 0)
+  if (bufsiz <= 0)
     {
       fprintf_unfiltered (gdb_stderr,
     {
       fprintf_unfiltered (gdb_stderr,
-                         "info io_registers NOT supported by target\n");
+                         _("ERR: info io_registers NOT supported "
+                           "by current target\n"));
       return;
     }
 
   if (sscanf (buf, "%x", &nreg) != 1)
     {
       fprintf_unfiltered (gdb_stderr,
       return;
     }
 
   if (sscanf (buf, "%x", &nreg) != 1)
     {
       fprintf_unfiltered (gdb_stderr,
-                         "Error fetching number of io registers\n");
+                         _("Error fetching number of io registers\n"));
+      xfree (buf);
       return;
     }
 
       return;
     }
 
+  xfree (buf);
+
   reinitialize_more_filter ();
 
   reinitialize_more_filter ();
 
-  printf_unfiltered ("Target has %u io registers:\n\n", nreg);
+  printf_unfiltered (_("Target has %u io registers:\n\n"), nreg);
 
   /* only fetch up to 8 registers at a time to keep the buffer small */
   step = 8;
 
   /* only fetch up to 8 registers at a time to keep the buffer small */
   step = 8;
@@ -1439,7 +1379,8 @@ avr_io_reg_read_command (char *args, int from_tty)
         j = nreg - i;           /* last block is less than 8 registers */
 
       snprintf (query, sizeof (query) - 1, "avr.io_reg:%x,%x", i, j);
         j = nreg - i;           /* last block is less than 8 registers */
 
       snprintf (query, sizeof (query) - 1, "avr.io_reg:%x,%x", i, j);
-      target_query ((int) 'R', query, buf, &bufsiz);
+      bufsiz = target_read_alloc (&current_target, TARGET_OBJECT_AVR,
+                                 query, &buf);
 
       p = buf;
       for (k = i; k < (i + j); k++)
 
       p = buf;
       for (k = i; k < (i + j); k++)
@@ -1454,6 +1395,8 @@ avr_io_reg_read_command (char *args, int from_tty)
                break;
            }
        }
                break;
            }
        }
+
+      xfree (buf);
     }
 }
 
     }
 }
 
@@ -1472,5 +1415,6 @@ _initialize_avr_tdep (void)
      io_registers' to signify it is not available on other platforms. */
 
   add_cmd ("io_registers", class_info, avr_io_reg_read_command,
      io_registers' to signify it is not available on other platforms. */
 
   add_cmd ("io_registers", class_info, avr_io_reg_read_command,
-          "query remote avr target for io space register values", &infolist);
+          _("query remote avr target for io space register values"),
+          &infolist);
 }
 }
This page took 0.033787 seconds and 4 git commands to generate.