Does every function in a Windows GUI application need to use stdcall? - c

From what I understand, the caller and the callee both need to have the same calling convention. Otherwise, the stack might be corrupted.
WinMain is declared with __stdcall and calls all the functions I've defined. Does this mean all the functions I define should use the stdcall calling convention?
I've tried not using __stdcall and nothing bad happened. I have also seen well-known GUI libraries supporting Windows don't use stdcall. Why is the stack not corrupting?

WinMain is declared with __stdcall and calls all the functions I've defined. Does this mean all the functions I define should use the stdcall calling convention?
No. Calling conventions are handled on a per-function-call basis, right at the call site. The convention dictates how the caller and callee manage the call stack - how parameters are passed, in what order, who cleans up the stack, etc. As long as the caller and callee agree to use the same calling convention on each individual function call, it is perfectly safe for a stdcall function to call a function that uses a different convention, like cdecl, and vice versa. A function's calling convention applies only when:
the function is being entered by a new caller.
the function is returning back to that caller.
the function is accessing its own parameters.
Outside of that, what a function does internally has nothing to with its own calling convention.
For example, lets say that WinMain(), a stdcall function, wants to call a cdecl function.
It does not matter at all that WinMain() is itself a stdcall function. While code execution is inside of WinMain(), it can do whatever it wants. WinMain()'s stdcall convention is applied only upon entry and exit of WinMain() itself. That is the contract WinMain() has with ITS caller.
What matters is that WinMain() must follow the rules of cdecl when setting up the call stack for a cdecl function that it is about to call into, and cleaning up the call stack when that function returns back to WinMain().
The same goes for any function call of any calling convention.
I've tried not using __stdcall and nothing bad happened. I have also seen well-known GUI libraries supporting Windows don't use stdcall. Why is the stack not corrupting?
Because the call stack is being managed correctly at every function call and return, so there is no unbalanced cleanup to corrupt the stack.

Related

Linux Kernel should I use asmlinkage for a function that implements a system call?

