Skip to content

[CMake] Add a linker test for -Bsymbolic-functions to AddLLVM #79539

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 19, 2025

Conversation

brad0
Copy link
Contributor

@brad0 brad0 commented Jan 26, 2024

Add a linker test for -Bsymbolic-functions to AddLLVM and remove
the illumos hardcoded bits for its handling. OpenBSD also has a
local patch for linking with the old BFD linker on mips64 and
sparc64.

@llvmbot llvmbot added cmake Build system in general and CMake in particular clang Clang issues not falling into any other category labels Jan 26, 2024
@llvmbot
Copy link
Member

llvmbot commented Jan 26, 2024

@llvm/pr-subscribers-clang

Author: Brad Smith (brad0)

Changes

Add a linker test for -Bsymbolic-functions to AddLLVM and remove
the illumos hardcoded bits for its handling. OpenBSD also has a
local patch for linking with the old BFD linker on mips64 and
sparc64.


Full diff: https://github.com/llvm/llvm-project/pull/79539.diff

3 Files Affected:

  • (modified) clang/tools/clang-shlib/CMakeLists.txt (+1-1)
  • (modified) llvm/cmake/modules/AddLLVM.cmake (+6-7)
  • (modified) llvm/tools/llvm-shlib/CMakeLists.txt (+1-1)
diff --git a/clang/tools/clang-shlib/CMakeLists.txt b/clang/tools/clang-shlib/CMakeLists.txt
index 298d3a9d18fec8c..6afd3efebe53a0b 100644
--- a/clang/tools/clang-shlib/CMakeLists.txt
+++ b/clang/tools/clang-shlib/CMakeLists.txt
@@ -50,7 +50,7 @@ add_clang_library(clang-cpp
                   ${_DEPS})
 # Optimize function calls for default visibility definitions to avoid PLT and
 # reduce dynamic relocations.
-if (NOT APPLE AND NOT MINGW AND NOT LLVM_LINKER_IS_SOLARISLD_ILLUMOS)
+if (NOT APPLE AND LINKER_SUPPORTS_B_SYMBOLIC_FUNCTIONS)
   target_link_options(clang-cpp PRIVATE LINKER:-Bsymbolic-functions)
 endif()
 if (MINGW OR CYGWIN)
diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake
index 5e9896185528246..a030489b6196023 100644
--- a/llvm/cmake/modules/AddLLVM.cmake
+++ b/llvm/cmake/modules/AddLLVM.cmake
@@ -241,12 +241,6 @@ if (NOT DEFINED LLVM_LINKER_DETECTED AND NOT WIN32)
       set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
       set(LLVM_LINKER_IS_GNULD YES CACHE INTERNAL "")
       message(STATUS "Linker detection: GNU ld")
-    elseif("${stderr}" MATCHES "(illumos)" OR
-           "${stdout}" MATCHES "(illumos)")
-      set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
-      set(LLVM_LINKER_IS_SOLARISLD YES CACHE INTERNAL "")
-      set(LLVM_LINKER_IS_SOLARISLD_ILLUMOS YES CACHE INTERNAL "")
-      message(STATUS "Linker detection: Solaris ld (illumos)")
     elseif("${stderr}" MATCHES "Solaris Link Editors" OR
            "${stdout}" MATCHES "Solaris Link Editors")
       set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
@@ -260,6 +254,7 @@ if (NOT DEFINED LLVM_LINKER_DETECTED AND NOT WIN32)
 endif()
 
 function(add_link_opts target_name)
+  include(LLVMCheckLinkerFlag)
   get_llvm_distribution(${target_name} in_distribution in_distribution_var)
   if(NOT in_distribution)
     # Don't LTO optimize targets that aren't part of any distribution.
@@ -291,7 +286,6 @@ function(add_link_opts target_name)
       elseif(${CMAKE_SYSTEM_NAME} MATCHES "SunOS" AND LLVM_LINKER_IS_SOLARISLD)
         # Support for ld -z discard-unused=sections was only added in
         # Solaris 11.4.  GNU ld ignores it, but warns every time.
