From 11127ad49c01040c2d7ba1320ac964b7cec37cfe Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Tue, 1 Apr 2025 14:44:29 -0400 Subject: [PATCH] Review compiler options for Clang and GCC Signed-off-by: Juan Cruz Viotti --- cmake/FindPCRE2.cmake | 10 ++++ cmake/common/compiler/options.cmake | 72 +++++++++++++++++++-------- cmake/common/targets/executable.cmake | 9 ++-- 3 files changed, 65 insertions(+), 26 deletions(-) diff --git a/cmake/FindPCRE2.cmake b/cmake/FindPCRE2.cmake index a3cf0ae4d..304e17727 100644 --- a/cmake/FindPCRE2.cmake +++ b/cmake/FindPCRE2.cmake @@ -103,6 +103,11 @@ if(NOT PCRE2_FOUND) target_compile_options(sljit PRIVATE -Wno-conditional-uninitialized) endif() + if(SOURCEMETA_COMPILER_GCC) + target_compile_options(sljit PRIVATE -Wno-stringop-overflow) + target_compile_options(sljit PRIVATE -fstrict-flex-arrays=0) + endif() + if(SOURCEMETA_COMPILER_MSVC) target_compile_options(sljit PRIVATE /sdl-) target_compile_options(sljit PRIVATE /wd4701) @@ -140,6 +145,11 @@ if(NOT PCRE2_FOUND) target_compile_options(pcre2 PRIVATE -Wno-type-limits) endif() + if(SOURCEMETA_COMPILER_GCC) + target_compile_options(pcre2 PRIVATE -Wno-stringop-overflow) + target_compile_options(pcre2 PRIVATE -fstrict-flex-arrays=0) + endif() + if(SOURCEMETA_COMPILER_MSVC) target_compile_options(pcre2 PRIVATE /sdl-) target_compile_options(pcre2 PRIVATE /wd4127) diff --git a/cmake/common/compiler/options.cmake b/cmake/common/compiler/options.cmake index 1c14a1678..0180261e4 100644 --- a/cmake/common/compiler/options.cmake +++ b/cmake/common/compiler/options.cmake @@ -7,7 +7,9 @@ function(sourcemeta_add_default_options visibility target) $<$,$>:/W4> $<$,$>:/WL> $<$,$>:/MP> - $<$,$>:/sdl>) + $<$,$>:/sdl> + # See https://learn.microsoft.com/en-us/cpp/build/reference/guard-enable-control-flow-guard + $<$,$>:/guard:cf>) elseif(SOURCEMETA_COMPILER_LLVM OR SOURCEMETA_COMPILER_GCC) target_compile_options("${target}" ${visibility} -Wall @@ -41,17 +43,43 @@ function(sourcemeta_add_default_options visibility target) $<$,$>:-Woverloaded-virtual> $<$,$>:-Winvalid-offsetof> -funroll-loops - -fstrict-aliasing -ftree-vectorize # To improve how much GCC/Clang will vectorize -fno-math-errno + -fno-trapping-math # Assume that signed arithmetic overflow of addition, subtraction and # multiplication wraps around using twos-complement representation # See https://users.cs.utah.edu/~regehr/papers/overflow12.pdf # See https://www.postgresql.org/message-id/1689.1134422394@sss.pgh.pa.us - -fwrapv) + -fwrapv + + # See https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html + -Wformat + -Wformat=2 + -Werror=format-security + -fstack-protector-strong + -fstrict-flex-arrays=3) + + # Control-flow protection: requires hardware and OS support + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + # -fcf-protection uses Intel CET (Control-flow Enforcement Technology) + # Requires OS kernel support, primarily available on Linux + if(SOURCEMETA_OS_LINUX) + target_compile_options("${target}" ${visibility} -fcf-protection=full) + endif() + elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") + # -mbranch-protection uses ARM BTI/PAC, requires Linux kernel 5.8+ + if(SOURCEMETA_OS_LINUX) + target_compile_options("${target}" ${visibility} -mbranch-protection=standard) + endif() + endif() + + # _GLIBCXX_ASSERTIONS is libstdc++ (GNU) specific, not applicable to libc++ (LLVM/macOS) + if(NOT APPLE AND SOURCEMETA_COMPILER_GCC) + target_compile_definitions("${target}" ${visibility} $<$:_GLIBCXX_ASSERTIONS>) + endif() endif() if(SOURCEMETA_COMPILER_LLVM) @@ -80,30 +108,34 @@ function(sourcemeta_add_default_options visibility target) -fvectorize # Enable vectorization of straight-line code for performance -fslp-vectorize) + + # See https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html + target_compile_options("${target}" ${visibility} + $<$:-fno-delete-null-pointer-checks;-ftrivial-auto-var-init=zero> + $<$:-fno-delete-null-pointer-checks;-ftrivial-auto-var-init=zero>) elseif(SOURCEMETA_COMPILER_GCC) target_compile_options("${target}" ${visibility} - -fno-trapping-math # Newer versions of GCC (i.e. 14) seem to print a lot of false-positives here $<$,$>:-Wno-dangling-reference> # GCC seems to print a lot of false-positives here -Wno-free-nonheap-object # Disables runtime type information - $<$,$>:-fno-rtti>) - endif() -endfunction() + $<$,$>:-fno-rtti> -# For studying failed vectorization results -# - On Clang , seems to only take effect on release shared builds -# - On GCC, seems to only take effect on release shared builds -function(sourcemeta_add_vectorization_diagnostics target) - if(SOURCEMETA_COMPILER_LLVM) - # See https://llvm.org/docs/Vectorizers.html#id6 - target_compile_options("${target}" PRIVATE - -Rpass-analysis=loop-vectorize - -Rpass-missed=loop-vectorize) - elseif(SOURCEMETA_COMPILER_GCC) - target_compile_options("${target}" PRIVATE - -fopt-info-vec-missed - -fopt-info-loop-missed) + # See https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html + -Wtrampolines + -Wbidi-chars=any + -fstack-clash-protection) + + # Prevent the compiler from assuming shared library symbols could be + # interposed at runtime, enabling more inlining and devirtualization + if(BUILD_SHARED_LIBS) + target_compile_options("${target}" ${visibility} -fno-semantic-interposition) + endif() + + # See https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html + target_compile_options("${target}" ${visibility} + $<$:-fno-delete-null-pointer-checks -ftrivial-auto-var-init=zero> + $<$:-fno-delete-null-pointer-checks -ftrivial-auto-var-init=zero>) endif() endfunction() diff --git a/cmake/common/targets/executable.cmake b/cmake/common/targets/executable.cmake index 2066d39a1..bb0332c62 100644 --- a/cmake/common/targets/executable.cmake +++ b/cmake/common/targets/executable.cmake @@ -32,12 +32,9 @@ function(sourcemeta_executable) sourcemeta_add_default_options(PRIVATE ${TARGET_NAME}) # See https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html - # Position Independent Executable (PIE) for ASLR support + # PIE linker flags for ASLR support. The compile-time -fPIC is already + # enabled globally via CMAKE_POSITION_INDEPENDENT_CODE in defaults.cmake. if(SOURCEMETA_COMPILER_LLVM OR SOURCEMETA_COMPILER_GCC) - target_compile_options(${TARGET_NAME} PRIVATE - $<$:-fPIE> - $<$:-fPIE> - $<$:-fPIE>) target_link_options(${TARGET_NAME} PRIVATE $<$:-pie> $<$:-pie> @@ -46,8 +43,8 @@ function(sourcemeta_executable) # See https://learn.microsoft.com/en-us/cpp/build/reference/guard-enable-control-flow-guard # See https://learn.microsoft.com/en-us/cpp/build/reference/cetcompat + # The /guard:cf compile flag is in sourcemeta_add_default_options() if(SOURCEMETA_COMPILER_MSVC) - target_compile_options(${TARGET_NAME} PRIVATE /guard:cf) target_link_options(${TARGET_NAME} PRIVATE /guard:cf /CETCOMPAT) endif()