clinuxgccx86-64

How can I get the _GLOBAL_OFFSET_TABLE_ address in my program?


I want to get the address of _GLOBAL_OFFSET_TABLE_ in my program. One way is to use the nm command in Linux, maybe redirect the output to a file and parse that file to get address of _GLOBAL_OFFSET_TABLE_. However, that method seems to be quite inefficient. What are some more efficient methods of doing it?


Solution

  • This appears to work:

    // test.c
    #include <stdio.h>
    
    extern void *_GLOBAL_OFFSET_TABLE_;
    
    int main()
    {
        printf("_GLOBAL_OFFSET_TABLE = %p\n", &_GLOBAL_OFFSET_TABLE_);
        return 0;
    }
    

    In order to get consistent address of _GLOBAL_OFFSET_TABLE_, matching nm's result, you will need to compile your code with -fPIE to do code-gen as if linking into a position-independent executable. (Otherwise you get a small integer like 0x2ed6 with -fno-pie -no-pie). The GCC default for most modern Linux distros is -fPIE -pie, which would make nm addresses be just offsets relative to an image base, and the runtime address be ASLRed. (This is normally good for security, but you may not want it.)

    $: gcc -fPIE -no-pie test.c -o test
    

    It gives:

    $ ./test
    _GLOBAL_OFFSET_TABLE = 0x6006d0
    

    However, nm thinks different:

    $ nm test | fgrep GLOBAL
    0000000000600868 d _GLOBAL_OFFSET_TABLE_
    

    Or with a GCC too old to know about PIEs at all, let alone have it -fPIE -pie as the default, -fpic can work.