c++ - 来自同一地址的 readelf 几乎重复的符号

标签 c++ linux linker readelf

我正在使用 readelf 来弄清楚为什么二进制文件如此之大,但我对输出感到困惑。或者我的二进制链接非常错误。现在二进制大约有 380MB,如果我这样做:

readelf -W -s binary | awk 'NR > 3 { sum += $3 } END { print sum }'

我得到 236221726 个字节。似乎很低,但也许我缺少静态符号或什么。但如果我这样做:

readelf -W -s binary | sort -n -r -k 3 | less

我看到了这个:

172766: 000000000cf8d960 99993 FUNC GLOBAL DEFAULT 10 symbolA

147338: 000000000cf8d960 99993 FUNC GLOBAL DEFAULT 10 symbolB

132791: 000000000cf8d960 99993 FUNC GLOBAL DEFAULT 10 symbolA

107363: 000000000cf8d960 99993 FUNC GLOBAL DEFAULT 10 symbolB

其中 symbolA 和 symbolB 仅 1 个字符不同,并且分解为同一事物。

所以,我的问题是: 1)如果这些东西有相同的地址,我的二进制文件中实际上有四个拷贝吗? 2) 如果没有四个拷贝,并且这些是别名,那么 readelf 不应该报告吗? 3)如果是四份,如何以及为什么?我假设我在做一些不好的链接方面的事情。 4) 如果没有四个拷贝,则 readelf 的总大小比二进制文件的实际大小要小得多 - 为什么?

编辑:添加更多信息... 上面的 readelf 输出来自完全链接的二进制文件。仅查看包含 symbolA/symbolB 的 .o,readelf 仍会在同一地址报告每个 symbolA 和 symbolB 的 1 个拷贝。

但是如果我 objdump -d .o 文件,我只看到 symbolA 的程序集。

那么 - objdump 或 readelf 是“错误的”吗?

最佳答案

如果您将一个函数定义放在一个头文件中,然后将这个头文件包含在不同的源文件中,那么每次包含都会生成一个不同的函数(好吧,除非它在特定源文件中的任何地方都被内联).如果不查看您的来源,很难判断,但情况可能就是这样。

考虑在单独的源文件中移动大型非内联函数,在相应的头文件中只留下声明。这可能会成功。

关于c++ - 来自同一地址的 readelf 几乎重复的符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44167430/

相关文章:

c++ - 通过网络发送可变长度数组?

android - Android Studio 项目中的 C++ 代码是否最终出现在 apk 文件中(除了 .so 文件)?

c++ - 我需要哪个 SDK 来确保 Visual Studio C++ 2017 中的 Windows 7 兼容性

c++ - 向 C++ 文件添加命名空间的脚本

linux - 哪个lib属于deb

c++ - 当涉及路径时,如何编写与系统无关的代码?

c++ - 读取 Windows 套接字上的 SIO_KEEPALIVE_VALS 字段(用于保持空闲和间隔时间)

c - 如何向从 shell 脚本启动的所有进程发送 SIGSTOP

linux - 链接器如何将程序头添加到可重定位文件?

c++ - 包括 .cpp 文件?