Gcc制作动态符号导出表(动态库)

Gcc制作动态符号导出表(动态库)

在这里插入图片描述

1.1 定义

  在Linux下动态库(.so)中,通过GCC的C++ visibility属性可以控制共享文件导出符号。在GCC 4.0及以上版本中,有个visibility属性,可见属性可以应用到函数、变量、模板以及C++类。不指定gcc在制作动态库时,除了static修饰的函数、变量外,都默认可见。

1.2 优势

1. 限制符号可见性的原因

从动态库中尽可能少地输出符号是一个好的实践经验。输出一个受限制的符号会提高程序的模块性,并隐藏实现的细节。动态库装载和识别的符号越少,程序启动和运行的速度就越快。导出所有符号会减慢程序速度,并耗用大量内存。

2. 制作动态库原因

对于相同函数存在不同库的情况,文件只会优先使用先编译链接的动态库。
例如:gcc main.c -L. -lhello -lhello1,只会链接libhello.so

1.3 属性分类

1. “default”

用它定义的符号将被导出,动态库中的函数默认是可见的。

2. ”hidden”

  用它定义的符号将不被导出,并且不能从其它对象进行使用,动态库中的函数是被隐藏的。default意味着该方法对其它模块是可见的。而hidden表示该方法符号不会被放到动态符号表里,所以其它模块(可执行文件或者动态库)不可以通过符号表访问该方法。

要定义GNU属性,需要包含__attribute__和用括号括住的内容。可以将符号的可见性指定为visibility(“hidden”),这将不允许它们在库中被导出,但是可以在源文件之间共享。实际上,隐藏的符号将不会出现在动态符号表中,但是还被留在符号表中用于静态链接。

导出列表由编译器在创建共享库的时候自动生成,也可以由开发人员手工编写。导出列表的原理是显式地告诉编译器可以通过外部文件从对象文件导出的符号是哪些。GNU用户将此类外部文件称作为”导出映射”。

1.4 动态库制作流程

1. Gcc指定编译选项,制作动态库

gcc -shared -fvisibility=hidden -o libhello.so hello.c
在编译时指定-fvisibility=hidden选项,未显式指定__attribute__(visibility(“default”))的符号都将被隐藏

2. 查看符号表

  1. 命令是readelf,选项是-s,如:readelf –s libhello.so
  2. 可设置隐藏.symtab符号表,命令为:strip libhello.so
    symtab和.dynsym两个不同的symbol table,.dynsym用来保存与动态链接相关的导入导出符号,而 .symtab 则保存所有符号,包括 .dynsym 中的符号,.dynsym是.symtab的一个子集。
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值