/* Target-dependent code for Atmel AVR, for GDB.
- Copyright (C) 1996-2013 Free Software Foundation, Inc.
+ Copyright (C) 1996-2015 Free Software Foundation, Inc.
This file is part of GDB.
#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,
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. */
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 *
{
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));
}
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);
}
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;
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);
/* 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)
{
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;
push_stack_item (struct stack_item *prev, const bfd_byte *contents, int len)
{
struct stack_item *si;
- si = xmalloc (sizeof (struct stack_item));
+ si = XNEW (struct stack_item);
si->data = xmalloc (len);
si->len = len;
si->prev = prev;
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. */
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;
}
}
/* 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;
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;
}