Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is "asmlinkage" required for a c function to be called from assembly?

I am writing a C function that will be invoked from assembly code.

(Specifically, I want to do some checking job in the path of system call handling in linux kernel, so I will call the c function before a system call is dispatched in entry_32.S)

I am confused with the "asmlinkage" modifier when defining my c function.

I know asmlinkage is to tell the compiler that the parameters will be passed through stack.

#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))

Questions:

(1) Is asmlinkage required when defining such a function that will be invoked from assembly code?

(2) what is the default calling convention in gcc. If I omit "asmlinkage" when defining a c function, does it imply _cdecl or fastcall?

(3) if the default calling convention is cdecl, why is asmlinkage needed, considering cdecl is equal to asmlinkage modifier? (am I correct here?)

(4) why are those system call functions all declared with asmlinkage. Can we copy the parameters to registers first, then call those system call functions? From my point of view, in x86, when issuing a system call, the parameters are readily saved in registers; then why bother to save then in stack to enforce such passing parameters via stack convention?

Finally, can anybody recommend some resources/books that I can refer to for such mix assembly/c programming?

like image 831
Infinite Avatar asked Apr 08 '12 03:04

Infinite


2 Answers

I would like to try to answer question (4) myself:

Why do all the system call functions sys_*, e.g. sys_gettimeofday, use stack to pass parameters?

The reason is that anyhow the kernel needs to save all the registers onto stack (in order to restore the environment before returning to the userspace) when handling the system call requests from userspace, so after that the parameters are available on stack. I.e., it doesn't need extra effort.

On the other hand, if you want to use fastcall for the calling convention, more work has to be done. We first need to know, when a user program issues a system call, in x86-linux, %eax is for syscall number, and %ebx, %ecx, %edx, %esi, %edi, %ebp are used for passing 6 parameters to system calls (before "int 80h" or "sysenter"). However, the calling convention of fastcall is to pass the first parameter in %eax, the 2nd one in %edx, the 3rd %ecx, others are pushed onto stack from right to left. In this way, to enforce such fastcall convention in kernel, you need to somehow arrange these in addition to save all the registers on the stack.

like image 60
Infinite Avatar answered Nov 20 '22 06:11

Infinite


The idea, I believe, is to allow the kernel to be compiled with gcc options that would change the default calling convention to something more efficient (i.e. passing more arguments in registers). However, functions that need to be called from asm cannot be allowed to vary in calling convention based on the gcc options in use, or there would have to be separate versions of the asm for every supported set of gcc options. Thus, functions that need to use a fixed calling convention (which happens to match the default with no special gcc options) are declared with special attributes so that their calling convention will remain fixed.

like image 21
R.. GitHub STOP HELPING ICE Avatar answered Nov 20 '22 07:11

R.. GitHub STOP HELPING ICE