《程序员的自我修养——链接、装载与库》读书笔记
文章平均质量分 57
朝搴夕揽
这个作者很懒,什么都没留下…
展开
-
《程序员的自我修养——链接、装载与库》读书笔记—— 7.6 动态链接的步骤和实现
简述动态链接可以分为以下几个步骤:动态链接器的自举装载共享对象重定位和初始化原创 2021-10-18 08:54:50 · 202 阅读 · 0 评论 -
《程序员的自我修养——链接、装载与库》读书笔记—— 7.5 动态链接相关结构
7.5.x 这几小节看的有点懵,只能多看几遍,慢慢理解。定几个小目标:搞清楚.dynamic, .dynsym, .rel.dyn, .rel.plt 这几个段都保存了哪些信息?这些段能在什么阶段起到什么作用?原创 2021-10-15 08:35:10 · 433 阅读 · 0 评论 -
《程序员的自我修养——链接、装载与库》读书笔记—— 7.4 延迟绑定
为什么需要延迟绑定根据前文所述,动态链接的可执行程序在使用.so 中的符号时,依赖.got 中保存的地址,这个地址是链接器在程序运行时才去填充(或者说绑定)的。如果有大量的符号需要动态链接,这些符号查找地址重定位的工作必定会消耗可观的时间。并且,可能很多动态库中的函数在程序执行完时都不会被调用到,那么对这些函数的查找和重定位的工作就白白浪费了。什么是PLT 延迟绑定PLT(procesure linkage table) 延迟绑定的基本思路就是,在程序第一次被使用的时候,才去进行绑定(符号查找,填充.原创 2021-09-26 08:17:17 · 284 阅读 · 0 评论 -
《程序员的自我修养——链接、装载与库》读书笔记—— 7.1-7.3 动态链接、地址无关码
为什么要动态链接静态链接时,公共库函数会被链接到程序内部,同时运行多个程序时,公共库函数在内存中(磁盘中也一样)就存在多个副本,极大浪费空间。而动态链接库只在内存中有一个副本,所有使用这个动态库的程序都使用这一份副本。(此时你也想到了,对于动态链接库中的可修改数据,比如全局变量,静态局部变量等,每个程序都必须有自己的副本才可以,否则将导致冲突)程序的开发和发布。使用静态链接时,一旦静态库发生改动(比如修了一个小bug),整个程序都必须被重新下载。使用动态链接时则只需要重新下载更新这个动态链接库就可以了原创 2021-09-20 08:26:37 · 144 阅读 · 0 评论 -
《程序员的自我修养——链接、装载与库》读书笔记—— 6.4.5 进程栈初始化
一直以来有个疑惑,在编写一个类似下面的简单的应用程序时,main 函数的两个参数argc, argv谁传给它的?int main(int argc, char *argv[]){ ....}这一小节解答了我的这个疑问。操作系统在启动进程前,会把进程的运行参数argc, argv提前保存到进程的虚拟空间的栈中。同时被报错的栈中的还有系统环境变量。假如我们运行命令prog的同时传入参数123,也就是“./prog 123”,此时的进程栈如下图:栈顶寄存器esp 指向的地址0XBF801FBC原创 2021-09-12 11:24:11 · 122 阅读 · 0 评论 -
《程序员的自我修养——链接、装载与库》读书笔记—— 6.4.1 ELF 文件链接视图和执行视图
查看可执行程序的段表,可以看到一共有33个段。如下图。在ELF被映射时,是以页长度为单位的。如果按照段来映射,那么33个段每个段都要映射到页长的整数倍大小的空间里,这将造成极大的内存空间浪费。其实,操作系统在映射ELF时,关心的只是段的权限(可读、可写和可执行)。因此,可以将相同权限的段合并在一起来进行映射,从而避免大量因对齐导致的内存空间浪费。合并之后的段被称为“Segment”。如下命令可以查看ELF 的Segment。从下图红框位置,还可以看到每个“Segment” 都合并了哪些段(section原创 2021-09-12 09:12:59 · 370 阅读 · 0 评论 -
《程序员的自我修养——链接、装载与库》读书笔记 6.2 装载方式
程序必须从磁盘装载到内存中才可以被执行。最简单的方法就是把程序装载到加载地址即可,但是内存往往不够用。这里介绍了两种典型的装载方式:覆盖装入和页映射。书中的介绍已经很简洁明了,这里就不再概括了。请直接参照书中原文。...原创 2021-08-22 16:17:08 · 121 阅读 · 0 评论 -
objdump和 readelf 的区别
在查看section 时,发现两者的section 下标是不一样的,对于同一个.o,两者的结果如下。可以看到,readelf -S 下标为0的是一个类型为NULL 段,但是objdump -h 的结果不存在这个段。因此,同一个段,在两个结果中的下标是不一样的。比如我碰到的疑问就是,通过readelf -s查看符号表,发现符号所在的段下标和objdump -h出来的段对应不起来。。。所以才有了这篇blog,记录一下zqxl@ubuntu:~/work/practice/_3.4_SimpleSection原创 2021-08-19 08:31:13 · 242 阅读 · 0 评论 -
《程序员的自我修养——链接、装载与库》读书笔记—— 6.3 可执行文件的装载
进程的建立创建一个独立的虚拟地址空间,实际上是创建映射函数所需要的相应的数据结构,该映射函数将虚拟空间映射到物理空间。在linux下,只是分配一个页目录((Page Directory),映射关系可以在后续发生页错误的时候在设置。读取可执行文件头,并且建立虚拟空间与可执行文件的映射关系。当操作系统捕获到缺页错误时,该映射关系便于它知道程序当前所需要的页在可执行义件中的哪一个位置。将CPU ...原创 2019-11-13 10:56:39 · 136 阅读 · 0 评论 -
《程序员的自我修养——链接、装载与库》读书笔记—— 4.6 链接过程控制
对于一些特殊要求的程序,须要指定输出文件的各个段虚拟地址、段的名称、段存放的顺序等。这些程序包括但不仅限于:操作系统内核BIOS ( Basic Input Output System)Boot Loader嵌入式程序脱离操作系统的硬盘分区软件PQMagic等内核驱动程序测试程序为了不使用库,这里使用了嵌入汇编的方式进行系统调用char* str = "Hello World...原创 2019-11-12 20:11:00 · 165 阅读 · 0 评论 -
《程序员的自我修养——链接、装载与库》读书笔记—— 4.5 静态库链接
一种语言的开发环境往往会附带有语言库(Language Library ) 。这些库就是对操作系统的API 的包装,如printf函数在linux下调用的是一个write系统调用,在Windows下是writeConsole系统API一个静态库可以简单地看成一组目标*.o文件的集合,为了便于管理,这些*.o文件被使用"ar"压缩程序压缩为.a文件。如 libc.a:zqxl@ubuntu:/...原创 2019-11-12 09:28:20 · 163 阅读 · 0 评论 -
《程序员的自我修养——链接、装载与库》读书笔记—— 4.1-4.2 空间与地址分配、符号解析与重定位
两步链接法(Two-pass Linking)空间与地址分配,也就是合并不同文件中相同的段符号解析与重定位,读取输入文件中段的数据、重定位信息,井且进行符号解析与重定位、调整代码中的地址等测试程序/*a.c*/extern int shared;int main(){ int a = 100; swap(&a, &shared);}/*b.c...原创 2019-11-11 22:23:21 · 237 阅读 · 0 评论 -
《程序员的自我修养——链接、装载与库》读书笔记—— 3.5 链接的接口:符号
概念符号(Symbel):函数和变量符号名(Symbel Name):函数名和变量名每个目标文件中都有符号表(Synbel Table),其中包含有:全局符号,包括本文件中的函数,以及全局变量外部符号,本目标文件中引用但未定义的符号局部符号,主要为局部变量,在链接过程中不起作用段名(如".text",".bss"),由编译器产生,其值为该段的起始地址。行号信息,目标文件指令对应源...原创 2019-11-10 12:28:51 · 342 阅读 · 0 评论 -
《程序员的自我修养——链接、装载与库》读书笔记—— 3.4 ELF文件结构
elf 文件查看常用命令:readelf:查看elf文件 -h:查看elf文件头objdump:查看elf文件 -s:打印所有段的内容 -d:将指令内容反汇编size:查看elf各段的长度将变量放入指定的名为“FOO1”的段中__attribute__((section("FOO1"))) int var=126; elf文件结构:文件头:整个elf文件的基本属性,包括...原创 2019-11-09 17:37:09 · 219 阅读 · 0 评论