标签:

在生成动态库时,常常习惯性的加上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文件的优点是加载速度比较快。

标签:

来源: https://www.cnblogs.com/fengliu-/p/10216878.html

linux 内核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. linux so fpic,linux编译动态库之fPIC

    今天在用g++编译代码时,提示说.rdata错误,然后网上找了一堆资料,最后明白了一个要重新编译对应的链接库. 在生成动态库时,常常习惯性的加上fPIC选项,fPIC有什么作用和意义,加不加有什么区别 ...

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

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

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

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

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

  7. Linux内核裁剪及编译

    Linux内核裁剪及编译可加载模块 一 Linux基础知识 linux内核组要由五个子系统组成: 进程调度 内存管理 文件系统 网络接口 进程间通信 Linux源码目录 arch    目录中包含于体 ...

  8. Linux内核5.10编译 与调试

    Linux内核5.10编译 与调试 Linux 5.10 编译 下载内核 准备编译环境 配置模板 编译 安装新内核 qemu 调试 busybox 根文件系统制作 qemu 运行 脚本二 方法三 目的 ...

  9. 安卓学习日记(一):了解安卓架构(linux内核层、系统运行库层、应用框架层、应用层)

    首先为了理解安卓系统是怎么工作的,就先来看一下android的系统架构,其架构大至可以分为四层:linux内核层.系统运行库层.应用框架层和应用层,那就先说说这几层. 1.linux内核层: Andr ...

最新文章

  1. spring 组件基于注解的注册方式
  2. Nature:首个肠道微生物对药物代谢影响的系统性研究
  3. python编程案例教程答案-Python基础案例教程
  4. 【Android 逆向】IDA 工具使用 ( 同步指定的 IDA View 视图 | Hex View 数据格式 | 过滤设置 )
  5. python中用于获取当前目录的是_python中获得当前目录和上级目录的实现方法
  6. chromium关闭更新_Win10今年最重磅更新!Win10 2004正式版详尽体验
  7. 对多个WCF服务进行统一的连接测试
  8. usermod使用方法
  9. Python并行编程(四):多线程同步之condition(条件变量)实现带有缓冲区的生产者-消费者模型...
  10. 传智播客 刘意_2015年Java基础视频-深入浅出精华版 笔记(day01~day10)(2015年11月17日20:47:22)...
  11. 【5分钟 Paper】Dueling Network Architectures for Deep Reinforcement Learning
  12. CSDN免登录复制方式
  13. 每日小结(就不平衡问题探讨)
  14. word在任意页开始添加页码
  15. 蓝桥杯总结及经验教训
  16. 新浪微博开放平台开发总结
  17. 两个定律,给你找了一个换手机的借口
  18. 理想浪漫主义色彩的句子
  19. python爬取视频--下载2019巴菲特股东大会直播视频
  20. clickhouse PARTITION操作

热门文章

  1. HTML---HTML简介
  2. shields 徽标_到处都有平面徽标
  3. 重口味动漫_每种口味的图标样式
  4. 为什么同事写的代码那么优雅~
  5. 行业看点 | 英特尔成功开发超导量子计算芯片 推动产业加速发展
  6. Problem C: 类的初体验(III)
  7. 实现仿简书选取内容生成分享图片效果
  8. 对于经常需要truncate的表进行固定统计信息
  9. JMS : Java Message Service (Java消息服务)之一 [转]
  10. aop实现原理_从宏观的实现原理和设计本质入手,带你理解 AOP 框架的原理