如何嵌入内联汇编来调用 sys_unlink?
我尝试使用内联汇编调用 sys_unlink,如下所示:
int sys_unlink(const char *filename) {
int ret;
__asm__("int $0x80" : "=a"(ret) : "a"(10), "b"(filename));
return ret;
}
但它不起作用,它总是返回 -14。
我想知道这段代码是否正确,因为我不太了解汇编。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
该代码仅适用于 x86(32 位)进程 - 它没有为 x86-64 进程使用正确的系统调用号。使用
asm/unistd.h
中的__NR_unlink
而不是硬编码的10
:如果您正在编译 32 位进程,则
-14
为EFAULT
,表示您传递的文件名有问题。你怎么称呼它?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
fromasm/unistd.h
instead of the hardcoded10
:If you are compiling a 32 bit process, then
-14
isEFAULT
, indicating an a problem with the filename you are passing. How are you calling it?我不认为你可以让这项工作甚至仅限于 Linux 下的单个平台:Linux 进行系统调用的现代方法是通过内核提供的存根并通过 VDSO 链接。即使您链接的 libc 也不知道(不需要知道)系统调用约定是什么 - 它只是从 VDSO 中提取引用。它通过隐藏在
environ
之后的神奇参数获取对 VDSO 的引用,然后像任何其他动态库一样对待它。内核根据 CPU 功能选择系统调用约定。我碰巧知道(因为我尝试这样做!)很难访问这些 VDSO 符号。 glibc 不会为您导出它们(或它们的任何有用句柄)。我看到的唯一可行的方法是检查您自己的 /proc/self/maps 来查找 VDSO,然后使用 dl 函数来获取它(重复一些glibc 设置工作)。
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 usedl
functions to get at it (repeating some of the glibc setup work).