linux 内核fpic,linux编译动态库 fPIC作用
标签:
在生成动态库时,常常习惯性的加上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作用相关推荐
- linux编译动态库之fPIC
转载:https://blog.csdn.net/sinc00/article/details/44833839 今天在用g++编译代码时,提示说.rdata错误,然后网上找了一堆资料,最后明白了一个 ...
- linux编译动态库之-fPIC
在生成动态库时,常常习惯性的加上fPIC选项,fPIC有什么作用和意义,加不加有什么区别,这里做下小结: fPIC的全称是 Position Independent Code, 用于生成位置无关代码. ...
- linux so fpic,linux编译动态库之fPIC
今天在用g++编译代码时,提示说.rdata错误,然后网上找了一堆资料,最后明白了一个要重新编译对应的链接库. 在生成动态库时,常常习惯性的加上fPIC选项,fPIC有什么作用和意义,加不加有什么区别 ...
- 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 c 如何编译静态库,Linux C 编程入门之一:gcc 编译动态库和静态库
主调用程序源代码3-1:main.c /** * main.c */ #include #include #include "hello_fn.h" int main () { h ...
- Linux环境编译动态库和静态库总结
首先总结静态库的编译步骤. 1 先基于.cpp或者.c文件生成对应的.o文件 2将几个.o文件 使用ar -cr命令 生成libname.a文件 libname.a 为静态库, name 为静态库的名 ...
- Linux内核裁剪及编译
Linux内核裁剪及编译可加载模块 一 Linux基础知识 linux内核组要由五个子系统组成: 进程调度 内存管理 文件系统 网络接口 进程间通信 Linux源码目录 arch 目录中包含于体 ...
- Linux内核5.10编译 与调试
Linux内核5.10编译 与调试 Linux 5.10 编译 下载内核 准备编译环境 配置模板 编译 安装新内核 qemu 调试 busybox 根文件系统制作 qemu 运行 脚本二 方法三 目的 ...
- 安卓学习日记(一):了解安卓架构(linux内核层、系统运行库层、应用框架层、应用层)
首先为了理解安卓系统是怎么工作的,就先来看一下android的系统架构,其架构大至可以分为四层:linux内核层.系统运行库层.应用框架层和应用层,那就先说说这几层. 1.linux内核层: Andr ...
最新文章
- spring 组件基于注解的注册方式
- Nature:首个肠道微生物对药物代谢影响的系统性研究
- python编程案例教程答案-Python基础案例教程
- 【Android 逆向】IDA 工具使用 ( 同步指定的 IDA View 视图 | Hex View 数据格式 | 过滤设置 )
- python中用于获取当前目录的是_python中获得当前目录和上级目录的实现方法
- chromium关闭更新_Win10今年最重磅更新!Win10 2004正式版详尽体验
- 对多个WCF服务进行统一的连接测试
- usermod使用方法
- Python并行编程(四):多线程同步之condition(条件变量)实现带有缓冲区的生产者-消费者模型...
- 传智播客 刘意_2015年Java基础视频-深入浅出精华版 笔记(day01~day10)(2015年11月17日20:47:22)...
- 【5分钟 Paper】Dueling Network Architectures for Deep Reinforcement Learning
- CSDN免登录复制方式
- 每日小结(就不平衡问题探讨)
- word在任意页开始添加页码
- 蓝桥杯总结及经验教训
- 新浪微博开放平台开发总结
- 两个定律,给你找了一个换手机的借口
- 理想浪漫主义色彩的句子
- python爬取视频--下载2019巴菲特股东大会直播视频
- clickhouse PARTITION操作