0

0

c++的地址无关代码(PIC)是什么_c++动态库与共享对象原理

穿越時空

穿越時空

发布时间:2025-12-04 14:39:10

|

396人浏览过

|

来源于php中文网

原创

PIC通过相对寻址和GOT/PLT机制实现代码在任意内存地址运行,确保共享库支持ASLR并可被多个进程安全共享。

c++的地址无关代码(pic)是什么_c++动态库与共享对象原理

地址无关代码(Position Independent Code,简称 PIC)是 C++(以及 C)编译时生成的一种特殊机器码,它不依赖于程序加载到内存中的具体地址。这种特性对于动态库(共享对象)至关重要,因为多个程序可能同时加载同一个共享库,而系统无法保证每次都将库加载到相同的内存地址。

PIC 是如何工作的?

PIC 的核心思想是避免使用绝对地址引用,转而采用相对寻址方式。在 x86-64 架构中,大多数指令支持 RIP 相对寻址(RIP 是指令指针寄存器),这意味着代码可以基于当前指令的位置来访问数据或跳转函数,而不是硬编码一个固定地址。

例如,当共享库中需要访问一个全局变量或调用另一个函数时,编译器不会直接写入该变量的绝对地址,而是通过全局偏移表(GOT, Global Offset Table)和过程链接表(PLT, Procedure Linkage Table)间接访问。

  • GOT:存储外部变量和函数的实际运行时地址,由动态链接器在加载时填充。
  • PLT:用于延迟绑定(lazy binding)外部函数调用,第一次调用时解析地址,后续直接跳转。

这样,无论共享库被加载到哪个内存位置,只要 GOT 和 PLT 被正确设置,代码都能正常运行。

立即学习C++免费学习笔记(深入)”;

为什么动态库必须使用 PIC?

现代操作系统使用 ASLR(Address Space Layout Randomization)安全机制,随机化程序和库的加载地址以防止攻击。如果动态库不是 PIC,它只能加载到预定地址,一旦地址冲突或被占用,就会导致加载失败。

使用 PIC 后,共享库可以在任意地址加载,提高了兼容性和安全性。Linux 上的 .so 文件(共享对象)通常要求使用 -fPIC 编译选项生成真正的地址无关代码。

Tellers AI
Tellers AI

Tellers是一款自动视频编辑工具,可以将文本、文章或故事转换为视频。

下载
  • 不带 -fPIC 编译的代码可能仍能在某些情况下工作,但在 64 位系统上链接为共享库时常会报错。
  • -fPIC 会对性能有轻微影响(间接访问增加开销),但现代 CPU 缓存机制已大幅缓解这一问题。

共享对象的加载与符号解析

当你编译一个 C++ 共享库:

g++ -fPIC -shared -o libmylib.so mylib.cpp

编译器会生成 PIC 指令,并构建包含代码段、数据段、GOT/PLT 等结构的 ELF 共享对象文件。

运行程序时,动态链接器(如 /lib64/ld-linux-x86-64.so)负责:

  • 将共享库映射到进程地址空间的可用区域。
  • 解析外部符号并填充 GOT 表项。
  • 处理重定位信息,修正需要调整的地址引用。

多个进程可以共享同一份共享库的代码段(只读),但每个进程拥有独立的数据段副本(包括 GOT),确保变量隔离。

基本上就这些。PIC 是实现高效、安全共享库的基础技术,理解它有助于写出更可靠、可移植的 C++ 动态库代码。

相关专题

更多
全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

78

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

96

2025.09.18

CSS position定位有几种方式
CSS position定位有几种方式

有4种,分别是静态定位、相对定位、绝对定位和固定定位。更多关于CSS position定位有几种方式的内容,可以访问下面的文章。

81

2023.11.23

磁盘配额是什么
磁盘配额是什么

磁盘配额是计算机中指定磁盘的储存限制,就是管理员可以为用户所能使用的磁盘空间进行配额限制,每一用户只能使用最大配额范围内的磁盘空间。php中文网为大家提供各种磁盘配额相关的内容,教程,供大家免费下载安装。

1349

2023.06.21

如何安装LINUX
如何安装LINUX

本站专题提供如何安装LINUX的相关教程文章,还有相关的下载、课程,大家可以免费体验。

702

2023.06.29

linux find
linux find

find是linux命令,它将档案系统内符合 expression 的档案列出来。可以指要档案的名称、类别、时间、大小、权限等不同资讯的组合,只有完全相符的才会被列出来。find根据下列规则判断 path 和 expression,在命令列上第一个 - ( ) , ! 之前的部分为 path,之后的是 expression。还有指DOS 命令 find,Excel 函数 find等。本站专题提供linux find相关教程文章,还有相关

294

2023.06.30

linux修改文件名
linux修改文件名

本专题为大家提供linux修改文件名相关的文章,这些文章可以帮助用户快速轻松地完成文件名的修改工作,大家可以免费体验。

776

2023.07.05

linux系统安装教程
linux系统安装教程

linux系统是一种可以免费使用,自由传播,多用户、多任务、多线程、多CPU的操作系统。本专题提供linux系统安装教程相关的文章,大家可以免费体验。

572

2023.07.06

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

72

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7.4万人学习

Git 教程
Git 教程

共21课时 | 2.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号