“。”在.symtab部分的Ndx列中的含义是什么?

时间:2010-11-09 19:18:27

标签: c gcc elf

add2.c:

int counter=0;
int a=0;
int b;
int c;
int add(int a, int b) {
    return a+b;
}

汇编: gcc -c add2.c -o add2.o

阅读符号表: readelf --symbols add2.o

Symbol table '.symtab' contains 12 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS add2.c
     2: 00000000     0 SECTION LOCAL  DEFAULT    1 
     3: 00000000     0 SECTION LOCAL  DEFAULT    2 
     4: 00000000     0 SECTION LOCAL  DEFAULT    3 
     5: 00000000     0 SECTION LOCAL  DEFAULT    5 
     6: 00000000     0 SECTION LOCAL  DEFAULT    4 
     7: 00000000     4 OBJECT  GLOBAL DEFAULT    3 counter
     8: 00000004     4 OBJECT  GLOBAL DEFAULT    3 a
     9: 00000004     4 OBJECT  GLOBAL DEFAULT  COM b
    10: 00000004     4 OBJECT  GLOBAL DEFAULT  COM c
    11: 00000000    14 FUNC    GLOBAL DEFAULT    1 add

“COM”在Ndx列中的含义是什么?我理解“#”和“a”在#3部分(即.bss)中定义,“add”在#1部分(即.text)中定义,但我期待“b”和“c”也在.bss部分中定义,因此在Ndx列中得到“3”。

谢谢

3 个答案:

答案 0 :(得分:5)

gcc将未初始化的未初始化的全局变量视为“常用”符号(因此为“COM”)。

在创建最终可执行文件时,链接器将相同公共符号的多个定义(跨多个目标文件)合并在一起,以便它们都引用相同的存储。其中一个目标文件可能会将其初始化为特定值(在这种情况下,它将最终出现在数据部分中);如果没有对象文件初始化它,将最终在BSS中;如果多个对象初始化它,您将收到链接器错误。

总之,如果您有extern的两个定义:

    一个对象中的
  • int a和另一个对象中的int a;是正常的:两者都引用相同的int a;,初始化为0
  • 一个对象中的
  • a和另一个对象中的int a;是正常的:两者都引用相同的int a = 42;,初始化为42
  • 一个对象中的
  • a和另一个对象中的int a = 23;会出现链接错误。

请注意,标准C在技术上不允许在两个对象上使用相同符号的多个定义;但许多编译器都支持它,包括gcc,作为扩展。 (它在“共同扩展”下列出 - 在C99规范中没有双关语。)

答案 1 :(得分:2)

来自this PDF,表7-11:

  

SHN_COMMON
  符号定义相对于   这部分是常见的符号,例如   作为FORTRAN COMMON或未分配的C.   外部变量。这些符号是   有时被称为暂定。

另请参阅this page

答案 2 :(得分:0)

它们是由链接器分配的未初始化的全局变量。 有时被称为公共变量。

编辑:嗯,保罗贝克打败了我,链接不少。用他的答案:)