PR29262, memory leak in pr_function_type
[binutils-gdb.git] / gdb / m68hc11-tdep.c
index c141711cc87d1c1b61afdfee5bf09486e9a1652c..98f1367423eb48ff6eccf0bae616c78744f017a3 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for Motorola 68HC11 & 68HC12
 
-   Copyright (C) 1999-2021 Free Software Foundation, Inc.
+   Copyright (C) 1999-2022 Free Software Foundation, Inc.
 
    Contributed by Stephane Carrez, stcarrez@nerim.fr
 
@@ -38,6 +38,7 @@
 #include "arch-utils.h"
 #include "regcache.h"
 #include "reggroups.h"
+#include "gdbarch.h"
 
 #include "target.h"
 #include "opcode/m68hc11.h"
    MSYMBOL_IS_RTI       Tests the "RTC" bit in a minimal symbol.  */
 
 #define MSYMBOL_SET_RTC(msym)                           \
-       MSYMBOL_TARGET_FLAG_1 (msym) = 1
+       (msym)->set_target_flag_1 (true)
 
 #define MSYMBOL_SET_RTI(msym)                           \
-       MSYMBOL_TARGET_FLAG_2 (msym) = 1
+       (msym)->set_target_flag_2 (true)
 
 #define MSYMBOL_IS_RTC(msym)                           \
-       MSYMBOL_TARGET_FLAG_1 (msym)
+       (msym)->target_flag_1 ()
 
 #define MSYMBOL_IS_RTI(msym)                           \
