首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C++系列:链接器是如何工作

多年来,链接认为是相当直接和无趣。然而,随着共享和动态链接在现代操作系统中重要性越来越高,链接是一个复杂过程,它为有知识程序员提供了强大功能。...例如,许多软件产品在运行时使用共享来升级压缩打包二进制文件。此外,许多web服务器依赖于共享动态链接来提供动态内容。 2.链接器是啥呢?...链接器:又译为链接器、连结器,是一个程序,将一个或多个由编译器或汇编器生成目标文件外加,链接为一个可执行文件。...链接器作用:简单讲,链接器工作就是解析未定义符号引用,将目标文件中占位符替换为符号地址。链接器还要完成程序中各目标文件地址空间组织,这可能涉及定位工作。...这里还会有个新名词,什么是定位呢? To:定位,就是将每个符号和内存中一个位置关联起来,然后修改代码中所有对这些符号引用,使它们指向这个内存位置。

1.7K40

《计算机系统2》学习笔记

链接器会解析目标文件之间引用关系,将它们合并成一个完整可执行文件。链接过程中,还会进行地址分配、定位和符号解析等操作。 静态链接与动态链接 完成两个任务:符号解析与定位。...符号解析: 建立符号引用和定义之间联系。 定位: 为每一个引用确定地址。 链接时间:编译时、加载时、运行时。...共享目标文件 (.so) 特殊定位目标文件,能在装入或运行时装入到内存并自动链接,称为共享文件,Windows 中称其为 Dynamic Link Libraries (DLLs)。...静态链接 静态 定义 将相关可定位目标模块打包成一个单独文件。...定位 定位由两步组成:定位节和符号定义,定位节中符号引用定位节和符号定义 赋予指令和全局变量唯一运行时内存地址。

21920
您找到你想要的搜索结果了吗?
是的
没有找到

CSAPP---第七章-链接

解决办法: 相关函数译为独立目标模块,然后封成一个单独静态文件,然后应用程序可以通过命令行指定单独文件名字来使用这些在库中定义函数。...Linux系统中,静态一种称为存档特殊文件格式存放在磁盘中,存档文件是一组连续定位目标文件集合,有一个头部用来描述每个成员目标文件大小和位置,存档文件名由后缀.a标识。...---- 静态解析过程 符号解析阶段,链接器从左到右按照他们在编译器驱动程序命令行上出现顺序来扫描可定位目标文件和存档文件(驱动程序自动将命令行中所有.c文件翻译为.o文件)。...加载时,加载器将部分链接可执行文件映射到内存,然后调用动态链接器,它通过加载共享定位程序中引用来完成链接任务。...译为位置无关代码共享可以加载到任何地方,也可以在运行时多个进程共享。为了加载、链接和访问共享函数和数据,应用程序也可以在运行时使用动态链接器。

83310

深入理解计算机系统(第三版) CSAPP 杂谈,第7章:链接

链接器主要完成符号解析和定位两个任务。 目标文件有三种形式:可定位目标文件(.so);可执行目标文件(.exe),共享目标文件(.so)。....symtab:符号表,存放定义和引用函数与全局变量信息。使用 STRIP 命令可以去掉符号表。 .rel.text:.text 中位置列表,是定位信息。...链接器把目标文件组合起来时候,需要修改这些位置,让各个目标文件链接起来。一般来说,修改是外部函数或者引用全局变量位置,调用本地函数位置则不需要修改。....rel.data: 引用或定义所有全局变量定位信息。 .debug:调试符号表。用 -g 选项编译时候才会得到这张表。 .line:源程序行号与 .text 机器码对应关系。...静态用于共享重复代码,链接器仅会拷贝需要函数。也可以通过参数拷贝所有函数。 gcc 静态链接是按顺序进行

99930

linux动态和静态

静态用.a为后缀, 例如: libhello.a    共享(动态)代码是可执行程序运行时才载入内存,在编译过程中仅简单引用,因此生成可执行程序代码体积较小。...,其中 xxxx 是该lib名称; 动态名字一般为libxxxx.so.major.minor,xxxx 是该lib名称,major是主版本号,minor是副版本号 1.5、可执行程序执行时候如何定位共享...; -fPIC:表示编译为位置独立(地址无关)代码,不用此选项的话,编译后代码是位置相关,所以动态载入时,是通过代码拷贝方式来满足不同进程需要,而不能达到真正代码段共享目的。...一、静态解析符号引用: 链接器ld是如何使用静态来解析引用符号解析阶段,链接器从左至右,依次扫描可定位目标文件(*.o)和静态(*.a)。...在这个过程中,链接器将维持三个集合: 集合E:可定位目标文件(*.o文件)集合。 集合U:未解析(未定义)符号集,即符号表中UNDEF符号。

12.3K20

编译器、链接器和解释器

