Tim*_*Tim 2 linux system-calls exec
当 C 程序被 kernel\xe2\x80\x94by 执行时execve(),
在哪里调用在调用 main 函数之前调用的execve()特殊启动例程?crt0
execve()main函数在哪里调用?
我在https://elixir.bootlin.com/linux/latest/source/fs/exec.c中找不到它们。
\n\n从理解Linux内核开始,execve()内部寻找一个可以加载可执行文件的linux_binfmt对象并调用其方法来加载,同时还加载动态链接器来加载和链接可执行文件所使用的共享库。但书中没有说明如何从可执行文件中调用启动例程和程序的 then 。load_binary()load_binary()execve()crt0main()
谢谢。
\n小智 5
execve内核代码都不会调用该函数_start(可执行文件的入口点,无论它被称为什么)。
那是因为它们在不同的上下文中运行;就好像它们在不同的机器上运行一样。
发生的情况是,内核execve在返回用户模式时安排系统调用,将IP(指令指针)寄存器设置为指向函数的开头_start,并将SP(堆栈指针)寄存器设置为指向函数的开头。 argv + env 字符串列表,因此从用户模式的角度来看,效果就像有人调用该_start函数一样:
_start(argc, argv0, argv1, ... , NULL, env0, env1, ... NULL)
Run Code Online (Sandbox Code Playgroud)
在所有参数都在堆栈上传递的调用约定中。
当然,在此之前,内核已经负责将这些 argv + env 复制到正确的位置,映射包含该_start函数的段等。
请注意,argv + env 字符串全部打包在一个块中,例如。
"prog\0arg1\0arg2\0VAR1=foo\0VAR2=bar\0"
Run Code Online (Sandbox Code Playgroud)
该块开始和结束的虚拟地址可以通过/proc/PID/stat文件访问;引用procfs(5)手册页:
Run Code Online (Sandbox Code Playgroud)(48) arg_start %lu (since Linux 3.5) [PT] Address above which program command-line arguments (argv) are placed. (49) arg_end %lu (since Linux 3.5) [PT] Address below program command-line arguments (argv) are placed.
写入该地址将修改ps输出中出现的任何内容:
$ sleep 3600 3600 3600 3600 3600 3600 3600 &
[2] 4927
$ awk '{print $48,$49,$49-$48-1}' /proc/4927/stat
140735402952841 140735402952882 40
$ printf 'Somebody set up us the bomb Main screen turn on\0' | dd bs=1 count=40 of
=/proc/4927/mem seek=140735402952841 conv=notrunc
40+0 records in
40+0 records out
40 bytes copied, 0.000229779 s, 174 kB/s
$ ps 4927
PID TTY STAT TIME COMMAND
4927 pts/4 S 0:00 Somebody set up us the bomb Main screen
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1479 次 |
| 最近记录: |