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

地址无关码

这个问题另一种表述就是:共享对象在编译不能假设自己进程虚拟地址空间中位置。...Linux和GCC支持这种装载定位方法,我们前面产生共享对象,使用了两个GCC参数“shared”和“-fPIC”,如果只使用“- shared”,那么输出共享对象就是使用装载定位方法...由于可执行文件在运行时并不进行代码定位,所以变量地址必须在链接过程中确定下来。为了能够使得链接过程正常进行,链接器会在创建可执行文件,“bss”段创建一个 global变量副本。...当动态 链接器装载共享对象,如果发现该共享对象有这样定位入口,那么动态链接器就会对 该共享对象进行定位。 实际上,我们甚至可以让代码段也使用这种装载定位方法,而不使用地址无关代码。...但是装载定位共享对象运行速度要比使用地址无关代码共享对象快,因为它省去了地址无关代码中每次访问全局数据和函数需要做一次计算当前地址以及间接地址寻址过程 对于可执行文件来说,默认情况下,如果可执行文件是动态链接

96320

动态链接步骤与实现

在编写动态链接器必须保证不使用任何系统库,运行库;对于第二个条件,动态链接器必须在启动时有一段非常精巧代码可以完成这项艰巨工作而同时又不能使用全局和静态变量。...从这一步开始,动态链接器代码中才可以使用自己全局变量和静态变量。 实际上动态链接器自举代码中,除了不可以使用全局变量和静态变量之外,甚至不能调用函数,即动态链接器本身函数也不能调用。...其实我们在前面分析地址无关代码已经提到过,实际上使用PIC模式编译共享对象,对于模块内部函数调用也是采用跟模块外部函数调用一样方式,即使用 GOT/PLT方式,所以 GOT/PLT没有被定位之前...由于存在这种重名符号被直接忽略问题,当程序使用大量共享对象应该非常小心符号重名问题,如果两个符号重名又执行不同功能,那么程序运行时可能会将所有该符号引用解析到第-个被加入全局符号使用符号符号...在这种情况下,动态链接器就会解析运行时参数,并且进行相应处理_dl_main本身非常长,主要工作就是前面提到对程序所依赖共享对象进行装载、符号解析和定位,我们在这里就不再详细展开了,因为它实现细节又是一个非常大的话题

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

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

小心两个共享库共用同一个静态库.pdf 注:以下内容仅针对Linux/GCC环境,不涵盖Windows,包括Cygwin环境。....html(Linux上制作可执行共享库示例) 问1:如果测试中全局变量global_var是个带构造和析构对象,会如何?...(答案最后) 问2:如果使用-fPIE替代-fPIC编译链接,会是什么结果了?...原因是使用dlopen动态加载共享,如果静态库中包含有全局变量,可能会出现名同地址不同全局变量。 解决办法:总是使用RTLD_GLOBAL加载共享库,而不是RTLD_LOCAL。...表示不丢弃未定义符号和需要定位符号 --export-dynamic 创建一个动态连接可执行程序时, 把所有的符号加到动态符号表中

2.6K50

Linux动态链接库使用

动态链接库与普通程序相比而言,没有main函数,是一系列函数实现。通过shared和fPIC编译参数生产so动态链接库文件。程序调用库函数,只需要连接上这个库即可。...针对二进制文件有用命令 查看文件类型 file 查看二进制文件链接到哪些库 ldd 查看二进制文件里面所包含symbol,T表示加载,U表示undefined symbol nm 读二进制文件里面的信息...所以想把sum.c编译成为一个动态链接库 gcc sum.o -shared -o sum.so 出现错误,提示 /usr/bin/ld: sum.o: relocation R_X86_64_PC32...-fPIC gcc -c sum.c -fPIC -o sum.o gcc sum.o -o shared sum.so 一般,共享编译命令为(曾经实验) 动态链接库 gcc -shared...是生成.o使用,-shared是用来生成动态链接库 以上就是本文全部内容,希望对大家学习有所帮助。

4.7K10

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

符号解析与定位使用第一步收集到所有信息,读取输入文件中段数据及定位信息,进行符号解析和定位,调整代码中地址,将每个段中需要定位指令和数据进行“修补”,使他们都指向正确位置。...对于那些需要定位符号,都会放在定位表里,也叫定位段,即.rel.data、.rel.text等,如果.text段有被定位地方,就有.rel.text段,如果.data段有被定位地方,就有...可以使用objdump查看目标文件定位表。...U puts 对于UND类型,这种未定义符号都是因为该目标文件中有关于他们定位项,链接器扫描完所有的输入目标文件后,所有这种未定义符号都应该能在全局符号表中找到,否则报符号未定义错误。...,要先初始化进程执行环境,如堆分配初始化、线程子系统等,C++全局对象构造函数也是这一期被执行,全局析构函数是main之后执行

1.2K30

CMake和静态库顺序

前言 C/C++程序许多同学被静态库依赖折腾,因为默认情况下要求被依赖库放在依赖它库后面,当一个程序或共享库依赖静态库较多时,可能会陷入解决链接问题坑中。...,这个使用静态库需要注意,否则会报符号找不到问题。...另外,在编译libb.a是不指定liba.a,因为编译一个静态库不会使用到链接选项,而只需要指定需要依赖头文件路径即可。...,-soname=libqhttpd.so -rpath 增加共享库搜索路径 --retain-symbols-file表示不丢弃未定义符号和需要定位符号 --export-dynamic 创建一个动态连接可执行程序时...,对于未使用符号(函数是一种符号),链接器不会将它们链接进共享库和可执行程序。

6.5K50

吴章金: 如何创建一个*可执行*共享

先来看看两类文件区别 当前 Linux 下面的二进制程序标准格式是 ELF,这类格式可以用来表示 4 种不同类型文件: 可定位目标文件(.o),用于静态链接 可执行文件格式,用于运行时创建进程映像...共享目标文件(.so,共享库),协同可执行文件创建进程映像 Core dump(core),运行过程中崩溃自动生成,用于调试 我们来看中间两类: 可执行文件 如果不引用外部库函数,那么所有符号地址是确定...,执行加载后可直接运行 共享库 如果可执行文件用到外部库函数,那么需要通过动态链接器加载引用到共享库并在运行时解析用到相应符号 所以,前者和后者通常情况下是独立存在,是联合行动,两者差异明显:...可执行文件有标准 C 语言程序执行入口 main,而共享库则并没有这类强制要求 后者为了确保可以灵活被多个可执行文件共享,所以,符号地址链接是相对,在装载动态分配和计算符号地址 接下来做个实验具体看看两者区别.../hello.noc hello 通过实验,可以确认“正常”创建出来共享库并不能够直接运行,而是需要链接到其他可执行文件中。

1.1K20

ELF文件及android hook原理

比如”.rel.text”就是针对”.text”定位表,”.rel.data”就是针对”.data”定位表。...第二步 符号解析与定位 使用第一步中收集到信息,读取输入文件中段数据、定位信息,并且进行符号解析与定位、调整代码中地址等 使用ld链接器将”a.o”和”b.o”链接起来: $ld a.o b.o...我们还需要有一种更好方法解决共享对象指令中对绝对地址定位问题。...程序开始执行时,动态链接器都要进行一次链接工作,会寻找并装载所需共享对象,然后进行符号查找地址定位等工作,如此一来,程序运行速度必定会减慢。....dynamic段 这个段里保存了动态链接器所需要基本信息,比如依赖哪些共享对象、动态链接符号位置、动态链接定位位置、共享对象初始化代码地址等。

3.7K81

Linux共享库、静态库、动态库详解

某些情况下使用gcc 来生成object文件,需要使用“-Wl,-export-dynamic”这个选项参数。 通常,动态函数库符号表里面包含了这些动态对象符号。...我建议将链接器名称作为与soname符号链接,因为大多数情况下,如果您更新库,那么您希望链接自动使用它。我问HJ Lu为什么ldconfig不会自动设置链接器名称。...首先,使用gcc -fPIC或-fpic标志创建将进入共享对象文件。-fPIC和-fpic选项可以实现“位置独立代码”生成,这是共享一个要求; 见下文差异。...使用-fpic选项通常会生成更小更快代码,但会有平台相关限制,例如全局可见符号数量或代码大小。链接器将告诉您,创建共享是否适合。如果有疑问,我选择-fPIC,因为它总是有效。...某些情况下,调用gcc来创建对象文件也需要包含“-Wl,-export-dynamic”选项。通常,动态符号表仅包含动态对象使用符号

8.7K10

Linux静态库和共享库详解及实例

简单来说,就相当于一个仓库,把你已经写好功能函数放到库中,然后后续需要通过正确接口去使用相应功能,当然可以把库分享给别人也很方便。...对于两种库使用,需要结合实际情况来选择使用。下面用加减乘除例子来简单实现一下两个库创建。我所用系统是Ubuntu18.04 server版,首先我先把文件夹和一些文件都提前创建好了。...次版本号是向下兼容,也就是说libxxx.so.1.2.0是对libxxx.so.1.1.0兼容,也就是说原有的接口不变情况下添加了一些新特性,提供了新功能。...首先我们要对.cpp文件进行编译,那么-fPIC这个命令此时就不能少,表示编译文件与路径无关,也就是说生成文件都是相对路径,而不是绝对路径,如果使用绝对路径,那么多个进程共享使用这个库时候,会根据这个代码段引用数据对象需要定位..., 定位会修改代码段内容,这就造成每个使用这个.so文件代码段进程在内核里都会生成这个.so文件代码段copy,那么就相当于每个进程都维护了一个自己.so副本,因此就做不到共享了。

3.3K20

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

(3)动态库情况下,有两个文件,一个是引入库(.LIB)文件(实际上也算是一个静态库,只是链接只能把函数DLL入口链接到exe中,而不像真正静态链接库那样将函数体真正链接到exe中 ,通过lib...Linux下,共享加载是由/lib/ld.so完成,ld.so加载共享,会从ld.so.cache查找。 创建函数库示例 我们通常把一些公用函数制作成函数库,供其它程序使用。...在生成动态库,需要使用-fPIC,这样才能生成位置无关代码,达到代码段和数据段共享目的。...如果不加fPIC,则编译出来代码加载需要根据加载到位置进行定位(因为它里面的代码并不是位置无关代码),如果被多个应用程序共同使用,那么它们必须每个程序维护一份so代码副本了。...(因为so被每个程序加载位置都不同,显然这些定位代码也不同,当然不能共享)。

4.1K52

一文领略链接与装载

装载定位 共享对象并非完全能被多个进程复用(参照上面共享对象实现图),一般只有指令部分是进程共享,而数据部分仍然是进程独立。...和目标文件一样,共享对象数据段中若有绝对地址引用,会生成对应定位表,当动态链接器把这个共享对象装载后,会根据定位表将数据段中地址引用修正。这个方法叫做 装载定位 。...对于共享对象指令部分来说,无法使用装载定位来处理 。因为我们说装载实际上是指装载到虚拟空间,那指令部分绝对地址引用就需要根据当前进程虚拟地址进行修正。...如果一个共享对象使用相对寻址访问这个全局符号,发生全局符号介入时就可能需要对这个引用定位了,那么这个共享对象指令部分就不能实现 PIC 了。所以对于全局符号来说,同样采用 GOT 方式来访问。...这些眼熟表名字实际上功能结构和静态链接那些表非常相似。最大区别就是目标文件定位静态链接完成,共享对象定位是在装载完成。 值得提出是可执行文件也可以编译为共享对象形式。

89530

linux动态库和静态库

; -fPIC:表示编译为位置独立(地址无关)代码,不用此选项的话,编译后代码是位置相关,所以动态载入时,是通过代码拷贝方式来满足不同进程需要,而不能达到真正代码段共享目的。...一、静态库解析符号引用: 链接器ld是如何使用静态库来解析引用符号解析阶段,链接器从左至右,依次扫描可定位目标文件(*.o)和静态库(*.a)。...在这个过程中,链接器将维持三个集合: 集合E:可定位目标文件(*.o文件)集合。 集合U:未解析(未定义)符号集,即符号表中UNDEF符号。...替换so文件,如果在不停程序情况下,直接用 cp new.so old.so 方式替换程序使用动态库文件会导致正在运行中程序崩溃。...很多同学在工作中遇到过这样一个问题,替换 so 文件,如果在不停程序情况下,直接用cp new.so old.so方式替换程序使用动态库文件会导致正在运行中程序崩溃,退出。

12.3K20

含大量图文解析及例程 | Linux下ELF文件、链接、加载与库(中)

可执行文件程序头表 我们用readelf -h [fileName]命令查看一个可执行ELF文件ELF头,会发现与可定位ELF文件ELF头有一个重大不同:可定位文件ELF头中 Start of...Linux环境下动态链接对象都是以.so为扩展名共享对象(Shared Object)。 真的是动态链接吗?...关键技术 之前静态链接过程中我们提到过重定位过程,那个时候其实属于链接定位,现在我们需要装载定位 ,主要使用了以下关键技术: PIC位置无关代码 GOT全局偏移表 GOT配合PLT实现延迟绑定技术...动态链接器本身也是.so文件,但是它比较特殊,它是静态链接。本身不依赖任何其他共享对象不能使用全局和静态变量。这是合理,试想,如果动态链接器都是动态链接的话,那么由谁来完成它动态链接呢?...动态链接过程图示 动态链接库构建与使用 创建自己动态链接库 创建号一个动态链接库(如我们libvector.so)之后,我们肯定不可能只在当前目录下使用它,那样他就不能被叫做 ”库“了。

2.4K20

CSAPP---第七章-链接

---- 目标文件 目标文件有三种形式: 可定位目标文件: 包含二进制代码和数据,编译可以和其他可定位文件合并起来,创建一个可执行目标文件。...count是全局符号,根据type可知符号表示是一个数据对象类型,它所在节头部表索引为3,可以定位到.data节中,再根据value表示.data节中偏移量得到对象地址,size表示对象大小。...这样选项调用链接器,遇到多重定义全局符号,触发一个错误,或者使用-Werror选项,它会把所有的警告都变成错误, ---- 静态库 我们可以通过链接器读取一组可定位文件,并把它们链接起来,形成一个可执行文件...这里涉及到CSAPP第九章要讲虚拟内存机制,该章节中会探讨如何实现库共享 静态库和共享库构造对比如下: 动态链接基本思路是当创建可执行文件,静态执行一些链接,然后程序加载,动态完成链接过程...因此,printf函数地址只能回写到数据段内,而不能回写到代码段上。 注意:刚才谈到回写,是指运行时修改,更专业称谓应该是运行时定位,与之相对应还有链接定位

83610

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

UNIX中,使用ar命令创建或者操作静态库 ar     archivefile objfile archivefile:archivefile是静态库名称 objfile:objfile是...相当于一个可执行文件 -fPIC:表示编译为位置独立代码,不用此选项的话编译后代码是位置相关所以动态载入时是通过代码拷贝方式来满足不同进程需要,而不能达到真正代码段共享目的。 -L....例如将libd2.so换成libd.so 显式调用动态库 显式调用动态库,编译无需库文件,执行时动态可存储于任意位置,库里共享对象必须先申请后使用,不同动态库版本,只要其共享对象接口相同,就可以直接动态加载...总结: 编译静态库使用-c选项,再利用ar工具产生.编译动态库方式依不同版本UNXI而定。隐式调用动态库与静态库用法相一致,而显示调用动态库则需要借助动态加载共享库函数族。...通过测试可以发现,当静态库和动态库同名, gcc命令将优先使用动态库.为了确保使用是静态库, 编译可以加上 -static  选项,因此多第三方程序为了确保没有相应动态库时运行正常,喜欢在编译最后应用程序时加入

16.6K21

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

包含二进制代码和数据,其形式可以在编译与其他可定位目标文件合并起来,创建一个可执行目标文件可执行目标文件。包含二进制代码和数据,其形式可以被直接复制到内存并执行。 可执行目标文件。...共享目标文件。一种特殊类型定位目标文件,可以加载或者运行时被动态地加载进内存并链接。   编译器和汇编器生成可定位目标文件(包括共享目标文件)。链接器生成可执行目标文件。...它们对应于带 static属性C函数和全局变量。这些符号模块m中任何位置都可见,但是不能被其他模块引用。 如何解析多重定义全局符号   链接器输入是一组可定位目标模块。...在编译,编译器向汇编器输出每个全局符号,或者是强( strong)或者是弱(weak),而汇编器把这个信息隐含地编码定位目标文件符号表里。...加载,加载器将部分链接可执行文件映射到内存,然后调用动态链接器,它通过加载共享库和定位程序中引用来完成链接任务。

2.6K31

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

并且把代码中所有使用外部符号(变量、函数),都进行了定位(即:把变量、函数地址,都填写到代码段中需要定位地方),因此可执行程序执行时候,不依赖于其它外部模块即可运行。...代码段中引用外部符号,可以在数据段中增加一个跳板:让代码段先引用数据段中内容,然后定位,把外部符号地址填写到数据段中对应位置,不就解决这个矛盾了吗?!...ld-linux.so.2也是一个动态链接库,大部分情况下动态链接库已经被加载到内存中了(动态链接库就是为了共享),操作系统此时只需要把动态链接库所在物理内存,映射到 main进程虚拟地址空间中就可以了...然后第二遍扫描时候,查看每个目标文件中需要定位符号,然后全局符号表中查找该符号被安排在什么地址,然后把这个地址填写到引用地方,这就是静态链接定位。...,重新贴图如下: 因为编译动态库使用了代码位置无关参数(-fPIC),这里虚拟地址从0x0000_0000开始。

1.9K11

linux下 lib文件学习思考

/lib目录中存储着程序运行时使用共享库。通过共享库,许多程序可以重复使用相同代码,并且这些库可以存储一个公共位置上,因此能减小运行程序大小。这个目录包含程序链接使用 各种库。...第三个特点文件名是.so库为共享库(共享库是在运行时候动态加载 )。默认情况下,GCC链接优先使用共享库,只有当共享库不存在才考虑使用静态库。 ...(1)命令格式 ldd [选项] 文件名 (2)主要参数 -d 执行定位并报告丢失函数。 -r 执行对函数和数据对象定位,并报告丢失函数和数据对象。...2、当搜索库文件目录下同时存在该库静态版本和共享版本,链接器优先使用共享版本.so,此时你可以使用-static链接选项指定链接静态版本.a。...需要注意是:定义这两个函数后编译,需要使用 -nostartfiles选项,否则编译器报重复定义错误。

2.5K20
领券