-        include(LLVMCheckLinkerFlag)
         llvm_check_linker_flag(CXX "-Wl,-z,discard-unused=sections" LINKER_SUPPORTS_Z_DISCARD_UNUSED)
         if (LINKER_SUPPORTS_Z_DISCARD_UNUSED)
           set_property(TARGET ${target_name} APPEND_STRING PROPERTY
@@ -314,6 +308,11 @@ function(add_link_opts target_name)
     set_property(TARGET ${target_name} APPEND_STRING PROPERTY
                  LINK_FLAGS " -Wl,-brtl")
   endif()
+
+  if (NOT MINGW)
+    llvm_check_linker_flag(CXX "-Wl,-Bsymbolic-functions"
+                           LINKER_SUPPORTS_B_SYMBOLIC_FUNCTIONS)
+  endif()
 endfunction(add_link_opts)
 
 # Set each output directory according to ${CMAKE_CONFIGURATION_TYPES}.
diff --git a/llvm/tools/llvm-shlib/CMakeLists.txt b/llvm/tools/llvm-shlib/CMakeLists.txt
index a47a0ec84c625c6..3e08dd5459a3f1a 100644
--- a/llvm/tools/llvm-shlib/CMakeLists.txt
+++ b/llvm/tools/llvm-shlib/CMakeLists.txt
@@ -49,7 +49,7 @@ if(LLVM_BUILD_LLVM_DYLIB)
       # Solaris ld does not accept global: *; so there is no way to version *all* global symbols
       set(LIB_NAMES -Wl,--version-script,${LLVM_LIBRARY_DIR}/tools/llvm-shlib/simple_version_script.map ${LIB_NAMES})
     endif()
-    if (NOT MINGW AND NOT LLVM_LINKER_IS_SOLARISLD_ILLUMOS)
+    if (LINKER_SUPPORTS_B_SYMBOLIC_FUNCTIONS)
       # Optimize function calls for default visibility definitions to avoid PLT and
       # reduce dynamic relocations.
       # Note: for -fno-pic default, the address of a function may be different from

@brad0 brad0 force-pushed the cmake_symbolic_functions branch from 73eee52 to 024e972 Compare January 28, 2024 09:50
@brad0 brad0 requested review from rorth and MaskRay January 28, 2024 12:02
@MaskRay
Copy link
Member

MaskRay commented Jan 30, 2024

OpenBSD also has a local patch for linking with the old BFD linker on mips64 and sparc64.

What's the issue? GNU ld has had -Bsymbolic-functions since 2007 and for quite a few releases LLVM has been using -Bsymbolic-functions.

@brad0
Copy link
Contributor Author

brad0 commented Feb 19, 2024

What's the issue? GNU ld has had -Bsymbolic-functions since 2007 and for quite a few releases LLVM has been using -Bsymbolic-functions.

This is binutils 2.17. We've had patches for awhile in our tree too specifically for the exceptions not using LLD.

@jeremyd2019
Copy link
Contributor

This would be nice for Cygwin as well. It seems GNU ld just silently ignores -Bsymbolic-functions there, but the lld mingw driver rejects it.

Comment on lines 312 to 356
if (NOT MINGW)
llvm_check_linker_flag(CXX "-Wl,-Bsymbolic-functions"
LINKER_SUPPORTS_B_SYMBOLIC_FUNCTIONS)
endif()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if is unnecessary thanks to this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure about that and left MinGW as is but it looks like it's just using either LLD or the binutils BFD linker depending on which combo compiler / toolchain you go with.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BFD accepts -Bsymbolic-functions but it's a no-op for anything other than ELF. LLD rejects the option as unknown in the MinGW driver. So it would be fine to remove the if (NOT MINGW) wrapping that, and let it use the flag or not depending on whether the linker accepts it.

@brad0 brad0 force-pushed the cmake_symbolic_functions branch 4 times, most recently from e1d2ffe to be6feeb Compare May 14, 2025 03:19
@brad0
Copy link
Contributor Author

brad0 commented May 14, 2025

@rorth Can you please check this on Solaris?

@rorth
Copy link
Collaborator

rorth commented May 14, 2025

@rorth Can you please check this on Solaris?

I've now tested the patch on amd64-pc-solaris2.11 with both the native linker (which doesn't support -Bsymbolic-functions) and GNU ld (which does) as well as sparcv9-sun-solaris2.11 with /bin/ld: no regressions on either, with the exception of the gld case: I get a failure in Flang :: Driver/dynamic-linker.f90 which is unrelated, though: when configured with -DCLANG_DEFAULT_LINKER=gld, the test has

