如下图所示:
分析:以hello.c源文件为例
(1)预处理阶段:gcc -E -o hello.cpp hello.c -m32 将hello.c文件预处理成hello.cpp文件;预处理负责把include的文件包含进来及宏替换等工作。
(2) 编译阶段:gcc -x cpp-output -S -o hello.s hello.cpp -m32 将hello.cpp文件编译成hello.s汇编代码
(3)链接阶段:gcc -x assembler -c hello.s -o hello.o -m32 将目标文件链接成可执行文件hello
1.2 ELF可执行文件格式
ELF文件由4部分组成:ELF头(ELF header)、程序头表(Program header table)、节(Section)和节头表(Section header table)。实际上,一个文件中不一定包含全部内容,而且他们的位置也未必如同所示这样安排,只有ELF头的位置是固定的,其余各部分的位置、大小等信息由ELF头中的各项值来决定。
一个ELF头文件在文件的开始,保存了路线图(road map),描述了该文件的组织情况。程序头表(program header table)告诉系统如何来创建一个进程的内存映像。Section头表(section header table)包含了描述文件sections的信息。每个section在这个表中有一个入口;每个入口给出了该section的名字,大小。
当创建或增加一个进程映像的时候,系统在理论上将拷贝一个文件的段到一个虚拟的内存段。
ELF可执行文件分为三种:
Elf header格式代码如下:
typedef struct{ unsigned char e_ident[EI_NIDENT]; Elf32_Half e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; Elf32_Off e_phoff; Elf32_Off e_shoff; Elf32_Word e_flags; Elf32_Half e_ehsize; Elf32_Half e_phentsize; Elf32_Half e_phnum; Elf32_Half e_shentsize; Elf32_Half e_shnum; Elf32_Half e_shstrndx; }Elf32_Ehdr;数据类型说明:
名称 大小 对齐 用途 Elf32_Addr 4 4 无符号程序地址 Elf_32_Half 2 2 无符号中等大小整数 Elf32_Off 4 4 无符号文件偏移 Elf32_Sword 4 4 有符号整数 Elf32_Word 4 4 无符号大整数 unsigned char 1 1 无符号小整数
使用gdb跟踪分析一个execve系统调用内核处理函数sys_execve ,验证对Linux系统加载可执行程序所需处理过程的理解,详细内容参考本周第三节;推荐在实验楼Linux虚拟机环境下完成实验。
3.2 实验过程
3.2.1 打开实验楼虚拟机环境,进入LinuxKernel文件夹,然后重新下载menu文件:
3.2.2 使用qemu命令进入跟踪调试环境:
3.2.3 设置断点:sys_execve,load_elf_binary,start_thread
3.2.4 执行程序
3.2.5 进入sys_execve系统调用
3.2.6 单步执行sys_execve系统调用的指令
3.2.7 执行start_thread函数,这里的new_ip是返回到用户态的第一条指令的地址
3.2.8 在这里我们通过readelf命令,可以看到可执行文件hello的第一条指令地址就是:0x8048d0a
Linux内核装载一个可执行程序:首先创建新进程,该进程通过execve()系统调用执行指定的ELF文件,再调用execve()系统调用对应的内核的入口函数sys_execve(),sys_execve()服务例程修改当前进程的执行上下文。
上述步骤完成后,该进程开始执行可执行文件代码。当ELF被load_elf_binary()装载完成后,函数返回至do_execve()在返回至sys_execve()。ELF可执行文件的入口点取决于程序的链接方式,对于静态链接的可执行文件,若是静态链接的,elf_entry就是指向可执行文件里边规定的那个头部,即main函数对应的位置,若这个可执行文件是需要依赖其它动态链接库的话,则elf_entry就是指向动态链接器的起点。
参考资料:
http://baike.baidu.com/link?url=HCC0EFQk-PFws3q_PjRTMUblzoIFLE-M5CXW3BG6jGEXD4NqI3_gkTvNY6C2NfVfhXJIxYiVjmmr4Pgm4LkDwKrXnThq-zMUxJIL_vb3Vda