Index: lib/Support/Unix/Memory.inc =================================================================== --- lib/Support/Unix/Memory.inc +++ lib/Support/Unix/Memory.inc @@ -264,15 +264,12 @@ } bool Memory::setExecutable (MemoryBlock &M, std::string *ErrMsg) { -#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__)) if (M.Address == 0 || M.Size == 0) return false; Memory::InvalidateInstructionCache(M.Address, M.Size); +#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__)) kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address, (vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY); return KERN_SUCCESS == kr; -#elif defined(__arm__) || defined(__aarch64__) - Memory::InvalidateInstructionCache(M.Address, M.Size); - return true; #else return true; #endif Index: tools/llvm-rtdyld/llvm-rtdyld.cpp =================================================================== --- tools/llvm-rtdyld/llvm-rtdyld.cpp +++ tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -155,12 +155,6 @@ bool finalizeMemory(std::string *ErrMsg) override { return false; } - // Invalidate instruction cache for sections with execute permissions. - // Some platforms with separate data cache and instruction cache require - // explicit cache flush, otherwise JIT code manipulations (like resolved - // relocations) will get to the data cache but not to the instruction cache. - virtual void invalidateInstructionCache(); - void addDummySymbol(const std::string &Name, uint64_t Addr) { DummyExterns[Name] = Addr; } @@ -244,14 +238,6 @@ return (uint8_t*)MB.base(); } -void TrivialMemoryManager::invalidateInstructionCache() { - for (auto &FM : FunctionMemory) - sys::Memory::InvalidateInstructionCache(FM.base(), FM.size()); - - for (auto &DM : DataMemory) - sys::Memory::InvalidateInstructionCache(DM.base(), DM.size()); -} - static const char *ProgramName; static void Message(const char *Type, const Twine &Msg) { @@ -424,12 +410,9 @@ } } - // Resolve all the relocations we can. - Dyld.resolveRelocations(); - // Clear instruction cache before code will be executed. - MemMgr.invalidateInstructionCache(); - + // Resove all the relocations we can. // FIXME: Error out if there are unresolved relocations. + Dyld.resolveRelocations(); // Get the address of the entry point (_main by default). void *MainAddress = Dyld.getSymbolLocalAddress(EntryPoint); @@ -438,12 +421,15 @@ // Invalidate the instruction cache for each loaded function. for (auto &FM : MemMgr.FunctionMemory) { + // Make sure the memory is executable. + // setExecutable will call InvalidateInstructionCache. std::string ErrorStr; - sys::Memory::InvalidateInstructionCache(FM.base(), FM.size()); if (!sys::Memory::setExecutable(FM, &ErrorStr)) return Error("unable to mark function executable: '" + ErrorStr + "'"); } + for (auto &DM : MemMgr.DataMemory) + sys::Memory::InvalidateInstructionCache(DM.base(), DM.size()); // Dispatch to _main(). errs() << "loaded '" << EntryPoint << "' at: " << (void*)MainAddress << "\n";