I was recently trying to hide some symbols from 3rd party DSO and came across "--filter" LD option for creating "filter DSO". From the ld manpage, I have an impression that the dynamic linker will only take into account symbols which are present in filter DSO's dynsym:
"The dynamic linker will resolve symbols according to the symbol table of the filter object as usual, but it will actually link to the definitions found in the shared object name."
So it looks just what I need: a way to select which symbols from a DSO take part in dynamic linkage. Unfortunately, it does not work as I expect (this example can also be cloned from github)
Makefile:
lib1.so: lib1.c
gcc -shared -fPIC $^ -o $@
lib2.so: lib2.c
gcc -shared -fPIC $^ -o $@
lib2f.so: lib2f.c
gcc -shared -fPIC -Wl,--filter,lib2.so $^ -o $@
main: lib1.so lib2.so lib2f.so main.c
gcc main.c -L. -l2f -l1 -o $@
clean:
rm *.o *.so main
lib1.c
#include <stdio.h>
void func1()
{
printf("func1@lib1\n");
}
void func2()
{
printf("func2@lib1\n");
}
lib2.c
#include <stdio.h>
void func1()
{
printf("func1@lib2\n");
}
void func3()
{
printf("func3@lib2\n");
}
lib2f.c (filter for lib2.so):
void func3() {}
Executable
void func1();
void func2();
void func3();
int main()
{
func1();
func2();
func3();
return 0;
}
When I run that test program, I get following output:
> LD_LIBRARY_PATH=. ./main
func1@lib2
func2@lib1
func3@lib2
One can see that a symbol from lib2 is actually referenced despite the attempt to "filter" it with lib2f.so. What I would like the output to look like is
> LD_LIBRARY_PATH=. ./main
func1@lib1 // use func1 from lib1
func2@lib1
func3@lib2
Is it at all possible to achieve my goal (hiding some symbols from a DSO) with ld --filter option (aka DT_FILTER)?
If not, what is wrong in my expectations/reading of man pages?
Described behavior occurs on glibc 2.34 and 2.17.