Fix redhat arm64 (#52244)
authorJan Vorlicek <jan.vorlicek@volny.cz>
Wed, 28 Jul 2021 20:51:25 +0000 (22:51 +0200)
committerGitHub <noreply@github.com>
Wed, 28 Jul 2021 20:51:25 +0000 (22:51 +0200)
* 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/common/templates/jobs/source-build.yml
eng/native/configuretools.cmake
eng/native/functions.cmake
eng/native/init-compiler.sh
eng/pipelines/common/platform-matrix.yml
src/coreclr/pgosupport.cmake
src/coreclr/vm/CMakeLists.txt
src/coreclr/vm/arm/asmhelpers.S
src/coreclr/vm/arm/pinvokestubs.S
src/coreclr/vm/arm/stubs.cpp

index 00aa98e..b7737ff 100644 (file)
@@ -14,7 +14,7 @@ parameters:
   # This is the default platform provided by Arcade, intended for use by a managed-only repo.
   defaultManagedPlatform:
     name: 'Managed'
-    container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-7-3e800f1-20190501005343'
+    container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-7-20210714125435-9b5bbc2'
 
   # Defines the platforms on which to run build jobs. One job is created for each platform, and the
   # object in this array is sent to the job template as 'platform'. If no platforms are specified,
index 37f3b49..136cd67 100644 (file)
@@ -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)
index 1ca230c..0d03cc3 100644 (file)
@@ -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)
index ca408e4..567d18d 100755 (executable)
@@ -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
index defd34b..15fe948 100644 (file)
@@ -38,7 +38,7 @@ jobs:
       targetRid: linux-arm
       platform: Linux_arm
       container:
-        image: ubuntu-16.04-cross-20200413125008-09ec757
+        image: ubuntu-16.04-cross-20210719121212-8a8d3be
         registry: mcr
       jobParameters:
         runtimeFlavor: ${{ parameters.runtimeFlavor }}
@@ -64,7 +64,7 @@ jobs:
       targetRid: linux-arm64
       platform: Linux_arm64
       container:
-        image: ubuntu-16.04-cross-arm64-20201022204150-b2c2436
+        image: ubuntu-16.04-cross-arm64-20210719121212-8a8d3be
         registry: mcr
       jobParameters:
         runtimeFlavor: ${{ parameters.runtimeFlavor }}
@@ -91,7 +91,7 @@ jobs:
       targetRid: linux-musl-x64
       platform: Linux_musl_x64
       container:
-        image: alpine-3.9-WithNode-20200602002639-0fc54a3
+        image: alpine-3.9-WithNode-20210714125437-9b5bbc2
         registry: mcr
       jobParameters:
         runtimeFlavor: ${{ parameters.runtimeFlavor }}
@@ -116,7 +116,7 @@ jobs:
       targetRid: linux-musl-arm
       platform: Linux_musl_arm
       container:
-        image: ubuntu-16.04-cross-arm-alpine-20210409142327-044d5b9
+        image: ubuntu-16.04-cross-arm-alpine-20210719121212-044d5b9
         registry: mcr
       jobParameters:
         runtimeFlavor: ${{ parameters.runtimeFlavor }}
@@ -143,7 +143,7 @@ jobs:
       targetRid: linux-musl-arm64
       platform: Linux_musl_arm64
       container:
-        image: ubuntu-16.04-cross-arm64-alpine-20200413125008-406629a
+        image: ubuntu-16.04-cross-arm64-alpine-20210719121212-b2c2436
         registry: mcr
       jobParameters:
         runtimeFlavor: ${{ parameters.runtimeFlavor }}
@@ -169,7 +169,7 @@ jobs:
       targetRid: linux-x64
       platform: Linux_x64
       container:
-        image: centos-7-20201227183837-5fe0e50
+        image: centos-7-20210714125435-9b5bbc2
         registry: mcr
       jobParameters:
         runtimeFlavor: ${{ parameters.runtimeFlavor }}
@@ -193,7 +193,7 @@ jobs:
       targetRid: linux-x64
       platform: Linux_x64
       container:
-        image: centos-7-source-build-20210408124356-5d87b80
+        image: centos-7-source-build-20210714125450-5d87b80
         registry: mcr
       jobParameters:
         runtimeFlavor: ${{ parameters.runtimeFlavor }}
index 6f07f1c..7c20ca3 100644 (file)
@@ -30,7 +30,10 @@ function(add_pgo TargetName)
         else(CLR_CMAKE_HOST_WIN32)
             if(UPPERCASE_CMAKE_BUILD_TYPE STREQUAL RELEASE OR UPPERCASE_CMAKE_BUILD_TYPE STREQUAL RELWITHDEBINFO)
                 target_compile_options(${TargetName} PRIVATE -flto -fprofile-instr-generate)
-                set_property(TARGET ${TargetName} APPEND_STRING PROPERTY LINK_FLAGS " -flto -fuse-ld=gold -fprofile-instr-generate")
+                set_property(TARGET ${TargetName} APPEND_STRING PROPERTY LINK_FLAGS " -flto -fprofile-instr-generate")
+                if(NOT LD_LLVM)
+                    set_property(TARGET ${TargetName} APPEND_STRING PROPERTY LINK_FLAGS " -fuse-ld=gold")
+                endif()
             endif(UPPERCASE_CMAKE_BUILD_TYPE STREQUAL RELEASE OR UPPERCASE_CMAKE_BUILD_TYPE STREQUAL RELWITHDEBINFO)
         endif(CLR_CMAKE_HOST_WIN32)
     elseif(CLR_CMAKE_PGO_OPTIMIZE)
