linux内核启动时将ELF格式注册到内核可支持的文件格式链表中,也就是通过register_binfmt 函数将定义的elf_format结构体添加到链表中。该结构体如下:
当我们执行一个可执行程序的时候, 内核会list_for_each_entry遍历所有注册的linux_binfmt对象, 对其调用load_binrary方法来尝试加载, 直到加载成功为止。上面代码可以看倒,ELF中加载程序即为load_elf_binary,内核中已经注册的可运行文件结构linux_binfmt会让其所属的加载程序load_binary逐一前来认领需要运行的程序binary,如果某个格式的处理程序发现相符后,便执行该格式映像的装入和启动。
接下来,我们具体分析load_elf_binary函数。
第一步,填充并且检查目标程序ELF头部。
首先是填充映像的文件头,使用了内核之前对bprm->buf填充的128个字节信息。然后比较了文件头的前4个字节,查看是否是标准的ELF文件魔数(”\177ELF”),然后还需要确认该文件是可执行文件还是动态链接库文件,也就是代码中的ET_EXEC和ET_DYN
第二步,通过load_elf_phdrs加载目标程序的程序头表。