Search code examples
clinuxsymbol-tablesymbol-tables

Is it possible to determine if a symbol is a variable or function in C?


I am implementing some limited remote debugging functionality for an application written in C running on a Linux box. The goal is to communicate with the application and lookup the value of an arbitrary variable or run an arbitrary function.

I am able to lookup symbols through dlsym() calls, but I am unable to determine if the address returned refers to a function or a variable. Is there a way to determine typing information via this symbol table?


Solution

  • You can read the file /proc/self/maps and parse the first three fields of each line:

    <begin-addr>-<end-addr> rwxp ...
    

    Then you search the line that contains the address you are looking for and check the permissions:

    • r-x: it is code;
    • rw-: it is writable data;
    • r--: it is read-only data;
    • any other combination: something weird (rwxp: generated code, ...).

    For example the following program:

    #include <stdio.h>
    
    void foo() {}
    int x;
    
    int main()
    {
        int y;
        printf("%p\n%p\n%p\n", foo, &x, &y);
        scanf("%*s");
        return 0;
    }
    

    ...in my system gives this output:

    0x400570
    0x6009e4
    0x7fff4c9b4e2c
    

    ...and these are the relevant lines from /proc/<pid>/maps:

    00400000-00401000 r-xp 00000000 00:1d 641656       /tmp/a.out
    00600000-00601000 rw-p 00000000 00:1d 641656       /tmp/a.out
    ....
    7fff4c996000-7fff4c9b7000 rw-p 00000000 00:00 0    [stack]
    ....
    

    So the addresses are: code, data and data.