http://blog.csdn.net/q_l_s/article/details/52597330

三、分析在fork产生新进程中ELF文件格式与进程地址空间的联系


1、进程的虚拟地址空间

每个程序都有自己的虚拟地址空间(Virtual Address Space),大小由硬件平台(CPU位数)决定。 如32位平台下每个程序都有4G虚拟空间。但4G空间不是都分配给程序的用户空间,还有系统的虚拟空间。如Linux系统默认情况下高1G为系统的虚拟地址空间,低3G为用户空间。 这也就是说每个进程原则上最多可使用3G的虚拟空间。

2、 进程装载

覆盖装入(Overlay)和页映射(Paging)是两种典型的动态装载方法。现在前者已经不用了。

创建一个进程,然后装载相应的可执行文件并且执行。上述过程最开始只需要做三件事情:

①创建一个独立的虚拟地址空间。主要是分配一个页目录(Page Directory)。

②读取可执行文件的头,并且建立虚拟空间和可执行文件的映射关系。主要是把可执行文件映射到虚拟地址空间,即做虚拟页和物理页的映射,以便“缺页”时载入。

③将CPU的指令寄存器设置成可执行文件的入口地址,启动运行。从ELF文件中的入口地址开始执行程序。

3、过程分析

在bash下执行一个程序时,Linux是怎样装载这个ELF文件并执行的呢?
    首先bash调用fork()系统调用创建一个新的进程,然后新的进程调用execve()系统调用执行指定的ELF文件。 bash进程继续返回等待新进程执行结束,然后重新等待用户输入命令。execve()系统调用被定义在unistd.h,它的原型如下:
    int execve(const char *filenarne, char *const argv[], char *const envp[]);
    它的三个参数分别是被执行的程序文件名、执行参数和环境变最。Glibc对execvp()系统调用进行了包装,提供了execl(), execlp(), execle(), execv()和execvp()等5个不同形式的exec系列API,它们只是在调用的参数形式上有所区别,但最终都会调用到execve()这个系统中。

调用execve()系统调用之后,再调用内核的入口sys_execve()。 sys_execve()进行一些参数的检查复制之后,调用do_execve()。 因为可执行文件不止ELF一种,还有Java程序和以“#!”开始的脚本程序等, 所以do_execve()会首先检查被执行文件,读取前128个字节,特别是开头4个字节的魔数,用以判断可执行文件的格式。 如果是解释型语言的脚本,前两个字节“#!"就构成了魔数,系统一旦判断到这两个字节,就对后面的字符串进行解析,以确定程序解释器的路径。

当do_execve()读取了这128个字节的文件头部之后,然后调用search_binary_handle()去搜索和匹配合适的可执行文件装载处理过程。Linux中所有被支持的可执行文件格式都有相应的装载处理过程,search_binary_handle()会通过判断文件头部的魔数确定文件的格式,并且调用相应的装载处理过程。如ELF用load_elf_binary(),a.out用load_aout_binary(),脚本用load_script()。其中ELF装载过程的主要步骤是:
    ①检查ELF可执行文件格式的有效性,比如魔数、程序头表中段(Segment)的数量。
    ②寻找动态链接的”.interp”段(该段保存可执行文件所需要的动态链接器的路径),设置动态链接器路径。
    ③根据ELF可执行文件的程序头表的描述,对ELF文件进行映射,比如代码、数据、只读数据。
    ④初始化ELF进程环境,比如进程启动时EDX寄存器的地址应该是DT_FINI的地址(结束代码地址)。
    ⑤将系统调用的返回地址修改成ELF可执行文件的入口点,这个入口点取决于程序的链接方式,对于静态链接的ELF可执行文件,这个程序入口就是ELF文件的文件头中e_enEry所指的地址;对于动态链接的ELF可执行文件,程序入口点是动态链接器。
    当ELF被load_elf_binary()装载完成后,函数返回至do_execve()在返回至sys_execve()。在load_elf_binary()中(第5步)系统调用的返回地址已经被改成ELF程序的入口地址了。 所以当sys_execve()系统调用从内核态返回到用户态时,EIP寄存器直接跳转到了ELF程序的入口地址,于是新的程序开始执行,ELF可执行文件装载完成。

