系统调用包装器asm C.

kin*_*er1 2 c assembly arm system-calls wrapper

有人可以向我解释这段代码吗?还请给我一些链接/ URL,我可以在这里了解更多信息?此代码用作包装器来覆盖库中的"extern int errno".有人可以解释我这个功能,并告诉为什么在一些系统调用中需要包装器?哪个也叫做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;                                     \
})
Run Code Online (Sandbox Code Playgroud)

Dev*_*lar 5

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

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

但是,在任何情况下,您都不能像在C函数调用中那样简单地将许多参数传递给内核.但是,您可以将参数值放入某些寄存器中.哪些注册,以及内核如何解释它们的内容,再次特定于所讨论的OS.

既然你既不能访问特定的寄存器,也不能调用上面提到的任何内核触发方法,那么在普通的C代码中,有一些syscall包装器可以被称为 C函数,然后将参数放在寄存器中并触发内核使用ASM代码.

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