From 04cedd3c8f6c7d00e06f63a49aaef05d1d4a726f Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 9 Sep 2009 01:56:29 +0000 Subject: [PATCH] Make sure to make stub region writable before emission, executable after emission. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81311 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMJITInfo.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/lib/Target/ARM/ARMJITInfo.cpp b/lib/Target/ARM/ARMJITInfo.cpp index 0456f33ea26..754fafe0287 100644 --- a/lib/Target/ARM/ARMJITInfo.cpp +++ b/lib/Target/ARM/ARMJITInfo.cpp @@ -140,6 +140,10 @@ ARMJITInfo::getLazyResolverFunction(JITCompilerFn F) { void *ARMJITInfo::emitGlobalValueIndirectSym(const GlobalValue *GV, void *Ptr, JITCodeEmitter &JCE) { JCE.startGVStub(GV, 4, 4); + intptr_t Addr = (intptr_t)JCE.getCurrentPCValue(); + if (!sys::Memory::setRangeWritable((void*)Addr, 4)) { + llvm_unreachable("ERROR: Unable to mark indirect symbol writable"); + } JCE.emitWordLE((intptr_t)Ptr); void *PtrAddr = JCE.finishGVStub(GV); addIndirectSymAddr(Ptr, (intptr_t)PtrAddr); @@ -167,18 +171,30 @@ void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn, } JCE.startGVStub(F, 16, 4); intptr_t Addr = (intptr_t)JCE.getCurrentPCValue(); + if (!sys::Memory::setRangeWritable((void*)Addr, 16)) { + llvm_unreachable("ERROR: Unable to mark stub writable"); + } JCE.emitWordLE(0xe59fc004); // ldr pc, [pc, #+4] JCE.emitWordLE(0xe08fc00c); // L_func$scv: add ip, pc, ip JCE.emitWordLE(0xe59cf000); // ldr pc, [ip] JCE.emitWordLE(LazyPtr - (Addr+4+8)); // func - (L_func$scv+8) sys::Memory::InvalidateInstructionCache((void*)Addr, 16); + if (!sys::Memory::setRangeExecutable((void*)Addr, 16)) { + llvm_unreachable("ERROR: Unable to mark stub executable"); + } } else { // The stub is 8-byte size and 4-aligned. JCE.startGVStub(F, 8, 4); intptr_t Addr = (intptr_t)JCE.getCurrentPCValue(); + if (!sys::Memory::setRangeWritable((void*)Addr, 8)) { + llvm_unreachable("ERROR: Unable to mark stub writable"); + } JCE.emitWordLE(0xe51ff004); // ldr pc, [pc, #-4] JCE.emitWordLE((intptr_t)Fn); // addr of function sys::Memory::InvalidateInstructionCache((void*)Addr, 8); + if (!sys::Memory::setRangeExecutable((void*)Addr, 8)) { + llvm_unreachable("ERROR: Unable to mark stub executable"); + } } } else { // The compilation callback will overwrite the first two words of this @@ -190,6 +206,9 @@ void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn, // The stub is 16-byte size and 4-byte aligned. JCE.startGVStub(F, 16, 4); intptr_t Addr = (intptr_t)JCE.getCurrentPCValue(); + if (!sys::Memory::setRangeWritable((void*)Addr, 16)) { + llvm_unreachable("ERROR: Unable to mark stub writable"); + } // Save LR so the callback can determine which stub called it. // The compilation callback is responsible for popping this prior // to returning. @@ -201,6 +220,9 @@ void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn, // The address of the compilation callback. JCE.emitWordLE((intptr_t)ARMCompilationCallback); sys::Memory::InvalidateInstructionCache((void*)Addr, 16); + if (!sys::Memory::setRangeExecutable((void*)Addr, 16)) { + llvm_unreachable("ERROR: Unable to mark stub executable"); + } } return JCE.finishGVStub(F);