ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【勘误】《编译、链接与库》 5.5 大家都有符号表

2021-08-22 18:34:15  阅读:199  来源: 互联网

标签:00 符号表 5.5 CC 00000000 int Static notype 勘误


​ 在输出结果的最左列是符号的编号,也是符号在符号表中的下标。接着是符号的大小,即符号所表示的对象所占用的空间。第三列是符号所在的位置,……

SimpleSection.c源程序代码:

int printf(const char *format, ...);

int global_init_var = 84;
int global_uninit_var;

void func1(int i)
{
    printf("%d\n", i);
}

int main(void)
{
    static int static_var = 85;
    static int static_var2;

    int a = 1;
    int b;

    func1(static_var + static_var2 + a + b);
    return a;
}

命令行命令:

cl /c /Za .\SimpleSection.c
dumpbin /ALL .\SimpleSection.obj > .\SimpleSection.txt

关于符号表的输出摘录:

COFF SYMBOL TABLE
000 01047558 ABS    notype       Static       | @comp.id
001 80010190 ABS    notype       Static       | @feat.00
002 00000001 ABS    notype       Static       | @vol.md
003 00000000 SECT1  notype       Static       | .drectve
    Section length   18, #relocs    0, #linenums    0, checksum        0
005 00000000 SECT2  notype       Static       | .debug$S
    Section length   94, #relocs    0, #linenums    0, checksum        0
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 UNDEF  notype       External     | global_uninit_var
00B 00000000 SECT4  notype       Static       | .text$mn
    Section length   64, #relocs    5, #linenums    0, checksum  D696A53
00D 00000000 UNDEF  notype ()    External     | printf
00E 00000000 SECT4  notype ()    External     | func1
00F 00000030 SECT4  notype ()    External     | main
010 00000000 SECT4  notype       Label        | $LN3
011 00000030 SECT4  notype       Label        | $LN3
012 00000000 SECT5  notype       Static       | .xdata
    Section length   10, #relocs    0, #linenums    0, checksum 434E1581
014 00000000 SECT5  notype       Static       | $unwind$func1
015 00000000 SECT6  notype       Static       | .pdata
    Section length   18, #relocs    6, #linenums    0, checksum 5710F00F
