第七课 可执行程序的装载(1)
2016-04-09 18:36
246 查看
可执行文件格式
在linux下的可执行文件的格式是ELF文件格式,与windows下常见的PE格式是不同的文件类型。ELF文件是指可执行的可链接的文件。常见的.o文件或者可执行文件都可以是这种文件格式,但是他们又有不同,下面将查看分析他们的不同之处。
可重定位的文件
可重定位的文件就是我们常见的*.o目标文件,他包含一段代码和一段数据。用来生成可执行文件或者库文件。这比较好理解。
可执行的文件
可执行文件保存着一个用来执行的程序。该文件将会指出函数exec函数如何创建程序进程映像。这里也说出了我们可以调用exec来执行一个可执行文件的原因。
共享文件
共享文件是指一些库文件,包括了静态链接库和动态链接库两种。保存有代码和数据。用来被不同的连接器处理。
静态库将会被链接编辑器处理,最终和其他的目标文件处理形成新的目标文件。(编译时刻)
动态库将会被动态连接器处理,和可执行文件获取目标文件一起处理形成新的进程映像。(运行时刻)
ELF文件的格式都包含哪些部分呢?
在课件中老师以两种视角来看待一个object文件,其实是和文件的应用场景有关的。比如如果目标文件是库文件将会是可连接的视角来看,如果是可执行文件将会是可执行的视角来看待这个文件,但是文件的基本框架是相同的。
文件内部结构图:
Linking 视角 Execution 视角 ============ ============== ELF header ELF header Program header table (optional) Program header table Section 1 Segment 1 ... Segment 2 Section n ... Section header table Section header table (optional)
基本框架包括:头部信息,可编程的头部表和分段信息,以及每一个段头部信息。
头部信息的基本格式为:
#define EI_NIDENT 16 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;
第二个字段是type信息,主要三种类型,列举如下,和我们前文的讲解是能够核对上的。
Name Value Meaning ==== ===== ======= ET_NONE 0 No file type ET_REL 1 Relocatable file ET_EXEC 2 Executable file ET_DYN 3 Shared object file
还有一个字段比较重要是:
Elf32_Addr e_entry;
这个值指出了程序的入口地址。
文件与进程
在目标文件中的段的地址和进程中的地址是有对应关系的。我们知道一个可执行文件要在系统中运行, 必须拷贝程序的程序段和数据段到内存中来。
那么程序段要拷贝哪里呢?
在课件中,老师讲解是固定的虚拟地址位置:0x0804 8000.在这个地址基础之上拷贝可执行文件的头部信息。而0x0804 8300这个地址是在可执行文件中指定的,是加载到程序中执行的第一条可执行指令。
而0x804 8300这个地址就是我们在上文中 elf header中字段Elf32_Addr e_entry的值。
从这个入口地址开始后面都是可执行的连续的代码。在静态库链接状态下,所有的可执行代码都是连续存储的。
通过孟宁老师的讲解,我们知道了,代码段的内存开始位置是0x0804 8000,但是程序的开始执行位置是0x0804 8300.这两个位置是不同的。为什么不同呢?
这里,我这样理解,入口地址是main函数的入口,但是在main函数之前是不是应当在做一些准备工作啊,比如入参啥的。所以和代码段的第一条指令是不同的。这里存疑问。下面做了实验后,我将回来更正。
如果在动态链接库的情况,将会出现多个代码段,并且代码段是在运行时加载的。将会比静态链接库更加复杂一些。
相关文章推荐
- linux基础学习之 gSOAP文件夹中的README中文翻译
- STL的基本使用之关联容器:map和multiMap的基本使用
- 第一次结对项目报告
- git相关操作流程学习
- Android常见的几种RuntimeException
- 指针与数组(1)
- JVM 运行时数据区域
- linux中用户创建与删除以及文件权限查看和修改
- boost解析info文件
- mogodb的一些小事 mongodb+express+node.js增删改查
- codeforces Round #258(div2) D解题报告
- android性能调优工具TraceView的使用
- DOM
- 第七周项目一(2) 求两点间的距离
- VB.net版机房收费系统——结账功能实现(调错与优化)
- 骨骼的一点东西
- 受限波兹曼机导论Introduction to Restricted Boltzmann Machines
- 练习二1005
- Hibernate 关联映射之---- 一对多双向映射
- Java实验2 类的继承性