一、实验要求
1.理解编译链接的过程和ELF可执行文件格式;
2.编程使用exec*库函数加载一个可执行文件,动态链接分为可执行程序装载时动态链接和运行时动态链接,编程练习动态链接库的这两种使用方式;
3.使用gdb跟踪分析一个execve系统调用内核处理函数sys_execve,验证Linux系统加载可执行程序所需过程的理解。
二、实验过程及分析
1.将menu目录删除,利用git命令克隆一个新的menu目录
cd ~/LinuxeKernel/
rm -rf menu
git clone https://github.com/mengning/menu.git
2.用test_exec.c将test.c覆盖,重新编译rootfs。查看代码发现,除了增加execlp函数之外,还在Makefile中编译了hello.c,然后在生成跟文件系统时把init和hello都放到rootfs.img中。在这个实验中,hello就是一个加载进来的可执行文件。
cd menu
mv test_exec.c test.c
make roofts
3.使用help命令可以看到增加了exec指令,执行exec指令发现比fork指令增加了一行输出“hello world!”。实际上是新加载了一个可执行程序来输出了一行语句。
4.启动内核到调试的状态,加载符号并设置端口,准备单步调试。
cd ~/LinuxKernel/
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
5.启动新的终端窗口开始gdb调试
cd ~/LinuxKernel/
gdb
file linux-3.18.6/vmlinux
target remote:1234
6.设置断点到sys_exec、load_elf_binary、start_thread
b sys_execve
b load_elf_binary
b start_thread
7.使用命令c继续执行发现执行到load_elf_binary处,在继续执行发现执行到start_thread处,继续单步执行,可以看到加载新可执行程序的一系列数据,并构造新的代码段。
三、实验分析
1.从test.c源码中看到exec函数的具体实现方案
2.查看hello(ELF文件)的头部信息
3.ELF文件格式
ELF文件是一种用于二进制文件、可执行文件、目标代码、共享库和core转存格式文件。是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface,ABI)而开发和发布的,也是Linux的主要可执行文件格式。
ELF主要分为四种类型:
1)可重定位文件(Relocatable File) 包含适合于与其他目标文件链接来创建可执行文件或者共享目标文件的代码和数据,即 xxx.o 文件。
2)可执行文件(Executable File) 包含适合于执行的一个程序,此文件规定了 exec() 如何创建一个程序的进程映像,即 a.out文件。
3)共享目标文件(Shared Object File) 包含可在两种上下文中链接的代码和数据。首先链接编辑器可以将它和其它可重定位文件和共享目标文件一起处理,生成另外一个目标文件。其次,动态链接器(Dynamic Linker)可能将它与某个可执行文件以及其它共享目标一起组合,创建进程映像,即 xxx.so文件。
4)内核转储(core dumps),存放当前进程的执行上下文,用于dump信号触发。