第一章
1.2 万变不离其宗
——》各种平台软硬件差异大,但基本概念和原理是一样
SO,只需掌握一种平台上的技术,就可以举一反三。
我们要掌握的是
X86平台下 系统软件 背后的机理。
——》介绍硬件结构框架
1.3 站得高,望得远
——》系统软件的概念
——》系统软件的结构——层
1.4 操作系统主要做什么:提供抽象接口+管理硬件资源
——》硬件资源(1.CPU;2.Memory&Disk;3.I/O设备)是有限的,如何发挥硬件的全部能力
——》(1.4.1)如何发挥CPU的能力
——》(1.4.2)。。。。I/O设备。。。
——》(1.5)。。。。memory。。。
*********************************NEXT CHAPTER************************************
第二章:编译与链接:“分”析被IDE合并的步骤
2.1 被隐藏了的过程
——》如何用GCC将helloworld的source code形成可执行文件的四个步骤分开
2.2 “编译”器做了什么:四个步骤中的第二步compilation
——》词法分析 | 语法分析 | 语义分析 | 中间语言生成 | 目标代码生成与优化
2.3 “链接”器年龄比编译器长
——》链接器完成2个任务:重定位 | 多个模块间的访问
2.4 模块拼接——静态链接
——》概念:如何将分隔开的各个模块合成 一个 正常工作的整体
——》将两个source code静态链接的基本流程:
Address & Storage Allocation | Symbol Resolution | Relocation
*********************************NEXT CHAPTER************************************
第三章:目标文件里有什么
——》单个source code编译后的文件是“目标文件”。看source code是如何存储在目标文件中的
3.1 目标文件的格式:了解有PE和ELF两种主要格式
3.2 目标文件是什么样的
——》以source code中的“指令”和“数据”分段存放
3.3 挖掘SimpleSection.o
——》学习如何查看ELF文件中的各个段
——》各section解释
3.4 ELF文件结构描述:对ELF至关重要的几个section
——》文件头 | 段表 | 重定位表 | 字符串表
3.5 链接的接口——ELF中的符号表
3.6 调试信息:也可能保存在ELF文件中
*********************************NEXT CHAPTER************************************
第四章:静态链接(按链接各个步骤的先后顺序)
4.1 空间与地址分配
——》如何将两个ELF文件中的各个段合并到一个输出文件中
4.2 符号解析与重定位
——》(4.2.1)重定位概念:单独编译时先将全局符号地址置为某特殊地址,当链接器完成4.1后,就由链接器确定所有符号的虚拟地址
——》(4.2.2)重定位表:每个要重定位的ELF段都有一个重定位表
一个source file中要重定位的地方就是引用外部符号的地方
——》符号解析(?)
4.3 COMMON块
——针对弱符号在多个file中定义的处理
4.4 C++相关问题
——》(4.4.1)消除重复代码(如template等)
——》(4.4.2)C++全局构造和析构
4.5 静态库链接
——》程序如何能够使用操作系统提供的API?
4.6 链接过程控制
——》大多数情况下,使用的是链接器的默认规则,这没问题;
但有一些有特殊要求的程序。
——》如何指定链接脚本(4.6.1)
——》小程序:不使用任何库 | 指定nomain为程序的入口 | 控制链接过程生成特殊段
4.7 BFD库:概念
*********************************NEXT CHAPTER************************************
第六章:可执行文件的装载与进程
——》ELF文件(为什么不说可执行文件?)在Linux下的装载过程
6.1 进程虚拟的地址空间
——》一个进程的虚拟进程空间分为几段:operating system | user process
6.2 装载的方式
——》静态装入
动态装入:覆盖装入
页映射
6.3 从操作系统的角度看可执行文件 的装载
——》详细阐述:一个可执行文件如何被装载 + 如何在进程中执行
——》(6.3.1)进程的建立
——》(6.3.2)页错误
6.4 进程虚拟存储空间分布
——》(6.4.1)ELF文件的链接视图和执行视图:从section到segment
从section到segment转变的原因在于:装载时,操作系统并不关心各section的内容,只关心section的读写权限。SO,将相同权限的section归纳为segment——(最终目的),减少按页映射(装载?)的内存浪费。
——》(6.4.2)VMA映射可执行文件的各个segment
VMA映射进程的stack和heap
(6.4.3略)
——》(6.4.4)段地址对齐:可执行文件如何在 基于页映射机制 的装载中节省空间
——》(6.4.5)进程栈初始化:操作系统在 进程启动前 将系统环境变量和进程的运行参数提前保存到栈中。
6.5 Linux系统如何装载指定ELF文件 + 执行它?(实例)
*********************************NEXT CHAPTER************************************
第七章:动态链接
7.1 为什么要动态链接:节省空间(memory,disk)| 模块更新
——》动态链接基本思想:不对各目标文件进行链接(静态链接),而是等到程序要运行时才进行链接
——》动态链接基本实现
7.2 简单的动态链接例子
7.3 地址无关代码
——》(7.3.1)一个困扰
——》(7.3.2)装载时再重定位:使共享对象能在任意地址装载
——》(7.3.3)地址无关代码:装载时重定位的缺点 | 改进装载时重定位
——》(7.3.4)关于地址无关性问题的另一个问题
——》(7.3.5)以上是共享对象中代码部分“地址无关”,这里是数据段“地址无关”
7.4 延迟绑定PLT:优化动态链接性能的方法
——》需要理解7.3动态链接进行的复杂操作,才能理解针对额外操作的优化方法
7.5 动态链接的相关结构
——》以上是动态链接基本原理,这里是动态链接具体实现基础
7.6 动态链接的实际链接步骤(先后顺序)
——》动态链接器bootstrap | 装载共享对象 | 重定位和初始化
——》(7.6.4)Linux动态链接器的实现
7.7 显示运行时链接:通过API由程序自己控制何时加载/卸载
*********************************NEXT CHAPTER************************************
第十章:内存
10.1 程序的内存布局(和6.1的“进程的虚拟空间”有什么不同,是不是6.1是静态链接下,10.1是动态链接下?)
——》加上动态链接之后进程的地址空间是如何分布的。
10.2 栈与调用惯例
——》(10.2.1)栈的概念
——》(10.2.2)调用惯例:函数如何调用的约定(函数参数的入栈顺序)
——》(10.2.3)函数返回值如何传递:返回值 | 返回结构体
10.3 堆与内存管理
——》Linux 进程 堆管理
——》Windows 进程 堆管理
——》以上是关于“堆在进程的地址空间中是如何分布的”;
另一个问题是“如何按用户需要从堆中分配除一块内存”,这是“堆分配算法”
*********************************NEXT CHAPTER************************************
第十一章:运行库
11.1 入口函数和程序初始化(与4.6最后的小程序有关系吗?)
——》入口函数的概念
——》glibc和MSVC的入口函数实现概述(MSVC的入口函数更清晰)
——》(11.1.3)运行库与I/O的概念
——》(11.1.4)MSVC CRT 入口函数初始化:系统堆初始化 | I/O初始化
11.2 C/C++运行库
——》(11.2.1)C语言 运行库:Runtime Library概念
——》(11.2.2)C语言 标准库:
——》(11.2.3)glibc和MSVC都是C运行库的超集(详解)
11.3(没看):运行库与多线程
11.4 C++全局构造和析构(glibc和MSVC是如何完成这个任务,详解)
——》与4.4有关系吗?
11.5 fread实现
——》fread是C标准库一个重要的I/O函数,SO,是平台无关的
而fread最终在Windows平台上是通过Win提供的API ReadFile()实现的,SO,要打通从fread到ReadFile之间的通路
——》glibc的fread实现过于复杂,SO,这里分析MSVC的实现
——》缓冲的概念
——》(11.5.2~1.5.5)具体细节不重要,但 基本思想 | 分析的工具 重要
*********************************NEXT CHAPTER************************************
第十二章:系统调用和API
12.1 什么是系统调用
——》系统调用是“应用程序”从“操作系统”获得的帮助。
——》(12.1.2)Linux系统调用
——》(12.1.3)系统调用的弊端
12.2 系统调用的原理
——》特权级与中断概念
——》基于int的Linux的经典系统调用实现:
当“应用程序”调用系统调用时,“程序”是如何一步步进入操作系统“内核”调用相应函数的(详解):
触发中断 | 切换堆栈 | 中断处理程序
——》(12.2.3)Linux的新型系统调用机制
原因:基于int指令的系统调用在处理器上性能不佳
新机制的关键在于:使用专门针对系统调用的
指令:sysenter,sysexit
12.3 Windows API
——》(12.3.1)Windows API概览
——》(12.3.2)为什么系统调用不用,还要在CRT和系统调用之间加一层API?
——》(12.3.3)API与子系统的概念
链接,转载与库:GUIDELINE