New python events: inferior call, register/memory changed.
[deliverable/binutils-gdb.git] / gdb / avr-tdep.c
index 6beac3d1bbb20b161e5343604f191b9b3993ffd1..d2b5f5f38b2ff092e0f2f442720b8763f9bb27ed 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for Atmel AVR, for GDB.
 
-   Copyright (C) 1996-2013 Free Software Foundation, Inc.
+   Copyright (C) 1996-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -34,9 +34,8 @@
 #include "symfile.h"
 #include "arch-utils.h"
 #include "regcache.h"
-#include "gdb_string.h"
 #include "dis-asm.h"
-#include "linux-tdep.h"
+#include "objfiles.h"
 
 /* AVR Background:
 
 
 /* Constants: prefixed with AVR_ to avoid name space clashes */
 
+/* Address space flags */
+
+/* We are assigning the TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1 to the flash address
+   space.  */
+
+#define AVR_TYPE_ADDRESS_CLASS_FLASH TYPE_ADDRESS_CLASS_1
+#define AVR_TYPE_INSTANCE_FLAG_ADDRESS_CLASS_FLASH  \
+  TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1
+
+
 enum
 {
   AVR_REG_W = 24,
@@ -180,7 +189,7 @@ struct avr_unwind_cache
 struct gdbarch_tdep
 {
   /* Number of bytes stored to the stack by call instructions.
-     2 bytes for avr1-5, 3 bytes for avr6.  */
+     2 bytes for avr1-5 and avrxmega1-5, 3 bytes for avr6 and avrxmega6-7.  */
   int call_length;
 
   /* Type for void.  */
@@ -191,19 +200,6 @@ struct gdbarch_tdep
   struct type *pc_type;
 };
 
-/* This enum represents the signals' numbers on the AVR
-   architecture.  It just contains the signal definitions which are
-   different from the generic implementation.
-
-   It is derived from the file <arch/avr32/include/uapi/asm/signal.h>,
-   from the Linux kernel tree.  */
-
-enum
-  {
-    AVR_LINUX_SIGRTMIN = 32,
-    AVR_LINUX_SIGRTMAX = 63,
-  };
-
 /* Lookup the name of a register given it's number.  */
 
 static const char *
@@ -308,10 +304,19 @@ avr_address_to_pointer (struct gdbarch *gdbarch,
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 
+  /* Is it a data address in flash?  */
+  if (AVR_TYPE_ADDRESS_CLASS_FLASH (type))
+    {
+      /* A data pointer in flash is byte addressed.  */
+      store_unsigned_integer (buf, TYPE_LENGTH (type), byte_order,
+                             avr_convert_iaddr_to_raw (addr));
+    }
   /* Is it a code address?  */
-  if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC
-      || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD)
+  else if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC
+          || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD)
     {
+      /* A code pointer is word (16 bits) addressed.  We shift the address down
+        by 1 bit to convert it to a pointer.  */
       store_unsigned_integer (buf, TYPE_LENGTH (type), byte_order,
                              avr_convert_iaddr_to_raw (addr >> 1));
     }
@@ -331,11 +336,21 @@ avr_pointer_to_address (struct gdbarch *gdbarch,
   CORE_ADDR addr
     = extract_unsigned_integer (buf, TYPE_LENGTH (type), byte_order);
 
+  /* Is it a data address in flash?  */
+  if (AVR_TYPE_ADDRESS_CLASS_FLASH (type))
+    {
+      /* A data pointer in flash is already byte addressed.  */
+      return avr_make_iaddr (addr);
+    }
   /* Is it a code address?  */
-  if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC
-      || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD
-      || TYPE_CODE_SPACE (TYPE_TARGET_TYPE (type)))
-    return avr_make_iaddr (addr << 1);
+  else if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC
+          || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD
+          || TYPE_CODE_SPACE (TYPE_TARGET_TYPE (type)))
+    {
+      /* A code pointer is word (16 bits) addressed so we shift it up
+        by 1 bit to convert it to an address.  */
+      return avr_make_iaddr (addr << 1);
+    }
   else
     return avr_make_saddr (addr);
 }
@@ -506,7 +521,7 @@ avr_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR pc_beg, CORE_ADDR pc_end,
   int i;
   unsigned short insn;
   int scan_stage = 0;
-  struct minimal_symbol *msymbol;
+  struct bound_minimal_symbol msymbol;
   unsigned char prologue[AVR_MAX_PROLOGUE_SIZE];
   int vpc = 0;
   int len;
@@ -600,7 +615,7 @@ avr_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR pc_beg, CORE_ADDR pc_end,
       pc_offset += 2;
 
       msymbol = lookup_minimal_symbol ("__prologue_saves__", NULL, NULL);
-      if (!msymbol)
+      if (!msymbol.minsym)
        break;
 
       insn = extract_unsigned_integer (&prologue[vpc + 8], 2, byte_order);
@@ -638,7 +653,7 @@ 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 - SYMBOL_VALUE_ADDRESS (msymbol)) / 2;
+      num_pushes = AVR_MAX_PUSHES - (i - BMSYMBOL_VALUE_ADDRESS (msymbol)) / 2;
 
       if (num_pushes > AVR_MAX_PUSHES)
         {
@@ -733,7 +748,7 @@ avr_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR pc_beg, CORE_ADDR pc_end,
           info->size += gdbarch_tdep (gdbarch)->call_length;
           vpc += 2;
         }
-      else if (insn == 0x920f)  /* push r0 */
+      else if (insn == 0x920f || insn == 0x921f)  /* push r0 or push r1 */
         {
           info->size += 1;
           vpc += 2;
@@ -1355,58 +1370,52 @@ avr_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
   return -1;
 }
 
