| From 94d71c49eb1682a73465eb162b0a059561168bb2 Mon Sep 17 00:00:00 2001 |
| From: Marcin Niestroj <m.niestroj@grinn-global.com> |
| Date: Fri, 20 Jul 2018 14:26:44 +0200 |
| Subject: [PATCH] configure: Introduce --enable-symvers option |
| |
| Only few libc (e.g. glibc) libraries support full symbol version |
| resolution in runtime. There are lot of standard libraries that do not |
| support that, such as dietlibc, musl and uclibc. Hence there is no |
| reason to generate symbol versions when compiling against them. |
| |
| Additionally libdevmapper.so was broken when compiled against |
| uclibc. Runtime linker loader caused calling dm_task_get_info_base() |
| function recursively, leading to segmentation fault. |
| |
| Introduce --enable-symvers[=STYLE] option, which allows to choose |
| between gnu and disabled symbol versioning. By default gnu symbol |
| versioning is used to provide backward compatibility. |
| __GNUC__ check is replaced now with GNU_SYMVER, which is generated by |
| configure script. Additionally ld version script is included only in |
| case of gnu option, which slightly reduces output size. |
| |
| Providing --disable-symvers to configure script when building against |
| uclibc library fixes segmentation fault error described above, due to |
| lack of several versions of the same symbol in libdevmapper.so |
| library. |
| |
| Signed-off-by: Marcin Niestroj <m.niestroj@grinn-global.com> |
| --- |
| configure | 32 ++++++++++++++++++++++++++++++-- |
| configure.ac | 28 +++++++++++++++++++++++++--- |
| include/configure.h.in | 3 +++ |
| lib/misc/lib.h | 10 +++++----- |
| libdm/datastruct/bitset.c | 5 +---- |
| libdm/ioctl/libdm-iface.c | 2 +- |
| libdm/libdm-deptree.c | 2 +- |
| libdm/libdm-stats.c | 2 +- |
| 8 files changed, 67 insertions(+), 17 deletions(-) |
| |
| diff --git a/configure b/configure |
| index 7d945dfa8..94cd6b1ea 100755 |
| --- a/configure |
| +++ b/configure |
| @@ -975,6 +975,7 @@ enable_fsadm |
| enable_blkdeactivate |
| enable_dmeventd |
| enable_selinux |
| +enable_symvers |
| enable_nls |
| with_localedir |
| with_confdir |
| @@ -1725,6 +1726,9 @@ Optional Features: |
| --disable-blkdeactivate disable blkdeactivate |
| --enable-dmeventd enable the device-mapper event daemon |
| --disable-selinux disable selinux support |
| + --enable-symvers[=STYLE] |
| + enables symbol versioning of the shared library |
| + [default=gnu] |
| --enable-nls enable Native Language Support |
| |
| Optional Packages: |
| @@ -3156,7 +3160,6 @@ if test -z "$CFLAGS"; then : |
| fi |
| case "$host_os" in |
| linux*) |
| - CLDFLAGS="$CLDFLAGS -Wl,--version-script,.export.sym" |
| # equivalent to -rdynamic |
| ELDFLAGS="-Wl,--export-dynamic" |
| # FIXME Generate list and use --dynamic-list=.dlopen.sym |
| @@ -3178,7 +3181,6 @@ case "$host_os" in |
| ;; |
| darwin*) |
| CFLAGS="$CFLAGS -no-cpp-precomp -fno-common" |
| - CLDFLAGS="$CLDFLAGS" |
| ELDFLAGS= |
| CLDWHOLEARCHIVE="-all_load" |
| CLDNOWHOLEARCHIVE= |
| @@ -14401,6 +14403,32 @@ done |
| LIBS=$lvm_saved_libs |
| fi |
| |
| +################################################################################ |
| +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable symbol versioning" >&5 |
| +$as_echo_n "checking whether to enable symbol versioning... " >&6; } |
| +# Check whether --enable-symvers was given. |
| +if test "${enable_symvers+set}" = set; then : |
| + enableval=$enable_symvers; |
| + case "$enableval" in |
| + gnu|no) ;; |
| + *) as_fn_error $? "Unknown argument to enable/disable symvers" "$LINENO" 5 ;; |
| + esac |
| +else |
| + enable_symvers=gnu |
| +fi |
| + |
| +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_symvers" >&5 |
| +$as_echo "$enable_symvers" >&6; } |
| + |
| +if test x$GCC = xyes && test x$enable_symvers = xgnu ; then |
| + |
| +$as_echo "#define GNU_SYMVER 1" >>confdefs.h |
| + |
| + case "$host_os" in |
| + linux*) CLDFLAGS="$CLDFLAGS -Wl,--version-script,.export.sym" ;; |
| + esac |
| +fi |
| + |
| ################################################################################ |
| { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable internationalisation" >&5 |
| $as_echo_n "checking whether to enable internationalisation... " >&6; } |
| diff --git a/configure.ac b/configure.ac |
| index e427708cd..2e8712f92 100644 |
| --- a/configure.ac |
| +++ b/configure.ac |
| @@ -30,13 +30,11 @@ AC_CANONICAL_TARGET([]) |
| AS_IF([test -z "$CFLAGS"], [COPTIMISE_FLAG="-O2"]) |
| case "$host_os" in |
| linux*) |
| - CLDFLAGS="$CLDFLAGS -Wl,--version-script,.export.sym" |
| # equivalent to -rdynamic |
| ELDFLAGS="-Wl,--export-dynamic" |
| # FIXME Generate list and use --dynamic-list=.dlopen.sym |
| CLDWHOLEARCHIVE="-Wl,-whole-archive" |
| CLDNOWHOLEARCHIVE="-Wl,-no-whole-archive" |
| - LDDEPS="$LDDEPS .export.sym" |
| LIB_SUFFIX=so |
| DEVMAPPER=yes |
| BUILD_LVMETAD=no |
| @@ -52,7 +50,6 @@ case "$host_os" in |
| ;; |
| darwin*) |
| CFLAGS="$CFLAGS -no-cpp-precomp -fno-common" |
| - CLDFLAGS="$CLDFLAGS" |
| ELDFLAGS= |
| CLDWHOLEARCHIVE="-all_load" |
| CLDNOWHOLEARCHIVE= |
| @@ -1656,6 +1653,31 @@ package as well (which may be called readline-devel or something similar).]) |
| LIBS=$lvm_saved_libs |
| fi |
| |
| +################################################################################ |
| +dnl -- Symbol versioning |
| +AC_MSG_CHECKING(whether to enable symbol versioning) |
| +AC_ARG_ENABLE(symvers, |
| + AC_HELP_STRING([--enable-symvers[[[=STYLE]]]], |
| + [enables symbol versioning of the shared library [default=gnu]]), |
| + [ |
| + case "$enableval" in |
| + gnu|no) ;; |
| + *) AC_MSG_ERROR(Unknown argument to enable/disable symvers) ;; |
| + esac], |
| + enable_symvers=gnu) |
| +AC_MSG_RESULT($enable_symvers) |
| + |
| +if test x$GCC = xyes && test x$enable_symvers = xgnu ; then |
| + AC_DEFINE(GNU_SYMVER, 1, |
| + [Define to use GNU versioning in the shared library.]) |
| + case "$host_os" in |
| + linux*) |
| + CLDFLAGS="$CLDFLAGS -Wl,--version-script,.export.sym" |
| + LDDEPS="$LDDEPS .export.sym" |
| + ;; |
| + esac |
| +fi |
| + |
| ################################################################################ |
| dnl -- Internationalisation stuff |
| AC_MSG_CHECKING(whether to enable internationalisation) |
| diff --git a/include/configure.h.in b/include/configure.h.in |
| index 15fd150ed..7a07a10ef 100644 |
| --- a/include/configure.h.in |
| +++ b/include/configure.h.in |
| @@ -147,6 +147,9 @@ |
| /* Path to fsadm binary. */ |
| #undef FSADM_PATH |
| |
| +/* Define to use GNU versioning in the shared library. */ |
| +#undef GNU_SYMVER |
| + |
| /* Define to 1 if you have the `alarm' function. */ |
| #undef HAVE_ALARM |
| |
| diff --git a/lib/misc/lib.h b/lib/misc/lib.h |
| index d7fa5c721..7cf98f932 100644 |
| --- a/lib/misc/lib.h |
| +++ b/lib/misc/lib.h |
| @@ -41,16 +41,16 @@ |
| * macro DM_EXPORT_SYMBOL to export the function and bind it to the |
| * specified version string. |
| * |
| - * Since versioning is only available when compiling with GCC the entire |
| - * compatibility version should be enclosed in '#if defined(__GNUC__)', |
| - * for example: |
| + * Since versioning is only available when compiling with GCC |
| + * and GLIBC the entire compatibility version should be enclosed |
| + * in '#if defined(GNU_SYMVER)', for example: |
| * |
| * int dm_foo(int bar) |
| * { |
| * return bar; |
| * } |
| * |
| - * #if defined(__GNUC__) |
| + * #if defined(GNU_SYMVER) |
| * // Backward compatible dm_foo() version 1.02.104 |
| * int dm_foo_v1_02_104(void); |
| * int dm_foo_v1_02_104(void) |
| @@ -67,7 +67,7 @@ |
| * versions of library symbols prior to the introduction of symbol |
| * versioning: it must never be used for new symbols. |
| */ |
| -#if defined(__GNUC__) |
| +#if defined(GNU_SYMVER) |
| #define DM_EXPORT_SYMBOL(func, ver) \ |
| __asm__(".symver " #func "_v" #ver ", " #func "@DM_" #ver ) |
| #define DM_EXPORT_SYMBOL_BASE(func) \ |
| diff --git a/libdm/datastruct/bitset.c b/libdm/datastruct/bitset.c |
| index b0826e1eb..2ec3f8f84 100644 |
| --- a/libdm/datastruct/bitset.c |
| +++ b/libdm/datastruct/bitset.c |
| @@ -242,7 +242,7 @@ bad: |
| return NULL; |
| } |
| |
| -#if defined(__GNUC__) |
| +#if defined(GNU_SYMVER) |
| /* |
| * Maintain backward compatibility with older versions that did not |
| * accept a 'min_num_bits' argument to dm_bitset_parse_list(). |
| @@ -253,7 +253,4 @@ dm_bitset_t dm_bitset_parse_list_v1_02_129(const char *str, struct dm_pool *mem) |
| return dm_bitset_parse_list(str, mem, 0); |
| } |
| DM_EXPORT_SYMBOL(dm_bitset_parse_list, 1_02_129); |
| - |
| -#else /* if defined(__GNUC__) */ |
| - |
| #endif |
| diff --git a/libdm/ioctl/libdm-iface.c b/libdm/ioctl/libdm-iface.c |
| index 769b69c1b..28e2eadee 100644 |
| --- a/libdm/ioctl/libdm-iface.c |
| +++ b/libdm/ioctl/libdm-iface.c |
| @@ -2145,7 +2145,7 @@ void dm_lib_exit(void) |
| _version_checked = 0; |
| } |
| |
| -#if defined(__GNUC__) |
| +#if defined(GNU_SYMVER) |
| /* |
| * Maintain binary backward compatibility. |
| * Version script mechanism works with 'gcc' compatible compilers only. |
| diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c |
| index ab0545659..00651c0b2 100644 |
| --- a/libdm/libdm-deptree.c |
| +++ b/libdm/libdm-deptree.c |
| @@ -3797,7 +3797,7 @@ void dm_tree_node_set_callback(struct dm_tree_node *dnode, |
| dnode->callback_data = data; |
| } |
| |
| -#if defined(__GNUC__) |
| +#if defined(GNU_SYMVER) |
| /* |
| * Backward compatible implementations. |
| * |
| diff --git a/libdm/libdm-stats.c b/libdm/libdm-stats.c |
| index 94ad380e0..76efbbe35 100644 |
| --- a/libdm/libdm-stats.c |
| +++ b/libdm/libdm-stats.c |
| @@ -5065,7 +5065,7 @@ int dm_stats_start_filemapd(int fd, uint64_t group_id, const char *path, |
| * current dm_stats_create_region() version. |
| */ |
| |
| -#if defined(__GNUC__) |
| +#if defined(GNU_SYMVER) |
| int dm_stats_create_region_v1_02_106(struct dm_stats *dms, uint64_t *region_id, |
| uint64_t start, uint64_t len, int64_t step, |
| int precise, const char *program_id, |
| -- |
| 2.18.0 |
| |