【问题标题】:Implementation of function execve (unistd.h)函数execve的实现(unistd.h)
【发布时间】:2011-09-11 22:08:55
【问题描述】:

如何查看函数 execve 的实现(在 x86_64 Linux 下),它在库 unistd 中? 我想要这个,因为我想知道如何使用汇编程序调用外部程序,而不调用 execve。 我知道有一个名为 execve 的系统调用,但我不知道如何使用它。

如何将 char * 类型和 char * [] 类型的变量放入寄存器?

【问题讨论】:

    标签: linux assembly system-calls unistd.h execve


    【解决方案1】:

    execve() 函数在用户空间中的实现类似于:

    int execve(const char *filename, char * const argv[], char * const envp[]) {
        return syscall(SYS_execve, filename, argv, envp);
    }
    

    所有实际的“工作”都在内核中完成。除了一些线程清理之外,libc 中没有什么特别有趣的事情发生。

    【讨论】:

    • 谢谢大家,但是如何将 char * 类型的变量和 char * [] 类型的变量放入寄存器中?,我只知道如何进行写入和退出系统调用,例如,当我进行写入系统调用,我必须将指针放入寄存器并将缓冲区大小放入另一个,但我现在该怎么做?
    • 与以前没有什么不同——将指向文件名、参数数组和环境数组的指针放在三个寄存器中。后两者应该只是指向 char * 数组开头的指针,以 NULL 终止。
    【解决方案2】:

    只需查看内核源代码(更具体地说:arch/YOUR-ARCH/kernel/head*.S),了解您架构上的系统调用约定(系统调用号和参数的寄存器和/或堆栈) .

    例如,在 ARM 上,您可以将 __NR_execve 加载到 r7,将参数加载到 r0、r1、r2,然后使用 swi 0。您可能对this explantion of ARM EABI syscalls 感兴趣,了解更多详情。

    【讨论】:

      【解决方案3】:

      在 glibc 的源代码中没有真正直接的系统调用实现 - 这是在构建时从定义系统调用号的各种文件生成的。

      如果你理解的话,相关信息可以在sysdep.h 中找到,除了实际的系统调用号(你想要__NR_execve with, IIRC, #include <asm/unistd.h> - 我不记得它在 x86_64 上是什么)。

      系统调用号在 %rax 中,参数在 %rdi %rsi %rdx 中。所有这些信息(包括堆栈对齐和内核使用的寄存器)都在 sysdep.h 中进行了注释。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-31
        • 2020-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-07
        • 1970-01-01
        相关资源
        最近更新 更多