gpt4 book ai didi

c - COFF 目标文件中大于 64K 的未初始化数组出现意外符号值

转载 作者:行者123 更新时间:2023-11-30 16:22:55 25 4
gpt4 key购买 nike

编辑:我在使用 clang 编译器进行测试时犯了一个错误。这与 clang 的预期一致。 Visual Studio 2015 产生了意想不到的结果。我的结论是 Visual Studio 2015 有一些可疑之处。

我观察到,我无法解释 Visual Studio 2015 生成的 COFF 对象文件中表示未初始化 C 数组的对象文件符号的值。该值应该表示数组的大小(以字节为单位),但这是不是我观察到的。我希望有人可以解释这里发生了什么。

考虑源文件 testdata_works.c

  char testb[0x10002];

考虑源文件 testdata_fails.c:

  char testa[0x10001];
char testb[0x10002];

现在编译:

cl -c testdata_works.c
cl -c testdata_fails.c

现在在两个目标文件上运行“dumpbin/symbols”并注意两个目标文件之间符号“testb”的值不同(!)见下文了解血淋淋的细节。

dumpbin /symbols testdata_works.obj

006 00010002 UNDEF notype External | testb

现在测试testdata_fails.obj

dumpbin /symbols testdata_fails.obj

006 00010001 UNDEF notype External | testa
007 00010041 UNDEF notype External | testb

我们注意到符号 testb 的预期值为 0x10002testdata_works.obj 但在 testdata_fails.obj 中具有意外值 0x10041。

我把真正奇怪的部分留到了最后,这可能会触发对于那些精通 COFF 目标文件的人来说,这是众所周知的“啊哈”格式:

将 testdata_fails.c 中的数组大小减小到以下0x10000,例如:

  char testa[0x0001];
char testb[0x0002];

并编译

cl -c testdata_fails.c

dumpbin 命令现在可以生成符号 testa 和 的预期结果测试b:

006 00000001 UNDEF  notype       External     | testa
007 00000002 UNDEF notype External | testb

对于这里发生的情况以及如何修复它以便它为大于 64K 的符号值产生预期结果有什么建议吗?

最后的评论:

我使用 clang/llvm-nm 7.0.1 而不是 Visual 重现了此内容Studio 2015/dumpbin,所以可能和COFF格式有关?

你可能会问我是如何偶然发现这个的。我正在学习 BSD内核 genassym.sh 脚本,并决定编写一个小型 C++ STL 程序从 LLVM 库可以读取的任何目标文件格式实现了相同的任务。我已经构建了这个程序,但它无法正常工作,因为目标文件中的数据不符合预期。

最佳答案

COFF 不保留数组大小。与数组符号关联的值是其起始地址。要推断数组的大小 dumpbin 必须使用一些启发式方法,例如通过查看相邻的符号、节的末尾等。显然,启发式失败了。只有编译器知道为什么 BSS 比预期的要大。

关于c - COFF 目标文件中大于 64K 的未初始化数组出现意外符号值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54217746/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com