@@ -61,7 +64,10 @@ function(add_pgo TargetName)
                     if((CMAKE_CXX_COMPILER_ID MATCHES "Clang") AND (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.6))
                         if(HAVE_LTO)
                             target_compile_options(${TargetName} PRIVATE -flto -fprofile-instr-use=${ProfilePath} -Wno-profile-instr-out-of-date -Wno-profile-instr-unprofiled)
-                            set_property(TARGET ${TargetName} APPEND_STRING PROPERTY LINK_FLAGS " -flto -fuse-ld=gold -fprofile-instr-use=${ProfilePath}")
+                            set_property(TARGET ${TargetName} APPEND_STRING PROPERTY LINK_FLAGS " -flto -fprofile-instr-use=${ProfilePath}")
+                            if(NOT LD_LLVM)
+                                set_property(TARGET ${TargetName} APPEND_STRING PROPERTY LINK_FLAGS " -fuse-ld=gold")
+                            endif()
                         else(HAVE_LTO)
                             message(WARNING "LTO is not supported, skipping profile guided optimizations")
                         endif(HAVE_LTO)
index f31e5a3..d0f9652 100644 (file)
@@ -855,7 +855,6 @@ elseif(CLR_CMAKE_TARGET_ARCH_ARM64)
     set(VM_SOURCES_DAC_AND_WKS_ARCH
         ${ARCH_SOURCES_DIR}/stubs.cpp
         exceptionhandling.cpp
-        gcinfodecoder.cpp
     )
 
     set(VM_HEADERS_DAC_AND_WKS_ARCH
@@ -865,6 +864,7 @@ elseif(CLR_CMAKE_TARGET_ARCH_ARM64)
 
     set(VM_SOURCES_WKS_ARCH
         ${ARCH_SOURCES_DIR}/profiler.cpp
+        gcinfodecoder.cpp
     )
 
     if(CLR_CMAKE_HOST_UNIX)
index 3faa8fe..2780f95 100644 (file)
@@ -928,8 +928,9 @@ LOCAL_LABEL(CallCppHelper3):
     .endm
 
     .macro JIT_WRITEBARRIER_DESCRIPTOR name
-        .word \name
-        .word \name\()_End
+1:
+        .word \name-1b
+        .word \name\()_End-1b
         .word __\name\()__g_lowest_address_offset
         .word __\name\()__g_highest_address_offset
         .word __\name\()__g_ephemeral_low_offset
@@ -983,7 +984,9 @@ g_rgWriteBarrierDescriptors:
     LEAF_ENTRY JIT_WriteBarrier_Callable
 
     // Branch to the write barrier
-    ldr     r2, =JIT_WriteBarrier_Loc // or R3? See targetarm.h
+    ldr     r2, =JIT_WriteBarrier_Loc-(1f+4) // or R3? See targetarm.h
+1:
+    add     r2, pc
     ldr     pc, [r2]
 
     LEAF_END JIT_WriteBarrier_Callable
index 8e7c468..cd49280 100644 (file)
@@ -84,7 +84,9 @@
 
         PROLOG_PUSH  "{r4, lr}"
 
-        ldr     r1, =s_gsCookie
+        ldr     r1, =s_gsCookie-(1f+4)
+1:
+        add     r1, pc
         ldr     r1, [r1]
         str     r1, [r0]
         add     r4, r0, SIZEOF__GSCookie
@@ -92,7 +94,9 @@
         // r4 = pFrame
 
         // set first slot to the value of InlinedCallFrame::`vftable' (checked by runtime code)
-        ldr     r1, .L12
+        ldr     r1, =_ZTV16InlinedCallFrame+8-(2f+4)
+2:
+        add     r1, pc
         str     r1, [r4]
 
         mov     r1, 0
 
     NESTED_END JIT_PInvokeBegin, _TEXT
 
-.L12:
-    .word   _ZTV16InlinedCallFrame+8
-
 // ------------------------------------------------------------------
 // IN:
 // InlinedCallFrame (r0) = pointer to the InlinedCallFrame data, including the GS cookie slot (GS cookie right
         str     r2, [r1, #Thread_m_fPreemptiveGCDisabled]
 
         // Check return trap
-        ldr     r2, =g_TrapReturningThreads
+        ldr     r2, =g_TrapReturningThreads-(1f+4)
+1:
+        add     r2, pc
         ldr     r2, [r2]
         cbnz    r2, LOCAL_LABEL(RarePath)
 
index 6e62df2..6b4f71f 100644 (file)
@@ -281,8 +281,8 @@ void StubLinkerCPU::Init(void)
 // value of the global into a register.
 struct WriteBarrierDescriptor
 {
-    BYTE *  m_pFuncStart;                   // Pointer to the start of the barrier function
-    BYTE *  m_pFuncEnd;                     // Pointer to the end of the barrier function
+    DWORD   m_pFuncStart;                   // Offset to the start of the barrier function relative to this struct address
+    DWORD   m_pFuncEnd;                     // Offset to the end of the barrier function relative to this struct address
     DWORD   m_dw_g_lowest_address_offset;   // Offset of the instruction reading g_lowest_address
     DWORD   m_dw_g_highest_address_offset;  // Offset of the instruction reading g_highest_address
     DWORD   m_dw_g_ephemeral_low_offset;    // Offset of the instruction reading g_ephemeral_low
@@ -440,7 +440,7 @@ void UpdateGCWriteBarriers(bool postGrow = false)
     {
         // If the write barrier is being currently used (as in copied over to the patchable site)
         // then read the patch location from the table and use the offset to patch the target asm code
-        PBYTE to = FindWBMapping(pDesc->m_pFuncStart);
+        PBYTE to = FindWBMapping((BYTE *)pDesc + pDesc->m_pFuncStart);
         if(to)
         {
             to = (PBYTE)PCODEToPINSTR((PCODE)GetWriteBarrierCodeLocation(to));