-       MSYMBOL_TARGET_FLAG_2 (msym)
+       (msym)->target_flag_2 ()
 
 enum insn_return_kind {
   RETURN_RTS,
@@ -123,27 +124,38 @@ enum insn_return_kind {
 #define M68HC12_HARD_PC_REGNUM  (SOFT_D32_REGNUM+1)
 
 struct insn_sequence;
-struct gdbarch_tdep
+struct m68gc11_gdbarch_tdep : gdbarch_tdep
   {
     /* Stack pointer correction value.  For 68hc11, the stack pointer points
        to the next push location.  An offset of 1 must be applied to obtain
        the address where the last value is saved.  For 68hc12, the stack
        pointer points to the last value pushed.  No offset is necessary.  */
-    int stack_correction;
+    int stack_correction = 0;
 
     /* Description of instructions in the prologue.  */
-    struct insn_sequence *prologue;
+    struct insn_sequence *prologue = nullptr;
 
     /* True if the page memory bank register is available
        and must be used.  */
-    int use_page_register;
+    int use_page_register = 0;
 
     /* ELF flags for ABI.  */
-    int elf_flags;
+    int elf_flags = 0;
   };
 
-#define STACK_CORRECTION(gdbarch) (gdbarch_tdep (gdbarch)->stack_correction)
-#define USE_PAGE_REGISTER(gdbarch) (gdbarch_tdep (gdbarch)->use_page_register)
+static int
+stack_correction (gdbarch *arch)
+{
+  m68gc11_gdbarch_tdep *tdep = (m68gc11_gdbarch_tdep *) gdbarch_tdep (arch);
+  return tdep->stack_correction;
+}
+
+static int
+use_page_register (gdbarch *arch)
+{
+  m68gc11_gdbarch_tdep *tdep = (m68gc11_gdbarch_tdep *) gdbarch_tdep (arch);
+  return tdep->stack_correction;
+}
 
 struct m68hc11_unwind_cache
 {
@@ -203,7 +215,7 @@ m68hc11_get_register_info (struct m68hc11_soft_reg *reg, const char *name)
   msymbol = lookup_minimal_symbol (name, NULL, NULL);
   if (msymbol.minsym)
     {
-      reg->addr = BMSYMBOL_VALUE_ADDRESS (msymbol);
+      reg->addr = msymbol.value_address ();
       reg->name = xstrdup (name);
 
       /* Keep track of the address range for soft registers.  */
@@ -371,13 +383,15 @@ m68hc11_pseudo_register_write (struct gdbarch *gdbarch,
 static const char *
 m68hc11_register_name (struct gdbarch *gdbarch, int reg_nr)
 {
-  if (reg_nr == M68HC12_HARD_PC_REGNUM && USE_PAGE_REGISTER (gdbarch))
+  if (reg_nr == M68HC12_HARD_PC_REGNUM && use_page_register (gdbarch))
     return "pc";
-  if (reg_nr == HARD_PC_REGNUM && USE_PAGE_REGISTER (gdbarch))
+
+  if (reg_nr == HARD_PC_REGNUM && use_page_register (gdbarch))
     return "ppc";
   
   if (reg_nr < 0)
     return NULL;
+
   if (reg_nr >= M68HC11_ALL_REGS)
     return NULL;
 
@@ -387,6 +401,7 @@ m68hc11_register_name (struct gdbarch *gdbarch, int reg_nr)
      does not exist.  */
   if (reg_nr > M68HC11_LAST_HARD_REG && soft_regs[reg_nr].name == 0)
     return NULL;
+
   return m68hc11_register_names[reg_nr];
 }
 
@@ -627,7 +642,8 @@ m68hc11_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR pc,
       return pc;
     }
 
-  seq_table = gdbarch_tdep (gdbarch)->prologue;
+  m68gc11_gdbarch_tdep *tdep = (m68gc11_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  seq_table = tdep->prologue;
   
   /* The 68hc11 stack is as follows:
 
@@ -807,7 +823,7 @@ m68hc11_frame_unwind_cache (struct frame_info *this_frame,
       info->saved_regs[HARD_PC_REGNUM].set_addr (info->sp_offset);
       this_base = get_frame_register_unsigned (this_frame, HARD_SP_REGNUM);
       prev_sp = this_base + info->sp_offset + 2;
-      this_base += STACK_CORRECTION (gdbarch);
+      this_base += stack_correction (gdbarch);
     }
   else
     {
@@ -815,7 +831,7 @@ m68hc11_frame_unwind_cache (struct frame_info *this_frame,
         to before the first saved register giving the SP.  */
       prev_sp = this_base + info->size + 2;
 
-      this_base += STACK_CORRECTION (gdbarch);
+      this_base += stack_correction (gdbarch);
       if (soft_regs[SOFT_FP_REGNUM].name)
        info->saved_regs[SOFT_FP_REGNUM].set_addr (info->size - 2);
    }
@@ -898,7 +914,7 @@ m68hc11_frame_prev_register (struct frame_info *this_frame,
   /* Take into account the 68HC12 specific call (PC + page).  */
   if (regnum == HARD_PC_REGNUM
       && info->return_kind == RETURN_RTC
-      && USE_PAGE_REGISTER (get_frame_arch (this_frame)))
+      && use_page_register (get_frame_arch (this_frame)))
     {
       CORE_ADDR pc = value_as_long (value);
       if (pc >= 0x08000 && pc < 0x0c000)
@@ -997,23 +1013,26 @@ m68hc11_print_register (struct gdbarch *gdbarch, struct ui_file *file,
   if (regno == HARD_A_REGNUM || regno == HARD_B_REGNUM
       || regno == HARD_CCR_REGNUM || regno == HARD_PAGE_REGNUM)
     {
-      fprintf_filtered (file, "0x%02x   ", (unsigned char) rval);
+      gdb_printf (file, "0x%02x   ", (unsigned char) rval);
       if (regno != HARD_CCR_REGNUM)
        print_longest (file, 'd', 1, rval);
     }
   else
     {
-      if (regno == HARD_PC_REGNUM && gdbarch_tdep (gdbarch)->use_page_register)
+      m68gc11_gdbarch_tdep *tdep
+       = (m68gc11_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+      if (regno == HARD_PC_REGNUM && tdep->use_page_register)
        {
          ULONGEST page;
 
          page = get_frame_register_unsigned (frame, HARD_PAGE_REGNUM);
-         fprintf_filtered (file, "0x%02x:%04x ", (unsigned) page,
-                           (unsigned) rval);
+         gdb_printf (file, "0x%02x:%04x ", (unsigned) page,
+                     (unsigned) rval);
        }
       else
        {
-         fprintf_filtered (file, "0x%04x ", (unsigned) rval);
+         gdb_printf (file, "0x%04x ", (unsigned) rval);
          if (regno != HARD_PC_REGNUM && regno != HARD_SP_REGNUM
              && regno != SOFT_FP_REGNUM && regno != M68HC12_HARD_PC_REGNUM)
            print_longest (file, 'd', 1, rval);
@@ -1026,15 +1045,15 @@ m68hc11_print_register (struct gdbarch *gdbarch, struct ui_file *file,
       int C, Z, N, V;
       unsigned char l = rval & 0xff;
 
-      fprintf_filtered (file, "%c%c%c%c%c%c%c%c   ",
-                       l & M6811_S_BIT ? 'S' : '-',
-                       l & M6811_X_BIT ? 'X' : '-',
-                       l & M6811_H_BIT ? 'H' : '-',
-                       l & M6811_I_BIT ? 'I' : '-',
-                       l & M6811_N_BIT ? 'N' : '-',
-                       l & M6811_Z_BIT ? 'Z' : '-',
-                       l & M6811_V_BIT ? 'V' : '-',
-                       l & M6811_C_BIT ? 'C' : '-');
+      gdb_printf (file, "%c%c%c%c%c%c%c%c   ",
+                 l & M6811_S_BIT ? 'S' : '-',
+                 l & M6811_X_BIT ? 'X' : '-',
+                 l & M6811_H_BIT ? 'H' : '-',
+                 l & M6811_I_BIT ? 'I' : '-',
+                 l & M6811_N_BIT ? 'N' : '-',
+                 l & M6811_Z_BIT ? 'Z' : '-',
+                 l & M6811_V_BIT ? 'V' : '-',
+                 l & M6811_C_BIT ? 'C' : '-');
       N = (l & M6811_N_BIT) != 0;
       Z = (l & M6811_Z_BIT) != 0;
       V = (l & M6811_V_BIT) != 0;
@@ -1042,26 +1061,26 @@ m68hc11_print_register (struct gdbarch *gdbarch, struct ui_file *file,
 
       /* Print flags following the h8300.  */
       if ((C | Z) == 0)
-       fprintf_filtered (file, "u> ");
+       gdb_printf (file, "u> ");
       else if ((C | Z) == 1)
-       fprintf_filtered (file, "u<= ");
+       gdb_printf (file, "u<= ");
       else if (C == 0)
-       fprintf_filtered (file, "u< ");
+       gdb_printf (file, "u< ");
 
       if (Z == 0)
-       fprintf_filtered (file, "!= ");
+       gdb_printf (file, "!= ");
       else
-       fprintf_filtered (file, "== ");
+       gdb_printf (file, "== ");
 
       if ((N ^ V) == 0)
-       fprintf_filtered (file, ">= ");
+       gdb_printf (file, ">= ");
       else
-       fprintf_filtered (file, "< ");
+       gdb_printf (file, "< ");
 
       if ((Z | (N ^ V)) == 0)
-       fprintf_filtered (file, "> ");
+       gdb_printf (file, "> ");
       else
-       fprintf_filtered (file, "<= ");
+       gdb_printf (file, "<= ");
     }
 }
 
@@ -1077,41 +1096,43 @@ m68hc11_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
       if (!name || !*name)
        return;
 
-      fprintf_filtered (file, "%-10s ", name);
+      gdb_printf (file, "%-10s ", name);
       m68hc11_print_register (gdbarch, file, frame, regno);
-      fprintf_filtered (file, "\n");
+      gdb_printf (file, "\n");
     }
   else
     {
       int i, nr;
 
-      fprintf_filtered (file, "PC=");
+      gdb_printf (file, "PC=");
       m68hc11_print_register (gdbarch, file, frame, HARD_PC_REGNUM);
 
-      fprintf_filtered (file, " SP=");
+      gdb_printf (file, " SP=");
       m68hc11_print_register (gdbarch, file, frame, HARD_SP_REGNUM);
 
-      fprintf_filtered (file, " FP=");
+      gdb_printf (file, " FP=");
       m68hc11_print_register (gdbarch, file, frame, SOFT_FP_REGNUM);
 
-      fprintf_filtered (file, "\nCCR=");
+      gdb_printf (file, "\nCCR=");
       m68hc11_print_register (gdbarch, file, frame, HARD_CCR_REGNUM);
       
-      fprintf_filtered (file, "\nD=");
+      gdb_printf (file, "\nD=");
       m68hc11_print_register (gdbarch, file, frame, HARD_D_REGNUM);
 
-      fprintf_filtered (file, " X=");
+      gdb_printf (file, " X=");
       m68hc11_print_register (gdbarch, file, frame, HARD_X_REGNUM);
 
-      fprintf_filtered (file, " Y=");
+      gdb_printf (file, " Y=");
       m68hc11_print_register (gdbarch, file, frame, HARD_Y_REGNUM);
   
-      if (gdbarch_tdep (gdbarch)->use_page_register)
+      m68gc11_gdbarch_tdep *tdep = (m68gc11_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+      if (tdep->use_page_register)
        {
-         fprintf_filtered (file, "\nPage=");
+         gdb_printf (file, "\nPage=");
          m68hc11_print_register (gdbarch, file, frame, HARD_PAGE_REGNUM);
        }
-      fprintf_filtered (file, "\n");
+      gdb_printf (file, "\n");
 
       nr = 0;
       for (i = SOFT_D1_REGNUM; i < M68HC11_ALL_REGS; i++)
@@ -1120,16 +1141,16 @@ m68hc11_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
          if (soft_regs[i].name == 0)
            continue;
          
-         fprintf_filtered (file, "D%d=", i - SOFT_D1_REGNUM + 1);
+         gdb_printf (file, "D%d=", i - SOFT_D1_REGNUM + 1);
          m68hc11_print_register (gdbarch, file, frame, i);
          nr++;
          if ((nr % 8) == 7)
-           fprintf_filtered (file, "\n");
+           gdb_printf (file, "\n");
          else
-           fprintf_filtered (file, " ");
+           gdb_printf (file, " ");
        }
       if (nr && (nr % 8) != 7)
-       fprintf_filtered (file, "\n");
+       gdb_printf (file, "\n");
     }
 }
 
@@ -1159,7 +1180,7 @@ m68hc11_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
        {
          ULONGEST v;
 
-         v = extract_unsigned_integer (value_contents (args[0]),
+         v = extract_unsigned_integer (value_contents (args[0]).data (),
                                        TYPE_LENGTH (type), byte_order);
          first_stack_argnum = 1;
 
@@ -1183,7 +1204,7 @@ m68hc11_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
          sp--;
          write_memory (sp, &zero, 1);
        }
-      val = value_contents (args[argnum]);
+      val = value_contents (args[argnum]).data ();
       sp -= TYPE_LENGTH (type);
       write_memory (sp, val, TYPE_LENGTH (type));
     }
@@ -1194,7 +1215,7 @@ m68hc11_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   write_memory (sp, buf, 2);
 
   /* Finally, update the stack pointer...  */
-  sp -= STACK_CORRECTION (gdbarch);
+  sp -= stack_correction (gdbarch);
   regcache_cooked_write_unsigned (regcache, HARD_SP_REGNUM, sp);
 
   /* ...and fake a frame pointer.  */
@@ -1325,8 +1346,8 @@ m68hc11_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
 /* 68HC11/68HC12 register groups.
    Identify real hard registers and soft registers used by gcc.  */
 
-static struct reggroup *m68hc11_soft_reggroup;
-static struct reggroup *m68hc11_hard_reggroup;
+static const reggroup *m68hc11_soft_reggroup;
+static const reggroup *m68hc11_hard_reggroup;
 
 static void
 m68hc11_init_reggroups (void)
@@ -1340,18 +1361,11 @@ m68hc11_add_reggroups (struct gdbarch *gdbarch)
 {
   reggroup_add (gdbarch, m68hc11_hard_reggroup);
   reggroup_add (gdbarch, m68hc11_soft_reggroup);
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, float_reggroup);
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, save_reggroup);
-  reggroup_add (gdbarch, restore_reggroup);
-  reggroup_add (gdbarch, vector_reggroup);
-  reggroup_add (gdbarch, system_reggroup);
 }
 
 static int
 m68hc11_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-                            struct reggroup *group)
+                            const struct reggroup *group)
 {
   /* We must save the real hard register as well as gcc
      soft registers including the frame pointer.  */
@@ -1386,7 +1400,6 @@ m68hc11_gdbarch_init (struct gdbarch_info info,
                      struct gdbarch_list *arches)
 {
   struct gdbarch *gdbarch;
-  struct gdbarch_tdep *tdep;
   int elf_flags;
 
   soft_reg_initialized = 0;
@@ -1403,14 +1416,17 @@ m68hc11_gdbarch_init (struct gdbarch_info info,
        arches != NULL;
        arches = gdbarch_list_lookup_by_info (arches->next, &info))
     {
-      if (gdbarch_tdep (arches->gdbarch)->elf_flags != elf_flags)
+      m68gc11_gdbarch_tdep *tdep
+       = (m68gc11_gdbarch_tdep *) gdbarch_tdep (arches->gdbarch);
+
+      if (tdep->elf_flags != elf_flags)
        continue;
 
       return arches->gdbarch;
     }
 
   /* Need a new architecture.  Fill in a target specific vector.  */
-  tdep = XCNEW (struct gdbarch_tdep);
+  m68gc11_gdbarch_tdep *tdep = new m68gc11_gdbarch_tdep;
   gdbarch = gdbarch_alloc (&info, tdep);
   tdep->elf_flags = elf_flags;