From patchwork Mon Oct 27 03:10:34 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Kamensky X-Patchwork-Id: 3387 Received: (qmail 5966 invoked by alias); 27 Oct 2014 03:10:51 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 5852 invoked by uid 89); 27 Oct 2014 03:10:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pd0-f174.google.com Received: from mail-pd0-f174.google.com (HELO mail-pd0-f174.google.com) (209.85.192.174) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Mon, 27 Oct 2014 03:10:49 +0000 Received: by mail-pd0-f174.google.com with SMTP id p10so4722828pdj.5 for ; Sun, 26 Oct 2014 20:10:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=HV3oMbZawQV7Jif3opHkNuLhimubi9brEjKBEYfP/No=; b=TyQ0DOSAtt2rH0fk9dgjYM8gpkSYS3Iiqu7n03KWAiE8gxpxNEUan0t5Aq/ECRxfEJ nAdguUYlRQtsyFKoz8isROfaUaCq8uFzQc0bH3y/Ixjkr+nAa8gN7+nA9HRVZXPx7I8M GeL0MHukrFqVf4yMxKpRSKQkgg0OXrExYNRNq/rQUPikp/NUvp1DChVh286NQXBEFRoX e+btsJ2kVgMO+aaXI0DbdjaUtDnNLJ2rDmR7cYTk+goFb7FRiW2940eYgosBsF1Pc8nt PHCQVWohRNnxSn6QwtbD5fkfS7k5VdLYYPgdBHT0vNAsifzGOJaZm4L9pOoIAUpgbmht Q1mQ== X-Gm-Message-State: ALoCoQnlspOiXCCLe3CjEgY6NOL2dFAgYAp0AgXNbnO05WyIgrDM33ktzyBh3N77AHluvor5pifP X-Received: by 10.66.242.203 with SMTP id ws11mr21453497pac.69.1414379447501; Sun, 26 Oct 2014 20:10:47 -0700 (PDT) Received: from kamensky-w530.cisco.com (128-107-239-233.cisco.com. [128.107.239.233]) by mx.google.com with ESMTPSA id sb2sm9410723pbc.24.2014.10.26.20.10.45 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 26 Oct 2014 20:10:46 -0700 (PDT) From: Victor Kamensky To: gdb-patches@sourceware.org, Yao Qi Cc: Andrew Pinski , victor.kamensky@linaro.org Subject: [PATCH V4 3/3] read_pieced_value do big endian processing only in case of valid gdb_regnum Date: Sun, 26 Oct 2014 20:10:34 -0700 Message-Id: <1414379434-5217-4-git-send-email-victor.kamensky@linaro.org> In-Reply-To: <1414379434-5217-1-git-send-email-victor.kamensky@linaro.org> References: <1414379434-5217-1-git-send-email-victor.kamensky@linaro.org> During armv7b testing gdb.base/store.exp test was failling with 'GDB internal error' with the following message: Temporary breakpoint 1, wack_double (u= ../../binutils-gdb/gdb/regcache.c:177: internal-error: register_size: Assertion `regnum >= 0 && regnum < (gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch))' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. It turns out that compiler generated DWARF with non-existent register numbers. The compiler issue is present in both little endian (armv7) and big endian (armv7b) (it is separate issue). Here is example for one of formal parameters of wack_double function: <2><792>: Abbrev Number: 10 (DW_TAG_formal_parameter) <793> DW_AT_name : u <795> DW_AT_decl_file : 1 <796> DW_AT_decl_line : 115 <797> DW_AT_type : <0x57c> <79b> DW_AT_location : 6 byte block: 6d 93 4 6c 93 4 (DW_OP_reg29 (r29); DW_OP_piece: 4; DW_OP_reg28 (r28); DW_OP_piece: 4) In both big and little endian cases gdbarch_dwarf2_reg_to_regnum returns -1 which is stored into gdb_regnum. But it causes severe problem only in big endian case because in read_pieced_value and write_pieced_value functions BFD_ENDIAN_BIG related processing happen regardless of gdb_regnum value, for example register_size function is called and in case of gdb_regnum=-1, it cause 'GDB internal error' and crash. Solution is to move BFD_ENDIAN_BIG related processing under (gdb_regnum != -1) branch of processing. gdb/ChangeLog: 2014-10-21 Victor Kamensky * dwarf2loc.c (read_pieced_value): Do big endian processing only if gdb_regnum is not -1. (write_pieced_value): Ditto. --- gdb/dwarf2loc.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 71adc89..6e461bc 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -1683,21 +1683,21 @@ read_pieced_value (struct value *v) { struct gdbarch *arch = get_frame_arch (frame); int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.regno); - int reg_offset = source_offset; - - if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG - && this_size < register_size (arch, gdb_regnum)) - { - /* Big-endian, and we want less than full size. */ - reg_offset = register_size (arch, gdb_regnum) - this_size; - /* We want the lower-order THIS_SIZE_BITS of the bytes - we extract from the register. */ - source_offset_bits += 8 * this_size - this_size_bits; - } if (gdb_regnum != -1) { int optim, unavail; + int reg_offset = source_offset; + + if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG + && this_size < register_size (arch, gdb_regnum)) + { + /* Big-endian, and we want less than full size. */ + reg_offset = register_size (arch, gdb_regnum) - this_size; + /* We want the lower-order THIS_SIZE_BITS of the bytes + we extract from the register. */ + source_offset_bits += 8 * this_size - this_size_bits; + } if (!get_frame_register_bytes (frame, gdb_regnum, reg_offset, this_size, buffer, @@ -1875,15 +1875,18 @@ write_pieced_value (struct value *to, struct value *from) { struct gdbarch *arch = get_frame_arch (frame); int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.regno); - int reg_offset = dest_offset; - - if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG - && this_size <= register_size (arch, gdb_regnum)) - /* Big-endian, and we want less than full size. */ - reg_offset = register_size (arch, gdb_regnum) - this_size; if (gdb_regnum != -1) { + int reg_offset = dest_offset; + + if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG + && this_size <= register_size (arch, gdb_regnum)) + { + /* Big-endian, and we want less than full size. */ + reg_offset = register_size (arch, gdb_regnum) - this_size; + } + if (need_bitwise) { int optim, unavail;