4

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

4

2 回答 2

5

ELF 文件布局

一个 ELF 文件有两个视图:

  • 程序头显示运行时使用的段
  • 节头列出了二进制文件的节集

每个 ELF 文件由一个 ELF 头组成,后面是文件数据。

文件数据可以包括:

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

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

在此处输入图像描述

将程序加载到内存

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

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

加载程序涉及:

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

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

*NIX 方式

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

Unix 加载器的任务包括:

  • 验证(权限、内存要求等)
  • 将程序映像从磁盘复制到主存储器
  • 在堆栈上复制命令行参数
  • 初始化寄存器(例如,堆栈指针)
  • 跳转到程序入口点 ( _start)
于 2012-04-11T00:14:40.167 回答
4

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

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

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

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

于 2012-04-11T08:13:03.513 回答