Add `set print repeats' tests for C/C++ arrays
[binutils-gdb.git] / gdb / or1k-tdep.c
index a8de029997d53f45ba951c759d9fe4de6a980e78..1e01df223adda4f21fee6b496f48e28d22841e96 100644 (file)
@@ -1,5 +1,5 @@
 /* Target-dependent code for the 32-bit OpenRISC 1000, for the GDB.
-   Copyright (C) 2008-2017 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "block.h"
 #include "reggroups.h"
 #include "arch-utils.h"
-#include "frame.h"
 #include "frame-unwind.h"
 #include "frame-base.h"
-#include "dwarf2-frame.h"
+#include "dwarf2/frame.h"
 #include "trad-frame.h"
 #include "regset.h"
 #include "remote.h"
 #include "target-descriptions.h"
 #include <inttypes.h>
 #include "dis-asm.h"
+#include "gdbarch.h"
 
 /* OpenRISC specific includes.  */
 #include "or1k-tdep.h"
@@ -51,7 +51,7 @@
 
 /* Global debug flag.  */
 
-static int or1k_debug = 0;
+static bool or1k_debug = false;
 
 static void
 show_or1k_debug (struct ui_file *file, int from_tty,
@@ -63,11 +63,11 @@ show_or1k_debug (struct ui_file *file, int from_tty,
 
 /* The target-dependent structure for gdbarch.  */
 
-struct gdbarch_tdep
+struct or1k_gdbarch_tdep : gdbarch_tdep
 {
-  int bytes_per_word;
-  int bytes_per_address;
-  CGEN_CPU_DESC gdb_cgen_cpu_desc;
+  int bytes_per_word = 0;
+  int bytes_per_address = 0;
+  CGEN_CPU_DESC gdb_cgen_cpu_desc = nullptr;
 };
 
 /* Support functions for the architecture definition.  */
@@ -246,9 +246,10 @@ or1k_return_value (struct gdbarch *gdbarch, struct value *functype,
                   gdb_byte *readbuf, const gdb_byte *writebuf)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  enum type_code rv_type = TYPE_CODE (valtype);
+  enum type_code rv_type = valtype->code ();
   unsigned int rv_size = TYPE_LENGTH (valtype);
-  int bpw = (gdbarch_tdep (gdbarch))->bytes_per_word;
+  or1k_gdbarch_tdep *tdep = (or1k_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int bpw = tdep->bytes_per_word;
 
   /* Deal with struct/union as addresses.  If an array won't fit in a
      single register it is returned as address.  Anything larger than 2
@@ -297,7 +298,7 @@ or1k_return_value (struct gdbarch *gdbarch, struct value *functype,
          else
            memcpy (buf, writebuf, rv_size);
 
-         regcache_cooked_write (regcache, OR1K_RV_REGNUM, buf);
+         regcache->cooked_write (OR1K_RV_REGNUM, buf);
 
          free (buf);
        }
@@ -330,8 +331,8 @@ or1k_return_value (struct gdbarch *gdbarch, struct value *functype,
          memcpy (buf_hi, writebuf, rv_size - bpw);
          memcpy (buf_lo, writebuf + bpw, bpw);
 
-         regcache_cooked_write (regcache, OR1K_RV_REGNUM, buf_hi);
-         regcache_cooked_write (regcache, OR1K_RV_REGNUM + 1, buf_lo);
+         regcache->cooked_write (OR1K_RV_REGNUM, buf_hi);
+         regcache->cooked_write (OR1K_RV_REGNUM + 1, buf_lo);
 
          free (buf_lo);
          free (buf_hi);
@@ -347,6 +348,33 @@ constexpr gdb_byte or1k_break_insn[] = {0x21, 0x00, 0x00, 0x01};
 
 typedef BP_MANIPULATION (or1k_break_insn) or1k_breakpoint;
 
+static int
+or1k_delay_slot_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  const CGEN_INSN *insn;
+  CGEN_FIELDS tmp_fields;
+  or1k_gdbarch_tdep *tdep = (or1k_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  insn = cgen_lookup_insn (tdep->gdb_cgen_cpu_desc,
+                          NULL,
+                          or1k_fetch_instruction (gdbarch, pc),
+                          NULL, 32, &tmp_fields, 0);
+
+  /* NULL here would mean the last instruction was not understood by cgen.
+     This should not usually happen, but if does its not a delay slot.  */
+  if (insn == NULL)
+    return 0;
+
+  /* TODO: we should add a delay slot flag to the CGEN_INSN and remove
+     this hard coded test.  */
+  return ((CGEN_INSN_NUM (insn) == OR1K_INSN_L_J)
+         || (CGEN_INSN_NUM (insn) == OR1K_INSN_L_JAL)
+         || (CGEN_INSN_NUM (insn) == OR1K_INSN_L_JR)
+         || (CGEN_INSN_NUM (insn) == OR1K_INSN_L_JALR)
+         || (CGEN_INSN_NUM (insn) == OR1K_INSN_L_BNF)
+         || (CGEN_INSN_NUM (insn) == OR1K_INSN_L_BF));
+}
+
 /* Implement the single_step_through_delay gdbarch method.  */
 
 static int
@@ -356,10 +384,7 @@ or1k_single_step_through_delay (struct gdbarch *gdbarch,
   ULONGEST val;
   CORE_ADDR ppc;
   CORE_ADDR npc;
-  CGEN_FIELDS tmp_fields;
-  const CGEN_INSN *insn;
   struct regcache *regcache = get_current_regcache ();
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   /* Get the previous and current instruction addresses.  If they are not
     adjacent, we cannot be in a delay slot.  */
@@ -371,24 +396,28 @@ or1k_single_step_through_delay (struct gdbarch *gdbarch,
   if (0x4 != (npc - ppc))
     return 0;
 
-  insn = cgen_lookup_insn (tdep->gdb_cgen_cpu_desc,
-                          NULL,
-                          or1k_fetch_instruction (gdbarch, ppc),
-                          NULL, 32, &tmp_fields, 0);
+  return or1k_delay_slot_p (gdbarch, ppc);
+}
 
-  /* NULL here would mean the last instruction was not understood by cgen.
-     This should not usually happen, but if does its not a delay slot.  */
-  if (insn == NULL)
-    return 0;
+/* or1k_software_single_step() is called just before we want to resume
+   the inferior, if we want to single-step it but there is no hardware
+   or kernel single-step support (OpenRISC on GNU/Linux for example).  We
+   find the target of the coming instruction skipping over delay slots
+   and breakpoint it.  */
 
-  /* TODO: we should add a delay slot flag to the CGEN_INSN and remove
-     this hard coded test.  */
-  return ((CGEN_INSN_NUM (insn) == OR1K_INSN_L_J)
-         || (CGEN_INSN_NUM (insn) == OR1K_INSN_L_JAL)
-         || (CGEN_INSN_NUM (insn) == OR1K_INSN_L_JR)
-         || (CGEN_INSN_NUM (insn) == OR1K_INSN_L_JALR)
-         || (CGEN_INSN_NUM (insn) == OR1K_INSN_L_BNF)
-         || (CGEN_INSN_NUM (insn) == OR1K_INSN_L_BF));
+std::vector<CORE_ADDR>
+or1k_software_single_step (struct regcache *regcache)
+{
+  struct gdbarch *gdbarch = regcache->arch ();
+  CORE_ADDR pc, next_pc;
+
+  pc = regcache_read_pc (regcache);
+  next_pc = pc + 4;
+
+  if (or1k_delay_slot_p (gdbarch, pc))
+    next_pc += 4;
+
+  return {next_pc};
 }
 
 /* Name for or1k general registers.  */
@@ -595,7 +624,8 @@ static CORE_ADDR
 or1k_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)
+                     function_call_return_method return_method,
+                     CORE_ADDR struct_addr)
 {
 
   int argreg;
@@ -605,8 +635,9 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   int heap_offset = 0;
   CORE_ADDR heap_sp = sp - 128;
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  int bpa = (gdbarch_tdep (gdbarch))->bytes_per_address;
-  int bpw = (gdbarch_tdep (gdbarch))->bytes_per_word;
+  or1k_gdbarch_tdep *tdep = (or1k_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int bpa = tdep->bytes_per_address;
+  int bpw = tdep->bytes_per_word;
   struct type *func_type = value_type (function);
 
   /* Return address */
@@ -617,7 +648,7 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
   /* Location for a returned structure.  This is passed as a silent first
      argument.  */
-  if (struct_return)
+  if (return_method == return_method_struct)
     {
       regcache_cooked_write_unsigned (regcache, OR1K_FIRST_ARG_REGNUM,
                                      struct_addr);
@@ -633,9 +664,9 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       struct value *arg = args[argnum];
       struct type *arg_type = check_typedef (value_type (arg));
       int len = TYPE_LENGTH (arg_type);
-      enum type_code typecode = TYPE_CODE (arg_type);
+      enum type_code typecode = arg_type->code ();
 
-      if (TYPE_VARARGS (func_type) && argnum >= TYPE_NFIELDS (func_type))
+      if (func_type->has_varargs () && argnum >= func_type->num_fields ())
        break; /* end or regular args, varargs go to stack.  */
 
       /* Extract the value, either a reference or the data.  */
@@ -655,7 +686,7 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
              heap_offset += align_up (len, bpw);
              valaddr = heap_sp + heap_offset;
 
-             write_memory (valaddr, value_contents (arg), len);
+             write_memory (valaddr, value_contents (arg).data (), len);
            }
 
          /* The ABI passes all structures by reference, so get its
@@ -667,7 +698,7 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       else
        {
          /* Everything else, we just get the value.  */
-         val = value_contents (arg);
+         val = value_contents (arg).data ();
        }
 
       /* Stick the value in a register.  */
@@ -723,7 +754,7 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       struct value *arg = args[argnum];
       struct type *arg_type = check_typedef (value_type (arg));
       int len = TYPE_LENGTH (arg_type);
-      enum type_code typecode = TYPE_CODE (arg_type);
+      enum type_code typecode = arg_type->code ();
 
       if ((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode)
          || (len > bpw * 2))
@@ -755,9 +786,9 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       struct value *arg = args[argnum];
       struct type *arg_type = check_typedef (value_type (arg));
       int len = TYPE_LENGTH (arg_type);
-      enum type_code typecode = TYPE_CODE (arg_type);
+      enum type_code typecode = arg_type->code ();
       /* The EABI passes structures that do not fit in a register by
-         reference.  In all other cases, pass the structure by value.  */
+        reference.  In all other cases, pass the structure by value.  */
       if ((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode)
          || (len > bpw * 2))
        {
@@ -767,7 +798,7 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
          val = valbuf;
        }
       else
-       val = value_contents (arg);
+       val = value_contents (arg).data ();
 
       while (len > 0)
        {
@@ -789,14 +820,6 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   return sp;
 }
 
-/* Implement the dummy_id gdbarch method.  */
-
-static struct frame_id
-or1k_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
-  return frame_id_build (get_frame_sp (this_frame),
-                        get_frame_pc (this_frame));
-}
 \f
 
 /* Support functions for frame handling.  */
@@ -832,7 +855,7 @@ or1k_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 
    l.sw    lr_loc(r1),r9        # Link (return) address
 
-   The link register is usally saved at fp_loc - 4.  It may not be saved at
+   The link register is usually saved at fp_loc - 4.  It may not be saved at
    all in a leaf function.
 
    l.sw    reg_loc(r1),ry       # Save any callee saved regs
@@ -982,8 +1005,8 @@ or1k_frame_cache (struct frame_info *this_frame, void **prologue_cache)
          else
            {
              /* We are past this point, so the stack pointer of the prev
-                frame is frame_size greater than the stack pointer of this
-                frame.  */
+                frame is frame_size greater than the stack pointer of this
+                frame.  */
              trad_frame_set_reg_value (info, OR1K_SP_REGNUM,
                                        this_sp + frame_size);
            }
@@ -1016,7 +1039,7 @@ or1k_frame_cache (struct frame_info *this_frame, void **prologue_cache)
              inst = or1k_fetch_instruction (gdbarch, addr);
 
              /* If we have got this far, the stack pointer of the previous
-                frame is the frame pointer of this frame.  */
+                frame is the frame pointer of this frame.  */
              trad_frame_set_reg_realreg (info, OR1K_SP_REGNUM,
                                          OR1K_FP_REGNUM);
            }
@@ -1055,7 +1078,7 @@ or1k_frame_cache (struct frame_info *this_frame, void **prologue_cache)
              inst = or1k_fetch_instruction (gdbarch, addr);
 
              /* The register in the previous frame can be found at this
-                location in this frame.  */
+                location in this frame.  */
              trad_frame_set_reg_addr (info, rb, this_sp + simm);
            }
          else
@@ -1104,6 +1127,7 @@ or1k_frame_prev_register (struct frame_info *this_frame,
 /* Data structures for the normal prologue-analysis-based unwinder.  */
 
 static const struct frame_unwind or1k_frame_unwind = {
+  "or1k prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   or1k_frame_this_id,
@@ -1119,9 +1143,8 @@ static struct gdbarch *
 or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
   struct gdbarch *gdbarch;
-  struct gdbarch_tdep *tdep;
   const struct bfd_arch_info *binfo;
-  struct tdesc_arch_data *tdesc_data = NULL;
+  tdesc_arch_data_up tdesc_data;
   const struct target_desc *tdesc = info.target_desc;
 
   /* Find a candidate among the list of pre-declared architectures.  */
@@ -1134,7 +1157,7 @@ or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      actually know which target we are talking to, but put in some defaults
      for now.  */
   binfo = info.bfd_arch_info;
-  tdep = XCNEW (struct gdbarch_tdep);
+  or1k_gdbarch_tdep *tdep = new or1k_gdbarch_tdep;
   tdep->bytes_per_word = binfo->bits_per_word / binfo->bits_per_byte;
   tdep->bytes_per_address = binfo->bits_per_address / binfo->bits_per_byte;
   gdbarch = gdbarch_alloc (&info, tdep);
@@ -1184,7 +1207,6 @@ or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
   set_gdbarch_push_dummy_code (gdbarch, or1k_push_dummy_code);
   set_gdbarch_push_dummy_call (gdbarch, or1k_push_dummy_call);
-  set_gdbarch_dummy_id (gdbarch, or1k_dummy_id);
 
   /* Frame unwinders.  Use DWARF debug info if available, otherwise use our
      own unwinder.  */
@@ -1223,21 +1245,18 @@ or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
       feature = tdesc_find_feature (tdesc, "org.gnu.gdb.or1k.group0");
       if (feature == NULL)
-        return NULL;
+       return NULL;
 
       tdesc_data = tdesc_data_alloc ();
 
       valid_p = 1;
 
       for (i = 0; i < OR1K_NUM_REGS; i++)
-        valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
-                                            or1k_reg_names[i]);
+       valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
+                                           or1k_reg_names[i]);
 
       if (!valid_p)
-        {
-          tdesc_data_cleanup (tdesc_data);
-          return NULL;
-        }
+       return NULL;
     }
 
   if (tdesc_data != NULL)
@@ -1252,9 +1271,12 @@ or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       reggroup_add (gdbarch, save_reggroup);
       reggroup_add (gdbarch, restore_reggroup);
 
-      tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+      tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
     }
 
+  /* Hook in ABI-specific overrides, if they have been registered.  */
+  gdbarch_init_osabi (info, gdbarch);
+
   return gdbarch;
 }
 
@@ -1263,20 +1285,21 @@ or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 static void
 or1k_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  or1k_gdbarch_tdep *tdep = (or1k_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (NULL == tdep)
     return; /* Nothing to report */
 
-  fprintf_unfiltered (file, "or1k_dump_tdep: %d bytes per word\n",
-                     tdep->bytes_per_word);
-  fprintf_unfiltered (file, "or1k_dump_tdep: %d bytes per address\n",
-                     tdep->bytes_per_address);
+  fprintf_filtered (file, "or1k_dump_tdep: %d bytes per word\n",
+                   tdep->bytes_per_word);
+  fprintf_filtered (file, "or1k_dump_tdep: %d bytes per address\n",
+                   tdep->bytes_per_address);
 }
 \f
 
+void _initialize_or1k_tdep ();
 void
-_initialize_or1k_tdep (void)
+_initialize_or1k_tdep ()
 {
   /* Register this architecture.  */
   gdbarch_register (bfd_arch_or1k, or1k_gdbarch_init, or1k_dump_tdep);