This is the mail archive of the
mailing list for the GCC project.
Re: alloca attribute?
Perry Smith writes:
> On Nov 29, 2006, at 8:24 AM, Andrew Haley wrote:
> > Perry Smith writes:
> >> On Nov 29, 2006, at 4:19 AM, Andrew Haley wrote:
> >>> Perry Smith writes:
> >> No, I did not. I thought it would be too big a task and I'm
> >> willing to put a try/catch after the stack has been changed so the
> >> unwind does not need to go through this. This may be naive. (See
> >> more below).
> > You'll need unwinder data, sooner or later. But let's leave it for
> > later, it's not strictly relevant to what you need now.
> >> But in optimized code, the compiler does not load r1 with r1(0).
> >> It assumes that r1 has not changed, and it knows the size of the
> >> stack frame, it just adds the size of the stack frame to r1. This
> >> will be the same address if r1 has not been changed.
> > Right.
> >> It seems like (but I may be wrong), even with the DWARF unwinder
> >> information, the compiler will still produce the code that adds the
> >> size of the stack from to r1 to get r1 to point to the previous
> >> stack frame instead of loading r1 with r1 (0).
> > Sure, but why would it matter? Your newStack routine should do
> > something like
> > newStack:
> > save caller registers somewhere
> > load new stack and frame pointer
> > call <foo> -- whatever it is you want to run on the new stack
> > restore caller registers, including stack and frame pointer
> > return
> > so it should not metter how the caller of newStack uses its stack
> > frame or what foo does. As long as you conform to the ABI you'll be
> > OK.
> Ahh... I think I see your confusion. newStack does not call <foo>.
> I could do that and it would probably be safer, easier. But
> sometimes newStack would need to call foo(a) and other times it
> would need to call foo(a, b), etc. I thought about using varargs
> so that any foo that is called must take a varargs argument. That
> approach, obviously, is doable but imposes several restriction.
> But then I hit upon this other idea (which may suck). newStack
> simply mucks with the stack and returns back to testit (the routine
> that calls newStack).
You're right. It sucks. :-)
> I wish I could include some graphics but I'll try to describe it
> with words.
No, you've explained it perfectly well, but trust me here: it's a
really bad idea. gcc can eliminate the stack pointer to the frame
pointer, as you have discovered. gcc can also save a pointer to a
local area on the stack, and that can be of indeterminate size.
So gcc might do this
int a = 2;
p = &a; // allocated on the stack
*p = 3;
And a, being on the new stack, would now be different from *p, which
still points to the old stack. It can't possibly work.