X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Favr-tdep.c;h=dff0be996175af715798d9559e571a3123026dcc;hb=f95f4ed2c4680fea68399691481b277ece11570e;hp=31dd7df4ab51e47cd2cb7fd9fd87fef9928404d6;hpb=05d1431c1e0a4ecf30462109f5fb9876d78b7b4a;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c index 31dd7df4ab..dff0be9961 100644 --- a/gdb/avr-tdep.c +++ b/gdb/avr-tdep.c @@ -1,7 +1,6 @@ /* Target-dependent code for Atmel AVR, for GDB. - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 1996-2015 Free Software Foundation, Inc. This file is part of GDB. @@ -35,8 +34,8 @@ #include "symfile.h" #include "arch-utils.h" #include "regcache.h" -#include "gdb_string.h" #include "dis-asm.h" +#include "objfiles.h" /* AVR Background: @@ -69,11 +68,18 @@ via the remote serial protocol. The extra bits are the MSBs and are used to decode which memory space the address is referring to. */ -#undef XMALLOC -#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE))) - /* 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, @@ -183,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. */ @@ -298,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)); } @@ -321,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); } @@ -496,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; @@ -590,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); @@ -628,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) { @@ -723,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; @@ -743,7 +768,6 @@ avr_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR pc_beg, CORE_ADDR pc_end, 0xcd, 0xb7, /* in r28,__SP_L__ */ 0xde, 0xb7 /* in r29,__SP_H__ */ }; - unsigned short insn1; if (vpc + sizeof (img) < len && memcmp (prologue + vpc, img, sizeof (img)) == 0) @@ -903,7 +927,7 @@ avr_breakpoint_from_pc (struct gdbarch *gdbarch, from WRITEBUF into REGCACHE. */ static enum return_value_convention -avr_return_value (struct gdbarch *gdbarch, struct type *func_type, +avr_return_value (struct gdbarch *gdbarch, struct value *function, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { @@ -1105,7 +1129,7 @@ avr_frame_prev_register (struct frame_info *this_frame, everything else about the avr is little endian. Ick! */ ULONGEST pc; int i; - unsigned char buf[3]; + gdb_byte buf[3]; struct gdbarch *gdbarch = get_frame_arch (this_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); @@ -1131,6 +1155,7 @@ avr_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind avr_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, avr_frame_this_id, avr_frame_prev_register, NULL, @@ -1246,7 +1271,7 @@ avr_push_dummy_call (struct gdbarch *gdbarch, struct value *function, { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int i; - unsigned char buf[3]; + gdb_byte buf[3]; int call_length = gdbarch_tdep (gdbarch)->call_length; CORE_ADDR return_pc = avr_convert_iaddr_to_raw (bp_addr); int regnum = AVR_ARGN_REGNUM; @@ -1345,6 +1370,54 @@ avr_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) return -1; } +/* Implementation of `address_class_type_flags' gdbarch method. + + This method maps DW_AT_address_class attributes to a + type_instance_flag_value. */ + +static int +avr_address_class_type_flags (int byte_size, int dwarf2_addr_class) +{ + /* 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; +} + +/* Implementation of `address_class_type_flags_to_name' gdbarch method. + + 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 `address_class_name_to_type_flags' gdbarch method. + + Convert an address space qualifier to a type_instance_flag_value. */ + +static int +avr_address_class_name_to_type_flags (struct gdbarch *gdbarch, + const char* name, + int *type_flags_ptr) +{ + if (strcmp (name, "flash") == 0) + { + *type_flags_ptr = AVR_TYPE_INSTANCE_FLAG_ADDRESS_CLASS_FLASH; + return 1; + } + else + return 0; +} + /* Initialize the gdbarch structure for the AVR's. */ static struct gdbarch * @@ -1359,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; } @@ -1381,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; @@ -1448,6 +1528,12 @@ 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_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; } @@ -1469,8 +1555,9 @@ avr_io_reg_read_command (char *args, int from_tty) { LONGEST bufsiz = 0; gdb_byte *buf; + const char *bufstr; char query[400]; - char *p; + const char *p; unsigned int nreg = 0; unsigned int val; int i, j, k, step; @@ -1478,6 +1565,7 @@ avr_io_reg_read_command (char *args, int from_tty) /* Find out how many io registers the target has. */ bufsiz = target_read_alloc (¤t_target, TARGET_OBJECT_AVR, "avr.io_reg", &buf); + bufstr = (const char *) buf; if (bufsiz <= 0) { @@ -1487,7 +1575,7 @@ avr_io_reg_read_command (char *args, int from_tty) return; } - if (sscanf (buf, "%x", &nreg) != 1) + if (sscanf (bufstr, "%x", &nreg) != 1) { fprintf_unfiltered (gdb_stderr, _("Error fetching number of io registers\n")); @@ -1515,7 +1603,7 @@ avr_io_reg_read_command (char *args, int from_tty) bufsiz = target_read_alloc (¤t_target, TARGET_OBJECT_AVR, query, &buf); - p = buf; + p = (const char *) buf; for (k = i; k < (i + j); k++) { if (sscanf (p, "%[^,],%x;", query, &val) == 2)