Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

5.5 大家都有符号表

"SimpleSection.txt"的最后部分是COFF符号表(Symbol table),COFF文件的符号表包含的内容几乎跟ELF文件的符号表一样,主要就是符号名、符号的类型、所在的位置。我们把"SimpleSection.txt"关于符号表的输出摘录如下:

COFF SYMBOL TABLE
000 006DC627 ABS    notype      Static        | @comp.id
001 00000001 ABS    notype      Static      | @feat.00
002 00000000 SECT1  notype      Static      | .drectve
    Section length   18, #relocs  0, #linenums  0, checksum     0
004 00000000 SECT2  notype      Static      | .debug$S
    Section length   86, #relocs  0, #linenums  0, checksum     0
006 00000004 UNDEF  notype      External    | _global_uninit_var
007 00000000 SECT3  notype      Static      | .data
    Section length    C, #relocs  0, #linenums  0, checksum AC5AB941
009 00000000 SECT3  notype      External    | _global_init_var
00A 00000004 SECT3  notype      Static      | $SG594
00B 00000008 SECT3  notype      Static      | ?static_var@?1??main@@9@9 (`main'::`2'::static_var)
00C 00000000 SECT4  notype      Static      | .text
    Section length   4E, #relocs    5, #linenums  0, checksum CC61DB94
00E 00000000 SECT4  notype ()   External    | _func1
00F 00000000 UNDEF  notype ()   External    | _printf
010 00000020 SECT4  notype ()   External    | _main
011 00000000 SECT5  notype      Static    | .bss
    Section length    4, #relocs  0, #linenums  0, checksum     0
013 00000000 SECT5  notype      Static    | ?static_var2@?1??main@@9@9 ('main'::'2'::static_var2)

在输出结果的最左列是符号的编号,也是符号在符号表中的下标。接着是符号的大小,即符号所表示的对象所占用的空间。第三列是符号所在的位置,ABS(Absolute)表示符号是个绝对值,即一个常量,它不存在于任何段中;SECT1(Section #1)表示符号所表示的对象定义在本COFF文件的第一个段中,即本例中的".drectve"段;UNDEF(Undefined)表示符号是未定义的,即这个符号被定义在其他目标文件。第四列是符号类型,可以看到对于C语言的符号,COFF只区分了两种,一种是变量和其他符号,类行为notype,另外一种是函数,类型为 notype (),这个符号类型值可以用于其他一些需要强符号类型的语言或系统中,可以给链接器更多的信息来识别符号的类型。第五列是符号的可见范围,Static表示符号是局部变量,只有目标文件内部是可见的;External表示符号是全局变量,可以被其他目标文件引用。最后一列是符号名,对于不需要修饰的符号名,"dumpbin"直接输出原始的符号名;对于那些经过修饰的符号名,它会把修饰前和修饰后的名字都打印出来,后面括号里面的就是未修饰的符号名。

从符号表的dump输出信息中,我们可以看到"_global_init_varabal"这个符号位于Section #3,即".data"段,它的长度是4个字节,可见范围是全局。另外还有一个为$SG574的符号,其实它表示的是程序中的那个"%d\n"字符串常量。因为程序中要引用到这个字符串常量,而该字符串常量又没有名字,所以编译器自动为它生成了一个名字,并且作为符号放在符号表里面,可以看到这个符号对外部是不可见的。可以看到,ELF文件中并没有为字符串常量自动生成的符号,另外所有的段名都是一个符号,"dumpbin"如果碰到某个符号是一个段的段名,那么它还会解析该符号所表示的段的基本属性,每个段名符号后面紧跟着一行就是段的基本属性,分别是段长度、重定位数、行号数和校验和。