This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/5625] [mips] exception unwinding creates invalid pointer on mips
- From: "wilson at specifixinc dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 5 Feb 2004 07:41:43 -0000
- Subject: [Bug libstdc++/5625] [mips] exception unwinding creates invalid pointer on mips
- References: <20020207120601.5625.emaste@sandvine.com>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- 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