How can I embed inline assembly to call sys_unlink?
I am try to make a call to sys_unlink using inline assembly, like this:
int sys_unlink(const char *filename) {
int ret;
__asm__("int $0x80" : "=a"(ret) : "a"(10), "b"(filename));
return ret;
}
But it does not work, it always return -14.
I开发者_如何学运维 would like to know if this code is correct, as I do not know much assembly.
That code is only correct for an x86 (32 bit) process - it does not use the right syscall number for an x86-64 process. Use __NR_unlink
from asm/unistd.h
instead of the hardcoded 10
:
#include <asm/unistd.h>
int sys_unlink(const char *filename)
{
int ret;
asm("int $0x80" : "=a"(ret) : "a"(__NR_unlink), "b"(filename));
return ret;
}
If you are compiling a 32 bit process, then -14
is EFAULT
, indicating an a problem with the filename you are passing. How are you calling it?
I don't think you can make this work even restricted to a single platform under Linux: The modern way for Linux to make syscalls is via a stub provided by the kernel and linked in via VDSO. Even the libc you are linking against doesn't know (doesn't need to know) what the system call convention is -- it just pulls in a reference from the VDSO. It gets a reference to the VDSO via a magic parameter that's hidden just after environ
and then treats it like any other dynamic library. The kernel chooses the system call convention based on the CPU capabilities.
I happen to know (because I tried to do it!) that it's hard to get access to those VDSO symbols. glibc does not export them (or any useful handle to them) for you. About the only workable way I saw was to inspect your own /proc/self/maps
to find the VDSO and then use dl
functions to get at it (repeating some of the glibc setup work).
精彩评论