From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15630 invoked by alias); 15 Jul 2014 10:12:32 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 15613 invoked by uid 89); 15 Jul 2014 10:12:32 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 X-HELO: mail-wi0-f179.google.com Received: from mail-wi0-f179.google.com (HELO mail-wi0-f179.google.com) (209.85.212.179) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Tue, 15 Jul 2014 10:12:28 +0000 Received: by mail-wi0-f179.google.com with SMTP id f8so3100951wiw.12 for ; Tue, 15 Jul 2014 03:12:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:message-id:date:from:user-agent:mime-version:to :subject:references:in-reply-to:content-type :content-transfer-encoding; bh=ZgOmzAbAT4HN3YQDMRgrtP9LwFnT0h6o5UFTJbyGKbE=; b=H71a0hZ6ZtwiBJTVoIHkoAtYM7JFdbV35GVK2EzCUK0SI8TclYvQMDonrEwXJjo/Gl k9QByn1WjnD2/35z1P4qElDWK+/mVKrIXeDXF4fYrYIAzEQLBspcqaSuFFQC14Ly+QiT IwWI+a52wFqQdawooOCppgkxSG2KSPCBJFS5bzCwu9o+JV2L3QbG/LJaFm855OyCy+hZ ROn/AR6n6yyHpx3a7qonRxOLc5XAy7q2Ho7sFUMaYwQPsbwGw1dmqQ4wb78CO7phoqKo w6XmQ2It83GFcw5RDJ4kpz1W2OsPjxL3IzWhl0l0FMQe9ADVyAntJ0Txy5+WKIbjOAbO 6obg== X-Gm-Message-State: ALoCoQnHT1osdRZIpCYgSUmPwHsk3MToUCb5VkjEtVfjdSl5Dxm4WFyYsVyTESbD5cX0ziCFkQu/ X-Received: by 10.194.219.70 with SMTP id pm6mr25661738wjc.53.1405419144754; Tue, 15 Jul 2014 03:12:24 -0700 (PDT) Received: from [192.168.0.9] (cust64-dsl91-135-5.idnet.net. [91.135.5.64]) by mx.google.com with ESMTPSA id w5sm42006153wif.3.2014.07.15.03.12.23 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 15 Jul 2014 03:12:23 -0700 (PDT) Message-ID: <53C4FE86.2070207@embecosm.com> Date: Tue, 15 Jul 2014 10:36:00 -0000 From: Pierre Langlois User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.5.0 MIME-Version: 1.0 To: gdb-patches@sourceware.org Subject: [PING][PATCH] Add support for the __flash qualifier on AVR References: <1404816844-1639-1-git-send-email-pierre.langlois@embecosm.com> In-Reply-To: <1404816844-1639-1-git-send-email-pierre.langlois@embecosm.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2014-07/txt/msg00367.txt.bz2 Ping. On 08/07/14 11:54, Pierre Langlois wrote: > The __flash qualifier is part of the named address spaces for AVR [1]. It allows > putting read-only data in the flash memory, normally reserved for code. > > When used together with a pointer, the DW_AT_address_class attribute is set to 1 > and allows GDB to detect that when it will be dereferenced, the data will be > loaded from the flash memory (with the LPM instruction). > > We can now properly debug the following code: > > ~~~ > const __flash char data_in_flash = 0xab; > > int > main (void) > { > const __flash char *pointer_to_flash = &data_in_flash; > } > ~~~ > > ~~~ > (gdb) print pointer_to_flash > $1 = 0x1e8 "\253" > (gdb) print/x *pointer_to_flash > $2 = 0xab > (gdb) x/x pointer_to_flash > 0x1e8 : 0xXXXXXXab > ~~~ > > Whereas previously, GDB would revert to the default address space which is RAM > and mapped in higher memory: > > ~~~ > (gdb) print pointer_to_flash > $1 = 0x8001e8 "" > ~~~ > > Thanks, > > Pierre > > [1] https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html > > 2014-07-08 Pierre Langlois > > gdb/ > * 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. > > gdb/testsuite/ > * gdb.arch/avr-flash-qualifer.c: New. > * gdb.arch/avr-flash-qualifer.exp: New. > --- > gdb/avr-tdep.c | 77 ++++++++++++++++++++++++-- > gdb/testsuite/gdb.arch/avr-flash-qualifier.c | 32 +++++++++++ > gdb/testsuite/gdb.arch/avr-flash-qualifier.exp | 52 +++++++++++++++++ > 3 files changed, 156 insertions(+), 5 deletions(-) > create mode 100644 gdb/testsuite/gdb.arch/avr-flash-qualifier.c > create mode 100644 gdb/testsuite/gdb.arch/avr-flash-qualifier.exp > > diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c > index 9b0bfaf..eb99748 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,45 @@ avr_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) > return -1; > } > > +/* Map DW_AT_address_class attributes to a type_instance_flag_value. 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. */ > + > +static int > +avr_address_class_type_flags (int byte_size, int dwarf2_addr_class) > +{ > + // __flash qualifier > + if (dwarf2_addr_class == 1 && byte_size == 2) > + return AVR_TYPE_INSTANCE_FLAG_ADDRESS_CLASS_FLASH; > + return 0; > +} > + > +/* Convert a type_instance_flag_value to an address space qualifier and > + vice-versa. */ > + > +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; > +} > + > +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 +1513,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/gdb.arch/avr-flash-qualifier.c b/gdb/testsuite/gdb.arch/avr-flash-qualifier.c > new file mode 100644 > index 0000000..4e5b451 > --- /dev/null > +++ b/gdb/testsuite/gdb.arch/avr-flash-qualifier.c > @@ -0,0 +1,32 @@ > +/* 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 . */ > + > +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 . > +# > +# This file is part of the gdb testsuite. > +# > +# Contributed by Pierre Langlois > +# 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 .*" > + > +gdb_breakpoint "pass_to_function" > +gdb_continue_to_breakpoint "pass_to_function" > + > +gdb_test "print p" \ > + " = $hex .*" > + > +gdb_test "backtrace 1" \ > + "\#0 pass_to_function \\(p=$hex .*\\).*" >