Skip to content

Commit 089480c

Browse files
committed
Default to hidden visibility for extension libraries where possible
Until now postgres built extension libraries with global visibility, i.e. exporting all symbols. On the one platform where that behavior is not natively available, namely windows, we emulate it by analyzing the input files to the shared library and exporting all the symbols therein. Not exporting all symbols is actually desirable, as it can improve loading speed, reduces the likelihood of symbol conflicts and can improve intra extension library function call performance. It also makes the non-windows builds more similar to windows builds. Additionally, with meson implementing the export-all-symbols behavior for windows, turns out to be more verbose than desirable. This patch adds support for hiding symbols by default and, to counteract that, explicit symbol visibility annotation for compilers that support __attribute__((visibility("default"))) and -fvisibility=hidden. That is expected to be most, if not all, compilers except msvc (for which we already support explicit symbol export annotations). Now that extension library symbols are explicitly exported, we don't need to export all symbols on windows anymore, hence remove that behavior from src/tools/msvc. The supporting code can't be removed, as we still need to export all symbols from the main postgres binary. Author: Andres Freund <andres@anarazel.de> Author: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/20211101020311.av6hphdl6xbjbuif@alap3.anarazel.de
1 parent fd4bad1 commit 089480c

File tree

9 files changed

+198
-12
lines changed

9 files changed

+198
-12
lines changed

configure

100755100644
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,8 @@ CPP
741741
CFLAGS_SL
742742
BITCODE_CXXFLAGS
743743
BITCODE_CFLAGS
744+
CXXFLAGS_SL_MODULE
745+
CFLAGS_SL_MODULE
744746
CFLAGS_VECTORIZE
745747
CFLAGS_UNROLL_LOOPS
746748
PERMIT_DECLARATION_AFTER_STATEMENT
@@ -6302,6 +6304,154 @@ if test x"$pgac_cv_prog_CC_cflags__ftree_vectorize" = x"yes"; then
63026304
fi
63036305

63046306

