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

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

目标文件定义和引用符号,每个符号对应于一个函数、一个全局变量一个静态变量(即C语言中任何以 static属性声明的变量)。符号解析的目的是将每个符号引用正好和一个符号定义关联起来。....data:已初始化的全局和静态C变量。局部C变量在运行时被保存在栈,既不出现在,data节,也不出现在.bss节 .bss:初始化的全局和静态C变量,以及所有被初始化为0的全局静态变量。...全局链接器符号对应于非静态的C函数和全局变量。   由其他模块定义并被模块m引用的全局符号。这些符号称为外部符号,对应于在其他模块定义的非静态C函数和全局变量。   只被模块m定义和引用的局部符号。...多个目标文件可以定义相同的符号,而链接器用来悄悄地解析这些多重定义的规则可能在用户程序引入微妙的错误。   多个目标文件可以被连接到一个单独的静态。链接器用解析其他目标模块符号引用。...链接器还可能生成部分链接的可执行目标文件,这样的文件中有对定义在共享的例程和数据的解析的引用。

2.6K31

CSAPP---第七章-链接

c变量在运行时被保存在栈 .bss: 存放初始化的全局和静态c变量,以及所有被初始化为0的全局静态变量。...value属于初始化的全局变量,存放于COMMON,COMMON和.bss的区别如下: common: 存放初始化的全局变量 .bss: 存放初始化的静态变量,以及初始化为0的全局静态变量...---- 符号解析 链接器解析符号引用的方法就是将每个引用与它输入的可重定位目标文件的符号的一个确定符号定义关联起来。...,那么链接器就尝试匹配U解析符号和由静态文件成员定义的符号,如果在某个静态文件成员m定位到了U某个解析符号,那么就将m添加到E,并通过修改U和D来反映m符号定义和引用。...链接器还可能生成部分链接的可执行目标文件,这样的文件中有对定义在共享的例程和数据的解析的引用。

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

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

链接器主要完成符号解析和重定位两个任务。 目标文件有三种形式:可重定位目标文件(.so);可执行目标文件(.exe),共享目标文件(.so)。...一般 ELF 包含以下几种 section: .text:可执行机器码 .rodata:只读数据,如字符串常量和 switch 跳转表 .data:已初始化的全局和静态变量 :bss:初始化初始化为...一般来说,修改的是外部函数或者引用全局变量的位置,调用的本地函数的位置则不需要修改。 .rel.data: 引用定义的所有全局变量的重定位信息。 .debug:调试符号表。...弱全局符号分配在 COMMON section ,强全局符号分配在 .bss 静态用于共享重复的代码,链接器仅会拷贝需要的函数。也可以通过参数拷贝所有函数。...这样的话因为是顺序的,如果把静态放在前面,则会错过后面目标文件的匹配,从而在链接完所有文件,却还是有未定义符号,结果编译报错。 所以一般做法是静态文件放在最后。

98930

整理《阿里巴巴Java开发手册》常用的编码规约

2、括号是数组类型的一部分,数组定义如下:String[] args; 3、POJO类布尔类型的变量,都不要加is,否则部分框架解析会引起序列化错误。...6、接口类方法和属性不要加任何修饰符号(public 也不要加),保持代码的简洁性,并加上有效的Javadoc注释。...1) 跨应用共享常量:放置在二方,通常是client.jar的constant目录下。      2) 应用内共享常量:放置在一方的modules的constant目录下。...18、避免通过一个类的对象引用访问此类的静态变量静态方法,无谓增加编译器解析成本,直接用类名来访问即可。 19、所有的覆写方法,必须加@Override注解。 20、不能使用过时的类方法。...3) 类方法确定不允许被重写。 31、类成员与方法访问控制从严:      1) 如果不允许外部直接通过new来创建对象,那么构造方法必须是private。

63330

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

