We can use a version script to explicitly control the symbols exported by a library:
bash$ cat vis.map VER_1 { global: vis_f1; vis_f2; local: *; };
Here, our local specification says that all symbols are not exported, other than those explicitly exported by exported by global).
We can then build our shared library using the version script as follows:
bash$ gcc -g -c -fPIC -Wall vis_comm.c vis_f1.c vis_f2.c bash$ gcc -g -shared -o vis.so vis_comm.o vis_f1.o vis_f2.o \ -Wl,--version-script,vis.map
And readelf shows that vis_comm() is no longer externally visible:
bash$ readelf --syms --use-dynamic vis.so | grep vis_ 25 0: 00000730 73 FUNC GLOBAL DEFAULT 11 vis_f2 29 16: 000006f0 59 FUNC GLOBAL DEFAULT 11 vis_f1
(C) 2006, Michael Kerrisk