程序加载/执行

Joh*_*ugo 4 c++ linux gcc elf llvm

我是编译器的初学者,但我对了解程序的结构(二进制)以及如何在内存中读取和加载以执行非常感兴趣。你们建议我阅读哪些电子书/书籍/教程以快速入门?

Dr.*_*eon 5

ELF 文件布局

一个 ELF 文件有两个视图:

  • 程序头示出了在运行时使用的段
  • 区段标题列出一组二进制的切片的

每个 ELF 文件由一个 ELF 头和文件数据组成。

文件数据可以包括:

  • 程序头表,描述零个或多个段
  • 节头表,描述零个或多个节
  • 由程序头表或节头表中的条目引用的数据

段包含文件运行时执行所需的信息,而段包含用于链接和重定位的重要数据。整个文件中的任何字节最多只能由一个节拥有,并且可以存在不为任何节所有的孤立字节。

在此处输入图片说明

将程序加载到内存

在计算中,加载器是操作系统中负责加载程序的部分。

它是启动程序过程中的重要阶段之一,因为它将程序放入内存并准备执行。

加载程序包括:

  • 将可执行文件(包含程序文本的文件)的内容读入内存
  • 执行其他必需的准备任务以准备运行可执行文件。

加载完成后,操作系统通过将控制权传递给加载的程序代码来启动程序。

*NIX 方式

在 Unix 中,加载器是系统调用的处理程序execve()

Unix 加载器的任务包括:

  • 验证(权限、内存要求等)
  • 将程序映像从磁盘复制到主内存中
  • 复制堆栈上的命令行参数
  • 初始化寄存器(例如,堆栈指针)
  • 跳转到程序入口点 ( _start)


Bas*_*tch 5

编译器和可执行二进制文件是远程相关的。(实际的可执行文件是由链接器ld而不是编译器构建的)。

在 Linux 系统上,Linux 内核使用写时复制请求分页技术来延迟加载ELF可执行文件的程序页面。共享库可以动态加载,并且最好包含与位置无关的代码

您可能有兴趣阅读有关编译器构造、Levine 关于链接器和加载器的书、Linux Assembly Howto程序库 Howtoldd(1)execve(2)intro(2)fork(2)mmap( 2)dlopen(3)elf(5)proc(5)signal(7)手册页。

还尝试了解cat /proc/self/maps正在向您显示的内容(执行该操作的进程的内存映射cat)。您还可以玩objdump