As the comments mentioned you can't get the type unless you have debugging symbols. But if you do have the symbols then you can use GDB. Consider this program:
#include <stdio.h>
static int i = 42;
static float f = 42.1;
static double d = 42.2;
int main (int argc, char **argv) {
printf("i=%d, f=%f, d=%f\n", i, f, d);
return (0);
}
If you compile it as follows:
gcc -g -o types types.c
You can then get the type of variables like this:
ubuntu@ubuntu:~$ echo ptype i | gdb --silent types Reading symbols from /home/ubuntu/types...done. (gdb) type = int ubuntu@ubuntu:~$ echo ptype f | gdb --silent types Reading symbols from /home/ubuntu/types...done. (gdb) type = float ubuntu@ubuntu:~$ echo ptype d | gdb --silent types Reading symbols from /home/ubuntu/types...done. (gdb) type = double ubuntu@ubuntu:~$
If you only have the symbol table and not full debugging information, i.e. the binary was compiled with -g
, then processed by strip -d
, then the best you can do is get the size of the given object using binary dump utilities such as nm
, objdump
or readelf
.
Using nm
:
ubuntu@ubuntu:~$ read addr next_addr <<< $(nm -n types | grep -A1 ' i$' | cut -d' ' -f1)
ubuntu@ubuntu:~$ echo "ibase=16; ${next_addr^^} - ${addr^^}" | bc
4
ubuntu@ubuntu:~$ read addr next_addr <<< $(nm -n types | grep -A1 ' f$' | cut -d' ' -f1)
ubuntu@ubuntu:~$ echo "ibase=16; ${next_addr^^} - ${addr^^}" | bc
4
ubuntu@ubuntu:~$ read addr next_addr <<< $(nm -n types | grep -A1 ' d$' | cut -d' ' -f1)
ubuntu@ubuntu:~$ echo "ibase=16; ${next_addr^^} - ${addr^^}" | bc
8
ubuntu@ubuntu:~$
This works as follows:
nm -n
lists the symbol table with addresses in numerical ordergrep -A1 ' i$
filters the symbol we are interested long with the immediately following line. Note this is a regular expression search constructed to find exactly the symboli
and nothing elsecut -d' ' -f1
lists just the addressesread addr next_addr
puts the addresses into two variables- The expression piped into
bc
then calculates the difference between the address we are interested in and the immediately following address. Note the addresses are in hex, so we need to tellbc
that with theibase
parameter. Also the${var^^}
bash expansion converts the hex digits a-f to uppercase asbc
requires this.