From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5938 invoked by alias); 5 Feb 2004 07:41:44 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 5924 invoked by alias); 5 Feb 2004 07:41:43 -0000 Date: Thu, 05 Feb 2004 07:41:00 -0000 Message-ID: <20040205074143.5922.qmail@sources.redhat.com> From: "wilson at specifixinc dot com" To: gcc-bugs@gcc.gnu.org In-Reply-To: <20020207120601.5625.emaste@sandvine.com> References: <20020207120601.5625.emaste@sandvine.com> Reply-To: gcc-bugzilla@gcc.gnu.org Subject: [Bug libstdc++/5625] [mips] exception unwinding creates invalid pointer on mips X-Bugzilla-Reason: CC X-SW-Source: 2004-02/txt/msg00596.txt.bz2 List-Id: ------- Additional Comments From wilson at specifixinc dot com 2004-02-05 07:41 ------- Subject: Re: [mips] exception unwinding creates invalid pointer on mips On Wed, 2004-02-04 at 22:25, cgd at broadcom dot com wrote: > I'm a bit concerned about this comment, because SImode values in > registers on MIPS should be in their properly sign-extended forms. The MIPS backend knows that SImode values need to be sign-extended, and it does take care of this. However, the EH code is doing something very special, similar to what longjmp does. Except instead of reading values from a context saved by a setjmp, we are computing values at runtime, and then storing them into a context, which later gets stuffed into registers. When we store values into the context, if the pointer size does not equal the register size, then we have a problem. The code currently assumes that pointers extend unsigned, which is a reasonable assumption in general, but breaks the MIPS convention of requiring SImode values to be sign-extended. There are actually 3 options here, signed-extension, unsigned-extension, and pointer swizzling (IA-64). We need some way to get a machine dependent conversion of a pointer to a possibly larger integer which represents a register, an operation which is not part of the C language. Gcc does have a convention already that mostly solves this problem. You define Pmode to the register size, POINTER_SIZE to the pointer size, and POINTERS_EXTEND_UNSIGNED to indicate how to convert pointers. This is the obvious approach, except that changing the MIPS backend looks like a lot of work. I was looking at other 64-bit targets like Alpha and IA-64, but it occurs to me that MIPS is somewhat different, in that we have a complete set of both 32-bit and 64-bit operations (or at least we can pretend that we do have them all), and thus maybe an SImode Pmode makes more sense for 64-bit ILP32 MIPS than it does for other targets. If we don't modify the mips backend, then another possible solution would be to modify the convert_memory_address function so that we can specify conversions from ptr_mode to word_mode. Or alternatively create a specialized version of the function that only does conversions from ptr_mode to word_mode, for use in the EH code. This specialized version could be a lot simpler than convert_memory_address, as it would not have to handle arbitrary addresses, it only needs to handle MEM and REG I think. Actually, looking at this again, I think all we need to do is call convert_modes. I think I gave up too early when I looked at this the first time. I will have to revisit this option. I suppose another way to solve this is to modify the code that saves/restores the context. When we store a pointer into the context, we could mark that we stored a pointer value, and then when we load the context into registers, we do a pointer sized load instead of a word sized load. I am not sure whether this can actually work, because contexts are created in different ways in different places. There is also the problem that this requires changes to the standard Unwind API, and there are already alternative implementations (HPUX libunwind, David Mosberger linux libunwind) that we would be incompatible with if we go down this route, so this seems to be a very poor option. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=5625