assembly - Difference in ABI between x86_64 Linux functions and syscalls -


the x86_64 sysv abi's function calling convention defines integer argument #4 passed in rcx register. linux kernel syscall abi, on other hand, uses r10 same purpose. other arguments passed in same registers both functions , syscalls.

this leads strange things. check out, example, implementation of mmap in glibc x32 platform (for same discrepancy exists):

00432ce0 <__mmap>:   432ce0:       49 89 ca                mov    %rcx,%r10   432ce3:       b8 09 00 00 40          mov    $0x40000009,%eax   432ce8:       0f 05                   syscall 

so register in place, except move rcx r10.

i wondering why not define syscall abi same function call abi, considering similar.

the syscall instruction intended provide quicker method of entering ring-0 in order carry out system call. meant improvement on old method, raise software interrupt (int 0x80 on linux).

part of reason instruction faster because not change memory, or change rsp point @ kernel stack. unlike software interrupt, cpu forced allow os resume operation without clobbering anything, command cpu allowed assume software aware happening here.

in particular, syscall stores 2 parts of user-space state in registers. rip return after call stored in rcx, , flags stored in r11 (because rflags masked kernel-supplied value before entry kernel). means both registers clobbered instruction.

since clobbered, syscall abi uses register instead of rcx, hence use of r10 4th argument.

r10 natural choice, since in x86-64 systemv abi it's not used passing function args, , functions don't need preserve caller's value of r10. syscall wrapper function can mov %rcx, %r10 without save/restore. wouldn't possible other register, 6-arg syscalls , sysv abi's function calling convention.


btw, 32-bit system call abi accessible sysenter, requires cooperation between user-space , kernel-space allow returning user-space after sysenter. (i.e. storing state in user-space before running sysenter). higher performance int 0x80, awkward. still, glibc uses (by jumping user-space code in vdso pages kernel maps address space of every process).

amd's syscall approach same idea intel's sysenter: make entry/exit kernel less expensive not preserving absolutely everything.


Comments

Popular posts from this blog

jOOQ update returning clause with Oracle -

java - Warning equals/hashCode on @Data annotation lombok with inheritance -

java - BasicPathUsageException: Cannot join to attribute of basic type -