-fvisibility=hidden

Greg Banks gnb at fastmail.fm
Thu Jul 19 22:02:10 EDT 2012



On Fri, Jul 20, 2012, at 12:13 AM, Дилян Палаузов wrote:
> Hello,
> 
> On 19.07.2012 03:11, Greg Banks wrote:
> > On Wed, Jul 18, 2012, at 10:46 PM, Дилян Палаузов wrote:
> >> On 16.07.2012 02:08, Greg Banks wrote:
> 
> > That's a lot of exported symbols for such a small library :(
> >
> > But you could fix that without advanced non-portable linker trickery, by
> > (for example) moving chunks of sieve/tree.c into sieve/sieve.y, or
> > #include'ing one into the other or vice versa.
> 
> The most T-symbols are generated by flex/bison and this cannot be 
> tricked.  Flex can be instructed not to generate unnecessary functions 
> with %option noyyset_in or alike, however flex on ci.cyrus-imapd.org 
> does not support these options.  So the functions are there.

You could always post-process the generated C code at build time with a
two-line Perl script which inserts the word "static" in front of
function definitions and/or declarations.

> Moving functions from tree.c to sieve.y is marginal compared to the 
> amount of functions created by bison/flex.
> 
> The non-portable trickery does not harm.  It is supported by GCC and 
> Clang (according to 
> http://clang-developers.42468.n3.nabble.com/Does-clang-support-attribute-visibility-quot-default-quot-td3944043.html 
> ).  

There are still some other compilers left in the world.  The Sun, sorry
Oracle, compiler, for example, will parse and ignore both
__attribute__(visibility()) in the code and -fvisibility=hidden on the
commandline, without failing.

-bash-3.00$ cat foo.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int foo(int x)
{
        return x+42;
}

__attribute__((visibility("default"))) int bar(int x)
{
        return x-42;
}


-bash-3.00$ ld -V
ld: Software Generation Utilities - Solaris Link Editors: 5.10-1.493
-bash-3.00$ cc -V
cc: Sun C 5.10 SunOS_i386 2009/06/03
usage: cc [ options] files.  Use 'cc -flags' for details

-bash-3.00$ cc -Kpic -fvisibility=hidden -c -o foo.o foo.c
cc: Warning: Option -fvisibility=hidden passed to ld, if ld is invoked,
ignored otherwise

-bash-3.00$ cc -Kpic -G -o libfoo.so foo.o

-bash-3.00$ nm foo.o | egrep '(foo|bar)'
foo.o:
[17]    |        32|      26|FUNC |GLOB |0    |2      |bar
[16]    |         0|      26|FUNC |GLOB |0    |2      |foo
[1]     |         0|       0|FILE |LOCL |0    |ABS    |foo.c

-bash-3.00$ nm libfoo.so | egrep '(foo|bar)'
libfoo.so:
[42]    |       592|      26|FUNC |GLOB |0    |4      |bar
[43]    |       560|      26|FUNC |GLOB |0    |4      |foo
[31]    |         0|       0|FILE |LOCL |0    |ABS    |foo.c
[1]     |         0|       0|FILE |LOCL |0    |ABS    |libfoo.so

-bash-3.00$ nm -D libfoo.so | egrep '(foo|bar)'
libfoo.so:
[6]     |       592|      26|FUNC |GLOB |0    |4      |bar
[7]     |       560|      26|FUNC |GLOB |0    |4      |foo

nm -D does the same thing as the GNU nm, i.e. prints the symbols visible
to the dynamic linker.

Here, you're lucky that -fvisibility=hidden is effectively ignored by
the compile stage, and is harmlessly misinterpreted by the linker as

     -f name

         Useful only when building  a  shared  object.  Specifies
         that the symbol table of the shared object is used as an
         auxiliary filter on  the  symbol  table  of  the  shared
         object  specified  by  name.  Multiple instances of this
         option are allowed. This option can not be combined with
         the -F option.

I think that you can solve this problem in a more portable way, that
actually does the useful thing you want to achieve on all platforms,
without breaking our link semantics on any platform.

-- 
Greg.


More information about the Cyrus-devel mailing list