今天在用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相关推荐

  1. linux编译动态库之fPIC

    转载:https://blog.csdn.net/sinc00/article/details/44833839 今天在用g++编译代码时,提示说.rdata错误,然后网上找了一堆资料,最后明白了一个 ...

  2. linux编译动态库之-fPIC

    在生成动态库时,常常习惯性的加上fPIC选项,fPIC有什么作用和意义,加不加有什么区别,这里做下小结: fPIC的全称是 Position Independent Code, 用于生成位置无关代码. ...

  3. GCC编译静态库的-fPIC选项

    GCC编译静态库的-fPIC选项 背景 通常在linux下用gcc编译动态库时都会加上一个-fPIC选项来生成位置无关代码,但是从来没有人明确的说过是不是要在编译静态库时也加上-fPIC选项.我在这篇 ...

  4. linux 内核fpic,linux编译动态库 fPIC作用

    标签: 在生成动态库时,常常习惯性的加上fPIC选项,fPIC有什么作用和意义,加不加有什么区别,这里做下小结: fPIC的全称是 Position Independent Code, 用于生成位置无 ...

  5. linux c 如何编译静态库,Linux C 编程入门之一:gcc 编译动态库和静态库

    主调用程序源代码3-1:main.c /** * main.c */ #include #include #include "hello_fn.h" int main () { h ...

  6. 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 ...

  7. Linux环境编译动态库和静态库总结

    首先总结静态库的编译步骤. 1 先基于.cpp或者.c文件生成对应的.o文件 2将几个.o文件 使用ar -cr命令 生成libname.a文件 libname.a 为静态库, name 为静态库的名 ...

  8. 如何让linux加载当前目录的动态库

    debian从7.0开始支持multiarch,64位库的路径改到/usr/lib/x86_64-linux-gnu了,mint.ubuntu这些衍生版有没有跟着改我就不清楚了. deepin lin ...

  9. mysql.h 动态编译命令_Linux环境编译动态库和静态库总结

    对Linux环境动态库和静态库的一些基础知识做一些总结, 首先总结静态库的编译步骤. 1 先基于.cpp或者.c文件生成对应的.o文件 2将几个.o文件 使用ar -cr命令 生成libname.a文 ...

最新文章

  1. 三线表是什么?R语言使用table1包绘制(生成)三线表、构建不分层的三线表
  2. 上海day2--两年前最烧脑的环境变量
  3. mysql去除select换行符_MySQL中去除字段中的回车符和换行符
  4. 什么是HDMI视频光端机?
  5. scratch的积木相与java的_scratch课堂:积木块详解
  6. mysql 视图 字典_MySQL深入01-SQL语言-数据字典-服务器变量-数据操作DML-视图
  7. F - Wormholes(判断是否存在负环)
  8. ORACLE 10g下载|ORACLE 10g下载地址|ORACLE 10g官网下载地址
  9. [导入]需要关注的十大安全技巧之:免受垃圾邮件侵扰
  10. 程序员技能与成长:程序员的必备工具箱(值得收藏)
  11. 2-网络编程学习环境搭建
  12. 常青科技冲刺A股上市:研发费用率较低,关联方曾拆出资金达1亿元
  13. BLV 3D打印机Klipper配置参考
  14. 德尔玛递交注册:半年营收15亿 小米与欧派是股东
  15. 基于密码的移动办公安全能力体系构建
  16. python BFS最短路径问题
  17. 如何打印pmd和*pmd的值
  18. 模仿QQ的左右滑动切换界面和下拉更新的效果
  19. 1个月写900多条用例,二线城市年薪33W+的测试经理能有多卷?
  20. 大学物理·第4章刚体的转动

热门文章

  1. 目标检测之RPN网络(Feature Pyramid Networks for Object Detection)
  2. SSD 闪存盘技术详解
  3. UAT环境正常,上线生产环境后访问不到数据的原因分析及问题解决
  4. chatgpt无法登录报错Access denied OpenAl‘s services are not available in yourcountry.报错1020
  5. 时钟服务器之晶振类型
  6. 2、AUTOSAR-EB tresos Studio使用说明--“工欲善其事,必先利其器“
  7. 云鹏杂记 之 执行力
  8. svn回退特定版本的提交
  9. 解决使用绝对定位absolute后,margin:0 auto居中方法失效
  10. 构建智慧城市的“新细胞”:“未来社区”