public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* x86_64 calling conventions and stack frames
@ 2011-12-24 11:02 Amittai Aviram
  2011-12-24 19:10 ` Bob Plantz
  2011-12-27 15:16 ` Ian Lance Taylor
  0 siblings, 2 replies; 5+ messages in thread
From: Amittai Aviram @ 2011-12-24 11:02 UTC (permalink / raw)
  To: gcc-help

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?

My real goal here to is to try to figure out a reasonable address to consider as the top (highest address) of the user stack when execution reaches the start of a function further into the program, where perhaps the Stack Pointer has moved down.  I had at first thought that I could use the old backtrace method: chasing saved Frame Pointer values until the value saved is 0--then, the next one after that can count as the highest practical value.  Now, I don't know how to get the equivalent address in 64-bit code.

Thanks.


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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: x86_64 calling conventions and stack frames
  2011-12-24 11:02 x86_64 calling conventions and stack frames Amittai Aviram
@ 2011-12-24 19:10 ` Bob Plantz
  2011-12-25  0:50   ` Amittai Aviram
  2011-12-27 15:16 ` Ian Lance Taylor
  1 sibling, 1 reply; 5+ messages in thread
From: Bob Plantz @ 2011-12-24 19:10 UTC (permalink / raw)
  To: Amittai Aviram; +Cc: gcc-help

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.

> x86-64
>
> My real goal here to is to try to figure out a reasonable address to consider as the top (highest address) of the user stack when execution reaches the start of a function further into the program, where perhaps the Stack Pointer has moved down.  I had at first thought that I could use the old backtrace method: chasing saved Frame Pointer values until the value saved is 0--then, the next one after that can count as the highest practical value.  Now, I don't know how to get the equivalent address in 64-bit code.

If you don't have it, you should get a copy of "System V Application 
Binary Interface AMD64 Architecture Processor Supplement." It was 
available at www.x86-64.org, but I can't seem to connect to them right 
now. The latest version I have is 0.99 (Dec. 7, 2007). It describes the 
red zone, etc.

--Bob

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: x86_64 calling conventions and stack frames
  2011-12-24 19:10 ` Bob Plantz
@ 2011-12-25  0:50   ` Amittai Aviram
  2011-12-25 21:31     ` Amittai Aviram
  0 siblings, 1 reply; 5+ messages in thread
From: Amittai Aviram @ 2011-12-25  0:50 UTC (permalink / raw)
  To: plantz; +Cc: gcc-help

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.
> 
>> x86-64
>> 
>> My real goal here to is to try to figure out a reasonable address to consider as the top (highest address) of the user stack when execution reaches the start of a function further into the program, where perhaps the Stack Pointer has moved down.  I had at first thought that I could use the old backtrace method: chasing saved Frame Pointer values until the value saved is 0--then, the next one after that can count as the highest practical value.  Now, I don't know how to get the equivalent address in 64-bit code.
> 
> If you don't have it, you should get a copy of "System V Application Binary Interface AMD64 Architecture Processor Supplement." It was available at www.x86-64.org, but I can't seem to connect to them right now. The latest version I have is 0.99 (Dec. 7, 2007). It describes the red zone, etc.
> 
> --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.

I have not read that document, and I am having the same trouble that you had with the x86-64.org link, but I've managed to find a copy of the document at 

http://math-atlas.sourceforge.net/devel/assembly/abi_sysV_amd64.pdf

That draft is dated 2005.  Do you happen to know whether that's sufficiently current?

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: x86_64 calling conventions and stack frames
  2011-12-25  0:50   ` Amittai Aviram
@ 2011-12-25 21:31     ` Amittai Aviram
  0 siblings, 0 replies; 5+ messages in thread
From: Amittai Aviram @ 2011-12-25 21:31 UTC (permalink / raw)
  To: Amittai Aviram; +Cc: plantz, gcc-help

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: x86_64 calling conventions and stack frames
  2011-12-24 11:02 x86_64 calling conventions and stack frames Amittai Aviram
  2011-12-24 19:10 ` Bob Plantz
@ 2011-12-27 15:16 ` Ian Lance Taylor
  1 sibling, 0 replies; 5+ messages in thread
From: Ian Lance Taylor @ 2011-12-27 15:16 UTC (permalink / raw)
  To: Amittai Aviram; +Cc: gcc-help

Amittai Aviram <amittai.aviram@yale.edu> writes:

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

On x86_64 gcc will by default generate unwind tables which can be used
at runtime to unwind the stack.  These unwind tables are stored in the
.eh_frame section.  The format is described in the x86_64 ELF processor
supplement or at http://www.airs.com/blog/archives/460 .

As of gcc 4.6 gcc defaults to this behaviour on i386 as well.

You can change it by using -fno-omit-frame-pointer.

Ian

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2011-12-27 15:10 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-24 11:02 x86_64 calling conventions and stack frames Amittai Aviram
2011-12-24 19:10 ` Bob Plantz
2011-12-25  0:50   ` Amittai Aviram
2011-12-25 21:31     ` Amittai Aviram
2011-12-27 15:16 ` Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).