-/* Implementation of `gdbarch_gdb_signal_from_target', as defined in
-   gdbarch.h.  */
+/* Implementation of `address_class_type_flags' gdbarch method.
+
+   This method maps DW_AT_address_class attributes to a
+   type_instance_flag_value.  */
 
-static enum gdb_signal
-avr_linux_gdb_signal_from_target (struct gdbarch *gdbarch, int signal)
+static int
+avr_address_class_type_flags (int byte_size, int dwarf2_addr_class)
 {
-  if (signal >= AVR_LINUX_SIGRTMIN && signal <= AVR_LINUX_SIGRTMAX)
-    {
-      int offset = signal - AVR_LINUX_SIGRTMIN;
+  /* The value 1 of the DW_AT_address_class attribute corresponds to the
+     __flash qualifier.  Note that this attribute is only valid with
+     pointer types and therefore the flag is set to the pointer type and
+     not its target type.  */
+  if (dwarf2_addr_class == 1 && byte_size == 2)
+    return AVR_TYPE_INSTANCE_FLAG_ADDRESS_CLASS_FLASH;
+  return 0;
+}
 
-      if (offset == 0)
-       return GDB_SIGNAL_REALTIME_32;
-      else
-       return (enum gdb_signal) (offset - 1
-                                 + (int) GDB_SIGNAL_REALTIME_33);
-    }
-  else if (signal > AVR_LINUX_SIGRTMAX)
-    return GDB_SIGNAL_UNKNOWN;
+/* Implementation of `address_class_type_flags_to_name' gdbarch method.
 
-  return linux_gdb_signal_from_target (gdbarch, signal);
+   Convert a type_instance_flag_value to an address space qualifier.  */
+
+static const char*
+avr_address_class_type_flags_to_name (struct gdbarch *gdbarch, int type_flags)
+{
+  if (type_flags & AVR_TYPE_INSTANCE_FLAG_ADDRESS_CLASS_FLASH)
+    return "flash";
+  else
+    return NULL;
 }
 
-/* Implementation of `gdbarch_gdb_signal_to_target', as defined in
-   gdbarch.h.  */
+/* Implementation of `address_class_name_to_type_flags' gdbarch method.
+
+   Convert an address space qualifier to a type_instance_flag_value.  */
 
 static int
-avr_linux_gdb_signal_to_target (struct gdbarch *gdbarch,
-                               enum gdb_signal signal)
+avr_address_class_name_to_type_flags (struct gdbarch *gdbarch,
+                                      const char* name,
+                                      int *type_flags_ptr)
 {
-  switch (signal)
-    {
-    /* GDB_SIGNAL_REALTIME_32 is not continuous in <gdb/signals.def>,
-       therefore we have to handle it here.  */
-    case GDB_SIGNAL_REALTIME_32:
-      return AVR_LINUX_SIGRTMIN;
-
-    /* GDB_SIGNAL_REALTIME_64 is not valid on AVR.  */
-    case GDB_SIGNAL_REALTIME_64:
-      return -1;
-    }
-
-  /* GDB_SIGNAL_REALTIME_33 to _63 are continuous.
-     AVR does not have _64.  */
-  if (signal >= GDB_SIGNAL_REALTIME_33
-      && signal <= GDB_SIGNAL_REALTIME_63)
+  if (strcmp (name, "flash") == 0)
     {
-      int offset = signal - GDB_SIGNAL_REALTIME_33;
-
-      return AVR_LINUX_SIGRTMIN + 1 + offset;
+      *type_flags_ptr = AVR_TYPE_INSTANCE_FLAG_ADDRESS_CLASS_FLASH;
+      return 1;
     }
-
-  return linux_gdb_signal_to_target (gdbarch, signal);
+  else
+    return 0;
 }
 
 /* Initialize the gdbarch structure for the AVR's.  */
@@ -1423,14 +1432,21 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   switch (info.bfd_arch_info->mach)
     {
     case bfd_mach_avr1:
+    case bfd_mach_avrxmega1:
     case bfd_mach_avr2:
+    case bfd_mach_avrxmega2:
     case bfd_mach_avr3:
+    case bfd_mach_avrxmega3:
     case bfd_mach_avr4:
+    case bfd_mach_avrxmega4:
     case bfd_mach_avr5:
+    case bfd_mach_avrxmega5:
     default:
       call_length = 2;
       break;
     case bfd_mach_avr6:
+    case bfd_mach_avrxmega6:
+    case bfd_mach_avrxmega7:
       call_length = 3;
       break;
     }
@@ -1445,7 +1461,7 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
   /* None found, create a new architecture from the information provided.  */
-  tdep = XMALLOC (struct gdbarch_tdep);
+  tdep = XNEW (struct gdbarch_tdep);
   gdbarch = gdbarch_alloc (&info, tdep);
   
   tdep->call_length = call_length;
@@ -1512,10 +1528,11 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_unwind_pc (gdbarch, avr_unwind_pc);
   set_gdbarch_unwind_sp (gdbarch, avr_unwind_sp);
 
-  set_gdbarch_gdb_signal_from_target (gdbarch,
-                                     avr_linux_gdb_signal_from_target);
-  set_gdbarch_gdb_signal_to_target (gdbarch,
-                                   avr_linux_gdb_signal_to_target);
+  set_gdbarch_address_class_type_flags (gdbarch, avr_address_class_type_flags);
+  set_gdbarch_address_class_name_to_type_flags
+    (gdbarch, avr_address_class_name_to_type_flags);
+  set_gdbarch_address_class_type_flags_to_name
+    (gdbarch, avr_address_class_type_flags_to_name);
 
   return gdbarch;
 }
This page took 0.035947 seconds and 4 git commands to generate.