【问题标题】:Why size of extern variables is 0 in ELF?为什么 ELF 中外部变量的大小为 0?
【发布时间】:2019-06-06 03:48:12
【问题描述】:

c 程序中变量的外部声明导致 ELF 中的大小为 0。为什么已知的实际大小不存储在 ELF 中?对于像不完整数组这样的情况,我知道没有大小信息,但对于其他情况,应该可以存储大小。

我尝试了一些简单的代码,并验证了 ELF 发出的大小为零。

// file1.c

extern int var;
int main()
{
    var = 2;
}
// file 2.c
long long int var = 8;
gcc -c file1.c
readelf -s file1.o
...
9: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND var
...
gcc -c file2.c
readelf -s file2.o
...
7: 0000000000000000     8 OBJECT  GLOBAL DEFAULT    2 var
...

如果 var 的大小在 file1.o 中存储为 4,则链接器实际上可以在与 file2.o 链接时检测到由于大小导致的潜在不匹配。

那么为什么不发出 size ,因为它可以帮助捕捉一些像这样的微妙问题?

【问题讨论】:

  • size 不能很好地替代类型检查。 long longdouble 通常具有相同的大小,8. 大小检查不会捕获 extern long long x 被定义为 double x
  • 关于不完整数组的要点!本来打算写的,但后来发现你已经提到了。
  • @kaz,是的,在您提到的情况下,大小是不够的,但总比没有好。在目标文件中保存类型可能并不总是可能的。我还发现如果我启用 LTO,它会捕获诸如存储 -flto 类型信息并检测到不匹配并发出警告之类的不匹配。

标签: c linker elf


【解决方案1】:

file1 中,var 只是一个占位符。它不会占用任何内存。 extern 标识符用于向编译器和链接器指示变量var 存储在其他位置。

按照您的建议,为单个变量 var 设置两个存储位置是错误的。

这是 C 语言的一个怪癖,您可以为外部变量定义不同的类型,为底层全局变量定义不同的类型,就像您在示例中所做的那样。这也是我们拥有静态分析工具的原因之一。

【讨论】:

  • 虽然有将未定义符号与已定义符号合并的通用扩展。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-18
  • 2016-01-19
  • 2022-10-13
  • 1970-01-01
  • 2017-02-17
  • 1970-01-01
  • 2021-10-25
相关资源
最近更新 更多