gollvm: add workaround for hard-wired cf-protection=branch

Some newer linux distrubutions are shipping with
-fcf-protection=branch hard-wired on; this causes problems with the
gold linker when it is looking for split-stack prolog sequences. Until
the upstream bug https://sourceware.org/bugzilla/show_bug.cgi?id=25921
is fixed, work around this problem via additional cmake rules to test
if turning off cf-protection will allow split-stack examples to
compile.

Fixes golang/go#38728.

Change-Id: Ie2d41d59d9e6ce8e9c616b73771055780f9c1e09
Reviewed-on: https://go-review.googlesource.com/c/gollvm/+/232742
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: eric fang <eric.fang@arm.com>
diff --git a/cmake/modules/AddGollvm.cmake b/cmake/modules/AddGollvm.cmake
index 80e602e..6b4bb96 100644
--- a/cmake/modules/AddGollvm.cmake
+++ b/cmake/modules/AddGollvm.cmake
@@ -21,6 +21,12 @@
 set(GOLLVM_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}")
 set(GOLLVM_INSTALL_LIBDIR "${CMAKE_INSTALL_PREFIX}/${libsubdir}")
 
+# Check to see whether the build compiler supports -fcf-protection=branch
+set(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
+set(CMAKE_REQUIRED_FLAGS "-fcf-protection=branch")
+check_c_source_compiles("#include<stdio.h>\nint main(){printf(\"hello\");\nreturn 0;}" C_SUPPORTS_CF_PROTECTION_BRANCH)
+set(CMAKE_REQUIRED_FLAGS "${OLD_CMAKE_REQUIRED_FLAGS}")
+
 # We need to check if '-fsplit-stack' is supported with 'USING_SPLIT_STACK'
 # at compile time. So define this macro in GollvmConfig.h if it's supported.
 if(GOLLVM_USE_SPLIT_STACK)
@@ -31,8 +37,25 @@
   # splitting. So here we do this test with ld.gold linker.
   # FIXME: update here once one day there is a linker that supports '-fsplit-stack'
   # on arm64.
-  SET(CMAKE_REQUIRED_FLAGS "-fuse-ld=gold -fsplit-stack")
-  check_c_source_compiles("#include<stdio.h>\nint main(){printf(\"hello\");\nreturn 0;}" C_SUPPORTS_SPLIT_STACK)
+  set(C_SUPPORTS_SPLIT_STACK 0)
+  set(CMAKE_REQUIRED_FLAGS "-fuse-ld=gold -fsplit-stack")
+  check_c_source_compiles("#include<stdio.h>\nint main(){printf(\"hello\");\nreturn 0;}" SPLIT_STACK_FUNCTIONAL)
+  if(NOT SPLIT_STACK_FUNCTIONAL)
+    if(C_SUPPORTS_CF_PROTECTION_BRANCH)
+      # Try again with -fcf-protection=none, since that option
+      # can cause unpleasant interactions with gold (see
+      # https://sourceware.org/bugzilla/show_bug.cgi?id=25921 for details).
+      message(STATUS "trying -fcf-protection=none workaround")
+      SET(CMAKE_REQUIRED_FLAGS "-fuse-ld=gold -fsplit-stack -fcf-protection=none")
+      check_c_source_compiles("#include<stdio.h>\nint main(){printf(\"hello\");\nreturn 0;}" SPLIT_STACK_WORKAROUND)
+      if(SPLIT_STACK_WORKAROUND)
+        message(STATUS "applying -fcf-protection=none workaround")
+        set(C_SUPPORTS_SPLIT_STACK 1)
+      endif()
+    endif()
+  else()
+    set(C_SUPPORTS_SPLIT_STACK 1)
+  endif()
   if(NOT C_SUPPORTS_SPLIT_STACK)
     message(SEND_ERROR "C compiler does not support -fsplit-stack")
   else()