系统调用包装 asm C [英] syscall wrapper asm C

查看:19
本文介绍了系统调用包装 asm C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以向我解释一下这段代码吗?另外请给我一些链接/URL,我可以在其中了解更多信息?此代码用作包装器来覆盖我们库中的extern int errno".有人可以解释一下这个函数,并告诉我为什么在某些系统调用中需要包装器吗?哪些也称为 WeakSYSCALLS?

Can someone explain this code snippet to me? Also please give me some link/URL where i can know more about this? This code is used as a wrapper to override the "extern int errno" in our library. Can someone explain me this function, and tell why is wrapper needed in some syscalls? Which are also called WeakSYSCALLS?

#define ASM_ARGS_1      ASM_ARGS_0, "r" (_a1)
#define ASM_ARGS_2      ASM_ARGS_1, "r" (_a2)
#define ASM_ARGS_3      ASM_ARGS_2, "r" (_a3)
#define LOADREGS_5(a1, a2, a3, a4, a5)          
register int _v1 asm ("v1") = (int) (a5);     
LOADREGS_4 (a1, a2, a3, a4)

#define LOADREGS_6(a1, a2, a3, a4, a5, a6)      

register int _v2 asm ("v2") = (int) (a6);     

LOADREGS_5 (a1, a2, a3, a4, a5)

#define MYLIBC_SYSCALL(name, nargs, args...)               
({                                                        

    unsigned int retval;                              

    {                                                 

    register int _a1 asm ("r0"), _nargs asm ("r7");   
    LOADREGS_##nargs(args)                            
    _nargs = __NR_##name;                             
    asm volatile (                                    
            "swi    0x0"                              
            :"=r"(_a1)                                
            :"r"(_nargs) ASM_ARGS_##nargs             
            : "memory" );                             

      retval = _a1;                                     
    }                                                 

    if ( retval >= 0xfffff001 )     {                 
            errno = -retval;                          
            retval = (unsigned int)-1;                      
    }                                                 
    (int) retval;                                     
})

推荐答案

做一个系统调用"意味着触发内核执行一个特殊的活动.由于内核运行在不同的地址空间,这不能通过简单的函数调用来完成.

Doing a "syscall" means triggering the kernel to execute a special activity. Since the kernel runs in a different address space, this cannot be done via a simple function call.

根据操作系统和硬件平台,系统调用可以通过例如触发中断、调用门、SYSENTER 或其他几种方法来调用.

Depending on the operating system and hardware platform, a syscall can be invoked by, for example, triggering an interrupt, a call gate, SYSENTER, or several other methods.

但是,无论如何,您不能像使用 C 函数调用那样简单地将大量参数传递给内核.但是,您可以将参数值放入某些寄存器中.这些是哪些寄存器,内核如何解释它们的内容,这又是特定于所讨论的操作系统的.

In any case, though, you cannot simply pass a number of parameters to the kernel the way you would do with a C function call. You can, however, place parameter values into certain registers. Which registers those are, and how their contents are interpreted by the kernel, is again specific to the OS in question.

由于您既不能访问特定寄存器,也不能调用上述任何内核触发方法,所以在纯 C 代码中,您可以使用 调用的 系统调用包装器em> 类似于 C 函数,然后将参数放在寄存器中,并使用 ASM 代码触发内核.

Since you can neither access specific registers, nor invoke any of the kernel-triggering methods mentioned above, in plain C code, there are syscall wrappers available to you that are called like C functions, and then place the parameters in registers and trigger the kernel using ASM code.

您在上面看到的就是这样一个系统调用包装器.您会看到将参数数量放入寄存器 r7 的部分,将参数本身放入适当的寄存器 (LOADREGS_*),然后执行触发器 (swi 0x0,它我是软件中断-我对ARM平台了解不多),并从寄存器A1获取返回值".

What you see above is such a syscall wrapper. You see the part where it places the number of arguments into register r7, the arguments themselves into the appropriate registers (LOADREGS_*), then does the trigger (swi 0x0, which I guess is a software interrupt - I don't know much about the ARM platform), and gets the "return value" from register A1.

这篇关于系统调用包装 asm C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