Re: alloca attribute?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On Nov 29, 2006, at 4:19 AM, Andrew Haley wrote:

Perry Smith writes:
I wrote a class that switches the stack to a new area.  This is for
the power PC.

In the text below, I'll use main, testit, and newStack.  main is the
main program, testit is a function that main calls, and newStack is
the method that switches the stack to the new space.  main calls
testit which calls s.newStack.  (s is an instance of the class that
switches the stack).

The purpose of separating main and testit is so I can verify that
returning from testit works properly.

newStack gets the current value of r1 (the stack pointer) and copies
the last two stack frames (which would be the stack frame for testit
and newStack) to the top of some allocated memory.  It alters r1(0)
(the previous stack value for newStack) in the new memory to point to
the address of testit's new stack frame.  It sets r1 up to the base
of this new area and returns.

OK, before we go any further.  Did you write and test DWARF unwinder
information for newStack?

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).

With g++ and no optimization, this works.  When newStack returns,
it consumes its stack frame in the new memory leaving only testit's
new stack frame and r1 pointing to the base of the new stack from
for testit.  When testit returns, it loads r1 with r1(0) and
returns.  This properly puts r1 back to main's stack frame.

If I put -O3, then at the return of testit, instead of loading r1
with r1(0), just adds in the size of the stack frame (and assumes
that r1 has not been munged with).  I presume this is faster.  I
know that xlc does the same thing.  As a result, when we return
back to main, the stack pointer is off in the weeds somewhere.

I get the feeling I'm not understanding something here.  As long as
newStack is correct and handles all registers according to the ABI,
there shouldn't be any trouble.

I'm sure you understand this better than I do. Can you point me to the info
needed for the DWARF unwinder you mention above?  That may educate me
more.

It still seems I am going to have problems so I will try and repeat the symptom:

The code generated to return from a function can have two forms. Logically, it is a three step process. Pick up the return address which is located at r1(8) (assuming a 32 bit system) into a register (like r0), replace r1 with r1(0) which moves r1 to
point to the previous stack frame, and then branch to what was at r1(8).

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.

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).

Am I making sense?

Perry Smith ( pedz@xxxxxxxxxxxxxxxx )
Ease Software, Inc. ( http://www.easesoftware.com )

Low cost SATA Disk Systems for IBMs p5, pSeries, and RS/6000 AIX systems



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux