20135239 益西拉姆 linux内核分析 可执行程序的装载
益西拉姆 + 原创作品请勿转载 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”
week 7 可执行程序的装载
1.预处理、编译、链接和目标文件的格式
- 从c语言到可执行程序的由来过程
- 可执行文件的创建——预处理、编译和链接
以helloworld为例
- -s assembler 汇编
- gcc -o hello hello.o -m32 是把hello.o链接成可执行文件。
- ELF格式的文件是怎么回事?
- vi hello 是使用共享库的。
- static是静态库的意思。
- 静态链接和动态链接是怎么回事?
- 可执行文件的内部是什么?
2. 目标文件的格式ELF
目标文件及链接
目标文件是什么样的?
目标文件中的内容至少有编译后的机器指令代码、数据。没错,除了这些内容以外,目标文件中还包括了链接时所须要的一些信息,比如符号表、调试信息、字符串等。
ELF:exectable and linkable format.可执行和可链接的格式。
它是文件格式的标准,可执行连接格式是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface(ABI)而开发和发布的。工具接口标准委员会(TIS)选择了正在发展中的ELF标准作为工作在32位INTEL体系上不同操作系统之间可移植的二进制文件格式。
ABI和目标文件格式是怎么回事?
ABI 又称目标文件,应用程序二进制接口。二进制兼容的问题。复杂来讲就是:
- 符号修饰标准、变量内层布局、函数调用方式等这些跟可执行代码二进制兼容性相关的内容称为ABI(Application Binary Interface)。
- 常见的ABI格式:
ELF( ELF: 可执行连接格式 )中的三种目标文件:
- 一个可重定位文件保存着代码和适当的数据,用来和其他的object文件一起来创建一个可执行文件或者一个共享文件。(**主要是.o文件 **)
- 一个可执行文件保存着一个用来执行的程序;该文件指出了exec如何来创建程序进程映像。
- 一个共享object(目标)文件保存着代码和合适的数据,用来被下面的两个链接器链接。第一个是链接编辑器,可以和其他的可重定位和共享object文件来创建其他的object。第二个是动态链接器,联合一个可执行文件和其他的共享object文件来文件来创建一个进程映像。
- ELF目标文件的格式:
- ELF文件结构描述
ELF文件头: 如何查看ELF文件的头部
shiyanlou:Code/ $ readelf -h hello
段头表
- 目标文件中各节的位置和大小
- 处于目标文件的末尾
- 链接:
- 链接是一个收集、组织程序所需的不同代码 和数据的过程,以便程序能被装入内存并被执行。
- 链接过程分为两步: - 空间与地址分配: - 扫描所有的输入目标文件,获得它们的各个段的长度、属性和位置,并且将输入目标文件中的符号定义和符号引用收集起来,统一放到一个全局符号表。这一步中,链接器将能获得所有输入目标文件的段长度,并且将它们合并,计算出输出文件中各个段合并后的长度与位置,并建立映射关系。 - 符号解析与重定位: - 使用上面第一步中收集到的所有信息,读取输入文件中段的数据、重定位信息,并且进行符号解析与重定位、调整代码中的地址等。事实上第二步是链接过程的核心,特别是重定位过程。
静态链接的ELF可执行文件与进程的地址空间
目标文件、可执行文件与进程空间
- 一般静态链接都会将所有代码放在一个代码段。 - 动态链接的进程会有多个代码段。
可执行目标文件及装入
- 可执行目标文件与可重定位目标文件格式类似
- 可执行目标文件的装入由装载器完成
典型的ELF可执行目标文件
处理目标文件的一些工具
2.可执行程序、共享库和动态链接
装载可执行程序之前的工作。 - 可执行程序的执行环境: - 命令行参数和shell环境,一般我们执行一个程序的Shell环境,我们的实验直接使用execve系统调用。 - $ ls -l /usr/bin 列出/usr/bin下的目录信息 - Shell本身不限制命令行参数的个数,命令行参数的个数受限于命令自身 - ---例如,int main(int argc, char *argv[]) - ---又如, int main(int argc, char *argv[], char envp[]) - Shell会调用execve将命令行参数和环境参数传递给可执行程序的main函数 - ---int execve(const char * filename,char * const argv[ ],char * const envp[ ]); - 库函数exec都是execve的封装例程 - - 命令行参数和环境变量是如何保存和传递的? - 命令行参数和环境串都放在用户态堆栈中
- shell程序->>execve->> sys_execve
- 然后在初始化新程序堆栈时拷贝进去
- 先函数调用参数传递,在系统调用参数传递
装载时动态链接和运行时动态链接应用举例
动态链接分为可执行程序装载时动态链接和运行时动态链接。
3.可执行程序的装载
可执行程序的装载相关关键问题分析
sysexecve内核处理过程 - sysexecve内部会解析可执行文件格式
- doexecve -> doexecvecommon -> execbinprm
- searchbinaryhandler符合寻找文件格式对应的解析模块,如下(根据文件头部信息寻找对应的文件格式处理模块):
- 下面的地方相当于被观察者代码里面的一部分:
- 对于ELF格式的可执行文件fmt->loadbinary(bprm);执行的应该是loadelf_binary其内部是和ELF文件格式解析的部分需要和ELF文件格式标准结合起来阅读
- Linux内核是如何支持多种不同的可执行文件格式的?
- 下面的属于观察者:
- ---elfformat 和 initelf_binfmt,这里是不是就是观察者模式中的观察者?(上面有答案。)
- 可执行文件开始执行的起点在哪里?如何才能让execve系统调用返回到用户态时执行新程序?
- 修改int 0x80压入内核堆栈的EIP
- loadelfbinary -> ** start_thread** 通过修改内核堆栈中EIP的值作为新程序的起点。
sys_execve的内部处理过程
- ELF可执行文件会被默认映射到0x8048000这个地址。
- 需要动态链接的可执行文件先加载链接器ld
- 将CPU控制权交给ld来加载依赖库并完成动态链接。
- 对于静态链接库的文件elf_entry是新程序执行的起点。
使用gdb跟踪sys_execve内核函数的处理过程
可执行程序的装载与庄生梦蝶的故事
- 庄生梦蝶 —— 醒来迷惑是庄周梦见了蝴蝶还是蝴蝶梦见了庄周?
- 庄周(调用execve的可执行程序)入睡(调用execve陷入内核),醒来(系统调用execve返回用户态)发现自己是蝴蝶(被execve加载的可执行程序)
浅析动态链接的可执行程序的装载
- 实际上动态链接库的依赖关系会形成一个图。
- 是由内核负责加载可执行程序依赖的动态链接库吗?
- 当一个问件是Interpreter是是依赖的。
- 动态链接库的装载过程是一个图的遍历。
- 装载和链接之后ld将CPU的控制权交给可执行程序。
20135239 益西拉姆 linux内核分析 可执行程序的装载的更多相关文章
- 20135239益西拉姆 Linux内核分析 进程的描述和进程的创建
[益西拉姆 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] 第六周 进程的描述 ...
- 20135239益西拉姆 Linux内核分析 汇编一个简单的c程序并分析其指令过程
益西拉姆+<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 第一周linux内核分析 学习笔记 一.计算机 ...
- 20135239益西拉姆 Linux内核分析 操作系统是怎样工作的?
益西拉姆+ 原创作品+ <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 堆栈 堆栈是C语言程序运行时 ...
- 20135239 益西拉姆 linux内核分析 进程的切换和系统的一般执行过程
week 8 进程的切换和系统的一般执行过程 [ 20135239 原文请转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course ...
- 20135239 益西拉姆 linux内核分析 读书笔记之第四章
chapter 4 进程调度 4.1 多任务 多任务操作系统就是能同时并发的交互执行多个进程的操作系统. 多任务系统可以划分为两类: - 非抢占式多任务: - 进程会一直执行直到自己主动停止运行(这一 ...
- 20135239 益西拉姆 linux内核分析 跟踪分析Linux内核的启动过程
回顾 1.中断上下文的切换——保存现场&恢复现场 本节主要课程内容 Linux内核源代码简介 1.打开内核源代码页面 arch/目录:支持不同CPU的源代码:其中的X86是重点 init/目录 ...
- 20135239 益西拉姆 linux内核分析 扒开系统调用的三层皮(下)
一. 给MenuOS增加time-asm命令 代码解释 1.-rf:强制删除 2.clone :重新克隆 3.time-asm:显示系统时间的汇编形式 给MenuOS增加time和time-asm命令 ...
- 20135239 益西拉姆 linux内核分析 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
https://drive.wps.cn/preview#l/759e32d65654419cb765da932cdf5cdc 本次直接在wps上写的,因为不能连同图片一起粘贴过来,一个一个粘比较费时 ...
- Linux内核分析——可执行程序的装载
链接的过程 首先运行C预处理器cpp,将C的源程序(a.c)翻译成ASCII码的中间文件(a.i) 接着C编译器ccl,将a.i翻译成ASCII汇编语言文件a.s 接着运行汇编器as,将a.s翻译成可 ...
随机推荐
- 01-numpy基础简介
import numpy as np # ndarray ''' # 三种创建方式 1.从python的基础数据对象转化 2.通过numpy内置的函数生成 3.从硬盘(文件)读取数据 ''' # 创建 ...
- C++判断回文
判断一个字符串是否为回文,如“goddog”. 代码: #include <iostream> #include <string> #include <stdio.h&g ...
- 用python实现数字图片识别神经网络--启动网络的自我训练流程,展示网络数字图片识别效果
上一节,我们完成了网络训练代码的实现,还有一些问题需要做进一步的确认.网络的最终目标是,输入一张手写数字图片后,网络输出该图片对应的数字.由于网络需要从0到9一共十个数字中挑选出一个,于是我们的网络最 ...
- spring boot之配置跨域
在启动类中配置 @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override p ...
- 每日Scrum(10)
今天我们小组整合了下我们所编辑的程序,然后在界面上进行了修改和少部分的完善,现在就等着下午的验收了 任务展板 燃尽图如下:
- spring冲刺第十天
调试运行,对整体的游戏方面进行改进.冲刺完了,但依然有很多问题,比如无法暂停,游戏结束后只能退出重来等
- beta冲刺(5/7)
目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:恺琳 组员6:翟丹丹 组员7:何家伟 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4 ...
- C++作业 一
计算圆面积 Github:https://github.com/tinghaishuo/object-oriented/tree/master/circle
- BNUOJ 52305 Around the World 树形dp
题目链接: https://www.bnuoj.com/v3/problem_show.php?pid=52305 Around the World Time Limit: 20000msMemory ...
- 【CSAPP笔记】2. 整型运算
现在想补补推荐这本书的理由. Most books on systems-computer architecture, compilers, operating systems, and networ ...