diff options
Diffstat (limited to 'nixpkgs/pkgs/development/compilers/llvm/aarch64.patch')
-rw-r--r-- | nixpkgs/pkgs/development/compilers/llvm/aarch64.patch | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/development/compilers/llvm/aarch64.patch b/nixpkgs/pkgs/development/compilers/llvm/aarch64.patch new file mode 100644 index 000000000000..205074e48e4e --- /dev/null +++ b/nixpkgs/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(); |