使用nm 无代码
只要让你的东西成为一个全局变量。 nm 可以报告它的大小。
// getsize.c
struct foo {
char str[3];
short s; // expect padding galore...
int i;
} my_struct;
编译但不链接,然后使用nm:
$ gcc -c getsize.c
$ nm getsize.o --format=posix
my_struct C 000000000000000c 000000000000000c
请注意,最后一列是大小(十六进制),我们可以通过以下方式获取它:
$ nm test.o -P | cut -d ' ' -f 4
000000000000000c
# or in decimal
$ printf %d 0x`nm test.o -P | cut -d ' ' -f 4`
12
使用objdump 无代码
如果nm 因某种原因不起作用,您可以将size 本身 存储在全局变量中。
从这个 C 文件开始:
// getsize.c
struct foo { char str[3]; short s; int i; };
unsigned long my_sizeof = sizeof(struct foo);
现在我们必须从目标文件中找到这个变量的值。
$ gcc -c sizeof.c
$ objdump -Sj .data sizeof.o
test.o: file format elf64-x86-64
Disassembly of section .data:
0000000000000000 <my_sizeof>:
0: 0c 00 00 00 00 00 00 00 ........
该死的,小端!您可以编写一个脚本来解析它,但以下解决方案(假设 GCC 扩展)将强制它始终为大端:
// getsize.c
struct foo { char str[3]; short s; int i; };
struct __attribute__ ((scalar_storage_order("big-endian"))) {
unsigned long v;
} my_sizeof = { sizeof(struct foo) };
这会产生:
0000000000000000 <my_sizeof>:
0: 00 00 00 00 00 00 00 0c ........
小心!您不能只删除所有非十六进制字符,因为有时右侧的“....”内容将是有效的 ASCII。但第一个应该始终是.。以下命令在: 和第一个. 之间保留内容。
$ gcc -c sizeof.c
$ objdump -Sj .data sizeof.o |
sed '$!d # keep last line only
s/\s//g # remove tabs and spaces
s/.*:\([^.]*\)\..*/\1/' # only keep between : and .'
000000000000000c