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

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

链接器主要完成符号解析重定位两个任务。 目标文件有三种形式:可重定位目标文件(.so);可执行目标文件(.exe),共享目标文件(.so)。...弱全局符号分配在 COMMON section 中,强全局符号分配在 .bss 中。 静态用于共享重复代码,链接器会拷贝需要函数。也可以通过参数拷贝所有函数。...gcc 静态链接是按顺序进行。...遇到目标文件 .o 时会把未定义已定义符号保存起来,遇到存档文件 .a 时,除了前面的操作,还会把 .a 成员符号与未定义符号比较,把匹配成员符号对应 .o 链接起来。...这样的话因为是顺序,如果把静态放在前面,则会错过后面目标文件匹配,从而在链接完所有文件,却还是有未定义符号,结果编译报错。 所以一般做法是静态文件放在最后。

98930

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

4.1 精简动态符号表 使用 visibility attribute 控制符号可见性 可以通过给编译器传递 -fvisibility=VALUE 控制全局符号可见性,VALUE 常取值为 default...使用 exclude libs 移除静态符号 上述 visibility 方式、attribute 方式 static 关键字,都是控制项目源码中符号可见性,而无法控制依赖静态符号在最终...exclude libs 就是用来控制依赖静态符号是否可见,它是传递给链接器参数,可以使依赖静态符号在动态符号表中不存在。...script 方式可以控制编译进 so 静态符号是否导出,visibility attribute 方式都无法做到这一点。...具体来讲,就是可以删除 liba.so libb.so 动态符号表中所有导出符号,以及 libx.so 动态符号表中 liba.so libb.so 中导入符号

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

静态链接动态链接区别

:sub.o ,add.o无论是静态文件还是动态文件,都是由 .o 文件创建。...2.3、由 .o 文件创建.a静态ar crlibmymath.a sub.o add.oar:静态函数创建命令-c :create意思-r :replace意思,表示当前插入模块名已经在库中存在...例如:我们将创建动态名为mymath,则动态文件名就是libmamath.so。用gcc来创建动态。在系统提示符下键入以下命令得到动态文件libmamath.so。...shared :生成共享3.2、隐式方式使用动态在程序中隐式使用动态使用静态完全一样,也是在使用到这些公用函数源程序中包含这些公用函数原型声明,然后在用gcc命令生成目标文件时指明动态名进行编译...使用G++对其进行编译:g++ -fPIC -shared b1.c -o libb.so编译成功!可见GCCG++对于这种全局变量初始化方法,支持力度是不一样

7.9K21

CSAPP---第七章-链接

CSAPP---第七章-链接 什么是链接 目标文件 目标文件格式 可重定位目标文件格式 符号符号符号解析 多重定义全局符号处理 静态 静态解析过程 重定位 重定位条目 可执行文件...在链接器上下文中,符号又分为以下三类: 由模块m定义并能被其他模块引用全局符号全局符号对应于 非静态c函数全局变量 由其他模块定义并被模块m引用全局符号,这些符号被称为外部符号,对应于在其他模块中定义静态...在Linux系统中,静态以一种称为存档特殊文件格式存放在磁盘中,存档文件是一组连续可重定位目标文件集合,有一个头部用来描述每个成员目标文件大小位置,存档文件名由后缀.a标识。...所有引用该可执行目标文件共享这个 .so 文件中代码和数据,而不是像静态内容那样被复制嵌入到引用它们可执行文件中。...这里涉及到CSAPP第九章要讲虚拟内存机制,该章节中会探讨如何实现共享 静态共享构造对比如下: 动态链接基本思路是当创建可执行文件时,静态执行一些链接,然后在程序加载时,动态完成链接过程

81410

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

小心两个共享共用同一个静态.pdf 注:以下内容针对Linux/GCC环境,不涵盖Windows,包括Cygwin环境。....html(Linux上制作可执行共享示例) 问1:如果测试中全局变量global_var是个带构造析构类对象,会如何?...原因是在使用dlopen动态加载共享时,如果静态中包含有全局变量,可能会出现名同地址不同全局变量。 解决办法:总是使用RTLD_GLOBAL加载共享,而不是RTLD_LOCAL。...如果被依赖不是静态,而是共享,则无论何种方式都不存在问题 为何即使RTLD_GLOBAL加载,也会执行两次构造析构?...--retain-symbols-file表示不丢弃未定义符号需要重定位符号 --export-dynamic 创建一个动态连接可执行程序时, 把所有的符号加到动态符号表中

2.6K50

动态静态优缺点比较分析_c静态动态区别

