[Git][ghc/ghc][wip/ubsan] 6 commits: hadrian: add support for building with UndefinedBehaviorSanitizer
Cheng Shao pushed to branch wip/ubsan at Glasgow Haskell Compiler / GHC Commits: 1047a8a2 by Cheng Shao at 2025-11-25T12:43:59+01:00 hadrian: add support for building with UndefinedBehaviorSanitizer This patch adds a +ubsan flavour transformer to hadrian to build all stage1+ C/C++ code with UndefinedBehaviorSanitizer. This is particularly useful to catch potential undefined behavior in the RTS codebase. - - - - - e0c517b2 by Cheng Shao at 2025-11-25T12:44:04+01:00 configure: bump LlvmMaxVersion to 22 This commit bumps LlvmMaxVersion to 22; 21.x releases have been available since Aug 26th, 2025 and there's no regressions with 21.x so far. This bump is also required for updating fedora image to 43. - - - - - d5fd2758 by Cheng Shao at 2025-11-25T12:44:04+01:00 ci: add x86_64-linux-fedora43-validate+debug_info+ubsan job This patch updates fedora image to 43, and adds a `x86_64-linux-fedora43-validate+debug_info+ubsan` job that's run in validate/nightly pipelines to catch undefined behavior in the RTS codebase. - - - - - 9b82355c by Cheng Shao at 2025-11-25T12:44:35+01:00 rts: fix zero-length VLA undefined behavior in interpretBCO This commit fixes a zero-length VLA undefined behavior in interpretBCO, caught by UBSan: ``` +rts/Interpreter.c:3133:19: runtime variable length array bound evaluates to non-positive value 0 ``` - - - - - 127800a2 by Cheng Shao at 2025-11-25T12:44:35+01:00 rts: fix unaligned ReadSpB in interpretBCO This commit fixes unaligned ReadSpB in interpretBCO, caught by UBSan: ``` +rts/Interpreter.c:2174:64: runtime load of misaligned address 0x004202059dd1 for type 'StgWord', which requires 8 byte alignment ``` To perform proper unaligned read, we define StgUnalignedWord as a type alias of StgWord with aligned(1) attribute, and load StgUnalignedWord instead of StgWord in ReadSpB, so the C compiler is aware that we're not loading with natural alignment. - - - - - f958e99b by Cheng Shao at 2025-11-25T12:44:35+01:00 rts: fix signed integer overflow in subword arithmetic in interpretBCO - - - - - 14 changed files: - .gitlab-ci.yml - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - configure.ac - hadrian/doc/flavours.md - hadrian/src/Flavour.hs - + rts/.ubsan-suppressions - rts/Interpreter.c - rts/include/stg/Types.h - rts/rts.cabal - testsuite/driver/testglobals.py - testsuite/driver/testlib.py Changes: ===================================== .gitlab-ci.yml ===================================== @@ -11,7 +11,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: a97d5c67d803c6b3811c6cccdf33dc8e9d7eafe3 + DOCKER_REV: 91427f8ccea7dd472d6e0e44db858b4003aef826 # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. @@ -444,14 +444,14 @@ hadrian-ghc-in-ghci: hadrian-multi: stage: testing needs: - - job: x86_64-linux-fedora42-release + - job: x86_64-linux-fedora43-release optional: true - - job: nightly-x86_64-linux-fedora42-release + - job: nightly-x86_64-linux-fedora43-release optional: true - - job: release-x86_64-linux-fedora42-release + - job: release-x86_64-linux-fedora43-release optional: true dependencies: null - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV" + image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV" before_script: # workaround for docker permissions - sudo chown ghc:ghc -R . @@ -471,7 +471,7 @@ hadrian-multi: - ls - | mkdir tmp - tar -xf ghc-x86_64-linux-fedora42-release.tar.xz -C tmp + tar -xf ghc-x86_64-linux-fedora43-release.tar.xz -C tmp pushd tmp/ghc-*/ ./configure --prefix=$root make install @@ -533,17 +533,17 @@ test-cabal-reinstall-x86_64-linux-deb10: abi-test-nightly: stage: full-build needs: - - job: nightly-x86_64-linux-fedora42-release-hackage - - job: nightly-x86_64-linux-fedora42-release + - job: nightly-x86_64-linux-fedora43-release-hackage + - job: nightly-x86_64-linux-fedora43-release tags: - x86_64-linux - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV" + image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV" dependencies: null before_script: - mkdir -p normal - mkdir -p hackage - - tar -xf ghc-x86_64-linux-fedora42-release.tar.xz -C normal/ - - tar -xf ghc-x86_64-linux-fedora42-release-hackage_docs.tar.xz -C hackage/ + - tar -xf ghc-x86_64-linux-fedora43-release.tar.xz -C normal/ + - tar -xf ghc-x86_64-linux-fedora43-release-hackage_docs.tar.xz -C hackage/ script: - .gitlab/ci.sh compare_interfaces_of "normal/ghc-*" "hackage/ghc-*" artifacts: @@ -620,9 +620,9 @@ doc-tarball: hackage-doc-tarball: stage: packaging needs: - - job: nightly-x86_64-linux-fedora42-release-hackage + - job: nightly-x86_64-linux-fedora43-release-hackage optional: true - - job: release-x86_64-linux-fedora42-release-hackage + - job: release-x86_64-linux-fedora43-release-hackage optional: true - job: source-tarball tags: @@ -639,7 +639,7 @@ hackage-doc-tarball: - hackage_docs before_script: - tar -xf ghc-*[0-9]-src.tar.xz - - tar -xf ghc-x86_64-linux-fedora42-release.tar.xz -C ghc*/ + - tar -xf ghc-x86_64-linux-fedora43-release.tar.xz -C ghc*/ script: - cd ghc*/ - mv .gitlab/rel_eng/upload_ghc_libs.py . @@ -765,7 +765,7 @@ test-bootstrap: # Triggering jobs in the ghc/head.hackage project requires that we have a job # token for that repository. Furthermore the head.hackage CI job must have # access to an unprivileged access token with the ability to query the ghc/ghc -# project such that it can find the job ID of the fedora42 job for the current +# project such that it can find the job ID of the fedora43 job for the current # pipeline. # # hackage-lint: Can be triggered on any MR, normal validate pipeline or nightly build. @@ -852,7 +852,7 @@ nightly-hackage-lint: nightly-hackage-perf: needs: - - job: nightly-x86_64-linux-fedora42-release + - job: nightly-x86_64-linux-fedora43-release optional: true artifacts: false - job: nightly-aarch64-linux-deb12-validate @@ -871,7 +871,7 @@ nightly-hackage-perf: release-hackage-lint: needs: - - job: release-x86_64-linux-fedora42-release + - job: release-x86_64-linux-fedora43-release optional: true artifacts: false - job: release-aarch64-linux-deb12-release+no_split_sections @@ -957,13 +957,13 @@ perf-nofib: allow_failure: true stage: testing needs: - - job: x86_64-linux-fedora42-release + - job: x86_64-linux-fedora43-release optional: true - - job: nightly-x86_64-linux-fedora42-release + - job: nightly-x86_64-linux-fedora43-release optional: true - - job: release-x86_64-linux-fedora42-release + - job: release-x86_64-linux-fedora43-release optional: true - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV" + image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV" rules: - when: never - *full-ci @@ -976,7 +976,7 @@ perf-nofib: - root=$(pwd)/ghc - | mkdir tmp - tar -xf ../ghc-x86_64-linux-fedora42-release.tar.xz -C tmp + tar -xf ../ghc-x86_64-linux-fedora43-release.tar.xz -C tmp pushd tmp/ghc-*/ ./configure --prefix=$root make install @@ -1000,14 +1000,14 @@ perf-nofib: perf: stage: testing needs: - - job: x86_64-linux-fedora42-release + - job: x86_64-linux-fedora43-release optional: true - - job: nightly-x86_64-linux-fedora42-release + - job: nightly-x86_64-linux-fedora43-release optional: true - - job: release-x86_64-linux-fedora42-release + - job: release-x86_64-linux-fedora43-release optional: true dependencies: null - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV" + image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV" tags: - x86_64-linux-perf before_script: @@ -1017,7 +1017,7 @@ perf: - root=$(pwd)/ghc - | mkdir tmp - tar -xf ghc-x86_64-linux-fedora42-release.tar.xz -C tmp + tar -xf ghc-x86_64-linux-fedora43-release.tar.xz -C tmp pushd tmp/ghc-*/ ./configure --prefix=$root make install @@ -1041,14 +1041,14 @@ perf: abi-test: stage: testing needs: - - job: x86_64-linux-fedora42-release + - job: x86_64-linux-fedora43-release optional: true - - job: nightly-x86_64-linux-fedora42-release + - job: nightly-x86_64-linux-fedora43-release optional: true - - job: release-x86_64-linux-fedora42-release + - job: release-x86_64-linux-fedora43-release optional: true dependencies: null - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV" + image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV" rules: - if: $CI_MERGE_REQUEST_ID - if: '$CI_COMMIT_BRANCH == "master"' @@ -1059,7 +1059,7 @@ abi-test: - root=$(pwd)/ghc - | mkdir tmp - tar -xf ghc-x86_64-linux-fedora42-release.tar.xz -C tmp + tar -xf ghc-x86_64-linux-fedora43-release.tar.xz -C tmp pushd tmp/ghc-*/ ./configure --prefix=$root make install @@ -1214,7 +1214,7 @@ ghcup-metadata-nightly: extends: .ghcup-metadata # Explicit needs for validate pipeline because we only need certain bindists needs: - - job: nightly-x86_64-linux-fedora42-release + - job: nightly-x86_64-linux-fedora43-release artifacts: false - job: nightly-x86_64-linux-ubuntu24_04-validate artifacts: false @@ -1265,7 +1265,7 @@ ghcup-metadata-nightly: # Update the ghcup metadata with information about this nightly pipeline ghcup-metadata-nightly-push: stage: deploy - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV" + image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV" dependencies: null tags: - x86_64-linux ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -82,7 +82,7 @@ The generated names for the jobs is important as there are a few downstream cons of the jobs artifacts. Therefore some care should be taken if changing the generated names of jobs to update these other places. -1. fedora42 jobs are required by head.hackage +1. fedora43 jobs are required by head.hackage 2. The fetch-gitlab release utility pulls release artifacts from the 3. The ghc-head-from script downloads release artifacts based on a pipeline change. 4. Some subsequent CI jobs have explicit dependencies (for example docs-tarball, perf, perf-nofib) @@ -118,7 +118,7 @@ data LinuxDistro | Debian11Js | Debian10 | Debian9 - | Fedora42 + | Fedora43 | Ubuntu2404LoongArch64 | Ubuntu2404 | Ubuntu2204 @@ -161,6 +161,7 @@ data BuildConfig , hostFullyStatic :: Bool , tablesNextToCode :: Bool , threadSanitiser :: Bool + , ubsan :: Bool , noSplitSections :: Bool , validateNonmovingGc :: Bool , textWithSIMDUTF :: Bool @@ -186,6 +187,7 @@ mkJobFlavour BuildConfig{..} = Flavour buildFlavour opts [FullyStatic | fullyStatic] ++ [HostFullyStatic | hostFullyStatic] ++ [ThreadSanitiser | threadSanitiser] ++ + [UBSan | ubsan] ++ [NoSplitSections | noSplitSections, buildFlavour == Release ] ++ [BootNonmovingGc | validateNonmovingGc ] ++ [TextWithSIMDUTF | textWithSIMDUTF] @@ -198,6 +200,7 @@ data FlavourTrans = | FullyStatic | HostFullyStatic | ThreadSanitiser + | UBSan | NoSplitSections | BootNonmovingGc | TextWithSIMDUTF @@ -226,6 +229,7 @@ vanilla = BuildConfig , hostFullyStatic = False , tablesNextToCode = True , threadSanitiser = False + , ubsan = False , noSplitSections = False , validateNonmovingGc = False , textWithSIMDUTF = False @@ -279,6 +283,9 @@ llvm = vanilla { llvmBootstrap = True } tsan :: BuildConfig tsan = vanilla { threadSanitiser = True } +enableUBSan :: BuildConfig +enableUBSan = vanilla { withDwarf = True, ubsan = True } + noTntc :: BuildConfig noTntc = vanilla { tablesNextToCode = False } @@ -318,7 +325,7 @@ distroName Debian12Riscv = "deb12-riscv" distroName Debian12Wine = "deb12-wine" distroName Debian10 = "deb10" distroName Debian9 = "deb9" -distroName Fedora42 = "fedora42" +distroName Fedora43 = "fedora43" distroName Ubuntu2404LoongArch64 = "ubuntu24_04-loongarch" distroName Ubuntu1804 = "ubuntu18_04" distroName Ubuntu2004 = "ubuntu20_04" @@ -373,6 +380,7 @@ flavourString (Flavour base trans) = base_string base ++ concatMap (("+" ++) . f flavour_string FullyStatic = "fully_static" flavour_string HostFullyStatic = "host_fully_static" flavour_string ThreadSanitiser = "thread_sanitizer_cmm" + flavour_string UBSan = "ubsan" flavour_string NoSplitSections = "no_split_sections" flavour_string BootNonmovingGc = "boot_nonmoving_gc" flavour_string TextWithSIMDUTF = "text_simdutf" @@ -1196,13 +1204,22 @@ rhel_x86 = fedora_x86 :: [JobGroup Job] fedora_x86 = - [ -- Fedora42 job is always built with perf so there's one job in the normal + [ -- Fedora43 job is always built with perf so there's one job in the normal -- validate pipeline which is built with perf. - fastCI (standardBuildsWithConfig Amd64 (Linux Fedora42) releaseConfig) + fastCI (standardBuildsWithConfig Amd64 (Linux Fedora43) releaseConfig) -- This job is only for generating head.hackage docs - , hackage_doc_job (disableValidate (standardBuildsWithConfig Amd64 (Linux Fedora42) releaseConfig)) - , disableValidate (standardBuildsWithConfig Amd64 (Linux Fedora42) dwarf) - , disableValidate (standardBuilds Amd64 (Linux Fedora42)) + , hackage_doc_job (disableValidate (standardBuildsWithConfig Amd64 (Linux Fedora43) releaseConfig)) + , disableValidate (standardBuildsWithConfig Amd64 (Linux Fedora43) dwarf) + , disableValidate (standardBuilds Amd64 (Linux Fedora43)) + -- For UBSan jobs, only enable for validate/nightly pipelines. + -- Also disable docs since it's not the point for UBSan jobs. + , modifyJobs + ( setVariable "HADRIAN_ARGS" "--docs=none" + . addVariable + "UBSAN_OPTIONS" + "suppressions=$CI_PROJECT_DIR/rts/.ubsan-suppressions" + ) + $ validateBuilds Amd64 (Linux Fedora43) enableUBSan ] where hackage_doc_job = rename (<> "-hackage") . modifyJobs (addVariable "HADRIAN_ARGS" "--haddock-for-hackage") @@ -1364,7 +1381,7 @@ platform_mapping = Map.map go combined_result , "x86_64-linux-deb11-validate" , "x86_64-linux-deb12-validate" , "x86_64-linux-deb10-validate+debug_info" - , "x86_64-linux-fedora42-release" + , "x86_64-linux-fedora43-release" , "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate" , "x86_64-windows-validate" , "aarch64-linux-deb12-validate" @@ -1379,13 +1396,13 @@ platform_mapping = Map.map go combined_result , "nightly-aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate" , "nightly-x86_64-linux-alpine3_12-validate+fully_static" , "nightly-x86_64-linux-deb10-validate" - , "nightly-x86_64-linux-fedora42-release" + , "nightly-x86_64-linux-fedora43-release" , "nightly-x86_64-windows-validate" , "release-x86_64-linux-alpine3_12-release+fully_static+no_split_sections" , "release-x86_64-linux-deb10-release" , "release-x86_64-linux-deb11-release" , "release-x86_64-linux-deb12-release" - , "release-x86_64-linux-fedora42-release" + , "release-x86_64-linux-fedora43-release" , "release-x86_64-windows-release" ] ===================================== .gitlab/jobs.yaml ===================================== @@ -2942,7 +2942,7 @@ "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-fedora42-release": { + "nightly-x86_64-linux-fedora43-release": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -2953,7 +2953,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-fedora42-release.tar.xz", + "ghc-x86_64-linux-fedora43-release.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -2963,14 +2963,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-fedora42-$CACHE_REV", + "key": "x86_64-linux-fedora43-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -2996,16 +2996,16 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-release", + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-fedora42-release", + "TEST_ENV": "x86_64-linux-fedora43-release", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-fedora42-release-hackage": { + "nightly-x86_64-linux-fedora43-release-hackage": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -3016,7 +3016,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-fedora42-release.tar.xz", + "ghc-x86_64-linux-fedora43-release.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -3026,14 +3026,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-fedora42-$CACHE_REV", + "key": "x86_64-linux-fedora43-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -3059,17 +3059,17 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-release", + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "HADRIAN_ARGS": "--haddock-for-hackage", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-fedora42-release", + "TEST_ENV": "x86_64-linux-fedora43-release", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-fedora42-validate": { + "nightly-x86_64-linux-fedora43-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -3080,7 +3080,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-fedora42-validate.tar.xz", + "ghc-x86_64-linux-fedora43-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -3090,14 +3090,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-fedora42-$CACHE_REV", + "key": "x86_64-linux-fedora43-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -3123,16 +3123,16 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-fedora42-validate", + "TEST_ENV": "x86_64-linux-fedora43-validate", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-fedora42-validate+debug_info": { + "nightly-x86_64-linux-fedora43-validate+debug_info": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -3143,7 +3143,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-fedora42-validate+debug_info.tar.xz", + "ghc-x86_64-linux-fedora43-validate+debug_info.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -3153,14 +3153,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-fedora42-$CACHE_REV", + "key": "x86_64-linux-fedora43-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -3186,12 +3186,77 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-validate+debug_info", + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+debug_info", "BUILD_FLAVOUR": "validate+debug_info", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-fedora42-validate+debug_info", + "TEST_ENV": "x86_64-linux-fedora43-validate+debug_info", + "XZ_OPT": "-9" + } + }, + "nightly-x86_64-linux-fedora43-validate+debug_info+ubsan": { + "after_script": [ + ".gitlab/ci.sh save_cache", + ".gitlab/ci.sh save_test_output", + ".gitlab/ci.sh clean", + "cat ci_timings.txt" + ], + "allow_failure": false, + "artifacts": { + "expire_in": "8 weeks", + "paths": [ + "ghc-x86_64-linux-fedora43-validate+debug_info+ubsan.tar.xz", + "junit.xml", + "unexpected-test-output.tar.gz" + ], + "reports": { + "junit": "junit.xml" + }, + "when": "always" + }, + "cache": { + "key": "x86_64-linux-fedora43-$CACHE_REV", + "paths": [ + "cabal-cache", + "toolchain" + ] + }, + "dependencies": [], + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV", + "needs": [ + { + "artifacts": false, + "job": "hadrian-ghc-in-ghci" + } + ], + "rules": [ + { + "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY)", + "when": "on_success" + } + ], + "script": [ + "sudo chown ghc:ghc -R .", + ".gitlab/ci.sh setup", + ".gitlab/ci.sh configure", + ".gitlab/ci.sh build_hadrian", + ".gitlab/ci.sh test_hadrian" + ], + "stage": "full-build", + "tags": [ + "x86_64-linux" + ], + "variables": { + "BIGNUM_BACKEND": "gmp", + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+debug_info+ubsan", + "BUILD_FLAVOUR": "validate+debug_info+ubsan", + "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "HADRIAN_ARGS": "--docs=none", + "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "RUNTEST_ARGS": "", + "TEST_ENV": "x86_64-linux-fedora43-validate+debug_info+ubsan", + "UBSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.ubsan-suppressions", "XZ_OPT": "-9" } }, @@ -4808,7 +4873,7 @@ "XZ_OPT": "-9" } }, - "release-x86_64-linux-fedora42-release": { + "release-x86_64-linux-fedora43-release": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -4819,7 +4884,7 @@ "artifacts": { "expire_in": "1 year", "paths": [ - "ghc-x86_64-linux-fedora42-release.tar.xz", + "ghc-x86_64-linux-fedora43-release.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -4829,14 +4894,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-fedora42-$CACHE_REV", + "key": "x86_64-linux-fedora43-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -4862,17 +4927,17 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-release", + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "IGNORE_PERF_FAILURES": "all", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-fedora42-release", + "TEST_ENV": "x86_64-linux-fedora43-release", "XZ_OPT": "-9" } }, - "release-x86_64-linux-fedora42-release+debug_info": { + "release-x86_64-linux-fedora43-release+debug_info": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -4883,7 +4948,7 @@ "artifacts": { "expire_in": "1 year", "paths": [ - "ghc-x86_64-linux-fedora42-release+debug_info.tar.xz", + "ghc-x86_64-linux-fedora43-release+debug_info.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -4893,14 +4958,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-fedora42-$CACHE_REV", + "key": "x86_64-linux-fedora43-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -4926,17 +4991,17 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-release+debug_info", + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release+debug_info", "BUILD_FLAVOUR": "release+debug_info", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "IGNORE_PERF_FAILURES": "all", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-fedora42-release+debug_info", + "TEST_ENV": "x86_64-linux-fedora43-release+debug_info", "XZ_OPT": "-9" } }, - "release-x86_64-linux-fedora42-release-hackage": { + "release-x86_64-linux-fedora43-release-hackage": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -4947,7 +5012,7 @@ "artifacts": { "expire_in": "1 year", "paths": [ - "ghc-x86_64-linux-fedora42-release.tar.xz", + "ghc-x86_64-linux-fedora43-release.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -4957,14 +5022,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-fedora42-$CACHE_REV", + "key": "x86_64-linux-fedora43-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -4990,14 +5055,14 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-release", + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "HADRIAN_ARGS": "--haddock-for-hackage", "IGNORE_PERF_FAILURES": "all", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-fedora42-release", + "TEST_ENV": "x86_64-linux-fedora43-release", "XZ_OPT": "-9" } }, @@ -7032,7 +7097,7 @@ "TEST_ENV": "x86_64-linux-deb9-validate" } }, - "x86_64-linux-fedora42-release": { + "x86_64-linux-fedora43-release": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -7043,7 +7108,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-fedora42-release.tar.xz", + "ghc-x86_64-linux-fedora43-release.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -7053,14 +7118,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-fedora42-$CACHE_REV", + "key": "x86_64-linux-fedora43-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -7069,7 +7134,7 @@ ], "rules": [ { - "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora42-release(\\s|$).*/)) || (($ONLY_JOBS == null) && ((\"true\" == \"true\")))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-release(\\s|$).*/)) || (($ONLY_JOBS == null) && ((\"true\" == \"true\")))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -7086,15 +7151,15 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-release", + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-fedora42-release" + "TEST_ENV": "x86_64-linux-fedora43-release" } }, - "x86_64-linux-fedora42-release-hackage": { + "x86_64-linux-fedora43-release-hackage": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -7105,7 +7170,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-fedora42-release.tar.xz", + "ghc-x86_64-linux-fedora43-release.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -7115,14 +7180,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-fedora42-$CACHE_REV", + "key": "x86_64-linux-fedora43-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -7131,7 +7196,7 @@ ], "rules": [ { - "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora42-release(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-release(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -7148,16 +7213,16 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-release", + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "HADRIAN_ARGS": "--haddock-for-hackage", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-fedora42-release" + "TEST_ENV": "x86_64-linux-fedora43-release" } }, - "x86_64-linux-fedora42-validate": { + "x86_64-linux-fedora43-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -7168,7 +7233,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-fedora42-validate.tar.xz", + "ghc-x86_64-linux-fedora43-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -7178,14 +7243,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-fedora42-$CACHE_REV", + "key": "x86_64-linux-fedora43-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -7194,7 +7259,7 @@ ], "rules": [ { - "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora42-validate(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-validate(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -7211,15 +7276,15 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-fedora42-validate" + "TEST_ENV": "x86_64-linux-fedora43-validate" } }, - "x86_64-linux-fedora42-validate+debug_info": { + "x86_64-linux-fedora43-validate+debug_info": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -7230,7 +7295,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-fedora42-validate+debug_info.tar.xz", + "ghc-x86_64-linux-fedora43-validate+debug_info.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -7240,14 +7305,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-fedora42-$CACHE_REV", + "key": "x86_64-linux-fedora43-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -7256,7 +7321,7 @@ ], "rules": [ { - "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora42-validate\\+debug_info(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-validate\\+debug_info(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -7273,12 +7338,76 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-validate+debug_info", + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+debug_info", "BUILD_FLAVOUR": "validate+debug_info", "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", - "TEST_ENV": "x86_64-linux-fedora42-validate+debug_info" + "TEST_ENV": "x86_64-linux-fedora43-validate+debug_info" + } + }, + "x86_64-linux-fedora43-validate+debug_info+ubsan": { + "after_script": [ + ".gitlab/ci.sh save_cache", + ".gitlab/ci.sh save_test_output", + ".gitlab/ci.sh clean", + "cat ci_timings.txt" + ], + "allow_failure": false, + "artifacts": { + "expire_in": "2 weeks", + "paths": [ + "ghc-x86_64-linux-fedora43-validate+debug_info+ubsan.tar.xz", + "junit.xml", + "unexpected-test-output.tar.gz" + ], + "reports": { + "junit": "junit.xml" + }, + "when": "always" + }, + "cache": { + "key": "x86_64-linux-fedora43-$CACHE_REV", + "paths": [ + "cabal-cache", + "toolchain" + ] + }, + "dependencies": [], + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV", + "needs": [ + { + "artifacts": false, + "job": "hadrian-ghc-in-ghci" + } + ], + "rules": [ + { + "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-validate\\+debug_info\\+ubsan(\\s|$).*/)) || (($ONLY_JOBS == null) && ((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "when": "on_success" + } + ], + "script": [ + "sudo chown ghc:ghc -R .", + ".gitlab/ci.sh setup", + ".gitlab/ci.sh configure", + ".gitlab/ci.sh build_hadrian", + ".gitlab/ci.sh test_hadrian" + ], + "stage": "full-build", + "tags": [ + "x86_64-linux" + ], + "variables": { + "BIGNUM_BACKEND": "gmp", + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+debug_info+ubsan", + "BUILD_FLAVOUR": "validate+debug_info+ubsan", + "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "HADRIAN_ARGS": "--docs=none", + "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "RUNTEST_ARGS": "", + "TEST_ENV": "x86_64-linux-fedora43-validate+debug_info+ubsan", + "UBSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.ubsan-suppressions" } }, "x86_64-linux-rocky8-validate": { ===================================== .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py ===================================== @@ -23,8 +23,8 @@ def job_triple(job_name): 'release-x86_64-linux-ubuntu22_04-release': 'x86_64-ubuntu22_04-linux', 'release-x86_64-linux-ubuntu20_04-release': 'x86_64-ubuntu20_04-linux', 'release-x86_64-linux-ubuntu18_04-release': 'x86_64-ubuntu18_04-linux', - 'release-x86_64-linux-fedora42-release': 'x86_64-fedora42-linux', - 'release-x86_64-linux-fedora42-release+debug_info': 'x86_64-fedora42-linux-dwarf', + 'release-x86_64-linux-fedora43-release': 'x86_64-fedora43-linux', + 'release-x86_64-linux-fedora43-release+debug_info': 'x86_64-fedora43-linux-dwarf', 'release-x86_64-linux-deb12-release': 'x86_64-deb12-linux', 'release-x86_64-linux-deb11-release': 'x86_64-deb11-linux', 'release-x86_64-linux-deb10-release+debug_info': 'x86_64-deb10-linux-dwarf', ===================================== .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py ===================================== @@ -200,7 +200,7 @@ def mk_new_yaml(release_mode, version, date, pipeline_type, job_map): ubuntu2204 = mk(ubuntu("22_04")) ubuntu2404 = mk(ubuntu("24_04")) rocky8 = mk(rocky("8")) - fedora42 = mk(fedora(42)) + fedora43 = mk(fedora(43)) darwin_x86 = mk(darwin("x86_64")) darwin_arm64 = mk(darwin("aarch64")) windows = mk(windowsArtifact) @@ -239,7 +239,7 @@ def mk_new_yaml(release_mode, version, date, pipeline_type, job_map): , "unknown_versioning": ubuntu2004 } , "Linux_CentOS" : { "( >= 8 && < 9 )" : rocky8 , "unknown_versioning" : rocky8 } - , "Linux_Fedora" : { ">= 42": fedora42 + , "Linux_Fedora" : { ">= 43": fedora43 , "unknown_versioning": rocky8 } , "Linux_RedHat" : { "unknown_versioning": rocky8 } , "Linux_UnknownLinux" : { "unknown_versioning": rocky8 } ===================================== configure.ac ===================================== @@ -526,7 +526,7 @@ AC_SUBST(InstallNameToolCmd) # versions of LLVM simultaneously, but that stopped working around # 3.5/3.6 release of LLVM. LlvmMinVersion=13 # inclusive -LlvmMaxVersion=21 # not inclusive +LlvmMaxVersion=22 # not inclusive AC_SUBST([LlvmMinVersion]) AC_SUBST([LlvmMaxVersion]) ===================================== hadrian/doc/flavours.md ===================================== @@ -238,6 +238,10 @@ The supported transformers are listed below: <td><code>thread_sanitizer</code></td> <td>Build the runtime system with ThreadSanitizer support</td> </tr> + <tr> + <td><code>ubsan</code></td> + <td>Build all stage1+ C/C++ code with UndefinedBehaviorSanitizer support</td> + </tr> <tr> <td><code>llvm</code></td> <td>Use GHC's LLVM backend (`-fllvm`) for all stage1+ compilation.</td> ===================================== hadrian/src/Flavour.hs ===================================== @@ -7,6 +7,7 @@ module Flavour , addArgs , splitSections , enableThreadSanitizer + , enableUBSan , enableLateCCS , enableHashUnitIds , enableDebugInfo, enableTickyGhc @@ -33,6 +34,9 @@ import Data.Either import Data.Map (Map) import qualified Data.Map as M import qualified Data.Set as Set +import GHC.Platform.ArchOS +import Oracles.Flag +import Oracles.Setting import Packages import Flavour.Type import Settings.Parser @@ -53,6 +57,7 @@ flavourTransformers = M.fromList , "no_split_sections" =: noSplitSections , "thread_sanitizer" =: enableThreadSanitizer False , "thread_sanitizer_cmm" =: enableThreadSanitizer True + , "ubsan" =: enableUBSan , "llvm" =: viaLlvmBackend , "profiled_ghc" =: enableProfiledGhc , "no_dynamic_ghc" =: disableDynamicGhcPrograms @@ -258,6 +263,51 @@ enableThreadSanitizer instrumentCmm = addArgs $ notStage0 ? mconcat ] ] +-- | Whether or not -shared-libsan should be passed to clang at +-- link-time. +-- +-- See +-- https://github.com/llvm/llvm-project/blob/llvmorg-21.1.6/clang/lib/Driver/Sa..., +-- clang defaults to -shared-libsan on darwin/windows and +-- -static-libsan on linux. In general, -static-libsan is incredibly +-- problematic when multiple copies of the sanitizer runtimes coexist +-- in the same address space due to being linked into multiple Haskell +-- libraries. So we should explicitly specify `-shared-libsan` if +-- needed. +-- +-- A small downside of -shared-libsan is the clang-specific sanitizer +-- runtime shared library path needs to be manually specified via +-- @export LD_LIBRARY_PATH=$(dirname $(clang -print-libgcc-file-name +-- -rtlib=compiler-rt))@ for ld.so to find it at runtime. +needSharedLibSAN :: Action Bool +needSharedLibSAN = do + is_clang <- flag CcLlvmBackend + is_default_shared_libsan <- anyTargetOs [OSDarwin, OSMinGW32] + pure $ is_clang && not is_default_shared_libsan + +-- | Build all stage1+ C/C++ code with UndefinedBehaviorSanitizer +-- support: +-- https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html +enableUBSan :: Flavour -> Flavour +enableUBSan = + addArgs $ + notStage0 + ? mconcat + [ package rts + ? builder (Cabal Flags) + ? arg "+ubsan" + <> (needSharedLibSAN ? arg "+shared-libsan"), + builder (Ghc CompileHs) ? arg "-optc-fsanitize=undefined", + builder (Ghc CompileCWithGhc) ? arg "-optc-fsanitize=undefined", + builder (Ghc CompileCppWithGhc) ? arg "-optcxx-fsanitize=undefined", + builder (Ghc LinkHs) + ? arg "-optc-fsanitize=undefined" + <> arg "-optl-fsanitize=undefined" + <> (needSharedLibSAN ? arg "-optl-shared-libsan"), + builder (Cc CompileC) ? arg "-fsanitize=undefined", + builder Testsuite ? arg "--config=have_ubsan=True" + ] + -- | Use the LLVM backend in stages 1 and later. viaLlvmBackend :: Flavour -> Flavour viaLlvmBackend = addArgs $ notStage0 ? builder Ghc ? arg "-fllvm" ===================================== rts/.ubsan-suppressions ===================================== @@ -0,0 +1,8 @@ +# libraries/text/cbits/measure_off.c:50:39: runtime left shift of 1 by 31 places cannot be represented in type 'int' +shift-base:libraries/text/cbits/measure_off.c + +# "runtime call to function foo through pointer to incorrect function +# type" is unfortunately pretty common (e.g. evac_fn in rts) and +# impact the signal to noise ratio of UBSan warnings. gcc doesn't +# implement this instrumentation though. +function:* ===================================== rts/Interpreter.c ===================================== @@ -274,12 +274,21 @@ See also Note [Width of parameters] for some more motivation. #define W64_TO_WDS(n) ((n * sizeof(StgWord64) / sizeof(StgWord))) +// Returns a pointer to the stack location. +#define SafeSpWP(n) \ + ( ((WITHIN_CAP_CHUNK_BOUNDS_W(n)) ? Sp_plusW(n) : slow_spw(Sp, cap->r.rCurrentTSO->stackobj, n))) +#define SafeSpBP(off_w) \ + ( (WITHIN_CAP_CHUNK_BOUNDS_W((1+(off_w))/sizeof(StgWord))) ? \ + Sp_plusB(off_w) : \ + (void*)((ptrdiff_t)((ptrdiff_t)(off_w) % (ptrdiff_t)sizeof(StgWord)) + (StgWord8*)slow_spw(Sp, cap->r.rCurrentTSO->stackobj, (off_w)/sizeof(StgWord))) \ + ) + // Always safe to use - Return the value at the address #define ReadSpW(n) (*((StgWord*) SafeSpWP(n))) //Argument is offset in multiples of word64 #define ReadSpW64(n) (*((StgWord64*) SafeSpWP(W64_TO_WDS(n)))) // Perhaps confusingly this still reads a full word, merely the offset is in bytes. -#define ReadSpB(n) (*((StgWord*) SafeSpBP(n))) +#define ReadSpB(n) (*((StgUnalignedWord*) SafeSpBP(n))) /* Note [PUSH_L underflow] ~~~~~~~~~~~~~~~~~~~~~~~ @@ -326,15 +335,6 @@ See ticket #25750 */ -// Returns a pointer to the stack location. -#define SafeSpWP(n) \ - ( ((WITHIN_CAP_CHUNK_BOUNDS_W(n)) ? Sp_plusW(n) : slow_spw(Sp, cap->r.rCurrentTSO->stackobj, n))) -#define SafeSpBP(off_w) \ - ( (WITHIN_CAP_CHUNK_BOUNDS_W((1+(off_w))/sizeof(StgWord))) ? \ - Sp_plusB(off_w) : \ - (void*)((ptrdiff_t)((ptrdiff_t)(off_w) % (ptrdiff_t)sizeof(StgWord)) + (StgWord8*)slow_spw(Sp, cap->r.rCurrentTSO->stackobj, (off_w)/sizeof(StgWord))) \ - ) - /* Note [Interpreter subword primops] @@ -2904,6 +2904,8 @@ run_BCO: NEXT_INSTRUCTION; \ } +#define TYPE_IS_SIGNED(ty) ((ty)-1 < (ty)1) + // op :: ty -> ty -> ty #define SIZED_BIN_OP(op,ty) \ { \ @@ -2911,8 +2913,12 @@ run_BCO: ty r = ((ty) ReadSpW64(0)) op ((ty) ReadSpW64(1)); \ Sp_addW64(1); \ SpW64(0) = (StgWord64) r; \ + } else if (TYPE_IS_SIGNED(ty)) { \ + ty r = ((StgInt)(ty)ReadSpW(0)) op ((StgInt)(ty)ReadSpW(1)); \ + Sp_addW(1); \ + SpW(0) = (StgWord) r; \ } else { \ - ty r = ((ty) ReadSpW(0)) op ((ty) ReadSpW(1)); \ + ty r = ((StgWord)(ty)ReadSpW(0)) op ((StgWord)(ty)ReadSpW(1)); \ Sp_addW(1); \ SpW(0) = (StgWord) r; \ }; \ @@ -2949,12 +2955,12 @@ run_BCO: NEXT_INSTRUCTION; \ } - INSTRUCTION(bci_OP_ADD_64): SIZED_BIN_OP(+, StgInt64) - INSTRUCTION(bci_OP_SUB_64): SIZED_BIN_OP(-, StgInt64) - INSTRUCTION(bci_OP_AND_64): SIZED_BIN_OP(&, StgInt64) - INSTRUCTION(bci_OP_XOR_64): SIZED_BIN_OP(^, StgInt64) - INSTRUCTION(bci_OP_OR_64): SIZED_BIN_OP(|, StgInt64) - INSTRUCTION(bci_OP_MUL_64): SIZED_BIN_OP(*, StgInt64) + INSTRUCTION(bci_OP_ADD_64): SIZED_BIN_OP(+, StgWord64) + INSTRUCTION(bci_OP_SUB_64): SIZED_BIN_OP(-, StgWord64) + INSTRUCTION(bci_OP_AND_64): SIZED_BIN_OP(&, StgWord64) + INSTRUCTION(bci_OP_XOR_64): SIZED_BIN_OP(^, StgWord64) + INSTRUCTION(bci_OP_OR_64): SIZED_BIN_OP(|, StgWord64) + INSTRUCTION(bci_OP_MUL_64): SIZED_BIN_OP(*, StgWord64) INSTRUCTION(bci_OP_SHL_64): SIZED_BIN_OP_TY_INT(<<, StgWord64) INSTRUCTION(bci_OP_LSR_64): SIZED_BIN_OP_TY_INT(>>, StgWord64) INSTRUCTION(bci_OP_ASR_64): SIZED_BIN_OP_TY_INT(>>, StgInt64) @@ -2972,15 +2978,15 @@ run_BCO: INSTRUCTION(bci_OP_S_LE_64): SIZED_BIN_OP_TY_TY_INT(<=, StgInt64) INSTRUCTION(bci_OP_NOT_64): UN_SIZED_OP(~, StgWord64) - INSTRUCTION(bci_OP_NEG_64): UN_SIZED_OP(-, StgInt64) + INSTRUCTION(bci_OP_NEG_64): UN_SIZED_OP(-, StgWord64) - INSTRUCTION(bci_OP_ADD_32): SIZED_BIN_OP(+, StgInt32) - INSTRUCTION(bci_OP_SUB_32): SIZED_BIN_OP(-, StgInt32) - INSTRUCTION(bci_OP_AND_32): SIZED_BIN_OP(&, StgInt32) - INSTRUCTION(bci_OP_XOR_32): SIZED_BIN_OP(^, StgInt32) - INSTRUCTION(bci_OP_OR_32): SIZED_BIN_OP(|, StgInt32) - INSTRUCTION(bci_OP_MUL_32): SIZED_BIN_OP(*, StgInt32) + INSTRUCTION(bci_OP_ADD_32): SIZED_BIN_OP(+, StgWord32) + INSTRUCTION(bci_OP_SUB_32): SIZED_BIN_OP(-, StgWord32) + INSTRUCTION(bci_OP_AND_32): SIZED_BIN_OP(&, StgWord32) + INSTRUCTION(bci_OP_XOR_32): SIZED_BIN_OP(^, StgWord32) + INSTRUCTION(bci_OP_OR_32): SIZED_BIN_OP(|, StgWord32) + INSTRUCTION(bci_OP_MUL_32): SIZED_BIN_OP(*, StgWord32) INSTRUCTION(bci_OP_SHL_32): SIZED_BIN_OP_TY_INT(<<, StgWord32) INSTRUCTION(bci_OP_LSR_32): SIZED_BIN_OP_TY_INT(>>, StgWord32) INSTRUCTION(bci_OP_ASR_32): SIZED_BIN_OP_TY_INT(>>, StgInt32) @@ -2998,15 +3004,15 @@ run_BCO: INSTRUCTION(bci_OP_S_LE_32): SIZED_BIN_OP_TY_TY_INT(<=, StgInt32) INSTRUCTION(bci_OP_NOT_32): UN_SIZED_OP(~, StgWord32) - INSTRUCTION(bci_OP_NEG_32): UN_SIZED_OP(-, StgInt32) + INSTRUCTION(bci_OP_NEG_32): UN_SIZED_OP(-, StgWord32) - INSTRUCTION(bci_OP_ADD_16): SIZED_BIN_OP(+, StgInt16) - INSTRUCTION(bci_OP_SUB_16): SIZED_BIN_OP(-, StgInt16) - INSTRUCTION(bci_OP_AND_16): SIZED_BIN_OP(&, StgInt16) - INSTRUCTION(bci_OP_XOR_16): SIZED_BIN_OP(^, StgInt16) - INSTRUCTION(bci_OP_OR_16): SIZED_BIN_OP(|, StgInt16) - INSTRUCTION(bci_OP_MUL_16): SIZED_BIN_OP(*, StgInt16) + INSTRUCTION(bci_OP_ADD_16): SIZED_BIN_OP(+, StgWord16) + INSTRUCTION(bci_OP_SUB_16): SIZED_BIN_OP(-, StgWord16) + INSTRUCTION(bci_OP_AND_16): SIZED_BIN_OP(&, StgWord16) + INSTRUCTION(bci_OP_XOR_16): SIZED_BIN_OP(^, StgWord16) + INSTRUCTION(bci_OP_OR_16): SIZED_BIN_OP(|, StgWord16) + INSTRUCTION(bci_OP_MUL_16): SIZED_BIN_OP(*, StgWord16) INSTRUCTION(bci_OP_SHL_16): SIZED_BIN_OP_TY_INT(<<, StgWord16) INSTRUCTION(bci_OP_LSR_16): SIZED_BIN_OP_TY_INT(>>, StgWord16) INSTRUCTION(bci_OP_ASR_16): SIZED_BIN_OP_TY_INT(>>, StgInt16) @@ -3024,15 +3030,15 @@ run_BCO: INSTRUCTION(bci_OP_S_LE_16): SIZED_BIN_OP(<=, StgInt16) INSTRUCTION(bci_OP_NOT_16): UN_SIZED_OP(~, StgWord16) - INSTRUCTION(bci_OP_NEG_16): UN_SIZED_OP(-, StgInt16) + INSTRUCTION(bci_OP_NEG_16): UN_SIZED_OP(-, StgWord16) - INSTRUCTION(bci_OP_ADD_08): SIZED_BIN_OP(+, StgInt8) - INSTRUCTION(bci_OP_SUB_08): SIZED_BIN_OP(-, StgInt8) - INSTRUCTION(bci_OP_AND_08): SIZED_BIN_OP(&, StgInt8) - INSTRUCTION(bci_OP_XOR_08): SIZED_BIN_OP(^, StgInt8) - INSTRUCTION(bci_OP_OR_08): SIZED_BIN_OP(|, StgInt8) - INSTRUCTION(bci_OP_MUL_08): SIZED_BIN_OP(*, StgInt8) + INSTRUCTION(bci_OP_ADD_08): SIZED_BIN_OP(+, StgWord8) + INSTRUCTION(bci_OP_SUB_08): SIZED_BIN_OP(-, StgWord8) + INSTRUCTION(bci_OP_AND_08): SIZED_BIN_OP(&, StgWord8) + INSTRUCTION(bci_OP_XOR_08): SIZED_BIN_OP(^, StgWord8) + INSTRUCTION(bci_OP_OR_08): SIZED_BIN_OP(|, StgWord8) + INSTRUCTION(bci_OP_MUL_08): SIZED_BIN_OP(*, StgWord8) INSTRUCTION(bci_OP_SHL_08): SIZED_BIN_OP_TY_INT(<<, StgWord8) INSTRUCTION(bci_OP_LSR_08): SIZED_BIN_OP_TY_INT(>>, StgWord8) INSTRUCTION(bci_OP_ASR_08): SIZED_BIN_OP_TY_INT(>>, StgInt8) @@ -3050,7 +3056,7 @@ run_BCO: INSTRUCTION(bci_OP_S_LE_08): SIZED_BIN_OP_TY_TY_INT(<=, StgInt8) INSTRUCTION(bci_OP_NOT_08): UN_SIZED_OP(~, StgWord8) - INSTRUCTION(bci_OP_NEG_08): UN_SIZED_OP(-, StgInt8) + INSTRUCTION(bci_OP_NEG_08): UN_SIZED_OP(-, StgWord8) INSTRUCTION(bci_OP_INDEX_ADDR_64): { @@ -3130,7 +3136,7 @@ run_BCO: StgPtr p; W_ ret[2]; // max needed W_ *arguments[stk_offset]; // max needed - void *argptrs[nargs]; + void *argptrs[nargs > 0 ? nargs : 1]; // the size of a variable length array must be positive void (*fn)(void); if (cif->rtype == &ffi_type_void) { ===================================== rts/include/stg/Types.h ===================================== @@ -147,6 +147,8 @@ typedef uint16_t StgHalfWord; #error GHC untested on this architecture: sizeof(void *) != 4 or 8 #endif +typedef StgWord StgUnalignedWord __attribute__((aligned(1))); + #define W_MASK (sizeof(W_)-1) /* ===================================== rts/rts.cabal ===================================== @@ -91,6 +91,19 @@ flag thread-sanitizer in @rts/include/rts/TSANUtils.h@. default: False manual: True +flag ubsan + description: + Link with -fsanitize=undefined, to be enabled when building with + UndefinedBehaviorSanitizer. + default: False + manual: True +flag shared-libsan + description: + Link with -shared-libsan, to guarantee only one copy of the + sanitizer runtimes exist in the address space. See + needSharedLibSAN in hadrian/src/Flavour.hs. + default: False + manual: True library -- rts is a wired in package and @@ -200,6 +213,12 @@ library cc-options: -fsanitize=thread ld-options: -fsanitize=thread + if flag(ubsan) + ld-options: -fsanitize=undefined + + if flag(shared-libsan) + ld-options: -shared-libsan + if os(linux) -- the RTS depends upon libc. while this dependency is generally -- implicitly added by `cc`, we must explicitly add it here to ensure ===================================== testsuite/driver/testglobals.py ===================================== @@ -186,6 +186,9 @@ class TestConfig: # Are we running in a ThreadSanitizer-instrumented build? self.have_thread_sanitizer = False + # Are we running with UndefinedBehaviorSanitizer enabled? + self.have_ubsan = False + # Do symbols use leading underscores? self.leading_underscore = False ===================================== testsuite/driver/testlib.py ===================================== @@ -1090,6 +1090,8 @@ def llvm_build ( ) -> bool: def have_thread_sanitizer( ) -> bool: return config.have_thread_sanitizer +def have_ubsan( ) -> bool: + return config.have_ubsan def gcc_as_cmmp() -> bool: return config.cmm_cpp_is_gcc View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/310bf01b52db3b2ca6416170662d32e... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/310bf01b52db3b2ca6416170662d32e... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Cheng Shao (@TerrorJack)