+ /var/llvm/local-amd64-release-stage2-A-flang-openmp-gcc14-gld/tools/clang/stage2-bins/bin/flang -### --target=x86_64-windows-msvc -rpath /path/to/dir -shared -static /vol/llvm/src/llvm-project/local/flang/test/Driver/dynamic-linker.f90
+ /var/llvm/local-amd64-release-stage2-A-flang-openmp-gcc14-gld/tools/clang/stage2-bins/bin/FileCheck --check-prefixes=MSVC-LINKER-OPTIONS --implicit-check-not=MSVC-LINKER-OPTIONS-NOT /vol/llvm/src/llvm-project/local/flang/test/Driver/dynamic-linker.f90
/vol/llvm/src/llvm-project/local/flang/test/Driver/dynamic-linker.f90:24:24: error: MSVC-LINKER-OPTIONS: expected string not found in input
! MSVC-LINKER-OPTIONS: "{{.*}}link{{(.exe)?}}"
                       ^

while flang emits

          7:  "/usr/bin/gld" "-out:a.exe" "-libpath:lib/amd64" "-libpath:atlmfc/lib/amd64" "-libpath:/var/llvm/local-amd64-release-stage2-A-flang-openmp-gcc14-gld/tools/clang/stage2-bins/lib" "/subsystem:console" "-nologo" "-dll" "-implib:a.lib" "-rpath" "/path/to/dir" "/tmp/lit-tmp-s10rro7u/dynamic-linker-074508.o" 

@brad0
Copy link
Contributor Author

brad0 commented May 15, 2025

@rorth Thanks. It was more so the native linker I wasn't sure about.

@brad0 brad0 force-pushed the cmake_symbolic_functions branch from be6feeb to 03859cb Compare May 15, 2025 05:57
@@ -355,6 +349,9 @@ function(add_link_opts target_name)
set_property(TARGET ${target_name} APPEND_STRING PROPERTY
LINK_FLAGS " -Wl,-brtl")
endif()