使用方法上分库大体上可以分为两类:静态共享。在windows中静态是以 .lib 为后缀文件,共享是以 .dll 为后缀文件。...b.o 共享: 同静态一样编译成目标文件:gcc –c a.c b.c 生成共享:gcc –fPIC –shared –o libshared.so a.o b.o 由此可见静态动态都是对目标文件处理...(四) 静态 在linux环境中, 使用ar命令创建静态文件.如下是命令选项: d —–指定静态文件中删除文件 m —–把文件移动到指定静态文件中...创建文件之后,可以创建这个静态文件索引来帮助提高连接其他程序编译速度: 使用ranlib程序创建索引,索引存放在库文件内部....ranlib libapue.a 用nm程序显示存档文件索引,它可以显示目标文件符号 nm libapue.a | more 如果是显示目标文件符号: nm error.o | more 如何使用呢

3.1K20

c#封装动态_nginx调用so动态

一般分为两种:静态(.a 、.lib)动态(.so 、.dll )所谓静态、动态是指链接过程。 3、静态与动态 区别: (1)lib是编译时用到,dll是运行时用到。...在使用静态情况下,在编译链接可执行文件时,链接器中复制这些函数和数据并把它们应用程序其它模块组合起来创建最终可执行文件(.EXE文件)。...(1)导出与导入 在ELF(Linux下动态格式),共享中所有的全局函数变量在默认情况下都可以被其他模块使用,即ELF默认导出所有的全局符号。...对于其他DLL导入符号,需要使用“__declspec(dllimport)”显式声明某个符号为导入符号。在ELF中,使用外部符号时,不需要额外声明该符号其他共享对象导入。...// 下列 ifdef 块是创建使 DLL 导出更简单 // 宏标准方法。此 DLL 中所有文件都是用命令行上定义 MYDLL_EXPORTS // 符号编译

2.6K20

Opentelemetry社区在gRPC几个链接问题(静态动态混用,musl工具链,符号裁剪)

