C 如何嵌入内联程序集以调用sys\u unlink?
我尝试使用内联程序集调用sys_unlink,如下所示:C 如何嵌入内联程序集以调用sys\u unlink?,c,assembly,inline-assembly,system-calls,unlink,C,Assembly,Inline Assembly,System Calls,Unlink,我尝试使用内联程序集调用sys_unlink,如下所示: int sys_unlink(const char *filename) { int ret; __asm__("int $0x80" : "=a"(ret) : "a"(10), "b"(filename)); return ret; } 但它不起作用,它总是返回-14 我想知道这段代码是否正确,因为我对汇编不太了解。这段代码只对x86(32位)进程正确-它没有对x86-64进程使用正确的系统调用号。
int sys_unlink(const char *filename) {
int ret;
__asm__("int $0x80" : "=a"(ret) : "a"(10), "b"(filename));
return ret;
}
但它不起作用,它总是返回-14
我想知道这段代码是否正确,因为我对汇编不太了解。这段代码只对x86(32位)进程正确-它没有对x86-64进程使用正确的系统调用号。使用
\uuu NR\u从asm/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;
}
#包括
int sys_unlink(常量字符*文件名)
{
int ret;
asm(“int$0x80”:“=a”(ret):“a”((未链接),“b”(文件名));
返回ret;
}
如果您正在编译一个32位进程,则-14
为EFAULT
,表示您传递的文件名有问题。如何调用它?该代码仅适用于x86(32位)进程-它没有为x86-64进程使用正确的系统调用号。使用\uuu NR\u从asm/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;
}
#包括
int sys_unlink(常量字符*文件名)
{
int ret;
asm(“int$0x80”:“=a”(ret):“a”((未链接),“b”(文件名));
返回ret;
}
如果您正在编译一个32位进程,则-14
为EFAULT
,表示您传递的文件名有问题。您如何称呼它?我认为您甚至不能将此工作限制在Linux下的单个平台上:Linux进行系统调用的现代方式是通过内核提供的存根并通过VDSO链接。即使是您正在链接的libc也不知道(不需要知道)系统调用约定是什么——它只是从VDSO中提取一个引用。它通过一个隐藏在environ
之后的神奇参数获取对VDSO的引用,然后将其视为任何其他动态库。内核根据CPU能力选择系统调用约定
我碰巧知道(因为我试过这么做!)很难访问那些VDSO符号。glibc不会为您导出它们(或任何有用的句柄)。我看到的唯一可行的方法是检查您自己的/proc/self/maps
以找到VDSO,然后使用dl
函数来获得它(重复一些glibc设置工作).我认为在Linux下,您甚至不能将此工作限制在单个平台上:Linux进行系统调用的现代方式是通过内核提供的存根,并通过VDSO链接。即使是您正在链接的libc也不知道(不需要知道)系统调用约定是什么——它只是从VDSO中提取一个引用。它通过一个隐藏在environ
之后的神奇参数获取对VDSO的引用,然后将其视为任何其他动态库。内核根据CPU能力选择系统调用约定
我碰巧知道(因为我试过这么做!)很难访问那些VDSO符号。glibc不会为您导出它们(或任何有用的句柄)。我看到的唯一可行的方法是检查您自己的/proc/self/maps
以找到VDSO,然后使用dl
函数来获取它(重复一些glibc设置工作)。旧的int$0x80
入口点仍然受支持(并且将在很长一段时间内得到支持),因为它是旧ABI的一个基本部分。int$0x80
接口对于实现clone
也是必不可少的,因为VDSO接口需要一个工作堆栈,而使用SYS\u clone
时,堆栈是在syscall返回后在用户空间中创建的。旧的int$0x80
入口点仍然受支持(并且将在很长一段时间内得到支持),因为它是旧ABI的基本部分。int$0x80
接口对于实现clone
也是必不可少的,因为VDSO接口需要一个工作堆栈,而对于SYS\u clone
,堆栈是在syscall返回后在用户空间中创建的。谢谢你的回答,我使用的是64位机器。我在取消链接时更改了10,但现在我得到了-1(EPERM)。谢谢你的回答,我使用的是64位机器。我在取消链接时更改了10,但现在得到了-1(EPERM)