可执行程序的装载
可执行文件的创建
预处理:加入头文件执行宏替换等操作
gcc -E hello.c -o hello.i
编译:检查无误后转为汇编语言
gcc –S hello.i –o hello.s
汇编:转为二进制
gcc –c hello.s –o hello.o
链接:生成可执行文件
gcc hello.o –o hello
一步完成的命令为:
gcc hello.c -o hello
elf文件分为可重定位文件、可执行文件、共享文件等
查看elf文件的文件头可以用readelf
程序的入口地址是0x8048000
可执行文件的执行环境
-
命令行参数和shell环境,一般我们执行一个程序的Shell环境,我们的实验直接使用execve系统调用。
-
$ ls -l /usr/bin 列出/usr/bin下的目录信息
-
Shell本身不限制命令行参数的个数,命令行参数的个数受限于命令自身
-
例如,int main(int argc, char *argv[])
-
又如, int main(int argc, char *argv[], char *envp[])
-
Shell会调用execve将命令行参数和环境参数传递给可执行程序的main函数
-
int execve(const char * filename,char * const argv[ ],char * const envp[ ]);
-
库函数exec*都是execve的封装例程
- 命令行参数和环境串都放在用户态堆栈中
动态链接分为可执行程序装载时动态链接和运行时动态链接
- 准备.so文件
shlibexample.h (1.3 KB) - Interface of Shared Lib Example
shlibexample.c (1.2 KB) - Implement of Shared Lib Example
- 编译成libshlibexample.so文件
$ gcc -shared shlibexample.c -o libshlibexample.so -m32
dllibexample.h (1.3 KB) - Interface of Dynamical Loading Lib Example
dllibexample.c (1.3 KB) - Implement of Dynamical Loading Lib Example
- 编译成libdllibexample.so文件
$ gcc -shared dllibexample.c -o libdllibexample.so -m32
-
运行
gcc main.c -o main -L/path/to/your/dir -lshlibexample -ldl -m32
export LD_LIBRARY_PATH=$PWD #将当前目录加入默认路径,否则main找不到依赖的库文件,当然也可以将库文件copy到默认路径下。
./main
可执行程序的装载
实验:
gdb跟踪内核函数sys_execve处理过程
内核准备
执行exec
gdb调试
执行结果
单步运行,可以看到do_execv函数
执行到start_thread查看入口地址
与readelf的结果一致