diff --git a/builder/comp-builder.nix b/builder/comp-builder.nix index 5e6bd41a8..39a915372 100644 --- a/builder/comp-builder.nix +++ b/builder/comp-builder.nix @@ -209,7 +209,15 @@ let (enableFeature enableShared "shared") (enableFeature enableExecutableDynamic "executable-dynamic") (enableFeature doCoverage "coverage") - (enableFeature (enableLibraryForGhci && !stdenv.hostPlatform.isGhcjs) "library-for-ghci") + # For Android (or really anything that uses lld), -r will silently drop + # "lazy" symbols. Those are leaf symbols with no referenes. This however + # does not work when loading the objects into the linker, because then we + # occationally miss symbols when subsequent libraries depending on the one + # that dropped the symbol are loaded. bfd and lld support --whole-archive + # lld -r --whole-archive ... will _not_ drop lazy symbols. However the + # --whole-archive flag needs to come _before_ the objects, it's applied in + # sequence. The proper fix is thusly to add --while-archive to Cabal. + (enableFeature (enableLibraryForGhci && !stdenv.hostPlatform.isGhcjs && !stdenv.hostPlatform.isAndroid) "library-for-ghci") ] ++ lib.optionals (stdenv.hostPlatform.isMusl && (haskellLib.isExecutableType componentId)) [ # These flags will make sure the resulting executable is statically linked. # If it uses other libraries it may be necessary for to add more diff --git a/builder/default.nix b/builder/default.nix index 6a029e896..98c1b977c 100644 --- a/builder/default.nix +++ b/builder/default.nix @@ -68,7 +68,7 @@ let let haskellPackages = { # For musl we can use haddock from the buildGHC - ghc = if stdenv.hostPlatform.isLinux && stdenv.targetPlatform.isMusl && !haskellLib.isNativeMusl + ghc = if stdenv.targetPlatform.isMusl then ghc.buildGHC else ghc; inherit packages hoogle; diff --git a/builder/ghc-for-component-wrapper.nix b/builder/ghc-for-component-wrapper.nix index 8afb44d76..1849e3626 100644 --- a/builder/ghc-for-component-wrapper.nix +++ b/builder/ghc-for-component-wrapper.nix @@ -23,7 +23,7 @@ let libDir = "$wrappedGhc/${configFiles.libDir}"; docDir = "$wrappedGhc/share/doc/ghc/html"; # For musl we can use haddock from the buildGHC - haddock = if stdenv.hostPlatform.isLinux && stdenv.targetPlatform.isMusl && !haskellLib.isNativeMusl + haddock = if stdenv.targetPlatform.isMusl then ghc.buildGHC else ghc; diff --git a/ci.nix b/ci.nix index 7ff047680..a2df435e4 100644 --- a/ci.nix +++ b/ci.nix @@ -64,6 +64,7 @@ nixpkgs.lib.optionalAttrs (nixpkgsName == "R2405") { ghc96 = false; ghc98 = false; + ghc910 = true; } // nixpkgs.lib.optionalAttrs (nixpkgsName == "unstable") { ghc810 = true; ghc92 = false; @@ -101,8 +102,10 @@ } // lib.optionalAttrs (system == "x86_64-linux" && nixpkgsName == "unstable" && !builtins.elem compiler-nix-name ["ghc902" "ghc928" "ghc948"]) { # Musl cross only works on linux # aarch64 cross only works on linux - inherit (lib.systems.examples) musl64 aarch64-multiplatform; - } // lib.optionalAttrs (system == "x86_64-linux" && nixpkgsName == "unstable" && builtins.elem compiler-nix-name ["ghc927" "ghc928"]) { + inherit (lib.systems.examples) musl32 musl64 aarch64-multiplatform; + } // lib.optionalAttrs (system == "x86_64-linux" && nixpkgsName == "unstable" && !builtins.elem compiler-nix-name ["ghc902" "ghc928" "ghc948"]) { + inherit (lib.systems.examples) aarch64-android-prebuilt armv7a-android-prebuilt; + } // lib.optionalAttrs (system == "x86_64-linux" && nixpkgsName == "unstable" && !builtins.elem compiler-nix-name ["ghc8107" "ghc902"]) { # TODO fix this for the compilers we build with hadrian (ghc >=9.4) inherit (lib.systems.examples) aarch64-multiplatform-musl; } // lib.optionalAttrs (system == "aarch64-linux" && nixpkgsName == "unstable" && !builtins.elem compiler-nix-name ["ghc8107" "ghc902"]) { diff --git a/compiler/ghc/default.nix b/compiler/ghc/default.nix index 1bafff3d3..18782b3be 100644 --- a/compiler/ghc/default.nix +++ b/compiler/ghc/default.nix @@ -45,9 +45,9 @@ let self = , enableDWARF ? false -, enableTerminfo ? +, enableTerminfo ? !stdenv.targetPlatform.isAndroid && # Terminfo does not work on older ghc cross arm and windows compilers - (!haskell-nix.haskellLib.isCrossTarget || !(stdenv.targetPlatform.isAarch64 || stdenv.targetPlatform.isWindows) || builtins.compareVersions ghc-version "8.10" >= 0) + (!haskell-nix.haskellLib.isCrossTarget || !(stdenv.targetPlatform.isAarch32 || stdenv.targetPlatform.isAarch64 || stdenv.targetPlatform.isWindows) || builtins.compareVersions ghc-version "8.10" >= 0) , # Wheter to build in NUMA support enableNUMA ? true @@ -62,7 +62,7 @@ let self = , # Whether to disable the large address space allocator # necessary fix for iOS: https://www.reddit.com/r/haskell/comments/4ttdz1/building_an_osxi386_to_iosarm64_cross_compiler/d5qvd67/ - disableLargeAddressSpace ? stdenv.targetPlatform.isDarwin && stdenv.targetPlatform.isAarch64 + disableLargeAddressSpace ? stdenv.targetPlatform.isDarwin && stdenv.targetPlatform.isAarch64 || stdenv.targetPlatform.isAndroid , useLdGold ? # might be better check to see if cc is clang/llvm? @@ -169,8 +169,9 @@ let WITH_TERMINFO=NO '' # musl doesn't have a system-linker. Only on x86, and on x86 we need it, as - # our elf linker for x86_64 is broken. - + lib.optionalString (targetPlatform.isAndroid || (targetPlatform.isMusl && !targetPlatform.isx86)) '' + # our elf linker for x86_64 is broken. The i686 one seems also to not exist. + # So it's really _just_ x86_64. + + lib.optionalString (targetPlatform.isAndroid || (targetPlatform.isMusl && !targetPlatform.isx86_64)) '' compiler_CONFIGURE_OPTS += --flags=-dynamic-system-linker '' # While split sections are now enabled by default in ghc 8.8 for windows, @@ -183,12 +184,14 @@ let SplitSections = NO '' + lib.optionalString (!enableLibraryProfiling) '' BUILD_PROF_LIBS = NO + '' + lib.optionalString (disableLargeAddressSpace) '' + libraries/base_CONFIGURE_OPTS += --configure-option=--with-libcharset=no ''; # `--with` flags for libraries needed for RTS linker configureFlags = [ "--datadir=$doc/share/doc/ghc" - ] ++ lib.optionals (!targetPlatform.isGhcjs) ["--with-curses-includes=${targetPackages.ncurses.dev}/include" "--with-curses-libraries=${targetPackages.ncurses.out}/lib" + ] ++ lib.optionals (!targetPlatform.isGhcjs && !targetPlatform.isAndroid) ["--with-curses-includes=${targetPackages.ncurses.dev}/include" "--with-curses-libraries=${targetPackages.ncurses.out}/lib" ] ++ lib.optionals (targetLibffi != null && !targetPlatform.isGhcjs) ["--with-system-libffi" "--with-ffi-includes=${targetLibffi.dev}/include" "--with-ffi-libraries=${targetLibffi.out}/lib" ] ++ lib.optionals (!enableIntegerSimple && !targetPlatform.isGhcjs) [ "--with-gmp-includes=${targetGmp.dev}/include" "--with-gmp-libraries=${targetGmp.out}/lib" @@ -216,23 +219,24 @@ let # https://gitlab.haskell.org/ghc/ghc/-/issues/23188 # https://github.com/haskell/cabal/issues/8882 "fp_cv_prog_ar_supports_dash_l=no" - ] ++ lib.optional (targetPlatform.isGhcjs) "--target=javascript-unknown-ghcjs"; # TODO use configurePlatforms once tripple is updated in nixpkgs + ] ++ lib.optionals (targetPlatform.isDarwin) [ + "--without-libcharset" + ] ++ lib.optional (targetPlatform.isGhcjs) "--target=javascript-unknown-ghcjs" # TODO use configurePlatforms once tripple is updated in nixpkgs + ; # Splicer will pull out correct variations - libDeps = platform: lib.optional (enableTerminfo && !targetPlatform.isGhcjs) [ targetPackages.ncurses targetPackages.ncurses.dev ] + libDeps = platform: lib.optional (enableTerminfo && !targetPlatform.isGhcjs && !targetPlatform.isAndroid) [ targetPackages.ncurses targetPackages.ncurses.dev ] ++ lib.optional (!targetPlatform.isGhcjs) targetLibffi ++ lib.optional (!enableIntegerSimple && !targetPlatform.isGhcjs) gmp ++ lib.optional (platform.libc != "glibc" && !targetPlatform.isWindows) libiconv ++ lib.optional (enableNUMA && platform.isLinux && !platform.isAarch32 && !platform.isAndroid) numactl - # Even with terminfo disabled some older ghc cross arm and windows compilers do not build unless `ncurses` is found and they seem to want the buildPlatform version - ++ lib.optional (!enableTerminfo && haskell-nix.haskellLib.isCrossTarget && (stdenv.targetPlatform.isAarch64 || stdenv.targetPlatform.isWindows) && builtins.compareVersions ghc-version "8.10" < 0) ncurses.dev ++ lib.optional enableDWARF (lib.getLib elfutils); toolsForTarget = if targetPlatform.isGhcjs then [ buildPackages.emscripten ] else if hostPlatform == buildPlatform - then [ targetPackages.stdenv.cc ] ++ lib.optionals useLLVM [llvmPackages.llvm llvmPackages.clang] + then [ targetPackages.stdenv.cc ] ++ lib.optionals useLLVM ([llvmPackages.llvm] ++ lib.optional (!targetPlatform.useAndroidPrebuilt) llvmPackages.clang) else assert targetPlatform == hostPlatform; # build != host == target [ stdenv.cc ] ++ lib.optional useLLVM buildLlvmPackages.llvm; @@ -244,7 +248,7 @@ let # for musl only; but I'd like to stay far away from the unnecessary # bindist logic as we can. It's slow, and buggy, and doesn't provide any # value for us. - installStage1 = useHadrian && (haskell-nix.haskellLib.isCrossTarget || stdenv.targetPlatform.isMusl); + installStage1 = useHadrian && (with haskell-nix.haskellLib; isCrossTarget || isNativeMusl); hadrian = let @@ -339,7 +343,14 @@ let " '*.ghc.cabal.configure.opts += --flags=-dynamic-system-linker'" # The following is required if we build on aarch64-darwin for aarch64-iOS. Otherwise older # iPhones/iPads/... won't understand the compiled code, as the compiler will emit LDSETALH - # + lib.optionalString (targetPlatform.???) "'*.rts.ghc.c.opts += -optc-mcpu=apple-a7 -optc-march=armv8-a+norcpc'" + # FIXME: we should have iOS as an argument to this derivation, and then make this, as well as + # disableLargeAddress space conditional on iOS = true. + + lib.optionalString (stdenv.targetPlatform.isDarwin && stdenv.targetPlatform.isAarch64) + " '*.*.ghc.c.opts += -optc-mcpu=apple-a7 -optc-march=armv8-a+norcpc'" + + lib.optionalString (targetPlatform.isAndroid && targetPlatform.isAarch32) + " 'stage1.*.ghc.c.opts += -optc-march=armv7-a -optc-mfloat-abi=softfp -optc-mfpu=vfpv3-d16'" + + lib.optionalString (targetPlatform.isAndroid && targetPlatform.isAarch64) + " 'stage1.*.ghc.c.opts += -optc-march=armv8-a'" # For GHC versions in the 9.x range that don't support the +native_bignum flavour transformer yet + lib.optionalString ((enableNativeBignum && !hadrianHasNativeBignumFlavour)) " --bignum=native" @@ -456,7 +467,10 @@ stdenv.mkDerivation (rec { export NIX_LDFLAGS+=" -rpath $out/lib/${targetPrefix}ghc-${ghc-version}" '' + lib.optionalString stdenv.isDarwin '' export NIX_LDFLAGS+=" -no_dtrace_dof" - '' + lib.optionalString targetPlatform.useAndroidPrebuilt '' + '' + + # we really want "+armv7-a,+soft-float,+neon" as features, but llvm will + # fail with those :facepalm: + lib.optionalString targetPlatform.useAndroidPrebuilt '' sed -i -e '5i ,("armv7a-unknown-linux-androideabi", ("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64", "cortex-a8", ""))' llvm-targets '' + lib.optionalString targetPlatform.isMusl '' echo "patching llvm-targets for musl targets..." @@ -531,7 +545,7 @@ stdenv.mkDerivation (rec { ++ lib.optional stdenv.targetPlatform.isMusl "pie" ++ lib.optional enableDWARF "fortify"; - postInstall = lib.optionalString (enableNUMA && targetPlatform.isLinux) '' + postInstall = lib.optionalString (enableNUMA && targetPlatform.isLinux && !targetPlatform.isAarch32 && !targetPlatform.isAndroid) '' # Patch rts.conf to ensure libnuma can be found for file in $(find "$out/lib" -name "rts*.conf"); do @@ -725,7 +739,7 @@ stdenv.mkDerivation (rec { --replace 'dynamic-library-dirs:' 'dynamic-library-dirs: ${libcxx}/lib' find . -name 'system*.conf*' cat mk/system-cxx-std-lib-1.0.conf - '' + lib.optionalString (installStage1 && stdenv.targetPlatform.isMusl) '' + '' + lib.optionalString (installStage1 && haskell-nix.haskellLib.isNativeMusl) '' substituteInPlace hadrian/cfg/system.config \ --replace 'cross-compiling = YES' \ 'cross-compiling = NO' @@ -775,7 +789,7 @@ stdenv.mkDerivation (rec { dontStrip = true; dontPatchELF = true; noAuditTmpdir = true; -} // lib.optionalAttrs (stdenv.buildPlatform.isDarwin || stdenv.targetPlatform.isWindows) { +} // { # ghc install on macOS wants to run `xattr -r -c` # The macOS version fails because it wants python 2. # The nix version of xattr does not support those args. @@ -815,12 +829,13 @@ stdenv.mkDerivation (rec { --replace 'dynamic-library-dirs:' 'dynamic-library-dirs: ${libcxx}/lib' find . -name 'system*.conf*' cat mk/system-cxx-std-lib-1.0.conf - '' + lib.optionalString (installStage1 && !haskell-nix.haskellLib.isCrossTarget && stdenv.targetPlatform.isMusl) '' + '' + lib.optionalString (installStage1 && haskell-nix.haskellLib.isNativeMusl) '' substituteInPlace hadrian/cfg/system.config \ --replace 'cross-compiling = YES' \ 'cross-compiling = NO' ''; buildPhase = '' + runHook preBuild ${hadrian}/bin/hadrian ${hadrianArgs} '' + lib.optionalString (installStage1 && !stdenv.targetPlatform.isGhcjs && builtins.compareVersions ghc-version "9.8" < 0) '' ${hadrian}/bin/hadrian ${hadrianArgs} stage1:lib:libiserv @@ -835,6 +850,8 @@ stdenv.mkDerivation (rec { mv $exe ${targetPrefix}$exe done popd + '' + '' + runHook postBuild ''; # Hadrian's installation only works for native compilers, and is broken for cross compilers. diff --git a/lib/call-cabal-project-to-nix.nix b/lib/call-cabal-project-to-nix.nix index d90f5716b..d8d183f2d 100644 --- a/lib/call-cabal-project-to-nix.nix +++ b/lib/call-cabal-project-to-nix.nix @@ -334,8 +334,14 @@ let echo ',("target arch","${ if pkgs.stdenv.targetPlatform.isx86_64 then "ArchX86_64" + else if pkgs.stdenv.targetPlatform.isx86 + then "ArchX86" + else if pkgs.stdenv.targetPlatform.isRiscV64 + then "ArchRISCV64" else if pkgs.stdenv.targetPlatform.isAarch64 then "ArchAArch64" + else if pkgs.stdenv.targetPlatform.isAarch32 + then "ArchAArch32" else if pkgs.stdenv.targetPlatform.isJavaScript then "ArchJavaScript" else throw "Unknown target arch ${pkgs.stdenv.targetPlatform.config}" @@ -681,8 +687,8 @@ let cabal.project.freeze chmod +w cabal.project.freeze ''} - export SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt - export GIT_SSL_CAINFO=${cacert}/etc/ssl/certs/ca-bundle.crt + export SSL_CERT_FILE=${evalPackages.cacert}/etc/ssl/certs/ca-bundle.crt + export GIT_SSL_CAINFO=${evalPackages.cacert}/etc/ssl/certs/ca-bundle.crt export CABAL_DIR=${ # This creates `.cabal` directory that is as it would have diff --git a/lib/default.nix b/lib/default.nix index 88fef4a05..2d7a0aebb 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -256,9 +256,9 @@ in { isCrossTarget = stdenv.targetPlatform != stdenv.hostPlatform && !(stdenv.hostPlatform.isLinux && stdenv.targetPlatform.isMusl && stdenv.hostPlatform.linuxArch == stdenv.targetPlatform.linuxArch); # Native musl build-host-target combo - isNativeMusl = stdenv.hostPlatform.isMusl - && stdenv.buildPlatform == stdenv.hostPlatform - && stdenv.hostPlatform == stdenv.targetPlatform; + isNativeMusl = stdenv.targetPlatform.isMusl + && stdenv.buildPlatform.linuxArch == stdenv.hostPlatform.linuxArch + && stdenv.hostPlatform.linuxArch == stdenv.targetPlatform.linuxArch; # Takes a version number, module or list of modules (for cabalProject) # and converts it to an list of project modules. This allows @@ -593,6 +593,8 @@ in { then "arm" else if hostPlatform.isAarch64 then "aarch64" + else if hostPlatform.isi686 + then "i386" else abort "Don't know which QEMU to use for hostPlatform ${hostPlatform.config}. Please provide qemuSuffix"; # How to run ldd when checking for static linking diff --git a/overlays/android.nix b/overlays/android.nix index 57720c1c5..93c1c2dde 100644 --- a/overlays/android.nix +++ b/overlays/android.nix @@ -1,4 +1,21 @@ -_final: prev: prev.lib.optionalAttrs prev.stdenv.hostPlatform.isAndroid ({ +final: prev: { + # Use android SDK version 26 + lib = prev.lib // { + systems = prev.lib.systems // { + examples = prev.lib.systems.examples // { + aarch64-android = prev.lib.systems.examples.aarch64-android // { + androidSdkVersion = "269"; + androidNdkVersion = "24"; + }; + armv7a-android-prebuilt = prev.lib.systems.examples.armv7a-android-prebuilt // { + androidSdkVersion = "26"; + androidNdkVersion = "24"; + }; + }; + }; + }; +} // prev.lib.optionalAttrs prev.stdenv.hostPlatform.isAndroid ({ + # we really only want the static one. libiconv = (prev.libiconv.override { enableStatic = true; enableShared = false; }).overrideAttrs(_: { hardeningDisable = [ "fortify" "stackprotector" "format" ]; @@ -11,18 +28,31 @@ _final: prev: prev.lib.optionalAttrs prev.stdenv.hostPlatform.isAndroid ({ ''; # my current thinking is that this is due to the android toolchain using r23, api30. }); - libffi = prev.libffi.overrideAttrs (_: { + libffi = prev.libffi.overrideAttrs ( old: { dontDisableStatic = true; + configureFlags = old.configureFlags ++ [ "--disable-shared" ]; hardeningDisable = [ "fortify" "stackprotector" "format" ]; + } // prev.lib.optionalAttrs (prev.stdenv.hostPlatform.isAarch32 || prev.stdenv.hostPlatform.isAarch64) { # see libiconv. We want to target a lower minsdk postConfigure = '' - echo "#undef HAVE_MEMFD_CREATE" >> aarch64-unknown-linux-android/fficonfig.h + echo "#undef HAVE_MEMFD_CREATE" >> ${prev.stdenv.hostPlatform.config}/fficonfig.h ''; }); - gmp6 = (prev.gmp6.override { withStatic = true; }).overrideAttrs(_: { + gmp6 = (prev.gmp6.override { withStatic = true; }).overrideAttrs(old: { hardeningDisable = [ "fortify" "stackprotector" "format" ]; + configureFlags = old.configureFlags ++ [ "--disable-shared" ]; }); + zlib = prev.zlib.override { shared = false; static = true; }; + # kernel tls (ktls) doesn't work with the android kernel. And will complain + # about lots of implicitly declared functions and undeclared identifiers, + # because the android (linux) kernel doesn't expose those. + openssl = prev.openssl.override { static = true; enableKTLS = false; }; + }) // prev.lib.optionalAttrs (prev.stdenv.targetPlatform.isAndroid && (!prev.stdenv.hostPlatform.useAndroidPrebuilt)) ({ - bionic = prev.bionic.override { enableStatic = true; }; + # we still need the shared libraries to link against on the platform. GHC + # has been neutered to not even try loading shared libs and will use dynamic ones. + # We also link iserv against the static libs, so that we have a fully static + # android (bionic/linux) iserv we can execute on glibc/linux. + bionic = prev.bionic.override { enableStatic = true; enableShared = true; }; }) diff --git a/overlays/bootstrap.nix b/overlays/bootstrap.nix index 1f3827ccd..2399c0c68 100644 --- a/overlays/bootstrap.nix +++ b/overlays/bootstrap.nix @@ -73,12 +73,14 @@ in { onMusl = final.lib.optionals final.stdenv.targetPlatform.isMusl; onWindows = final.lib.optionals final.stdenv.targetPlatform.isWindows; onWindowsOrMusl = final.lib.optionals (final.stdenv.targetPlatform.isWindows || final.stdenv.targetPlatform.isMusl); + onAarch32 = final.lib.optionals final.stdenv.targetPlatform.isAarch32; onAarch64 = final.lib.optionals final.stdenv.targetPlatform.isAarch64; onAarch64Musl = final.lib.optionals (final.stdenv.targetPlatform.isAarch64 && final.stdenv.targetPlatform.isMusl); onAndroid = final.lib.optionals final.stdenv.targetPlatform.isAndroid; onNative = final.lib.optionals (final.stdenv.buildPlatform == final.stdenv.targetPlatform); onCross = final.lib.optionals (final.stdenv.targetPlatform != final.stdenv.hostPlatform); onGhcjs = final.lib.optionals final.stdenv.targetPlatform.isGhcjs; + on32bit = final.lib.optionals final.stdenv.targetPlatform.is32bit; # Try to avoid reordering the patches unless a patch is added or changed that # will be applied to most versions of the GHC anyway (reordering the patches # results in rebuilds of GHC and reduces sharing in /nix/store). @@ -93,8 +95,8 @@ in { ++ onDarwin (until "9.0.2" ./patches/ghc/ghc-8.10-darwin-gcc-version-fix.patch) # See https://github.com/input-output-hk/haskell.nix/issues/1027 + ++ onAarch32 (until "9.2" ./patches/ghc/ghc-8.10-3434-armv7a.patch) ++ onAarch64 (until "9.2" ./patches/ghc/ghc-8.10-3434.patch) - ++ onAarch64 (fromUntil "9.2.1" "9.4" ./patches/ghc/ghc-9.2-3434.patch) ++ until "9.4" ./patches/ghc/ghc-acrt-iob-func.patch ++ until "9.2" ./patches/ghc/ghc-mprotect-nonzero-len.patch @@ -179,8 +181,11 @@ in { ++ onAndroid (until "9.0" ./patches/ghc/stack-protector-symbols.patch) ++ onAndroid (until "9.0" ./patches/ghc/libraries-prim-os-android.patch) ++ onAndroid (until "9.0" ./patches/ghc/ghc-rts-linker-condbr.patch) - ++ onAndroid (until "9.0" ./patches/ghc/ghc-8.10.7-linker-weak-and-common.patch) - ++ onAndroid (until "9.0" ./patches/ghc/libc-memory-symbols.patch) + # due to mmap-next renaming we need different ones for aarch64 and aarch32 m( + ++ onAndroid (onAarch32 (until "9.0" ./patches/ghc/ghc-8.10.7-linker-weak-and-common-armv7a.patch)) + ++ onAndroid (onAarch64 (until "9.0" ./patches/ghc/ghc-8.10.7-linker-weak-and-common.patch)) + ++ onAndroid (onAarch32 (until "9.0" ./patches/ghc/libc-memory-symbols-armv7a.patch)) + ++ onAndroid (onAarch64 (until "9.0" ./patches/ghc/libc-memory-symbols.patch)) ++ onAndroid (until "9.0" ./patches/ghc/android-base-needs-iconv.patch) ++ onCross (until "9.4" ./patches/ghc/ghc-make-stage-1-lib-ghc.patch) ++ onAarch64 (until "9.0" ./patches/ghc/ghc-8.10-better-symbol-addr-debug.patch) @@ -200,6 +205,7 @@ in { ++ onWindows (fromUntil "9.8" "9.8.2" ./patches/ghc/ghc-9.6-fix-code-symbol-jumps.patch) # this one is to allow linking extra symbols from iserv. # ++ fromUntil "9.6.1" "9.10" ./patches/ghc/iserv-syms.patch + ++ on32bit (fromUntil "9.6" "9.6.5" ./patches/ghc/ghc-9.6-genapply-cross-arch.patch) # Fix the bad fixups: https://gitlab.haskell.org/ghc/ghc/-/commit/2adc050857a9c1b992040fbfd55fbe65b2851b19 ++ onAarch64 (fromUntil "9.6" "9.6.4" ./patches/ghc/2adc050857a9c1b992040fbfd55fbe65b2851b19.patch) @@ -212,10 +218,28 @@ in { # This one will lead to segv's on darwin, when calling `strlen` during lookupStrHashTable. `strlen` ends up being called with 0x0. # This patch will allow adding additional symbols to iserv, instead of having to patch them into GHC all the time. ++ final.lib.optionals ( - final.stdenv.targetPlatform != final.stdenv.hostPlatform - && (final.stdenv.targetPlatform.isAndroid || final.stdenv.targetPlatform.isLinux) + (final.stdenv.targetPlatform.isAndroid || final.stdenv.targetPlatform.isLinux) && (final.stdenv.targetPlatform.isAarch64 || final.stdenv.targetPlatform.is32bit)) (fromUntil "9.6.1" "9.11" ./patches/ghc/iserv-syms.patch) + ++ onAndroid (until "9.0" ./patches/ghc/ghc-8.10.7-weak-symbols-2.patch) + ++ onDarwin (onAarch64 (until "9.0" ./patches/ghc/ghc-8.10.7-rts-aarch64-darwin.patch)) + ++ onAndroid (onAarch32 (until "9.2" ./patches/ghc/ghc-8.10-android.patch)) + ++ onAndroid (onAarch32 (until "9.2" ./patches/ghc/ghc-8.10.7-android-bionic-symbols.patch)) + ++ onAndroid (onAarch32 (until "9.2" ./patches/ghc/ghc-8.10.7-bionic-libc.patch)) + ++ onAndroid (onAarch32 (until "9.2" ./patches/ghc/ghc-8.10.7-cross-dont-build-stage2-tools.patch)) + ++ onAndroid (fromUntil "9.0" "9.10" ./patches/ghc/ghc-9.6-hadrian-android.patch) + ++ onAndroid (from "9.10" ./patches/ghc/ghc-9.10-hadrian-android.patch) + ++ onAndroid (fromUntil "9.10" "9.11" ./patches/ghc/ghc-9.10-relax-llvm-max-version.patch) + ++ onAndroid (from "9.12" ./patches/ghc/ghc-define-undefined-elf-st-visibility.patch) + ++ onMusl (onAarch64 (fromUntil "9.4" "9.8" ./patches/ghc/ghc-9.6-hadrian-strip-cmd.patch)) + ++ onMusl (onAarch64 (fromUntil "9.8" "9.10" ./patches/ghc/ghc-9.8-hadrian-strip-cmd.patch)) + ++ onMusl (onAarch64 (fromUntil "9.10" "9.12" ./patches/ghc/ghc-9.10-hadrian-strip-cmd.patch)) + ++ on32bit (fromUntil "9.0" "9.4.8" ./patches/ghc/ghc-9.6-32bit-cmm.patch) + ++ on32bit (fromUntil "9.6" "9.6.4" ./patches/ghc/ghc-9.6-32bit-cmm.patch) + ++ onAndroid (fromUntil "9.6.3" "9.8.3" ./patches/ghc/ghc-9.6-iog.patch) + ++ onAndroid (fromUntil "9.8.3" "9.10" ./patches/ghc/ghc-9.8.3-iog.patch) + ++ onAndroid (fromUntil "9.6" "9.9" ./patches/ghc/ghc-9.6-debug-secno.patch) + ++ onAndroid (from "9.8.1" ./patches/ghc/ghc-9.8-android-convert-os.patch) # Allow loading static external plugins into cross compilers ++ onCross (fromUntil "9.6.1" "9.11" ./patches/ghc/5c80a27488acfe3610ddfcb99a1e961002e386d0.patch) @@ -250,8 +274,12 @@ in { ++ fromUntil "9.8" "9.9" ./patches/ghc/docs-sphinx-7-ghc98.patch # These two patches are needed for libblst, which has now hidden symbols, which the linker doesn't know how to deal with. - ++ until "9.0" ./patches/ghc/ghc-8.10-0006-Adds-support-for-Hidden-symbols.patch - ++ until "9.0" ./patches/ghc/ghc-8.10-0006-Adds-support-for-Hidden-symbols-2.patch + ++ ( + if final.stdenv.targetPlatform.isAndroid + then until "9.0" ./patches/ghc/ghc-8.10-0006-Adds-support-for-Hidden-symbols-android.patch + else until "9.0" ./patches/ghc/ghc-8.10-0006-Adds-support-for-Hidden-symbols.patch + ++ until "9.0" ./patches/ghc/ghc-8.10-0006-Adds-support-for-Hidden-symbols-2.patch + ) ++ onWindowsOrMusl (fromUntil "9.6" "9.7" ./patches/ghc/ghc-9.6-0006-Adds-support-for-Hidden-symbols.patch) ++ onWindowsOrMusl (fromUntil "9.8.2" "9.11" ./patches/ghc/ghc-9.6-0006-Adds-support-for-Hidden-symbols.patch) ++ onWindowsOrMusl (fromUntil "9.6" "9.7" ./patches/ghc/ghc-9.6-0006-Adds-support-for-Hidden-symbols-2.patch) diff --git a/overlays/linux-cross.nix b/overlays/linux-cross.nix index 04b98153b..1fc2c8864 100644 --- a/overlays/linux-cross.nix +++ b/overlays/linux-cross.nix @@ -13,9 +13,25 @@ , ... }: let + # For 32bit android, we need to pass -no-pie, as we otherwise + # get -pie injected into the linker flags. We don't want that. + # If we target 32bit android, we need remote-iserv to be runnable + # in a 32bit linux (via qemu-arm user mode emulation). If we have + # -pie enabled, it will produce a static-pie executable, which + # seems a lot like what we want but will crash on launch. It appears + # the the __stack_chk_guard lookups go through some lookup table, and + # while the relocations for the lookup table are correct, the __stack_chk_guard + # address isn't properly relocated. This could also be because libc isn't + # supposed to be staticlly linked really. However because we are lacking + # the loader for arm on linux, we can't used dynamically linked executables + # until one in /system/bin/linker is provided. + # + # We also need to run armv7a-android in unshare --user --pid --fork, to + # ensure that we get a low pid < 65535 for android (If we run outside) + # of nix build envs. # we want this to hold only for arm (32 and 64bit) for now. - isLinuxCross = haskellLib.isCrossHost && hostPlatform.isLinux && (hostPlatform.isAarch32 || hostPlatform.isAarch64); + isLinuxCross = haskellLib.isCrossHost && hostPlatform.isLinux && (hostPlatform.isAarch32 || hostPlatform.isAarch64 || hostPlatform.isi686); qemuIservWrapperScript = enableProfiling: let interpreter = @@ -24,6 +40,7 @@ let else iserv-proxy-interpreter; in writeShellScriptBin ("iserv-wrapper" + lib.optionalString enableProfiling "-prof") '' + #!${stdenv.shell} set -euo pipefail ISERV_ARGS=''${ISERV_ARGS:-} PROXY_ARGS=''${PROXY_ARGS:-} @@ -32,10 +49,14 @@ let PORT=$((5000 + $RANDOM % 5000)) (>&2 echo "---> Starting ${interpreter.exeName} on port $PORT") ${qemu}/bin/qemu-${qemuSuffix} ${interpreter.override - (lib.optionalAttrs hostPlatform.isAndroid { + ({ + patches = lib.optional (builtins.compareVersions interpreter.version "9.0" > 0 && hostPlatform.isAndroid && hostPlatform.isAarch32) ./patches/iserv-proxy-interpreter-9.3-android32.patch + ++ lib.optional (builtins.compareVersions interpreter.version "9.0" > 0 && hostPlatform.isAndroid && hostPlatform.isAarch64) ./patches/iserv-proxy-interpreter-9.3-android.patch + ; + } // lib.optionalAttrs hostPlatform.isAndroid { setupBuildFlags = ["--ghc-option=-optl-static" ] ++ lib.optional hostPlatform.isAarch32 "--ghc-option=-optl-no-pie"; enableDebugRTS = true; - })}/bin/${interpreter.exeName} tmp $PORT $ISERV_ARGS & + })}/bin/${interpreter.exeName} tmp $PORT $ISERV_ARGS & (>&2 echo "---| ${interpreter.exeName} should have started on $PORT") RISERV_PID="$!" ${iserv-proxy}/bin/iserv-proxy $@ 127.0.0.1 "$PORT" $PROXY_ARGS @@ -43,7 +64,7 @@ let kill $RISERV_PID ''; qemuIservWrapper = symlinkJoin { name = "iserv-wrapper"; paths = [ (qemuIservWrapperScript false) (qemuIservWrapperScript true) ]; }; - configureFlags = lib.optional hostPlatform.isAarch32 "--disable-split-sections"; + configureFlags = lib.optional (hostPlatform.isAarch32 || hostPlatform.isAndroid) "--disable-split-sections"; setupBuildFlags = map (opt: "--ghc-option=" + opt) ((lib.optionals isLinuxCross [ "-fexternal-interpreter" "-pgmi" "${qemuIservWrapper}/bin/iserv-wrapper" diff --git a/overlays/mingw_w64.nix b/overlays/mingw_w64.nix index 7ac92d0c1..a309a8d10 100644 --- a/overlays/mingw_w64.nix +++ b/overlays/mingw_w64.nix @@ -37,7 +37,11 @@ let PORT=$((5000 + $RANDOM % 5000)) (>&2 echo "---> Starting ${interpreter.exeName} on port $PORT") REMOTE_ISERV=$(mktemp -d) - ln -s ${interpreter.override { enableDebugRTS = true; setupBuildFlags = ["--ghc-option=-optl-Wl,--disable-dynamicbase,--disable-high-entropy-va,--image-base=0x400000" ];}}/bin/* $REMOTE_ISERV + ln -s ${interpreter.override + { + enableDebugRTS = true; + setupBuildFlags = ["--ghc-option=-optl-Wl,--disable-dynamicbase,--disable-high-entropy-va,--image-base=0x400000" ]; + }}/bin/* $REMOTE_ISERV # See coment in comp-builder.nix for where this comes from and why it's here # TODO use `LINK_DLL_FOLDERS` here once it is in all the nixpkgs we want to support. for p in $pkgsHostTargetAsString; do diff --git a/overlays/patches/ghc/2adc050857a9c1b992040fbfd55fbe65b2851b19.patch b/overlays/patches/ghc/2adc050857a9c1b992040fbfd55fbe65b2851b19.patch index c43e4aeff..427e976b2 100644 --- a/overlays/patches/ghc/2adc050857a9c1b992040fbfd55fbe65b2851b19.patch +++ b/overlays/patches/ghc/2adc050857a9c1b992040fbfd55fbe65b2851b19.patch @@ -26,7 +26,7 @@ index 1d489178673..a251370bfaf 100644 +++ b/compiler/GHC/CmmToAsm.hs @@ -655,13 +655,14 @@ cmmNativeGen logger ncgImpl us fileIds dbgMap cmm count text "cfg not in lockstep") () - + ---- sequence blocks - let sequenced :: [NatCmmDecl statics instr] - sequenced = @@ -43,20 +43,20 @@ index 1d489178673..a251370bfaf 100644 + shorted + + -- massert (checkLayout shorted sequenced) - + let branchOpt :: [NatCmmDecl statics instr] branchOpt = @@ -684,7 +685,7 @@ cmmNativeGen logger ncgImpl us fileIds dbgMap cmm count addUnwind acc proc = acc `mapUnion` computeUnwinding config ncgImpl proc - + - return ( usAlloc + return ( us_seq , fileIds' , branchOpt , lastMinuteImports ++ imports @@ -704,10 +705,10 @@ maybeDumpCfg logger (Just cfg) msg proc_name - + -- | Make sure all blocks we want the layout algorithm to place have been placed. checkLayout :: [NatCmmDecl statics instr] -> [NatCmmDecl statics instr] - -> [NatCmmDecl statics instr] @@ -94,7 +94,7 @@ index b77aa73e52b..2a1fa03b1bc 100644 , generateJumpTableForInstr + , makeFarBranches ) - + where @@ -43,9 +44,11 @@ import GHC.Cmm.Utils import GHC.Cmm.Switch @@ -105,7 +105,7 @@ index b77aa73e52b..2a1fa03b1bc 100644 import GHC.Types.Tickish ( GenTickish(..) ) import GHC.Types.SrcLoc ( srcSpanFile, srcSpanStartLine, srcSpanStartCol ) +import GHC.Types.Unique.Supply - + -- The rest: import GHC.Data.OrdList @@ -61,6 +64,9 @@ import GHC.Data.FastString @@ -115,13 +115,13 @@ index b77aa73e52b..2a1fa03b1bc 100644 +import GHC.Utils.Monad (mapAccumLM) + +import GHC.Cmm.Dataflow.Collections - + -- Note [General layout of an NCG] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -161,15 +167,17 @@ basicBlockCodeGen block = do let (top,other_blocks,statics) = foldrOL mkBlocks ([],[],[]) instrs - + - mkBlocks (NEWBLOCK id) (instrs,blocks,statics) - = ([], BasicBlock id instrs : blocks, statics) - mkBlocks (LDATA sec dat) (instrs,blocks,statics) @@ -129,7 +129,7 @@ index b77aa73e52b..2a1fa03b1bc 100644 - mkBlocks instr (instrs,blocks,statics) - = (instr:instrs, blocks, statics) return (BasicBlock id top : other_blocks, statics) - + - +mkBlocks :: Instr + -> ([Instr], [GenBasicBlock Instr], [GenCmmDecl RawCmmStatics h g]) @@ -144,7 +144,7 @@ index b77aa73e52b..2a1fa03b1bc 100644 -- | Utilities ann :: SDoc -> Instr -> Instr @@ -1217,6 +1225,7 @@ assignReg_FltCode = assignReg_IntCode - + -- ----------------------------------------------------------------------------- -- Jumps + @@ -154,7 +154,7 @@ index b77aa73e52b..2a1fa03b1bc 100644 @@ -1302,6 +1311,22 @@ genCondJump bid expr = do _ -> pprPanic "AArch64.genCondJump:case mop: " (text $ show expr) _ -> pprPanic "AArch64.genCondJump: " (text $ show expr) - + +-- A conditional jump with at least +/-128M jump range +genCondFarJump :: MonadUnique m => Cond -> Target -> m InstrBlock +genCondFarJump cond far_target = do @@ -171,7 +171,7 @@ index b77aa73e52b..2a1fa03b1bc 100644 + , NEWBLOCK jmp_lbl_id + , B far_target + , NEWBLOCK skip_lbl_id] - + genCondBranch :: BlockId -- the source of the jump @@ -1816,3 +1841,163 @@ genCCall target dest_regs arg_regs bid = do @@ -344,12 +344,12 @@ index 687daccfda1..7efbb9c70bf 100644 +++ b/compiler/GHC/CmmToAsm/AArch64/Cond.hs @@ -1,6 +1,6 @@ module GHC.CmmToAsm.AArch64.Cond where - + -import GHC.Prelude +import GHC.Prelude hiding (EQ) - + -- https://developer.arm.com/documentation/den0024/a/the-a64-instruction-set/data-processing-instructions/conditional-instructions - + @@ -60,7 +60,13 @@ data Cond | UOGE -- b.pl | UOGT -- b.hi @@ -374,8 +374,8 @@ index d8dd1a4dc0c..1fb8193612f 100644 | TLabel CLabel | TReg Reg + deriving (Eq, Ord) - - + + -- Extension diff --git a/compiler/GHC/CmmToAsm/AArch64/Ppr.hs b/compiler/GHC/CmmToAsm/AArch64/Ppr.hs index fd56d37cd39..c672c342376 100644 @@ -384,12 +384,12 @@ index fd56d37cd39..c672c342376 100644 @@ -1,7 +1,7 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} {-# LANGUAGE CPP #-} - + -module GHC.CmmToAsm.AArch64.Ppr (pprNatCmmDecl, pprInstr) where +module GHC.CmmToAsm.AArch64.Ppr (pprNatCmmDecl, pprInstr, pprBasicBlock) where - + import GHC.Prelude hiding (EQ) - + @@ -353,7 +353,10 @@ pprInstr platform instr = case instr of -> line (text "\t.loc" <+> int file <+> int line' <+> int col) DELTA d -> dualDoc (asmComment $ text "\tdelta = " <> int d) empty @@ -400,17 +400,17 @@ index fd56d37cd39..c672c342376 100644 + -- print it for debugging purposes. + line (text "BLOCK " <> pprAsmLabel platform (blockLbl blockid)) LDATA _ _ -> panic "pprInstr: LDATA" - + -- Pseudo Instructions ------------------------------------------------------- @@ -567,7 +570,7 @@ pprCond c = case c of UGE -> text "hs" -- Carry set/unsigned higher or same ; Greater than or equal, or unordered UGT -> text "hi" -- Unsigned higher ; Greater than, or unordered - + - NEVER -> text "nv" -- Never + -- NEVER -> text "nv" -- Never VS -> text "vs" -- Overflow ; Unordered (at least one NaN operand) VC -> text "vc" -- No overflow ; Not unordered - + diff --git a/compiler/GHC/CmmToAsm/BlockLayout.hs b/compiler/GHC/CmmToAsm/BlockLayout.hs index fa0929348ce..e2096c90209 100644 --- a/compiler/GHC/CmmToAsm/BlockLayout.hs @@ -420,7 +420,7 @@ index fa0929348ce..e2096c90209 100644 import Control.Monad (foldM, unless) import GHC.Data.UnionFind +import GHC.Types.Unique.Supply (UniqSM) - + {- Note [CFG based code layout] @@ -794,29 +795,32 @@ sequenceTop @@ -476,7 +476,7 @@ index fa0929348ce..e2096c90209 100644 + far_blocks <- (ncgMakeFarBranches ncgImpl) platform info seq_blocks + pure $ CmmProc info lbl live $ ListGraph far_blocks + - + -- The old algorithm: -- It is very simple (and stupid): We make a graph out of diff --git a/compiler/GHC/CmmToAsm/Monad.hs b/compiler/GHC/CmmToAsm/Monad.hs @@ -508,7 +508,7 @@ index 3fedcc1fc40..8682d1db9d8 100644 +++ b/compiler/GHC/CmmToAsm/PPC/Instr.hs @@ -688,12 +688,13 @@ takeRegRegMoveInstr _ = Nothing -- big, we have to work around this limitation. - + makeFarBranches - :: LabelMap RawCmmStatics + :: Platform @@ -538,6 +538,6 @@ index a82674afe8f..a13fa2e4656 100644 , extractUnwindPoints = X86.extractUnwindPoints , invertCondBranches = X86.invertCondBranches } --- +-- GitLab diff --git a/overlays/patches/ghc/ghc-8.10-0006-Adds-support-for-Hidden-symbols-android.patch b/overlays/patches/ghc/ghc-8.10-0006-Adds-support-for-Hidden-symbols-android.patch new file mode 100644 index 000000000..69bba7d9c --- /dev/null +++ b/overlays/patches/ghc/ghc-8.10-0006-Adds-support-for-Hidden-symbols-android.patch @@ -0,0 +1,233 @@ +diff --git a/rts/Linker.c b/rts/Linker.c +index 3428a010da..6eb43be959 100644 +--- a/rts/Linker.c ++++ b/rts/Linker.c +@@ -267,9 +267,12 @@ int ghciInsertSymbolTable( + HashTable *table, + const SymbolName* key, + SymbolAddr* data, +- HsBool weak, ++ int flags, + ObjectCode *owner) + { ++ HsBool weak = flags & 1; ++ HsBool hidden = flags & 2; ++ + RtsSymbolInfo *pinfo = lookupStrHashTable(table, key); + if (!pinfo) /* new entry */ + { +@@ -277,6 +280,7 @@ int ghciInsertSymbolTable( + pinfo->value = data; + pinfo->owner = owner; + pinfo->weak = weak; ++ pinfo->hidden = hidden; + insertStrHashTable(table, key, pinfo); + return 1; + } +@@ -340,11 +344,22 @@ int ghciInsertSymbolTable( + call this function again to trigger the duplicate error. */ + return 1; + } ++ else if(pinfo->hidden && !hidden) ++ { ++ /* The existing symbol is hidden, let's replace it */ ++ pinfo->value = data; ++ pinfo->owner = owner; ++ pinfo->weak = weak; + ++ pinfo->hidden = hidden; ++ return 1; ++ } + pathchar* archiveName = NULL; + debugBelch( + "GHC runtime linker: fatal error: I found a duplicate definition for symbol\n" + " %s\n" ++ " new symbol is hidden: %d\n" ++ " old symbol is hidden: %d\n" + "whilst processing object file\n" + " %" PATH_FMT "\n" + "The symbol was previously defined in\n" +@@ -355,6 +370,8 @@ int ghciInsertSymbolTable( + " * An incorrect `package.conf' entry, causing some object to be\n" + " loaded twice.\n", + (char*)key, ++ hidden ? 1 : 0, ++ pinfo->hidden ? 1 : 0, + obj_name, + pinfo->owner == NULL ? WSTR("(GHCi built-in symbols)") : + pinfo->owner->archiveMemberName ? archiveName = mkPath(pinfo->owner->archiveMemberName) +@@ -451,7 +468,7 @@ initLinker_ (int retain_cafs) + for (sym = rtsSyms; sym->lbl != NULL; sym++) { + if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"), + symhash, sym->lbl, sym->addr, +- sym->weak, NULL)) { ++ sym->weak | (HS_BOOL_FALSE << 1), NULL)) { + barf("ghciInsertSymbolTable failed"); + } + IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr)); +@@ -463,7 +480,7 @@ initLinker_ (int retain_cafs) + use an arbitrary (hopefully unique) address here. + */ + if (! ghciInsertSymbolTable(WSTR("(GHCi special symbols)"), +- symhash, "__dso_handle", (void *)0x12345687, HS_BOOL_FALSE, NULL)) { ++ symhash, "__dso_handle", (void *)0x12345687, HS_BOOL_FALSE | (HS_BOOL_FALSE << 1), NULL)) { + barf("ghciInsertSymbolTable failed"); + } + +@@ -471,7 +488,7 @@ initLinker_ (int retain_cafs) + if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"), symhash, + MAYBE_LEADING_UNDERSCORE_STR("newCAF"), + retain_cafs ? newRetainedCAF : newGCdCAF, +- HS_BOOL_FALSE, NULL)) { ++ HS_BOOL_FALSE | (HS_BOOL_FALSE << 1), NULL)) { + barf("ghciInsertSymbolTable failed"); + } + +@@ -844,8 +861,8 @@ HsBool removeLibrarySearchPath(HsPtr dll_path_index) + */ + HsInt insertSymbol(pathchar* obj_name, SymbolName* key, SymbolAddr* data) + { +- return ghciInsertSymbolTable(obj_name, symhash, key, data, HS_BOOL_FALSE, +- NULL); ++ return ghciInsertSymbolTable(obj_name, symhash, key, data, ++ HS_BOOL_FALSE | (HS_BOOL_FALSE << 1), NULL); + } + + /* ----------------------------------------------------------------------------- +@@ -1696,7 +1713,8 @@ int ocTryLoad (ObjectCode* oc) { + if ( symbol.name + && !ghciInsertSymbolTable(oc->fileName, symhash, symbol.name, + symbol.addr, +- isSymbolWeak(oc, symbol.name), oc)) { ++ isSymbolWeak(oc, symbol.name) | (HS_BOOL_FALSE << 1), ++ oc)) { + return 0; + } + } +diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h +index a846bf5ca7..acba66828b 100644 +--- a/rts/LinkerInternals.h ++++ b/rts/LinkerInternals.h +@@ -310,6 +310,7 @@ typedef struct _RtsSymbolInfo { + SymbolAddr* value; + ObjectCode *owner; + HsBool weak; ++ HsBool hidden; + } RtsSymbolInfo; + + void exitLinker( void ); +@@ -337,7 +338,7 @@ int ghciInsertSymbolTable( + HashTable *table, + const SymbolName* key, + SymbolAddr* data, +- HsBool weak, ++ int flags, + ObjectCode *owner); + + /* Lock-free version of lookupSymbol. When 'dependent' is not NULL, adds it as a +diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c +index c3f9110509..5bf7f00f31 100644 +--- a/rts/linker/Elf.c ++++ b/rts/linker/Elf.c +@@ -1013,7 +1013,9 @@ ocGetNames_ELF ( ObjectCode* oc ) + setWeakSymbol(oc, nm); + } + if (!ghciInsertSymbolTable(oc->fileName, symhash, +- nm, symbol->addr, isWeak, oc)) { ++ nm, symbol->addr, ++ isWeak | ((ELF_ST_VISIBILITY(symbol->elf_sym->st_other) == STV_HIDDEN) << 1), ++ oc)) { + goto fail; + } + oc->symbols[curSymbol++].name = nm; +diff --git a/rts/linker/ElfTypes.h b/rts/linker/ElfTypes.h +index e5333d71a7..0a8e44a076 100644 +--- a/rts/linker/ElfTypes.h ++++ b/rts/linker/ElfTypes.h +@@ -32,6 +32,9 @@ + #define Elf_Sym Elf64_Sym + #define Elf_Rel Elf64_Rel + #define Elf_Rela Elf64_Rela ++#if !defined(ELF_ST_VISIBILITY) ++#define ELF_ST_VISIBILITY ELF64_ST_VISIBILITY ++#endif + #if !defined(ELF_ST_TYPE) + #define ELF_ST_TYPE ELF64_ST_TYPE + #endif +@@ -56,6 +59,9 @@ + #define Elf_Sym Elf32_Sym + #define Elf_Rel Elf32_Rel + #define Elf_Rela Elf32_Rela ++#if !defined(ELF_ST_VISIBILITY) ++#define ELF_ST_VISIBILITY ELF32_ST_VISIBILITY ++#endif /* ELF_ST_VISIBILITY */ + #if !defined(ELF_ST_TYPE) + #define ELF_ST_TYPE ELF32_ST_TYPE + #endif /* ELF_ST_TYPE */ +diff --git a/rts/linker/MachO.c b/rts/linker/MachO.c +index 00b0dce04c..d63369972d 100644 +--- a/rts/linker/MachO.c ++++ b/rts/linker/MachO.c +@@ -1336,7 +1336,7 @@ ocGetNames_MachO(ObjectCode* oc) + , symhash + , nm + , addr +- , HS_BOOL_FALSE ++ , HS_BOOL_FALSE | (HS_BOOL_FALSE << 1) + , oc); + + oc->symbols[curSymbol].name = nm; +@@ -1376,7 +1376,7 @@ ocGetNames_MachO(ObjectCode* oc) + + IF_DEBUG(linker, debugBelch("ocGetNames_MachO: inserting common symbol: %s\n", nm)); + ghciInsertSymbolTable(oc->fileName, symhash, nm, +- (void*)commonCounter, HS_BOOL_FALSE, oc); ++ (void*)commonCounter, HS_BOOL_FALSE | (HS_BOOL_FALSE << 1), oc); + oc->symbols[curSymbol].name = nm; + oc->symbols[curSymbol].addr = oc->info->macho_symbols[i].addr; + curSymbol++; +diff --git a/rts/linker/PEi386.c b/rts/linker/PEi386.c +index c73d858d52..74b7fd1009 100644 +--- a/rts/linker/PEi386.c ++++ b/rts/linker/PEi386.c +@@ -292,7 +292,7 @@ const void* __rts_iob_func = (void*)&__acrt_iob_func; + void initLinker_PEi386() + { + if (!ghciInsertSymbolTable(WSTR("(GHCi/Ld special symbols)"), +- symhash, "__image_base__", __image_base, HS_BOOL_TRUE, NULL)) { ++ symhash, "__image_base__", __image_base, HS_BOOL_TRUE | (HS_BOOL_FALSE << 1), NULL)) { + barf("ghciInsertSymbolTable failed"); + } + +@@ -1533,7 +1533,7 @@ ocGetNames_PEi386 ( ObjectCode* oc ) + sname = strdup (sname); + addr = strdup (addr); + if (!ghciInsertSymbolTable(oc->fileName, symhash, sname, +- addr, false, oc)) { ++ addr, HS_BOOL_FALSE | (HS_BOOL_FALSE << 1), oc)) { + releaseOcInfo (oc); + stgFree (oc->image); + oc->image = NULL; +@@ -1751,7 +1751,9 @@ ocGetNames_PEi386 ( ObjectCode* oc ) + stgFree(tmp); + sname = strdup (sname); + if (!ghciInsertSymbolTable(oc->fileName, symhash, sname, +- addr, false, oc)) ++ addr, ++ HS_BOOL_FALSE | ((secNumber == IMAGE_SYM_UNDEFINED) << 1), ++ oc)) + return false; + + break; +@@ -1768,9 +1770,9 @@ ocGetNames_PEi386 ( ObjectCode* oc ) + if (isWeak) { + setWeakSymbol(oc, sname); + } +- + if (! ghciInsertSymbolTable(oc->fileName, symhash, sname, addr, +- isWeak, oc)) ++ isWeak | ((secNumber == IMAGE_SYM_UNDEFINED) << 1), ++ oc)) + return false; + } else { + /* We're skipping the symbol, but if we ever load this diff --git a/overlays/patches/ghc/ghc-8.10-3434-armv7a.patch b/overlays/patches/ghc/ghc-8.10-3434-armv7a.patch new file mode 100644 index 000000000..6f1eb66ad --- /dev/null +++ b/overlays/patches/ghc/ghc-8.10-3434-armv7a.patch @@ -0,0 +1,68 @@ +diff --git a/libraries/ghc-prim/ghc-prim.cabal b/libraries/ghc-prim/ghc-prim.cabal +index c633124..2bd51c0 100644 +--- a/libraries/ghc-prim/ghc-prim.cabal ++++ b/libraries/ghc-prim/ghc-prim.cabal +@@ -70,7 +70,7 @@ Library + if os(linux) + -- we need libm, but for musl and other's we might need libc, as libm + -- is just an empty shell. +- extra-libraries: c, m ++ extra-libraries: c, m + + c-sources: + cbits/atomic.c +diff --git a/rts/RtsSymbols.c b/rts/RtsSymbols.c +index 9ca696c..b4a85e5 100644 +--- a/rts/RtsSymbols.c ++++ b/rts/RtsSymbols.c +@@ -1000,6 +1000,18 @@ + #define RTS_LIBGCC_SYMBOLS + #endif + ++ ++#if !defined(DYNAMIC) && defined(linux_HOST_OS) ++// we need these for static musl builds. However when ++// linking shared objects (DLLs) this will fail, hence ++// we do not include them when building with -DDYNAMIC ++#define RTS_LINKER_SYMBOLS \ ++ SymI_NeedsProto(__fini_array_start) \ ++ SymI_NeedsProto(__fini_array_end) ++#else ++#define RTS_LINKER_SYMBOLS ++#endif ++ + /* entirely bogus claims about types of these symbols */ + #define SymI_NeedsProto(vvv) extern void vvv(void); + #define SymI_NeedsDataProto(vvv) extern StgWord vvv[]; +@@ -1028,6 +1040,7 @@ RTS_DARWIN_ONLY_SYMBOLS + RTS_OPENBSD_ONLY_SYMBOLS + RTS_LIBGCC_SYMBOLS + RTS_LIBFFI_SYMBOLS ++RTS_LINKER_SYMBOLS + #undef SymI_NeedsProto + #undef SymI_NeedsDataProto + #undef SymI_HasProto +@@ -1068,6 +1081,8 @@ RTS_LIBFFI_SYMBOLS + #define SymI_HasProto_deprecated(vvv) \ + { #vvv, (void*)0xBAADF00D, true }, + ++void *RTS_DYNAMIC = NULL; ++ + RtsSymbolVal rtsSyms[] = { + RTS_SYMBOLS + RTS_RET_SYMBOLS +@@ -1078,6 +1093,7 @@ RtsSymbolVal rtsSyms[] = { + RTS_OPENBSD_ONLY_SYMBOLS + RTS_LIBGCC_SYMBOLS + RTS_LIBFFI_SYMBOLS ++ RTS_LINKER_SYMBOLS + SymI_HasDataProto(nonmoving_write_barrier_enabled) + #if defined(darwin_HOST_OS) && defined(i386_HOST_ARCH) + // dyld stub code contains references to this, +@@ -1085,5 +1101,6 @@ RtsSymbolVal rtsSyms[] = { + // lazy pointers as nonlazy. + { "dyld_stub_binding_helper", (void*)0xDEADBEEF, false }, + #endif ++ { "_DYNAMIC", (void*)(&RTS_DYNAMIC), false }, + { 0, 0, false } /* sentinel */ + }; diff --git a/overlays/patches/ghc/ghc-8.10-android.patch b/overlays/patches/ghc/ghc-8.10-android.patch new file mode 100644 index 000000000..fd499548d --- /dev/null +++ b/overlays/patches/ghc/ghc-8.10-android.patch @@ -0,0 +1,259 @@ +diff --git a/rts/Linker.c b/rts/Linker.c +index cfae6fc..b766ce0 100644 +--- a/rts/Linker.c ++++ b/rts/Linker.c +@@ -350,6 +350,37 @@ int ghciInsertSymbolTable( + || strncmp(key, "calloc", 6) == 0 + || strncmp(key, "realloc", 7) == 0 + || strncmp(key, "reallocarray", 12) == 0 ++ ++ || strncmp(key, "open", 4) == 0 ++ || strncmp(key, "close", 5) == 0 ++ || strncmp(key, "stderr", 6) == 0 ++ || strncmp(key, "clock_gettime", 13) == 0 ++ || strncmp(key, "clock_getres", 12) == 0 ++ || strncmp(key, "__stack_chk_guard", 17) == 0 ++ || strncmp(key, "__strchr_chk", 12) == 0 ++ || strncmp(key, "__strcpy_chk", 12) == 0 ++ || strncmp(key, "__strcpy_chk_generic", 20) == 0 ++ || strncmp(key, "__strcat_chk_generic", 20) == 0 ++ || strncmp(key, "__strlcpy_chk", 13) == 0 ++ || strncmp(key, "__strlen_chk", 12) == 0 ++ || strncmp(key, "__strncpy_chk", 13) == 0 ++ || strncmp(key, "__vsnprintf_chk", 15) == 0 ++ || strncmp(key, "__write_chk", 11) == 0 ++ || strncmp(key, "__read_chk", 10) == 0 ++ || strncmp(key, "__memset_chk", 12) == 0 ++ || strncmp(key, "__memset_chk_fail", 17) == 0 ++ || strncmp(key, "__libc_globals", 14) == 0 ++ || strncmp(key, "memmove", 7) == 0 ++ || strncmp(key, "gettimeofday", 12) == 0 ++ || strncmp(key, "strcmp", 6) == 0 ++ || strncmp(key, "fopen", 5) == 0 ++ || strncmp(key, "fread", 5) == 0 ++ || strncmp(key, "fwrite", 6) == 0 ++ || strncmp(key, "fclose", 5) == 0 ++ || strncmp(key, "open", 4) == 0 ++ || strncmp(key, "close", 5) == 0 ++ || strncmp(key, "strerror", 8) == 0 ++ || strncmp(key, "__rel_iplt_start", 16) == 0 + ) { + /* symbols we link aginst the libc we link ghc or iserv against */ + return 1; +diff --git a/rts/RtsSymbols.c b/rts/RtsSymbols.c +index 1da73dd..29ef159 100644 +--- a/rts/RtsSymbols.c ++++ b/rts/RtsSymbols.c +@@ -1009,7 +1009,31 @@ + SymI_NeedsProto(__ashldi3) \ + SymI_NeedsProto(__ashrdi3) \ + SymI_NeedsProto(__lshrdi3) \ +- SymI_NeedsProto(__fixunsdfdi) ++ SymI_NeedsProto(__fixunsdfdi) \ ++ SymI_NeedsProto(__aeabi_memset) \ ++ SymI_NeedsProto(__aeabi_memset4) \ ++ SymI_NeedsProto(__aeabi_memset8) \ ++ SymI_NeedsProto(__aeabi_memcpy) \ ++ SymI_NeedsProto(__aeabi_memcpy4) \ ++ SymI_NeedsProto(__aeabi_memcpy8) \ ++ SymI_NeedsProto(__aeabi_memmove) \ ++ SymI_NeedsProto(__aeabi_memmove4) \ ++ SymI_NeedsProto(__aeabi_memclr) \ ++ SymI_NeedsProto(__aeabi_memclr4) \ ++ SymI_NeedsProto(__aeabi_memclr8) \ ++ SymI_NeedsProto(__aeabi_idiv) \ ++ SymI_NeedsProto(__aeabi_uidiv) \ ++ SymI_NeedsProto(__aeabi_idivmod) \ ++ SymI_NeedsProto(__aeabi_ldivmod) \ ++ SymI_NeedsProto(__aeabi_uidivmod) \ ++ SymI_NeedsProto(__aeabi_uldivmod) \ ++ SymI_NeedsProto(__aeabi_l2f) \ ++ SymI_NeedsProto(__aeabi_l2d) \ ++ SymI_NeedsProto(__aeabi_ul2d) \ ++ SymI_NeedsProto(__aeabi_d2lz) \ ++ SymI_NeedsProto(__aeabi_d2ulz) ++ ++ + #elif defined(__GNUC__) && SIZEOF_VOID_P == 8 + #define RTS_LIBGCC_SYMBOLS \ + SymI_NeedsProto(__udivti3) \ +@@ -1045,10 +1069,45 @@ + SymI_HasProto(free) \ + SymI_HasProto(malloc) \ + SymI_HasProto(calloc) \ +- SymI_HasProto(realloc) ++ SymI_HasProto(realloc) \ ++ SymI_HasProto(stderr) \ ++ SymI_HasProto(fopen) \ ++ SymI_HasProto(fwrite) \ ++ SymI_HasProto(fread) \ ++ SymI_HasProto(fclose) \ ++ SymI_NeedsProto(__assert) \ ++ SymI_NeedsProto(__assert2) \ ++ SymI_NeedsProto(__stack_chk_guard) \ ++ SymI_NeedsProto(__memset_chk) \ ++ SymI_NeedsProto(__memcpy_chk) \ ++ SymI_HasProto(__strlen_chk) \ ++ SymI_NeedsProto(__write_chk) \ ++ SymI_NeedsProto(__read_chk) \ ++ SymI_NeedsProto(__strlcpy_chk) \ ++ SymI_NeedsProto(__strcpy_chk) \ ++ SymI_NeedsProto(__strncpy_chk) \ ++ SymI_NeedsProto(__vsnprintf_chk) \ ++ SymI_HasProto(__strchr_chk) \ ++ SymI_NeedsProto(open) \ ++ SymI_NeedsProto(close) \ ++ SymI_HasProto(strerror) ++#if defined(linux_android_HOST_OS) && SIZEOF_VOID_P <= 4 ++#define RTS_BIONIC_LIBC_SYMBOLS \ ++ // SymI_NeedsProto(reallocarray) \ ++ // SymI_NeedsProto(__svfscanf) \ ++ // SymI_NeedsProto(__vfwscanf) \ ++ // SymI_NeedsProto(__memset_chk_fail) \ ++ // SymI_NeedsProto(__strcpy_chk_generic) \ ++ // SymI_NeedsProto(__strcat_chk_generic) \ ++ // SymI_NeedsProto(__libc_globals) \ ++ // SymI_NeedsProto(__rel_iplt_start) ++#else ++#define RTS_BIONIC_LIBC_SYMBOLS ++#endif + #else + #define RTS_STACK_PROTECTOR_SYMBOLS + #define RTS_LIBC_SYMBOLS ++#define RTS_BIONIC_LIBC_SYMBOLS + #endif + + /* entirely bogus claims about types of these symbols */ +@@ -1082,6 +1141,7 @@ RTS_LIBFFI_SYMBOLS + RTS_LINKER_SYMBOLS + RTS_STACK_PROTECTOR_SYMBOLS + RTS_LIBC_SYMBOLS ++RTS_BIONIC_LIBC_SYMBOLS + #undef SymI_NeedsProto + #undef SymI_NeedsDataProto + #undef SymI_HasProto +@@ -1137,6 +1197,7 @@ RtsSymbolVal rtsSyms[] = { + RTS_LINKER_SYMBOLS + RTS_STACK_PROTECTOR_SYMBOLS + RTS_LIBC_SYMBOLS ++ RTS_BIONIC_LIBC_SYMBOLS + SymI_HasDataProto(nonmoving_write_barrier_enabled) + #if defined(darwin_HOST_OS) && defined(i386_HOST_ARCH) + // dyld stub code contains references to this, +diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c +index c3f9110..da7007c 100644 +--- a/rts/linker/Elf.c ++++ b/rts/linker/Elf.c +@@ -931,6 +931,14 @@ ocGetNames_ELF ( ObjectCode* oc ) + debugBelch("COMMON symbol, size %ld name %s allocated at %p\n", + symbol->elf_sym->st_size, nm, symbol->addr)); + ++ } else if (ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK ++ && shndx == SHN_UNDEF ++ && (ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_FUNC ++ || ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_OBJECT ++ || ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_NOTYPE)) { ++ symbol->addr = NULL; ++ isLocal = false; ++ isWeak = true; + /* Pointless to do addProddableBlock() for this area, + since the linker should never poke around in it. */ + } else if ((ELF_ST_BIND(symbol->elf_sym->st_info) == STB_GLOBAL +@@ -978,14 +986,7 @@ ocGetNames_ELF ( ObjectCode* oc ) + isWeak = ELF_ST_BIND(symbol->elf_sym->st_info) + == STB_WEAK; + } +- } else if (ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK +- && shndx == SHN_UNDEF +- && (ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_FUNC +- || ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_OBJECT +- || ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_NOTYPE)) { +- symbol->addr = NULL; +- isLocal = false; +- isWeak = true; ++ + } else { + /* skip this symbol */ + IF_DEBUG(linker, +@@ -1244,6 +1245,7 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC, + + const StgBool overflow = !isInt(26, (StgInt32) result); + // Handle overflow and Thumb interworking ++ is_target_thm = S & 0x1; + const StgBool needs_veneer = + (is_target_thm && ELF_R_TYPE(info) == COMPAT_R_ARM_JUMP24) + || overflow; +diff --git a/rts/linker/elf_plt_arm.c b/rts/linker/elf_plt_arm.c +index bd21243..e3bd3cb 100644 +--- a/rts/linker/elf_plt_arm.c ++++ b/rts/linker/elf_plt_arm.c +@@ -117,13 +117,13 @@ makeStubArmArm(Stub * s) { + uint32_t movt_r12 = 0xe340c000; + uint32_t bx_r12 = 0xe12fff1c; + +- *((uint32_t*)s->addr+0) = movw_r12 ++ ((uint32_t*)s->addr)[0] = movw_r12 + | (((uint32_t )s->target & 0xf000) << 4) + | ((uint32_t )s->target & 0x0fff); +- *((uint32_t*)s->addr+1) = movt_r12 ++ ((uint32_t*)s->addr)[1] = movt_r12 + | ((((uint32_t )s->target >> 16) & 0xf000) << 4) + | (((uint32_t )s->target >> 16) & 0x0fff); +- *((uint32_t*)s->addr+2) = bx_r12; ++ ((uint32_t*)s->addr)[2] = bx_r12; + + return EXIT_SUCCESS; + } +@@ -157,17 +157,20 @@ makeStubArmThm(Stub * s) { + uint32_t movt_r12 = 0xf2c00c00; + uint32_t bx_r12 = 0x47600000; + +- *((uint32_t*)s->addr+0) = movw_r12 ++ uint32_t movw_r12_inst = movw_r12 + | (((uint32_t )s->target & 0xf000) << 4) +- | (((uint32_t )s->target & 0x0800) << 16) ++ | (((uint32_t )s->target & 0x0800) << 15) + | (((uint32_t )s->target & 0x0700) << 4) + | ((uint32_t )s->target & 0x00ff); +- *((uint32_t*)s->addr+1) = movt_r12 ++ uint32_t movt_r12_inst = movt_r12 + | ((((uint32_t )s->target >> 16) & 0xf000) << 4) +- | ((((uint32_t )s->target >> 16) & 0x0800) << 16) ++ | ((((uint32_t )s->target >> 16) & 0x0800) << 15) + | ((((uint32_t )s->target >> 16) & 0x0700) << 4) + | (((uint32_t )s->target >> 16) & 0x00ff); +- *((uint32_t*)s->addr+2) = bx_r12; ++ // encode in little endian (half word reversal) ++ ((uint32_t*)s->addr)[0] = (movw_r12_inst << 16) | (movw_r12_inst >> 16); ++ ((uint32_t*)s->addr)[1] = (movt_r12_inst << 16) | (movt_r12_inst >> 16); ++ ((uint32_t*)s->addr)[2] = (bx_r12 << 16) | (bx_r12 >> 16); + + return EXIT_SUCCESS; + } +diff --git a/utils/genapply/Main.hs b/utils/genapply/Main.hs +index 8c194f1..24514e1 100644 +--- a/utils/genapply/Main.hs ++++ b/utils/genapply/Main.hs +@@ -12,6 +12,11 @@ + -- for details + module Main(main) where + ++#undef linux_BUILD_OS ++#undef x86_64_BUILD_ARCH ++#undef linux_HOST_OS ++#undef x86_64_HOST_ARCH ++ + -- Note [Genapply target as host for RTS macros] + -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + -- We improperly include *HOST* macros for our target... +diff --git a/utils/genapply/ghc.mk b/utils/genapply/ghc.mk +index 8da1f7a..c206b24 100644 +--- a/utils/genapply/ghc.mk ++++ b/utils/genapply/ghc.mk +@@ -27,4 +27,5 @@ $(eval $(call build-prog,utils/genapply,dist,0)) + + # Purposely do the wrong stage for HOST := TARGET hack. + # See Note [Genapply target as host for RTS macros]. +-utils/genapply_dist_CC_OPTS += -I,$(BUILD_1_INCLUDE_DIR) ++$(utils/genapply_dist_depfile_haskell) : $(includes_1_H_CONFIG) $(includes_1_H_PLATFORM) ++utils/genapply_dist_HC_OPTS += -I$(BUILD_1_INCLUDE_DIR) diff --git a/overlays/patches/ghc/ghc-8.10.7-android-bionic-symbols.patch b/overlays/patches/ghc/ghc-8.10.7-android-bionic-symbols.patch new file mode 100644 index 000000000..eea586d95 --- /dev/null +++ b/overlays/patches/ghc/ghc-8.10.7-android-bionic-symbols.patch @@ -0,0 +1,31 @@ +diff --git a/rts/RtsSymbols.c b/rts/RtsSymbols.c +index 29ef159..3cb0fc0 100644 +--- a/rts/RtsSymbols.c ++++ b/rts/RtsSymbols.c +@@ -1093,14 +1093,18 @@ + SymI_HasProto(strerror) + #if defined(linux_android_HOST_OS) && SIZEOF_VOID_P <= 4 + #define RTS_BIONIC_LIBC_SYMBOLS \ +- // SymI_NeedsProto(reallocarray) \ +- // SymI_NeedsProto(__svfscanf) \ +- // SymI_NeedsProto(__vfwscanf) \ +- // SymI_NeedsProto(__memset_chk_fail) \ +- // SymI_NeedsProto(__strcpy_chk_generic) \ +- // SymI_NeedsProto(__strcat_chk_generic) \ +- // SymI_NeedsProto(__libc_globals) \ +- // SymI_NeedsProto(__rel_iplt_start) ++ SymI_NeedsProto(reallocarray) \ ++ SymI_NeedsProto(dlopen) \ ++ SymI_NeedsProto(dlerror) \ ++ SymI_NeedsProto(dlclose) \ ++ SymI_NeedsProto(dlsym) \ ++ SymI_NeedsProto(__svfscanf) \ ++ SymI_NeedsProto(__vfwscanf) \ ++ SymI_NeedsProto(__memset_chk_fail) \ ++ SymI_NeedsProto(__strcpy_chk_generic) \ ++ SymI_NeedsProto(__strcat_chk_generic) \ ++ SymI_NeedsProto(__libc_globals) \ ++ SymI_NeedsProto(__rel_iplt_start) + #else + #define RTS_BIONIC_LIBC_SYMBOLS + #endif diff --git a/overlays/patches/ghc/ghc-8.10.7-bionic-libc.patch b/overlays/patches/ghc/ghc-8.10.7-bionic-libc.patch new file mode 100644 index 000000000..1a71fa24d --- /dev/null +++ b/overlays/patches/ghc/ghc-8.10.7-bionic-libc.patch @@ -0,0 +1,35 @@ +diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c +index da7007c..9f99f58 100644 +--- a/rts/linker/Elf.c ++++ b/rts/linker/Elf.c +@@ -1968,15 +1968,22 @@ int ocRunInit_ELF( ObjectCode *oc ) + } + + if (kind == SECTIONKIND_INIT_ARRAY) { +- char *init_startC = oc->sections[i].start; +- init_start = (init_t*)init_startC; +- init_end = (init_t*)(init_startC + shdr[i].sh_size); +- for (init = init_start; init < init_end; init++) { +- ASSERT(0x0 != *init); +- (*init)(argc, argv, envv); +- } +- } ++ char *bname = basename(OC_INFORMATIVE_FILENAME(oc)); + ++ // do not run .array initialization for jemalloc from libc. This simply cannot work. ++ // It's most likely already run by the hosting process (ghc, or iserv) as they've been ++ // linked against that libc. ++ if(strncmp(bname, "libc.a(jemalloc.o)", 18) != 0) ++ { ++ char *init_startC = oc->sections[i].start; ++ init_start = (init_t*)init_startC; ++ init_end = (init_t*)(init_startC + shdr[i].sh_size); ++ for (init = init_start; init < init_end; init++) { ++ ASSERT(0x0 != *init); ++ (*init)(argc, argv, envv); ++ } ++ } ++ } + // XXX could be more strict and assert that it's + // SECTIONKIND_RWDATA; but allowing RODATA seems harmless enough. + if ((kind == SECTIONKIND_RWDATA || kind == SECTIONKIND_CODE_OR_RODATA) diff --git a/overlays/patches/ghc/ghc-8.10.7-cross-dont-build-stage2-tools.patch b/overlays/patches/ghc/ghc-8.10.7-cross-dont-build-stage2-tools.patch new file mode 100644 index 000000000..9d6031dc4 --- /dev/null +++ b/overlays/patches/ghc/ghc-8.10.7-cross-dont-build-stage2-tools.patch @@ -0,0 +1,74 @@ +diff --git a/utils/compare_sizes/ghc.mk b/utils/compare_sizes/ghc.mk +index d659a5e..b5e4228 100644 +--- a/utils/compare_sizes/ghc.mk ++++ b/utils/compare_sizes/ghc.mk +@@ -5,5 +5,6 @@ utils/compare_sizes_MODULES = Main + utils/compare_sizes_dist-install_PROGNAME = compareSizes + utils/compare_sizes_dist-install_INSTALL_INPLACE = NO + ++ifneq "$(Stage1Only)" "YES" + $(eval $(call build-prog,utils/compare_sizes,dist-install,1)) +- ++endif +\ No newline at end of file +diff --git a/utils/ghc-cabal/ghc.mk b/utils/ghc-cabal/ghc.mk +index 290b233..c9a119f 100644 +--- a/utils/ghc-cabal/ghc.mk ++++ b/utils/ghc-cabal/ghc.mk +@@ -104,4 +104,6 @@ utils/ghc-cabal_dist-install_INSTALL_INPLACE = NO + utils/ghc-cabal_dist-install_WANT_BINDIST_WRAPPER = YES + utils/ghc-cabal_dist-install_MODULES = Main + ++ifneq "$(Stage1Only)" "YES" + $(eval $(call build-prog,utils/ghc-cabal,dist-install,1)) ++endif +\ No newline at end of file +diff --git a/utils/hpc/ghc.mk b/utils/hpc/ghc.mk +index 9b2bce2..448ad16 100644 +--- a/utils/hpc/ghc.mk ++++ b/utils/hpc/ghc.mk +@@ -18,4 +18,6 @@ utils/hpc_dist-install_PROGNAME = hpc + utils/hpc_dist-install_SHELL_WRAPPER = YES + utils/hpc_dist-install_INSTALL_SHELL_WRAPPER_NAME = hpc + ++ifneq "$(Stage1Only)" "YES" + $(eval $(call build-prog,utils/hpc,dist-install,1)) ++endif +\ No newline at end of file +diff --git a/utils/hsc2hs/ghc.mk b/utils/hsc2hs/ghc.mk +index 386d472..5cc6037 100644 +--- a/utils/hsc2hs/ghc.mk ++++ b/utils/hsc2hs/ghc.mk +@@ -18,8 +18,12 @@ utils/hsc2hs_dist_INSTALL = NO + utils/hsc2hs_dist-install_INSTALL = YES + endif + ++ifeq "$(Stage1Only)" "YES" ++$(eval $(call build-prog,utils/hsc2hs,dist,0)) ++else + $(eval $(call build-prog,utils/hsc2hs,dist,0)) + $(eval $(call build-prog,utils/hsc2hs,dist-install,1)) ++endif + + # After build-prog above + utils/hsc2hs_dist-install_MODULES = $(utils/hsc2hs_dist_MODULES) +diff --git a/utils/iserv/ghc.mk b/utils/iserv/ghc.mk +index 74f90e6..e747ca7 100644 +--- a/utils/iserv/ghc.mk ++++ b/utils/iserv/ghc.mk +@@ -96,6 +96,7 @@ NEED_iserv_dyn = NO + endif + endif + ++ifneq "$(Stage1Only)" "YES" + ifeq "$(NEED_iserv)" "YES" + $(eval $(call build-prog,utils/iserv,stage2,1)) + endif +@@ -107,6 +108,7 @@ endif + ifeq "$(NEED_iserv_dyn)" "YES" + $(eval $(call build-prog,utils/iserv,stage2_dyn,1)) + endif ++endif + + all_ghc_stage2 : $(iserv-stage2_INPLACE) + all_ghc_stage2 : $(iserv-stage2_p_INPLACE) diff --git a/overlays/patches/ghc/ghc-8.10.7-linker-weak-and-common-armv7a.patch b/overlays/patches/ghc/ghc-8.10.7-linker-weak-and-common-armv7a.patch new file mode 100644 index 000000000..b416c6e2c --- /dev/null +++ b/overlays/patches/ghc/ghc-8.10.7-linker-weak-and-common-armv7a.patch @@ -0,0 +1,189 @@ +diff --git a/rts/Linker.c b/rts/Linker.c +index 10b0764..7d473f8 100644 +--- a/rts/Linker.c ++++ b/rts/Linker.c +@@ -273,7 +273,7 @@ int ghciInsertSymbolTable( + RtsSymbolInfo *pinfo = lookupStrHashTable(table, key); + if (!pinfo) /* new entry */ + { +- pinfo = stgMallocBytes(sizeof (*pinfo), "ghciInsertToSymbolTable"); ++ pinfo = stgCallocBytes(1, sizeof (*pinfo), "ghciInsertToSymbolTable"); + pinfo->value = data; + pinfo->owner = owner; + pinfo->weak = weak; +@@ -1329,7 +1329,7 @@ mkOc( pathchar *path, char *image, int imageSize, + ObjectCode* oc; + + IF_DEBUG(linker, debugBelch("mkOc: start\n")); +- oc = stgMallocBytes(sizeof(ObjectCode), "mkOc(oc)"); ++ oc = stgCallocBytes(1, sizeof(ObjectCode), "mkOc(oc)"); + + oc->info = NULL; + +@@ -1496,12 +1496,12 @@ preloadObjectFile (pathchar *path) + // reading the file, and then we misalign image on purpose so + // that the actual sections end up aligned again. + misalignment = machoGetMisalignment(f); +- image = stgMallocBytes(fileSize + misalignment, "loadObj(image)"); ++ image = stgCallocBytes(1, fileSize + misalignment, "loadObj(image)"); + image += misalignment; + + # else /* !defined(darwin_HOST_OS) */ + +- image = stgMallocBytes(fileSize, "loadObj(image)"); ++ image = stgCallocBytes(1, fileSize, "loadObj(image)"); + + #endif + +diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h +index f326a84..a846bf5 100644 +--- a/rts/LinkerInternals.h ++++ b/rts/LinkerInternals.h +@@ -209,6 +209,10 @@ typedef struct _ObjectCode { + int n_segments; + Segment *segments; + ++ // COMMON section ++ void * common_mem; ++ unsigned long common_size; ++ + // + // Garbage collection fields + // +diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c +index fdfe87a..c3f9110 100644 +--- a/rts/linker/Elf.c ++++ b/rts/linker/Elf.c +@@ -325,6 +325,15 @@ ocDeinit_ELF(ObjectCode * oc) + stgFree(oc->info); + oc->info = NULL; + } ++ if(NULL != oc->common_mem) { ++#if RTS_LINKER_USE_MMAP ++ munmap(oc->common_mem, oc->common_size); ++#else ++ stgFree(oc->common_mem); ++#endif ++ } ++ oc->common_mem = NULL; ++ oc->common_size = 0; + } + + /* +@@ -861,14 +870,17 @@ ocGetNames_ELF ( ObjectCode* oc ) + for (size_t j = 0; j < symTab->n_symbols; j++) { + ElfSymbol *symbol = &symTab->symbols[j]; + if (SHN_COMMON == symTab->symbols[j].elf_sym->st_shndx) { +- common_size += symbol->elf_sym->st_size; ++ // st_value holds the alignment. Adding alignment always ++ // should give us some wiggle room to get alignment right. ++ common_size += symbol->elf_sym->st_size + symbol->elf_sym->st_value; + } + } + } +- void * common_mem = NULL; ++ oc->common_mem = NULL; ++ oc->common_size = common_size; + if(common_size > 0) { +- common_mem = mmapAnonForLinker(common_size); +- if (common_mem == NULL) { ++ oc->common_mem = mmapAnonForLinker(common_size); ++ if (oc->common_mem == NULL) { + barf("ocGetNames_ELF: Failed to allocate memory for SHN_COMMONs"); + } + } +@@ -909,9 +921,10 @@ ocGetNames_ELF ( ObjectCode* oc ) + if (shndx == SHN_COMMON) { + isLocal = false; + ASSERT(common_used < common_size); +- ASSERT(common_mem); +- symbol->addr = (void*)((uintptr_t)common_mem + common_used); +- common_used += symbol->elf_sym->st_size; ++ ASSERT(oc->common_mem); ++ int alignment = symbol->elf_sym->st_value-1; ++ symbol->addr = (void*)(((uintptr_t)oc->common_mem + common_used + alignment) & ~alignment); ++ common_used = (uintptr_t)symbol->addr - (uintptr_t)oc->common_mem + symbol->elf_sym->st_size; + ASSERT(common_used <= common_size); + + IF_DEBUG(linker, +@@ -925,7 +938,9 @@ ocGetNames_ELF ( ObjectCode* oc ) + || ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK + ) + /* and not an undefined symbol */ +- && shndx != SHN_UNDEF ++ && (shndx != SHN_UNDEF ++ /* unless it's weak */ ++ || (shndx == SHN_UNDEF && ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK)) + /* and not in a "special section" */ + && (shndx < SHN_LORESERVE + #if defined(SHN_XINDEX) +@@ -963,33 +978,20 @@ ocGetNames_ELF ( ObjectCode* oc ) + isWeak = ELF_ST_BIND(symbol->elf_sym->st_info) + == STB_WEAK; + } +- } +- +- /* And the decision is ... */ +- +- if (symbol->addr != NULL) { +- ASSERT(nm != NULL); +- /* Acquire! */ +- if (!isLocal) { +- +- if (isWeak == HS_BOOL_TRUE) { +- setWeakSymbol(oc, nm); +- } +- if (!ghciInsertSymbolTable(oc->fileName, symhash, +- nm, symbol->addr, isWeak, oc) +- ) { +- goto fail; +- } +- oc->symbols[curSymbol++].name = nm; +- oc->symbols[curSymbol].addr = symbol->addr; +- } +- } else { +- /* Skip. */ ++ } else if (ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK ++ && shndx == SHN_UNDEF ++ && (ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_FUNC ++ || ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_OBJECT ++ || ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_NOTYPE)) { ++ symbol->addr = NULL; ++ isLocal = false; ++ isWeak = true; ++ } else { ++ /* skip this symbol */ + IF_DEBUG(linker, + debugBelch("skipping `%s'\n", + nm) + ); +- + /* + debugBelch( + "skipping bind = %d, type = %d, secno = %d `%s'\n", +@@ -999,7 +1001,24 @@ ocGetNames_ELF ( ObjectCode* oc ) + nm + ); + */ +- } ++ continue; ++ } ++ ++ /* And the decision is ... */ ++ ASSERT(nm != NULL); ++ /* Acquire! */ ++ if (!isLocal) { ++ ++ if (isWeak == HS_BOOL_TRUE) { ++ setWeakSymbol(oc, nm); ++ } ++ if (!ghciInsertSymbolTable(oc->fileName, symhash, ++ nm, symbol->addr, isWeak, oc)) { ++ goto fail; ++ } ++ oc->symbols[curSymbol++].name = nm; ++ oc->symbols[curSymbol].addr = symbol->addr; ++ } + } + } + } \ No newline at end of file diff --git a/overlays/patches/ghc/ghc-8.10.7-linker-weak-and-common.patch b/overlays/patches/ghc/ghc-8.10.7-linker-weak-and-common.patch index b416c6e2c..b982fe366 100644 --- a/overlays/patches/ghc/ghc-8.10.7-linker-weak-and-common.patch +++ b/overlays/patches/ghc/ghc-8.10.7-linker-weak-and-common.patch @@ -85,9 +85,9 @@ index fdfe87a..c3f9110 100644 + oc->common_mem = NULL; + oc->common_size = common_size; if(common_size > 0) { -- common_mem = mmapAnonForLinker(common_size); +- common_mem = mmapAnonForLinker(common_size, true, "anon:common_mem"); - if (common_mem == NULL) { -+ oc->common_mem = mmapAnonForLinker(common_size); ++ oc->common_mem = mmapAnonForLinker(common_size, true, "anon:common_mem"); + if (oc->common_mem == NULL) { barf("ocGetNames_ELF: Failed to allocate memory for SHN_COMMONs"); } diff --git a/overlays/patches/ghc/ghc-8.10.7-rts-aarch64-darwin.patch b/overlays/patches/ghc/ghc-8.10.7-rts-aarch64-darwin.patch new file mode 100644 index 000000000..04d527a09 --- /dev/null +++ b/overlays/patches/ghc/ghc-8.10.7-rts-aarch64-darwin.patch @@ -0,0 +1,18 @@ +diff --git a/rts/ghc.mk b/rts/ghc.mk +index 6d6ff4bb90..02d3c64ce9 100644 +--- a/rts/ghc.mk ++++ b/rts/ghc.mk +@@ -415,6 +415,13 @@ rts_CC_OPTS += -fno-strict-aliasing + + rts_CC_OPTS += -fno-common + ++ ++ifeq "$(TargetArch_CPP)" "aarch64" ++ifeq "$(TargetOS_CPP)" "darwin" ++rts_CC_OPTS += -mcpu=apple-a7 -march=armv8-a+norcpc ++endif ++endif ++ + ifeq "$(BeConservative)" "YES" + rts_CC_OPTS += -DBE_CONSERVATIVE + endif \ No newline at end of file diff --git a/overlays/patches/ghc/ghc-8.10.7-weak-symbols-2.patch b/overlays/patches/ghc/ghc-8.10.7-weak-symbols-2.patch new file mode 100644 index 000000000..32d493dfa --- /dev/null +++ b/overlays/patches/ghc/ghc-8.10.7-weak-symbols-2.patch @@ -0,0 +1,37 @@ +diff --git a/rts/Linker.c b/rts/Linker.c +index 727fe74..12a22d7 100644 +--- a/rts/Linker.c ++++ b/rts/Linker.c +@@ -1810,6 +1810,8 @@ static HsInt resolveObjs_ (void) + IF_DEBUG(linker, debugBelch("resolveObjs: start\n")); + + for (ObjectCode *oc = objects; oc; oc = oc->next) { ++ if(oc->status == OBJECT_RESOLVED) ++ continue; + int r = ocTryLoad(oc); + if (!r) + { +diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c +index c3f9110..1b497af 100644 +--- a/rts/linker/Elf.c ++++ b/rts/linker/Elf.c +@@ -963,10 +963,15 @@ ocGetNames_ELF ( ObjectCode* oc ) + stab[j].st_size, stab[j].st_value, nm); + } + */ +- symbol->addr = (SymbolAddr*)( +- (intptr_t) oc->sections[secno].start + +- (intptr_t) symbol->elf_sym->st_value); +- ASSERT(symbol->addr != 0x0); ++ if(shndx == SHN_UNDEF && ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK) { ++ symbol->addr = NULL; ++ } else { ++ symbol->addr = (SymbolAddr*)( ++ (intptr_t) oc->sections[secno].start + ++ (intptr_t) symbol->elf_sym->st_value); ++ ASSERT(symbol->addr != 0x0); ++ } ++ + if (ELF_ST_BIND(symbol->elf_sym->st_info) == STB_LOCAL) { + isLocal = true; + isWeak = false; diff --git a/overlays/patches/ghc/ghc-9.0-better-symbol-addr-debug.patch b/overlays/patches/ghc/ghc-9.0-better-symbol-addr-debug.patch index 6ccc52a72..5d71d3c36 100644 --- a/overlays/patches/ghc/ghc-9.0-better-symbol-addr-debug.patch +++ b/overlays/patches/ghc/ghc-9.0-better-symbol-addr-debug.patch @@ -4,11 +4,11 @@ index d8c4f8b724..5e349f2839 100644 +++ b/rts/linker/elf_reloc_aarch64.c @@ -325,7 +325,8 @@ relocateObjectCodeAarch64(ObjectCode * oc) { ELF64_R_SYM((Elf64_Xword)rel->r_info)); - + CHECK(0x0 != symbol); - CHECK(0x0 != symbol->addr); + if(0x0 == symbol->addr) -+ barf("0x0 address for %s + %d of type %d in %s for relocation %d in section %d of kind: %d\n", symbol->name, rel->r_addend, ELF64_R_TYPE((Elf64_Xword)rel->r_info), OC_INFORMATIVE_FILENAME(oc), i, relaTab->targetSectionIndex, oc->sections[relaTab->targetSectionIndex].kind); - ++ barf("0x0 address for %s + %lld of type %llu in %s for relocation %d in section %d of kind: %d\n", symbol->name, rel->r_addend, ELF64_R_TYPE((Elf64_Xword)rel->r_info), OC_INFORMATIVE_FILENAME(oc), i, relaTab->targetSectionIndex, oc->sections[relaTab->targetSectionIndex].kind); + /* take explicit addend */ int64_t addend = rel->r_addend; diff --git a/overlays/patches/ghc/ghc-9.10-hadrian-android.patch b/overlays/patches/ghc/ghc-9.10-hadrian-android.patch new file mode 100644 index 000000000..4200269d9 --- /dev/null +++ b/overlays/patches/ghc/ghc-9.10-hadrian-android.patch @@ -0,0 +1,10 @@ +diff --git a/hadrian/src/Hadrian/Haskell/Cabal.hs b/hadrian/src/Hadrian/Haskell/Cabal.hs +index 17249efd79..ff6cc57949 100644 +--- a/hadrian/src/Hadrian/Haskell/Cabal.hs ++++ b/hadrian/src/Hadrian/Haskell/Cabal.hs +@@ -84,5 +84,6 @@ cabalOsString "mingw32" = "windows" + cabalOsString "darwin" = "osx" + cabalOsString "solaris2" = "solaris" + cabalOsString "gnu" = "hurd" ++cabalOsString "linux_android" = "android" + cabalOsString other = other diff --git a/overlays/patches/ghc/ghc-9.10-hadrian-strip-cmd.patch b/overlays/patches/ghc/ghc-9.10-hadrian-strip-cmd.patch new file mode 100644 index 000000000..523f05328 --- /dev/null +++ b/overlays/patches/ghc/ghc-9.10-hadrian-strip-cmd.patch @@ -0,0 +1,55 @@ +diff --git a/hadrian/cfg/system.config.in b/hadrian/cfg/system.config.in +index e8e6076f9a..e748ca514d 100644 +--- a/hadrian/cfg/system.config.in ++++ b/hadrian/cfg/system.config.in +@@ -13,6 +13,7 @@ cc = @CC@ + happy = @HappyCmd@ + make = @MakeCmd@ + objdump = @ObjdumpCmd@ ++strip = @StripCmd@ + sphinx-build = @SPHINXBUILD@ + system-ghc = @WithGhc@ + system-ghc-pkg = @GhcPkgCmd@ +diff --git a/hadrian/src/Oracles/Setting.hs b/hadrian/src/Oracles/Setting.hs +index b20b023173..881c122885 100644 +--- a/hadrian/src/Oracles/Setting.hs ++++ b/hadrian/src/Oracles/Setting.hs +@@ -69,6 +69,7 @@ data Setting = CursesIncludeDir + | ProjectPatchLevel + | ProjectPatchLevel1 + | ProjectPatchLevel2 ++ | Strip + | SystemGhc + | TargetPlatformFull + | BourneShell +@@ -125,6 +126,7 @@ setting key = lookupSystemConfig $ case key of + ProjectPatchLevel -> "project-patch-level" + ProjectPatchLevel1 -> "project-patch-level1" + ProjectPatchLevel2 -> "project-patch-level2" ++ Strip -> "strip" + SystemGhc -> "system-ghc" + TargetPlatformFull -> "target-platform-full" + BourneShell -> "bourne-shell" +diff --git a/hadrian/src/Settings/Builders/Cabal.hs b/hadrian/src/Settings/Builders/Cabal.hs +index 3e83bb5634..241f8a51ef 100644 +--- a/hadrian/src/Settings/Builders/Cabal.hs ++++ b/hadrian/src/Settings/Builders/Cabal.hs +@@ -84,15 +84,11 @@ cabalSetupArgs = builder (Cabal Setup) ? do + commonCabalArgs :: Stage -> Args + commonCabalArgs stage = do + pkg <- getPackage ++ strip <- getSetting Strip + package_id <- expr $ pkgUnitId stage pkg + let prefix = "${pkgroot}" ++ (if windowsHost then "" else "/..") +- mconcat [ -- Don't strip libraries when cross compiling. +- -- TODO: We need to set @--with-strip=(stripCmdPath :: Action FilePath)@, +- -- and if it's @:@ disable stripping as well. As it is now, I believe +- -- we might have issues with stripping on Windows, as I can't see a +- -- consumer of 'stripCmdPath'. +- -- TODO: See https://github.com/snowleopard/hadrian/issues/549. +- flag CrossCompiling ? pure [ "--disable-executable-stripping" ++ mconcat [ notStage0 ? strip /= "" ? pure [ "--with-strip=" ++ strip ] ++ , flag CrossCompiling ? pure [ "--disable-executable-stripping" + , "--disable-library-stripping" ] + -- We don't want to strip the debug RTS + , S.package rts ? pure [ "--disable-executable-stripping" diff --git a/overlays/patches/ghc/ghc-9.10-relax-llvm-max-version.patch b/overlays/patches/ghc/ghc-9.10-relax-llvm-max-version.patch new file mode 100644 index 000000000..e8df35f80 --- /dev/null +++ b/overlays/patches/ghc/ghc-9.10-relax-llvm-max-version.patch @@ -0,0 +1,13 @@ +diff --git a/configure.ac b/configure.ac +index 1bf37789c7..3f91701dbe 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -492,7 +492,7 @@ AC_SUBST(InstallNameToolCmd) + # versions of LLVM simultaneously, but that stopped working around + # 3.5/3.6 release of LLVM. + LlvmMinVersion=13 # inclusive +-LlvmMaxVersion=16 # not inclusive ++LlvmMaxVersion=18 # not inclusive + AC_SUBST([LlvmMinVersion]) + AC_SUBST([LlvmMaxVersion]) + diff --git a/overlays/patches/ghc/ghc-9.6-32bit-cmm.patch b/overlays/patches/ghc/ghc-9.6-32bit-cmm.patch new file mode 100644 index 000000000..4267c8ec1 --- /dev/null +++ b/overlays/patches/ghc/ghc-9.6-32bit-cmm.patch @@ -0,0 +1,24 @@ +diff --git a/compiler/GHC/StgToCmm/CgUtils.hs b/compiler/GHC/StgToCmm/CgUtils.hs +index 4718cbf..07001c6 100644 +--- a/compiler/GHC/StgToCmm/CgUtils.hs ++++ b/compiler/GHC/StgToCmm/CgUtils.hs +@@ -173,15 +173,15 @@ fixStgRegStmt platform stmt = fixAssign $ mapExpDeep fixExpr stmt + BaseReg -> baseAddr + _other -> CmmLoad baseAddr (globalRegType platform reg) NaturallyAligned + +- CmmRegOff (CmmGlobal reg) offset -> ++ CmmRegOff greg@(CmmGlobal reg) offset -> + -- RegOf leaves are just a shorthand form. If the reg maps + -- to a real reg, we keep the shorthand, otherwise, we just + -- expand it and defer to the above code. + case reg `elem` activeStgRegs platform of + True -> expr +- False -> CmmMachOp (MO_Add (wordWidth platform)) [ +- fixExpr (CmmReg (CmmGlobal reg)), ++ False -> CmmMachOp (MO_Add (cmmRegWidth platform greg)) [ ++ fixExpr (CmmReg greg), + CmmLit (CmmInt (fromIntegral offset) +- (wordWidth platform))] ++ (cmmRegWidth platform greg))] + + other_expr -> other_expr \ No newline at end of file diff --git a/overlays/patches/ghc/ghc-9.6-debug-secno.patch b/overlays/patches/ghc/ghc-9.6-debug-secno.patch new file mode 100644 index 000000000..6564734a7 --- /dev/null +++ b/overlays/patches/ghc/ghc-9.6-debug-secno.patch @@ -0,0 +1,22 @@ +diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c +index 9f623a6..f4ee928 100644 +--- a/rts/linker/Elf.c ++++ b/rts/linker/Elf.c +@@ -1056,7 +1056,15 @@ ocGetNames_ELF ( ObjectCode* oc ) + ) + ) { + /* Section 0 is the undefined section, hence > and not >=. */ +- CHECK(secno > 0 && secno < shnum); ++ // This is only a problem if the symbol is _not_ WEAK. If it's ++ // weak this is perfectly ok. See below how we set the symbol's ++ // address to NULL in that case. ++ // if (!(secno > 0 && secno < shnum)) { ++ // debugBelch("while processing %s\n", OC_INFORMATIVE_FILENAME(oc)); ++ // debugBelch("while processing symbol %s (%d)\n", nm, j); ++ // barf("secno %d out of range (0, %d)\n", secno, shnum); ++ // } ++ // CHECK(secno > 0 && secno < shnum); + /* + if (shdr[secno].sh_type == SHT_NOBITS) { + debugBelch(" BSS symbol, size %d off %d name %s\n", + diff --git a/overlays/patches/ghc/ghc-9.6-genapply-cross-arch.patch b/overlays/patches/ghc/ghc-9.6-genapply-cross-arch.patch new file mode 100644 index 000000000..8aa2b8107 --- /dev/null +++ b/overlays/patches/ghc/ghc-9.6-genapply-cross-arch.patch @@ -0,0 +1,35 @@ +diff --git a/utils/genapply/Main.hs b/utils/genapply/Main.hs +index 74351ee..8a6513c 100644 +--- a/utils/genapply/Main.hs ++++ b/utils/genapply/Main.hs +@@ -12,6 +12,17 @@ + -- for details + module Main(main) where + ++-- GHC will helpfully pass ++-- -Dlinux_BUILD_OS -Dx86_64_BUILD_ARCH -Dlinux_HOST_OS -Dx86_64_HOST_ARCH -D__GLASGOW_HASKELL_TH__ -D__SSE__ -D__SSE2__ '-D__IO_MANAGER_MIO__=1' ++-- to cc -E when running the CPP phase. :-/ So we have to undefine them. ++#if defined(linux_BUILD_OS) || defined(x86_64_BUILD_ARCH) || defined(linux_HOST_OS) || defined(x86_64_HOST_ARCH) ++#warning "Undefining macros that GHC passes to CPP" ++#undef linux_BUILD_OS ++#undef x86_64_BUILD_ARCH ++#undef linux_HOST_OS ++#undef x86_64_HOST_ARCH ++#endif ++ + -- Note [Genapply target as host for RTS macros] + -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + -- We improperly include *HOST* macros for our target... +@@ -957,6 +968,12 @@ main = do + text "// DO NOT EDIT!", + text "// Automatically generated by utils/genapply/Main.hs", + text "", ++ text "// DEBUG: SIZEOF_VOID_P " <> int SIZEOF_VOID_P, ++ text "// DEBUG: HOST_ARCH " <> text HOST_ARCH, ++ text "// DEBUG: HOST_OS " <> text HOST_OS, ++ text "// DEBUG: BUILD_ARCH " <> text BUILD_ARCH, ++ text "// DEBUG: BUILD_OS " <> text BUILD_OS, ++ text "", + text "#include \"Cmm.h\"", + text "#include \"AutoApply.h\"", + text "#if !defined(UnregisterisedCompiler)", diff --git a/overlays/patches/ghc/ghc-9.6-hadrian-android.patch b/overlays/patches/ghc/ghc-9.6-hadrian-android.patch new file mode 100644 index 000000000..6e32aaadd --- /dev/null +++ b/overlays/patches/ghc/ghc-9.6-hadrian-android.patch @@ -0,0 +1,11 @@ +diff --git a/hadrian/src/Hadrian/Haskell/Cabal.hs b/hadrian/src/Hadrian/Haskell/Cabal.hs +index f5864b6..69123e1 100644 +--- a/hadrian/src/Hadrian/Haskell/Cabal.hs ++++ b/hadrian/src/Hadrian/Haskell/Cabal.hs +@@ -71,4 +71,5 @@ cabalOsString :: String -> String + cabalOsString "mingw32" = "windows" + cabalOsString "darwin" = "osx" + cabalOsString "solaris2" = "solaris" ++cabalOsString "linux_android" = "android" + cabalOsString other = other + diff --git a/overlays/patches/ghc/ghc-9.6-hadrian-strip-cmd.patch b/overlays/patches/ghc/ghc-9.6-hadrian-strip-cmd.patch new file mode 100644 index 000000000..f5652b35e --- /dev/null +++ b/overlays/patches/ghc/ghc-9.6-hadrian-strip-cmd.patch @@ -0,0 +1,56 @@ +diff --git a/hadrian/cfg/system.config.in b/hadrian/cfg/system.config.in +index 6a891b4..a2289f8 100644 +--- a/hadrian/cfg/system.config.in ++++ b/hadrian/cfg/system.config.in +@@ -18,6 +18,7 @@ merge-objects = @MergeObjsCmd@ + system-merge-objects = @LD_STAGE0@ + objdump = @ObjdumpCmd@ + ranlib = @REAL_RANLIB_CMD@ ++strip = @StripCmd@ + sphinx-build = @SPHINXBUILD@ + system-ar = @AR_STAGE0@ + system-cc = @CC_STAGE0@ +diff --git a/hadrian/src/Oracles/Setting.hs b/hadrian/src/Oracles/Setting.hs +index 462d289..535cc5f 100644 +--- a/hadrian/src/Oracles/Setting.hs ++++ b/hadrian/src/Oracles/Setting.hs +@@ -69,6 +69,7 @@ data Setting = BuildArch + | ProjectPatchLevel + | ProjectPatchLevel1 + | ProjectPatchLevel2 ++ | Strip + | SystemGhc + | TargetArch + | TargetOs +@@ -171,6 +172,7 @@ setting key = lookupSystemConfig $ case key of + ProjectPatchLevel -> "project-patch-level" + ProjectPatchLevel1 -> "project-patch-level1" + ProjectPatchLevel2 -> "project-patch-level2" ++ Strip -> "strip" + SystemGhc -> "system-ghc" + TargetArch -> "target-arch" + TargetArmVersion -> "target-arm-version" +diff --git a/hadrian/src/Settings/Builders/Cabal.hs b/hadrian/src/Settings/Builders/Cabal.hs +index 2e42185..032ca72 100644 +--- a/hadrian/src/Settings/Builders/Cabal.hs ++++ b/hadrian/src/Settings/Builders/Cabal.hs +@@ -85,15 +85,11 @@ commonCabalArgs :: Stage -> Args + commonCabalArgs stage = do + verbosity <- expr getVerbosity + pkg <- getPackage ++ strip <- getSetting Strip + package_id <- expr $ pkgIdentifier pkg + let prefix = "${pkgroot}" ++ (if windowsHost then "" else "/..") +- mconcat [ -- Don't strip libraries when cross compiling. +- -- TODO: We need to set @--with-strip=(stripCmdPath :: Action FilePath)@, +- -- and if it's @:@ disable stripping as well. As it is now, I believe +- -- we might have issues with stripping on Windows, as I can't see a +- -- consumer of 'stripCmdPath'. +- -- TODO: See https://github.com/snowleopard/hadrian/issues/549. +- flag CrossCompiling ? pure [ "--disable-executable-stripping" ++ mconcat [ notStage0 ? strip /= "" ? pure [ "--with-strip=" ++ strip ] ++ , flag CrossCompiling ? pure [ "--disable-executable-stripping" + , "--disable-library-stripping" ] + -- We don't want to strip the debug RTS + , S.package rts ? pure [ "--disable-executable-stripping" + diff --git a/overlays/patches/ghc/ghc-9.6-iog.patch b/overlays/patches/ghc/ghc-9.6-iog.patch new file mode 100644 index 000000000..849b86731 --- /dev/null +++ b/overlays/patches/ghc/ghc-9.6-iog.patch @@ -0,0 +1,370 @@ +diff --git a/rts/Linker.c b/rts/Linker.c +index 59e2ff9397..78e43cd471 100644 +--- a/rts/Linker.c ++++ b/rts/Linker.c +@@ -267,7 +267,7 @@ int ghciInsertSymbolTable( + RtsSymbolInfo *pinfo = lookupStrHashTable(table, key); + if (!pinfo) /* new entry */ + { +- pinfo = stgMallocBytes(sizeof (*pinfo), "ghciInsertToSymbolTable"); ++ pinfo = stgCallocBytes(1, sizeof (*pinfo), "ghciInsertToSymbolTable"); + pinfo->value = data; + pinfo->owner = owner; + pinfo->strength = strength; +@@ -605,11 +605,11 @@ internal_dlopen(const char *dll_name) + /* dlopen failed; return a ptr to the error msg. */ + errmsg = dlerror(); + if (errmsg == NULL) errmsg = "addDLL: unknown error"; +- errmsg_copy = stgMallocBytes(strlen(errmsg)+1, "addDLL"); ++ errmsg_copy = stgCallocBytes(1,strlen(errmsg)+1, "addDLL"); + strcpy(errmsg_copy, errmsg); + errmsg = errmsg_copy; + } else { +- o_so = stgMallocBytes(sizeof(OpenedSO), "addDLL"); ++ o_so = stgCallocBytes(1,sizeof(OpenedSO), "addDLL"); + o_so->handle = hdl; + o_so->next = openedSOs; + openedSOs = o_so; +@@ -1314,7 +1314,7 @@ mkOc( ObjectType type, pathchar *path, char *image, int imageSize, + + + IF_DEBUG(linker, debugBelch("mkOc: %" PATH_FMT "\n", path)); +- oc = stgMallocBytes(sizeof(ObjectCode), "mkOc(oc)"); ++ oc = stgCallocBytes(1, sizeof(ObjectCode), "mkOc(oc)"); + + oc->info = NULL; + oc->type = type; +@@ -1334,7 +1334,7 @@ mkOc( ObjectType type, pathchar *path, char *image, int imageSize, + oc->fileName = pathdup(path); + + if (archiveMemberName) { +- oc->archiveMemberName = stgMallocBytes( (pathlen(archiveMemberName)+1) * pathsize, ++ oc->archiveMemberName = stgCallocBytes(1, (pathlen(archiveMemberName)+1) * pathsize, + "loadObj" ); + pathcopy(oc->archiveMemberName, archiveMemberName); + } else { +@@ -1489,12 +1489,12 @@ preloadObjectFile (pathchar *path) + // reading the file, and then we misalign image on purpose so + // that the actual sections end up aligned again. + misalignment = machoGetMisalignment(f); +- image = stgMallocBytes(fileSize + misalignment, "loadObj(image)"); ++ image = stgCallocBytes(1, fileSize + misalignment, "loadObj(image)"); + image += misalignment; + + # else /* !defined(darwin_HOST_OS) */ + +- image = stgMallocBytes(fileSize, "loadObj(image)"); ++ image = stgCallocBytes(1, fileSize, "loadObj(image)"); + + #endif /* !defined(darwin_HOST_OS) */ + +@@ -1787,6 +1787,8 @@ static HsInt resolveObjs_ (void) + IF_DEBUG(linker, debugBelch("resolveObjs: start\n")); + + for (ObjectCode *oc = objects; oc; oc = oc->next) { ++ if(oc->status == OBJECT_RESOLVED) ++ continue; + int r = ocTryLoad(oc); + if (!r) { + errorBelch("Could not load Object Code %" PATH_FMT ".\n", OC_INFORMATIVE_FILENAME(oc)); +@@ -1907,7 +1909,7 @@ void + addProddableBlock ( ObjectCode* oc, void* start, int size ) + { + ProddableBlock* pb +- = stgMallocBytes(sizeof(ProddableBlock), "addProddableBlock"); ++ = stgCallocBytes(1,sizeof(ProddableBlock), "addProddableBlock"); + + IF_DEBUG(linker, debugBelch("addProddableBlock: %p %p %d\n", oc, start, size)); + ASSERT(size > 0); +diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h +index 271611a249..784bb19c10 100644 +--- a/rts/LinkerInternals.h ++++ b/rts/LinkerInternals.h +@@ -299,6 +299,10 @@ struct _ObjectCode { + int n_segments; + Segment *segments; + ++ // COMMON section ++ void * common_mem; ++ unsigned long common_size; ++ + // + // Garbage collection fields + // +diff --git a/rts/RtsUtils.c b/rts/RtsUtils.c +index 4cac10ba15..fe0d8ca40e 100644 +--- a/rts/RtsUtils.c ++++ b/rts/RtsUtils.c +@@ -104,6 +104,11 @@ stgCallocBytes (size_t count, size_t size, char *msg) + rtsConfig.mallocFailHook((W_) count*size, msg); + stg_exit(EXIT_INTERNAL_ERROR); + } ++ // If we run under qemu with jemalloc, calloc is not guaranteed ++ // to zero memory. ++ // - https://giters.com/jemalloc/jemalloc/issues/1844 ++ // - https://lists.nongnu.org/archive/html/qemu-devel/2020-05/msg03119.html ++ memset(space, 0, count*size); + return space; + } + +diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c +index bab2ca3041..9f623a62da 100644 +--- a/rts/linker/Elf.c ++++ b/rts/linker/Elf.c +@@ -303,6 +303,15 @@ ocInit_ELF(ObjectCode * oc) + } + } + } ++ if(NULL != oc->common_mem) { ++#if RTS_LINKER_USE_MMAP ++ munmap(oc->common_mem, oc->common_size); ++#else ++ stgFree(oc->common_mem); ++#endif ++ } ++ oc->common_mem = NULL; ++ oc->common_size = 0; + } + + void +@@ -961,14 +970,17 @@ ocGetNames_ELF ( ObjectCode* oc ) + for (size_t j = 0; j < symTab->n_symbols; j++) { + ElfSymbol *symbol = &symTab->symbols[j]; + if (SHN_COMMON == symTab->symbols[j].elf_sym->st_shndx) { +- common_size += symbol->elf_sym->st_size; ++ // st_value holds the alignment. Adding alignment always ++ // should give us some wiggle room to get alignment right. ++ common_size += symbol->elf_sym->st_size + symbol->elf_sym->st_value; + } + } + } +- void * common_mem = NULL; ++ oc->common_mem = NULL; ++ oc->common_size = common_size; + if(common_size > 0) { +- common_mem = mmapAnonForLinker(common_size); +- if (common_mem == NULL) { ++ oc->common_mem = mmapAnonForLinker(common_size); ++ if (oc->common_mem == NULL) { + barf("ocGetNames_ELF: Failed to allocate memory for SHN_COMMONs"); + } + } +@@ -1009,9 +1021,10 @@ ocGetNames_ELF ( ObjectCode* oc ) + if (shndx == SHN_COMMON) { + isLocal = false; + CHECK(common_used < common_size); +- CHECK(common_mem); +- symbol->addr = (void*)((uintptr_t)common_mem + common_used); +- common_used += symbol->elf_sym->st_size; ++ CHECK(oc->common_mem); ++ int alignment = symbol->elf_sym->st_value-1; ++ symbol->addr = (void*)(((uintptr_t)oc->common_mem + common_used + alignment) & ~alignment); ++ common_used = (uintptr_t)symbol->addr - (uintptr_t)oc->common_mem + symbol->elf_sym->st_size; + CHECK(common_used <= common_size); + + IF_DEBUG(linker_verbose, +@@ -1025,7 +1038,9 @@ ocGetNames_ELF ( ObjectCode* oc ) + || ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK + ) + /* and not an undefined symbol */ +- && shndx != SHN_UNDEF ++ && (shndx != SHN_UNDEF ++ /* unless it's weak */ ++ || (shndx == SHN_UNDEF && ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK)) + /* and not in a "special section" */ + && (shndx < SHN_LORESERVE + #if defined(SHN_XINDEX) +@@ -1052,6 +1067,14 @@ ocGetNames_ELF ( ObjectCode* oc ) + (intptr_t) oc->sections[secno].start + + (intptr_t) symbol->elf_sym->st_value); + CHECK(symbol->addr != 0x0); ++ if(shndx == SHN_UNDEF && ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK) { ++ symbol->addr = NULL; ++ } else { ++ symbol->addr = (SymbolAddr*)( ++ (intptr_t) oc->sections[secno].start + ++ (intptr_t) symbol->elf_sym->st_value); ++ CHECK(symbol->addr != 0x0); ++ } + if (ELF_ST_BIND(symbol->elf_sym->st_info) == STB_LOCAL) { + isLocal = true; + isWeak = false; +@@ -1063,42 +1086,20 @@ ocGetNames_ELF ( ObjectCode* oc ) + isWeak = ELF_ST_BIND(symbol->elf_sym->st_info) + == STB_WEAK; + } +- } +- +- SymType sym_type; +- if (ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_FUNC) { +- sym_type = SYM_TYPE_CODE; ++ } else if (ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK ++ && shndx == SHN_UNDEF ++ && (ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_FUNC ++ || ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_OBJECT ++ || ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_NOTYPE)) { ++ symbol->addr = NULL; ++ isLocal = false; ++ isWeak = true; + } else { +- sym_type = SYM_TYPE_DATA; +- } +- +- /* And the decision is ... */ +- +- if (symbol->addr != NULL) { +- CHECK(nm != NULL); +- /* Acquire! */ +- if (!isLocal) { +- +- if (isWeak == HS_BOOL_TRUE) { +- setWeakSymbol(oc, nm); +- } +- if (!ghciInsertSymbolTable(oc->fileName, symhash, +- nm, symbol->addr, isWeak, sym_type, oc) +- ) { +- goto fail; +- } +- oc->symbols[curSymbol].name = nm; +- oc->symbols[curSymbol].addr = symbol->addr; +- oc->symbols[curSymbol].type = sym_type; +- curSymbol++; +- } +- } else { +- /* Skip. */ ++ /* Skip. */ + IF_DEBUG(linker_verbose, + debugBelch("skipping `%s'\n", + nm) + ); +- + /* + debugBelch( + "skipping bind = %d, type = %d, secno = %d `%s'\n", +@@ -1108,7 +1109,34 @@ ocGetNames_ELF ( ObjectCode* oc ) + nm + ); + */ ++ continue; + } ++ ++ SymType sym_type; ++ if (ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_FUNC) { ++ sym_type = SYM_TYPE_CODE; ++ } else { ++ sym_type = SYM_TYPE_DATA; ++ } ++ ++ /* And the decision is ... */ ++ CHECK(nm != NULL); ++ /* Acquire! */ ++ if (!isLocal) { ++ ++ if (isWeak == HS_BOOL_TRUE) { ++ setWeakSymbol(oc, nm); ++ } ++ if (!ghciInsertSymbolTable(oc->fileName, symhash, ++ nm, symbol->addr, isWeak, sym_type, oc) ++ ) { ++ goto fail; ++ } ++ oc->symbols[curSymbol].name = nm; ++ oc->symbols[curSymbol].addr = symbol->addr; ++ oc->symbols[curSymbol].type = sym_type; ++ curSymbol++; ++ } + } + } + } +diff --git a/rts/linker/elf_plt.c b/rts/linker/elf_plt.c +index 9cd42efff2..70817d8b0b 100644 +--- a/rts/linker/elf_plt.c ++++ b/rts/linker/elf_plt.c +@@ -1,4 +1,5 @@ + #include "Rts.h" ++#include "RtsUtils.h" + #include "elf_plt.h" + + #include +@@ -51,7 +52,7 @@ makeStub(Section * section, + void* * addr, + uint8_t flags) { + +- Stub * s = calloc(1, sizeof(Stub)); ++ Stub * s = stgCallocBytes(1, sizeof(Stub), "makeStub"); + ASSERT(s != NULL); + s->target = *addr; + s->flags = flags; +diff --git a/rts/linker/elf_plt_aarch64.c b/rts/linker/elf_plt_aarch64.c +index 11354a63db..6b27a2c73d 100644 +--- a/rts/linker/elf_plt_aarch64.c ++++ b/rts/linker/elf_plt_aarch64.c +@@ -25,6 +25,7 @@ const size_t stubSizeAarch64 = 5 * 4; + */ + bool needStubForRelAarch64(Elf_Rel * rel) { + switch(ELF64_R_TYPE(rel->r_info)) { ++ case COMPAT_R_AARCH64_CONDBR19: + case COMPAT_R_AARCH64_CALL26: + case COMPAT_R_AARCH64_JUMP26: + return true; +@@ -34,6 +35,7 @@ bool needStubForRelAarch64(Elf_Rel * rel) { + } + bool needStubForRelaAarch64(Elf_Rela * rela) { + switch(ELF64_R_TYPE(rela->r_info)) { ++ case COMPAT_R_AARCH64_CONDBR19: + case COMPAT_R_AARCH64_CALL26: + case COMPAT_R_AARCH64_JUMP26: + return true; +diff --git a/rts/linker/elf_reloc_aarch64.c b/rts/linker/elf_reloc_aarch64.c +index 4743e81ea2..f37e3699f1 100644 +--- a/rts/linker/elf_reloc_aarch64.c ++++ b/rts/linker/elf_reloc_aarch64.c +@@ -105,8 +105,24 @@ encodeAddendAarch64(Section * section, Elf_Rel * rel, int64_t addend) { + break; + } + /* - control flow relocations */ ++ case COMPAT_R_AARCH64_CONDBR19: { /* relocate b.* ... */ ++ // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 ++ // 0 1 0 1 0 1 0 0 [ imm19 ... ++ // ++ // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ++ // ... imm19 ] 0 [ cond ] ++ CHECK(isInt64(19+2, addend)); /* X in range */ ++ *(inst_t *)P = (*(inst_t *)P & 0xff00001f) ++ | ((uint32_t)(addend << (5-2)) & 0x00ffffe0); ++ break; ++ } + case COMPAT_R_AARCH64_JUMP26: /* relocate b ... */ + case COMPAT_R_AARCH64_CALL26: { /* relocate bl ... */ ++ // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 ++ // 0|1 0 0 1 0 1 [ imm26 ... ++ ++ // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ++ // ... imm26 ] + CHECK(isInt64(26+2, addend)); /* X in range */ + *(inst_t *)P = (*(inst_t *)P & 0xfc000000) /* keep upper 6 (32-6) + * bits */ +@@ -222,6 +238,23 @@ computeAddend(Section * section, Elf_Rel * rel, + case COMPAT_R_AARCH64_ADD_ABS_LO12_NC: + /* type: static, class: aarch64, op: S + A */ + return (S + A) & 0xfff; ++ case COMPAT_R_AARCH64_CONDBR19: { ++ int64_t V = S + A - P; ++ if(!isInt64(19+2, V)) { ++ /* need a stub */ ++ /* check if we already have that stub */ ++ if(findStub(section, (void**)&S, 0)) { ++ /* did not find it. Crete a new stub. */ ++ if(makeStub(section, (void**)&S, 0)) { ++ abort(/* could not find or make stub */); ++ } ++ } ++ ++ V = S + A -P; ++ assert(isInt64(19+2, V)); ++ } ++ return V; ++ } + case COMPAT_R_AARCH64_JUMP26: + case COMPAT_R_AARCH64_CALL26: { + // S+A-P diff --git a/overlays/patches/ghc/ghc-9.6-missing-symbols-deadbeef.patch b/overlays/patches/ghc/ghc-9.6-missing-symbols-deadbeef.patch index cd02ae829..d767074b9 100644 --- a/overlays/patches/ghc/ghc-9.6-missing-symbols-deadbeef.patch +++ b/overlays/patches/ghc/ghc-9.6-missing-symbols-deadbeef.patch @@ -8,7 +8,7 @@ index 4d0c978..96a9d60 100644 symbol->name); - return EXIT_FAILURE; + // return EXIT_FAILURE; -+ symbol->addr = 0xDEADBEEF; ++ symbol->addr = (void*)0xDEADBEEF; } } } else { @@ -20,7 +20,7 @@ index 2356818..727e845 100644 "See top entry above.\n", lbl); IF_DEBUG(linker, printLoadedObjects()); fflush(stderr); -+ r = 0xDEADBEEF; ++ r = (void*)0xDEADBEEF; } if (!runPendingInitializers()) { diff --git a/overlays/patches/ghc/ghc-9.6.3-fix-outline-atomics-signature.patch b/overlays/patches/ghc/ghc-9.6.3-fix-outline-atomics-signature.patch new file mode 100644 index 000000000..65b683b19 --- /dev/null +++ b/overlays/patches/ghc/ghc-9.6.3-fix-outline-atomics-signature.patch @@ -0,0 +1,820 @@ +diff --git a/rts/ARMOutlineAtomicsSymbols.h b/rts/ARMOutlineAtomicsSymbols.h +index c8a78b5..31c095e 100644 +--- a/rts/ARMOutlineAtomicsSymbols.h ++++ b/rts/ARMOutlineAtomicsSymbols.h +@@ -10,583 +10,583 @@ + #include + #include + +-uint8_t ghc___aarch64_cas1_relax(uint8_t old, uint8_t new, uint8_t* p); +-uint8_t ghc___aarch64_cas1_relax(uint8_t old, uint8_t new, uint8_t* p) { ++uint8_t ghc___aarch64_cas1_relax(uint8_t old, uint8_t new, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_cas1_relax(uint8_t old, uint8_t new, atomic_uint_least8_t* p) { + atomic_compare_exchange_strong_explicit(p, &old, new, memory_order_relaxed, memory_order_relaxed); return old; + } + +-uint8_t ghc___aarch64_cas1_acq(uint8_t old, uint8_t new, uint8_t* p); +-uint8_t ghc___aarch64_cas1_acq(uint8_t old, uint8_t new, uint8_t* p) { ++uint8_t ghc___aarch64_cas1_acq(uint8_t old, uint8_t new, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_cas1_acq(uint8_t old, uint8_t new, atomic_uint_least8_t* p) { + atomic_compare_exchange_strong_explicit(p, &old, new, memory_order_acquire, memory_order_acquire); return old; + } + +-uint8_t ghc___aarch64_cas1_acq_rel(uint8_t old, uint8_t new, uint8_t* p); +-uint8_t ghc___aarch64_cas1_acq_rel(uint8_t old, uint8_t new, uint8_t* p) { ++uint8_t ghc___aarch64_cas1_acq_rel(uint8_t old, uint8_t new, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_cas1_acq_rel(uint8_t old, uint8_t new, atomic_uint_least8_t* p) { + atomic_compare_exchange_strong_explicit(p, &old, new, memory_order_acq_rel, memory_order_acquire); return old; + } + +-uint8_t ghc___aarch64_cas1_sync(uint8_t old, uint8_t new, uint8_t* p); +-uint8_t ghc___aarch64_cas1_sync(uint8_t old, uint8_t new, uint8_t* p) { ++uint8_t ghc___aarch64_cas1_sync(uint8_t old, uint8_t new, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_cas1_sync(uint8_t old, uint8_t new, atomic_uint_least8_t* p) { + atomic_compare_exchange_strong_explicit(p, &old, new, memory_order_seq_cst, memory_order_seq_cst); return old; + } + +-uint16_t ghc___aarch64_cas2_relax(uint16_t old, uint16_t new, uint16_t* p); +-uint16_t ghc___aarch64_cas2_relax(uint16_t old, uint16_t new, uint16_t* p) { ++uint16_t ghc___aarch64_cas2_relax(uint16_t old, uint16_t new, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_cas2_relax(uint16_t old, uint16_t new, atomic_uint_least16_t* p) { + atomic_compare_exchange_strong_explicit(p, &old, new, memory_order_relaxed, memory_order_relaxed); return old; + } + +-uint16_t ghc___aarch64_cas2_acq(uint16_t old, uint16_t new, uint16_t* p); +-uint16_t ghc___aarch64_cas2_acq(uint16_t old, uint16_t new, uint16_t* p) { ++uint16_t ghc___aarch64_cas2_acq(uint16_t old, uint16_t new, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_cas2_acq(uint16_t old, uint16_t new, atomic_uint_least16_t* p) { + atomic_compare_exchange_strong_explicit(p, &old, new, memory_order_acquire, memory_order_acquire); return old; + } + +-uint16_t ghc___aarch64_cas2_acq_rel(uint16_t old, uint16_t new, uint16_t* p); +-uint16_t ghc___aarch64_cas2_acq_rel(uint16_t old, uint16_t new, uint16_t* p) { ++uint16_t ghc___aarch64_cas2_acq_rel(uint16_t old, uint16_t new, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_cas2_acq_rel(uint16_t old, uint16_t new, atomic_uint_least16_t* p) { + atomic_compare_exchange_strong_explicit(p, &old, new, memory_order_acq_rel, memory_order_acquire); return old; + } + +-uint16_t ghc___aarch64_cas2_sync(uint16_t old, uint16_t new, uint16_t* p); +-uint16_t ghc___aarch64_cas2_sync(uint16_t old, uint16_t new, uint16_t* p) { ++uint16_t ghc___aarch64_cas2_sync(uint16_t old, uint16_t new, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_cas2_sync(uint16_t old, uint16_t new, atomic_uint_least16_t* p) { + atomic_compare_exchange_strong_explicit(p, &old, new, memory_order_seq_cst, memory_order_seq_cst); return old; + } + +-uint32_t ghc___aarch64_cas4_relax(uint32_t old, uint32_t new, uint32_t* p); +-uint32_t ghc___aarch64_cas4_relax(uint32_t old, uint32_t new, uint32_t* p) { ++uint32_t ghc___aarch64_cas4_relax(uint32_t old, uint32_t new, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_cas4_relax(uint32_t old, uint32_t new, atomic_uint_least32_t* p) { + atomic_compare_exchange_strong_explicit(p, &old, new, memory_order_relaxed, memory_order_relaxed); return old; + } + +-uint32_t ghc___aarch64_cas4_acq(uint32_t old, uint32_t new, uint32_t* p); +-uint32_t ghc___aarch64_cas4_acq(uint32_t old, uint32_t new, uint32_t* p) { ++uint32_t ghc___aarch64_cas4_acq(uint32_t old, uint32_t new, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_cas4_acq(uint32_t old, uint32_t new, atomic_uint_least32_t* p) { + atomic_compare_exchange_strong_explicit(p, &old, new, memory_order_acquire, memory_order_acquire); return old; + } + +-uint32_t ghc___aarch64_cas4_acq_rel(uint32_t old, uint32_t new, uint32_t* p); +-uint32_t ghc___aarch64_cas4_acq_rel(uint32_t old, uint32_t new, uint32_t* p) { ++uint32_t ghc___aarch64_cas4_acq_rel(uint32_t old, uint32_t new, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_cas4_acq_rel(uint32_t old, uint32_t new, atomic_uint_least32_t* p) { + atomic_compare_exchange_strong_explicit(p, &old, new, memory_order_acq_rel, memory_order_acquire); return old; + } + +-uint32_t ghc___aarch64_cas4_sync(uint32_t old, uint32_t new, uint32_t* p); +-uint32_t ghc___aarch64_cas4_sync(uint32_t old, uint32_t new, uint32_t* p) { ++uint32_t ghc___aarch64_cas4_sync(uint32_t old, uint32_t new, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_cas4_sync(uint32_t old, uint32_t new, atomic_uint_least32_t* p) { + atomic_compare_exchange_strong_explicit(p, &old, new, memory_order_seq_cst, memory_order_seq_cst); return old; + } + +-uint64_t ghc___aarch64_cas8_relax(uint64_t old, uint64_t new, uint64_t* p); +-uint64_t ghc___aarch64_cas8_relax(uint64_t old, uint64_t new, uint64_t* p) { ++uint64_t ghc___aarch64_cas8_relax(uint64_t old, uint64_t new, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_cas8_relax(uint64_t old, uint64_t new, atomic_uint_least64_t* p) { + atomic_compare_exchange_strong_explicit(p, &old, new, memory_order_relaxed, memory_order_relaxed); return old; + } + +-uint64_t ghc___aarch64_cas8_acq(uint64_t old, uint64_t new, uint64_t* p); +-uint64_t ghc___aarch64_cas8_acq(uint64_t old, uint64_t new, uint64_t* p) { ++uint64_t ghc___aarch64_cas8_acq(uint64_t old, uint64_t new, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_cas8_acq(uint64_t old, uint64_t new, atomic_uint_least64_t* p) { + atomic_compare_exchange_strong_explicit(p, &old, new, memory_order_acquire, memory_order_acquire); return old; + } + +-uint64_t ghc___aarch64_cas8_acq_rel(uint64_t old, uint64_t new, uint64_t* p); +-uint64_t ghc___aarch64_cas8_acq_rel(uint64_t old, uint64_t new, uint64_t* p) { ++uint64_t ghc___aarch64_cas8_acq_rel(uint64_t old, uint64_t new, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_cas8_acq_rel(uint64_t old, uint64_t new, atomic_uint_least64_t* p) { + atomic_compare_exchange_strong_explicit(p, &old, new, memory_order_acq_rel, memory_order_acquire); return old; + } + +-uint64_t ghc___aarch64_cas8_sync(uint64_t old, uint64_t new, uint64_t* p); +-uint64_t ghc___aarch64_cas8_sync(uint64_t old, uint64_t new, uint64_t* p) { ++uint64_t ghc___aarch64_cas8_sync(uint64_t old, uint64_t new, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_cas8_sync(uint64_t old, uint64_t new, atomic_uint_least64_t* p) { + atomic_compare_exchange_strong_explicit(p, &old, new, memory_order_seq_cst, memory_order_seq_cst); return old; + } + +-uint8_t ghc___aarch64_swp1_relax(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_swp1_relax(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_swp1_relax(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_swp1_relax(uint8_t v, atomic_uint_least8_t* p) { + return atomic_exchange_explicit(p, v, memory_order_relaxed); + } + +-uint8_t ghc___aarch64_swp1_acq(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_swp1_acq(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_swp1_acq(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_swp1_acq(uint8_t v, atomic_uint_least8_t* p) { + return atomic_exchange_explicit(p, v, memory_order_acquire); + } + +-uint8_t ghc___aarch64_swp1_rel(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_swp1_rel(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_swp1_rel(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_swp1_rel(uint8_t v, atomic_uint_least8_t* p) { + return atomic_exchange_explicit(p, v, memory_order_release); + } + +-uint8_t ghc___aarch64_swp1_acq_rel(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_swp1_acq_rel(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_swp1_acq_rel(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_swp1_acq_rel(uint8_t v, atomic_uint_least8_t* p) { + return atomic_exchange_explicit(p, v, memory_order_acq_rel); + } + +-uint8_t ghc___aarch64_swp1_sync(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_swp1_sync(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_swp1_sync(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_swp1_sync(uint8_t v, atomic_uint_least8_t* p) { + return atomic_exchange_explicit(p, v, memory_order_seq_cst); + } + +-uint16_t ghc___aarch64_swp2_relax(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_swp2_relax(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_swp2_relax(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_swp2_relax(uint16_t v, atomic_uint_least16_t* p) { + return atomic_exchange_explicit(p, v, memory_order_relaxed); + } + +-uint16_t ghc___aarch64_swp2_acq(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_swp2_acq(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_swp2_acq(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_swp2_acq(uint16_t v, atomic_uint_least16_t* p) { + return atomic_exchange_explicit(p, v, memory_order_acquire); + } + +-uint16_t ghc___aarch64_swp2_rel(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_swp2_rel(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_swp2_rel(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_swp2_rel(uint16_t v, atomic_uint_least16_t* p) { + return atomic_exchange_explicit(p, v, memory_order_release); + } + +-uint16_t ghc___aarch64_swp2_acq_rel(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_swp2_acq_rel(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_swp2_acq_rel(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_swp2_acq_rel(uint16_t v, atomic_uint_least16_t* p) { + return atomic_exchange_explicit(p, v, memory_order_acq_rel); + } + +-uint16_t ghc___aarch64_swp2_sync(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_swp2_sync(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_swp2_sync(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_swp2_sync(uint16_t v, atomic_uint_least16_t* p) { + return atomic_exchange_explicit(p, v, memory_order_seq_cst); + } + +-uint32_t ghc___aarch64_swp4_relax(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_swp4_relax(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_swp4_relax(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_swp4_relax(uint32_t v, atomic_uint_least32_t* p) { + return atomic_exchange_explicit(p, v, memory_order_relaxed); + } + +-uint32_t ghc___aarch64_swp4_acq(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_swp4_acq(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_swp4_acq(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_swp4_acq(uint32_t v, atomic_uint_least32_t* p) { + return atomic_exchange_explicit(p, v, memory_order_acquire); + } + +-uint32_t ghc___aarch64_swp4_rel(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_swp4_rel(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_swp4_rel(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_swp4_rel(uint32_t v, atomic_uint_least32_t* p) { + return atomic_exchange_explicit(p, v, memory_order_release); + } + +-uint32_t ghc___aarch64_swp4_acq_rel(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_swp4_acq_rel(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_swp4_acq_rel(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_swp4_acq_rel(uint32_t v, atomic_uint_least32_t* p) { + return atomic_exchange_explicit(p, v, memory_order_acq_rel); + } + +-uint32_t ghc___aarch64_swp4_sync(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_swp4_sync(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_swp4_sync(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_swp4_sync(uint32_t v, atomic_uint_least32_t* p) { + return atomic_exchange_explicit(p, v, memory_order_seq_cst); + } + +-uint64_t ghc___aarch64_swp8_relax(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_swp8_relax(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_swp8_relax(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_swp8_relax(uint64_t v, atomic_uint_least64_t* p) { + return atomic_exchange_explicit(p, v, memory_order_relaxed); + } + +-uint64_t ghc___aarch64_swp8_acq(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_swp8_acq(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_swp8_acq(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_swp8_acq(uint64_t v, atomic_uint_least64_t* p) { + return atomic_exchange_explicit(p, v, memory_order_acquire); + } + +-uint64_t ghc___aarch64_swp8_rel(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_swp8_rel(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_swp8_rel(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_swp8_rel(uint64_t v, atomic_uint_least64_t* p) { + return atomic_exchange_explicit(p, v, memory_order_release); + } + +-uint64_t ghc___aarch64_swp8_acq_rel(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_swp8_acq_rel(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_swp8_acq_rel(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_swp8_acq_rel(uint64_t v, atomic_uint_least64_t* p) { + return atomic_exchange_explicit(p, v, memory_order_acq_rel); + } + +-uint64_t ghc___aarch64_swp8_sync(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_swp8_sync(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_swp8_sync(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_swp8_sync(uint64_t v, atomic_uint_least64_t* p) { + return atomic_exchange_explicit(p, v, memory_order_seq_cst); + } + +-uint8_t ghc___aarch64_ldadd1_relax(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldadd1_relax(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldadd1_relax(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldadd1_relax(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_relaxed); + } + +-uint8_t ghc___aarch64_ldadd1_acq(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldadd1_acq(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldadd1_acq(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldadd1_acq(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_acquire); + } + +-uint8_t ghc___aarch64_ldadd1_rel(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldadd1_rel(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldadd1_rel(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldadd1_rel(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_release); + } + +-uint8_t ghc___aarch64_ldadd1_acq_rel(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldadd1_acq_rel(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldadd1_acq_rel(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldadd1_acq_rel(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_acq_rel); + } + +-uint8_t ghc___aarch64_ldadd1_sync(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldadd1_sync(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldadd1_sync(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldadd1_sync(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_seq_cst); + } + +-uint16_t ghc___aarch64_ldadd2_relax(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldadd2_relax(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldadd2_relax(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldadd2_relax(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_relaxed); + } + +-uint16_t ghc___aarch64_ldadd2_acq(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldadd2_acq(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldadd2_acq(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldadd2_acq(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_acquire); + } + +-uint16_t ghc___aarch64_ldadd2_rel(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldadd2_rel(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldadd2_rel(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldadd2_rel(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_release); + } + +-uint16_t ghc___aarch64_ldadd2_acq_rel(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldadd2_acq_rel(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldadd2_acq_rel(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldadd2_acq_rel(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_acq_rel); + } + +-uint16_t ghc___aarch64_ldadd2_sync(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldadd2_sync(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldadd2_sync(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldadd2_sync(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_seq_cst); + } + +-uint32_t ghc___aarch64_ldadd4_relax(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldadd4_relax(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldadd4_relax(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldadd4_relax(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_relaxed); + } + +-uint32_t ghc___aarch64_ldadd4_acq(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldadd4_acq(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldadd4_acq(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldadd4_acq(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_acquire); + } + +-uint32_t ghc___aarch64_ldadd4_rel(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldadd4_rel(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldadd4_rel(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldadd4_rel(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_release); + } + +-uint32_t ghc___aarch64_ldadd4_acq_rel(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldadd4_acq_rel(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldadd4_acq_rel(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldadd4_acq_rel(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_acq_rel); + } + +-uint32_t ghc___aarch64_ldadd4_sync(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldadd4_sync(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldadd4_sync(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldadd4_sync(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_seq_cst); + } + +-uint64_t ghc___aarch64_ldadd8_relax(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldadd8_relax(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldadd8_relax(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldadd8_relax(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_relaxed); + } + +-uint64_t ghc___aarch64_ldadd8_acq(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldadd8_acq(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldadd8_acq(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldadd8_acq(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_acquire); + } + +-uint64_t ghc___aarch64_ldadd8_rel(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldadd8_rel(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldadd8_rel(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldadd8_rel(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_release); + } + +-uint64_t ghc___aarch64_ldadd8_acq_rel(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldadd8_acq_rel(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldadd8_acq_rel(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldadd8_acq_rel(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_acq_rel); + } + +-uint64_t ghc___aarch64_ldadd8_sync(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldadd8_sync(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldadd8_sync(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldadd8_sync(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_add_explicit(p, v, memory_order_seq_cst); + } + +-uint8_t ghc___aarch64_ldclr1_relax(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldclr1_relax(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldclr1_relax(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldclr1_relax(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_relaxed); + } + +-uint8_t ghc___aarch64_ldclr1_acq(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldclr1_acq(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldclr1_acq(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldclr1_acq(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_acquire); + } + +-uint8_t ghc___aarch64_ldclr1_rel(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldclr1_rel(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldclr1_rel(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldclr1_rel(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_release); + } + +-uint8_t ghc___aarch64_ldclr1_acq_rel(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldclr1_acq_rel(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldclr1_acq_rel(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldclr1_acq_rel(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_acq_rel); + } + +-uint8_t ghc___aarch64_ldclr1_sync(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldclr1_sync(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldclr1_sync(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldclr1_sync(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_seq_cst); + } + +-uint16_t ghc___aarch64_ldclr2_relax(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldclr2_relax(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldclr2_relax(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldclr2_relax(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_relaxed); + } + +-uint16_t ghc___aarch64_ldclr2_acq(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldclr2_acq(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldclr2_acq(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldclr2_acq(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_acquire); + } + +-uint16_t ghc___aarch64_ldclr2_rel(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldclr2_rel(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldclr2_rel(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldclr2_rel(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_release); + } + +-uint16_t ghc___aarch64_ldclr2_acq_rel(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldclr2_acq_rel(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldclr2_acq_rel(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldclr2_acq_rel(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_acq_rel); + } + +-uint16_t ghc___aarch64_ldclr2_sync(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldclr2_sync(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldclr2_sync(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldclr2_sync(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_seq_cst); + } + +-uint32_t ghc___aarch64_ldclr4_relax(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldclr4_relax(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldclr4_relax(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldclr4_relax(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_relaxed); + } + +-uint32_t ghc___aarch64_ldclr4_acq(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldclr4_acq(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldclr4_acq(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldclr4_acq(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_acquire); + } + +-uint32_t ghc___aarch64_ldclr4_rel(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldclr4_rel(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldclr4_rel(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldclr4_rel(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_release); + } + +-uint32_t ghc___aarch64_ldclr4_acq_rel(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldclr4_acq_rel(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldclr4_acq_rel(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldclr4_acq_rel(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_acq_rel); + } + +-uint32_t ghc___aarch64_ldclr4_sync(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldclr4_sync(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldclr4_sync(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldclr4_sync(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_seq_cst); + } + +-uint64_t ghc___aarch64_ldclr8_relax(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldclr8_relax(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldclr8_relax(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldclr8_relax(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_relaxed); + } + +-uint64_t ghc___aarch64_ldclr8_acq(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldclr8_acq(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldclr8_acq(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldclr8_acq(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_acquire); + } + +-uint64_t ghc___aarch64_ldclr8_rel(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldclr8_rel(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldclr8_rel(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldclr8_rel(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_release); + } + +-uint64_t ghc___aarch64_ldclr8_acq_rel(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldclr8_acq_rel(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldclr8_acq_rel(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldclr8_acq_rel(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_acq_rel); + } + +-uint64_t ghc___aarch64_ldclr8_sync(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldclr8_sync(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldclr8_sync(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldclr8_sync(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_and_explicit(p, v, memory_order_seq_cst); + } + +-uint8_t ghc___aarch64_ldeor1_relax(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldeor1_relax(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldeor1_relax(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldeor1_relax(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_relaxed); + } + +-uint8_t ghc___aarch64_ldeor1_acq(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldeor1_acq(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldeor1_acq(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldeor1_acq(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_acquire); + } + +-uint8_t ghc___aarch64_ldeor1_rel(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldeor1_rel(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldeor1_rel(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldeor1_rel(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_release); + } + +-uint8_t ghc___aarch64_ldeor1_acq_rel(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldeor1_acq_rel(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldeor1_acq_rel(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldeor1_acq_rel(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_acq_rel); + } + +-uint8_t ghc___aarch64_ldeor1_sync(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldeor1_sync(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldeor1_sync(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldeor1_sync(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_seq_cst); + } + +-uint16_t ghc___aarch64_ldeor2_relax(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldeor2_relax(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldeor2_relax(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldeor2_relax(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_relaxed); + } + +-uint16_t ghc___aarch64_ldeor2_acq(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldeor2_acq(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldeor2_acq(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldeor2_acq(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_acquire); + } + +-uint16_t ghc___aarch64_ldeor2_rel(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldeor2_rel(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldeor2_rel(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldeor2_rel(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_release); + } + +-uint16_t ghc___aarch64_ldeor2_acq_rel(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldeor2_acq_rel(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldeor2_acq_rel(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldeor2_acq_rel(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_acq_rel); + } + +-uint16_t ghc___aarch64_ldeor2_sync(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldeor2_sync(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldeor2_sync(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldeor2_sync(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_seq_cst); + } + +-uint32_t ghc___aarch64_ldeor4_relax(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldeor4_relax(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldeor4_relax(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldeor4_relax(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_relaxed); + } + +-uint32_t ghc___aarch64_ldeor4_acq(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldeor4_acq(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldeor4_acq(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldeor4_acq(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_acquire); + } + +-uint32_t ghc___aarch64_ldeor4_rel(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldeor4_rel(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldeor4_rel(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldeor4_rel(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_release); + } + +-uint32_t ghc___aarch64_ldeor4_acq_rel(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldeor4_acq_rel(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldeor4_acq_rel(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldeor4_acq_rel(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_acq_rel); + } + +-uint32_t ghc___aarch64_ldeor4_sync(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldeor4_sync(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldeor4_sync(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldeor4_sync(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_seq_cst); + } + +-uint64_t ghc___aarch64_ldeor8_relax(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldeor8_relax(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldeor8_relax(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldeor8_relax(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_relaxed); + } + +-uint64_t ghc___aarch64_ldeor8_acq(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldeor8_acq(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldeor8_acq(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldeor8_acq(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_acquire); + } + +-uint64_t ghc___aarch64_ldeor8_rel(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldeor8_rel(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldeor8_rel(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldeor8_rel(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_release); + } + +-uint64_t ghc___aarch64_ldeor8_acq_rel(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldeor8_acq_rel(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldeor8_acq_rel(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldeor8_acq_rel(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_acq_rel); + } + +-uint64_t ghc___aarch64_ldeor8_sync(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldeor8_sync(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldeor8_sync(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldeor8_sync(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_xor_explicit(p, v, memory_order_seq_cst); + } + +-uint8_t ghc___aarch64_ldset1_relax(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldset1_relax(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldset1_relax(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldset1_relax(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_relaxed); + } + +-uint8_t ghc___aarch64_ldset1_acq(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldset1_acq(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldset1_acq(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldset1_acq(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_acquire); + } + +-uint8_t ghc___aarch64_ldset1_rel(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldset1_rel(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldset1_rel(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldset1_rel(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_release); + } + +-uint8_t ghc___aarch64_ldset1_acq_rel(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldset1_acq_rel(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldset1_acq_rel(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldset1_acq_rel(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_acq_rel); + } + +-uint8_t ghc___aarch64_ldset1_sync(uint8_t v, uint8_t* p); +-uint8_t ghc___aarch64_ldset1_sync(uint8_t v, uint8_t* p) { ++uint8_t ghc___aarch64_ldset1_sync(uint8_t v, atomic_uint_least8_t* p); ++uint8_t ghc___aarch64_ldset1_sync(uint8_t v, atomic_uint_least8_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_seq_cst); + } + +-uint16_t ghc___aarch64_ldset2_relax(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldset2_relax(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldset2_relax(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldset2_relax(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_relaxed); + } + +-uint16_t ghc___aarch64_ldset2_acq(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldset2_acq(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldset2_acq(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldset2_acq(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_acquire); + } + +-uint16_t ghc___aarch64_ldset2_rel(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldset2_rel(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldset2_rel(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldset2_rel(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_release); + } + +-uint16_t ghc___aarch64_ldset2_acq_rel(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldset2_acq_rel(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldset2_acq_rel(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldset2_acq_rel(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_acq_rel); + } + +-uint16_t ghc___aarch64_ldset2_sync(uint16_t v, uint16_t* p); +-uint16_t ghc___aarch64_ldset2_sync(uint16_t v, uint16_t* p) { ++uint16_t ghc___aarch64_ldset2_sync(uint16_t v, atomic_uint_least16_t* p); ++uint16_t ghc___aarch64_ldset2_sync(uint16_t v, atomic_uint_least16_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_seq_cst); + } + +-uint32_t ghc___aarch64_ldset4_relax(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldset4_relax(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldset4_relax(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldset4_relax(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_relaxed); + } + +-uint32_t ghc___aarch64_ldset4_acq(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldset4_acq(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldset4_acq(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldset4_acq(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_acquire); + } + +-uint32_t ghc___aarch64_ldset4_rel(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldset4_rel(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldset4_rel(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldset4_rel(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_release); + } + +-uint32_t ghc___aarch64_ldset4_acq_rel(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldset4_acq_rel(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldset4_acq_rel(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldset4_acq_rel(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_acq_rel); + } + +-uint32_t ghc___aarch64_ldset4_sync(uint32_t v, uint32_t* p); +-uint32_t ghc___aarch64_ldset4_sync(uint32_t v, uint32_t* p) { ++uint32_t ghc___aarch64_ldset4_sync(uint32_t v, atomic_uint_least32_t* p); ++uint32_t ghc___aarch64_ldset4_sync(uint32_t v, atomic_uint_least32_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_seq_cst); + } + +-uint64_t ghc___aarch64_ldset8_relax(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldset8_relax(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldset8_relax(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldset8_relax(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_relaxed); + } + +-uint64_t ghc___aarch64_ldset8_acq(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldset8_acq(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldset8_acq(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldset8_acq(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_acquire); + } + +-uint64_t ghc___aarch64_ldset8_rel(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldset8_rel(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldset8_rel(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldset8_rel(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_release); + } + +-uint64_t ghc___aarch64_ldset8_acq_rel(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldset8_acq_rel(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldset8_acq_rel(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldset8_acq_rel(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_acq_rel); + } + +-uint64_t ghc___aarch64_ldset8_sync(uint64_t v, uint64_t* p); +-uint64_t ghc___aarch64_ldset8_sync(uint64_t v, uint64_t* p) { ++uint64_t ghc___aarch64_ldset8_sync(uint64_t v, atomic_uint_least64_t* p); ++uint64_t ghc___aarch64_ldset8_sync(uint64_t v, atomic_uint_least64_t* p) { + return atomic_fetch_or_explicit(p, v, memory_order_seq_cst); + } + diff --git a/overlays/patches/ghc/ghc-9.8-android-convert-os.patch b/overlays/patches/ghc/ghc-9.8-android-convert-os.patch new file mode 100644 index 000000000..bdbf1db0a --- /dev/null +++ b/overlays/patches/ghc/ghc-9.8-android-convert-os.patch @@ -0,0 +1,13 @@ +diff --git a/m4/ghc_convert_os.m4 b/m4/ghc_convert_os.m4 +index 586b33d09b..275bd997eb 100644 +--- a/m4/ghc_convert_os.m4 ++++ b/m4/ghc_convert_os.m4 +@@ -10,7 +10,7 @@ AC_DEFUN([GHC_CONVERT_OS],[ + ios|watchos|tvos) + $3="ios" + ;; +- linux-android*) ++ linux-android*|android) + $3="linux-android" + ;; + linux-*|linux) diff --git a/overlays/patches/ghc/ghc-9.8-hadrian-strip-cmd.patch b/overlays/patches/ghc/ghc-9.8-hadrian-strip-cmd.patch new file mode 100644 index 000000000..e6dc4079e --- /dev/null +++ b/overlays/patches/ghc/ghc-9.8-hadrian-strip-cmd.patch @@ -0,0 +1,55 @@ +diff --git a/hadrian/cfg/system.config.in b/hadrian/cfg/system.config.in +index 4912673869..85b5c58c2a 100644 +--- a/hadrian/cfg/system.config.in ++++ b/hadrian/cfg/system.config.in +@@ -18,6 +18,7 @@ merge-objects = @MergeObjsCmd@ + system-merge-objects = @LD_STAGE0@ + objdump = @ObjdumpCmd@ + ranlib = @REAL_RANLIB_CMD@ ++strip = @StripCmd@ + sphinx-build = @SPHINXBUILD@ + system-ar = @AR_STAGE0@ + system-cc = @CC_STAGE0@ +diff --git a/hadrian/src/Oracles/Setting.hs b/hadrian/src/Oracles/Setting.hs +index a0f639d325..55f9a2f902 100644 +--- a/hadrian/src/Oracles/Setting.hs ++++ b/hadrian/src/Oracles/Setting.hs +@@ -73,6 +73,7 @@ data Setting = BuildArch + | ProjectPatchLevel + | ProjectPatchLevel1 + | ProjectPatchLevel2 ++ | Strip + | SystemGhc + | TargetArch + | TargetOs +@@ -176,6 +177,7 @@ setting key = lookupSystemConfig $ case key of + ProjectPatchLevel -> "project-patch-level" + ProjectPatchLevel1 -> "project-patch-level1" + ProjectPatchLevel2 -> "project-patch-level2" ++ Strip -> "strip" + SystemGhc -> "system-ghc" + TargetArch -> "target-arch" + TargetArmVersion -> "target-arm-version" +diff --git a/hadrian/src/Settings/Builders/Cabal.hs b/hadrian/src/Settings/Builders/Cabal.hs +index 75eb78ccd8..6904c973d4 100644 +--- a/hadrian/src/Settings/Builders/Cabal.hs ++++ b/hadrian/src/Settings/Builders/Cabal.hs +@@ -85,15 +85,11 @@ commonCabalArgs :: Stage -> Args + commonCabalArgs stage = do + verbosity <- expr getVerbosity + pkg <- getPackage ++ strip <- getSetting Strip + package_id <- expr $ pkgUnitId stage pkg + let prefix = "${pkgroot}" ++ (if windowsHost then "" else "/..") +- mconcat [ -- Don't strip libraries when cross compiling. +- -- TODO: We need to set @--with-strip=(stripCmdPath :: Action FilePath)@, +- -- and if it's @:@ disable stripping as well. As it is now, I believe +- -- we might have issues with stripping on Windows, as I can't see a +- -- consumer of 'stripCmdPath'. +- -- TODO: See https://github.com/snowleopard/hadrian/issues/549. +- flag CrossCompiling ? pure [ "--disable-executable-stripping" ++ mconcat [ notStage0 ? strip /= "" ? pure [ "--with-strip=" ++ strip ] ++ , flag CrossCompiling ? pure [ "--disable-executable-stripping" + , "--disable-library-stripping" ] + -- We don't want to strip the debug RTS + , S.package rts ? pure [ "--disable-executable-stripping" diff --git a/overlays/patches/ghc/ghc-9.8.3-iog.patch b/overlays/patches/ghc/ghc-9.8.3-iog.patch new file mode 100644 index 000000000..8f2df690c --- /dev/null +++ b/overlays/patches/ghc/ghc-9.8.3-iog.patch @@ -0,0 +1,356 @@ +diff --git a/rts/Linker.c b/rts/Linker.c +index 1f229f8173..7f954702a3 100644 +--- a/rts/Linker.c ++++ b/rts/Linker.c +@@ -273,7 +273,7 @@ int ghciInsertSymbolTable( + RtsSymbolInfo *pinfo = lookupStrHashTable(table, key); + if (!pinfo) /* new entry */ + { +- pinfo = stgMallocBytes(sizeof (*pinfo), "ghciInsertToSymbolTable"); ++ pinfo = stgCallocBytes(1, sizeof (*pinfo), "ghciInsertToSymbolTable"); + pinfo->value = data; + pinfo->owner = owner; + pinfo->strength = strength; +@@ -1203,7 +1203,7 @@ mkOc( ObjectType type, pathchar *path, char *image, int imageSize, + + + IF_DEBUG(linker, debugBelch("mkOc: %" PATH_FMT "\n", path)); +- oc = stgMallocBytes(sizeof(ObjectCode), "mkOc(oc)"); ++ oc = stgCallocBytes(1, sizeof(ObjectCode), "mkOc(oc)"); + + oc->info = NULL; + oc->type = type; +@@ -1223,7 +1223,7 @@ mkOc( ObjectType type, pathchar *path, char *image, int imageSize, + oc->fileName = pathdup(path); + + if (archiveMemberName) { +- oc->archiveMemberName = stgMallocBytes( (pathlen(archiveMemberName)+1) * pathsize, ++ oc->archiveMemberName = stgCallocBytes(1, (pathlen(archiveMemberName)+1) * pathsize, + "loadObj" ); + pathcopy(oc->archiveMemberName, archiveMemberName); + } else { +@@ -1380,12 +1380,12 @@ preloadObjectFile (pathchar *path) + // reading the file, and then we misalign image on purpose so + // that the actual sections end up aligned again. + misalignment = machoGetMisalignment(f); +- image = stgMallocBytes(fileSize + misalignment, "loadObj(image)"); ++ image = stgCallocBytes(1, fileSize + misalignment, "loadObj(image)"); + image += misalignment; + + # else /* !defined(darwin_HOST_OS) */ + +- image = stgMallocBytes(fileSize, "loadObj(image)"); ++ image = stgCallocBytes(1, fileSize, "loadObj(image)"); + + #endif /* !defined(darwin_HOST_OS) */ + +@@ -1678,6 +1678,8 @@ static HsInt resolveObjs_ (void) + IF_DEBUG(linker, debugBelch("resolveObjs: start\n")); + + for (ObjectCode *oc = objects; oc; oc = oc->next) { ++ if(oc->status == OBJECT_RESOLVED) ++ continue; + int r = ocTryLoad(oc); + if (!r) { + errorBelch("Could not load Object Code %" PATH_FMT ".\n", OC_INFORMATIVE_FILENAME(oc)); +@@ -1806,7 +1808,7 @@ void + addProddableBlock ( ObjectCode* oc, void* start, int size ) + { + ProddableBlock* pb +- = stgMallocBytes(sizeof(ProddableBlock), "addProddableBlock"); ++ = stgCallocBytes(1,sizeof(ProddableBlock), "addProddableBlock"); + + IF_DEBUG(linker, debugBelch("addProddableBlock: %p %p %d\n", oc, start, size)); + ASSERT(size > 0); +diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h +index e6098aa2b0..4b8992e817 100644 +--- a/rts/LinkerInternals.h ++++ b/rts/LinkerInternals.h +@@ -299,6 +299,10 @@ struct _ObjectCode { + int n_segments; + Segment *segments; + ++ // COMMON section ++ void * common_mem; ++ unsigned long common_size; ++ + // + // Garbage collection fields + // +diff --git a/rts/RtsUtils.c b/rts/RtsUtils.c +index 4cac10ba15..fe0d8ca40e 100644 +--- a/rts/RtsUtils.c ++++ b/rts/RtsUtils.c +@@ -104,6 +104,11 @@ stgCallocBytes (size_t count, size_t size, char *msg) + rtsConfig.mallocFailHook((W_) count*size, msg); + stg_exit(EXIT_INTERNAL_ERROR); + } ++ // If we run under qemu with jemalloc, calloc is not guaranteed ++ // to zero memory. ++ // - https://giters.com/jemalloc/jemalloc/issues/1844 ++ // - https://lists.nongnu.org/archive/html/qemu-devel/2020-05/msg03119.html ++ memset(space, 0, count*size); + return space; + } + +diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c +index d181450190..1ad05fc286 100644 +--- a/rts/linker/Elf.c ++++ b/rts/linker/Elf.c +@@ -307,6 +307,15 @@ ocInit_ELF(ObjectCode * oc) + } + } + } ++ if(NULL != oc->common_mem) { ++#if RTS_LINKER_USE_MMAP ++ munmap(oc->common_mem, oc->common_size); ++#else ++ stgFree(oc->common_mem); ++#endif ++ } ++ oc->common_mem = NULL; ++ oc->common_size = 0; + } + + void +@@ -963,14 +972,17 @@ ocGetNames_ELF ( ObjectCode* oc ) + for (size_t j = 0; j < symTab->n_symbols; j++) { + ElfSymbol *symbol = &symTab->symbols[j]; + if (SHN_COMMON == symTab->symbols[j].elf_sym->st_shndx) { +- common_size += symbol->elf_sym->st_size; ++ // st_value holds the alignment. Adding alignment always ++ // should give us some wiggle room to get alignment right. ++ common_size += symbol->elf_sym->st_size + symbol->elf_sym->st_value; + } + } + } +- void * common_mem = NULL; ++ oc->common_mem = NULL; ++ oc->common_size = common_size; + if(common_size > 0) { +- common_mem = mmapAnonForLinker(common_size); +- if (common_mem == NULL) { ++ oc->common_mem = mmapAnonForLinker(common_size); ++ if (oc->common_mem == NULL) { + barf("ocGetNames_ELF: Failed to allocate memory for SHN_COMMONs"); + } + } +@@ -1011,9 +1023,10 @@ ocGetNames_ELF ( ObjectCode* oc ) + if (shndx == SHN_COMMON) { + isLocal = false; + CHECK(common_used < common_size); +- CHECK(common_mem); +- symbol->addr = (void*)((uintptr_t)common_mem + common_used); +- common_used += symbol->elf_sym->st_size; ++ CHECK(oc->common_mem); ++ int alignment = symbol->elf_sym->st_value-1; ++ symbol->addr = (void*)(((uintptr_t)oc->common_mem + common_used + alignment) & ~alignment); ++ common_used = (uintptr_t)symbol->addr - (uintptr_t)oc->common_mem + symbol->elf_sym->st_size; + CHECK(common_used <= common_size); + + IF_DEBUG(linker_verbose, +@@ -1027,7 +1040,9 @@ ocGetNames_ELF ( ObjectCode* oc ) + || ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK + ) + /* and not an undefined symbol */ +- && shndx != SHN_UNDEF ++ && (shndx != SHN_UNDEF ++ /* unless it's weak */ ++ || (shndx == SHN_UNDEF && ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK)) + /* and not in a "special section" */ + && (shndx < SHN_LORESERVE + #if defined(SHN_XINDEX) +@@ -1054,6 +1069,14 @@ ocGetNames_ELF ( ObjectCode* oc ) + (intptr_t) oc->sections[secno].start + + (intptr_t) symbol->elf_sym->st_value); + CHECK(symbol->addr != 0x0); ++ if(shndx == SHN_UNDEF && ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK) { ++ symbol->addr = NULL; ++ } else { ++ symbol->addr = (SymbolAddr*)( ++ (intptr_t) oc->sections[secno].start + ++ (intptr_t) symbol->elf_sym->st_value); ++ CHECK(symbol->addr != 0x0); ++ } + if (ELF_ST_BIND(symbol->elf_sym->st_info) == STB_LOCAL) { + isLocal = true; + isWeak = false; +@@ -1065,42 +1088,20 @@ ocGetNames_ELF ( ObjectCode* oc ) + isWeak = ELF_ST_BIND(symbol->elf_sym->st_info) + == STB_WEAK; + } +- } +- +- SymType sym_type; +- if (ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_FUNC) { +- sym_type = SYM_TYPE_CODE; ++ } else if (ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK ++ && shndx == SHN_UNDEF ++ && (ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_FUNC ++ || ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_OBJECT ++ || ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_NOTYPE)) { ++ symbol->addr = NULL; ++ isLocal = false; ++ isWeak = true; + } else { +- sym_type = SYM_TYPE_DATA; +- } +- +- /* And the decision is ... */ +- +- if (symbol->addr != NULL) { +- CHECK(nm != NULL); +- /* Acquire! */ +- if (!isLocal) { +- +- if (isWeak == HS_BOOL_TRUE) { +- setWeakSymbol(oc, nm); +- } +- if (!ghciInsertSymbolTable(oc->fileName, symhash, +- nm, symbol->addr, isWeak, sym_type, oc) +- ) { +- goto fail; +- } +- oc->symbols[curSymbol].name = nm; +- oc->symbols[curSymbol].addr = symbol->addr; +- oc->symbols[curSymbol].type = sym_type; +- curSymbol++; +- } +- } else { +- /* Skip. */ ++ /* Skip. */ + IF_DEBUG(linker_verbose, + debugBelch("skipping `%s'\n", + nm) + ); +- + /* + debugBelch( + "skipping bind = %d, type = %d, secno = %d `%s'\n", +@@ -1110,7 +1111,34 @@ ocGetNames_ELF ( ObjectCode* oc ) + nm + ); + */ ++ continue; + } ++ ++ SymType sym_type; ++ if (ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_FUNC) { ++ sym_type = SYM_TYPE_CODE; ++ } else { ++ sym_type = SYM_TYPE_DATA; ++ } ++ ++ /* And the decision is ... */ ++ CHECK(nm != NULL); ++ /* Acquire! */ ++ if (!isLocal) { ++ ++ if (isWeak == HS_BOOL_TRUE) { ++ setWeakSymbol(oc, nm); ++ } ++ if (!ghciInsertSymbolTable(oc->fileName, symhash, ++ nm, symbol->addr, isWeak, sym_type, oc) ++ ) { ++ goto fail; ++ } ++ oc->symbols[curSymbol].name = nm; ++ oc->symbols[curSymbol].addr = symbol->addr; ++ oc->symbols[curSymbol].type = sym_type; ++ curSymbol++; ++ } + } + } + } +diff --git a/rts/linker/elf_plt.c b/rts/linker/elf_plt.c +index 5c6ef8ed44..314d49cbc6 100644 +--- a/rts/linker/elf_plt.c ++++ b/rts/linker/elf_plt.c +@@ -1,4 +1,5 @@ + #include "Rts.h" ++#include "RtsUtils.h" + #include "elf_plt.h" + + #include +@@ -51,7 +52,7 @@ makeStub(Section * section, + void* * addr, + uint8_t flags) { + +- Stub * s = calloc(1, sizeof(Stub)); ++ Stub * s = stgCallocBytes(1, sizeof(Stub), "makeStub"); + ASSERT(s != NULL); + s->target = *addr; + s->flags = flags; +diff --git a/rts/linker/elf_plt_aarch64.c b/rts/linker/elf_plt_aarch64.c +index 11354a63db..6b27a2c73d 100644 +--- a/rts/linker/elf_plt_aarch64.c ++++ b/rts/linker/elf_plt_aarch64.c +@@ -25,6 +25,7 @@ const size_t stubSizeAarch64 = 5 * 4; + */ + bool needStubForRelAarch64(Elf_Rel * rel) { + switch(ELF64_R_TYPE(rel->r_info)) { ++ case COMPAT_R_AARCH64_CONDBR19: + case COMPAT_R_AARCH64_CALL26: + case COMPAT_R_AARCH64_JUMP26: + return true; +@@ -34,6 +35,7 @@ bool needStubForRelAarch64(Elf_Rel * rel) { + } + bool needStubForRelaAarch64(Elf_Rela * rela) { + switch(ELF64_R_TYPE(rela->r_info)) { ++ case COMPAT_R_AARCH64_CONDBR19: + case COMPAT_R_AARCH64_CALL26: + case COMPAT_R_AARCH64_JUMP26: + return true; +diff --git a/rts/linker/elf_reloc_aarch64.c b/rts/linker/elf_reloc_aarch64.c +index 51d7178094..dc0724c4f1 100644 +--- a/rts/linker/elf_reloc_aarch64.c ++++ b/rts/linker/elf_reloc_aarch64.c +@@ -105,8 +105,24 @@ encodeAddendAarch64(Section * section, Elf_Rel * rel, int64_t addend) { + break; + } + /* - control flow relocations */ ++ case COMPAT_R_AARCH64_CONDBR19: { /* relocate b.* ... */ ++ // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 ++ // 0 1 0 1 0 1 0 0 [ imm19 ... ++ // ++ // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ++ // ... imm19 ] 0 [ cond ] ++ CHECK(isInt64(19+2, addend)); /* X in range */ ++ *(inst_t *)P = (*(inst_t *)P & 0xff00001f) ++ | ((uint32_t)(addend << (5-2)) & 0x00ffffe0); ++ break; ++ } + case COMPAT_R_AARCH64_JUMP26: /* relocate b ... */ + case COMPAT_R_AARCH64_CALL26: { /* relocate bl ... */ ++ // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 ++ // 0|1 0 0 1 0 1 [ imm26 ... ++ ++ // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ++ // ... imm26 ] + CHECK(isInt64(26+2, addend)); /* X in range */ + *(inst_t *)P = (*(inst_t *)P & 0xfc000000) /* keep upper 6 (32-6) + * bits */ +@@ -222,6 +238,23 @@ computeAddend(Section * section, Elf_Rel * rel, + case COMPAT_R_AARCH64_ADD_ABS_LO12_NC: + /* type: static, class: aarch64, op: S + A */ + return (S + A) & 0xfff; ++ case COMPAT_R_AARCH64_CONDBR19: { ++ int64_t V = S + A - P; ++ if(!isInt64(19+2, V)) { ++ /* need a stub */ ++ /* check if we already have that stub */ ++ if(findStub(section, (void**)&S, 0)) { ++ /* did not find it. Crete a new stub. */ ++ if(makeStub(section, (void**)&S, 0)) { ++ abort(/* could not find or make stub */); ++ } ++ } ++ ++ V = S + A -P; ++ assert(isInt64(19+2, V)); ++ } ++ return V; ++ } + case COMPAT_R_AARCH64_JUMP26: + case COMPAT_R_AARCH64_CALL26: { + // S+A-P diff --git a/overlays/patches/ghc/ghc-define-undefined-elf-st-visibility.patch b/overlays/patches/ghc/ghc-define-undefined-elf-st-visibility.patch new file mode 100644 index 000000000..bd3b3ea60 --- /dev/null +++ b/overlays/patches/ghc/ghc-define-undefined-elf-st-visibility.patch @@ -0,0 +1,24 @@ +diff --git a/rts/linker/ElfTypes.h b/rts/linker/ElfTypes.h +index f5e2f819d9..7f75087738 100644 +--- a/rts/linker/ElfTypes.h ++++ b/rts/linker/ElfTypes.h +@@ -33,6 +33,9 @@ + #define Elf_Sym Elf64_Sym + #define Elf_Rel Elf64_Rel + #define Elf_Rela Elf64_Rela ++#if !defined(ELF64_ST_VISIBILITY) ++#define ELF64_ST_VISIBILITY(o) ((o)&0x3) ++#endif + #if !defined(ELF_ST_VISIBILITY) + #define ELF_ST_VISIBILITY ELF64_ST_VISIBILITY + #endif +@@ -60,6 +63,9 @@ + #define Elf_Sym Elf32_Sym + #define Elf_Rel Elf32_Rel + #define Elf_Rela Elf32_Rela ++#if !defined(ELF32_ST_VISIBILITY) ++#define ELF32_ST_VISIBILITY(o) ((o)&0x3) ++#endif + #if !defined(ELF_ST_VISIBILITY) + #define ELF_ST_VISIBILITY ELF32_ST_VISIBILITY + #endif /* ELF_ST_VISIBILITY */ diff --git a/overlays/patches/ghc/libc-memory-symbols-armv7a.patch b/overlays/patches/ghc/libc-memory-symbols-armv7a.patch new file mode 100644 index 000000000..c705bdda8 --- /dev/null +++ b/overlays/patches/ghc/libc-memory-symbols-armv7a.patch @@ -0,0 +1,42 @@ +diff --git a/rts/Linker.c b/rts/Linker.c +index 062159f..727fe74 100644 +--- a/rts/Linker.c ++++ b/rts/Linker.c +@@ -340,6 +340,20 @@ int ghciInsertSymbolTable( + call this function again to trigger the duplicate error. */ + return 1; + } ++ else if(strncmp(key, "fprintf", 7) == 0 ++ || strncmp(key, "printf", 6) == 0 ++ || strncmp(key, "sprintf", 7) == 0 ++ || strncmp(key, "snprintf", 8) == 0 ++ || strncmp(key, "getauxval", 9) == 0 ++ || strncmp(key, "free", 4) == 0 ++ || strncmp(key, "malloc", 6) == 0 ++ || strncmp(key, "calloc", 6) == 0 ++ || strncmp(key, "realloc", 7) == 0 ++ || strncmp(key, "reallocarray", 12) == 0 ++ ) { ++ /* symbols we link aginst the libc we link ghc or iserv against */ ++ return 1; ++ } + + pathchar* archiveName = NULL; + debugBelch( +diff --git a/rts/RtsSymbols.c b/rts/RtsSymbols.c +index 2acd634..b86b516 100644 +--- a/rts/RtsSymbols.c ++++ b/rts/RtsSymbols.c +@@ -1039,7 +1039,11 @@ + SymI_HasProto(printf) \ + SymI_HasProto(fprintf) \ + SymI_HasProto(sprintf) \ +- SymI_HasProto(snprintf) ++ SymI_HasProto(snprintf) \ ++ SymI_HasProto(free) \ ++ SymI_HasProto(malloc) \ ++ SymI_HasProto(calloc) \ ++ SymI_HasProto(realloc) + #else + #define RTS_STACK_PROTECTOR_SYMBOLS + #define RTS_LIBC_SYMBOLS \ No newline at end of file diff --git a/overlays/patches/ghc/libraries-prim-os-android-armv7a.patch b/overlays/patches/ghc/libraries-prim-os-android-armv7a.patch new file mode 100644 index 000000000..23274bf73 --- /dev/null +++ b/overlays/patches/ghc/libraries-prim-os-android-armv7a.patch @@ -0,0 +1,13 @@ +diff --git a/libraries/ghc-prim/ghc-prim.cabal b/libraries/ghc-prim/ghc-prim.cabal +index 2bd51c0..aeaeacc 100644 +--- a/libraries/ghc-prim/ghc-prim.cabal ++++ b/libraries/ghc-prim/ghc-prim.cabal +@@ -67,7 +67,7 @@ Library + -- on Windows. Required because of mingw32. + extra-libraries: user32, mingw32, mingwex + +- if os(linux) ++ if os(linux) || os(android) || os(linux-android) + -- we need libm, but for musl and other's we might need libc, as libm + -- is just an empty shell. + extra-libraries: c, m diff --git a/overlays/patches/iserv-proxy-interpreter-9.3-android.patch b/overlays/patches/iserv-proxy-interpreter-9.3-android.patch index 12f3dda3f..ec106c1e6 100644 --- a/overlays/patches/iserv-proxy-interpreter-9.3-android.patch +++ b/overlays/patches/iserv-proxy-interpreter-9.3-android.patch @@ -324,14 +324,17 @@ index 0000000..d447895 +} \ No newline at end of file diff --git a/iserv-proxy.cabal b/iserv-proxy.cabal -index a0eeaeb..a146108 100644 +index 5f1449a..328b000 100644 --- a/iserv-proxy.cabal +++ b/iserv-proxy.cabal -@@ -103,6 +103,7 @@ Executable iserv-proxy +@@ -106,9 +106,7 @@ Executable iserv-proxy-interpreter -- We need to pass -fkeep-cafs to ensure that the interpreter retains CAFs -- Iserv and GHC do something similar. ghc-options: -fkeep-cafs +- -- no idea how to check for musl :-/ +- if os(linux) && arch(aarch64) +- c-sources: cbits/symbols.aarch64-musl.c + c-sources: cbits/symbols.c + Build-Depends: base >= 4 && < 5, iserv-proxy - diff --git a/overlays/patches/iserv-proxy-interpreter-9.3-android32.patch b/overlays/patches/iserv-proxy-interpreter-9.3-android32.patch index 7aeba03e0..f91fbb797 100644 --- a/overlays/patches/iserv-proxy-interpreter-9.3-android32.patch +++ b/overlays/patches/iserv-proxy-interpreter-9.3-android32.patch @@ -453,14 +453,17 @@ index 0000000..9974c73 +} \ No newline at end of file diff --git a/iserv-proxy.cabal b/iserv-proxy.cabal -index eca2047..51a125b 100644 +index 5f1449a..328b000 100644 --- a/iserv-proxy.cabal +++ b/iserv-proxy.cabal -@@ -104,6 +104,7 @@ Executable iserv-proxy-interpreter +@@ -106,9 +106,7 @@ Executable iserv-proxy-interpreter -- We need to pass -fkeep-cafs to ensure that the interpreter retains CAFs -- Iserv and GHC do something similar. ghc-options: -fkeep-cafs +- -- no idea how to check for musl :-/ +- if os(linux) && arch(aarch64) +- c-sources: cbits/symbols.aarch64-musl.c + c-sources: cbits/symbols.c + Build-Depends: base >= 4 && < 5, iserv-proxy - diff --git a/test/gi-gtk/default.nix b/test/gi-gtk/default.nix index c8ef2232a..540863449 100644 --- a/test/gi-gtk/default.nix +++ b/test/gi-gtk/default.nix @@ -30,6 +30,8 @@ in recurseIntoAttrs rec { || builtins.elem compiler-nix-name ["ghc8107" "ghc902" "ghc928" "ghc948"] && stdenv.hostPlatform.isAarch64 # Cross compilation to aarch64 is also broken || stdenv.hostPlatform.isAarch64 && !stdenv.buildPlatform.isAarch64 + # glu is marked ase broken for isAndroid + || stdenv.hostPlatform.isAndroid # Building profiled version of Cabal for haskell-gi is currently broken for GHC head || compiler-nix-name == "ghc91320241204";