0

我尝试使用内联汇编调用 sys_unlink,如下所示:

 int sys_unlink(const char *filename) {

    int ret;

    __asm__("int $0x80" : "=a"(ret) : "a"(10), "b"(filename));

    return ret;

}

但它不起作用,它总是返回-14。

我想知道这段代码是否正确,因为我不太了解汇编。

4

2 回答 2

3

该代码仅适用于 x86(32 位)进程 - 它没有为 x86-64 进程使用正确的系统调用号。使用__NR_unlinkfromasm/unistd.h而不是硬编码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;
}

如果您正在编译 32 位进程,则-14is EFAULT,表示您传递的文件名有问题。你怎么称呼它?

于 2011-01-01T03:24:02.187 回答
3

我认为您甚至不能将这项工作限制在 Linux 下的单个平台上:Linux 进行系统调用的现代方式是通过内核提供的存根并通过 VDSO 链接。即使您要链接的 libc 也不知道(不需要知道)系统调用约定是什么——它只是从 VDSO 中提取引用。它通过一个隐藏在后面的魔术参数获取对 VDSO 的引用,environ然后像对待任何其他动态库一样对待它。内核根据 CPU 能力选择系统调用约定。

我碰巧知道(因为我试图这样做!)很难访问那些 VDSO 符号。glibc 不会为您导出它们(或任何有用的句柄)。关于我看到的唯一可行的方法是检查你自己的/proc/self/maps以找到 VDSO,然后使用dl函数来获取它(重复一些 glibc 设置工作)。

于 2011-01-01T03:47:46.857 回答