x86_64 calling conventions and stack frames

Amittai Aviram amittai.aviram@yale.edu
Sun Dec 25 21:31:00 GMT 2011


On Dec 24, 2011, at 2:10 PM, Amittai Aviram wrote:

> On Dec 24, 2011, at 12:18 PM, Bob Plantz wrote:
> 
>> On 12/23/2011 11:37 PM, Amittai Aviram wrote:
>>> I am trying to make sense out of the executable code that GCC (4.4.3) is generating for an x86_64 machine running under Ubuntu Linux.  In particular, I don't understand how the code keeps track of stack frames.  In the old days, in 32-bit code, I am accustomed to seeing this as a "prologue" in just about every function:
>>> 
>>> push %ebp
>>> movl %esp, %ebp
>>> 
>>> Then, at the end of the function, there would either be
>>> 
>>> sub $xx, %esp   # Where xx is a number based on GCC's accounting.
>>> pop %ebp
>>> ret
>>> 
>>> or simply
>>> 
>>> leave
>>> ret
>>> 
>>> which accomplishes the same thing:
>>> - Set the Stack Pointer to the top of the current frame, just below the return address
>>> - Restore the old Frame Pointer value.
>>> 
>>> In 64-bit code, as I see it through an objdump disassembly, many functions do not follow this convention--they do not push %rbp and then save %rsp to %rbp, How does a debugger like GDB build a backtrace?
>> 
>> Are you looking at leaf functions? They are allowed to use the "red zone" as their stack frame, with rsp as the reference point. Since there are twice as many registers in 64-bit mode, you will find many fewer pushes and pops. Most arguments (the first six integer) are passed in registers and simply moved to the stack frame for safe keeping.
>> 
>> 
>> --Bob
> 
> 
> Thanks, Bob.  No, I want to get this information from a function that is neither a root nor a leaf, but an internal node of the call graph.  I would like to have a reliable way of finding out where the Stack Pointer is anywhere above the start of the stack frame for main, but below the actual top of the stack, and preferably as close to the top of the stack frame for main as possible.  I still haven't found a way to do this.  Again, I am wondering how people build backtrace routines for x86_64.  (The standard C/Unix library routine backtrace will not give me what I need, because it gives me the return addresses rather than stack frames.  As convention goes, the former addresses will be far lower than the latter.
> 


It looks as if I can probably use the symbol glibc symbol __libc_stack_end, assuming that I am linking to glibc (which I am doing):

extern  void * __libc_stack_end;

Thanks, all!


Amittai Aviram
PhD Student in Computer Science
Yale University
646 483 2639
amittai.aviram@yale.edu
http://www.amittai.com



More information about the Gcc-help mailing list