Search code examples
c++dlsymsymbol-table

Reference a variable by name in C++ by using Symbol Table


Basically what the title asks.

Being a bit unfamiliar with C++, and the more advanced concepts such as symbol tables, I've looked into it online but am struggling to find any direction towards what my end goal is. Most of the tutorials I've seen cater to C, and the closest question I've found (here) puts me at a brick wall, as I've tried compiling it but I'm not getting the desired results, and I'm not too solid on how extern "C" works yet.

By the end of this, I want to be able to access a variable from the symbol table, and change the variable. I have played around with nm and objdump (and coming from a hardware background, it's definitely cool to look at), and I looked into dlsym, dlopen, etc. but I'm not sure how that could help me (especially since I've seen it used in C more than anything else).

Any advice or small snippets of code (so I can write my own sample program) would be great. Just to add, this is on a Linux system with a sort of outdated version of G++ (I'm not on the machine right now so I don't have that information) and I don't have access to upgrade it right now.


Solution

  • Here's an example program that shows how to use dlsym to look up a symbol:

    #include <dlfcn.h>
    #include <iostream>
    
    extern "C" int my_variable = 42;
    
    int main()
    {
        if (int* p = (int*)dlsym(NULL, "my_variable"))
            std::cout << "my_variable @" << p << ' ' << *p << '\n';
        else
            std::cout << "dlsym failed\n";
    }
    

    The extern "C" bit prevents name mangling, ensuring the symbol table entry is simply the "my_variable" text passed to dlsym(). You could not use extern "C" and provide a mangled name, but that would be compiler specific.

    To compile the code, use:

    g++ x.cc -o x -ldl -rdynamic
    

    The -ldl is the library for dlsym, and -rdynamic asks not to discard symbol information for seemingly unused variables (see here):

    -rdynamic Pass the flag -export-dynamic to the ELF linker, on targets that support it. This instructs the linker to add all symbols, not only used ones, to the dynamic symbol table. This option is needed for some uses of dlopen or to allow obtaining backtraces from within a program

    Output on my machine:

    my_variable @0x401010 42