Using nm
with no code
Just make your thing a global variable. nm
can report its size.
// getsize.c
struct foo {
char str[3];
short s; // expect padding galore...
int i;
} my_struct;
Compile but don't link, then use nm
:
$ gcc -c getsize.c
$ nm getsize.o --format=posix
my_struct C 000000000000000c 000000000000000c
Note that the last column is the size (in hex), here is how we can get it:
$ nm test.o -P | cut -d ' ' -f 4
000000000000000c
# or in decimal
$ printf %d 0x`nm test.o -P | cut -d ' ' -f 4`
12
Using objdump
with no code
If nm
doesn't work for some reason, you can store the size itself in a global variable.
Start with this C file:
// getsize.c
struct foo { char str[3]; short s; int i; };
unsigned long my_sizeof = sizeof(struct foo);
Now we have to find the value of this variable from the object file.
$ 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 ........
Darn, little endian! You could write a script to parse this, but the following solution (assuming GCC extensions) will force it to always be big endian:
// 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) };
This yields:
0000000000000000 <my_sizeof>:
0: 00 00 00 00 00 00 00 0c ........
Watch out! You can't just strip out all non-hex characters because sometimes the "...." stuff on the right will be valid ASCII. But the first one should always be a .
. The following command keeps things between the :
and the first .
.
$ 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