一、实验内容
Linux 内核如何装载和启动一个可执行程
1、理解编译链接的过程和 ELF 可执行文件格式,详细内容参考本周第一节;
2、编程使用 exec*库函数加载一个可执行文件,动态链接分为可执行程序装载时动态链接和运行时动态链接,编程练习动态链接库的这两种使用方式,详细内容参3考本周第二节;
3、使用 gdb 跟踪分析一个 execve 系统调用内核处理函数 sys_execve ,验证您对 Linux 系统加载可执行程序所需处理过程的理解,详细内容参考本周第三节;推荐在实验楼 Linux 虚拟机环境下完成实验。
4、特别关注新的可执行程序是从哪里开始执行的?为什么 execve 系统调用返回后新的可执行程序能顺利执行?对于静态链接的可执行程序和动态链接的可执行程序 execve 系统调用返回时会有什么不同?
二、实验过程
1、实验前期准备
(1)理解 ELF 文件格式
- 查看系统上的 ELF 文件结构。我们可以使用
readelf
或objdump
工具来分析 ELF 文件的内容和结构。 - 命令如下:
readelf -h <executable-file> objdump -d <executable-file>
- 这些命令可以帮助我们查看 ELF 文件的头部信息、段信息、符号表等内容。
(2)了解编译和链接过程
- 编写一个简单的 C 程序,如
hello.c
,并对其进行编译和链接,观察生成的目标文件和可执行文件。 - C 代码示例 (
hello.c
):#include <stdio.h> int main() { printf("Hello, world!\n"); return 0; }
- 运行以下命令查看编译和链接过程:
gcc -c hello.c -o hello.o # 编译为目标文件 gcc hello.o -o hello_static # 链接生成静态可执行文件 gcc -o hello hello.c # 编译生成动态可执行文件
- 查看生成的静态和动态可执行文件的区别:
file hello_static file hello