6307+
#
6308+
# If the compiler knows how to hide symbols add the switch needed for that
6309+
# to CFLAGS_SL_MODULE and define HAVE_VISIBILITY_ATTRIBUTE.
6310+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -fvisibility=hidden, for CFLAGS_SL_MODULE" >&5
6311+
$as_echo_n "checking whether ${CC} supports -fvisibility=hidden, for CFLAGS_SL_MODULE... " >&6; }
6312+
if ${pgac_cv_prog_CC_cflags__fvisibility_hidden+:} false; then :
6313+
$as_echo_n "(cached) " >&6
6314+
else
6315+
pgac_save_CFLAGS=$CFLAGS
6316+
pgac_save_CC=$CC
6317+
CC=${CC}
6318+
CFLAGS="${CFLAGS_SL_MODULE} -fvisibility=hidden"
6319+
ac_save_c_werror_flag=$ac_c_werror_flag
6320+
ac_c_werror_flag=yes
6321+
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
6322+
/* end confdefs.h. */
6323+
6324+
int
6325+
main ()
6326+
{
6327+
6328+
;
6329+
return 0;
6330+
}
6331+
_ACEOF
6332+
if ac_fn_c_try_compile "$LINENO"; then :
6333+
pgac_cv_prog_CC_cflags__fvisibility_hidden=yes
6334+
else
6335+
pgac_cv_prog_CC_cflags__fvisibility_hidden=no
6336+
fi
6337+
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
6338+
ac_c_werror_flag=$ac_save_c_werror_flag
6339+
CFLAGS="$pgac_save_CFLAGS"
6340+
CC="$pgac_save_CC"
6341+
fi
6342+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CC_cflags__fvisibility_hidden" >&5
6343+
$as_echo "$pgac_cv_prog_CC_cflags__fvisibility_hidden" >&6; }
6344+
if test x"$pgac_cv_prog_CC_cflags__fvisibility_hidden" = x"yes"; then
6345+
CFLAGS_SL_MODULE="${CFLAGS_SL_MODULE} -fvisibility=hidden"
6346+
fi
6347+
6348+
6349+
if test "$pgac_cv_prog_CC_cflags__fvisibility_hidden" = yes; then
6350+
6351+
$as_echo "#define HAVE_VISIBILITY_ATTRIBUTE 1" >>confdefs.h
6352+
6353+
fi
6354+
# For C++ we additionally want -fvisibility-inlines-hidden
6355+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX} supports -fvisibility=hidden, for CXXFLAGS_SL_MODULE" >&5
6356+
$as_echo_n "checking whether ${CXX} supports -fvisibility=hidden, for CXXFLAGS_SL_MODULE... " >&6; }
6357+
if ${pgac_cv_prog_CXX_cxxflags__fvisibility_hidden+:} false; then :
6358+
$as_echo_n "(cached) " >&6
6359+
else
6360+
pgac_save_CXXFLAGS=$CXXFLAGS
6361+
pgac_save_CXX=$CXX
6362+
CXX=${CXX}
6363+
CXXFLAGS="${CXXFLAGS_SL_MODULE} -fvisibility=hidden"
6364+
ac_save_cxx_werror_flag=$ac_cxx_werror_flag
6365+
ac_cxx_werror_flag=yes
6366+
ac_ext=cpp
6367+
ac_cpp='$CXXCPP $CPPFLAGS'
6368+
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
6369+
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
6370+
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
6371+
6372+
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
6373+
/* end confdefs.h. */
6374+
6375+
int
6376+
main ()
6377+
{
6378+
6379+
;
6380+
return 0;
6381+
}
6382+
_ACEOF
6383+
if ac_fn_cxx_try_compile "$LINENO"; then :
6384+
pgac_cv_prog_CXX_cxxflags__fvisibility_hidden=yes
6385+
else
6386+
pgac_cv_prog_CXX_cxxflags__fvisibility_hidden=no
6387+
fi
6388+
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
6389+
ac_ext=c
6390+
ac_cpp='$CPP $CPPFLAGS'
6391+
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
6392+
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
6393+
ac_compiler_gnu=$ac_cv_c_compiler_gnu
6394+
6395+
ac_cxx_werror_flag=$ac_save_cxx_werror_flag
6396+
CXXFLAGS="$pgac_save_CXXFLAGS"
6397+
CXX="$pgac_save_CXX"
6398+
fi
6399+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CXX_cxxflags__fvisibility_hidden" >&5
6400+
$as_echo "$pgac_cv_prog_CXX_cxxflags__fvisibility_hidden" >&6; }
6401+
if test x"$pgac_cv_prog_CXX_cxxflags__fvisibility_hidden" = x"yes"; then
6402+
CXXFLAGS_SL_MODULE="${CXXFLAGS_SL_MODULE} -fvisibility=hidden"
6403+
fi
6404+
6405+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX} supports -fvisibility-inlines-hidden, for CXXFLAGS_SL_MODULE" >&5
6406+
$as_echo_n "checking whether ${CXX} supports -fvisibility-inlines-hidden, for CXXFLAGS_SL_MODULE... " >&6; }
6407+
if ${pgac_cv_prog_CXX_cxxflags__fvisibility_inlines_hidden+:} false; then :
6408+
$as_echo_n "(cached) " >&6
6409+
else
6410+
pgac_save_CXXFLAGS=$CXXFLAGS
6411+
pgac_save_CXX=$CXX
6412+
CXX=${CXX}
6413+
CXXFLAGS="${CXXFLAGS_SL_MODULE} -fvisibility-inlines-hidden"
6414+
ac_save_cxx_werror_flag=$ac_cxx_werror_flag
6415+
ac_cxx_werror_flag=yes
6416+
ac_ext=cpp
6417+
ac_cpp='$CXXCPP $CPPFLAGS'
6418+
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
6419+
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
6420+
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
6421+
6422+
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
6423+
/* end confdefs.h. */
6424+
6425+
int
6426+
main ()
6427+
{
6428+
6429+
;
6430+
return 0;
6431+
}
6432+
_ACEOF
6433+
if ac_fn_cxx_try_compile "$LINENO"; then :
6434+
pgac_cv_prog_CXX_cxxflags__fvisibility_inlines_hidden=yes
6435+
else
6436+
pgac_cv_prog_CXX_cxxflags__fvisibility_inlines_hidden=no
6437+
fi
6438+
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
6439+
ac_ext=c
6440+
ac_cpp='$CPP $CPPFLAGS'
6441+
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
6442+
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
6443+
ac_compiler_gnu=$ac_cv_c_compiler_gnu
6444+
6445+
ac_cxx_werror_flag=$ac_save_cxx_werror_flag
6446+
CXXFLAGS="$pgac_save_CXXFLAGS"
6447+
CXX="$pgac_save_CXX"
6448+
fi
6449+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CXX_cxxflags__fvisibility_inlines_hidden" >&5
6450+
$as_echo "$pgac_cv_prog_CXX_cxxflags__fvisibility_inlines_hidden" >&6; }
6451+
if test x"$pgac_cv_prog_CXX_cxxflags__fvisibility_inlines_hidden" = x"yes"; then
6452+
CXXFLAGS_SL_MODULE="${CXXFLAGS_SL_MODULE} -fvisibility-inlines-hidden"
6453+
fi
6454+
63056455
#
63066456
# The following tests want to suppress various unhelpful warnings by adding
63076457
# -Wno-foo switches. But gcc won't complain about unrecognized -Wno-foo
@@ -6860,6 +7010,8 @@ fi
68607010

