转: http://www.cnblogs.com/leo0000/p/5691483.html

linux下共享库的注意点之-fpic

在编译共享库必须加上-fpic。这是为什么呢?

首先看一个简单的例子:

#include <stdio.h>

int fun1()
{
printf("fun1\n");
}

先不加-fpic的情况下生成库,反汇编查看fun1的机器码

0000044c <fun1>:
44c: 55 push %ebp
44d: 89 e5 mov %esp,%ebp
44f: 83 ec 18 sub $0x18,%esp
452: c7 04 24 b2 04 00 00 movl $0x4b2,(%esp)
459: e8 fc ff ff ff call 45a <fun1+0xe>
45e: c9 leave
45f: c3 ret

可以看出调用printf的位置是那个唯一的一个call,并不是跳转到plt表,有关plt表的内容可以查看我前面的博文。也就是说在该库被加载时需要修改代码段来达到重定位的效果。那么每一个加载这个共享库的程序都要有这个库的一份拷贝,这样实际上就没有达到共享库的效果。

看下运行时的机器码

   0xb771d44c <+0>:     55      push   %ebp
0xb771d44d <+1>: 89 e5 mov %esp,%ebp
0xb771d44f <+3>: 83 ec 18 sub $0x18,%esp
0xb771d452 <+6>: c7 04 24 b2 d4 71 b7 movl $0xb771d4b2,(%esp)
0xb771d459 <+13>: e8 42 b2 ea ff call 0xb75c86a0 <puts>
0xb771d45e <+18>: c9 leave
0xb771d45f <+19>: c3 ret

显然代码段被修改了。

再看一下再加了-fpic的情况下生成的库,反汇编看下fun1的机器码

0000045c <fun1>:
45c: 55 push %ebp
45d: 89 e5 mov %esp,%ebp
45f: 53 push %ebx
460: 83 ec 14 sub $0x14,%esp
463: e8 ef ff ff ff call 457 <__i686.get_pc_thunk.bx>
468: 81 c3 8c 1b 00 00 add $0x1b8c,%ebx
46e: 8d 83 ee e4 ff ff lea -0x1b12(%ebx),%eax
474: 89 04 24 mov %eax,(%esp)
477: e8 04 ff ff ff call 380 <puts@plt>
47c: 83 c4 14 add $0x14,%esp
47f: 5b pop %ebx
480: 5d pop %ebp
481: c3 ret
482: 90 nop
483: 90 nop
484: 90 nop
485: 90 nop
486: 90 nop
487: 90 nop
488: 90 nop

看过很多汇编代码的人知道printf有时候是puts,所以这段机器码中printf就对应第二个call,也就是跳转到plt表中去查找puts符号,那么这样就达到了共享库的效果,此时每一个需要该库的程序只是有一个plt表的拷贝,而代码段所有应用程序是共享的。

再看下运行时机器码

   0xb773045c <+0>:     55      push   %ebp
0xb773045d <+1>: 89 e5 mov %esp,%ebp
0xb773045f <+3>: 53 push %ebx
0xb7730460 <+4>: 83 ec 14 sub $0x14,%esp
0xb7730463 <+7>: e8 ef ff ff ff call 0xb7730457 <__i686.get_pc_thunk.bx>
0xb7730468 <+12>: 81 c3 8c 1b 00 00 add $0x1b8c,%ebx
0xb773046e <+18>: 8d 83 ee e4 ff ff lea -0x1b12(%ebx),%eax
0xb7730474 <+24>: 89 04 24 mov %eax,(%esp)
0xb7730477 <+27>: e8 04 ff ff ff call 0xb7730380 <puts@plt>
0xb773047c <+32>: 83 c4 14 add $0x14,%esp
0xb773047f <+35>: 5b pop %ebx
0xb7730480 <+36>: 5d pop %ebp
0xb7730481 <+37>: c3 ret

显然是一致的。

所以,在编译共享库时是必须加上-fpic的选项的,否则共享库剩(省?)下的仅仅是硬盘上的空间,而没有剩(省?)下内存。

