读书频道 > 系统 > linux > 深度探索Linux操作系统系统构建和原理解析
4. 符号表
2013-09-28 13:17:34     我来说两句 
收藏    我要投稿   
全书一共8章:第1章介绍了如何准备工作环境。在第2章中构建了编译工具链,这是后面构建操作系统各个组件的基础。在这一章中,不仅详细讲解了工具链的构建过程,而且还通过对编译链接过程的探讨,深入讨论了工具链  立即去当当网订购

既然在链接时,需要重定位目标文件中引用的外部符号,显然,链接器需要知道这些符号的定义在哪里,为此汇编器在每个目标文件中创建了一个符号表,符号表中记录了这个模块定义的可以提供给其他模块引用的全局符号。可以使用工具readelf查看文件中的符号表,如目标文件foo2.o的符号表如下:
root@baisheng:~/demo# readelf -s foo2.o
Symbol table '.symtab' contains 10 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS foo2.c
     2: 00000000     0 SECTION LOCAL  DEFAULT    1
     3: 00000000     0 SECTION LOCAL  DEFAULT    3
     4: 00000000     0 SECTION LOCAL  DEFAULT    4
     5: 00000000     0 SECTION LOCAL  DEFAULT    6
     6: 00000000     0 SECTION LOCAL  DEFAULT    7
     7: 00000000     0 SECTION LOCAL  DEFAULT    5
     8: 00000000     4 OBJECT  GLOBAL DEFAULT    3 foo2
     9: 00000000    16 FUNC    GLOBAL DEFAULT    1 foo2_func

根据输出可见,foo2.o符号表包含10个符号。Value列表示的是符号的地址。前面我们提到,链接时链接器才会为符号分配地址,所以我们看到的符号的地址全部是0。Size列表示符号对应的实体占据的内存大小,如变量foo2占据4字节,函数foo2_func占据16字节。Type列表示符号的类型,如foo2类型为OBJECT,表示变量;foo2_func类型为FUNC,表示函数。Bind列表示符号绑定的相关信息,LOCAL表示模块内部符号,对外部不可见;GLOBAL表示全局符号,foo2和foo2_func都属于全局变量。Ndx列表示该符号在哪个段,如foo2在第3个段,即“.data”段,foo2_func在第1个段,即“.text”段。Name列表示符号的名称。

除了模块定义的符号外,符号表中也包括了模块引用的外部符号,如模块hello的符号表如下:
root@baisheng:~/demo# readelf -s hello.o
Symbol table '.symtab' contains 11 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS hello.c
     2: 00000000     0 SECTION LOCAL  DEFAULT    1
     3: 00000000     0 SECTION LOCAL  DEFAULT    3
     4: 00000000     0 SECTION LOCAL  DEFAULT    4
     5: 00000000     0 SECTION LOCAL  DEFAULT    6
     6: 00000000     0 SECTION LOCAL  DEFAULT    7
     7: 00000000     0 SECTION LOCAL  DEFAULT    5
     8: 00000000    33 FUNC    GLOBAL DEFAULT    1 main
     9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo2
    10: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo2_func

符号foo2和foo2_func都在模块foo2中定义,对于模块hello来说是外部符号,没有在任何一个段中, 所以在列Ndx中,foo2和foo2_func的值是UND。UND是Undefined的缩写,表示符号foo2、foo2_func是未定义的。

在链接时,对于模块中引用的外部符号,链接器将根据符号表进行符号的重定位。如果我们将符号表删除了,那么链接器在链接时将找不到符号的定义,从而不能进行正确的符号解析。如我们将foo2.o中的符号表删除,再次进行链接,则链接器将因找不到符号定义而终止链接,如下所示:
root@baisheng:~/demo/tmp# strip foo2.o
root@baisheng:~/demo# gcc -o hello *.o
/usr/bin/ld: error in foo2.o(.eh_frame); no .eh_frame_hdr table will be created.
hello.o: In function 'main':
hello.c:(.text+0xb): undefined reference to 'foo2'
hello.c:(.text+0x1b): undefined reference to 'foo2_func'
collect2: error: ld returned 1 exit status

点击复制链接 与好友分享!回本站首页
分享到: 更多
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:3. 重定位表
下一篇:2.1.4 链接
相关文章
图文推荐
3.3.6 GNOME的软件管
3.3.5 GNOME的文件管
3.3.4 GNOME的窗口管
3.3.3 收藏夹和快捷
排行
热门
文章
下载
读书

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做最好的IT技术学习网站