I am trying to implement a new syscall in linux kernel, so I wrote:
asmlinkage int my_func(void) {
return my_func_internal();
}
my question, should I define my_func_internal as asmlinkage or not?
in other words, should I write A or B?
A) asmlinkage int my_func_internal(void) {return 1;}
B) int my_func_internal(void) {return 1;}
I would like some explanation too
Note: I have added my_func to syscalls.h should I add the internal one too (probably the answer is no)
It doesn't matter (for correctness) what calling convention you use for functions that aren't called directly by hand-written asm. (Which syscall implementation functions might be on some architectures, that's why they should be asmlinkage.) As long as all callers can see a prototype that matches the definition, it will work.
If asmlinkinkage is a different calling convention from the default one (e.g. on i386, asmlinkage means to use stack args, overriding the -mregparm=3 build option that makes internal functions use register args), the compiler will have to emit a definition for my_func that handles the difference if it calls a function that isn't asmlinkage. Or simply inline my_func_internal() into it.
If they use the same calling convention, and the compiler chooses not to inline, it could just do an optimized tailcall to my_func_internal, e.g. on x86 jmp my_func_internal. So there's a possible efficiency advantage to using the same calling convention if there's a possibility of an optimized tailcall. Otherwise don't; asmlinkage makes the calling convention less efficient on i386.
(IIRC, asmlinkage has no effect on x86-64 and most other modern ISAs with register-args calling conventions; the default calling convention on x86 is already good so the kernel doesn't need to override it with -mregparm=3 like it does on i386.)
In your example where there are no args, there's no difference.
BTW, the usual naming convention for the function name is sys_foo to implement a system-call called foo. i.e. the function that will get called when user-space passes __NR_foo as the call number.
Note: I have added my_func to syscalls.h should I add the internal one too (probably the answer is no)
Of course not, unless my_func_internal implements a different system call that you want user-space to be able to call directly.

Call MASM function in StdCall convention [duplicate]

I'm programming for Windows in assembly in NASM, and i found this in the code:
extern _ExitProcess#4
;Rest of code...
; ...
call _ExitProcess#4
What does the #4 mean in the declaration and call of a winapi library function?
The winapi uses the __stdcall calling convention. The caller pushes all the arguments on the stack from right to left, the callee pops them again to cleanup the stack, typically with a RET n instruction.
It is the antipode of the __cdecl calling convention, the common default in C and C++ code where the caller cleans up the stack, typically with an ADD ESP,n instruction after the CALL. The advantage of __stdcall is that it is generates more compact code, just one cleanup instruction in the called function instead of many for each call to the function. But one big disadvantage: it is dangerous.
The danger lurks in the code that calls the function having been compiled with an out-dated declaration of the function. Typical when the function was changed by adding an argument for example. This ends very poorly, beyond the function trying to use an argument that is not available, the new function pops too many arguments off the stack. This imbalances the stack, causing not just the callee to fail but the caller as well. Extremely hard to diagnose.
So they did something about that, they decorated the name of the function. First with a leading _underscore, as is done for __cdecl functions. And appended #n, the value of n is the operand of the RET instruction at the end of the function. Or in other words, the number of bytes taken by the arguments on the stack.
This provides a linker diagnostic when there's a mismatch, a change in a foo(int) function to foo(int, int) for example generates the name _foo#8. The calling code not yet recompiled will look for a _foo#4 function. The linker fails, it cannot find that symbol. Disaster avoided.
The name decoration scheme for C is documented at Format of a C Decorated Name. A decorated name containing a # character is used for the __stdcall calling convention:
__stdcall: Leading underscore (_) and a trailing at sign (#) followed by a number representing the number of bytes in the parameter list
Tools like Dependency Walker are capable of displaying both decorated and undecorated names.
Unofficial documentation can be found here: Name Decoration
It's a name decoration specifying the total size of the function's arguments:
The name is followed by the at sign (#) followed by the number of bytes (in decimal) in the argument list.
(source)

Is it safe to invoke a C function with more parameters than it expects?

I was reading on wikipedia about the cdecl calling convention. Since the parameters are pushed on the stack in reverse order, I believe it is safe to call a C function with more parameters than it expects.
Am I right or did I miss something?
Note: I am not talking about variadic functions.
I just had a quick look into ISO/IEC 9899 (a.k.a. C99): There's no word about calling conventions anywhere, thus (as suggested in the comments) you should clearly not do this. Even if it might work on a certain architecture, a certain operating system, and a certain version of a certain compiler, there is absolutely no guarantee that it will still work when only one of those parameters changes.
You are making one big wrong assumption: The so-called C calling convention is not contractual for C.
While old C compilers were forced to use such a calling convention (even if it was suboptimal), due to there being no function prototypes, modern compilers can (and are allowed to) use more efficient callee-clean calling conventions for all but old-style and vararg functions. Most compilers have a switch to select the standard calling convention used.
It is not!!!
This code causes a segmentation fault:
#include <stdio.h>
#define stdcall __attribute__((stdcall))
stdcall void func(int param1, int param2)
{
printf("%d, %d\n", param1, param2);
}
int main()
{
void(*f)(int, int, int) = func;
f(66, 67, 666);
f(1, 2, 3);
return 0;
}
This is just an elaboration to what other people have pointed out about calling conventions. I believe a POC helps making a point.
Yes, it is safe, partially for the reason you gave (params pushed in reverse order), and also partially due to the calling convention.
C Calling Convention
The C calling convention is that the Caller cleans up parameters.
(the alternative is that the Callee cleans up).
Because the caller knows how many params it pushed, it will know how many to properly clean up, regardless of how many params the Callee used or expected.
Pushing args in reverse order
When parameters are pushed onto the stack in reverse order, the 1st parameter gets pushed on last. Regardless of how many params were pushed, the Callee always knows where to find param #1, at the top of the stack. (and also param #2, #3, etc).
If the stack convention were reversed, param 1 would be put on the stack first, and could be "buried" by an arbitrary number of subsequent parameters; the Callee would not know how far into the stack to look.

Who is responsible for cleanup?

I wish to know which one is responsible for cleanup of the stack
Suppose you have a function fun lets say like this:
var = fun(int x, int y, float z, char x);
when fun will get called it will go into the stack along with the parameters then when the function returns who is responsible for cleanup of the stack is it the function it self or the "var" which will hold the return value.
One more thing, can anyone explain the concepts of calling conventions?
You referred to the answer yourself: calling conventions.
A calling convention is similar to a contract. It decides the following things:
Who is responsible to cleanup the parameters.
How and in which order the parameters are passed to the called function.
Where the return value is stored.
There are many different calling conventions, depending on the platform and the programming environment. Two common calling conventions on the x86 platforms are:
stdcall
The parameters are passed onto the stack from right to left. The called function cleans up the stack.
cdecl
The parameters are passed onto the stack from right to left. The calling function cleans up the stack.
In both cases the return value is in the EAX register (or ST0 for floating point values)
Many programming languages for the x86 platform allow to specify the calling convention, for example:
Delphi
function MyFunc(x: Integer): Integer; stdcall;
Microsoft C/C++
int __stdcall myFunc(int x)
Some usage notes:
When creating a simple application it's rarely necessary to change or to know about the calling convention, but there are two typical cases where you need to concern yourself with calling conventions:
When calling external libraries, Win32 API for example: You have to use compatible calling conventions, otherwise the stack might get corrupted.
When creating inline assembler code: You have to know in which registers and where on the stack you find the variables.
For further details I recommend these Wikipedia articles:
Calling convention
x86 calling conventions
calling convention refers to who is doing the cleanup of the stack; caller or callee.
Calling conventions can differ in:
where parameters and return values are placed (in registers; on the call
stack; a mix of both)
the order in which parameters are passed (or parts of a single
parameter)
how the task of setting up and cleaning up a function call is divided
between the caller and the callee.
which registers that may be directly used by the callee may sometimes also
be included
Architectures almost always have more
than one possible calling convention.
By the time that line is complete var will hold the value returned by fun() and any memory on the stack used by fun will be gone: "push", "pop" all tidy.
Calling conventions: everything that the compiler organises so that fun can do its work. Consider those parameters x, y, z. What order do they get pushed onto the stack (indeed do they get passed via the stack)? Doesn't matter so long as the caller and callee agree! It's a convention.

What is __stdcall?

I'm learning about Win32 programming, and the WinMain prototype looks like:
int WINAPI WinMain ( HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show )
I was confused as to what this WINAPI identifier was for and found:
#define WINAPI __stdcall
What does this do? I'm confused by this having something at all after a return type. What is __stdcall for? What does it mean when there is something between the return type and function name?
__stdcall is the calling convention used for the function. This tells the compiler the rules that apply for setting up the stack, pushing arguments and getting a return value.
There are a number of other calling conventions, __cdecl, __thiscall, __fastcall and the wonderfully named __declspec(naked). __stdcall is the standard calling convention for Win32 system calls.
Wikipedia covers the details.
It primarily matters when you are calling a function outside of your code (e.g. an OS API) or the OS is calling you (as is the case here with WinMain). If the compiler doesn't know the correct calling convention then you will likely get very strange crashes as the stack will not be managed correctly.
C or C++ itself do not define those identifiers. They are compiler extensions and stand for certain calling conventions. That determines where to put arguments, in what order, where the called function will find the return address, and so on. For example, __fastcall means that arguments of functions are passed over registers.
The Wikipedia Article provides an overview of the different calling conventions found out there.
The answers so far have covered the details, but if you don't intend to drop down to assembly, then all you have to know is that both the caller and the callee must use the same calling convention, otherwise you'll get bugs that are hard to find.
I agree that all the answers so far are correct, but here is the reason. Microsoft's C and C++ compilers provide various calling conventions for (intended) speed of function calls within an application's C and C++ functions. In each case, the caller and callee must agree on which calling convention to use. Now, Windows itself provides functions (APIs), and those have already been compiled, so when you call them you must conform to them. Any calls to Windows APIs, and callbacks from Windows APIs, must use the __stdcall convention.
Have a look at:
http://www.codeproject.com/KB/cpp/calling_conventions_demystified.aspx
It has to do with how the function is called- basically the order in which things are put on the the stack and who is responsible for cleanup.
Here's the documentation, but it doesn't mean much unless you understand the first part:
http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx
__stdcall is used to put the function arguments in the stack.
After the completion of the function it automatically deallocates the memory.
This is used for fixed arguments.
void __stdcall fnname ( int, int* )
{
...
}
int main()
{
CreateThread ( NULL, 0, fnname, int, int*...... )
}
Here the fnname has args it directly push into the stack.
I never had to use this before until today. Its because in my code I am using multi-threadding and the multi-threading API I am using is the windows one (_beginthreadex).
To start the thread:
_beginthreadex(NULL, 0, ExecuteCommand, currCommand, 0, 0);
The ExecuteCommand function MUST use the __stdcall keyword in the method signature in order for beginthreadex to call it:
unsigned int __stdcall Scene::ExecuteCommand(void* command)
{
return system(static_cast<char*>(command));
}

Resources