I have a shared object where file indicates it is a shared object, and it is used and behaves as a shared object.
% file libirc.so
libirc.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=9d54bda46b31ae048aae323dfd809f9ae6c8c55c, not stripped
%
But the ldd command indicates it is statically linked.
% ldd libirc.so
statically linked
%
When I run an executable, ./Solver, that uses this libirc.so it runs as expected. But when I run the same with LD_PRELOAD="io_functions.so" the run time linker, /lib64/ld-linux-x86-64.so.2, segfaults just after issuing the error message:
./Solver: Relink `./lib/libirc.so' with `/lib64/libc.so.6' for IFUNC symbol `memmove'
I can make the run using LD_PRELOAD work by also including libirc.so on the LD_PRELOAD. I don't have source for libirc.so so I can't figure out much on that end. I suspect that the troubles are centered on libirc.so being statically linked. It should not matter what code is in io_functions.so because ld.so doesn't even get to the point of calling the init functions as ld.so is segfaulting while binding symbols.
I have done a bit of investigating using LD_DEBUG. When I run with LD_PRELOAD=irc/libirc.so ld.so needs to find memmove for libstdc++ , and uses memmove [GLIBC_2.2.5] from /lib64/libc.so.6. Later ld.so needs to find memmove for libirc.so and also uses memmove from libc.so.6.
LD_DEBUG output from successfull run with LD_PRELOAD=irc/libirc.so
3677171: binding file /lib64/libstdc++.so.6 [0] to /lib64/libc.so.6 [0]: normal symbol `memmove' [GLIBC_2.2.5]
.
.
.
3677171: binding file irc/libirc.so [0] to /lib64/libc.so.6 [0]: normal symbol 'memmove'
When I run the failing job (without LD_PRELOAD=irc/libirc.so), ld.so first needs to find memmove for libirc.so and finds it in libc.so.6. ld.so then prints out the Relink message, followed by a segfault. Why does running this way cause the Relink message and segfault, even though its finding memmove for libirc.so in the same place ( libc.so.6 ) as the above successful run?
The last LD_DEBUG line for this process, followed by the print
3676728: binding file irc/libirc.so [0] to /lib64/libc.so.6 [0]: normal symbol `memmove'
./bin/SMAEqsDirSolverSymmetric: Relink `irc/libirc.so' with `/lib64/libc.so.6' for IFUNC symbol `memmove'
There is nothing inherently crooked about a DSO that ldd
reports as statically linked. In that case ldd is just telling
you that the DSO has no dynamic dependencies itself.
Here comes one such:
$ gcc --version
gcc (Ubuntu 13.2.0-4ubuntu3) 13.2.0
This compiler emits PIC code by default.
$ cat hello.c
#include <stdio.h>
void hello(void)
{
puts("Hello World");
}
$ gcc -shared -o libhello-musl.so hello.c -L/usr/lib/x86_64-linux-musl/ -l:libc.a
The stock muscl static libc built for and by my compiler contains PIC object files,
so it harbours no relocation errors.
$ file libhello-musl.so
libhello-musl.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=015152e75131cd274f08fa16447ff926b7c6d85d, not stripped
and:
$ ldd libhello-musl.so
statically linked
even though I did not attempt to link -shared -static (which would fail). ldd says that because there is no dynamic section in the shared library:
$ readelf --dynamic libhello-musl.so | grep NEEDED; echo Done
Done
Because it doesn't need one. Whereas:
$ gcc -shared -o libhello-gnu.so hello.c
$ readelf --dynamic libhello-gnu.so | grep NEEDED; echo Done
0x0000000000000001 (NEEDED) Shared library [libc.so.6]
Done
$ ldd libhello-gnu.so
linux-vdso.so.1 (0x00007ffc4f5ce000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000079377ee00000)
/lib64/ld-linux-x86-64.so.2 (0x000079377f104000)
libhello-musl.so is fit for purpose.
$ cat main.c
#include <stdio.h>
extern void hello(void);
int main(void)
{
hello();
return 0;
}
$ gcc -o hello main.c -L. -lhello-musl -Wl,-rpath=$(pwd)
$ ./hello
Hello World
$ ltrace -l libhello-musl.so ./hello
hello->hello(1, 0x7ffd219317d8, 0x7ffd219317e8, 0x5c2dd535bda0 <unfinished ...>
libhello-musl.so->puts("Hello World" <unfinished ...>
libhello-musl.so->fputs("Hello World", 0x78c0473fe060 <unfinished ...>
libhello-musl.so->strlen("Hello World") = 11
libhello-musl.so->fwrite("Hello World", 1, 11, 0x78c0473fe060 <unfinished ...>
libhello-musl.so->memcpy(0x78c0473fe188, "Hello World", 11) = 0x78c0473fe188
<... fwrite resumed> ) = 11
<... fputs resumed> ) = 0
Hello World
<... puts resumed> ) = 0
<... hello resumed> ) = 0
+++ exited (status 0) +++
In this light:
I suspect that the troubles are centered on
libirc.sobeing statically linked.
seems to be a misplaced suspicion.
The internet throws up other examples of the same class of
Relink `/path/to/libsome.so' with `/path/to/libc.so.6' for IFUNC symbol `symbol'
error, in which the observation that libsome.so is statically linked does not appear.
These include:
in which as it happens the libsome.so = /usr/lib/libgcc_s.so.1 transpires to have been
linked against libc.musl-x86_64.so.1 .
and:
which is identical to your error modulo paths.
and:
which implicates glibc patch:
committed Oct. 21st 2021.
In this light, like @n. m. could be an AI, I suggest
that the version of [g]libc that your libirc.so has been statically
linked with is unaligned with the one that your ./Solver is linked with. The likeliest remedy - as usual? - is to obey the diagnostic: get a new libirc.so that you know has been linked
with libc.so.6 (or a static PIC version of same). If that's difficult just getting the
latest version of libirc.so from wherever you got it may be a fix.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With