017 00000000 SECT6  notype       Static       | $pdata$func1
018 00000008 SECT5  notype       Static       | $unwind$main
019 0000000C SECT6  notype       Static       | $pdata$main
01A 00000004 SECT3  notype       Static       | $SG6143
01B 00000008 SECT3  notype       Static       | ?static_var@?1??main@@9@9 (`main'::`2'::static_var)
01C 00000000 SECT7  notype       Static       | .bss
    Section length    4, #relocs    0, #linenums    0, checksum        0
01E 00000000 SECT7  notype       Static       | ?static_var2@?1??main@@9@9 (`main'::`2'::static_var2)
01F 00000000 SECT8  notype       Static       | .chks64
    Section length   40, #relocs    0, #linenums    0, checksum        0

String Table Size = 0x8F bytes

  Summary

           4 .bss
          40 .chks64
           C .data
          94 .debug$S
          18 .drectve
          18 .pdata
          64 .text$mn
          10 .xdata

可是对照global_init_var那一行的信息,第二列是00000000,如果这一列表示符号的大小,那显示的应该是00000004,这显然与书上说的矛盾,这让我很困惑。

对照.data中的数据:

SECTION HEADER #3
   .data name
       0 physical address
       0 virtual address
       C size of raw data
     200 file pointer to raw data (00000200 to 0000020B)
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
C0300040 flags
         Initialized Data
         4 byte align
         Read Write

RAW DATA #3
  00000000: 54 00 00 00 25 64 0A 00 55 00 00 00              T...%d..U...

54 00 00 00的十进制是84,那么这个是变量global_init_var,而25 64 0A 00这个显然是字符串"%d\n"了,55 00 00 00是变量static_var

再次结合之前讲到的关于ELF文件关于符号的内容:

符号值(st_value)我们前面已经介绍过,每个符号都有一个对应的值,如果这个符号是一个函数或变量的定义,那么符号的值就是这个函数或变量的地址……在目标文件中,如果是符号的定义并且该符号不是“COMMON块”类型的,则st_value表示该符号在段中的偏移。即符号所对应的函数或变量位于由st_shndx指定的段,偏移st_value的位置。这也是目标文件中定义全局变量的符号的最常见情况……

那么可以初步断定这一列表示的意义实际上是变量或函数在该段中的偏移量,再结合代码段看看:

SECTION HEADER #4
.text$mn name
       0 physical address
       0 virtual address
      64 size of raw data
     20C file pointer to raw data (0000020C to 0000026F)
     270 file pointer to relocation table
       0 file pointer to line numbers
       5 number of relocations
       0 number of line numbers
60500020 flags
         Code
         16 byte align
         Execute Read

RAW DATA #4
  00000000: 89 4C 24 08 48 83 EC 28 8B 54 24 30 48 8D 0D 00  .L$.H.?.T$0H...
  00000010: 00 00 00 E8 00 00 00 00 48 83 C4 28 C3 CC CC CC  ...?...H.?锰烫
  00000020: CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC  烫烫烫烫烫烫烫烫
  00000030: 48 83 EC 38 C7 44 24 20 01 00 00 00 8B 05 00 00  H.?荄$ ........
  00000040: 00 00 8B 0D 00 00 00 00 03 C8 8B C1 03 44 24 20  .........??D$ 
  00000050: 03 44 24 24 8B C8 E8 00 00 00 00 8B 44 24 20 48  .D$$.辱.....D$ H
  00000060: 83 C4 38 C3                                      .??

RELOCATIONS #4
                                                Symbol    Symbol
 Offset    Type              Applied To         Index     Name
 --------  ----------------  -----------------  --------  ------
 0000000F  REL32                      00000000        1A  $SG6143
 00000014  REL32                      00000000         D  printf
 0000003E  REL32                      00000000        1E  ?static_var2@?1??main@@9@9 (`main'::`2'::static_var2)
 00000044  REL32                      00000000        1B  ?static_var@?1??main@@9@9 (`main'::`2'::static_var)
 00000057  REL32                      00000000         E  func1

将目标文件反汇编:

dumpbin /disasm .\SimpleSection.obj > .\SimpleSection.asm

反汇编文件内容:

Microsoft (R) COFF/PE Dumper Version 14.29.30040.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file .\SimpleSection.obj

File Type: COFF OBJECT

func1:
  0000000000000000: 89 4C 24 08        mov         dword ptr [rsp+8],ecx
  0000000000000004: 48 83 EC 28        sub         rsp,28h
  0000000000000008: 8B 54 24 30        mov         edx,dword ptr [rsp+30h]
  000000000000000C: 48 8D 0D 00 00 00  lea         rcx,[$SG6143]
                    00
  0000000000000013: E8 00 00 00 00     call        printf
  0000000000000018: 48 83 C4 28        add         rsp,28h
  000000000000001C: C3                 ret
  000000000000001D: CC                 int         3
  000000000000001E: CC                 int         3
  000000000000001F: CC                 int         3
  0000000000000020: CC                 int         3
  0000000000000021: CC                 int         3
  0000000000000022: CC                 int         3
  0000000000000023: CC                 int         3
  0000000000000024: CC                 int         3
  0000000000000025: CC                 int         3
  0000000000000026: CC                 int         3
  0000000000000027: CC                 int         3
  0000000000000028: CC                 int         3
  0000000000000029: CC                 int         3
  000000000000002A: CC                 int         3
  000000000000002B: CC                 int         3
  000000000000002C: CC                 int         3
  000000000000002D: CC                 int         3
  000000000000002E: CC                 int         3
  000000000000002F: CC                 int         3
main:
  0000000000000030: 48 83 EC 38        sub         rsp,38h
  0000000000000034: C7 44 24 20 01 00  mov         dword ptr [rsp+20h],1
                    00 00
  000000000000003C: 8B 05 00 00 00 00  mov         eax,dword ptr [?static_var2@?1??main@@9@9]
  0000000000000042: 8B 0D 00 00 00 00  mov         ecx,dword ptr [?static_var@?1??main@@9@9]
  0000000000000048: 03 C8              add         ecx,eax
  000000000000004A: 8B C1              mov         eax,ecx
  000000000000004C: 03 44 24 20        add         eax,dword ptr [rsp+20h]
  0000000000000050: 03 44 24 24        add         eax,dword ptr [rsp+24h]
  0000000000000054: 8B C8              mov         ecx,eax
  0000000000000056: E8 00 00 00 00     call        func1
  000000000000005B: 8B 44 24 20        mov         eax,dword ptr [rsp+20h]
  000000000000005F: 48 83 C4 38        add         rsp,38h
  0000000000000063: C3                 ret

  Summary

           4 .bss
          40 .chks64
           C .data
          94 .debug$S
          18 .drectve
          18 .pdata
          64 .text$mn
          10 .xdata

可以看到func1确实是以00000000开头,main以00000030开头,那么可以确定之前的结论是正确的。对于变量和函数来说,符号表输出的第二列是其在段内的偏移量。而对于global_uninit_var这样的(COMMON块)变量才表示是符号的大小,即符号所表示的对象所占用的空间:

// ...
long long global_uninit_var;
int global_uninit_var2;
// ...
int main()
{
	// ...
}
00A 00000008 UNDEF  notype       External     | global_uninit_var
00B 00000004 UNDEF  notype       External     | global_uninit_var2

标签:00,符号表,5.5,CC,00000000,int,Static,notype,勘误
来源: https://www.cnblogs.com/juzaizai/p/15173066.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有