c - 如何从 ELF 文件中提取通过编译器优化添加的常量地址?

标签 c debugging embedded dwarf

我正在为我的 C 程序编写一些代码大小分析工具,使用输出 ELF 文件。

我正在使用 readelf -debug-dump=info 生成 Dwarf 格式文件

我注意到我的编译器正在将 Dwarf 文件中没有的新常量添加到 .rodata 部分,作为优化的一部分。

所以.rodata部分大小包括它们的大小,但我在Dwarf中没有它们的大小。

这是 map 文件的示例:

*(.rodata)
 .rodata        0x10010000       0xc0 /<.o file0 path>
                0x10010000                const1
                0x10010040                const2

 .rodata        0x100100c0        0xa /<.o file1 path>

  fill         0x100100ca        0x6 

 .rodata        0x100100d0       0x6c /<.o file2 path>
                0x100100d0                const3
                0x100100e0                const4
                0x10010100                const5
                0x10010120                const6

    fill        0x1001013c        0x4 

在上面的 file1 中,虽然我没有声明 const 变量 - 编译器做了声明,但这个 const 占用了 .rodata 中的空间,但没有它的符号/名称。

这是生成它的某个函数内的代码:

uint8 arr[3][2] = {{146,179},
                   {133, 166},
                   {108, 141}} ;

因此编译器添加一些常量值来优化数组的负载。

如何从数据部分中提取这些隐藏的添加内容?

我希望能够完全表征我的代码 - 每个文件使用了多少空间等...

最佳答案

我在这里猜测 - 它将取决于链接器,但是当您有如下代码时:

uint8 arr[3][2] = {{146,179},
                   {133, 166},
                   {108, 141}} ;

arr在运行时存在于读/写内存中,但其初始化程序将位于R/O内存中,并在数组初始化时复制到读/写内存中。链接器只需要提供地址,因为该大小将在本地被称为作为初始化代码中的文字嵌入的编译时常量。因此,大小信息不会出现在映射中,因为链接器会丢弃该信息。

但是,长度是由填充空间的相邻对象的地址隐含的。例如:

例如,const1 的大小等于 const2 - const1,对于 const6 来说,它是 0x1001013c - const6 >.

然而,这一切都相当学术性 - 您可以根据常量初始化程序的大小来精确控制它。它们并不是神奇地创建的与您的代码无关的数据,而且我不相信您是像您所建议的那样优化的产物。无论优化选项如何,非零初始化程序都必须存在,并且在任何情况下,优化主要影响代码 (.text) 的大小和/或速度,而不是数据。对数据大小的影响可能仅与填充和对齐有关,并且在调试版本中可能与溢出检测的“保护空间”有关。

但是完全没有必要猜测。您可以通过在调试器中检查反汇编或观察其执行(在指令级别)来确定如何使用此数据 - 以准确查看初始化变量从何处复制数据。您甚至可以在这些地址处放置一个读取访问断点,然后您将直接确定哪些代码正在使用它们。

关于c - 如何从 ELF 文件中提取通过编译器优化添加的常量地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49430840/

相关文章:

visual-studio-2010 - Visual Studio 2010 调试器不会在断点处停止?

matlab - 在 Matlab 中调试各个部分

c++ - 更深层次的带宽消耗

c - 仅通过 C 中的错误处理强制输入为正数

debugging - 如何强制 glfwInit() 因调试目的而失败?

embedded - 如何确定嵌入式系统中的最大堆栈使用量?

c++ - 在使用模板的c++中核心类型不同的不同项目中使用通用代码

python - 如何防止嵌入式 python 退出()我的进程

C - 如何更改 Ncurses 中的字体大小?

c - 寻找最大的回文数