Reputation: 11598
I am currently reading about exploiting memory vulnerabilities under Linux and I found it hard to find any information on when the layout of stack frames is decided. In other words, is it something determined at the compile time, before the program's execution or are those built when a function is being called? Does the layout differ between operating systems?
Upvotes: 4
Views: 993
Reputation: 71586
It is a compiler choice at compiler time, if you use the same compiler with the same built choices on different operating systems for the same processor/target you may get the same types of results for stack frames or not.
Stack frames make it easier for the compiler developer to debug the code as well as others to read the code, it is debatable as to whether it costs more or not to use a stack frame. It also might make life easier on the debugger (software) as well, but you would have to be closely in sync with the compiler for that to work.
They are generally not required, cant imagine why a calling convention would ever care, it is simply an implementation thing, do I constantly have to keep track at every point in the function where things are relative to my changing the top of stack, or do I want to pre-compute all the stack I will need for the whole function, and consume it one time, then for the remainder of the function I can hardcode where everything is relative to that, making it easier to read and debug the code sometimes at the cost of another register, sometimes not depending on implementation.
Stack frames are a design choice by the compiler folks and is a compile time thing not a runtime thing. If yo use the same compiler with the same choices you can get the same layout across operating systems, use a different compiler on the same operating system or different operating systems and there are no guarantees the same layout is used or if both even use a stack frame.
Upvotes: 0
Reputation: 95420
I doubt you will generally or easily find an documented answer to how stack frames were designed. As others have observed, what gets documented is the result of that design process, often without a lot of associated rationale which I agree would be pretty interesting.
Each design of a stack frame layout comes from presumably people designing a compiler or a set of interoperable compilers for a particular processor architecture and maybe even for the particular OS. This will be influenced by what subroutine needs to access information from callers (arguments? lexical scopes?), what the instruction set does well (lots of registers? easy to push arguments?), strengths or weaknesses of the compilers, etc. Microsoft, as an example, did this design several times over decades, as their compilers and the x86 evolved; their conventions for the x86-32 are really different than they are for x86-64. You can guess at the rationale from the documented result and sometimes there are hints, but not always.
I can give you some ideas, having designed "stack frames" for my company's parallel programming language that runs on an x86.
My point is the rationale for stack frame design is driven by the machine architecture and the goal of the programming language it is supposed to support. Rationale such as the above doesn't appear in many documents, and yes, that makes it pretty hard to find.
Given a stack frame design, the compiler for a language then allocates space within the frame, for a particular subroutine being compiled.
Upvotes: 3
Reputation: 3368
There are several factors. On x86, there's a calling convention that defines how to call a function. I assume other architectures have similar things. The system library (e.g. glibc) can define additional conventions. But ultimately the compiler decides how it uses the stack - at least when it does not need to interface external libraries and needs to follow their stack-layout.
Upvotes: 2