ELF文件格式与进程地址空间的联系的更多相关文章

  1. Linux计算机进程地址空间与内核装载ELF

    本文基于Linux™系统对进程创建与加载进行分析,文中实现了Linux库函数fork.exec,剖析内核态执行过程,并进一步展示进程创建过程中进程控制块字段变化信息及ELF文件加载过程. 一.初识Li ...

  2. linux内核--进程地址空间(三)

    引言:上篇博文中,我们简单的介绍了Linux虚拟存储器的概念及组成情况,下面来分析分析进程的创建和终结及跟进程地址空间的联系. 这里首先介绍一个比较重要的概念:存储器映射 在Linux系统中,通过将一 ...

  3. C语言的ELF文件格式学习

    最近的lab里面有ELF文件相关的,所以成这个几乎,学点ELF的东西. ELF,是一种文件格式.暂时,只看可执行文件的ELF文件格式. 首先,给出文件的格式的布局图: 光看这个很难理解,所以写一个小的 ...

  4. elf 文件格式探秘——程序运行背后的故事

    摘要:本文主要讲解elf文件格式,通过readelf命令结合底层的相关数据结构,讲解相关内容,分析程序运行的基本原理. 本文来源:elf 文件格式探秘——程序运行背后的故事 http://blog.c ...

  5. ELF文件格式定义

    ELF(Executable and Linking Format)是一种对象文件的格式,用于定义不同类型的对象文件(Object files)中都放了什么东西.以及都以什么样的格式去放这些东西.它自 ...

  6. ELF文件格式学习总结

    ELF文件格式学习总结 ELF文件格式学习总结1. 概述2. 目标文件结构3. ELF文件头3.1 魔数3.2 文件类型3.3 机器类型4. ELF文件内容4.1段表4.2字符串表(.**strtab ...

  7. ELF文件格式

    ELF--Linux下可执行文件格式   1.类型          常见的ELF格式文件包括:                                                     ...

  8. linux进程地址空间详解(转载)

    linux进程地址空间详解(转载) 在前面的<对一个程序在内存中的分析 >中很好的描述了程序在内存中的布局,这里对这个结果做些总结和实验验证.下面以Linux为例(实验结果显示window ...

  9. Linux课题实践四——ELF文件格式分析

    2.4   ELF文件格式分析 20135318 刘浩晨 ELF全称Executable and Linkable Format,可执行连接格式,ELF格式的文件用于存储Linux程序.ELF文件(目 ...

随机推荐

  1. Mock Server利器 - Moco

    Moco介绍Moco独立运行所需环境如何运行Moco启动http服务启动https服务Moco HTTPs API配置如何在配置文件添加注释约定请求Body约定接口的uri约定请求参数约定请求方法约定 ...

  2. ruby 更换源 + sass 安装

    gem sources -c #删除所有镜像地址 gem sources -a http://gems.ruby-china.com #添加ruby-china的镜像地址 原有的org域名更换变成co ...

  3. 搭建 Django 平台

    1.使用Pycharm.创建一个Django项目 2.图示 3.在终端输入: 4.结果

  4. Android Studio CMake依赖第三方库

    这里实现一个简单的功能在APP里调用libnative-lib.so里的add.libnative-lib.so去调用libthird.so里的third_add来实现 JniUtil public ...

  5. Android NDK开发 Jni中打日志LOG(二)

    HelloJni.c文件中,加入头文件和函数声明.最终文件如下: #include <jni.h> #include <string.h> #include<androi ...

  6. Cinder Columns

    http://www.screencast.com/users/xiangxinyong/folders/Smaug http://www.screencast.com/t/SLqCyOwtBRl

  7. IA-32e架构下的内核初始化内存管理

    初级内存管理单元 关于内存的分页 以往的物理页是按照4KB进行分配和管理的, 而在Linux之后流行的就是2MB大小的物理页的分配和管理, 整个物理内存管理单元也是2MB物理页管理的 先获取基本的物理 ...

  8. Jersey实现文件上传下载

    一 文件上传 使用ajaxFileUpload进行文件上传的前端处理.在ajaxFileupload.js中,针对服务端返回的类型增加text判断, //ajax文件上传 function ajaxF ...

  9. maven课程 项目管理利器-maven 3-2 maven自动建立目录骨架

    使用cmd创建maven目录的两种方式: 使用archetype插件 1 按照提示进行选择  步骤: a 进入指定目录 b mvn archetype:generate --创建项目目录 c ente ...

  10. MySQL连接服务端的几种方式

    一.MySQL 连接本地数据库,用户名为“root”,密码“123456”: D:\>mysql -h localhost -u root -p123456 注意:“-p”和“123456” 之 ...