From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6615 invoked by alias); 27 Apr 2007 21:10:30 -0000 Received: (qmail 6606 invoked by uid 22791); 27 Apr 2007 21:10:29 -0000 X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 27 Apr 2007 22:10:26 +0100 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.1/8.13.1) with ESMTP id l3RLAOAH032215 for ; Fri, 27 Apr 2007 17:10:24 -0400 Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [10.11.255.20]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l3RLAJHE013794 for ; Fri, 27 Apr 2007 17:10:24 -0400 Received: from ironwood.lan (vpn-14-75.rdu.redhat.com [10.11.14.75]) by pobox.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l3RLAIeY030617 for ; Fri, 27 Apr 2007 17:10:18 -0400 Date: Fri, 27 Apr 2007 21:30:00 -0000 From: Kevin Buettner To: gdb-patches@sources.redhat.com Subject: Re: [RFC] dwarf2_read_address(): sign extend as appropriate Message-ID: <20070427141018.1430725b@ironwood.lan> In-Reply-To: <20070424181308.GA26543@caradoc.them.org> References: <20070420163312.56701614@ironwood.lan> <200704231505.l3NF5KV5025451@d12av02.megacenter.de.ibm.com> <20070423094900.15a047d2@ironwood.lan> <20070423165646.GA15110@caradoc.them.org> <20070423140642.3920579e@ironwood.lan> <20070424181308.GA26543@caradoc.them.org> X-Mailer: Sylpheed-Claws 2.6.0 (GTK+ 2.10.4; i386-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-IsSubscribed: yes 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 X-SW-Source: 2007-04/txt/msg00362.txt.bz2 I decided to give the `value_as_address' approach a try. It worked as expected when I tried running it against a MIPS target. Comments? * dwarf2expr.c (unsigned_address_type): Add forward declaration. (dwarf2_read_address): Sign extend return address as required by target architecture. Index: dwarf2expr.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2expr.c,v retrieving revision 1.19 diff -u -p -r1.19 dwarf2expr.c --- dwarf2expr.c 9 Jan 2007 17:58:50 -0000 1.19 +++ dwarf2expr.c 27 Apr 2007 21:07:10 -0000 @@ -33,6 +33,7 @@ static void execute_stack_op (struct dwarf_expr_context *, gdb_byte *, gdb_byte *); +static struct type *unsigned_address_type (void); /* Create a new context for the expression evaluator. */ @@ -205,9 +206,42 @@ dwarf2_read_address (gdb_byte *buf, gdb_ error (_("dwarf2_read_address: Corrupted DWARF expression.")); *bytes_read = TARGET_ADDR_BIT / TARGET_CHAR_BIT; - /* NOTE: cagney/2003-05-22: This extract is assuming that a DWARF 2 - address is always unsigned. That may or may not be true. */ - result = extract_unsigned_integer (buf, TARGET_ADDR_BIT / TARGET_CHAR_BIT); + + /* For most architectures, calling extract_unsigned_integer() alone + is sufficient for extracting an address. However, some + architectures (e.g. MIPS) use signed addresses and using + extract_unsigned_integer() will not produce a correct + result. Turning the unsigned integer into a value and then + decomposing that value as an address will cause + gdbarch_integer_to_address() to be invoked for those + architectures which require it. Thus, using value_as_address() + will produce the correct result for both types of architectures. + + One concern regarding the use of values for this purpose is + efficiency. Obviously, these extra calls will take more time to + execute and creating a value takes more space, space which will + have to be garbage collected at a later time. If constructing + and then decomposing a value for this purpose proves to be too + inefficient, then gdbarch_integer_to_address() can be called + directly. This could be done as follows: + + if (gdbarch_integer_to_address_p (current_gdbarch)) + result = gdbarch_integer_to_address (current_gdbarch, + unsigned_address_type (), buf); + else + result = extract_unsigned_integer + (buf, TARGET_ADDR_BIT / TARGET_CHAR_BIT); + + The use of `unsigned_address_type' in the code below (or in the + suggested replacement code above) refers to the type of buf and + has no bearing on the signedness of the address being returned. */ + + result = value_as_address (value_from_longest + (unsigned_address_type (), + extract_unsigned_integer + (buf, + TARGET_ADDR_BIT / TARGET_CHAR_BIT))); + return result; }