【静态链接】第2章---------------------目标文件(符号)

来源:互联网 发布:礼记中庸好学近乎知 编辑:程序博客网 时间:2024/05/18 22:40

 

########  该系列博文为书籍《程序员的自我修养》的笔记 ##########

 

【说明】

                链接中最基本的概念,就是符号了,如果没有符号,链接是没办法进行的,既然这么重要,当然要来一篇总结一下啦。

 

【符号的分类】

                当目标文件A.o中引用了B.o的 一个变量(或者函数)的时候,其实就是引用了B.o 中的符号,在编译目标文件的时候,会把所有的变量名,函数名,都保存到符号表中(可能不是原来的变量函数名,不过在C中一般就是原来名字),在编译A.o 的时候,由于找不到引用的B.o 中的变量,所以这个符号在A.o 的符号表中就应该和其他符号的雷兴国有所区别,它们分为下面几种类型:

                1)本目标文件的全局符号,它可以被外部引用。

                2)外部目标文件的符号,也叫“外部符号”

                3)段名,它也是符号,它由编译器产生

                4)局部符号,无视他吧!也就是调试的时候有用

                5)行号,同上。。。。

 

【符号表】

                 好吧,我们用同样的方式介绍符号表,,首先是他的C语言定义,同样的在elf.h 中

                 

                 接下来就是对应的一张 各个成员的作用

                

                  然后就是重点地方的详细介绍了

                 1】符号类型和绑定信息 st_info

                     这个成员其实记录了2个东西  ,,低4位表示符号类型,高28位表示绑定的信息,这2个配合才是st_info 的具体意义,如下

                    

               

               2】符号所在段  st_shndx

                      这个特别值得注意

                                        1)如果符号定义在本目标文件中,那么这个成员表示符号所在的段在段表中的下标,

                                        2)如果不是,那么应该是下面的含义

                                            

           

              3】符号值  st_value ,这个值其实含义有好多种呢

                                  1)在目标文件中,如果是符号的定义并且符号不是"COMMON"类型,则表示符号在段中的偏移

                                  2)在目标文件中,如果是"COMMON"类型,则表示符号的对齐属性

                                  3)在可执行文件中,表示虚拟地址。

               

               4】有了这些知识,在来看看我们的 simp.o

                     利用 readelf -s simp.o

                     

                      具体的分析我就不写了。。

 

【特殊符号】

                     其实有很多符号我们没有定义,我们也可以直接使用,ld链接器会帮你处理,称之为“特殊符号”,下面的C语言例子中使用了特殊符号

                   

#include <stdio.h>extern char __executable_start[];extern char etext[], _etext[], __etext[];extern char edata[], _edata[];extern char end[], _end[];int main(){    printf("Executable start 0x%x\n", __executable_start);    printf("Text End 0x%x  0x%x  0x%x\n", etext, _etext, __etext);    printf("Data End 0x%x  0x%x\n", edata, _edata);    printf("Executable End 0x%x  0x%x\n", end, _end);    return 0;}


                      看下编译执行后的输出。。。。

                     

                    
0 0
原创粉丝点击