【问题标题】:Symbol Resolution for ELFELF 的符号解析
【发布时间】:2016-09-12 01:26:47
【问题描述】:

我对 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

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

【问题讨论】:

  • 因为函数和变量没有不同的命名空间,请参阅标准。并且链接器不知道对象的类型。
  • @Olaf 但它可能知道函数和变量之间的区别,它不像信息不在目标文件中。我的问题是它是否有特殊的原因没有做出区分。
  • 那么您将如何解决void *p = &main; 之类的问题?或者在函数也是对象的语言中?或者...
  • @Olaf 这是一个很好的例子。

标签: c gcc linker elf


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2015-08-25
    • 2011-10-21
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2015-12-20
    相关资源
    最近更新 更多