Chinaunix首页 | 论坛 | 博客
  • 博客访问: 678308
  • 博文数量: 77
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1173
  • 用 户 组: 普通用户
  • 注册时间: 2014-05-16 11:20
个人简介

将技术做到极致...

文章分类

全部博文(77)

文章存档

2019年(3)

2015年(27)

2014年(47)

分类: LINUX

2015-02-03 14:04:22

 前言  
    

    试想这样的情景,程序调用某函数A,A函数存在于两个动态链接库liba.so,libb.so中,并且程序执行需要链接这两个库,此时程序调用的A函数到底是来自于a还是b呢?

    这取决于链接时的顺序,比如先链接liba.so,这时候通过liba.so的导出符号表就可以找到函数A的定义,并加入到符号表中,链接libb.so的时候,符号表中已经存在函数A,就不会再更新符号表,所以调用的始终是liba.so中的A函数

 这里的调用严重的依赖于链接库加载的顺序,可能会导致混乱;gcc的扩展中有如下属性__attribute__ ((visibility("hidden"))),可以用于抑制将一个函数的名称被导出,对连接该库的程序文件来说,该函数是不可见的,使用的方法如下:
    -fvisibility=default|internal|hidden|protected
    gcc的visibility是说,如果编译的时候用了这个属性,那么动态库的符号都是hidden的,除非强制声明。

1.创建一个vis.c源文件,内容简单

点击(此处)折叠或打开

  1. #include<stdio.h>
  2. #include<stdlib.h>

  3. __attribute__((visibility("default")))
  4. void not_hidden ()
  5. {
  6.     printf("exported symbol\n");
  7. }

  8. void is_hidden ()
  9. {
  10.     printf("hidden one\n");
  11. }

想要做的是,第一个函数符号可以被导出,第二个被隐藏。
先编译成一个动态库,使用到属性-fvisibility

点击(此处)折叠或打开

  1. # arm-unknown-linux-gnu-gcc -shared -o libvis.so -fvisibility=hidden vis.c
  2. /opt/tools/gcc-4.2.0-glibc-2.5/arm-unknown-linux-gnu/bin/../lib/gcc/arm-unknown-linux-gnu/4.2.0/../../../../arm-unknown-linux-gnu/bin/ld: warning: creating a DT_TEXTREL in object.

现在查看

点击(此处)折叠或打开

  1. # arm-unknown-linux-gnu-readelf -s libvis.so | grep hidden
  2.      3: 00000494 28 FUNC GLOBAL DEFAULT 10 not_hidden
  3.     75: 000004b0 28 FUNC LOCAL HIDDEN 10 is_hidden
  4.     80: 00000494 28 FUNC GLOBAL DEFAULT 10 not_hidden

可以看到,属性确实有作用了。

现在试图链接libvis.so库

点击(此处)折叠或打开

  1. # vi visdemo.c

  2. int main()
  3. {
  4.         not_hidden();
  5.         is_hidden();
  6.         return 0;
  7. }

试图编译成一个可执行文件,链接到刚才生成的动态库,
结果提示:

点击(此处)折叠或打开

  1. # arm-unknown-linux-gnu-gcc -o demo visdemo.c -L ./ -lvis
  2. /tmp/ccAPIZHV.o: In function `main':
  3. visdemo.c:(.text+0x10): undefined reference to `is_hidden'
  4. collect2: ld returned 1 exit status

说明了hidden确实起到作用了。

阅读(3213) | 评论(0) | 转发(0) |
0

上一篇:堆和栈的区别

下一篇:SSL ENGINE机制

给主人留下些什么吧!~~