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 table after the binary image has been loaded by the defective linker.
Then, --defsym becomes useful in PIC libraries/executables, which seems to me is a welcome progress.