From 39803d4d3cbf818641437afb7402da15fa076bec Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Wed, 28 Jul 2021 22:51:25 +0200 Subject: Fix redhat arm64 (#52244) * Fix RHEL 8 ARM64 Clang on ARM64 places the .rodata section into the same segment as .text. On RHEL 8 ARM64, the kernel is configured for 64kB memory pages. When we flip the page protection of the page containing the GS cookie to RW and back to RO, we assume that the cookie lives in a non-executable memory. This assumption is broken on RHEL 8 and we end up setting protection of a part of the coreclr code to read only instead of back to RX. This change switches the linker we use to lld from the previously used gnu linker. That linker places .rodata into a different segment than .text by default. Moreover, I was planning to move to using lld anyways to use all build tools from LLVM. * Fix ARM build to use PC relative addresses only The lld linker has revealed that we were using absolute addresses in some asm helpers and so load time relocation was necessary. This change fixes it by replacing all of those by PC relative ones. * Update docker images used for building runtime Use new images that have lld linker * Disable lld linker for s390x --- eng/native/configuretools.cmake | 6 ++++-- eng/native/functions.cmake | 2 +- eng/native/init-compiler.sh | 12 +++++++++++- 3 files changed, 16 insertions(+), 4 deletions(-) (limited to 'eng/native') diff --git a/eng/native/configuretools.cmake b/eng/native/configuretools.cmake index 37f3b4932cd..136cd67925d 100644 --- a/eng/native/configuretools.cmake +++ b/eng/native/configuretools.cmake @@ -65,12 +65,14 @@ endif() if (NOT CLR_CMAKE_HOST_WIN32) # detect linker - set(ldVersion ${CMAKE_C_COMPILER};-Wl,--version) + separate_arguments(ldVersion UNIX_COMMAND "${CMAKE_C_COMPILER} ${CMAKE_SHARED_LINKER_FLAGS} -Wl,--version") execute_process(COMMAND ${ldVersion} ERROR_QUIET OUTPUT_VARIABLE ldVersionOutput) - if("${ldVersionOutput}" MATCHES "GNU ld" OR "${ldVersionOutput}" MATCHES "GNU gold" OR "${ldVersionOutput}" MATCHES "GNU linkers") + if("${ldVersionOutput}" MATCHES "LLD") + set(LD_LLVM 1) + elseif("${ldVersionOutput}" MATCHES "GNU ld" OR "${ldVersionOutput}" MATCHES "GNU gold" OR "${ldVersionOutput}" MATCHES "GNU linkers") set(LD_GNU 1) elseif("${ldVersionOutput}" MATCHES "Solaris Link") set(LD_SOLARIS 1) diff --git a/eng/native/functions.cmake b/eng/native/functions.cmake index 1ca230c3e53..0d03cc3d2d4 100644 --- a/eng/native/functions.cmake +++ b/eng/native/functions.cmake @@ -157,7 +157,7 @@ function(preprocess_files PreprocessedFilesList) endfunction() function(set_exports_linker_option exports_filename) - if(LD_GNU OR LD_SOLARIS) + if(LD_GNU OR LD_SOLARIS OR LD_LLVM) # Add linker exports file option if(LD_SOLARIS) set(EXPORTS_LINKER_OPTION -Wl,-M,${exports_filename} PARENT_SCOPE) diff --git a/eng/native/init-compiler.sh b/eng/native/init-compiler.sh index ca408e4d088..567d18da474 100755 --- a/eng/native/init-compiler.sh +++ b/eng/native/init-compiler.sh @@ -22,6 +22,7 @@ minorVersion="$4" # clear the existing CC and CXX from environment CC= CXX= +LDFLAGS= if [[ "$compiler" == "gcc" ]]; then cxxCompiler="g++"; fi @@ -106,6 +107,15 @@ if [[ -z "$CC" ]]; then exit 1 fi +if [[ "$compiler" == "clang" ]]; then + if command -v "lld$desired_version" > /dev/null; then + # Only lld version >= 9 can be considered stable + if [[ "$majorVersion" -ge 9 ]]; then + LDFLAGS="-fuse-ld=lld" + fi + fi +fi + SCAN_BUILD_COMMAND="$(command -v "scan-build$desired_version")" -export CC CXX SCAN_BUILD_COMMAND +export CC CXX LDFLAGS SCAN_BUILD_COMMAND -- cgit v1.2.3