linux 带ifdef运行程序_linux可执行文件的加载和运行

本文深入探讨Linux系统的execve()系统调用及其在内核中的实现,详细解析了可执行文件加载的过程,包括参数复制、内存分配、VMA初始化等步骤,并介绍了搜索二进制处理模块的方法。
摘要由CSDN通过智能技术生成

linux可执行文件的加载和运行之一

三:可执行文件的加载和运行

Execve系统调用可以调用一个可执行文件完全代替当前的进程,它在libc中的封装有几个API:

int execl(const charp a t* h n a m e, const char a* rg 0, ... /* (char *) 0 */);

int execv(const charp a t* h n a m e, char *consta rgv[] );

int execle(const charp a t* h n a m e, const char a* rg 0, ...

/* (char *)0, char *cones nt v p[] */);

int execve(const charp a t* h n a m e, char *consta rgv[], char *consten vp[] );

int execlp(const charf i l e* n a m e, const char a* rg 0, ... /* (char *) 0 */);

int execvp(const charf i l e* n a m e, char *consta rgv[] );

我们深入内核代码来研究一下可执行文件的加载过程.execve()系统调用的入口是sys_execve().代码如下:

asmlinkage int sys_execve(struct pt_regs regs)

{

int error;

char * filename;

//将用户空间的第一个参数(也就是可执行文件的路径)复制到内核

filename = getname((char __user *) regs.ebx);

error = PTR_ERR(filename);

if (IS_ERR(filename))

goto out;

error = do_execve(filename,

(char __user * __user *) regs.ecx,

(char __user * __user *) regs.edx,

s);

if (error == 0) {

task_lock(current);

current->ptrace &= ~PT_DTRACE;

task_unlock(current);

/* Make sure we don't return using sysenter.. */

set_thread_flag(TIF_IRET);

}

//释放内存

putname(filename);

out:

return error;

}

系统调用的时候,把参数依次放在:ebx,ecx,edx,esi,edi,ebp寄存器.详情请参阅本站 Linux中断处理之系统调用>>.第一个参数为可执行文件路径,第二个参数为参数的个数,第三个参数为可执行文件对应的参数.

do_execve()是这个系统调用的核心,它的代码如下:

int do_execve(char * filename,

char __user *__user *argv,

char __user *__user *envp,

struct pt_regs * regs)

{

//linux_binprm:保存可执行文件的一些参数

struct linux_binprm *bprm;

struct file *file;

unsigned long env_p;

int retval;

retval = -ENOMEM;

bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);

if (!bprm)

goto out_ret;

//在内核中打开这个可执行文件

file = open_exec(filename);

retval = PTR_ERR(file);

//如果打开失败

if (IS_ERR(file))

goto out_kfree;

sched_exec();

bprm->file = file;

bprm->filename = filename;

bprm->interp = filename;

//bprm初始化,主要是初始化bprm->mm

retval = bprm_mm_init(bprm);

if (retval)

goto out_file;

//计算参数个数

bprm->argc = count(argv, MAX_ARG_STRINGS);

if ((retval = bprm->argc)

goto out_mm;

//环境变量个数

bprm-

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值