PR29482 - strip: heap-buffer-overflow
[binutils-gdb.git] / gdb / avr-tdep.c
index e9493f1ec6fb6e38b3f3a957c146f6cd0d74a2f6..357f5bb8f2dc4c5954a9a1a3a3160d881d7b1098 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for Atmel AVR, for GDB.
 
-   Copyright (C) 1996-2021 Free Software Foundation, Inc.
+   Copyright (C) 1996-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -37,6 +37,7 @@
 #include "dis-asm.h"
 #include "objfiles.h"
 #include <algorithm>
+#include "gdbarch.h"
 
 /* AVR Background:
 
@@ -188,18 +189,18 @@ struct avr_unwind_cache
   trad_frame_saved_reg *saved_regs;
 };
 
-struct gdbarch_tdep
+struct avr_gdbarch_tdep : gdbarch_tdep_base
 {
   /* Number of bytes stored to the stack by call instructions.
      2 bytes for avr1-5 and avrxmega1-5, 3 bytes for avr6 and avrxmega6-7.  */
-  int call_length;
+  int call_length = 0;
 
   /* Type for void.  */
-  struct type *void_type;
+  struct type *void_type = nullptr;
   /* Type for a function returning void.  */
-  struct type *func_void_type;
+  struct type *func_void_type = nullptr;
   /* Type for a pointer to a function.  Used for the type of PC.  */
-  struct type *pc_type;
+  struct type *pc_type = nullptr;
 };
 
 /* Lookup the name of a register given it's number.  */
@@ -230,10 +231,14 @@ avr_register_type (struct gdbarch *gdbarch, int reg_nr)
 {
   if (reg_nr == AVR_PC_REGNUM)
     return builtin_type (gdbarch)->builtin_uint32;
+
+  avr_gdbarch_tdep *tdep = gdbarch_tdep<avr_gdbarch_tdep> (gdbarch);
   if (reg_nr == AVR_PSEUDO_PC_REGNUM)
-    return gdbarch_tdep (gdbarch)->pc_type;
+    return tdep->pc_type;
+
   if (reg_nr == AVR_SP_REGNUM)
     return builtin_type (gdbarch)->builtin_data_ptr;
+
   return builtin_type (gdbarch)->builtin_uint8;
 }
 
@@ -659,12 +664,12 @@ avr_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR pc_beg, CORE_ADDR pc_end,
 
       /* Resolve offset (in words) from __prologue_saves__ symbol.
         Which is a pushes count in `-mcall-prologues' mode */
-      num_pushes = AVR_MAX_PUSHES - (i - BMSYMBOL_VALUE_ADDRESS (msymbol)) / 2;
+      num_pushes = AVR_MAX_PUSHES - (i - msymbol.value_address ()) / 2;
 
       if (num_pushes > AVR_MAX_PUSHES)
        {
-         fprintf_unfiltered (gdb_stderr, _("Num pushes too large: %d\n"),
-                             num_pushes);
+         gdb_printf (gdb_stderr, _("Num pushes too large: %d\n"),
+                     num_pushes);
          num_pushes = 0;
        }
 
@@ -745,13 +750,13 @@ avr_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR pc_beg, CORE_ADDR pc_end,
   gdb_assert (vpc < AVR_MAX_PROLOGUE_SIZE);
 
   /* Handle static small stack allocation using rcall or push.  */
