Question

I use Bash to get a c program variables' addresses. How to know if the address is related to an integer, float or double variable?

Was it helpful?

Solution

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 order
  • grep -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 symbol i and nothing else
  • cut -d' ' -f1 lists just the addresses
  • read 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 tell bc that with the ibase parameter. Also the ${var^^} bash expansion converts the hex digits a-f to uppercase as bc requires this.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top