diff options
-rw-r--r-- | gdb/ChangeLog | 13 | ||||
-rw-r--r-- | gdb/avr-tdep.c | 86 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/avr-flash-qualifier.c | 33 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/avr-flash-qualifier.exp | 52 |
5 files changed, 184 insertions, 5 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2b6604b..6a05145 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,16 @@ +2014-07-15 Pierre Langlois <pierre.langlois@embecosm.com> + + * avr-tdep.c (AVR_TYPE_ADDRESS_CLASS_FLASH): New macro. + (AVR_TYPE_INSTANCE_FLAG_ADDRESS_CLASS_FLASH): Likewise. + (avr_address_to_pointer): Check for AVR_TYPE_ADDRESS_CLASS_FLASH. + (avr_pointer_to_address): Likewise. + (avr_address_class_type_flags): New function. + (avr_address_class_type_flags_to_name): Likewise. + (avr_address_class_name_to_type_flags): Likewise. + (avr_gdbarch_init): Set address_class_type_flags, + address_class_type_flags_to_name and + address_class_name_to_type_flags. + 2014-07-15 Pedro Alves <palves@redhat.com> * linux-nat.c (kill_callback): Save errno and work with saved diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c index 9b0bfaf..be0b543 100644 --- a/gdb/avr-tdep.c +++ b/gdb/avr-tdep.c @@ -71,6 +71,16 @@ /* 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, @@ -295,10 +305,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 address in flash is always 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 address, either a function pointer or the program counter, is + word (16 bits) addressed. */ store_unsigned_integer (buf, TYPE_LENGTH (type), byte_order, avr_convert_iaddr_to_raw (addr >> 1)); } @@ -318,10 +337,13 @@ 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)) + 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))) + 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))) return avr_make_iaddr (addr << 1); else return avr_make_saddr (addr); @@ -1342,6 +1364,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 * @@ -1452,6 +1522,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; } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index b3dd34d..38357ea 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-07-15 Pierre Langlois <pierre.langlois@embecosm.com> + + * gdb.arch/avr-flash-qualifer.c: New. + * gdb.arch/avr-flash-qualifer.exp: New. + 2014-07-14 Pedro Alves <palves@redhat.com> * gdb.base/paginate-after-ctrl-c-running.c: New file. diff --git a/gdb/testsuite/gdb.arch/avr-flash-qualifier.c b/gdb/testsuite/gdb.arch/avr-flash-qualifier.c new file mode 100644 index 0000000..7bfbe3a --- /dev/null +++ b/gdb/testsuite/gdb.arch/avr-flash-qualifier.c @@ -0,0 +1,33 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +const __flash char data_in_flash = 0xab; + +static void +pass_to_function (const __flash char *p) +{ +} + +int +main (void) +{ + const __flash char *pointer_to_flash = &data_in_flash; + + /* break here. */ + pass_to_function (&data_in_flash); + return 0; +} diff --git a/gdb/testsuite/gdb.arch/avr-flash-qualifier.exp b/gdb/testsuite/gdb.arch/avr-flash-qualifier.exp new file mode 100644 index 0000000..e9ccb4f --- /dev/null +++ b/gdb/testsuite/gdb.arch/avr-flash-qualifier.exp @@ -0,0 +1,52 @@ +# Copyright 2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# This file is part of the gdb testsuite. +# +# Contributed by Pierre Langlois <pierre.langlois@embecosm.com> +# Tests for the AVR __flash named address space qualifier. + +if {![istarget "avr*"]} { + verbose "Skipping ${gdb_test_file_name}." + return +} + +# The __flash qualifier was added in GCC 4.7. +if {[test_compiler_info {gcc-[0-4]-[0-6]}]} { + verbose "Skipping ${gdb_test_file_name}." + return +} + +standard_testfile +if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}]} { + return -1 +} + +if ![runto [gdb_get_line_number "break here."]] { + untested "could not run to \"break here.\"" + return -1 +} + +gdb_test "print pointer_to_flash" \ + " = $hex <data_in_flash> .*" + +gdb_breakpoint "pass_to_function" +gdb_continue_to_breakpoint "pass_to_function" + +gdb_test "print p" \ + " = $hex <data_in_flash> .*" + +gdb_test "backtrace 1" \ + "\#0 pass_to_function \\(p=$hex <data_in_flash> .*\\).*" |