优化:编译器会进行一系列优化操作,提高生成机器代码性能。这包括代码消除、循环展开、内联函数等优化技术。 目标代码生成:目标代码生成阶段将中间代码或其他中间表示翻译为特定体系结构机器代码。...定位(Relocation): 目标文件和文件通常会包含相对于文件起始位置相对地址,这些地址需要在最终可执行文件中被映射到正确内存地址上。...动态链接可能发生在两个时机: 加载时动态链接:操作系统会在执行可执行文件之前,将所需共享加载到内存中。这时,链接器会解析可执行文件中引用,将这些引用关联到所加载共享实际函数和变量。...运行时动态链接:共享已经加载时加载到了内存中,但链接最终步骤是程序运行时进行。这时,操作系统会确保程序可以正确地访问所需共享函数和变量。...生成可执行文件(Executable File Generation): 完成所有的符号解析、定位依赖解析后,链接器会根据上述步骤结果生成最终可执行文件。

27220

一文领略链接与装载

与弱符号对应还有弱引用,如果弱引用符号有定义,链接器决议该符号,如果弱引用符号未定义,链接器不认为是一个错误。...链接器扫描完所有的定位表,所有的定位入口符号都能在全局符号表中找到,否则链接器就会报符号未定义错误。...装载时定位 共享对象并非完全能多个进程复用(参照上面共享对象实现图),一般只有指令部分是进程共享,而数据部分仍然是进程独立。...和目标文件一样,共享对象数据段中若有绝对地址引用,会生成对应定位表,当动态链接器把这个共享对象装载后,会根据定位表将数据段中地址引用修正。这个方法叫做 装载时定位 。...这些眼熟表名字实际上功能结构和静态链接时那些表非常相似。最大区别就是目标文件定位静态链接时完成,共享对象定位是在装载时完成。 值得提出是可执行文件也可以编译为共享对象形式。

88630

《深入理解计算机系统》(CSAPP)读书笔记 —— 第七章 链接

还有,大多数Web服共享动牡动太内 静态链接   像 Linux LD程序这样静态链接器一组可定位目标文件和命令行参数作为输入,生成一个完全链接、可以加载和运行可执行目标文件作为输出。...符号和符号表   每个可定位目标模块m都有一个符号表,它包含m定义和引用符号信息。链接器上下文中,有三种不同符号:   由模块m定义并能其他模块引用全局符号。...共享目标文件(共享)是在运行时由动态链接器链接和加载,或者隐含地调用程序加载和开始执行时,或者根据需要在程序调用dlopen函数时。   ...加载时,加载器将部分链接可执行文件映射到内存,然后调用动态链接器,它通过加载共享定位程序中引用来完成链接任务。...译为位置无关代码共享可以加载到任何地方,也可以在运行时多个进程共享。为了加载链接和访问共享函数和数据,应用程序也可以在运行时使用动态链接器。

2.6K31

符号解析与定位

使用objdump-d参数可以看到“a.o”代码反汇编结果: objdump -d a.o 我们知道程序代码里面使用都是虚拟地址,在这里也可以看到“main”起始地址0x00000000...没有定位之前,相对偏移置为0xFFFFFFFC(小端),它是常量“-4”补码形式。 让我们来仔细看看这条指令含义。...定位过程中,每个定位入口都是对一个符号引用,那么当链接器须要对某个符号引用进行定位时,它就要确定这个符号目标地址。...比如我们查看“a.o”符号表: GLOBAL”类型符号,除了“main”函数是定义代码段之外,其他两个“ shared和“swap”都是“UND”,即“ undefined”未定义类型,这种未定义符号都是因为该目标文件中有关于它们定位项...所以链接器扫描完所有的输入目标文件之后,所有这些未定义符号都应该能够全局符号表中找到,否则链接器就报符号未定义错误。

1.1K10

小心两个共享共用同一个静态

小心两个共享共用同一个静态.pdf 注:以下内容仅针对Linux/GCC环境,不涵盖Windows,包括Cygwin环境。...原因是使用dlopen动态加载共享时,如果静态中包含有全局变量,可能会出现名同地址不同全局变量。 解决办法:总是使用RTLD_GLOBAL加载共享,而不是RTLD_LOCAL。...如果依赖不是静态,而是共享,则无论何种方式都不存在问题 为何即使RTLD_GLOBAL加载,也会执行两次构造和析构?...原因是两个共享库存在相同代码段,如果依赖共享,则不存在这个问题 -Wl使用 -Wl表示后面的参数传递给链接器,其中l是linker意思。...表示不丢弃未定义符号和需要定位符号 --export-dynamic 创建一个动态连接可执行程序时, 把所有的符号加到动态符号表中

2.6K50

ELF文件及android hook原理

