From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23556 invoked by alias); 9 Jan 2009 13:12:51 -0000 Received: (qmail 23547 invoked by uid 22791); 9 Jan 2009 13:12:50 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 09 Jan 2009 13:12:38 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 2DF8F2A9669; Fri, 9 Jan 2009 08:12:36 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id j-bycDn4z0qH; Fri, 9 Jan 2009 08:12:36 -0500 (EST) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 9B79E2A965C; Fri, 9 Jan 2009 08:12:34 -0500 (EST) Received: by joel.gnat.com (Postfix, from userid 1000) id A7222E7ACD; Fri, 9 Jan 2009 17:12:27 +0400 (RET) Date: Fri, 09 Jan 2009 13:12:00 -0000 From: Joel Brobecker To: Mark Kettenis Cc: gdb-patches@sourceware.org Subject: Re: [RFC] convert a host address to a string Message-ID: <20090109131227.GL24105@adacore.com> References: <20090107121908.GH1751@adacore.com> <200901071616.n07GGXtu029119@brahms.sibelius.xs4all.nl> <20090108101911.GQ3664@adacore.com> <200901081326.n08DQEgY002357@brahms.sibelius.xs4all.nl> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="LyciRD1jyfeSSjG0" Content-Disposition: inline In-Reply-To: <200901081326.n08DQEgY002357@brahms.sibelius.xs4all.nl> User-Agent: Mutt/1.4.2.2i 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: 2009-01/txt/msg00191.txt.bz2 --LyciRD1jyfeSSjG0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 1317 > > 3. Work through uintptr_t. > > > > #ifdef PRINTF_HAS_LONG_LONG > > fprintf (buf, "0x%llx", (unsigned long long) (uintptr_t) address); > > #else > > fprintf (buf, "0x%lx", (unsigned long) (uintptr_t) address); > > #endif > > This wouldn't be the first place where we'd use a double cast in > connection with intptr_t/uintptr_t. So I'd say that while this is a > bit ugly, it's certainly acceptable. It's by far the simplest way to > fix things. Here is a new patch implementing this approach. As I told Kai, it's probably not going to work for x86_64/XP, but it works for x86_64/Vista (I think Kai agreed to take on the job of improving this approach to work on XP as well :-). 2009-01-09 Joel Brobecker * utils.c (host_address_to_string): Cast the address to uintptr_t first to avoid a possible compilation warning about casting to an integer of the wrong size. Then format the address using unsigned long long if supported by printf. Otherwise, fallback on using usingned long, hoping that long is large enough to hold an address. Tested on x86-linux. I also verified that it still builds on x86_64 Vista, as well as x86/Windows XP (on XP, PRINTF_HAS_LONG_LONG is undefined). -- Joel --LyciRD1jyfeSSjG0 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="host_addr_to_str.diff" Content-length: 2332 diff --git a/gdb/utils.c b/gdb/utils.c index 9e2dfd7..dd606a2 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -3071,10 +3071,44 @@ host_address_to_string (const void *addr) { char *str = get_cell (); - /* We could use the %p conversion specifier to sprintf if we had any - way of knowing whether this host supports it. But the following - should work on the Alpha and on 32 bit machines. */ - sprintf (str, "0x%lx", (unsigned long) addr); + /* We do not use the %p conversion specifier, because the resulting + image can vary from implementation to implementation. For instance, + some implementations format the pointer value with a leading "0x" + whereas others don't (Solaris, for instance). Also, it is unspecified + whether the alphabetical digits are printed using uppercase letters + or not (in GDB, we want lowercase). + + So we use the %x type instead. This, however, introduces + a couple of issues: + + 1. The %x type expects an integer value, not a pointer. + So we first need to cast our pointer to an integer type + whose size is identical to the size of our pointer. + We use uintptr_t for that. + + 2. The %x type alone expects and int, which is not always + large enough to hold an address. Usually, type "long" + has the same size as pointers, but certain ABIs define + the size of pointers to be larger than the size of long + (64bit Windows is one such example). + + So, to be certain to have a type that's large enough + to hold an address, we need to use "long long". But + the trick is that not all printf implementations support + the "ll" modifier. On those platforms where the "ll" + modifier is not available, we'll assume that type "long" + is large enough to contain an address. + + To make sure that the type we pass to sprintf matches + the type we specified in our expression, we perform + a second cast to "unsigned long long" if we used "%llx", + or "unsigned long" if we used "%lx". */ + +#ifdef PRINTF_HAS_LONG_LONG + sprintf (str, "0x%llx", (unsigned long long) (uintptr_t) addr); +#else + sprintf (str, "0x%lx", (unsigned long) (uintptr_t) addr); +#endif return str; } --LyciRD1jyfeSSjG0--