68617011

68627012

7013+
7014+
68637015
# Determine flags used to emit bitcode for JIT inlining.
68647016
# 1. We must duplicate any behaviour-changing compiler flags used above,
68657017
# to keep compatibility with the compiler used for normal Postgres code.

configure.ac

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,17 @@ if test "$GCC" = yes -a "$ICC" = no; then
525525
# Optimization flags for specific files that benefit from vectorization
526526
PGAC_PROG_CC_VAR_OPT(CFLAGS_VECTORIZE, [-ftree-vectorize])
527527
#
528+
# If the compiler knows how to hide symbols add the switch needed for that
529+
# to CFLAGS_SL_MODULE and define HAVE_VISIBILITY_ATTRIBUTE.
530+
PGAC_PROG_CC_VAR_OPT(CFLAGS_SL_MODULE, [-fvisibility=hidden])
531+
if test "$pgac_cv_prog_CC_cflags__fvisibility_hidden" = yes; then
532+
AC_DEFINE([HAVE_VISIBILITY_ATTRIBUTE], 1,
533+
[Define to 1 if your compiler knows the visibility("hidden") attribute.])
534+
fi
535+
# For C++ we additionally want -fvisibility-inlines-hidden
536+
PGAC_PROG_VARCXX_VARFLAGS_OPT(CXX, CXXFLAGS_SL_MODULE, [-fvisibility=hidden])
537+
PGAC_PROG_VARCXX_VARFLAGS_OPT(CXX, CXXFLAGS_SL_MODULE, [-fvisibility-inlines-hidden])
538+
#
528539
# The following tests want to suppress various unhelpful warnings by adding
529540
# -Wno-foo switches. But gcc won't complain about unrecognized -Wno-foo
530541
# switches, so we have to test for the positive form and if that works,
@@ -573,6 +584,8 @@ fi
573584

574585
AC_SUBST(CFLAGS_UNROLL_LOOPS)
575586
AC_SUBST(CFLAGS_VECTORIZE)
587+
AC_SUBST(CFLAGS_SL_MODULE)
588+
AC_SUBST(CXXFLAGS_SL_MODULE)
576589

577590
# Determine flags used to emit bitcode for JIT inlining.
578591
# 1. We must duplicate any behaviour-changing compiler flags used above,

src/Makefile.global.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,9 @@ SUN_STUDIO_CC = @SUN_STUDIO_CC@
258258
CXX = @CXX@
259259
CFLAGS = @CFLAGS@
260260
CFLAGS_SL = @CFLAGS_SL@
261+
# *_MODULE are for flags applied to extension libraries
262+
CFLAGS_SL_MODULE = @CFLAGS_SL_MODULE@
263+
CXXFLAGS_SL_MODULE = @CXXFLAGS_SL_MODULE@
261264
CFLAGS_UNROLL_LOOPS = @CFLAGS_UNROLL_LOOPS@
262265
CFLAGS_VECTORIZE = @CFLAGS_VECTORIZE@
263266
CFLAGS_SSE42 = @CFLAGS_SSE42@

src/Makefile.shlib

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,19 @@ ifeq ($(PORTNAME), win32)
218218
endif
219219

