我如何提取常数'通过编译器优化添加的地址来自ELF文件?

时间:2018-03-22 14:10:53

标签: c debugging embedded dwarf

我正在使用输出SELECT tbl.run_no, TBL.JOB_ID, TBL.STREAM_ID, TBL.FILE_NAME --INTO v_run_no, -- intentionally commented -- v_job_id, -- v_stream_id, -- v_file_name FROM REGRESSION_STATUS tbl INNER JOIN ( SELECT job_id, MIN (run_no) min_run_no FROM REGRESSION_STATUS WHERE status = 'R' GROUP BY job_id) tbl1 ON tbl1.job_id = tbl.job_id WHERE tbl1.min_run_no = tbl.run_no AND tbl.file_name LIKE '%A%'; --> or B / C / D 文件为我的C程序编写一些代码大小分析工具。

我使用ELF生成readelf -debug-dump=info

我注意到我的编译器正在添加作为优化新功能的一部分,而不是在Dwarf文件中,添加到Dwarf format file部分。

所以.rodata部分尺寸包括尺码,但我的尺码不在.rodata

以下是地图文件的示例:

Dwarf

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

以下是生成它的某个函数中的代码:

*(.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 

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

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

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

2 个答案:

答案 0 :(得分:0)

详细使用

获取精灵文件的大小

&#34;您可以使用nm和size来获取函数和ELF部分的大小。

获取函数(以及具有静态存储持续时间的对象)的大小:

$ nm --print-size --size-sort --radix = d tst.o 第二列显示函数和对象的十进制大小。

获取部分的大小:

$ size -A -d tst.o 第二列显示了部分的十进制大小。&#34;

Tool to analyze size of ELF sections and symbol

答案 1 :(得分:0)

我在这里猜测 - 它将依赖于链接器,但当你有代码如:

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

arr存在于r / w内存中,但其初始化程序将位于R / O内存中,以便在初始化阵列时复制到R / W内存。链接器只需要提供地址,因为在本地将大小称为在初始化代码中嵌入为文字的编译时常量。因此,大小信息不会出现在地图中,因为链接器会丢弃该信息。

然而,填充空间的相邻对象的地址隐含了长度。例如:

const1的大小等于const2 - const1const6的大小等于0x1001013c - const6

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

根本不需要猜测。您可以通过检查反汇编或在调试器中观察其执行(在指令级别)来确定如何使用此数据 - 以准确查看初始化变量从哪里复制数据。您甚至可以在这些地址放置读取访问断点,您将直接确定使用它们的代码。