提问人:Dmitry Grigoryev 提问时间:4/6/2023 更新时间:4/11/2023 访问量:165
“nm”报告相同类型的变量的不同大小。我如何知道它们的真实尺寸?
'nm' reports different sizes for variables of the same type. How do I find out their real size?
问:
我试图找出我的程序中变量的地址和大小,我刚刚意识到我的一大堆变量出乎意料地大。我制作了以下测试文件“test.c”:nm
static char test1 = 0;
static char test2 = 0;
char test_f(void)
{
test1 = test2;
return test2;
}
int main(void)
{
return test_f();
}
然后我运行以下命令:
gcc test.c
nm -C -S --size-sort a.exe | findstr /rc:"test"
输出是
0000000140007040 0000000000000001 b test1
0000000140007041 000000000000000f b test2
0000000140001540 000000000000001a T test_f
我假设这里有某种填充/对齐在起作用,但我不明白为什么填充会成为符号的一部分。有没有办法生成类似的文本日志,其中 和 的大小均为 1?test1
test2
答:
...我不明白为什么填充物会成为符号的一部分。
nm
手册页显示“大小计算为符号值与具有下一个较高值的符号值之间的差值。因此,如果在变量 A 之后和变量 B 之前有填充,则填充将显示为 A 大小的一部分。
在您的示例中,显然紧随其后的是 ,因此 的大小被计算为一个字节。 在其程序部分中没有任何明确的符号;使用的下一个“符号”可能是下一节的开头或其中的第一个符号。下一部分有一些对齐要求,因此在下一部分之后和之前有未使用的空间,也称为填充。因此,与下一个“符号”之间的差异包括该填充,并且它显示在手册页所述的“大小”中。test1
test2
test1
test2
nm
test2
test2
test2
评论
我不明白为什么填充会成为符号的一部分
根据手册页: https://man7.org/linux/man-pages/man1/nm.1.html
ELF 格式记录符号的大小,其他格式(如 EXE)将仅报告从此符号开始到下一个符号开始的间隔大小。
有没有办法生成类似的文本日志,其中 test1 和 test2 两者的大小都是 1 吗?
在使用 ELF 二进制文件的 Linux 中执行相同的步骤。
0000000000004011 0000000000000001 b test1
0000000000004012 0000000000000001 b test2
评论
nm
long
最后,如果没有调试信息,似乎无法知道 PE 中的符号大小。使用调试信息,可以提取它,然后用 查找符号类型,然后用 找出该类型的大小:objdump -W a.exe
DW_AT_type
DW_AT_byte_size
<1><28ce>: Abbrev Number: 2 (DW_TAG_variable)
<28cf> DW_AT_name : test1
<28d5> DW_AT_decl_file : 1
<28d6> DW_AT_decl_line : 3
<28d7> DW_AT_decl_column : 13
<28d8> DW_AT_type : <0x28e6>
<28dc> DW_AT_location : 9 byte block: 3 40 70 0 40 1 0 0 0 (DW_OP_addr: 140007040)
<1><28e6>: Abbrev Number: 3 (DW_TAG_base_type)
<28e7> DW_AT_byte_size : 1
<28e8> DW_AT_encoding : 6 (signed char)
<28e9> DW_AT_name : char
<1><28ee>: Abbrev Number: 2 (DW_TAG_variable)
<28ef> DW_AT_name : test2
<28f5> DW_AT_decl_file : 1
<28f6> DW_AT_decl_line : 4
<28f7> DW_AT_decl_column : 13
<28f8> DW_AT_type : <0x28e6>
<28fc> DW_AT_location : 9 byte block: 3 41 70 0 40 1 0 0 0 (DW_OP_addr: 140007041)
评论