Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Restricting symbols from getting exported to global symb table

99 views
Skip to first unread message

anirudh

unread,
Nov 26, 2009, 11:20:52 AM11/26/09
to
Hi All,

We have an executable on Linux which is linked to some third party
library. When our executable gets loaded , we got symbol conflicts for
the third party shared library.
To resolve the symbol conflict we tried to build our executable with
'--version-script' to restrict the symbols to local scope , however we
found that symbols were still getting exported to global symbol table.

After looking at some mailing list we found that the --version-script
option works only with Shared library and not with executable on Linux
platform.

We tried another linker flag 'retain-symbol-file’ which is applicable
to even executable s that prevents symbols being added to global
symbol table. With this option, we could see that only listed symbols
in the file were shown in the ‘nm’ output but still we see symbol
conflict when executable gets loaded.

Can anyone please suggest some way we can restrict exporting of our
symbols to global symbol table?

Thanks in advance

Jan Seiffert

unread,
Nov 26, 2009, 1:17:11 PM11/26/09
to
anirudh schrieb:

The only thing i can think of is the -fvisibility=hidden option of GCC.
Please refer to the manual for it.
On Solaris with the Sun ld you can specify a mapfile with -M where you can make
your GLOB symbols LOCL at link time:
$ cat main.c
int main(int argc, char *argv[])
{
return 0;
}
$ gcc main.c -o main
$ nm main | grep GLOB
[64] | 133028| 0|OBJT |GLOB |0 |15 |_DYNAMIC
[67] | 132864| 0|OBJT |GLOB |0 |13 |_GLOBAL_OFFSET_TABLE_
[61] | 132904| 0|OBJT |GLOB |0 |14 |_PROCEDURE_LINKAGE_TABLE_
[59] | 133216| 0|OBJT |GLOB |0 |16 |__dso_handle
[69] | 133252| 0|OBJT |GLOB |0 |21 |_edata
[65] | 133284| 0|OBJT |GLOB |0 |22 |_end
[58] | 133280| 4|OBJT |GLOB |0 |22 |_environ
[60] | 67328| 0|OBJT |GLOB |0 |12 |_etext
[70] | 132976| 0|FUNC |GLOB |0 |UNDEF |_exit
[72] | 67304| 20|FUNC |GLOB |0 |11 |_fini
[71] | 67276| 28|FUNC |GLOB |0 |10 |_init
[75] | 67324| 4|OBJT |GLOB |0 |12 |_lib_version
[73] | 66680| 116|FUNC |GLOB |0 |9 |_start
[62] | 132952| 0|FUNC |GLOB |0 |UNDEF |atexit
[68] | 132964| 0|FUNC |GLOB |0 |UNDEF |exit
[76] | 67144| 28|FUNC |GLOB |0 |9 |main
$ cat mapfile
{
local:
main;
};
$ gcc main.c -Wl,-M,mapfile -o main
$ nm main | grep GLOB
[68] | 132984| 0|OBJT |GLOB |0 |15 |_DYNAMIC
[66] | 132820| 0|OBJT |GLOB |0 |13 |_GLOBAL_OFFSET_TABLE_
[59] | 132860| 0|OBJT |GLOB |0 |14 |_PROCEDURE_LINKAGE_TABLE_
[69] | 133172| 0|OBJT |GLOB |0 |16 |__dso_handle
[60] | 133208| 0|OBJT |GLOB |0 |21 |_edata
[71] | 133240| 0|OBJT |GLOB |0 |22 |_end
[72] | 133236| 4|OBJT |GLOB |0 |22 |_environ
[70] | 67284| 0|OBJT |GLOB |0 |12 |_etext
[74] | 132932| 0|FUNC |GLOB |0 |UNDEF |_exit
[76] | 67260| 20|FUNC |GLOB |0 |11 |_fini
[65] | 67232| 28|FUNC |GLOB |0 |10 |_init
[61] | 67280| 4|OBJT |GLOB |0 |12 |_lib_version
[67] | 66636| 116|FUNC |GLOB |0 |9 |_start
[73] | 132908| 0|FUNC |GLOB |0 |UNDEF |atexit
[75] | 132920| 0|FUNC |GLOB |0 |UNDEF |exit

Tada!
If you find out how you do the same under Linux without visibility hidden, tell me.

With visibility hidden on Linux the result is as good, this is from a program
which uses __attribute__((visibility("hidden")) on all symbols with external
linkage which should not be exported:
$ nm -g random_prog | grep -v " U "
08091544 R _IO_stdin_used
w _Jv_RegisterClasses
08145338 A __bss_start
08145260 D __data_start
w __gmon_start__
08091470 T __libc_csu_fini
08091480 T __libc_csu_init
08145338 A _edata
082945ac A _end
0809150c T _fini
08091540 R _fp_hw
0804a5b0 T _init
0804af10 T _start
08145340 B in6addr_any@@GLIBC_2.1
0804b630 T main
08145364 B optarg@@GLIBC_2.0
08145350 B optopt@@GLIBC_2.0
08145354 B stderr@@GLIBC_2.0
08145358 B stdin@@GLIBC_2.0
08145360 B stdout@@GLIBC_2.0

-fvisibility=hidden on the compile/link command line is the sledgehammer approach.

Otherwise i would say... clear up the name clash, at least the end of your app
is under your control.

> Thanks in advance
Greetings
Jan

--
/home
sweet
/home

anirudh

unread,
Nov 27, 2009, 10:45:49 AM11/27/09
to

Hi,

Thanks for replying...

Actually I have an executable which is statically linked to a third
party library say "ver1.a" and also uses a third party ".so" file
which is again linked with same library but different version say
"ver2.a". Problem is implementation of both these versions is
different. At the beginning, when executable is loaded, symbols from
"ver1.a" will get exported to global symbol table. Now whenever ".so"
is loaded it will try to refer to symbols from ver2.a, it will end up
referring to symbols from "ver1.a" which were previously loaded.Thus
crashing our binary.

we thought of a solution that we wont be exporting the symbols for
executable to Global symbol table, thus when ".so" gets loaded and
will try to use symbols from ver2.a it wont find it in global symbol
table and it will use its own symbols i.e symbols from ver2.a

I cant find any way by which i can restrict exporting of symbols to
global symbol table. I tried with --version-script and retain-symbol-
file, but it didn't work. For -fvisibility=hidden option, its giving
an error that " -f option may only be used with -shared". So I guess,
this too like "--version-script" works only for shared libraries not
for executable binaries.

code is in c++, OS-Linux, gcc version-3.2. It may not be possible to
recompile any of the third party libraries and ".so"s. So option of
recompiling "so' file with bsymbolic flag is ruled out.

Any help would be appreciated.

0 new messages