diff --git a/pkgs/development/compilers/llvm/4/llvm.nix b/pkgs/development/compilers/llvm/4/llvm.nix index 1fe79d9300a..33147b07599 100644 --- a/pkgs/development/compilers/llvm/4/llvm.nix +++ b/pkgs/development/compilers/llvm/4/llvm.nix @@ -24,11 +24,6 @@ let src = fetch "llvm" "0l9bf7kdwhlj0kq1hawpyxhna1062z3h7qcz2y8nfl9dz2qksy6s"; - aarch64Patch = fetchpatch { - url = https://reviews.llvm.org/file/data/2oqw5rhhklsapbjrhlpd/PHID-FILE-lvo4fcs6hjvkxb5wneg2/D40423.diff; - sha256 = "0b0h7n7lxw33pn2j061hm9050zn263gmiig937g5cmcvjimxlybb"; - }; - # Used when creating a version-suffixed symlink of libLLVM.dylib shortVersion = with stdenv.lib; concatStringsSep "." (take 2 (splitString "." release_version)); @@ -87,7 +82,7 @@ in stdenv.mkDerivation rec { --replace 'struct sigaltstack' 'stack_t' ) '' + stdenv.lib.optionalString stdenv.isAarch64 '' - patch -p0 < ${aarch64Patch} + patch -p0 < ${../aarch64.patch} ''; # hacky fix: created binaries need to be run before installation diff --git a/pkgs/development/compilers/llvm/5/llvm.nix b/pkgs/development/compilers/llvm/5/llvm.nix index 20b0f4b20c6..8358b6b18c3 100644 --- a/pkgs/development/compilers/llvm/5/llvm.nix +++ b/pkgs/development/compilers/llvm/5/llvm.nix @@ -24,11 +24,6 @@ let src = fetch "llvm" "1nin64vz21hyng6jr19knxipvggaqlkl2l9jpd5czbc4c2pcnpg3"; - aarch64Patch = fetchpatch { - url = https://reviews.llvm.org/file/data/2oqw5rhhklsapbjrhlpd/PHID-FILE-lvo4fcs6hjvkxb5wneg2/D40423.diff; - sha256 = "0b0h7n7lxw33pn2j061hm9050zn263gmiig937g5cmcvjimxlybb"; - }; - # Used when creating a version-suffixed symlink of libLLVM.dylib shortVersion = with stdenv.lib; concatStringsSep "." (take 2 (splitString "." release_version)); @@ -81,7 +76,7 @@ in stdenv.mkDerivation rec { # Revert compiler-rt commit that makes codesign mandatory patch -p1 -i ${./compiler-rt-codesign.patch} -d projects/compiler-rt '' + stdenv.lib.optionalString stdenv.isAarch64 '' - patch -p0 < ${aarch64Patch} + patch -p0 < ${../aarch64.patch} ''; # hacky fix: created binaries need to be run before installation diff --git a/pkgs/development/compilers/llvm/aarch64.patch b/pkgs/development/compilers/llvm/aarch64.patch new file mode 100644 index 00000000000..205074e48e4 --- /dev/null +++ b/pkgs/development/compilers/llvm/aarch64.patch @@ -0,0 +1,51 @@ +--- lib/Support/Unix/Memory.inc ++++ lib/Support/Unix/Memory.inc +@@ -126,8 +126,12 @@ + Result.Address = Addr; + Result.Size = NumPages*PageSize; + +- if (PFlags & MF_EXEC) +- Memory::InvalidateInstructionCache(Result.Address, Result.Size); ++ // Rely on protectMappedMemory to invalidate instruction cache. ++ if (PFlags & MF_EXEC) { ++ EC = Memory::protectMappedMemory (Result, PFlags); ++ if (EC != std::error_code()) ++ return MemoryBlock(); ++ } + + return Result; + } +@@ -156,15 +160,31 @@ + return std::error_code(EINVAL, std::generic_category()); + + int Protect = getPosixProtectionFlags(Flags); +- + uintptr_t Start = alignAddr((uint8_t *)M.Address - PageSize + 1, PageSize); + uintptr_t End = alignAddr((uint8_t *)M.Address + M.Size, PageSize); ++ ++ bool InvalidateCache = (Flags & MF_EXEC); ++ ++#if defined(__arm__) || defined(__aarch64__) ++ // Certain ARM implementations treat icache clear instruction as a memory read, ++ // and CPU segfaults on trying to clear cache on !PROT_READ page. Therefore we need ++ // to temporarily add PROT_READ for the sake of flushing the instruction caches. ++ if (InvalidateCache && !(Protect & PROT_READ)) { ++ int Result = ::mprotect((void *)Start, End - Start, Protect | PROT_READ); ++ if (Result != 0) ++ return std::error_code(errno, std::generic_category()); ++ ++ Memory::InvalidateInstructionCache(M.Address, M.Size); ++ InvalidateCache = false; ++ } ++#endif ++ + int Result = ::mprotect((void *)Start, End - Start, Protect); + + if (Result != 0) + return std::error_code(errno, std::generic_category()); + +- if (Flags & MF_EXEC) ++ if (InvalidateCache) + Memory::InvalidateInstructionCache(M.Address, M.Size); + + return std::error_code();