linux so fpic,linux编译动态库之fPIC
今天在用g++编译代码时,提示说.rdata错误,然后网上找了一堆资料,最后明白了一个要重新编译对应的链接库。
在生成动态库时,常常习惯性的加上fPIC选项,fPIC有什么作用和意义,加不加有什么区别,这里做下小结:
fPIC的全称是 Position Independent Code, 用于生成位置无关代码。什么是位置无关代码,个人理解是代码无绝对跳转,跳转都为相对跳转。
1、不加fPIC选项
即使不加fPIC也可以生成.so文件,但是对于源文件有要求,例如
因为不加fPIC编译的so必须要在加载到用户程序的地址空间时重定向所有表目,所以在它里面不能引用其它地方的代码
如下:
#include
int func1(int a)
{
printf("haha a=%d\n", 2);
a++;
return a;
}
使用 gcc -shared -o libb3.so c.c 编译将报错
/usr/bin/ld: /tmp/ccCViivC.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
/tmp/ccCViivC.o: could not read symbols: Bad value
将上述代码改为:
int func1(int a)
{
// printf("haha a=%d\n", 2);
a++;
return a;
}
则可以编译通过。
对于不加 -fPIC生成的动态库,“ 生成动态库时假定它被加载在地址 0 处。加载时它会被加载到一个地址(base),这时要进行一次重定位(relocation),把代码、数据段中所有的地址加上这个 base 的值。这样代码运行时就能使用正确的地址了。”
2、加fPIC选项
加上fPIC选项生成的动态库,显然是位置无关的
“这样的代码本身就能被放到线性地址空间的任意位置,无需修改就能正确执行。通常的方法是获取指令指针的值,加上一个偏移得到全局变量/函数的地址。”
加fPIC选项的 源文件对于,它引用的函数头文件编写有很宽松的尺度。
比如只需要包含个声明的函数的头文件,即使没有相应的C文件来实现,编译成so库照样可以通过。
在内存引用上,加不加fPIC的异同:
加了fPIC实现真正意义上的多个进程共享so文件。
多个进程引用同一个 PIC 动态库时,可以共用内存。这一个库在不同进程中的虚拟地址不同,但操作系统显然会把它们映射到同一块物理内存上。
对于不加-fPIC的
不加fPIC,则加载so文件时,需要对代码段引用的数据对象需要重定位,重定位会修改代码段的内容,这就造成每个使用这个.so文件代码段的进程在内核里都会生成这个.so文件代码段的copy.每个copy都不一样,取决于这个.so文件代码段和数据段内存映射的位置。
可见,这种方式更消耗内存。
但是不加fPIC编译的 so文件的优点是加载速度比较快。
题外话:能不能使用so库来静态编译(-static)一个可执行程序,答案是否定的,会出现错误提示
attempted static link of dynamic object
linux so fpic,linux编译动态库之fPIC相关推荐
- linux编译动态库之fPIC
转载:https://blog.csdn.net/sinc00/article/details/44833839 今天在用g++编译代码时,提示说.rdata错误,然后网上找了一堆资料,最后明白了一个 ...
- linux编译动态库之-fPIC
在生成动态库时,常常习惯性的加上fPIC选项,fPIC有什么作用和意义,加不加有什么区别,这里做下小结: fPIC的全称是 Position Independent Code, 用于生成位置无关代码. ...
- GCC编译静态库的-fPIC选项
GCC编译静态库的-fPIC选项 背景 通常在linux下用gcc编译动态库时都会加上一个-fPIC选项来生成位置无关代码,但是从来没有人明确的说过是不是要在编译静态库时也加上-fPIC选项.我在这篇 ...
- linux 内核fpic,linux编译动态库 fPIC作用
标签: 在生成动态库时,常常习惯性的加上fPIC选项,fPIC有什么作用和意义,加不加有什么区别,这里做下小结: fPIC的全称是 Position Independent Code, 用于生成位置无 ...
- linux c 如何编译静态库,Linux C 编程入门之一:gcc 编译动态库和静态库
主调用程序源代码3-1:main.c /** * main.c */ #include #include #include "hello_fn.h" int main () { h ...
- Linux:编译动态库时遇到的错误relocation R_X86_64_32 against `a local symbol'
编译动态库时遇到如下错误: ... ... relocation R_X86_64_32 against `a local symbol' can not be used when making a ...
- Linux环境编译动态库和静态库总结
首先总结静态库的编译步骤. 1 先基于.cpp或者.c文件生成对应的.o文件 2将几个.o文件 使用ar -cr命令 生成libname.a文件 libname.a 为静态库, name 为静态库的名 ...
- 如何让linux加载当前目录的动态库
debian从7.0开始支持multiarch,64位库的路径改到/usr/lib/x86_64-linux-gnu了,mint.ubuntu这些衍生版有没有跟着改我就不清楚了. deepin lin ...
- mysql.h 动态编译命令_Linux环境编译动态库和静态库总结
对Linux环境动态库和静态库的一些基础知识做一些总结, 首先总结静态库的编译步骤. 1 先基于.cpp或者.c文件生成对应的.o文件 2将几个.o文件 使用ar -cr命令 生成libname.a文 ...
最新文章
- 三线表是什么?R语言使用table1包绘制(生成)三线表、构建不分层的三线表
- 上海day2--两年前最烧脑的环境变量
- mysql去除select换行符_MySQL中去除字段中的回车符和换行符
- 什么是HDMI视频光端机?
- scratch的积木相与java的_scratch课堂:积木块详解
- mysql 视图 字典_MySQL深入01-SQL语言-数据字典-服务器变量-数据操作DML-视图
- F - Wormholes(判断是否存在负环)
- ORACLE 10g下载|ORACLE 10g下载地址|ORACLE 10g官网下载地址
- [导入]需要关注的十大安全技巧之:免受垃圾邮件侵扰
- 程序员技能与成长:程序员的必备工具箱(值得收藏)
- 2-网络编程学习环境搭建
- 常青科技冲刺A股上市:研发费用率较低,关联方曾拆出资金达1亿元
- BLV 3D打印机Klipper配置参考
- 德尔玛递交注册:半年营收15亿 小米与欧派是股东
- 基于密码的移动办公安全能力体系构建
- python BFS最短路径问题
- 如何打印pmd和*pmd的值
- 模仿QQ的左右滑动切换界面和下拉更新的效果
- 1个月写900多条用例,二线城市年薪33W+的测试经理能有多卷?
- 大学物理·第4章刚体的转动
热门文章
- 目标检测之RPN网络(Feature Pyramid Networks for Object Detection)
- SSD 闪存盘技术详解
- UAT环境正常,上线生产环境后访问不到数据的原因分析及问题解决
- chatgpt无法登录报错Access denied OpenAl‘s services are not available in yourcountry.报错1020
- 时钟服务器之晶振类型
- 2、AUTOSAR-EB tresos Studio使用说明--“工欲善其事,必先利其器“
- 云鹏杂记 之 执行力
- svn回退特定版本的提交
- 解决使用绝对定位absolute后,margin:0 auto居中方法失效
- 构建智慧城市的“新细胞”:“未来社区”