ELF的符号解析

时间:2016-09-12 01:26:48

标签: c gcc linker elf

我有一个关于C链接中符号解析的问题(特别是与elf格式有关)。

假设我将两个模块拆分为单独的文件module1.c和module2.c:

// module1.c
int main() {
    return 0;
}

==========================

// module2.c
int main = 3;

int p2() {
    return 0;
}

将这两者编译在一起会给我一个链接器错误,因为两个模块中的main都有一个重复的符号。我的问题是,为什么链接器不能解释一个是函数而一个是变量的事实?这些信息肯定存在于两者的符号表中:

Symbol table '.symtab' contains 9 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS a.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     8: 0000000000000000    11 FUNC    GLOBAL DEFAULT    1 main

No version information found in this file.

===================================================================

Symbol table '.symtab' contains 10 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS b.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     8: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    2 main
     9: 0000000000000000    11 FUNC    GLOBAL DEFAULT    1 p2

您可以清楚地看到一个是对象,另一个是函数。我的问题是,链接器是否有任何具体原因不旨在对功能和变量进行区分?这是否意味着在由许多模块组成的庞大程序中,您永远不能声明一个与函数同名的全局变量?

1 个答案:

答案 0 :(得分:1)

这只是C语言的一个规则:函数和对象没有不同的命名空间。

所以是的 - 你不能拥有一个具有外部链接和相同名称的函数和变量。

请注意,您可以使用static关键字为文件范围变量和函数提供静态链接,并且在一个文件中具有静态链接的函数和具有静态链接的同名变量是可以的另一个文件。这减少了大型程序发生冲突的可能性。