check_linker_flag(CXX "-Wl,-Bsymbolic-functions"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment what targets may need the -Wl,-Bsymbolic-functions check?

While configure is right, llvm cmake is so complex and so slow that many contributors want to optimize the number of compile/linke checks. I would still hope that we only do this on targets that actually need it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't go this route: it makes feature tests completely unmaintainable. Consider the Solaris case where initially only /bin/ld was supported which didn't accept -Bsymbolic-functions. Only later when GNU ld became an alternative linker that one would support that option. How on earth is one supposed to know that I now have to revise the cmake check to detect this if it were restricted to some platforms?

Copy link
Member

@MaskRay MaskRay May 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I am aware of https://ewontfix.com/13/ ("Incorrect configure checks for availability of functions"), there have been many cmake changes to skip some checks that are guaranteed to succeed, to make cmake run faster (llvm's cmake is really slow; in the unofficial build system bazel, checks are also often hard-coded). I wonder whether there is a condition that can skip the check for systems that always have -Bsymbolic-functions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd argue it's much faster than autotools for other large projects. It would be nice if the configuration phase could be parallelized, at least to some degree, but even with a single thread, it's a matter of seconds.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mati865 This might be true for other, smaller projects, but for LLVM we have to be careful introducing new checks. https://discourse.llvm.org/t/cmake-compiler-flag-checks-are-really-slow-ideas-to-speed-them-up/78882
It could be slower on a slow device like NFS. For this single check_linker_flag it might be fine.

Add a linker test for -Bsymbolic-functions to AddLLVM and remove
the illumos hardcoded bits for its handling. OpenBSD also has a
local patch for linking with the old BFD linker on mips64 and
sparc64.
@brad0 brad0 force-pushed the cmake_symbolic_functions branch from 03859cb to 97c82e6 Compare May 16, 2025 02:38
@brad0
Copy link
Contributor Author

brad0 commented May 16, 2025

Added a comment.

@brad0 brad0 requested review from jeremyd2019, mati865 and MaskRay May 18, 2025 23:51
Copy link
Contributor

@jeremyd2019 jeremyd2019 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@brad0 brad0 merged commit fbb8a0c into llvm:main May 19, 2025
11 checks passed
@brad0 brad0 deleted the cmake_symbolic_functions branch May 19, 2025 01:20
@llvm-ci
Copy link
Collaborator

llvm-ci commented May 19, 2025

LLVM Buildbot has detected a new failure on builder llvm-clang-x86_64-gcc-ubuntu-no-asserts running on doug-worker-6 while building clang,llvm at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/202/builds/1313

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'LLVM :: tools/dsymutil/X86/op-convert-offset.test' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
warning: /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/../Inputs/private/tmp/op-convert-offset/op-convert-offset.o: timestamp mismatch between object file (2025-03-11 17:27:45.671531848) and debug map (2022-07-12 20:49:30.000000000)
warning: /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/../Inputs/private/tmp/op-convert-offset/op-convert-offset.o: timestamp mismatch between object file (2025-03-11 17:27:45.671531848) and debug map (2022-07-12 20:49:30.000000000)
warning: cann't read address attribute value.
note: while processing op-convert-offset1.c

--
Command Output (stderr):
--
/home/buildbot/buildbot-root/gcc-no-asserts/build/bin/dsymutil -oso-prepend-path /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/../Inputs /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/../Inputs/private/tmp/op-convert-offset/op-convert-offset -o /home/buildbot/buildbot-root/gcc-no-asserts/build/test/tools/dsymutil/X86/Output/op-convert-offset.test.tmp.dSYM 2>&1 # RUN: at line 23
+ /home/buildbot/buildbot-root/gcc-no-asserts/build/bin/dsymutil -oso-prepend-path /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/../Inputs /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/../Inputs/private/tmp/op-convert-offset/op-convert-offset -o /home/buildbot/buildbot-root/gcc-no-asserts/build/test/tools/dsymutil/X86/Output/op-convert-offset.test.tmp.dSYM
/home/buildbot/buildbot-root/gcc-no-asserts/build/bin/llvm-dwarfdump /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/../Inputs/private/tmp/op-convert-offset/op-convert-offset.o 2>&1 | /home/buildbot/buildbot-root/gcc-no-asserts/build/bin/FileCheck /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/op-convert-offset.test --check-prefix OBJ # RUN: at line 24
+ /home/buildbot/buildbot-root/gcc-no-asserts/build/bin/llvm-dwarfdump /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/../Inputs/private/tmp/op-convert-offset/op-convert-offset.o
+ /home/buildbot/buildbot-root/gcc-no-asserts/build/bin/FileCheck /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/op-convert-offset.test --check-prefix OBJ
/home/buildbot/buildbot-root/gcc-no-asserts/build/bin/llvm-dwarfdump /home/buildbot/buildbot-root/gcc-no-asserts/build/test/tools/dsymutil/X86/Output/op-convert-offset.test.tmp.dSYM 2>&1 | /home/buildbot/buildbot-root/gcc-no-asserts/build/bin/FileCheck /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/op-convert-offset.test --check-prefix DSYM # RUN: at line 25
+ /home/buildbot/buildbot-root/gcc-no-asserts/build/bin/llvm-dwarfdump /home/buildbot/buildbot-root/gcc-no-asserts/build/test/tools/dsymutil/X86/Output/op-convert-offset.test.tmp.dSYM
+ /home/buildbot/buildbot-root/gcc-no-asserts/build/bin/FileCheck /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/op-convert-offset.test --check-prefix DSYM
/home/buildbot/buildbot-root/gcc-no-asserts/build/bin/dsymutil --linker parallel -oso-prepend-path /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/../Inputs   /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/../Inputs/private/tmp/op-convert-offset/op-convert-offset   -o /home/buildbot/buildbot-root/gcc-no-asserts/build/test/tools/dsymutil/X86/Output/op-convert-offset.test.tmp.dSYM 2>&1 # RUN: at line 27
+ /home/buildbot/buildbot-root/gcc-no-asserts/build/bin/dsymutil --linker parallel -oso-prepend-path /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/../Inputs /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/../Inputs/private/tmp/op-convert-offset/op-convert-offset -o /home/buildbot/buildbot-root/gcc-no-asserts/build/test/tools/dsymutil/X86/Output/op-convert-offset.test.tmp.dSYM
/home/buildbot/buildbot-root/gcc-no-asserts/build/bin/llvm-dwarfdump    /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/../Inputs/private/tmp/op-convert-offset/op-convert-offset.o 2>&1    | /home/buildbot/buildbot-root/gcc-no-asserts/build/bin/FileCheck /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/op-convert-offset.test --check-prefix OBJ # RUN: at line 30
+ /home/buildbot/buildbot-root/gcc-no-asserts/build/bin/FileCheck /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/op-convert-offset.test --check-prefix OBJ
+ /home/buildbot/buildbot-root/gcc-no-asserts/build/bin/llvm-dwarfdump /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/../Inputs/private/tmp/op-convert-offset/op-convert-offset.o
/home/buildbot/buildbot-root/gcc-no-asserts/build/bin/llvm-dwarfdump /home/buildbot/buildbot-root/gcc-no-asserts/build/test/tools/dsymutil/X86/Output/op-convert-offset.test.tmp.dSYM 2>&1 | /home/buildbot/buildbot-root/gcc-no-asserts/build/bin/FileCheck /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/op-convert-offset.test --check-prefix DSYM # RUN: at line 33
+ /home/buildbot/buildbot-root/gcc-no-asserts/build/bin/llvm-dwarfdump /home/buildbot/buildbot-root/gcc-no-asserts/build/test/tools/dsymutil/X86/Output/op-convert-offset.test.tmp.dSYM
+ /home/buildbot/buildbot-root/gcc-no-asserts/build/bin/FileCheck /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/op-convert-offset.test --check-prefix DSYM
�[1m/home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/op-convert-offset.test:45:7: �[0m�[0;1;31merror: �[0m�[1mDSYM: expected string not found in input
�[0mDSYM: 0x00000084: DW_TAG_base_type
�[0;1;32m      ^
�[0m�[1m<stdin>:1:1: �[0m�[0;1;30mnote: �[0m�[1mscanning from here
�[0m/home/buildbot/buildbot-root/gcc-no-asserts/build/test/tools/dsymutil/X86/Output/op-convert-offset.test.tmp.dSYM/Contents/Resources/DWARF/op-convert-offset: file format Mach-O 64-bit x86-64
�[0;1;32m^
�[0m�[1m<stdin>:16:1: �[0m�[0;1;30mnote: �[0m�[1mpossible intended match here
�[0m0x0000001e: DW_TAG_base_type
�[0;1;32m^
�[0m
Input file: <stdin>
Check file: /home/buildbot/buildbot-root/gcc-no-asserts/llvm-project/llvm/test/tools/dsymutil/X86/op-convert-offset.test

-dump-input=help explains the following input dump.

Input was:
<<<<<<
�[1m�[0m�[0;1;30m            1: �[0m�[1m�[0;1;46m/home/buildbot/buildbot-root/gcc-no-asserts/build/test/tools/dsymutil/X86/Output/op-convert-offset.test.tmp.dSYM/Contents/Resources/DWARF/op-convert-offset: file format Mach-O 64-bit x86-64 �[0m
�[0;1;31mcheck:45'0     X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: no match found
�[0m�[0;1;30m            2: �[0m�[1m�[0;1;46m �[0m
�[0;1;31mcheck:45'0     ~
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang Clang issues not falling into any other category cmake Build system in general and CMake in particular
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants