动态链接库中与地址无关代码(PIC)对于地址引用的处理

【ARM 嵌入式 编译系列 2.8 -- GCC 编译优化参数 位置无关码】 PIC 主要用于共享库(shared libraries)和动态链接库(dynamic link libraries, DLLs),这使得它们可以被多个程序共享,节省内存并减少程序的磁盘占用。位置无关码(PIC)是一种编写和编译技术,生成的机器代码可以在内存中的任何位置执行而无需进行重定位。PIC 主要用于共享库,这使得它们可以被多个程序共享,节省内存并减少程序的磁盘占用。位置无关代码是一种编译生成的机器代码,这种代码可以在内存中的任何位置执行而不需要修改。将目标文件链接为共享库时,通常需要使用。 阅读详情

动态链接库希望所有进程共享指令段而各自拥有数据段的私有副本,为了实现这个目标,就要采用与地址无关代码(PIC: Position Independent code)的技术。该实现的基本思想是:把指令中需要修改的部分分离出来,跟数据部分放在一起,这样指令部分就可以保持不变,而数据部分则在每个进程拥有一个副本。


与地址无关的代码,也就是需要考虑代码中会对地址进行引用的情况,共享对象(GCC中的动态链接文件)中地址引用可以分为以下几种情况:
a) 模块内函数调用、跳转等
b) 模块内数据的访问,如模块内定义的静态变量,全局变量等
c) 模块外部的函数调用、跳转等
d) 模块外部的数据的访问,比如别的模块定义的全局变量

static int a;
extern int b;
extern void ext();

void bar()
{
    a = 1;   //情况b
    b = 2;   //情况d
}

void foo()
{
     bar();   //情况a
     ext();   //情况c
}


以下分别讨论:

1.模块(动态链接文件)内部的函数的调用

由于此时调用者与被调者都是位于同一个模块,所以调用者与被调者之间的相对位置是固定的,因此,对被调者的调用就可以使用相对地址来替代绝对地址,对于这种指令就是不需要重定位的。

eg: 对上面代码中的 foo() 与 bar() 函数,因为bar() 函数相对 foo()函数中的调用语句之间的距离是固定不变的,因此该语句将是与地址无关的。


2.模块内部的数据调用

与上面分析同理,由于数据定义与引用指令是位于同一个模块的,因此它们之间的相对位置是固定的。但是此时有一些区别,现代体系结构中,数据的相对寻址没有基于当前指令的寻址方式,因此 ELF 采用了一个巧妙的方法来获取当前的PC(程序计数器)的值,再在该基础上添加一个偏移,即可访问到变量。

获取当前PC的方法:调用 “__i686.get_pc_thunk.cx”函数,该函数的作用是将返回地址的值放入ecx寄存器中,即把 call 的下一句指令的地址放入 ecx 寄存器中。(以上面的例子,操作是将 a = 1 该句指令的地址放入寄存器)

实现将返回地址放入寄存器的方法:处理器执行 call 指令后,下一条指令的地址会被压到栈顶,而 esp 寄存器指向栈顶,那么当“__i686.get_pc_thunk.cx”执行 "mov (%esp) ecx" 的时候,返回地址就放入了寄存器。


3.模块外部的函数的调用

此时对外部符号的引用显然是与地址有关的,按照先前说的基本思想,此时需要将与地址相关的部分放到数据段里。ELF 的做法是在数据段中建立一个指向这些函数的指针数组,也即是全局偏移表(GOT,Global Offset Tabel),当代码需要引用这些外部函数时,则可以通过GOT 中的相对应的项间接引用。

动态链接器在装载模块的时候会查找每个函数所在地址,并填充GOT中的各个表项,以保证每个指针均指向正确的地址。同时由于GOT本身是放在数据段的,因此它可以在模块装载的时候被修改,并且每个进程都可有自己的副本。


4.模块外部的数据的调用

该方法与模块外部的函数访问方法相同,同样引入 GOT ,只是此时GOT 的表项中存储的是变量的地址。


*如何区分一个动态共享对象是否是PIC的?

PIC 的 DSO 是不会包含任何的代码段重定位表的。

readelf -d lib.so | grep TEXTREL
上面的代码对PIC 的动态共享对象是不会有输出的。
微信小程序 - 解决报错 {“errcode“:41002,“errmsg“:“appid missing, rid: X“} 微信报错错误码errcode“:41002问题分析及解决教程(详细排查) 【微信小程序】报错{“errcode“:41002,“errmsg“:“appid missing, rid: 64e55770-67c1fb7e-027c5a70“}:【微信小程序】微信小程序登录请求出现appid missing提示,微信公众号{"errcode":41002,"errmsg":"appid missing"},微信 报错{“errcode“:41002,“errmsg“:“appid missing,微信小程序获取openid返回appid missing的问题,微信小程序提示Erro 阅读详情

相关推荐

深入解析NPN与PNP传感器驱动电路的设计逻辑与实战应用

本文深入解析NPN与PNP传感器驱动电路的设计逻辑与实战应用,详细对比两者的电流路径差异和电平变化特性。通过实际案例分享电路设计要点,包括上拉电阻选择、保护二极管配置等,并提供工业应用中的选型策略和常见故障排查指南,帮助工程师优化传感器系统集成。

weixin_42561476的博客 469

位置无关码PIC详解:原理、动态链接库、代码重定位

本文解释了什么是位置无关代码,以及它如何帮助创建具有可共享只读文本段的共享库。位置无关代码(PIC)通过引入全局偏移表(GOT)和过程链接表(PLT)实现,解决了共享库加载时的重定位问题。GOT提供了数据和函数的间接引用,PLT实现了懒绑定,推迟函数地址的解析。当然这也伴随额外的内存加载和寄存器使用成本,但在权衡之下,现代的编译器都更倾向于使用PIC。

主要分享嵌入式软件、人工智能部分知识 7788

【Unity】Unity性能分析解决方案——UPR

由Unity中国团队提供的一套性能优化解决方案,其是一系列性能工具的集合,并可将收集的数据进行可视化。

Davidorzs的博客 1008

位置无关码(PIC)详解

位置无关码(Position-Independent Code, PIC)是指编译后的机器代码在内存中任意地址加载执行时,无需修改内部地址引用仍能正确运行。

2303_76316997的博客 1319

AWR射频仿真基本操作(一)

这里只讲述一个基本的操作: 软件是AWR 14版本

钢丝 2万+

[CTFSHOW]JWT

文章目录前言JWT简介CTFSHOW Web345CTFSHOW Web346前置知识开始做题CTFSHOW Web347CTFSHOW Web348CTFSHOW Web349CTFSHOW Web350前置知识利用WP如何防御 前言 有些师傅向我咨询WP,索性就发了吧,其实早就写好了,只是懒,在github仓库里囤着 JWT简介 可以看看我的Github总结给自己看的,Y4tacker CTFSHOW Web345 首先打开题目,查看源码,接下来访问/admin被跳转回主页啥也没有发生 where is

Y4tacker的博客 6045

ARM的位置无关程序设计

ARM处理器支持位置无关的程序设计,这种程序加载到存储器的任意地址空间都可以正常运行,其设计方法在嵌入式应用系统开发中具有重要的作用。尤其在裸机状态下开发Bootloader程序及进行内核初始化设计;利用位置无关的程序设计方法还可以在具体应用中用于构建高效率动态链接库,因而了解位置无关的程序设计方法,有助于开发人员设计出结构简单、清晰的应用程序。 应用程序必须经过编译、汇编和链接后才变成可执行文

arick2013的专栏 1604

02.1 知识图谱工具 Protege的下载安装与使用

Protege的下载安装与使用 本文是王昊奋老师《知识图谱》系列笔记第2.1篇。 文章目录Protege的下载安装与使用0 相关介绍0.0 Protege相关介绍0.1 Protégé的特点0.2 Protégé的用途1 Protege的下载1.1 准备工作:安装配置JAVA环境1.2 官网下载2 Protege的安装2.1 直接解压缩2.2 双击运行3 Protege的使用实例-创建类...

和而不流 7万+

对于位置无关代码的理解

这个概念其实很好理解。对于一个可重定位目标文件,里面一定有很多需要重定位的符号。这些符号需要在静态链接器进行链接的时候回填绝对的虚拟内存地址。这种叫做位置有关代码。 而位置无关代码的意思是,在动态链接阶段(这个阶段可以发生在装载时也可以发生在运行时)无需回填具体的代码段,而是只需要回填全局偏移量表(GOT)与过程链接表(PLT)即可。 位置无关代码与位置有关代码的根本区别在于: 链接阶段是否...

m0_37313888的博客 1599

安装Openclaw[本地自动化AI助手]至windows【WSL2模式】系统 Openclaw for Windows

摘要:OpenClaw最佳兼容OpenAI系列模型,推荐使用ChatGPT API(需Auth鉴权),避免K*mi等模型导致的信用卡风险。Windows系统需满足WSL2支持条件(Win11或Win10 1903+版本)。安装需导入自签名根证书或跳过浏览器安全警告,通过离线包部署WSL发行版。使用时通过clawtoken命令获取网关认证令牌,并在浏览器完成设备配对。提供代购ChatGPT Plus账号服务(¥140/月),详细操作指南需加微信群获取文件。(150字)

qq_27246521的博客 456

【25届数字IC秋招总结】面试经验7——联发科

25届数字ic面试记录——联发科

lalala0635的博客 981

动态库和PIC-位置无关代码

一、前言 本文主要描述了动态库以及和动态库有紧密联系的位置无关代码的相关资讯。首先介绍了动态库和位置无关代码的源由,了解这些背景知识有助于理解和学习动态库。随后,我们通过加-fPIC和不加这个编译选项分别编译出两个relocatable object file,看看编译器是如何生成位置无关代码的。最后,我们自己动手编写一个简单的动态库,并解析了一些symbol Visibility、动态符号

yangChong 3389

69、SAP数据库归档重做日志备份策略与工具详解

本文详细解析了SAP数据库归档重做日志备份的重要性及策略,介绍了SAP提供的备份工具brarchive及其配置和使用方法,探讨了BRBACKUP与BRARCHIVE的联合运行、一致在线备份、备用数据库备份场景以及备份策略的综合应用与优化。此外,还分析了备份过程中常见问题的解决方法、备份监控与评估流程、与第三方备份解决方案的集成方式,以及未来备份技术的发展趋势和应对策略。通过合理运用这些策略和工具,可以有效保障SAP数据库的安全性和可恢复性。

peace的博客 135

地址无关代码

https://baike.baidu.com/item/%E5%9C%B0%E5%9D%80%E6%97%A0%E5%85%B3%E4%BB%A3%E7%A0%81/22702477?fr=aladdin 在计算机领域中,地址无关代码 (position-independent code,PIC),又称地址无关可执行文件 (position-independent executable,PIE) ,是指可在主存储器中任意位置正确地运行,而不受其绝对地址影响的一种机器码。PIC广泛使用于共享库,使得.

happylzs2008的专栏 566

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

引用动态链接库的原理

引用动态链接库的原理 位置无关代码 可以架在你而无需重定位的代码成为位置无关代码(Position-Independent Code,PIC)。用户对GCC使用-fpic选项指示GNU编译系统生成PIC代码。动态链接库的编译必须总是使用该选项。 在x86-64系统中,对同一个目标模块中符号的引用是不需要特殊处理使之成为PIC。可以用PC相对寻址来编译这些引用,构造目标文件时由静态链接器重定位。然而...

qq_38600065的博客 1525

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

c++位置无关代码(PIC)生成

位置无关代码是指编译生成的代码在运行时可以被加载到内存中的任何位置,并且仍然能够正确运行。它不依赖于固定的内存地址,这使得代码可以被多次共享和重用,非常适合动态链接库等场景。

qq_62784677的博客 1127

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Linux操作系统--动态链接库和代码段地址无关性(PIC)

注意:本文中的大部分是阅读 《程序员的自我修养》 作 者:俞甲子,石凡,潘爱民  的读书笔记。推荐大家看看这本书。   一,动态链接    操作系统将把程序依赖的目标文件全部加载到内存,如果依赖关系满足,则系统开始进行链接。链接与静态链接相似,即进行符号解析、地址重定位。    例如程序program1和program2都依赖于lib.o,而在运行program1的时候,lib.o

liaoxinmeng的专栏 3908

【deepseek】位置无关代码介绍

好的,我来为你详细解释这些概念,并附上 RISC-V 的代码示例。PC 相对寻址auipc%pcrel_hi%pcrel_lo0x10000x800000000x200000000x80000000。

ruofengdeyu的博客 945

编译链接之----地址无关代码(PIC)总结

动态链接的进程空间分布:动态链接库的最终装载地址在编译的时候并不能确定,而是在装载时,装载器根据当前进程地址空间的空闲情况,动态的分配一块足够大小的地址空间给动态链接库。 这样对地址的引用就可以采用地址重定位的方式来解决了。就向静态库那样在静态链接时通过修改指令进行静态重定位,我们的动态链接很容易也想到用装载重定位来进行动态重定位,这样就不用管它到底是装载到哪个地址啦。因为我们的指令地址和数据相

keep_moving_cqu的专栏 5900

动态链接(上):地址无关代码是如何生成的?

要想解决静态链接的问题,可以把共享的部分抽离出来,组成新的模块。为了让一些公共的库函数能够被多个程序,在运行的过程中进行共享,我们可以让程序在链接和运行过程中,也拆分成不同的模块,即共享模块和私有模块。共享模块用来存放供所有进程公共使用的库函数,私有模块存放本进程独享的函数与数据。分析到这里,动态链接的基本思路就呼之欲出了。

qq_33240556的博客 461

Linux 位置无关(PIC)代码和代码重定位(relocate)

位置无关代码是指在任何内存地址处都可以正确执行的代码。这种特性使得代码可以在内存中任意位置加载而不需要修改。代码重定位是指在程序加载或运行时将代码和数据从编译时的地址映射到运行时的地址的过程。静态重定位: 在程序编译时决定地址,之后地址不变。动态重定位: 程序在运行时根据实际加载地址进行重定位。位置无关代码和代码重定位是现代操作系统中动态链接和共享库的重要组成部分。位置无关代码使得代码可以在内。

xuyun0565的专栏 947

C++ 地址无关代码(PIC):探讨 C++ 动态库在共享内存环境下的重定位机制及其对安全性的影响

PIC的基本思想是:所有对地址的引用(无论是数据还是代码)都不能使用绝对地址,而必须使用相对于当前指令指针(Program Counter, PC)的相对偏移量,或者通过一个间接表进行查找。问题出现在动态库上。PIC使得动态库的代码可以被加载到虚拟地址空间的任何位置,而无需在加载时进行修改,从而允许所有进程共享同一个物理代码副本。在PIC环境中访问 TLS 变量需要特殊的机制,因为 TLS 变量的地址也是相对于线程存储区域的某个偏移量,而线程存储区域的基地址在不同线程甚至不同进程中都可能不同。

weixin_41455464的博客 369

07 | 动态链接(上):地址无关代码是如何生成的?

要想解决静态链接的问题,可以把共享的部分抽离出来,组成新的模块。为了让一些公共的库函数能够被多个程序,在运行的过程中进行共享,我们可以让程序在链接和运行过程中,也拆分成不同的模块,即共享模块和私有模块。共享模块用来存放供所有进程公共使用的库函数,私有模块存放本进程独享的函数与数据。分析到这里,动态链接的基本思路就呼之欲出了。

qq_37756660的博客 594

告别启动慢和内存浪费:聊聊动态链接库的PIC技术是怎么省时省力的

本文深入解析动态链接库的PIC(位置无关码)技术如何解决启动慢和内存浪费问题。通过全局偏移表(GOT)和过程链接表(PLT)的协同机制,PIC技术实现了近乎静态链接的性能表现,同时保持代码灵活性。文章还提供了性能对比、编译器行为分析和调优建议,帮助开发者在工程实践中充分发挥PIC的优势。

weixin_30512089的博客 415

位置无关代码

ARM处理器支持位置无关的程序设计,这种程序加载到存储器的任意地址空间都可以正常运行,其设计方法在嵌入式应用系统开发中具有重要的作用。尤其在裸机状态下开发Bootloader程序及进行内核初始化设计;利用位置无关的程序设计方法还可以在具体应用中用于构建高效率动态链接库。 应用程序必须经过编译、汇编和链接后才变成可执行文件,在链接时,要对所有目标文件进行重定位(relocation),建立符号引用规则,同时为变量、函数等分配运行地址。当程序执行时,系统必须把代码加载到链接时所指定的地址空间,以保证程序在执行

lx123010的专栏 1504
上一篇: 动态链接知识点
下一篇: 详解RVO与NRVO(区别于网上常见的RVO)
Virtual_Func
博客等级 码龄11年 38粉丝 113原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值