220220

221+
# If the shared library doesn't have an export file, mark all symbols not
222+
# explicitly exported using PGDLLEXPORT as hidden. We can't pass these flags
223+
# when building a library with explicit exports, as the symbols would be
224+
# hidden before the linker script / exported symbol list takes effect.
225+
#
226+
# This is duplicated in pgxs.mk for MODULES style libraries.
227+
ifeq ($(SHLIB_EXPORTS),)
228+
# LDFLAGS_SL addition not strictly needed, CFLAGS used everywhere, but ...
229+
override LDFLAGS_SL += $(CFLAGS_SL_MODULE)
230+
override CFLAGS += $(CFLAGS_SL_MODULE)
231+
override CXXFLAGS += $(CXXFLAGS_SL_MODULE)
232+
endif
233+
221234

222235
##
223236
## BUILD

src/include/c.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,14 +1347,19 @@ extern unsigned long long strtoull(const char *str, char **endptr, int base);
13471347

13481348
/*
13491349
* Use "extern PGDLLEXPORT ..." to declare functions that are defined in
1350-
* loadable modules and need to be callable by the core backend. (Usually,
1351-
* this is not necessary because our build process automatically exports
1352-
* such symbols, but sometimes manual marking is required.)
1353-
* No special marking is required on most ports.
1350+
* loadable modules and need to be callable by the core backend or other
1351+
* loadable modules.
1352+
* If the compiler knows __attribute__((visibility("*"))), we use that,
1353+
* unless we already have a platform-specific definition. Otherwise,
1354+
* no special marking is required.
13541355
*/
13551356
#ifndef PGDLLEXPORT
1357+
#ifdef HAVE_VISIBILITY_ATTRIBUTE
1358+
#define PGDLLEXPORT __attribute__((visibility("default")))
1359+
#else
13561360
#define PGDLLEXPORT
13571361
#endif
1362+
#endif
13581363

13591364
/*
13601365
* The following is used as the arg list for signal handlers. Any ports

src/include/pg_config.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,9 @@
700700
/* Define to 1 if you have the <uuid/uuid.h> header file. */
701701
#undef HAVE_UUID_UUID_H
702702

703+
/* Define to 1 if your compiler knows the visibility("hidden") attribute. */
704+
#undef HAVE_VISIBILITY_ATTRIBUTE
705+
703706
/* Define to 1 if you have the `wcstombs_l' function. */
704707
#undef HAVE_WCSTOMBS_L
705708

src/makefiles/pgxs.mk

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,11 @@ endif # PGXS
101101

102102
override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS)
103103

104+
# See equivalent block in Makefile.shlib
104105
ifdef MODULES
105-
override CFLAGS += $(CFLAGS_SL)
106+
override LDFLAGS_SL += $(CFLAGS_SL_MODULE)
107+
override CFLAGS += $(CFLAGS_SL) $(CFLAGS_SL_MODULE)
108+
override CXXFLAGS += $(CFLAGS_SL) $(CXXFLAGS_SL_MODULE)
106109
endif
107110

108111
ifdef MODULEDIR

src/tools/msvc/Project.pm

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -419,13 +419,6 @@ sub Save
419419
{
420420
my ($self) = @_;
421421

422-
# If doing DLL and haven't specified a DEF file, do a full export of all symbols
423-
# in the project.
424-
if ($self->{type} eq "dll" && !$self->{def})
425-
{
426-
$self->FullExportDLL($self->{name} . ".lib");
427-
}
428-
429422
# Warning 4197 is about double exporting, disable this per
430423
# http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=99193
431424
$self->DisableLinkerWarnings('4197') if ($self->{platform} eq 'x64');

src/tools/msvc/Solution.pm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ sub GenerateFiles
429429
HAVE_WINLDAP_H => undef,
430430
HAVE_WCSTOMBS_L => 1,
431431
HAVE_WCTYPE_H => 1,
432+
HAVE_VISIBILITY_ATTRIBUTE => undef,
432433
HAVE_WRITEV => undef,
433434
HAVE_X509_GET_SIGNATURE_NID => 1,
434435
HAVE_X86_64_POPCNTQ => undef,

0 commit comments

Comments
 (0)