diff mbox series

[4/4] util: Use GCC 10's attribute symver to define compat symbol versions

Message ID 4-v1-f03f70229014+144-fix_lto_jgg@nvidia.com (mailing list archive)
State Not Applicable
Headers show
Series Enable LTO support for rdma-core | expand

Commit Message

Jason Gunthorpe Nov. 16, 2020, 8:16 p.m. UTC
This has no behavior change but allows LTO to be used to build rdma-core.
Also remove the LTO disablement in the spec files since it works now.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 CMakeLists.txt              | 13 +++++++++++++
 buildlib/FindLDSymVer.cmake | 28 +++++++++++++++++++---------
 buildlib/config.h.in        |  2 ++
 redhat/rdma-core.spec       |  7 -------
 suse/rdma-core.spec         |  2 --
 util/symver.h               |  9 +++++++--
 6 files changed, 41 insertions(+), 20 deletions(-)
diff mbox series

Patch

diff --git a/CMakeLists.txt b/CMakeLists.txt
index ab9caff1f68d02..33fd120f23581a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -282,6 +282,16 @@  CHECK_C_SOURCE_COMPILES("
   HAVE_FUNC_ATTRIBUTE_IFUNC
   FAIL_REGEX "warning")
 
+CHECK_C_SOURCE_COMPILES("
+ #include <unistd.h>
+
+ void _sym(void);
+ __attribute__((__symver__(\"sym@TEST_1.1\"))) void _sym(void) {}
+
+ int main(int argc,const char *argv[]) { _sym(); }"
+  HAVE_FUNC_ATTRIBUTE_SYMVER
+  FAIL_REGEX "warning")
+
 # The code does not do the racy fcntl if the various CLOEXEC's are not
 # supported so it really doesn't work right if this isn't available. Thus hard
 # require it.
@@ -700,6 +710,9 @@  endif()
 if (NOT HAVE_FUNC_ATTRIBUTE_IFUNC)
   message(STATUS " Compiler attribute ifunc NOT supported")
 endif()
+if (NOT HAVE_FUNC_ATTRIBUTE_SYMVER)
+  message(STATUS " Compiler attribute symver NOT supported, can not use LTO")
+endif()
 if (NOT HAVE_COHERENT_DMA)
   message(STATUS " Architecture NOT able to do coherent DMA (check util/udma_barrier.h) some providers disabled!")
 endif()
diff --git a/buildlib/FindLDSymVer.cmake b/buildlib/FindLDSymVer.cmake
index 48238f2407f4fd..d4065d92220a6e 100644
--- a/buildlib/FindLDSymVer.cmake
+++ b/buildlib/FindLDSymVer.cmake
@@ -27,15 +27,25 @@  else()
 endif()
 
 # And matching source, this also checks that .symver asm works
-check_c_source_compiles("
-void ibv_get_device_list_1(void);
-void ibv_get_device_list_1(void){}
-asm(\".symver ibv_get_device_list_1, ibv_get_device_list@IBVERBS_1.1\");
-void ibv_get_device_list_0(void);
-void ibv_get_device_list_0(void){}
-asm(\".symver ibv_get_device_list_0, ibv_get_device_list@@IBVERBS_1.0\");
-
-int main(int argc,const char *argv[]){return 0;}" _LDSYMVER_SUCCESS)
+if (HAVE_FUNC_ATTRIBUTE_SYMVER)
+  check_c_source_compiles("
+  void ibv_get_device_list_1(void);
+  __attribute((__symver__(\"ibv_get_device_list@IBVERBS_1.1\")))
+  void ibv_get_device_list_1(void){}
+  void ibv_get_device_list_0(void);
+  __attribute((__symver__(\"ibv_get_device_list@IBVERBS_1.0\")))
+  void ibv_get_device_list_0(void){}
+  int main(int argc,const char *argv[]){return 0;}" _LDSYMVER_SUCCESS)
+else()
+  check_c_source_compiles("
+  void ibv_get_device_list_1(void);
+  void ibv_get_device_list_1(void){}
+  asm(\".symver ibv_get_device_list_1, ibv_get_device_list@IBVERBS_1.1\");
+  void ibv_get_device_list_0(void);
+  void ibv_get_device_list_0(void){}
+  asm(\".symver ibv_get_device_list_0, ibv_get_device_list@@IBVERBS_1.0\");
+  int main(int argc,const char *argv[]){return 0;}" _LDSYMVER_SUCCESS)
+endif()
 
 file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/test.map")
 set(CMAKE_EXE_LINKER_FLAGS "${SAFE_CMAKE_EXE_LINKER_FLAGS}")
diff --git a/buildlib/config.h.in b/buildlib/config.h.in
index e22e136a5878aa..c5b0bf55709d03 100644
--- a/buildlib/config.h.in
+++ b/buildlib/config.h.in
@@ -46,6 +46,8 @@ 
 
 #cmakedefine HAVE_FUNC_ATTRIBUTE_IFUNC 1
 
+#cmakedefine HAVE_FUNC_ATTRIBUTE_SYMVER 1
+
 #cmakedefine HAVE_WORKING_IF_H 1
 
 // Operating mode for symbol versions
diff --git a/redhat/rdma-core.spec b/redhat/rdma-core.spec
index e1ee0801344a45..179f4a61aca9a9 100644
--- a/redhat/rdma-core.spec
+++ b/redhat/rdma-core.spec
@@ -279,13 +279,6 @@  easy, object-oriented access to IB verbs.
 %setup
 
 %build
-# This package uses top level ASM constructs which are incompatible with LTO.
-# Top level ASMs are often used to implement symbol versioning.  gcc-10
-# introduces a new mechanism for symbol versioning which works with LTO.
-# Converting packages to use that mechanism instead of toplevel ASMs is
-# recommended.
-# Disable LTO
-%define _lto_cflags %{nil}
 
 # New RPM defines _rundir, usually as /run
 %if 0%{?_rundir:1}
diff --git a/suse/rdma-core.spec b/suse/rdma-core.spec
index c89ecba6242f1f..229c75bb0118f7 100644
--- a/suse/rdma-core.spec
+++ b/suse/rdma-core.spec
@@ -389,8 +389,6 @@  Pyverbs is a Cython-based Python API over libibverbs, providing an
 easy, object-oriented access to IB verbs.
 
 %prep
-# Make sure LTO is disable as rdma-core fails to compile with LTO enabled
-%define _lto_cflags %{nil}
 %setup -q -n  %{name}-%{version}%{git_ver}
 
 %build
diff --git a/util/symver.h b/util/symver.h
index ae413050650e0f..eb14c57ebdc132 100644
--- a/util/symver.h
+++ b/util/symver.h
@@ -58,11 +58,16 @@ 
   warnings.  See also Documentation/versioning.md
 */
 
+#if HAVE_FUNC_ATTRIBUTE_SYMVER
 #define _MAKE_SYMVER(_local_sym, _public_sym, _ver_str)                        \
-	asm(".symver " #_local_sym "," #_public_sym "@" _ver_str)
+	__attribute__((__symver__(#_public_sym "@" _ver_str)))
+#else
+#define _MAKE_SYMVER(_local_sym, _public_sym, _ver_str)                        \
+	asm(".symver " #_local_sym "," #_public_sym "@" _ver_str);
+#endif
 #define _MAKE_SYMVER_FUNC(_public_sym, _uniq, _ver_str, _ret, ...)             \
 	_ret __##_public_sym##_##_uniq(__VA_ARGS__);                           \
-	_MAKE_SYMVER(__##_public_sym##_##_uniq, _public_sym, _ver_str);        \
+	_MAKE_SYMVER(__##_public_sym##_##_uniq, _public_sym, _ver_str)         \
 	_ret __##_public_sym##_##_uniq(__VA_ARGS__)
 
 #if defined(HAVE_FULL_SYMBOL_VERSIONS) && !defined(_STATIC_LIBRARY_BUILD_)