Limiting Exported Symbols on GCC

28 views
Skip to first unread message

Ron Blaschke

unread,
Apr 12, 2007, 7:37:24 AM4/12/07
to perl6-i...@perl.org
While poking the GCC documentation I found that there's a feature
available to limit the exported symbols (with GCC >= 3.3). Maybe worth
considering?
It's probably a design decision. If there's an option to limit the
exported symbols or make all available, which one should be taken?

http://gcc.gnu.org/wiki/Visibility
http://gcc.gnu.org/onlinedocs/gcc-3.3.6/gcc/Function-Attributes.html#Function-Attributes

This can be done by adding C<-fvisibility=hidden> to CFLAGS and setting
PARROT_API to C<__attribute__ ((visibility("default")))>.


If you're trying this, prepare to kill io_4 quickly while t/src/io.t is
running, as it would print "16777215:" for a very, very long time
(there's already a ticket for this). The following is r18140 on Ubuntu,
using GCC 4.1.2.

>prove t/src/io.t
...
t/src/io....ok 15/20# 'cc -L/usr/local/lib -Wl,-E t/src/io_16.o
src/parrot_config.o -o t/src/io_16 -Wl,-rpath=/home/rb
lasch/src/parrot/trunk/blib/lib -Lblib/lib -lparrot -lpthread -lm
-L/usr/lib -licuuc -licudata -lpthread -lm -ldl -lm -
lpthread -lcrypt -lrt -lgmp -lreadline -lncurses' failed with exit code 1
# Failed to build 't/src/io_16': t/src/io_16.o: In function `the_test':
# t/src/io_16.c:31: undefined reference to `PIO_make_offset'
# collect2: ld returned 1 exit status

# Failed test (t/src/io.t at line 506)
t/src/io....NOK 16# 'cc -L/usr/local/lib -Wl,-E t/src/io_17.o
src/parrot_config.o -o t/src/io_17 -Wl,-rpath=/home/rbla
sch/src/parrot/trunk/blib/lib -Lblib/lib -lparrot -lpthread -lm
-L/usr/lib -licuuc -licudata -lpthread -lm -ldl -lm -lp
thread -lcrypt -lrt -lgmp -lreadline -lncurses' failed with exit code 1
# Failed to build 't/src/io_17': t/src/io_17.o: In function `the_test':
# t/src/io_17.c:46: undefined reference to `PIO_make_offset'
# collect2: ld returned 1 exit status

# Failed test (t/src/io.t at line 538)
t/src/io....NOK 17# 'cc -L/usr/local/lib -Wl,-E t/src/io_18.o
src/parrot_config.o -o t/src/io_18 -Wl,-rpath=/home/rbla
sch/src/parrot/trunk/blib/lib -Lblib/lib -lparrot -lpthread -lm
-L/usr/lib -licuuc -licudata -lpthread -lm -ldl -lm -lp
thread -lcrypt -lrt -lgmp -lreadline -lncurses' failed with exit code 1
# Failed to build 't/src/io_18': t/src/io_18.o: In function `the_test':
# t/src/io_18.c:33: undefined reference to `PIO_STDOUT'
# collect2: ld returned 1 exit status

# Failed test (t/src/io.t at line 593)
t/src/io....NOK 18# 'cc -L/usr/local/lib -Wl,-E t/src/io_19.o
src/parrot_config.o -o t/src/io_19 -Wl,-rpath=/home/rbla
sch/src/parrot/trunk/blib/lib -Lblib/lib -lparrot -lpthread -lm
-L/usr/lib -licuuc -licudata -lpthread -lm -ldl -lm -lp
thread -lcrypt -lrt -lgmp -lreadline -lncurses' failed with exit code 1
# Failed to build 't/src/io_19': t/src/io_19.o: In function `the_test':
# t/src/io_19.c:29: undefined reference to `pio_stdio_layer'
# collect2: ld returned 1 exit status

# Failed test (t/src/io.t at line 628)
t/src/io....ok 20/20# Looks like you failed 9 tests of 20.
t/src/io....dubious
Test returned status 9 (wstat 2304, 0x900)
DIED. FAILED tests 2-4, 6-7, 16-19
Failed 9/20 tests, 55.00% okay
Failed Test Stat Wstat Total Fail Failed List of Failed
-------------------------------------------------------------------------------
t/src/io.t 9 2304 20 9 45.00% 2-4 6-7 16-19
Failed 1/1 test scripts, 0.00% okay. 9/20 subtests failed, 55.00% okay.


Ron

Steve Peters

unread,
Apr 12, 2007, 10:13:14 AM4/12/07
to r...@rblasch.org, perl6-i...@perl.org
On Thu, Apr 12, 2007 at 01:37:24PM +0200, Ron Blaschke wrote:
> While poking the GCC documentation I found that there's a feature
> available to limit the exported symbols (with GCC >= 3.3). Maybe worth
> considering?
> It's probably a design decision. If there's an option to limit the
> exported symbols or make all available, which one should be taken?
>
> http://gcc.gnu.org/wiki/Visibility
> http://gcc.gnu.org/onlinedocs/gcc-3.3.6/gcc/Function-Attributes.html#Function-Attributes
>
> This can be done by adding C<-fvisibility=hidden> to CFLAGS and setting
> PARROT_API to C<__attribute__ ((visibility("default")))>.
>
>

I think that we need to tread very carefully with adding additional
gcc-isms to Parrot, lest we break compatibility with additional compilers
even further. If Parrot will run everywhere, we need to think about
working more towards ANSI and POSIX compliance.

Steve Peters
st...@fisharerojo.org

Nicholas Clark

unread,
Apr 12, 2007, 10:29:54 AM4/12/07
to Steve Peters, r...@rblasch.org, perl6-i...@perl.org

On the other hand, we've managed very well in Perl 5 with the flag data in
embed.fnc and generating the annotated headers programmatically.

I think it would have been nice to have had something like this some years
ago (er, maybe 10) to prevent the magpies from turning any and every function
in the Perl 5 core into part of the supported API.

Particularly given that on some platforms (such as Win32) API functions need
to be exported explicitly, resulting in modules written on *nix platforms
not working on Win32.

(and actually, I'm tempted to add it even now to Perl 5 to enforce what
remains of our sanity)

Nicholas Clark

nah...@gmail.com

unread,
Apr 12, 2007, 10:56:15 AM4/12/07
to perl6-i...@perl.org
On Thu, Apr 12, 2007 at 09:13:14AM -0500, Steve Peters wrote:

I think that the same effect can be achieved using a linker script (although
I don't know much about them), in wich case you are not depending on a
compiler feature.

Nicholas Clark

unread,
Apr 12, 2007, 11:01:13 AM4/12/07
to nah...@gmail.com, perl6-i...@perl.org

I thought the same, but I've never seen clear documentation as to how to do it.

Nicholas Clark

Ron Blaschke

unread,
Apr 12, 2007, 11:29:37 AM4/12/07
to perl6-i...@perl.org

Just to elaborate a bit further on what I did: There's a macro called
PARROT_API (see F<include/parrot/config.h>) which is used to tag all
symbols to be exported. On Win32 it expands to C<__declspec(dllexport)>
to export the symbol (see F<config/init/hints/mswin32.pm>), for others
to nothing. For my test I defined it as C<__attribute__ ((visibility
("default")))>.

Ron

Nicholas Clark

unread,
Apr 12, 2007, 2:54:27 PM4/12/07
to Joshua Isom, Perl 6 Internals
On Thu, Apr 12, 2007 at 01:50:09PM -0500, Joshua Isom wrote:
>
> On Apr 12, 2007, at 9:29 AM, Nicholas Clark wrote:

> My view of this is something along these lines. You can use any
> function you want at all, but if it's not documented as part of the
> supported API, there's nothing saying I won't purposely break your code
> in the next release. In big bold red letters of course.


>
> >Particularly given that on some platforms (such as Win32) API
> >functions need
> >to be exported explicitly, resulting in modules written on *nix
> >platforms
> >not working on Win32.

The problem is that between now and that next release, someone inevitably
writes something on Linux that doesn't work on Win32, and they blame everyone
but themselves.

I'd much prefer to nip the problem in the bud by preventing the code from
ever being shipped.

Nicholas Clark

Joshua Isom

unread,
Apr 12, 2007, 2:50:09 PM4/12/07
to Nicholas Clark, Perl 6 Internals

On Apr 12, 2007, at 9:29 AM, Nicholas Clark wrote:

> On Thu, Apr 12, 2007 at 09:13:14AM -0500, Steve Peters wrote:
>> On Thu, Apr 12, 2007 at 01:37:24PM +0200, Ron Blaschke wrote:
>>
>> I think that we need to tread very carefully with adding additional
>> gcc-isms to Parrot, lest we break compatibility with additional
>> compilers
>> even further. If Parrot will run everywhere, we need to think about
>> working more towards ANSI and POSIX compliance.
>
> On the other hand, we've managed very well in Perl 5 with the flag
> data in
> embed.fnc and generating the annotated headers programmatically.
>
> I think it would have been nice to have had something like this some
> years
> ago (er, maybe 10) to prevent the magpies from turning any and every
> function
> in the Perl 5 core into part of the supported API.
>

My view of this is something along these lines. You can use any

function you want at all, but if it's not documented as part of the
supported API, there's nothing saying I won't purposely break your code
in the next release. In big bold red letters of course.

> Particularly given that on some platforms (such as Win32) API

Jerry Gay

unread,
Apr 12, 2007, 3:05:29 PM4/12/07
to Joshua Isom, Perl 6 Internals
i sit on nicholas's side of the fence. maybe i've been working on
windows too long, but this is the behavior i've come to expect. if a
function is not meant for public consumption, why is it available?
let's learn from the mistakes of previous designers and earlier
technologies.

when designing and implementing parrot's embedding/extending api, it'd
be nice if the linker failed on platforms other than windows. this
patch will accomplish that nicely.
~jerry

Joshua Isom

unread,
Apr 12, 2007, 3:28:11 PM4/12/07
to Nicholas Clark, Perl 6 Internals

I think it's been a while since we had many failure free smokes. Is
there/does someone know of a better "smoking" module to make it easily
to test failures and if it's architecture specific, or operating system
specific, or both. There's a few problems with freebsd on amd64 which
may largely be configuration(freebsd is amd64, not x86_64).
Portability on parrot is more than a problem of exported symbols at the
moment. I think we've become overly accustomed to having test
failures, but some installer scripts won't install if there's a single
failure, which may be something trivial.

Ron Blaschke

unread,
Apr 12, 2007, 3:43:21 PM4/12/07
to perl6-i...@perl.org
Nicholas Clark wrote:

> On the other hand, we've managed very well in Perl 5 with the flag data in
> embed.fnc and generating the annotated headers programmatically.

Interesting. I quite like this.

> Nicholas Clark

Ron

Joshua Hoblitt

unread,
Apr 14, 2007, 6:50:54 PM4/14/07
to nah...@gmail.com, perl6-i...@perl.org

ld scripts have non-portability issues as well.

At my day job, we make heavy use of gcc attributes protected in #ifdef
blocks. E.g.

...
#ifdef __GNUC__
) __attribute__((format(printf, 6, 7)));
#else // __GNUC__
);
#endif // __GNUC__

While this certainly does clutter up the headers we've decided that the
additional features, optimization, & error checking allowed by the use of
attributes are worth it. Machine generating the headers would be better
but we don't have to support non-POSIX like platforms so it hasn't been
worth the effort.

My guess is that the majority of Parrot users are building it with gcc
and just the extra error checking possible from using a rich set of
attributes would benefit all platforms (compile time NULL checking,
etc.). In fact, I'd vote for using the literal gcc attribute syntax
without protective #ifdefs and then mangling and/or removing
unsupported constructs for the target platform.

-J

--

Reply all
Reply to author
Forward
0 new messages