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
Post a Comment