[Pixman] Hidden symbols in libraries

Siarhei Siamashka siarhei.siamashka at gmail.com
Mon Aug 26 13:27:35 PDT 2013


On Mon, 26 Aug 2013 13:54:32 +1000
Mark Ashley <mark at ibiblio.org> wrote:

> I'm compiling on Solaris with the SunStudio 12.3 compilers.
> 
> The recipie is:
> 
>     cd /var/tmp
>     rm -rf pixman-0.30.2
>     untgz /usr/local/src/graphics/pixman-0.30.2.tar.gz
>     cd pixman-0.30.2
>     ./configure --prefix=/usr/local \
>         --disable-mmx \
>         --disable-vmx \
>         --disable-sse2 \

If you have an x86 system, then disabling mmx and sse2 is not a very
good idea. Otherwise the performance is going to be much worse.

>         --disable-silent-rules \
>         --disable-gcc-inline-asm
>     gmake
> 
> What happens is these errors show up:
> 
> DEPDIR=.deps depmode=none /bin/sh ../depcomp \
> cc -DHAVE_CONFIG_H -I. -I..  -I../pixman -I../pixman
> -I/usr/local/include/libpng16   -xopenmp -O -g -xldscope=hidden -c
> prng-test.c
> /bin/sh ../libtool  --tag=CC   --mode=link cc -xopenmp -O -g
> -xldscope=hidden -xopenmp   -o prng-test prng-test.o libutils.la ../pixman/
> libpixman-1.la -lm  -L/usr/local/lib -lpng16  -lm
> libtool: link: cc -xopenmp -O -g -xldscope=hidden -xopenmp -o
> .libs/prng-test prng-test.o  ./.libs/libutils.a
> ../pixman/.libs/libpixman-1.so -L/usr/local/lib /usr/local/lib/libpng16.so
> -lz -lcurses -lm -xopenmp -R/usr/local/lib
> Undefined                       first referenced
>  symbol                             in file
> global_implementation               prng-test.o
> _pixman_choose_implementation       prng-test.o
> ld: fatal: symbol referencing errors. No output written to .libs/prng-test
> gmake[2]: *** [prng-test] Error 2
> gmake[2]: Leaving directory `/var/tmp/pixman-0.30.2/test'
> gmake[1]: *** [all-recursive] Error 1
> gmake[1]: Leaving directory `/var/tmp/pixman-0.30.2'
> gmake: *** [all] Error 2
> 
> 
> because of this library symbol being local, not global:
> 
> host:/var/tmp/pixman-0.30.2/pixman/.libs root# nm -g libpixman-1.so.0.30.2
> | grep global
> host:/var/tmp/pixman-0.30.2/pixman/.libs root# nm libpixman-1.so.0.30.2 |
> grep global
> [59]    |    577936|         4|OBJT |LOCL |2    |25
> |global_implementation

This happens because the code for static always inline function
"get_implementation()" from "pixman-private.h" gets generated in
"prng-test.o" object file (and in some of the other object files for
different test programs). Linking fails because this function
references the "global_implementation" variable. The problem
can be workarounded by converting "get_implementation()" from an
inline function to a macro:


diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 9646605..55dff91 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -764,15 +764,16 @@ _pixman_iter_init_bits_stride (pixman_iter_t *iter, const pixman_iter_info_t *in
 
 extern pixman_implementation_t *global_implementation;
 
-static force_inline pixman_implementation_t *
-get_implementation (void)
-{
-#ifndef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
-    if (!global_implementation)
-	global_implementation = _pixman_choose_implementation ();
+/*
+ * Sun Studio does not always respect static always inline functions:
+ *   http://lists.freedesktop.org/archives/pixman/2013-August/002856.html
+ */
+#ifdef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
+#define get_implementation() (global_implementation)
+#else
+#define get_implementation() (global_implementation ? global_implementation : \
+                    (global_implementation = _pixman_choose_implementation ()))
 #endif
-    return global_implementation;
-}
 
 /* This function is exported for the sake of the test suite and not part
  * of the ABI.


The real patch would also need to change "get_implementation" name to
uppercase in order not to violate the coding style. Or maybe some
cleaner solution/workaround can be found.

The summary of this problem in a few words is "inline functions strike
again". They are intended to be cleaner typesafe replacements for the
ugly C macros, but occasionally cause problems with some compilers or
some compiler versions.

Please try to find a solution which works the best for you and submit
a patch for pixman. Creating a reduced testcase and reporting a bug
to SunStudio developers would be also great.

> Removing hidden symbol flags before running configure results in a clean
> compile.
> 
>     perl -pe 's#-xldscope=hidden##' -i configure
> 
> Is pixman just too zealous with limiting the symbol scope?

Not really. Limiting the number of exported symbols ensures that
the internal implementation details are not exposed and can't be
accidentally used by applications. Also any public symbols must have
'pixman_' prefix in order not to pollute the name space and avoid
symbol name clashes with other libraries and applications.

-- 
Best regards,
Siarhei Siamashka


More information about the Pixman mailing list