转:linux下共享库的注意点之-fpic的更多相关文章

  1. linux下共享库的注意点之-fpic

    在编译共享库必须加上-fpic.这是为什么呢? 首先看一个简单的例子: #include <stdio.h> int fun1() { printf("fun1\n") ...

  2. Linux下共享库嵌套依赖问题 (转载)

    转自:http://my.oschina.net/moooofly/blog/506466 问题场景: 动态库 librabbitmq_r.so 内部依赖动态库 libevent_core.so 和 ...

  3. Linux下的库操作工具-nm、ar、ldd、ldconfig和ld.so

    Linux下的库操作工具-nm.ar.ldd.ldconfig和ld.so .nm [options] file 列出file中的所有符号 [option] -c 将符号转化为用户级的名字 -s 当用 ...

  4. linux下静态库和动态库一些东西

    http://www.cnblogs.com/changefuture/archive/2011/12/22/2297460.html Linux  动态链接库和静态库示例 文件预览 文件目录树如下, ...

  5. 谈谈Linux下动态库查找路径的问题 ldconfig LD_LIBRARY_PATH PKG_CONFIG_PATH

    谈谈Linux下动态库查找路径的问题 ldconfig LD_LIBRARY_PATH  PKG_CONFIG_PATH 转载自:http://blog.chinaunix.net/xmlrpc.ph ...

  6. Linux下动态库生成和使用

    Linux下动态库生成和使用 一.动态库的基本概念 1.动态链接库是程序运行时加载的库,当动态链接库正确安装后,所有的程序都可以使用动态库来运行程序.动态链接库是目标文件的集合,目标文件在动态链接库中 ...

  7. Linux下静态库生成和使用

    Linux下静态库生成和使用 一.静态库概念 1.库是预编译的目标文件(object  files)的集合,它们可以被链接进程序.静态库以后缀为”.a”的特殊的存档(archive file)存储. ...

  8. 查看Linux下*.a库文件中文件、函数、变量

    查看Linux下*.a库文件中文件.函数.变量等情况在Linux 下经常需要链接一些 *.a的库文件,那怎么查看这些*.a 中包 含哪些文件.函数.变量: 1. 查看文件:ar -t xxx.a 2. ...

  9. 深入理解LINUX下动态库链接器/加载器ld-linux.so.2

    [ld-linux-x86-64.so.2] 最近在Linux 环境下开发,搞了好几天 Compiler 和 linker,觉得有必要来写一篇关于Linux环境下 ld.so的文章了,google上搜 ...

随机推荐

  1. Ubuntu18.04 下联想电脑 无法连接WIFI问题解决

    联想笔记本电脑Ubuntu系统下无法开启无线硬件开关的解决.总结了3个方法,方便以后使用. 方法一: 一.问题描述: 本人使用联想拯救者14IFI笔记本在安装Ubuntu系统时会出现无线硬件开关关闭的 ...

  2. HUAWEI交换机配置telnet登录

    Huawei交换机配置Telnet登录 一,交换机开启Telnet服务 <Huawei>system-view                                        ...

  3. DateFormat的format()方法线程不安全的问题分析

    最近看到<侦探剧场:堆内存神秘溢出事件>https://my.oschina.net/u/2368090/blog/1628720,于是自己也想测试了解一下DateFormat的多线程安全 ...

  4. Day05基本运算符,if判断和while循环

    day05 1.常量 变量名全大写 2.基本运算符 ①算术运算 10/3除法 10//3取整 10*3乘法 10**3幂 ②赋值运算 增量赋值 age += 1#age = age + 1 age * ...

  5. module_param

    该宏定义在include/linux/moduleparam.h中 #define ___module_cat(a,b) __mod_ ## a ## b #define __module_cat(a ...

  6. Maven运行报错:-Dmaven.multiModuleProjectDirectory system propery is not set.

    eclipse中使用maven插件的时候,运行run as maven build的时候报错 -Dmaven.multiModuleProjectDirectory system propery is ...

  7. Python第三方库之openpyxl(11)

    Python第三方库之openpyxl(11) Stock Charts(股票图) 在工作表上按特定顺序排列的列或行中的数据可以在股票图表中绘制.正如其名称所暗示的,股票图表通常被用来说明股价的波动. ...

  8. Jmeter性能指标分析-下载了服务器监控插件的各个组件的功能介绍

    1.jp@gc - Actiive Threads Over Time:不同时间的活动用户数量展示(图表) 当前的时间间隔是1毫秒,在setting中可以设置时间间隔以及其他的参数 2.jp@gc - ...

  9. c标准库 徐明远 背景基础

    背景基础 1.c语言库用c语言编写   其他语言则不同 早期语言的库是用汇编语言编写的    不同的计算机体系结构有不同的汇编语言   所以在移植性方面差一点   而c语言可以编写出高度可移植性的代码 ...

  10. [uiautomator篇][11]wifi

    package com.softwinner.network.wifi; import android.content.Context; import android.content.Intent; ...