、目的档、共享和核心转储标准文件格式。...ELF文件主要有四种类型: 可定位文件(Relocatable File) 包含适合于与其他目标文件链接来创建可执行文件或者共享目标文件代码和数据。...链接器处理目标文件时,需要对目标文件中某些部位进行定位,即代码段和数据中中那些绝对地址引用位置。对于每个需要定位代码段或数据段,都会有一个相应定位表。...地址无关代码(PIC) 装载时定位是解决动态模块中有绝对地址引用方法之一,但是它有一个很大缺点是指令部分无法多个进程之间共享,这样就失去了动态链接节省内存一大优势。...用readelf查看elf文件动态符号表及它哈希表。 ? 动态链接定位动态链接中,导入符号地址在运行时才确定,所以需要在运行时将这些导入符号引用修正,即需要定位

3.7K81

CC++内存管理

内存映射段是高效I/O映射方式,用于装载一个共享动态内存。用户可使用系统接口创建共享共享内存,做进程间通信。 堆用于程序运行时动态内存分配,堆是可以上增长。 数据段–存储全局数据和静态数据。...它接受一个参数,即所需内存大小(字节为单位),并返回指向这块内存指针。 初始化:malloc不会对分配内存进行初始化,内存中内容是未定义,可能是之前值或者全零,具体取决于操作系统。...如果不对齐,可能导致未定义行为。 安全性:使用定位new时,你需要确保所指定内存区域足够大,容纳完整对象实例,包括可能内部对齐填充。否则,可能会覆盖周边内存,引发严重错误。...标准支持:C++标准提供了一个全局operator new(void*, std::size_t)重载,它不执行任何实际内存分配,专门用于定位new表达式。...这个重载是固定,不能用户自定义版本替代。

3800

变量究竟存储什么地方?

计算机系统中,目标文件通常有三种形式: 1. 可定位目标文件:包含二进制代码和数据,与其他可定位目标文件合并起来,创建一个可执行目标文件。 2....共享目标文件:一种特殊定位目标文件,即我们通常所说动(静)态链接 一个典型定位目标文件如下图所示: 高地址 节头部表 .strtab .line .debug .rel.data .rel.text...下面我们通过符号表来解释变量存储。 每个可定位目标文件都有一个符号表,它包含该文件所定义和引用符号信息。链接器上下文中,有三种不同符号: 1....由该文件定义并能其他模块引用全局符号。即非静态C函数和非静态全局变量,如程序中a,z,swap。 2. 由其他模块定义并该文件引用全局符号。用extern关键字所定义变量和函数。...Vis 目前还没有查到资料,待以后改正 Ndx 通过索引来表示每个节 ABS:不该被定位符号 UND:代表未定义符号(在其他地方定义)

1.7K10

《程序员自我修养》第三章学习笔记

4,ELF文件类型:分为 可定位、可执行、共享目标文件、核心转储文件 3.4.2 段表(除了文件头以外最重要结构) 1,描述了ELF各个段信息(比如每个段段名、段长度、文件中偏移,读写权限及其他属性...3.4.3 定位表 1,一个叫”rel.text”段,类型是”SHT_REL”,就是定位表 2,链接器处理目标文件时,需要对目标文件中某些部位进行定位(即代码段和数据段中那些对绝对地址引用位置...3,这些定位信息都记录在ELF文件定位表里。对于每个需要定位代码段或数据段,都会有一个相应定位表。...5,弱引用与强引用: 强引用:假如链接时没找到该符号定义,链接器就会报符号未定义错误。 弱引用:假如链接时没找到该符号定义,链接器不会报错,默认其为0或是一个特殊值。...7,弱符号和弱引用来说非常有用,比如中定义弱符号可以用户定义强符号所覆盖。

1.1K60

Linux命令(65)——ld命令

-b :指定目标代码输入文件格式 -Bstatic:只使用静态 -Bdynamic:只使用动态 -Bsymbolic:把引用捆绑到共享全局符号 -c ,--mri-script=:为与MRI链接器兼容,ld接受由MRI命令语言编写脚本文件 --cref:创建跨引用表 -d,-dc,-dp:即使指定了可定位输出文件...这告诉动态链接器,正在创建共享对象符号表应该用作共享对象名称符号表筛选器。 -g:忽略。...=:从指定文件读取符号名称和地址 -r,--relocatable:生成可定位输出(称为部分连接) -rpath=:把指定目录添加到运行时搜索路径 -rpath-link...:创建共享 -split-by-file[=size]:为每个目标文件输出文件中创建额外段大小达到size。

17.1K01

【Linux】基础IO --- 软硬链接、acm时间、动静态制作、动静态链接、动静态加载原理…

动态可以多个进程间共享,所以动态链接可执行文件体积更小,节省磁盘空间。操作系统采用虚拟内存机制允许物理内存中一份动态多个进程共享,节省内存空间。 四、本质是什么?...如果我们不想给对方源代码,可以给对方提供.o可定位目标二进制文件和.h头文件,让对方直接进行链接工作,这样方式也可以生成可执行程序。 左侧相当于用的人,右侧相当于写的人。.../mylib/include/ 2.2 链接错误:函数未定义引用文件找不到,搜索路径) 1. 指令执行后产生了链接错误,也就是说预处理、编译、汇编阶段已经没有问题了。...下面是使用ncursesdemo代码,大家也可以vim上玩一下,在编译代码时候,要告诉gcc名称,否则会报连接错误:函数未定义引用。...),然后OS会通过页表将物理内存中动态位置映射到虚拟地址空间中共享区,一旦动态映射到共享区,那么这个起始地址也就立马确定了,完成映射之后,虚拟地址空间中不是有库函数偏移量吗?

