Alfred Huang's Weblog

Disclaimer: Whatever I suggested in my blog is what I would do, it does not necessarily mean the only way to do it.


« A look into the... | Main | On Studio and Gcc... »
Monday Mar 13, 2006

The humble Frame Pointer

Most architecture has a dedicated register called the frame or base pointer, in the case of 32-bit x86 platform, it is the %ebp register, for 64-bit amd64 it is the %rbp register.

The main purpose of base pointer (BP) is to allow access to the stack variables. Since the stack grows downward on x86, one can access the function argument by using (BP+offset) memory address mode, while using (BP-offset) to access the stack locals. Before the base pointer can be used, the compiler needs to set it up in the function prologue. The most common form of BP set up code at the very beginning of an amd64 32-bit mode function is

       pushl %ebp
       movl  %esp, %ebp

The first instruction saves the old BP of the previous stack frame, which later can be restored in the function epilogue before returning to the caller. The second instruction setup the new BP of the function by making it the same as the current stack pointer. So after the function prologue, we have

       | ...               |
       ---------------------
       | possible argumens |     previous stack frame
      -----------------------
       | return address    |     return address to caller
       --------------------- 
       | old BP            |     BP of caller
       --------------------- <-- BP of this frame
       | possible locals...| 
       ---------------------

In a sense the above BP setup instruction sequence is sacred, many applications use the sequence to "unwind" the stack, literally speaking that means to backtrace the stack frames from the current frame to its caller and so forth. These applications look for the existence of this sequence in the function prologue to find the saved old BP, so as to get to the previous frame. The kind of applications doing this may be a debugger, code analyzer, multi-threaded function cleanup handler, even C++ exception handling code. If the above sequence is not detected, the stack backtrace can not carried on and undefined result including core dump may occur.

Of course the world is never that nice to always leave the humble BP in place so as to allow all stack backtrace to take place. The compiler sometimes believes the BP is not really needed, it can still access the function arguments and locals using the stack pointer, the BP setup code and subsequent restore may thus be optimized away. Moreover on platform like 32-bit x86, where register is always in shortage, the availability of %ebp as a general purpose register is a blessing. Hence the BP setup code sometimes may not show up and application may break. All compilers usually have a way to turn off this form of optimization.

Sun Studio 10/11 compilers do not take the users to dangerous zone with this kind of optimization by default. For safety sake, one has to explicitly ask for it by using -xregs=frameptr option. Admittently, -xregs=frameptr is not very intuitive, but it means what it says, use BP as a general purpose register, thereby BP is no longer a dedicated base pointer and the BP setup code may not be generated.

Some architecture nowadays have a new concept of unwind information section. The compiler generates information about the stack status during compile time and records them in special sections. Users of such section may obtain information on the displacement to the previous stack frame at a certain instance. This eliminates the need to have the "sacred" BP setup code in the function prologue. AMD64 ABI defines an equivalence of this kind of unwind information section, namely the .eh_frame section.

Hence Sun Studio under 64-bit mode does not really need to have the BP setup code and the users are free to invoke -xregs=frameptr at any time. Studio and Solaris C++ exception handling library is intelligent enough to handle stack unwinding based on what it finds, it obtains the previous stack frame if the .eh_frame section is found, otherwise the existence of the BP setup code is assumed. But for 32-bit mode x86, where .eh_frame is not defined in the ABI, the existence of BP setup code is a must for any stack unwinding to take place.

Comments:

Post a Comment:
  • HTML Syntax: NOT allowed

Today's Page Hits: 7