From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 799 invoked by alias); 13 Jun 2006 16:45:56 -0000 Received: (qmail 791 invoked by uid 22791); 13 Jun 2006 16:45:55 -0000 X-Spam-Check-By: sourceware.org Received: from potter.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 13 Jun 2006 16:45:53 +0000 Received: (qmail 4154 invoked from network); 13 Jun 2006 16:45:51 -0000 Received: from unknown (HELO ?10.1.1.7?) (julian@127.0.0.2) by mail.codesourcery.com with ESMTPA; 13 Jun 2006 16:45:51 -0000 Message-ID: <448EEBB4.3090503@codesourcery.com> Date: Tue, 13 Jun 2006 17:23:00 -0000 From: Julian Brown User-Agent: Debian Thunderbird 1.0.7 (X11/20051017) MIME-Version: 1.0 To: Ian Lance Taylor CC: binutils@sourceware.org, GCC Patches , DJ Delorie Subject: Re: [PATCH, libiberty] Fix segfault in floatformat.c:get_field on 64-bit hosts References: <4489A779.2080101@codesourcery.com> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2006-06/txt/msg00211.txt.bz2 Ian Lance Taylor wrote: > Julian Brown writes: > > >>This patch fixes a problem with floatformat.c:get_field on 64-bit (on >>at least x86_64), when cross-assembling to arm-none-eabi. The line >>which reads: >> >> result = *(data + cur_byte) >> (-cur_bitshift); >> >>was executed with cur_byte = -1 (start + len == 0 and order == >>floatformat_little), which happily segfaulted (during printing of FP >>immediates). > > > I don't understand how start + len == 0 could ever be true. What was > calling the function? I note that put_field has the exact same > problem if start + len == 0. Sorry, I botched my explanation a bit. I should have said: (start + len) / FLOATFORMAT_CHAR_BIT == 0 which is true when e.g. extracting the sign bit of a single-precision IEEE float -- in that case, start will be 0 and len will be 1 (with big-endian bit numbering used elsewhere in floatformat.c). The function is called by opcodes/arm-dis.c to print out the ARM Neon "quarter-precision" floating-point immediates. >>! return result & ((2 << (total_len - 1)) - 1); > > > Why do you need to do this? And if you do need to do it, why use 2? > Why not ((1 << total_len) - 1)? It was to attempt to maintain the original semantics of the function, as I understood them: the result is truncated to total_len after being built up <=8 bits at a time (though looking again, that might not have been the original intention at all, or at least not at that level of granularity... I suspect that bit should be removed). The reason for using 2 << ... rather than 1 << .. was so that, e.g., the total_len == 32 case works properly. AIUI, shift amounts must be strictly less than the width of the operand, and the total_len==0 case isn't interesting. But that's irrelevant if I'm getting rid of that bit anyway :-) So, I'll remove that bit and do the following... > Please compile the file as a standalone program with -DIEEE_DEBUG to > make sure those tests still work. Ideally on both a big- and > little-endian system, if possible. Thanks, Julian