共享的目标文件 (.so) 特殊的可重定位目标文件,能在装入运行时被装入到内存并自动被链接,称为共享文件,Windows 称其为 Dynamic Link Libraries (DLLs)。....data:已初始化的全局和静态C变量。 .bss:初始化的全局和静态C变量,以及所有被初始化为0的全局静态变量。 .symtab:符号表,存放函数和全局变量的信息。...数据结构: 维护三个动态变化的集合E、U和D E:可重定位目标文件集合,被引用的目标文件将被拷贝到可执行文件; U:随着链接的展开而发现的解析符号集合,成功链接后最终该集合为空; D:所有输入文件解析符号集合...,匹配的加入到U; b)f是静态,将U符号与f定义的符号相匹配,存在匹配模块m上的符号,E = E U {m},否则丢弃该。...动态链接共享(shared library,又称共享动态链接) 目标文件,包含有代码和数据。 从程序中分离出来,磁盘和内存中都只有一个备份。 可在装入时或运行时被动态加载并链接。

20920

C语言头文件j解析

通过头文件包含的方法将程序的各功能模块联系起来有利于模块化程序设计: 1)通过头文件调用功能。在很多场合,源代码不便(不准)向用户公布,只要向用户提供头文件和二进制即可。...五、 注解 「【注1】全局变量的使用原则」 1)若全局变量仅在单个源文件访问,则可将该变量改为该文件内的静态全局变量; 2)若全局变量仅由单个函数访问,则可将该变量改为该函数内的静态局部变量; 3)尽量不要使用...规则二:若存在一个强符号和多个弱符号,则选择强符号。 规则三:若存在多个弱符号,则从这些弱符号任选一个。 当不同文件内定义同名(即便类型和含义不同)的全局变量时,该变量共享同一块内存(地址相同)。...若变量定义时均初始化,则会产生重定义(multiple definition)的链接错误;若某处变量定义时初始化,则无链接错误,仅在因类型不同而大小不同时可能产生符号大小变化(size of symbol...这种风险在使用无法接触源码的第三方时尤为突出。 因此,应尽量避免使用全局变量。若确有必要,应采用静态全局变量(无强弱之分,且不会和其他全局符号产生冲突),并封装访问函数供外部文件调用。

1.9K88

C语言头文件组织与包含原则

通过头文件包含的方法将程序的各功能模块联系起来有利于模块化程序设计: 1)通过头文件调用功能。在很多场合,源代码不便(不准)向用户公布,只要向用户提供头文件和二进制即可。...五、 注解 「【注1】全局变量的使用原则」 1)若全局变量仅在单个源文件访问,则可将该变量改为该文件内的静态全局变量; 2)若全局变量仅由单个函数访问,则可将该变量改为该函数内的静态局部变量; 3)尽量不要使用...规则二:若存在一个强符号和多个弱符号,则选择强符号。 规则三:若存在多个弱符号,则从这些弱符号任选一个。 当不同文件内定义同名(即便类型和含义不同)的全局变量时,该变量共享同一块内存(地址相同)。...若变量定义时均初始化,则会产生重定义(multiple definition)的链接错误;若某处变量定义时初始化,则无链接错误,仅在因类型不同而大小不同时可能产生符号大小变化(size of symbol...这种风险在使用无法接触源码的第三方时尤为突出。 因此,应尽量避免使用全局变量。若确有必要,应采用静态全局变量(无强弱之分,且不会和其他全局符号产生冲突),并封装访问函数供外部文件调用。

4.9K32

一文领略链接与装载

多个进程可以共享内存的只读数据,比如代码段和图片资源等(参考共享原理),节约内存占用。...这个外部符号可能定义在其它目标文件(这部分不考虑定义在共享文件的情况),如何修正外部符号的引用正是静态链接的核心问题。...符号解析与重定位 基于前面介绍的各种段结构,符号解析与重定位过程实际上非常简单,无非就是根据重定位入口的符号符号表的下标,找到该符号对应的目标地址,找出重定位表对应的段,根据重定位入口的偏移填入这个目标地址...和目标文件一样,共享对象数据段若有绝对地址引用,会生成对应的重定位表,当动态链接器把这个共享对象装载后,会根据重定位表将数据段的地址引用修正。这个方法叫做 装载时重定位 。...这时编译器其实判断不了这个符号是定义在内部还是外部的,就不知道该不该分配空间。在共享编译时,编译器处理方式是默认把定义在模块内部的全局变量当做定义在其它模块,通过 GOT 实现。

87430

体系结构复习笔记

image.png 14.3 符号解析 image.png 全局链接器符号:当前模块定义的非静态的C函数和全局变量 外部符号:其他模块定义的非静态的C函数和全局变量 局部符号:带static属性的...静态解析符号解析阶段,链接器从左到右按照它们在编译器驱动程序命令行上出现的顺序来扫描可重定位目标文件和存档文件。...在扫描过程,链接器维护一个可重定位目标文件集合E、一个解析(即已引用但尚未定义)的符号集合U、一个已定义的符号集合D 缺点: 存储时磁盘空间存在大量冗余 运行时内存空间存在大量冗余 更新导致所有程序需要显示重新链接...[注]静态文件是.a文件,一种归档文件。...动态解析 链接:加载时或运行时 打桩机制: 编译时:显示函数包装 链接时:链接符号时替换 加载/运行时:通过dlsym实现定制版函数 14.4 重定位 15.

2.4K30

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

3,可执行文件,动态链接静态链接都按照可执行文件格式存储(Windows下是 PE-COFF格式,Linux下是ELF格式)。...描述文件各个段的数组(各个段在文件的偏移和属性)。 5,  关于bss段:初始化的全局变量和静态局部变量一般放在一个”.bss”段的地方。...它只是为初始化的全局变量和静态局部变量预留位置而已,并没有内容,在文件不占空间。 6,  总体来说:程序源代码被编译后主要分成两种段:程序指令(代码段),程序数据(数据段,bss段)。...(2)       在本目标文件引用的全局符号,在别的目标文件定义。一般叫做外部符号(external symbol)。...7,弱符号和弱引用对来说非常有用,比如定义的弱符号可以被用户定义的强符号所覆盖。

1K60

Android对so体积优化的探索与实践

使用 static 关键字控制符号可见性 在C/C++语言中,static 关键字在不同场景下有不同意义,当使用 static 表示“该函数变量仅在本文件可见”时,那么这个函数变量就不会出现在动态符号...在项目开发,使用 static 关键字声明一个函数变量“仅在本文件可见”是很好的习惯,但是不建议使用 static 关键字控制符号可见性:无法使用 static 关键字控制一个多文件可见的函数变量的符号可见性...使用 exclude libs 移除静态符号 上述 visibility 方式、attribute 方式和 static 关键字,都是控制项目源码符号的可见性,而无法控制依赖的静态符号在最终...exclude libs 就是用来控制依赖的静态符号是否可见,它是传递给链接器的参数,可以使依赖的静态符号在动态符号不存在。...如果项目工程依赖了静态,可以使用 LTO 方式重新编译该静态,那么编译动态时,就能移除静态的 DeadCode,从而减小最终 so 的体积。

2.3K31

Visual StudioMD MDd MT MTd的含义以及_ITERATOR_DEBUG_LEVEL错误的解决方法

函数的可执行代码位于一个 DLL ,该 DLL 包含一个多个已被编译、链接并与使用它们的进程分开存储的函数。DLL 还有助于共享数据和资源。多个应用程序可同时访问内存单个DLL 副本的内容。...静态和动态是两种共享程序代码的方式,它们的区别是:静态在程序的链接阶段被复制到了程序,和程序运行的时候没有关系;动态在链接阶段没有被复制到程序,而是程序在运行时由系统动态加载到内存供程序调用...定义 _MT 和 _DLL,并使编译器将名 MSVCRT.lib 放入 .obj 文件。 用此选项编译的应用程序静态链接到 MSVCRT.lib。 此提供允许链接器解析外部引用的代码的层。...定义 _MT 并使编译器将LIBCMT.lib 放入 .obj 文件,以便链接器使用 LIBCMT.lib 解析外部符号。 /MTd 定义 _DEBUG 和 _MT。...此选项还使编译器将名 LIBCMTD.lib 放入 .obj 文件,以便链接器使用 LIBCMTD.lib 解析外部符号

1.6K20

一文带你了解静态和动态

,那么你就需要指定要链接的,本文中需要链接libm.solibm.a。...放在最后时它是这样的一个解析过程: 链接器从左往右扫描可重定位目标文件和静态 扫描main.o时,发现一个解析符号exp,记住这个解析符号 扫描libm.a,找到了前面解析符号,因此提取相关代码...最终没有任何解析符号,编译链接完成 那如果将-lm放在前面,又是怎样的情况呢?...链接器从左往右扫描可重定位目标文件和静态 扫描libm.a,由于前面没有任何解析符号,因此不会提取任何代码 扫描main.o,发现解析符号exp 扫描结束,还有一个解析符号,因此编译链接报错...什么是动态 动态静态类似,但是它并不在链接时将需要的二进制代码都“拷贝”到可执行文件,而是仅仅“拷贝”一些重定位和符号表信息,这些信息可以在程序运行时完成真正的链接过程。

93420

linux动态静态

一、静态解析符号引用: 链接器ld是如何使用静态解析引用的。在符号解析阶段,链接器从左至右,依次扫描可重定位目标文件(*.o)和静态(*.a)。...在这个过程,链接器将维持三个集合: 集合E:可重定位目标文件(*.o文件)的集合。 集合U:解析(未定义)的符号集,即符号UNDEF的符号。...2、如果f是一个静态(.a),那么链接器将尝试匹配U解析符号静态成员(静态的成员就是.o文件)定义的符号。...如果静态某个成员m(某个.o文件)定义了一个符号解析U引用,那么将m加入E,    同时使用m的符号表,来更新U、D。对静态中所有成员目标文件反复进行该过程,直至U和D不再发生变化。...解决方法: 解决的办法是采用“rm+cp” “mv+cp” 来替代直接“cp” 的操作方法。 linux系统的动态有两种使用方法:运行时动态链接,动态加载并在程序控制之下使用。

12.2K20

连接器工具错误lnk2019_2019年十大语文错误

文章目录 可能的原因 1.不编译包含符号定义的源文件 2.链接包含符号定义的对象文件 3.符号声明的拼写与符号的定义不同 4.使用了函数,但是参数的类型数量与函数定义不匹配 5.已声明但未定义函数变量...可能的原因 有多种方法可获取此错误。 所有这些都涉及到链接器无法解析的函数变量的引用,查找的定义。 编译器可以确定符号未声明的时间,但无法判断符号未定义的时间。...这是因为定义可能位于不同的源文件。 如果某个符号被引用但从未定义,则链接器将生成一个无法解析的 :::no-loc(extern)::: al 符号错误。...2.链接包含符号定义的对象文件 在 Visual Studio ,请确保包含符号定义的对象文件链接为项目的一部分。 在命令行上,确保要链接的文件列表包含对象文件。...如果根本没有定义此方法,则链接器会生成 LNK2019。 9.生成依赖项仅在解决方案定义为项目依赖项 在 Visual Studio 的早期版本,此级别的依赖项已经足够。

4.1K20

【编程基础】C语言内存使用的常见问题

规则二:若存在一个强符号和多个弱符号,则选择强符号。 规则三:若存在多个弱符号,则从这些弱符号任选一个。 当不同文件内定义同名(即便类型和含义不同)的全局变量时,该变量共享同一块内存(地址相同)。...若变量定义时均初始化,则会产生重定义(multiple definition)的链接错误;若某处变量定义时初始化,则无链接错误,仅在因类型不同而大小不同时可能产生符号大小变化(size of symbol...这种风险在使用无法接触源码的第三方时尤为突出。 【对策】 尽量避免使用全局变量。若确有必要,应采用静态全局变量(无强弱之分,且不会和其他全局符号产生冲突),并封装访问函数供外部文件调用。...例如,同样是free接口,其调试版与发布版、单线程与多线程的实现均有所不同。一旦链接错误的,则可能出现某个内存管理器中分配的内存,在另一个内存管理器释放的问题。...; Ÿ 程序能够请求未被释放的内存(如共享内存),甚至在程序终止时; Ÿ 泄漏发生在操作系统内部关键驱动; Ÿ 内存受限,如嵌入式系统便携设备; Ÿ 某些操作系统在程序运行终止时并不自动释放内存

3.2K60

error adding symbols: DSO missing from command line

它发生的主要原因是未在链接命令中指定所需的共享对象。编译器试图将缺失的作为符号添加到你的程序,但由于找不到该,编译过程失败并显示上述错误消息。...解决方案 以下是几种可能的解决方案,你可以根据具体情况选择其中一种多种方法。 1. 添加共享对象路径 错误消息中提到的共享对象(DSO)可能位于系统的非标准路径。...检查库文件是否存在 错误消息中提到的共享对象可能不存在于系统。请确保你在链接时使用的是正确的名称,并确保文件实际存在于所指定的路径。如果文件被移动删除,你需要重新安装更新所需的。...DSO的特点 动态加载和链接: DSO在程序运行时动态加载和链接,它与静态不同,静态需要在编译时链接到可执行文件。...动态符号解析: 在程序运行时,DSO的符号(函数、变量等)被动态解析,这意味着可以在程序运行期间替换更新共享,从而改变程序行为修复bug。

89110

编译器、链接器和解释器

如果有多个目标文件存在相同名称的符号,链接器会根据不同的规则解决冲突。...目标文件通常是由编译器生成的二进制文件,包含函数和变量的定义以及对其他符号的引用;而文件则包含预编译的目标文件(静态链接,如 .a .lib 文件)。 2....依赖解析(Library Dependency Resolution): 3.1 静态链接(Static Linking): 在静态链接,链接器会将程序所依赖的(如 .a .lib 文件)的代码和数据直接嵌入到最终的可执行文件...这些代码和数据存储在系统的共享(也称为动态链接共享对象,如 .so .dll 文件)。多个程序可以共享同一个的实例,减少了存储空间和系统资源的浪费。...动态链接可能发生在两个时机: 加载时的动态链接:操作系统会在执行可执行文件之前,将所需的共享加载到内存。这时,链接器会解析可执行文件的引用,将这些引用关联到所加载的共享的实际函数和变量。

25520

虚拟机类加载机制

生成这 4 条指令的最常见的 Java 代码场景是:使用 new 关键字实例化对象的时候、读取设置一个类的静态字段(被 final 修饰、已在编译期把结果放入常量池的静态字段除外)的时候,以及调用一个类的静态方法的时候...加载阶段完成后,虚拟机外部的二进制字节流就按照虚拟机所需的格式存储在方法区之中,方法的数据存储格式由虚拟机实现自行定义,虚拟机规范规定此区域的具体数据结构。...解析动作主要针对类接口、字段、类方法、接口方法方法类型、方法句柄和调用点限定符 7 类符号引用进行。...类接口的解析 字段解析方法解析 接口方法解析 3.5 初始化 类初始化阶段是类加载过程的最后一步,前面的类加载过程,除了在加载阶段用户应用程序可以通过自定义类加载器参与之外,其余动作完全由虚拟机主导和控制...lib目录也不会被加载) 类加载到虚拟机内存

16910

【Rust 漫画】揭开 Hello World 二进制文件巨大之谜

静态链接: 默认情况下,Rust 产生的二进制是静态链接的,这意味着所有用到的和函数都被直接包含在生成的文件,而不是在运行时动态地加载。...程序可能直接使用,但它们被包括在了编译的输出。...死代码消除: Rust编译器会分析代码,确定哪些函数、变量和其他结构是使用的。在编译和链接的过程,所有使用的代码(死代码)都不会出现在最终的二进制文件。 Rust的标准是模块化的。...当你使用某个特定的模块功能时,只有那部分代码会被拉入最终的二进制。例如,如果你的代码从标准只使用了 Vec 和 println!,那么只有与这些功能相关的代码部分会被包括进来。...静态链接的影响:尽管 Rust 进行了死代码消除,但静态链接仍然可能会导致较大的二进制文件,因为所有必要的代码都被包含在单个文件。这与动态链接相反,其中二进制文件依赖于外部共享

53120
领券