Goal: a shared library to use a function from an executable (which does not export symbols).

Means: gcc -Wl,--defsym,function=0x432238

The man page states that:

"--defsym symbol=expression" Create a global symbol in the output
file, containing the absolute address given by expression.

To my dismay, dlopen() is adding 0x7ffff676f000, the shared library's base address (this is 64-bit code) to the exported "absolute symbol address":

        executable        shared library
        ---------- linker --------------
symbol: 0x432238   =====> 0x7ffff6ba1238

objdump shows the correct symbol address (0x432238) in the library, but once loaded with dlopen(), the symbol has address 0x7ffff6ba1238.

If, once loaded, I manually patch the library symbol to the correct address then all works fine (else, the library SEGFAULTs).

  • Why the "absolute address" is modified?
  • How to avoid it?

Update:

I contest the technical relevance of the reply below, and, even more its 'update':

Having --defsym to define a relocated symbol in a PIC library/executable is pointless (it does not serve ANY purpose other than polluting the binary without any usable feature).

Therefore, the only relevant use of --defsym in a PIC shared library or PIC executable should be to define a (non-relocated) "absolute address".

Incidentally, that's the official purpose of --defsym if you bother to read the man page:

"Create a global symbol in the output file, containing the absolute address given by expression."

At best, this is a Linux linker deffect which would be trivial to fix. And for those who can't wait for the people-in-denial to realize (and fix) their mistake, the solution is to patch the relocation

Edit
Report