From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29373 invoked by alias); 25 Jan 2015 08:03:26 -0000 Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org Received: (qmail 22978 invoked by uid 89); 25 Jan 2015 08:02:56 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL,BAYES_00,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pd0-f175.google.com Received: from Unknown (HELO mail-pd0-f175.google.com) (209.85.192.175) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Sun, 25 Jan 2015 08:00:34 +0000 Received: by mail-pd0-f175.google.com with SMTP id fl12so6165209pdb.6 for ; Sat, 24 Jan 2015 23:59:01 -0800 (PST) X-Received: by 10.66.55.74 with SMTP id q10mr25111085pap.94.1422172741125; Sat, 24 Jan 2015 23:59:01 -0800 (PST) Received: from seba.sebabeach.org.gmail.com (173-13-178-53-sfba.hfc.comcastbusiness.net. [173.13.178.53]) by mx.google.com with ESMTPSA id ex11sm6670707pac.19.2015.01.24.23.58.59 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 24 Jan 2015 23:59:00 -0800 (PST) From: Doug Evans To: Jonathan Larmour Cc: gdb@sourceware.org Subject: Re: dwarf_block_to_fb_offset() and 64-bit host References: <54C48488.6040100@eCosCentric.com> Date: Sun, 25 Jan 2015 08:27:00 -0000 In-Reply-To: <54C48488.6040100@eCosCentric.com> (Jonathan Larmour's message of "Sun, 25 Jan 2015 05:52:08 +0000") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-IsSubscribed: yes X-SW-Source: 2015-01/txt/msg00072.txt.bz2 Jonathan Larmour writes: > Hi folks, > > I've been looking at a problem on a remote Cortex-M target, which notably > happens to have a somewhat atypical property of using an address space of > 0x9xxxxxxx - in other words, addresses will have the top bit set. > > When debugging, there is a problem with a GDB built for a 64-bit host, > versus one built for 32-bit, all from exactly the same source base. It > manifests with this sort of issue with a 64-bit hosted GDB: > > Breakpoint 2, fileio1_main (id=0, id@entry= access memory at address 0x9001917c>) > at /.../fatfs1.c:431 > > The cited address is perfectly valid and readable. Whereas on a 32-bit GDB: > Breakpoint 2, fileio1_main (id=0) at /.../fatfs1.c:431 > > I have tracked down where the 32-bit and 64-bit builds of GDB diverge in > behaviour and it's in dwarf2expr.c's dwarf_block_to_fb_offset(): > > int > dwarf_block_to_fb_offset (const gdb_byte *buf, const gdb_byte *buf_end, > CORE_ADDR *fb_offset_return) > { > int64_t fb_offset; > [snip] > buf++; > > buf = gdb_read_sleb128 (buf, buf_end, &fb_offset); > if (buf == NULL) > return 0; > *fb_offset_return = fb_offset; > if (buf != buf_end || fb_offset != (LONGEST) *fb_offset_return) > return 0; > > return 1; > } > > In the 32-bit (working) build, in one failing example, fb_offset ends up > as -28, whereas *fb_offset_return is 0xffffffe4 - this is because > CORE_ADDR is an *unsigned* 32-bit type (due to bfd_vma). But LONGEST is a > signed long long - 64-bits - so the comparison between fb_offset and > *fb_offset_return ends up comparing -28 and 4294967268. So 0 is returned. > > In the 64-bit (buggy) build, fb_offset is still -28 but *fb_offset_return > is 0xffffffffffffffe4 (CORE_ADDR now being an unsigned 64-bit type), which > when cast to LONGEST (which is signed) is still -28. Therefore 1 is > returned. This later results in read_frame_arg()'s call to > ops->read_variable_at_entry incorrectly believing there is a different > value of the variable on entry. > > I'm unsure about where the bug really lies. I'm not familiar enough with > Dwarf, but I have to wonder why there's the test for "fb_offset != > (LONGEST) *fb_offset_return" in the first place. > > Any help/advice from anyone with Dwarf experience would be welcome, thanks. Hi. It would not be unexpected if there are multiple bugs here. E.g., if the cited address is valid, why is there an error reading it? [and if gdb could successfully read it would it have noticed that the two values are the same and thus you'd get the same output as in the 32-bit case] Here's where fb_offset originates from: gdbtypes.h: union call_site_parameter_u { /* * DW_TAG_formal_parameter's DW_AT_location's DW_OP_regX as DWARF register number, for register passed parameters. */ int dwarf_reg; /* * Offset from the callee's frame base, for stack passed parameters. This equals offset from the caller's stack pointer. */ CORE_ADDR fb_offset; /* * Offset relative to the start of this PER_CU to DW_TAG_formal_parameter which is referenced by both caller and the callee. */ cu_offset param_offset; } u; I guess the first question is: Is an fb_offset of -28 valid? i.e., is a negative value valid? [Certainly a negative value is valid for DW_OP_fbreg. But is it valid in this context? Dunno off hand.] Also, I can imagine that the "fb_offset != (LONGEST) *fb_offset_return" test is to verify there's no loss in precision in the saved value. So while dwarf_block_to_fb_offset is returning 1 in the "buggy" case it seems to me that that could be the correct result. [Hence wondering if there's another bug.] I'm curious what would happen if you changed "CORE_ADDR fb_offset" to "LONGEST fb_offset" and updated all the affected pieces, including changing the signature of dwarf_block_to_fb_offset to int dwarf_block_to_fb_offset (const gdb_byte *buf, const gdb_byte *buf_end, LONGEST *fb_offset_return)