Search code examples
c++clinuxgccglibc

GCC: Executing Code at "Preinitialization" time


So on Linux when a C++ program that was compiled/linked with gcc, has its executable loaded the following happens:

  1. exec* syscall
  2. LD dynamic libraries loaded
  3. C++ static initialization
  4. entry point of main

Suppose I have some function with prototype void f(),

Is there some way (via source modification, attributes, compiler/linker options, etc) to link the executable with f such that it will be executed between step 1 and 2 ?

What about between step 2 and 3 ?

(Clearly there is no standard way to do this, I am asking for a platform-specifc, compiler-specific way for a recent versions of gcc/linux/x86_64/glibc/binutils)


Solution

  • Yes, you could do this between (1) and (2), or between (2) and (3). Step 2 "ld dynamic libraries loaded" is actually done by calling the dynamic linker, ld.so. Typically, this would be /lib64/ld-linux-x86-64.so.2 or similar; its part of glibc. However, the path is actually specified in the executable, so you can use any path you want.

    $ readelf -l `which bash`
    ⋮
    Program Headers:
    ⋮
      INTERP         0x0000000000000238 0x0000000000400238 0x0000000000400238
                     0x000000000000001c 0x000000000000001c  R      1
          [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
    
    ⋮
    

    This is in addition to doing things like LD_PRELOAD/LD_AUDIT.

    For between (2) and (3), it sounds like you just want to change the entrypoint address.