From patchwork Thu Oct 23 05:36:37 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Kamensky X-Patchwork-Id: 3332 Received: (qmail 29138 invoked by alias); 23 Oct 2014 05:37:01 -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 29120 invoked by uid 89); 23 Oct 2014 05:37:00 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f47.google.com Received: from mail-pa0-f47.google.com (HELO mail-pa0-f47.google.com) (209.85.220.47) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Thu, 23 Oct 2014 05:36:59 +0000 Received: by mail-pa0-f47.google.com with SMTP id kx10so413032pab.34 for ; Wed, 22 Oct 2014 22:36:57 -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; bh=vPdhtjNucW31qYvAanTr0luENBlOR0vAOaBPGDeQwiM=; b=IP4NycZUch2UW/ocOCmDgtolopAHeu9q2CFfllguMxBqdUYnNvJ6dHkUQvIazyjgjd CAtBHB0qX2GTgdn0TuhaaC7Jvywgpe+J9I08eCESVYOorkZO3TnylGXvgS6bI1ndkveF 0hDE4N+m4g/jdUoYRk5Lm8KIHozkMjPhzGG5M7z8H4DawZtSLJKxOLIOEw5bI0UgU+jN IVG0bKkcruz3UVdwnTidijW0ZVX3RkaN3IoDw+Ed+eweMAUQdlFt5SVBhEcknb4U8Nl7 /maNHPEUb/oqlyNY0Uo2YT05NePsU6a6ApXSjwgyxj3s6uT9Qd/B1wDufuU0cJfgrCyF xggw== X-Gm-Message-State: ALoCoQmAAG4QNafuejkgxgicF5RlD6oOwV8nwO7Zfz1dHA9RSmai3aGfkSidRpgECMOvKqz6FQVO X-Received: by 10.70.101.234 with SMTP id fj10mr2964081pdb.22.1414042617215; Wed, 22 Oct 2014 22:36:57 -0700 (PDT) Received: from kamensky-w530.hsd1.ca.comcast.net ([24.6.79.41]) by mx.google.com with ESMTPSA id g3sm619597pdh.33.2014.10.22.22.36.56 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 22 Oct 2014 22:36:56 -0700 (PDT) From: Victor Kamensky To: gdb-patches@sourceware.org, Yao Qi Cc: Andrew Pinski , victor.kamensky@linaro.org Subject: [PATCH V3] read_pieced_value do big endian processing only in case of valid gdb_regnum Date: Wed, 22 Oct 2014 22:36:37 -0700 Message-Id: <1414042597-30986-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 BE processing only if gdb_regnum is not -1. (write_pieced_value): Ditto. --- gdb/dwarf2loc.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index e347e59..d0ca35e 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -1684,21 +1684,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, @@ -1876,15 +1876,15 @@ 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;