第一章温故而知新...6
第二节万变不离其宗...6
第3节站得高看得远...7
第4节操作系统的功能...7
1.4.1不要让CPU打盹...7
1.4.2设备驱动...8
1.5内存不够怎么办?...8
1.5.1关于隔离...9
1.5.2分段...9
1.5.3分页...9
1.6众人拾柴火焰高...10
1.6.1线程基础...10
1.6.2线程安全...11
1.6.3多线程内部情况...14
第二章编译和链接...15
2.1被隐藏了的过程...15
2.1.1预编译...15
2.1.2编译...15
2.1.3汇编...15
2.1.4链接...16
2.2编译器做了什么...16
2.2.1词法分析...16
2.2.2语法分析...16
2.2.3语义分析...16
2.2.4中间语言生成...17
2.2.5目标代码的生成与优化...17
2.3链接器年龄比编译器长...18
2.4模块拼接——静态链接...18
第三章目标文件里有什么...18
3.1目标文件的格式...19
3.2目标文件是什么样的...19
3.3挖掘SimpleSection.o.20
3.3.3 BSS段...20
3.3.4其他段...20
3.4 ELF文件结构描述...20
3.4.1文件头...21
3.4.2段表...21
3.4.3重定位表...22
3.4.4字符串表...22
3.5链接的接口——符号...22
3.5.1 ELF符号表结构...23
3.5.2特殊符号...23
3.5.3符号修饰与函数签名...24
3.5.5弱符号和强符号...24
3.6调试信息...25
第4章静态链接...25
4.1空间与地址分配...25
4.1.2相似段合并...25
4.1.3符号地址的确定...26
4.2符号解析与重定位...26
4.2.2重定位表...26
4.2.3符号解析...27
4.2.4指令修正方式...27
4.3 COMMON块...27
4.4.1重复代码消除...28
4.4.2全局构造与析构...29
4.4.3 C++与ABI29
4.5静态库链接...30
4.6链接过程控制...30
4.6.1链接过程脚本...30
4.6.2最“小”的程序...31
4.6.3使用ld链接脚本...31
4.6.4 ld链接脚本语法简介...31
4.7 BFD库...31
第5章WINDOWS PE/COFF.31
5.1 Windows的二进制文件格式PE/COFF.31
5.2 PE的前身COFF.32
5.3链接指示信息...32
5.4调试信息...32
5.5大家都有符号表...32
5.6 WINDOWS下的ELF——PE.32
第6章可执行文件的装载与进程...33
6.1进程的虚拟地址空间...33
6.2装载的方式...33
6.2.1覆盖装入...33
6.2.2页映射...34
6.3从操作系统的角度看可执行文件的装载...34
6.3.1进程的建立...34
6.4进程虚存空间的分布...35
6.4.1 ELF文件链接视图和执行视图...35
6.4.2堆和栈...36
6.4.3堆的最大申请数量...36
6.4.4段地址对齐...36
6.4.5进程栈初始化...37
6.5 Linux内核装载ELF过程简介...37
6.6 Windows PE的装载...38
第7章动态链接...38
7.1为什么要动态链接...38
7.2简单的动态链接例子...39
7.3地址无关代码...40
7.3.1固定装载地址的困扰...40
7.3.2装载时重定位...40
7.3.3地址无关代码...40
7.3.4共享模块的全局变量问题...42
7.3.5代码段地址无关性...43
7.4延迟绑定(PLT)43
7.5动态链接相关结构...44
7.5.1 “.interp”段...45
7.5.2 “dynamic”段...45
7.5.3动态符号表...45
7.5.4动态链接重定位表...45
7.5.5动态链接时进程堆栈初始化信息...46
7.6动态链接的步骤和实现...46
7.6.1动态链接器自举...46
7.6.2装载共享对象...47
7.6.3重定位和初始化...47
7.6.4 Linux动态链接器的实现...47
7.7显示运行时链接...48
7.7.1打开动态库...48
7.7.2 dlsym()48
7.7.3 dlerror()48
7.7.4 dlclose()49
第8章Linux共享库的组织...49
8.1共享库版本...49
8.1.1共享库兼容性...49
8.1.2共享库版本命名...49
8.1.3 SO-NAME程序需要记录什么...50
8.2符号版本...50
8.2.1基于符号的版本机制...50
8.2.3 Linux中的符号版本...51
8.3共享库系统路径...51
8.4共享库的查找过程...51
8.5环境变量...52
8.6共享库的创建与安装...52
8.6.1共享库的创建...52
8.6.3共享库的安装...53
8.6.4共享库构造和析构函数...53
8.6.5共享库脚本...53
第9章Windows下的动态链接...54
9.1 dll介绍...54
9.1.2基地址和RVA.54
9.1.3 dll共享数据段...54
9.1.4 dll的简单例子...54
9.1.7使用模块定义文件...55
9.1.8 DLL显示运行时链接...55
9.2符号导出导入表...55
9.2.1导出表...55
9.2.2 EXP文件...56
9.2.4导入表...56
9.2.5导入函数的调用...56
9.3 DLL优化...57
9.3.1重定基地址...57
9.3.2序号...58
9.3.3导入函数绑定...58
9.4 C++与动态链接...58
9.5 DLL HELL.59
第4部分库与运行库...60
第10章内存...60
10.1程序的内存布局...60
10.2栈与调用惯例...61
10.2.1什么是栈...61
10.2.2调用惯例...61
10.2.3函数返回值传递...62
10.3堆与内存管理...63
10.3.1什么是堆...63
10.3.2 Linux进程堆管理...63
10.3.3 Windows进程堆管理...64
10.3.4堆分配算法...64
第11章运行库...64
11.1入口函数和程序初始化...64
11.1.1程序从main开始执行吗...64
11.1.2入口函数是如何实现的...65
11.1.3运行库与I/O..66
11.1.4 MSVC CRT的入口函数初始化...66
11.2 C/C++运行库...67
11.2.1 C语言运行库...67
11.2.2 C语言标准库...67
11.2.3 glibc和MSVC CRT.67
11.3运行库与多线程...68
11.3.1 CRT的多线程困扰...68
11.3.2 CRT改进...68
11.3.3线程局部存储实现...68
11.4 C++全局构造和析构...69
11.4.1 glibc全局构造和析构...69
11.4.2 MSVC的全局构造和析构...70
11.5 fread的实现...71
11.5.1缓冲...71
11.5.2 fread_s.71
11.5.3 _fread_nolock_s.71
11.5.4 _read.71
11.5.5文本换行...71
11.5.6 fread回顾...72
第12章系统调用与API72
12.1系统调用介绍...72
12.1.1什么是系统调用...72
12.1.3系统调用的弊端...72
12.2系统调用原理...73
12.2.2基于INT的Linux的经典系统调用实现...73
12.2.3 Linux的新型系统调用机制...73
12.3 Windows API73
12.3.1 Windows API概览...74
12.3.2为什么要使用Windows API?...74
第13章运行库的实现...74
13.1 C语言运行库...74
A.1字节序...74