3.6K30

程序一定要从main函数开始运行吗?

符号解析与定位:使用第一步收集到所有信息,读取输入文件中段数据及定位信息,进行符号解析和定位,调整代码中地址,将每个段中需要定位指令和数据进行“修补”,使他们都指向正确位置。...对于那些需要定位符号,都会放在定位表里,也叫定位段,即.rel.data、.rel.text等,如果.text段有定位地方,就有.rel.text段,如果.data段有定位地方,就有...: nm -u test.o U _GLOBAL_OFFSET_TABLE_ U puts 对于UND类型,这种未定义符号都是因为该目标文件中有关于他们定位项...,链接器扫描完所有的输入目标文件后,所有这种未定义符号都应该能在全局符号表中找到,否则报符号未定义错误。...I:该符号对另一个符号间接引用 N:debug符号 R:该符号位于只读数据区 T:该符号位于代码段 U:该符号在当前文件未定义,定义别的文件中 ?

1.2K30

编译连接过程总结

UNIX环境下主要有三种类型目标文件: (1)可定位文件 其中包含有适合于其它目标文件链接来创建一个可执行或者共享目标文件代码和数据。...(2)共享目标文件 这种文件存放了适合两种上下文里链接代码和数据。...第一种是链接程序可把它与其它可定位文件及共享目标文件一起处理来创建另一个 目标文件;第二种是动态链接程序将它与另一个可执行文件及其它共享目标文件结合到一起,创建一个进程映象。...例如,某个源文件中函数可能引用了另一个源文件中定义某个符号(如变量或者函数调用等);程序中可能调用了某个文件中函数,等等。所有的这些问题,都需要经链接程序处理方能得以解决。...(2) 动态链接 在此种方式下,函数代码放到称作是动态链接共享对象某个目标文件中。链接程序此时所作只是最终可执行程序中记录下共享对象名字以及其它少量登记信息。

1K31

db2 terminate作用_db2 truncate table immediate

01003 从列函数参数消去 NULL 值。01004 字符串值指定给具有较短长度另一字符串数据类型时截断。01005 SQLDA 中条目数不够。01007 未授予特权。...01657 缓冲池操作在下一次数据重新启动之后才会生效。01665 列名或参数名截断。01667 可能不能使用视图来优化查询处理。...42746 同一类型层次结构中,方法名不能与结构化类型名相同。42748 存储路径对于数据来说已存在或者指定了多次。...4274B XML 模式存储中未找到唯一 XSROBJECT。4274F 安全标号组件中未定义组件元素。4274G 在给定安全标号所使用安全标号策略中未定义安全标号组件。...4274B XML 模式存储中未找到唯一 XSROBJECT。 4274F 安全标号组件中未定义组件元素。 4274G 在给定安全标号所使用安全标号策略中未定义安全标号组件。

7.5K20

Linux静态共享详解及实例

Linux中静态.a为后缀,首先静态实现是文件编译后链接过程中就被载入到了程序中,那么后续程序运行使用就不会再依赖,那么弊端就是将静态载入到程序中会导致程序体积变大,而且如果静态后续进行了更新...而共享.so为后缀,它实现方式是链接过程中不会将载入到程序中,而是生成一个记录表,当程序运行时候再去通过记录表去链接共享,那么这个好处就是程序体积小,而且当有不同程序公用一个时候...首先我们先将这些函数文件编译为.o文件,需要加上-fPIC参数,表示让生成.o文件与路径无关,这一点主要是用于共享操作,单纯只用静态的话可以不加。 ?...首先我们要对.cpp文件进行编译,那么-fPIC这个命令此时就不能少,表示编译文件与路径无关,也就是说生成文件都是相对路径,而不是绝对路径,如果使用绝对路径,那么多个进程共享使用这个时候,会根据这个代码段引用数据对象需要定位..., 定位会修改代码段内容,这就造成每个使用这个.so文件代码段进程在内核里都会生成这个.so文件代码段copy,那么就相当于每个进程都维护了一个自己.so副本,因此就做不到共享了。

3.3K20
领券