-
+  avr_gdbarch_tdep *tdep = gdbarch_tdep<avr_gdbarch_tdep> (gdbarch);
   while (scan_stage == 1 && vpc < len)
     {
       insn = extract_unsigned_integer (&prologue[vpc], 2, byte_order);
       if (insn == 0xd000)      /* rcall .+0 */
        {
-         info->size += gdbarch_tdep (gdbarch)->call_length;
+         info->size += tdep->call_length;
          vpc += 2;
        }
       else if (insn == 0x920f || insn == 0x921f)  /* push r0 or push r1 */
@@ -984,7 +989,6 @@ avr_frame_unwind_cache (struct frame_info *this_frame,
   ULONGEST this_base;
   struct avr_unwind_cache *info;
   struct gdbarch *gdbarch;
-  struct gdbarch_tdep *tdep;
   int i;
 
   if (*this_prologue_cache)
@@ -1037,7 +1041,7 @@ avr_frame_unwind_cache (struct frame_info *this_frame,
   /* Adjust all the saved registers so that they contain addresses and not
      offsets.  */
   for (i = 0; i < gdbarch_num_regs (gdbarch) - 1; i++)
-    if (info->saved_regs[i].addr () > 0)
+    if (info->saved_regs[i].is_addr ())
       info->saved_regs[i].set_addr (info->prev_sp
                                    - info->saved_regs[i].addr ());
 
@@ -1049,9 +1053,9 @@ avr_frame_unwind_cache (struct frame_info *this_frame,
 
   /* The previous frame's SP needed to be computed.  Save the computed
      value.  */
-  tdep = gdbarch_tdep (gdbarch);
-  trad_frame_set_value (info->saved_regs, AVR_SP_REGNUM,
-                       info->prev_sp - 1 + tdep->call_length);
+  avr_gdbarch_tdep *tdep = gdbarch_tdep<avr_gdbarch_tdep> (gdbarch);
+  info->saved_regs[AVR_SP_REGNUM].set_value (info->prev_sp
+                                            - 1 + tdep->call_length);
 
   return info;
 }
@@ -1113,7 +1117,7 @@ avr_frame_prev_register (struct frame_info *this_frame,
 
   if (regnum == AVR_PC_REGNUM || regnum == AVR_PSEUDO_PC_REGNUM)
     {
-      if (trad_frame_addr_p (info->saved_regs, AVR_PC_REGNUM))
+      if (info->saved_regs[AVR_PC_REGNUM].is_addr ())
        {
          /* Reading the return PC from the PC register is slightly
             abnormal.  register_size(AVR_PC_REGNUM) says it is 4 bytes,
@@ -1131,7 +1135,7 @@ avr_frame_prev_register (struct frame_info *this_frame,
          int i;
          gdb_byte buf[3];
          struct gdbarch *gdbarch = get_frame_arch (this_frame);
-         struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+         avr_gdbarch_tdep *tdep = gdbarch_tdep<avr_gdbarch_tdep> (gdbarch);
 
          read_memory (info->saved_regs[AVR_PC_REGNUM].addr (),
                       buf, tdep->call_length);
@@ -1154,6 +1158,7 @@ avr_frame_prev_register (struct frame_info *this_frame,
 }
 
 static const struct frame_unwind avr_frame_unwind = {
+  "avr prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   avr_frame_this_id,
@@ -1194,18 +1199,19 @@ avr_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 /* When arguments must be pushed onto the stack, they go on in reverse
    order.  The below implements a FILO (stack) to do this.  */
 
-struct stack_item
+struct avr_stack_item
 {
   int len;
-  struct stack_item *prev;
+  struct avr_stack_item *prev;
   gdb_byte *data;
 };
 
-static struct stack_item *
-push_stack_item (struct stack_item *prev, const bfd_byte *contents, int len)
+static struct avr_stack_item *
+push_stack_item (struct avr_stack_item *prev, const bfd_byte *contents,
+                int len)
 {
-  struct stack_item *si;
-  si = XNEW (struct stack_item);
+  struct avr_stack_item *si;
+  si = XNEW (struct avr_stack_item);
   si->data = (gdb_byte *) xmalloc (len);
   si->len = len;
   si->prev = prev;
@@ -1213,11 +1219,10 @@ push_stack_item (struct stack_item *prev, const bfd_byte *contents, int len)
   return si;
 }
 
-static struct stack_item *pop_stack_item (struct stack_item *si);
-static struct stack_item *
-pop_stack_item (struct stack_item *si)
+static struct avr_stack_item *
+pop_stack_item (struct avr_stack_item *si)
 {
-  struct stack_item *dead = si;
+  struct avr_stack_item *dead = si;
   si = si->prev;
   xfree (dead->data);
   xfree (dead);
@@ -1272,10 +1277,11 @@ avr_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 {
   int i;
   gdb_byte buf[3];
-  int call_length = gdbarch_tdep (gdbarch)->call_length;
+  avr_gdbarch_tdep *tdep = gdbarch_tdep<avr_gdbarch_tdep> (gdbarch);
+  int call_length = tdep->call_length;
   CORE_ADDR return_pc = avr_convert_iaddr_to_raw (bp_addr);
   int regnum = AVR_ARGN_REGNUM;
-  struct stack_item *si = NULL;
+  struct avr_stack_item *si = NULL;
 
   if (return_method == return_method_struct)
     {
@@ -1295,7 +1301,7 @@ avr_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       int j;
       struct value *arg = args[i];
       struct type *type = check_typedef (value_type (arg));
-      const bfd_byte *contents = value_contents (arg);
+      const bfd_byte *contents = value_contents (arg).data ();
       int len = TYPE_LENGTH (type);
 
       /* Calculate the potential last register needed.
@@ -1423,7 +1429,6 @@ static struct gdbarch *
 avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
   struct gdbarch *gdbarch;
-  struct gdbarch_tdep *tdep;
   struct gdbarch_list *best_arch;
   int call_length;
 
@@ -1455,12 +1460,15 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        best_arch != NULL;
        best_arch = gdbarch_list_lookup_by_info (best_arch->next, &info))
     {
-      if (gdbarch_tdep (best_arch->gdbarch)->call_length == call_length)
+      avr_gdbarch_tdep *tdep
+       = gdbarch_tdep<avr_gdbarch_tdep> (best_arch->gdbarch);
+
+      if (tdep->call_length == call_length)
        return best_arch->gdbarch;
     }
 
   /* None found, create a new architecture from the information provided.  */
-  tdep = XCNEW (struct gdbarch_tdep);
+  avr_gdbarch_tdep *tdep = new avr_gdbarch_tdep;
   gdbarch = gdbarch_alloc (&info, tdep);
   
   tdep->call_length = call_length;
@@ -1561,13 +1569,14 @@ avr_io_reg_read_command (const char *args, int from_tty)
 
   /* Find out how many io registers the target has.  */
   gdb::optional<gdb::byte_vector> buf
-    = target_read_alloc (current_top_target (), TARGET_OBJECT_AVR, "avr.io_reg");
+    = target_read_alloc (current_inferior ()->top_target (),
+                        TARGET_OBJECT_AVR, "avr.io_reg");
 
   if (!buf)
     {
-      fprintf_unfiltered (gdb_stderr,
-                         _("ERR: info io_registers NOT supported "
-                           "by current target\n"));
+      gdb_printf (gdb_stderr,
+                 _("ERR: info io_registers NOT supported "
+                   "by current target\n"));
       return;
     }
 
@@ -1575,14 +1584,12 @@ avr_io_reg_read_command (const char *args, int from_tty)
 
   if (sscanf (bufstr, "%x", &nreg) != 1)
     {
-      fprintf_unfiltered (gdb_stderr,
-                         _("Error fetching number of io registers\n"));
+      gdb_printf (gdb_stderr,
+                 _("Error fetching number of io registers\n"));
       return;
     }
 
-  reinitialize_more_filter ();
-
-  printf_unfiltered (_("Target has %u io registers:\n\n"), nreg);
+  gdb_printf (_("Target has %u io registers:\n\n"), nreg);
 
   /* only fetch up to 8 registers at a time to keep the buffer small */
   int step = 8;
@@ -1595,13 +1602,14 @@ avr_io_reg_read_command (const 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);
-      buf = target_read_alloc (current_top_target (), TARGET_OBJECT_AVR, query);
+      buf = target_read_alloc (current_inferior ()->top_target (),
+                              TARGET_OBJECT_AVR, query);
 
       if (!buf)
        {
-         fprintf_unfiltered (gdb_stderr,
-                             _("ERR: error reading avr.io_reg:%x,%x\n"),
-                             i, j);
+         gdb_printf (gdb_stderr,
+                     _("ERR: error reading avr.io_reg:%x,%x\n"),
+                     i, j);
          return;
        }
 
@@ -1610,7 +1618,7 @@ avr_io_reg_read_command (const char *args, int from_tty)
        {
          if (sscanf (p, "%[^,],%x;", query, &val) == 2)
            {
-             printf_filtered ("[%02x] %-15s : %02x\n", k, query, val);
+             gdb_printf ("[%02x] %-15s : %02x\n", k, query, val);
              while ((*p != ';') && (*p != '\0'))
                p++;
              p++;              /* skip over ';' */