问题分析 首先是第一个静态动态混用问题,这个问题早在去年就有人提了issue(“example_otlp_grpc_log” sample not running. libopentelemetry_exporter_otlp_grpc_log.so...这种情况如果我们把 gRPC 编译成静态,并链接进多个动态库里,那么每个动态库里都有一份 gRPC 全局变量函数符号。...而在ELF ABI(Linux)下,情况变得有点不一样了,因为在ELF ABI下整个堆符号表是整个可执行程序共享,ld.so 保证了当多个动态包含相同符号(通常是链接了相同时候,默认选中最早链接进那一个...目前推荐跨平台兼容性比较好做法是对输出呃接口使用符号导出(Windows)或声明为可见(Linux/macOS等),然后把默认可见性改成 -fvisibility=hidden 。...这样能尽可能保证平台一致性,减少不必要符号导出以降低链接器负担。但是即便这样,对于head onlyC++而言,可能会导致可见性切换而导致一些其他告警(比如macOS上STL)。

31820

Linux命令(65)——ld命令

-b :指定目标代码输入文件格式 -Bstatic:只使用静态 -Bdynamic:只使用动态 -Bsymbolic:把引用捆绑到共享全局符号 -c <MRI-commandfile...脚本命令“FORCE_COMMON_ALLOCATION”具有相同效果 -defsym:在输出文件中创建指定全局符号 -demangle:在错误消息中还原符号名称 -e :使用指定符号作为程序初始执行点...这告诉动态链接器,正在创建共享对象符号表应该用作共享对象名称符号筛选器。 -g:被忽略。...=:指定文件读取符号名称地址 -r,--relocatable:生成可重定位输出(称为部分连接) -rpath=:把指定目录添加到运行时搜索路径 -rpath-link...:创建共享 -split-by-file[=size]:为每个目标文件在输出文件中创建额外段大小达到size。

16.9K01

【图片+代码】:Linux 动态链接过程中【重定位】底层原理

也就是说:动态链接器知道每个动态代码段、数据段被加载内存地址,因此动态链接器也会维护一个全局符号表,其中存放着每一个动态导出符号以及它们内存地址信息。...可以看到:在全局符号表中,没有找到liba.so变量a1函数func_a2这两个符号,因为它俩都是static类型,在编译成动态时候,没有导出符号表中。...既然提到了符号表,就来看看这 3 个ELF文件中动态符号表信息: 动态链接中保护两个符号表:.dynsym(动态符号表: 表示模块中符号导出、导入关系) .symtab(符号表: 表示模块中所有符号...而且,在liba.so中,定义了静态、动态全局变量函数,可以很好概况很多种情况,因此这部分内容就主要来分析liba.so这个动态。...通过指令 readelf -r liba.so来查看重定位信息: 黄色绿色矩形框中可以看出: liba.so 引用了外部符号 b,类型是 R_386_GLOB_DAT,这个符号重定位描述信息在

1.7K11

Linux共享静态、动态详解

,它创建两个object文件(a.ob.o),然后创建一个包含a.ob.o共享函数。...首先,你需要创建这些共享函数;然后,设置一些必须得符号链接,特别是soname到真正函数文件符号链接,简单方法就是运行ldconfig: ldconfig -n directory_with_shared_libraries...,它创建两个对象文件(aobo),然后创建一个包含它们共享。...使用-fpic选项通常会生成更小更快代码,但会有平台相关限制,例如全局可见符号数量或代码大小。链接器将告诉您,创建共享时是否适合。如果有疑问,我选择-fPIC,因为它总是有效。...在某些情况下,调用gcc来创建对象文件也需要包含“-Wl,-export-dynamic”选项。通常,动态符号包含动态对象使用符号

8.7K10

【胖虎逆向之路】——GOTPLT Hook详解&针对自定义soHook实操

为了表示动态链接这些模块之间符号导入导出关系,ELF有一个叫做动态符号表(Dynamic Symbol Table)段用来保存这些信息 .rel.dyn:实际上是对数据引用修正,它所修正位置位于...,以机器码形式存储 .dynamic:描述了模块动态链接相关信息 .got:全局偏移表(Global Offset Table),用于记录外部调用入口地址 .data: 数据段,保存那些已经初始化了全局静态变量和局部静态变量...使用~ 当so动态被装载时候,动态链接器linker会将动态装载到进程地址空间,并且将程序中所有没确定符号绑定到相应动态链接中,并进行重定位工作~ 3、重定位 共享进行重定位主要原因是在于导入符号原因...,在动态链接下,可执行文件如果依赖于其他共享对象,也就是说有导入符号时(比如easy_curl_getopt函数),那么它代码或数据中就会有对于导入符号引用,在编译时这些导入符号地址未知,在运行时才确定...来,跑起来~ 使用命令获取: cat /proc/对应进程pid/maps 上图已经列举出了我们应用加载一些so,左边标记红色地址就是各个so基址 addr = base_addr

71841

【一站式解惑】Linux中.a、.so.o文件以及-I,-L,LIBRARY_PATH,LD_LIBRARY_PATH等

DLL内函数分为两种 (1)DLL导出函数,可供应用程序调用; (2)DLL内部函数,只能在DLL程序使用,应用程序无法调用它们 创建静态链接创建动态链接 (1)VC6中创建[Win32 Dynamic-Link...Library]工程便可以创建出一个空DLL工程. (2)VC6中创建[Win32 Static Library]工程便可以创建出一个空LIB工程(静态链接工程,生成一个lib文件)....在Linux下,共享加载是由/lib/ld.so完成,ld.so加载共享时,会ld.so.cache查找。 创建函数示例 我们通常把一些公用函数制作成函数,供其它程序使用。...file or directory 程序hello运行结果中很容易知道,当静态动态同名时,gcc命令将优先使用动态,默认去链接/usr/lib/lib等目录中动态,将文件libmyhello.so...Note:编译参数解析 最主要是GCC命令行选项: -shared 该选项指定生成动态链接(让链接器生成T类型导出符号表,有时候也生成弱链接W类型导出符号),不用该标志外部程序无法链接。

3.7K52

c++DLL编程详解

在仓库发展史上经历了“无静态链接-动态链接时代。 静态链接与动态链接都是共享代码方式,如果采用静态链接,则无论你愿不愿意,lib中指令都被直接包含在最终生成EXE文件中了。...静态链接动态链接另外一个区别在于静态链接中不能再包含其他动态链接或者静态,而在动态链接中还可以再包含其他动态或静态链接。...动态链接版本创建,它只能被用MFC类所编写应用程序所调用。...静态调用:这个方式要与静态调用方式区别开,是由编译系统完成对DLL加载应用程序结束时DLL 卸载。...这是因为,当程序员通过静态链接方式编译生成应用程序时,应用程序中调用与.lib文件中导出符号相匹配函数符号将进入到生成EXE 文件中,.lib文件中所包含与之对应DLL文件文件名也被编译器存储在

2.2K60

Linux下动态(.so)和静态(.a) 区别

动态(共享)代码在可执行程序运行时才载入内存,在编译过程中简单引用,因此代码体积比较小。 不同应用程序如果调用相同,那么在内存中只需要有一份该动态(共享)实例。...静态动态最大区别,静态情况下,把直接加载到程序中,而动态链接时候,它只是保留接口,将动态与程序代码独立,这样就可以提高代码可复用度,降低程序耦合度。...无论静态,还是动态,都是由.o文件创建。...最主要是GCC命令行一个选项: -shared 该选项指定生成动态连接(让连接器生成T类型导出符号表,有时候也生成弱连接W类型导出符号),不用该标志外部程序无法连接。...隐式调用动态静态使用方法一致,使用静态使用动态编译成目标程序使用gcc命令完全一样,那当静态动态同名时,gcc命令会使用哪个文件呢?

16.5K21

动态链接相关结构

2.6.1,那么相应动态链接就是/lib/ld-2.6.1.so。...另外linux还提供了一个命令用来查看一个程序主模块或一个共享依赖于哪些共享: ? 动态符号表 为了完成动态链接,最关键还是所依赖符号相关文件信息。...我们知道在静态链接中,有一个专门段叫做符号表“.symtab”( Symbol Table),里面保存了所有关于该目标文件符号定义引用。...把这种导入导出关系放到静态链接情形下,我们可以把它们看作普通函数定义引用。...动态链接符号结构与静态链接符号表几乎一样,我们可以简单将导入韩式看作是对其他目标文件中函数引用:把导出函数看作是在本目标文件定义函数就可以了; 3.

1.6K20

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

还有,大多数Web服共享动牡动太内 静态链接   像 Linux LD程序这样静态链接器以一组可重定位目标文件命令行参数作为输入,生成一个完全链接、可以加载运行可执行目标文件作为输出。...全局链接器符号对应于非静态C函数全局变量。   由其他模块定义并被模块m引用全局符号。这些符号称为外部符号,对应于在其他模块中定义静态C函数全局变量。   只被模块m定义引用局部符号。...它们对应于带 static属性C函数全局变量。这些符号在模块m中任何位置都可见,但是不能被其他模块引用。 如何解析多重定义全局符号   链接器输入是一组可重定位目标模块。...每个模块定义一组符号,有些是局部(只对定义该符号模块可见),有些是全局(对其他模块也可见)。如果多个模块定义同名全局符号,会发生什么呢?下面是 Linux编译系统采用方法。   ...在 Linux x86-64系统中,代码段总是地址0x400000处开始,后面是数据段。运行时堆在数据段之后,通过调用malloc往上增长。堆后面的区域是为共享模块保留

2.6K31

c++动态静态区别_静态库里面包含动态

——让大家学会创建与使用静态、动态,知道静态与动态区别,知道使用时候如何选择。...有两种:静态(.a、.lib)动态(.so、.dll)。 所谓静态、动态是指链接。...l 空间浪费是静态一个问题。 l 另一个问题是静态对程序更新、部署发布页会带来麻烦。...Linux下创建与使用动态 linux动态命名规则 动态链接名字形式为 libxxx.so,前缀是lib,后缀名为“.so”。...实际上静态本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际执行代码位于动态中,导入库只包含了地址符号表等,确保程序找到对应函数一些基本地址信息。

1.7K30

程序员角度看ELF

链接器然后通过指向程序符号链接器自己符号若干指针来初始化一个符号   表链。概念上讲,程序文件所有加载到进程中共享一个符号表。...dynamic段中,它将符号表加入到符号表链   中,如果该还进一步需要其它尚未加载,则将那些新置入将要加载链表中。   ...在该过程结束时,所有的都被映射进来了,加载器拥有了一个由程序所有映射进   来符号表联合而成逻辑上全局符号表。   ...静态初始化   如果一个程序存在对定义在一个全局变量引用,由于程序数据地址必须在   链接时被绑定,因此链接器不得不在程序中创建一个该变量副本,如图4所示。...当链接器创建一个使用共享程序时,它会列出程序所使用SONAME而不是   真实名称。

93940

深度解密Android中基于pltgothook实现原理

为了表示动态链接这些模块之间符号导入导出关系,ELF有一个叫做动态符号表(Dynamic Symbol Table)段用来保存这些信息。....got:全局偏移表(Global Offset Table),用于记录外部调用入口地址。 .data:数据段,保存那些已经初始化了全局静态变量和局部静态变量。...当共享被装载时候,动态链接器linker会将共享装载到进程地址空间,并且将程序中所有未决议符号绑定到相应动态链接中,并进行重定位工作。...4.3、重定位 共享需要重定位主要原因是导入符号存在。...5.1 .dynsym开始 .dynsym:上面也说到了,这个节里只保存了与动态链接相关符号导入导出关系。

3.3K20
领券