符号表

符号定义的实质是:指分配了存储空间。

函数名指明代码所在区域,变量名指数据所在区域

所有符号的值就是其目标所在的首地址。符号解析也叫符号绑定。


函数名和已初始化的全局变量名都是强符号。

未初始化的全局变量名是弱符号


•尽量避免使用全局变量
•一定需要用的话,就按以下规则使用
尽量使用本地变量(static
全局变量要赋初值
外部全局变量要使用extern



多重定义符号的处理规则

    Rule 1: 强符号不能多次定义

强符号只能被定义一次,否则链接错误

    Rule 2: 若一个符号被定义为一次强符号和多次弱符号,则按强定义为准

对弱符号的引用被解析为其强定义符号

    Rule 3: 若有多个弱符号定义,则任选其中一个

使用命令 gcc fno -common 链接时,会告诉链接器在遇到多个弱定义的全局符号时输出一条警告信息。


•链接器对外部引用的解析算法要点如下:
按照命令行给出的 顺序扫描 .o .a 文件
扫描期间将 当前未解析的引用 记录到一个列表 U
每遇到一个新的 .o .a 中的模块,都试图用其来解析 U 中的符号
如果扫描到最后, U 中还有未被解析的符号,则发生错误


1:符号表(symtab)::::: objdump  -t或者--syms

2:.dynsym   动态符号表(Dynamic Symbol Table)::::::: objdump -T或者--dynamic-syms  

3:  readelf -a 


typedef  struct {
        int    name;    /*符号对应字符串在strtab节中的偏移量*/
        int    value;    /*在对应节中的偏移量,可执行文件中是虚拟地址*/
        int    size;      /*符号对应目标所占字节数*/
        char  type: 4,  /*符号对应目标的类型:数据、函数、源文件、节*/
                 binding: 4; /*符号类别:全局符号、局部符号、弱符号*/
        char  reserved;
        char  section;  /*符号对应目标所在的节,或其他情况*/
} Elf_Symbol;


 ABS表示不该被重定位;

UND表示未定义;

COM表示未初始化数据(.bss),此时,value表示对齐要求,size给出最小大小


符号表_第1张图片


符号表_第2张图片

符号表_第3张图片

局部变量临时分配在栈中,不会在过程外被引用,因此不是符号定义

符号表_第4张图片




你可能感兴趣的:(gcc)